objc2_metal_performance_shaders/generated/MPSNeuralNetwork/
MPSCNNConvolution.rs

1//! This file has been automatically generated by `objc2`'s `header-translator`.
2//! DO NOT EDIT
3use core::ffi::*;
4use core::ptr::NonNull;
5use objc2::__framework_prelude::*;
6use objc2_foundation::*;
7use objc2_metal::*;
8
9use crate::*;
10
11extern_class!(
12    /// Dependencies: This depends on Metal.framework
13    ///
14    /// The MPSCNNConvolutionDescriptor specifies a convolution descriptor
15    ///
16    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnconvolutiondescriptor?language=objc)
17    #[unsafe(super(NSObject))]
18    #[derive(Debug, PartialEq, Eq, Hash)]
19    pub struct MPSCNNConvolutionDescriptor;
20);
21
22extern_conformance!(
23    unsafe impl NSCoding for MPSCNNConvolutionDescriptor {}
24);
25
26extern_conformance!(
27    unsafe impl NSCopying for MPSCNNConvolutionDescriptor {}
28);
29
30unsafe impl CopyingHelper for MPSCNNConvolutionDescriptor {
31    type Result = Self;
32}
33
34extern_conformance!(
35    unsafe impl NSObjectProtocol for MPSCNNConvolutionDescriptor {}
36);
37
38extern_conformance!(
39    unsafe impl NSSecureCoding for MPSCNNConvolutionDescriptor {}
40);
41
42impl MPSCNNConvolutionDescriptor {
43    extern_methods!(
44        /// The width of the filter window.  The default value is 3.
45        /// Any positive non-zero value is valid, including even values.
46        /// The position of the left edge of the filter window is given
47        /// by offset.x - (kernelWidth>>1)
48        #[unsafe(method(kernelWidth))]
49        #[unsafe(method_family = none)]
50        pub unsafe fn kernelWidth(&self) -> NSUInteger;
51
52        /// Setter for [`kernelWidth`][Self::kernelWidth].
53        #[unsafe(method(setKernelWidth:))]
54        #[unsafe(method_family = none)]
55        pub unsafe fn setKernelWidth(&self, kernel_width: NSUInteger);
56
57        /// The height of the filter window.  The default value is 3.
58        /// Any positive non-zero value is valid, including even values.
59        /// The position of the top edge of the filter window is given
60        /// by offset.y - (kernelHeight>>1)
61        #[unsafe(method(kernelHeight))]
62        #[unsafe(method_family = none)]
63        pub unsafe fn kernelHeight(&self) -> NSUInteger;
64
65        /// Setter for [`kernelHeight`][Self::kernelHeight].
66        #[unsafe(method(setKernelHeight:))]
67        #[unsafe(method_family = none)]
68        pub unsafe fn setKernelHeight(&self, kernel_height: NSUInteger);
69
70        /// The number of feature channels per pixel in the input image.
71        #[unsafe(method(inputFeatureChannels))]
72        #[unsafe(method_family = none)]
73        pub unsafe fn inputFeatureChannels(&self) -> NSUInteger;
74
75        /// Setter for [`inputFeatureChannels`][Self::inputFeatureChannels].
76        #[unsafe(method(setInputFeatureChannels:))]
77        #[unsafe(method_family = none)]
78        pub unsafe fn setInputFeatureChannels(&self, input_feature_channels: NSUInteger);
79
80        /// The number of feature channels per pixel in the output image.
81        #[unsafe(method(outputFeatureChannels))]
82        #[unsafe(method_family = none)]
83        pub unsafe fn outputFeatureChannels(&self) -> NSUInteger;
84
85        /// Setter for [`outputFeatureChannels`][Self::outputFeatureChannels].
86        #[unsafe(method(setOutputFeatureChannels:))]
87        #[unsafe(method_family = none)]
88        pub unsafe fn setOutputFeatureChannels(&self, output_feature_channels: NSUInteger);
89
90        /// The output stride (downsampling factor) in the x dimension. The default value is 1.
91        #[unsafe(method(strideInPixelsX))]
92        #[unsafe(method_family = none)]
93        pub unsafe fn strideInPixelsX(&self) -> NSUInteger;
94
95        /// Setter for [`strideInPixelsX`][Self::strideInPixelsX].
96        #[unsafe(method(setStrideInPixelsX:))]
97        #[unsafe(method_family = none)]
98        pub unsafe fn setStrideInPixelsX(&self, stride_in_pixels_x: NSUInteger);
99
100        /// The output stride (downsampling factor) in the y dimension. The default value is 1.
101        #[unsafe(method(strideInPixelsY))]
102        #[unsafe(method_family = none)]
103        pub unsafe fn strideInPixelsY(&self) -> NSUInteger;
104
105        /// Setter for [`strideInPixelsY`][Self::strideInPixelsY].
106        #[unsafe(method(setStrideInPixelsY:))]
107        #[unsafe(method_family = none)]
108        pub unsafe fn setStrideInPixelsY(&self, stride_in_pixels_y: NSUInteger);
109
110        /// Number of groups input and output channels are divided into. The default value is 1.
111        /// Groups lets you reduce the parameterization. If groups is set to n, input is divided into n
112        /// groups with inputFeatureChannels/n channels in each group. Similarly output is divided into
113        /// n groups with outputFeatureChannels/n channels in each group. ith group in input is only
114        /// connected to ith group in output so number of weights (parameters) needed is reduced by factor
115        /// of n. Both inputFeatureChannels and outputFeatureChannels must be divisible by n and number of
116        /// channels in each group must be multiple of 4.
117        #[unsafe(method(groups))]
118        #[unsafe(method_family = none)]
119        pub unsafe fn groups(&self) -> NSUInteger;
120
121        /// Setter for [`groups`][Self::groups].
122        #[unsafe(method(setGroups:))]
123        #[unsafe(method_family = none)]
124        pub unsafe fn setGroups(&self, groups: NSUInteger);
125
126        /// dilationRateX property can be used to implement dilated convolution as described in
127        /// https://arxiv.org/pdf/1511.07122v3.pdf
128        /// to aggregate global information in dense prediction problems.
129        /// Default value is 1. When set to value > 1, original kernel width, kW is dilated to
130        ///
131        /// kW_Dilated = (kW-1)*dilationRateX + 1
132        ///
133        /// by inserting d-1 zeros between consecutive entries in each row of the original kernel.
134        /// The kernel is centered based on kW_Dilated.
135        #[unsafe(method(dilationRateX))]
136        #[unsafe(method_family = none)]
137        pub unsafe fn dilationRateX(&self) -> NSUInteger;
138
139        /// Setter for [`dilationRateX`][Self::dilationRateX].
140        #[unsafe(method(setDilationRateX:))]
141        #[unsafe(method_family = none)]
142        pub unsafe fn setDilationRateX(&self, dilation_rate_x: NSUInteger);
143
144        /// dilationRateY property can be used to implement dilated convolution as described in
145        /// https://arxiv.org/pdf/1511.07122v3.pdf
146        /// to aggregate global information in dense prediction problems.
147        /// Default value is 1. When set to value > 1, original kernel height, kH is dilated to
148        ///
149        /// kH_Dilated = (kH-1)*dilationRateY + 1
150        ///
151        /// by inserting d-1 rows of zeros between consecutive row of the original kernel.
152        /// The kernel is centered based on kH_Dilated.
153        #[unsafe(method(dilationRateY))]
154        #[unsafe(method_family = none)]
155        pub unsafe fn dilationRateY(&self) -> NSUInteger;
156
157        /// Setter for [`dilationRateY`][Self::dilationRateY].
158        #[unsafe(method(setDilationRateY:))]
159        #[unsafe(method_family = none)]
160        pub unsafe fn setDilationRateY(&self, dilation_rate_y: NSUInteger);
161
162        #[cfg(feature = "MPSCNNNeuron")]
163        /// This mathod can be used to add a neuron activation funtion of given type with
164        /// associated scalar parameters A and B that are shared across all output channels.
165        /// Neuron activation fucntion is applied to output of convolution. This is a per-pixel
166        /// operation that is fused with convolution kernel itself for best performance.
167        /// Note that this method can only be used to fuse neuron of kind for which parameters
168        /// A and B are shared across all channels of convoution output. It is an error to call
169        /// this method for neuron activation functions like MPSCNNNeuronTypePReLU,
170        /// which require per-channel parameter values. For those kind of neuron activation functions,
171        /// use appropriate setter functions. Default is descriptor with neuronType MPSCNNNeuronTypeNone.
172        ///
173        /// Note: in certain cases the neuron descriptor will be cached by the MPSNNGraph or the
174        /// MPSCNNConvolution. If the neuron type changes after either is made, behavior is undefined.
175        #[unsafe(method(fusedNeuronDescriptor))]
176        #[unsafe(method_family = none)]
177        pub unsafe fn fusedNeuronDescriptor(&self) -> Retained<MPSNNNeuronDescriptor>;
178
179        #[cfg(feature = "MPSCNNNeuron")]
180        /// Setter for [`fusedNeuronDescriptor`][Self::fusedNeuronDescriptor].
181        #[unsafe(method(setFusedNeuronDescriptor:))]
182        #[unsafe(method_family = none)]
183        pub unsafe fn setFusedNeuronDescriptor(
184            &self,
185            fused_neuron_descriptor: &MPSNNNeuronDescriptor,
186        );
187
188        #[cfg(all(
189            feature = "MPSCNNKernel",
190            feature = "MPSCNNNeuron",
191            feature = "MPSCore",
192            feature = "MPSKernel"
193        ))]
194        /// MPSCNNNeuron filter to be applied as part of convolution. This is applied after BatchNormalization in the end.
195        /// Default is nil.
196        /// This is deprecated. You dont need to create MPSCNNNeuron object to fuse with convolution. Use neuron properties
197        /// in this descriptor.
198        #[deprecated]
199        #[unsafe(method(neuron))]
200        #[unsafe(method_family = none)]
201        pub unsafe fn neuron(&self) -> Option<Retained<MPSCNNNeuron>>;
202
203        #[cfg(all(
204            feature = "MPSCNNKernel",
205            feature = "MPSCNNNeuron",
206            feature = "MPSCore",
207            feature = "MPSKernel"
208        ))]
209        /// Setter for [`neuron`][Self::neuron].
210        #[deprecated]
211        #[unsafe(method(setNeuron:))]
212        #[unsafe(method_family = none)]
213        pub unsafe fn setNeuron(&self, neuron: Option<&MPSCNNNeuron>);
214
215        /// <NSSecureCoding
216        /// > support
217        #[unsafe(method(supportsSecureCoding))]
218        #[unsafe(method_family = none)]
219        pub unsafe fn supportsSecureCoding() -> bool;
220
221        /// <NSSecureCoding
222        /// > support
223        ///
224        /// # Safety
225        ///
226        /// `a_coder` possibly has further requirements.
227        #[unsafe(method(encodeWithCoder:))]
228        #[unsafe(method_family = none)]
229        pub unsafe fn encodeWithCoder(&self, a_coder: &NSCoder);
230
231        /// <NSSecureCoding
232        /// > support
233        ///
234        /// # Safety
235        ///
236        /// `a_decoder` possibly has further requirements.
237        #[unsafe(method(initWithCoder:))]
238        #[unsafe(method_family = init)]
239        pub unsafe fn initWithCoder(
240            this: Allocated<Self>,
241            a_decoder: &NSCoder,
242        ) -> Option<Retained<Self>>;
243
244        #[cfg(all(
245            feature = "MPSCNNKernel",
246            feature = "MPSCNNNeuron",
247            feature = "MPSCore",
248            feature = "MPSKernel"
249        ))]
250        /// This method is deprecated. Please use neuronType, neuronParameterA and neuronParameterB properites to fuse
251        /// neuron with convolution.
252        ///
253        /// Parameter `kernelWidth`: The width of the filter window.  Must be > 0. Large values will take a long time.
254        ///
255        /// Parameter `kernelHeight`: The height of the filter window.   Must be > 0. Large values will take a long time.
256        ///
257        /// Parameter `inputFeatureChannels`: The number of feature channels in the input image. Must be >= 1.
258        ///
259        /// Parameter `outputFeatureChannels`: The number of feature channels in the output image. Must be >= 1.
260        ///
261        /// Parameter `neuronFilter`: An optional neuron filter that can be applied to the output of convolution.
262        ///
263        /// Returns: A valid MPSCNNConvolutionDescriptor object or nil, if failure.
264        #[deprecated]
265        #[unsafe(method(cnnConvolutionDescriptorWithKernelWidth:kernelHeight:inputFeatureChannels:outputFeatureChannels:neuronFilter:))]
266        #[unsafe(method_family = none)]
267        pub unsafe fn cnnConvolutionDescriptorWithKernelWidth_kernelHeight_inputFeatureChannels_outputFeatureChannels_neuronFilter(
268            kernel_width: NSUInteger,
269            kernel_height: NSUInteger,
270            input_feature_channels: NSUInteger,
271            output_feature_channels: NSUInteger,
272            neuron_filter: Option<&MPSCNNNeuron>,
273        ) -> Retained<Self>;
274
275        /// Creates a convolution descriptor.
276        ///
277        /// Parameter `kernelWidth`: The width of the filter window.  Must be > 0. Large values will take a long time.
278        ///
279        /// Parameter `kernelHeight`: The height of the filter window.   Must be > 0. Large values will take a long time.
280        ///
281        /// Parameter `inputFeatureChannels`: The number of feature channels in the input image. Must be >= 1.
282        ///
283        /// Parameter `outputFeatureChannels`: The number of feature channels in the output image. Must be >= 1.
284        ///
285        /// Returns: A valid MPSCNNConvolutionDescriptor object or nil, if failure.
286        #[unsafe(method(cnnConvolutionDescriptorWithKernelWidth:kernelHeight:inputFeatureChannels:outputFeatureChannels:))]
287        #[unsafe(method_family = none)]
288        pub unsafe fn cnnConvolutionDescriptorWithKernelWidth_kernelHeight_inputFeatureChannels_outputFeatureChannels(
289            kernel_width: NSUInteger,
290            kernel_height: NSUInteger,
291            input_feature_channels: NSUInteger,
292            output_feature_channels: NSUInteger,
293        ) -> Retained<Self>;
294
295        /// Adds batch normalization for inference, it copies all the float arrays provided, expecting
296        /// outputFeatureChannels elements in each.
297        ///
298        ///
299        /// This method will be used to pass in batch normalization parameters to the convolution during the
300        /// init call. For inference we modify weights and bias going in convolution or Fully Connected layer to combine
301        /// and optimize the layers.
302        ///
303        /// w: weights for a corresponding output feature channel
304        /// b: bias for a corresponding output feature channel
305        /// W: batch normalized weights for a corresponding output feature channel
306        /// B: batch normalized bias for a corresponding output feature channel
307        ///
308        /// I = gamma / sqrt(variance + epsilon), J = beta - ( I * mean )
309        ///
310        /// W = w * I
311        /// B = b * I + J
312        ///
313        /// Every convolution has (OutputFeatureChannel * kernelWidth * kernelHeight * InputFeatureChannel) weights
314        ///
315        /// I, J are calculated, for every output feature channel separately to get the corresponding weights and bias
316        /// Thus, I, J are calculated and then used for every (kernelWidth * kernelHeight * InputFeatureChannel)
317        /// weights, and this is done OutputFeatureChannel number of times for each output channel.
318        ///
319        /// thus, internally, batch normalized weights are computed as:
320        ///
321        /// W[no][i][j][ni] = w[no][i][j][ni] * I[no]
322        ///
323        /// no: index into outputFeatureChannel
324        /// i : index into kernel Height
325        /// j : index into kernel Width
326        /// ni: index into inputFeatureChannel
327        ///
328        /// One usually doesn't see a bias term and batch normalization together as batch normalization potentially cancels
329        /// out the bias term after training, but in MPS if the user provides it, batch normalization will use the above
330        /// formula to incorporate it, if user does not have bias terms then put a float array of zeroes in the convolution
331        /// init for bias terms of each output feature channel.
332        ///
333        /// this comes from:
334        /// https://arxiv.org/pdf/1502.03167v3.pdf
335        ///
336        /// Note: in certain cases the batch normalization parameters will be cached by the MPSNNGraph
337        /// or the MPSCNNConvolution. If the batch normalization parameters change after either is made,
338        /// behavior is undefined.
339        ///
340        ///
341        /// Parameter `mean`: Pointer to an array of floats of mean for each output feature channel
342        ///
343        /// Parameter `variance`: Pointer to an array of floats of variance for each output feature channel
344        ///
345        /// Parameter `gamma`: Pointer to an array of floats of gamma for each output feature channel
346        ///
347        /// Parameter `beta`: Pointer to an array of floats of beta for each output feature channel
348        ///
349        /// Parameter `epsilon`: A small float value used to have numerical stability in the code
350        ///
351        /// # Safety
352        ///
353        /// - `mean` must be a valid pointer or null.
354        /// - `variance` must be a valid pointer or null.
355        /// - `gamma` must be a valid pointer or null.
356        /// - `beta` must be a valid pointer or null.
357        #[unsafe(method(setBatchNormalizationParametersForInferenceWithMean:variance:gamma:beta:epsilon:))]
358        #[unsafe(method_family = none)]
359        pub unsafe fn setBatchNormalizationParametersForInferenceWithMean_variance_gamma_beta_epsilon(
360            &self,
361            mean: *const c_float,
362            variance: *const c_float,
363            gamma: *const c_float,
364            beta: *const c_float,
365            epsilon: c_float,
366        );
367
368        #[cfg(feature = "MPSCNNNeuronType")]
369        /// Adds a neuron activation function to convolution descriptor.
370        ///
371        ///
372        /// This mathod can be used to add a neuron activation funtion of given type with
373        /// associated scalar parameters A and B that are shared across all output channels.
374        /// Neuron activation fucntion is applied to output of convolution. This is a per-pixel
375        /// operation that is fused with convolution kernel itself for best performance.
376        /// Note that this method can only be used to fuse neuron of kind for which parameters
377        /// A and B are shared across all channels of convoution output. It is an error to call
378        /// this method for neuron activation functions like MPSCNNNeuronTypePReLU,
379        /// which require per-channel parameter values. For those kind of neuron activation functions,
380        /// use appropriate setter functions.
381        ///
382        /// Note: in certain cases, the neuron descriptor will be cached by the MPSNNGraph or the
383        /// MPSCNNConvolution. If the neuron type changes after either is made, behavior is undefined.
384        ///
385        ///
386        /// Parameter `neuronType`: type of neuron activation function. For full list see MPSCNNNeuronType.h
387        ///
388        /// Parameter `parameterA`: parameterA of neuron activation that is shared across all channels of convolution output.
389        ///
390        /// Parameter `parameterB`: parameterB of neuron activation that is shared across all channels of convolution output.
391        #[deprecated]
392        #[unsafe(method(setNeuronType:parameterA:parameterB:))]
393        #[unsafe(method_family = none)]
394        pub unsafe fn setNeuronType_parameterA_parameterB(
395            &self,
396            neuron_type: MPSCNNNeuronType,
397            parameter_a: c_float,
398            parameter_b: c_float,
399        );
400
401        #[cfg(feature = "MPSCNNNeuronType")]
402        /// Getter funtion for neuronType set using setNeuronType:parameterA:parameterB method
403        #[deprecated]
404        #[unsafe(method(neuronType))]
405        #[unsafe(method_family = none)]
406        pub unsafe fn neuronType(&self) -> MPSCNNNeuronType;
407
408        /// Getter funtion for neuronType set using setNeuronType:parameterA:parameterB method
409        #[deprecated]
410        #[unsafe(method(neuronParameterA))]
411        #[unsafe(method_family = none)]
412        pub unsafe fn neuronParameterA(&self) -> c_float;
413
414        /// Getter funtion for neuronType set using setNeuronType:parameterA:parameterB method
415        #[deprecated]
416        #[unsafe(method(neuronParameterB))]
417        #[unsafe(method_family = none)]
418        pub unsafe fn neuronParameterB(&self) -> c_float;
419
420        /// Add per-channel neuron parameters A for PReLu neuron activation functions.
421        ///
422        ///
423        /// This method sets the neuron to PReLU, zeros parameters A and B and sets the per-channel
424        /// neuron parameters A to an array containing a unique value of A for each output feature
425        /// channel.
426        ///
427        /// If the neuron function is f(v,a,b), it will apply
428        ///
429        /// OutputImage(x,y,i) = f( ConvolutionResult(x,y,i), A[i], B[i] ) where i in [0,outputFeatureChannels-1]
430        ///
431        /// See https://arxiv.org/pdf/1502.01852.pdf for details.
432        ///
433        /// All other neuron types, where parameter A
434        /// and parameter B are shared across channels must be set using
435        /// -setNeuronOfType:parameterA:parameterB:
436        ///
437        /// If batch normalization parameters are set, batch normalization will occur before
438        /// neuron application i.e. output of convolution is first batch normalized followed
439        /// by neuron activation. This function automatically sets neuronType to MPSCNNNeuronTypePReLU.
440        ///
441        /// Note: in certain cases the neuron descriptor will be cached by the MPSNNGraph or the
442        /// MPSCNNConvolution. If the neuron type changes after either is made, behavior is undefined.
443        ///
444        ///
445        /// Parameter `A`: An array containing per-channel float values for neuron parameter A.
446        /// Number of entries must be equal to outputFeatureChannels.
447        #[deprecated]
448        #[unsafe(method(setNeuronToPReLUWithParametersA:))]
449        #[unsafe(method_family = none)]
450        pub unsafe fn setNeuronToPReLUWithParametersA(&self, a: &NSData);
451    );
452}
453
454/// Methods declared on superclass `NSObject`.
455impl MPSCNNConvolutionDescriptor {
456    extern_methods!(
457        #[unsafe(method(init))]
458        #[unsafe(method_family = init)]
459        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
460
461        #[unsafe(method(new))]
462        #[unsafe(method_family = new)]
463        pub unsafe fn new() -> Retained<Self>;
464    );
465}
466
467extern_class!(
468    /// MPSCNNSubPixelConvolutionDescriptor can be used to create MPSCNNConvolution object that does sub pixel upsamling
469    /// and reshaping opeartion as described in
470    /// http://www.cv-foundation.org/openaccess/content_cvpr_2016/papers/Shi_Real-Time_Single_Image_CVPR_2016_paper.pdf
471    ///
472    /// Conceptually MPSCNNConvolution with subPixelScaleFactor > 1 can be thought of as filter performing regular CNN convolution producing N output feature channels at each pixel of
473    /// an intermediate MPSImage followed by a kernel that rearranges/reshapes these N channels at each pixel of intermediate MPSImage into a pixel block of
474    /// size subPixelScaleFactor x subPixelScaleFactor with N/(subPixelScaleFactor * subPixelScaleFactor) featureChannels at each pixel of this pixel block. Thus each pixel in intermedaite
475    /// MPSImage with N channels map to subPixelScaleFactor x subPixelScaleFactor pixel block in final destination MPSImage with N/(subPixelScaleFactor * subPixelScaleFactor) featureChannels.
476    /// MPSCNNConvolution with subPixelScaleFactor > 1 fuses the convolution and reshaping operation into single compute kernel thus not only saving DRAM roundtrip but also memory
477    /// needed for intermediate MPSImage had these operation done separately.
478    /// Let N be the value of outputFeatureChannels property and let r = subPixelScaleFactor.
479    /// Conceptually Convolution will produce intermedaite image Io of dimensions (treated as 3D tensor) width x height x N where
480    /// width = (clipRect.size.width + r - 1) / r
481    /// height = (clipRect.size.height + r -1) / r
482    /// Reshaping happens as follows
483    ///
484    /// ```text
485    ///                    Destination[clipRect.origin.x+x][clipRect.origin.y+y][c] = Io[ floor(x/r) ][ floor(y/r) ][ (N/r^2) * ( r * mod(y,r) + mod(x,r) ) + c ]
486    ///                    where x in [0,clipRect.size.width-1], y in [0,clipRect.size.height-1], c in [0,N/r^2 - 1]
487    /// ```
488    ///
489    /// The following conditions must be met:
490    /// 1) N (outputFeatureChannels) must be multiple of r^2 (subPixelScaleFactor * subPixelScaleFactor).
491    /// 2) The destination MPSImage to encode call must have at least N/r^2 + destinationFeatureChannelOffset channels.
492    /// 3) Number of feature channels in reshaped output image (N/r^2) can be any value when groups = 1 but must be multiple of 4 when groups > 1.
493    ///
494    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnsubpixelconvolutiondescriptor?language=objc)
495    #[unsafe(super(MPSCNNConvolutionDescriptor, NSObject))]
496    #[derive(Debug, PartialEq, Eq, Hash)]
497    pub struct MPSCNNSubPixelConvolutionDescriptor;
498);
499
500extern_conformance!(
501    unsafe impl NSCoding for MPSCNNSubPixelConvolutionDescriptor {}
502);
503
504extern_conformance!(
505    unsafe impl NSCopying for MPSCNNSubPixelConvolutionDescriptor {}
506);
507
508unsafe impl CopyingHelper for MPSCNNSubPixelConvolutionDescriptor {
509    type Result = Self;
510}
511
512extern_conformance!(
513    unsafe impl NSObjectProtocol for MPSCNNSubPixelConvolutionDescriptor {}
514);
515
516extern_conformance!(
517    unsafe impl NSSecureCoding for MPSCNNSubPixelConvolutionDescriptor {}
518);
519
520impl MPSCNNSubPixelConvolutionDescriptor {
521    extern_methods!(
522        /// Upsampling scale factor. Each pixel in input is upsampled into a subPixelScaleFactor x subPixelScaleFactor pixel block by rearranging
523        /// the outputFeatureChannels as described above. Default value is 1.
524        #[unsafe(method(subPixelScaleFactor))]
525        #[unsafe(method_family = none)]
526        pub unsafe fn subPixelScaleFactor(&self) -> NSUInteger;
527
528        /// Setter for [`subPixelScaleFactor`][Self::subPixelScaleFactor].
529        #[unsafe(method(setSubPixelScaleFactor:))]
530        #[unsafe(method_family = none)]
531        pub unsafe fn setSubPixelScaleFactor(&self, sub_pixel_scale_factor: NSUInteger);
532    );
533}
534
535/// Methods declared on superclass `MPSCNNConvolutionDescriptor`.
536impl MPSCNNSubPixelConvolutionDescriptor {
537    extern_methods!(
538        /// <NSSecureCoding
539        /// > support
540        ///
541        /// # Safety
542        ///
543        /// `a_decoder` possibly has further requirements.
544        #[unsafe(method(initWithCoder:))]
545        #[unsafe(method_family = init)]
546        pub unsafe fn initWithCoder(
547            this: Allocated<Self>,
548            a_decoder: &NSCoder,
549        ) -> Option<Retained<Self>>;
550
551        #[cfg(all(
552            feature = "MPSCNNKernel",
553            feature = "MPSCNNNeuron",
554            feature = "MPSCore",
555            feature = "MPSKernel"
556        ))]
557        /// This method is deprecated. Please use neuronType, neuronParameterA and neuronParameterB properites to fuse
558        /// neuron with convolution.
559        ///
560        /// Parameter `kernelWidth`: The width of the filter window.  Must be > 0. Large values will take a long time.
561        ///
562        /// Parameter `kernelHeight`: The height of the filter window.   Must be > 0. Large values will take a long time.
563        ///
564        /// Parameter `inputFeatureChannels`: The number of feature channels in the input image. Must be >= 1.
565        ///
566        /// Parameter `outputFeatureChannels`: The number of feature channels in the output image. Must be >= 1.
567        ///
568        /// Parameter `neuronFilter`: An optional neuron filter that can be applied to the output of convolution.
569        ///
570        /// Returns: A valid MPSCNNConvolutionDescriptor object or nil, if failure.
571        #[deprecated]
572        #[unsafe(method(cnnConvolutionDescriptorWithKernelWidth:kernelHeight:inputFeatureChannels:outputFeatureChannels:neuronFilter:))]
573        #[unsafe(method_family = none)]
574        pub unsafe fn cnnConvolutionDescriptorWithKernelWidth_kernelHeight_inputFeatureChannels_outputFeatureChannels_neuronFilter(
575            kernel_width: NSUInteger,
576            kernel_height: NSUInteger,
577            input_feature_channels: NSUInteger,
578            output_feature_channels: NSUInteger,
579            neuron_filter: Option<&MPSCNNNeuron>,
580        ) -> Retained<Self>;
581
582        /// Creates a convolution descriptor.
583        ///
584        /// Parameter `kernelWidth`: The width of the filter window.  Must be > 0. Large values will take a long time.
585        ///
586        /// Parameter `kernelHeight`: The height of the filter window.   Must be > 0. Large values will take a long time.
587        ///
588        /// Parameter `inputFeatureChannels`: The number of feature channels in the input image. Must be >= 1.
589        ///
590        /// Parameter `outputFeatureChannels`: The number of feature channels in the output image. Must be >= 1.
591        ///
592        /// Returns: A valid MPSCNNConvolutionDescriptor object or nil, if failure.
593        #[unsafe(method(cnnConvolutionDescriptorWithKernelWidth:kernelHeight:inputFeatureChannels:outputFeatureChannels:))]
594        #[unsafe(method_family = none)]
595        pub unsafe fn cnnConvolutionDescriptorWithKernelWidth_kernelHeight_inputFeatureChannels_outputFeatureChannels(
596            kernel_width: NSUInteger,
597            kernel_height: NSUInteger,
598            input_feature_channels: NSUInteger,
599            output_feature_channels: NSUInteger,
600        ) -> Retained<Self>;
601    );
602}
603
604/// Methods declared on superclass `NSObject`.
605impl MPSCNNSubPixelConvolutionDescriptor {
606    extern_methods!(
607        #[unsafe(method(init))]
608        #[unsafe(method_family = init)]
609        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
610
611        #[unsafe(method(new))]
612        #[unsafe(method_family = new)]
613        pub unsafe fn new() -> Retained<Self>;
614    );
615}
616
617extern_class!(
618    /// MPSCNNDepthWiseConvolutionDescriptor can be used to create MPSCNNConvolution object that does depthwise convolution
619    ///
620    /// Depthwise convolution applies different filter to each input feature channel i.e. no cross channel mixing.
621    /// Number of outputFeatureChannels can be greater than number of inputFeatureChannels, in which case convolution
622    /// expects channelMultipler = outputFeactureChannels/inputFeatureChannels number of filters for each input channel.
623    /// This means channelMultipler filters are applied to each input feature channel producing channelMultipler output feature channels.
624    /// All channelMultipler output feature channels produced by single input feature channel are stored togather in output image i.e.
625    /// output[x,y,k*channelMultiplier + q] = input[x,y,k] * filter[k,q]
626    /// where * here denotes convolution.
627    /// group must be 1.
628    /// Weights array returned by MPSCNNConvolutionDataProvier is interpreted as
629    /// Weights [inputFeatureChannels] [channelMultiplier] [kH] [kW]
630    /// = Weights [ inputFeatureChannels * channelMultiplier ] [kH] [kW]
631    /// = Weights [ outputFeatureChannels ] [kH] [kW]
632    ///
633    /// Currently only channel multipler of 1 is supported i.e. inputFeatureChannels == outputFeatureChannels
634    ///
635    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnndepthwiseconvolutiondescriptor?language=objc)
636    #[unsafe(super(MPSCNNConvolutionDescriptor, NSObject))]
637    #[derive(Debug, PartialEq, Eq, Hash)]
638    pub struct MPSCNNDepthWiseConvolutionDescriptor;
639);
640
641extern_conformance!(
642    unsafe impl NSCoding for MPSCNNDepthWiseConvolutionDescriptor {}
643);
644
645extern_conformance!(
646    unsafe impl NSCopying for MPSCNNDepthWiseConvolutionDescriptor {}
647);
648
649unsafe impl CopyingHelper for MPSCNNDepthWiseConvolutionDescriptor {
650    type Result = Self;
651}
652
653extern_conformance!(
654    unsafe impl NSObjectProtocol for MPSCNNDepthWiseConvolutionDescriptor {}
655);
656
657extern_conformance!(
658    unsafe impl NSSecureCoding for MPSCNNDepthWiseConvolutionDescriptor {}
659);
660
661impl MPSCNNDepthWiseConvolutionDescriptor {
662    extern_methods!(
663        /// Ratio of outputFeactureChannel to inputFeatureChannels for depthwise convolution i.e. how many output feature channels are
664        /// produced by each input channel.
665        #[unsafe(method(channelMultiplier))]
666        #[unsafe(method_family = none)]
667        pub unsafe fn channelMultiplier(&self) -> NSUInteger;
668    );
669}
670
671/// Methods declared on superclass `MPSCNNConvolutionDescriptor`.
672impl MPSCNNDepthWiseConvolutionDescriptor {
673    extern_methods!(
674        /// <NSSecureCoding
675        /// > support
676        ///
677        /// # Safety
678        ///
679        /// `a_decoder` possibly has further requirements.
680        #[unsafe(method(initWithCoder:))]
681        #[unsafe(method_family = init)]
682        pub unsafe fn initWithCoder(
683            this: Allocated<Self>,
684            a_decoder: &NSCoder,
685        ) -> Option<Retained<Self>>;
686
687        #[cfg(all(
688            feature = "MPSCNNKernel",
689            feature = "MPSCNNNeuron",
690            feature = "MPSCore",
691            feature = "MPSKernel"
692        ))]
693        /// This method is deprecated. Please use neuronType, neuronParameterA and neuronParameterB properites to fuse
694        /// neuron with convolution.
695        ///
696        /// Parameter `kernelWidth`: The width of the filter window.  Must be > 0. Large values will take a long time.
697        ///
698        /// Parameter `kernelHeight`: The height of the filter window.   Must be > 0. Large values will take a long time.
699        ///
700        /// Parameter `inputFeatureChannels`: The number of feature channels in the input image. Must be >= 1.
701        ///
702        /// Parameter `outputFeatureChannels`: The number of feature channels in the output image. Must be >= 1.
703        ///
704        /// Parameter `neuronFilter`: An optional neuron filter that can be applied to the output of convolution.
705        ///
706        /// Returns: A valid MPSCNNConvolutionDescriptor object or nil, if failure.
707        #[deprecated]
708        #[unsafe(method(cnnConvolutionDescriptorWithKernelWidth:kernelHeight:inputFeatureChannels:outputFeatureChannels:neuronFilter:))]
709        #[unsafe(method_family = none)]
710        pub unsafe fn cnnConvolutionDescriptorWithKernelWidth_kernelHeight_inputFeatureChannels_outputFeatureChannels_neuronFilter(
711            kernel_width: NSUInteger,
712            kernel_height: NSUInteger,
713            input_feature_channels: NSUInteger,
714            output_feature_channels: NSUInteger,
715            neuron_filter: Option<&MPSCNNNeuron>,
716        ) -> Retained<Self>;
717
718        /// Creates a convolution descriptor.
719        ///
720        /// Parameter `kernelWidth`: The width of the filter window.  Must be > 0. Large values will take a long time.
721        ///
722        /// Parameter `kernelHeight`: The height of the filter window.   Must be > 0. Large values will take a long time.
723        ///
724        /// Parameter `inputFeatureChannels`: The number of feature channels in the input image. Must be >= 1.
725        ///
726        /// Parameter `outputFeatureChannels`: The number of feature channels in the output image. Must be >= 1.
727        ///
728        /// Returns: A valid MPSCNNConvolutionDescriptor object or nil, if failure.
729        #[unsafe(method(cnnConvolutionDescriptorWithKernelWidth:kernelHeight:inputFeatureChannels:outputFeatureChannels:))]
730        #[unsafe(method_family = none)]
731        pub unsafe fn cnnConvolutionDescriptorWithKernelWidth_kernelHeight_inputFeatureChannels_outputFeatureChannels(
732            kernel_width: NSUInteger,
733            kernel_height: NSUInteger,
734            input_feature_channels: NSUInteger,
735            output_feature_channels: NSUInteger,
736        ) -> Retained<Self>;
737    );
738}
739
740/// Methods declared on superclass `NSObject`.
741impl MPSCNNDepthWiseConvolutionDescriptor {
742    extern_methods!(
743        #[unsafe(method(init))]
744        #[unsafe(method_family = init)]
745        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
746
747        #[unsafe(method(new))]
748        #[unsafe(method_family = new)]
749        pub unsafe fn new() -> Retained<Self>;
750    );
751}
752
753/// [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnconvolutionweightslayout?language=objc)
754// NS_ENUM
755#[repr(transparent)]
756#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
757pub struct MPSCNNConvolutionWeightsLayout(pub u32);
758impl MPSCNNConvolutionWeightsLayout {
759    #[doc(alias = "MPSCNNConvolutionWeightsLayoutOHWI")]
760    pub const OHWI: Self = Self(0);
761}
762
763unsafe impl Encode for MPSCNNConvolutionWeightsLayout {
764    const ENCODING: Encoding = u32::ENCODING;
765}
766
767unsafe impl RefEncode for MPSCNNConvolutionWeightsLayout {
768    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
769}
770
771/// [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnweightsquantizationtype?language=objc)
772// NS_ENUM
773#[repr(transparent)]
774#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
775pub struct MPSCNNWeightsQuantizationType(pub u32);
776impl MPSCNNWeightsQuantizationType {
777    #[doc(alias = "MPSCNNWeightsQuantizationTypeNone")]
778    pub const None: Self = Self(0);
779    #[doc(alias = "MPSCNNWeightsQuantizationTypeLinear")]
780    pub const Linear: Self = Self(1);
781    #[doc(alias = "MPSCNNWeightsQuantizationTypeLookupTable")]
782    pub const LookupTable: Self = Self(2);
783}
784
785unsafe impl Encode for MPSCNNWeightsQuantizationType {
786    const ENCODING: Encoding = u32::ENCODING;
787}
788
789unsafe impl RefEncode for MPSCNNWeightsQuantizationType {
790    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
791}
792
793extern_class!(
794    /// The MPSCNNConvolutionGradientState is returned by resultStateForSourceImage:sourceStates method on MPSCNNConvolution object.
795    /// Note that resultStateForSourceImage:sourceStates:destinationImage creates the object on autoreleasepool.
796    /// It will be consumed by MPSCNNConvolutionGradient. This is also used by MPSCNNConvolutionTranspose encode call
797    /// that returns MPSImage on left hand side to correctly size the destination.
798    /// Note that state objects are not usable across batches i.e. when batch is done you should nuke the state object and create
799    /// new one for next batch.
800    ///
801    /// This state exposes the gradient with respect to weights and biases, as computed by the MPSCNNConvolutionGradient kernel, as a metal buffer to be used
802    /// during weights and biases update. The standard weights and biases update formula is:
803    ///
804    /// weights(t+1) = f(weights(t), gradientForWeights(t)) and
805    /// biases(t+1) = f(biases(t), gradientForBiases(t)),
806    ///
807    /// where the weights(t)/biases(t) are the wegihts and the biases at step t that are provided by data source provider used to create MPSCNNConvolution and
808    /// MPSCNNConvoltuionGradient objects. There are multiple ways user can update weights and biases as described below:
809    ///
810    /// 1) For check pointing, i.e. updating weights/biases and storing:
811    /// once the command buffer on which MPSCNNConvolutionGradient is enqueued is done (e.g. in command
812    /// buffer completion callback), the application can simply use
813    /// float* delta_w = (float*)((char*)[gradientForWeights contents]);
814    /// float* delta_b = (float*)((char*)[gradientForBiases contents]);
815    /// to update the weights and biases in the data provider directly.
816    /// The application can instead provide a metal kernel that reads from gradientForWeights and gradientForBiases buffer and the buffer created using data provided by the data source
817    /// to do any kind of update it will like to do, then read back the updated weights/biases and store to the data source. Note that lifetime of the
818    /// gradientForWeights and gradientForBiases buffer is the same as the MPSCNNConvolutionGradientState. So it's the applications's responsibility to make sure the buffer is alive
819    /// (retained) when the update kernel is running if the command buffer doesn't retain the buffer. Also, in order to gaurantee that the buffer is correctly
820    /// synchronized for CPU side access, it is the application's responsibility to call
821    /// [gradientState synchronizeOnCommandBuffer:]
822    /// before accessing data from the buffer.
823    ///
824    /// 2) For a CPU side update, once the weights and biases in the data source provider are updated as above, the original MPSCNNConvolution and
825    /// MPSCNNConvolutionGradient objects need to be updated with the new weigths and biases by calling the
826    /// -(void) reloadWeightsAndBiasesFromDataSource
827    /// method. Again application needs to call [gradientState synchronizeOnCommandBuffer:] before touching data on CPU side.
828    ///
829    /// 3) The above CPU side update requires command buffer to be done. If the application doesn't want to update its data source provider object and would prefer to directly
830    /// enqueue an update of the internal MPSCNNConvolution and MPSCNNConvolutionGradient weights/biases buffers on the GPU without CPU side involvement, it needs to do
831    /// following:
832    /// i) get gradientForWeights and gradientForBiases buffers from this gradient state object and set it as source of update kernel
833    /// ii) create a temporary buffer, dest, of same size and set it as destination of update kernel
834    /// iii) enqueue update kernel on command buffer
835    /// iv) call reloadWeightsAndBiasesWithCommandBuffer:dest:weightsOffset:biasesOffset on MPSCNNConvolution and MPSCNNConvolutionGradient objects. This
836    /// will reload the weights from application's update kernel in dest on GPU without CPU side involvement.
837    ///
838    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnconvolutiongradientstate?language=objc)
839    #[unsafe(super(MPSNNGradientState, MPSState, NSObject))]
840    #[derive(Debug, PartialEq, Eq, Hash)]
841    #[cfg(all(
842        feature = "MPSCore",
843        feature = "MPSNNGradientState",
844        feature = "MPSState"
845    ))]
846    pub struct MPSCNNConvolutionGradientState;
847);
848
849#[cfg(all(
850    feature = "MPSCore",
851    feature = "MPSNNGradientState",
852    feature = "MPSNeuralNetworkTypes",
853    feature = "MPSState"
854))]
855extern_conformance!(
856    unsafe impl MPSImageSizeEncodingState for MPSCNNConvolutionGradientState {}
857);
858
859#[cfg(all(
860    feature = "MPSCore",
861    feature = "MPSNNGradientState",
862    feature = "MPSState"
863))]
864extern_conformance!(
865    unsafe impl NSObjectProtocol for MPSCNNConvolutionGradientState {}
866);
867
868#[cfg(all(
869    feature = "MPSCore",
870    feature = "MPSNNGradientState",
871    feature = "MPSState"
872))]
873impl MPSCNNConvolutionGradientState {
874    extern_methods!(
875        /// A buffer that contains the loss function gradients with respect to weights.
876        /// Each value in the buffer is a float. The layout of the gradients with respect to the weights is the same as
877        /// the weights layout provided by data source i.e. it can be interpreted as 4D array
878        ///
879        /// gradientForWeights[outputFeatureChannels][kernelHeight][kernelWidth][inputFeatureChannels/groups]
880        /// For depthwise convolution it will be (since we only support channel multiplier of 1 currently)
881        /// gradientForWeights[outputFeatureChannels][kernelHeight][kernelWidth]
882        #[unsafe(method(gradientForWeights))]
883        #[unsafe(method_family = none)]
884        pub unsafe fn gradientForWeights(&self) -> Retained<ProtocolObject<dyn MTLBuffer>>;
885
886        /// A buffer that contains the loss function gradients with respect to biases.
887        #[unsafe(method(gradientForBiases))]
888        #[unsafe(method_family = none)]
889        pub unsafe fn gradientForBiases(&self) -> Retained<ProtocolObject<dyn MTLBuffer>>;
890
891        #[cfg(all(feature = "MPSCNNKernel", feature = "MPSKernel"))]
892        /// The convolution filter that produced the state.
893        /// For child MPSCNNConvolutionTrasposeGradientState object, convolution
894        /// below refers to MPSCNNConvolution object that produced MPSCNNConvolutionGradientState object
895        /// which was used to create MPSCNNConvolutionTransposeGradientState object. See resultStateForSourceImage:sourceStates
896        /// method of MPSCNNConvolutionTranspose below.
897        #[unsafe(method(convolution))]
898        #[unsafe(method_family = none)]
899        pub unsafe fn convolution(&self) -> Retained<MPSCNNConvolution>;
900
901        /// Layout of gradient with respect to weights in gradientForWeights buffer.
902        /// Currently only MPSCNNConvolutionWeightsLayoutOHWI is supported.
903        #[unsafe(method(gradientForWeightsLayout))]
904        #[unsafe(method_family = none)]
905        pub unsafe fn gradientForWeightsLayout(&self) -> MPSCNNConvolutionWeightsLayout;
906    );
907}
908
909/// Methods declared on superclass `MPSState`.
910#[cfg(all(
911    feature = "MPSCore",
912    feature = "MPSNNGradientState",
913    feature = "MPSState"
914))]
915impl MPSCNNConvolutionGradientState {
916    extern_methods!(
917        /// Create a MPSState holding a temporary MTLBuffer
918        ///
919        /// Parameter `cmdBuf`: The command buffer against which the temporary resource is allocated
920        ///
921        /// Parameter `bufferSize`: The size of the buffer in bytes
922        #[unsafe(method(temporaryStateWithCommandBuffer:bufferSize:))]
923        #[unsafe(method_family = none)]
924        pub unsafe fn temporaryStateWithCommandBuffer_bufferSize(
925            cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
926            buffer_size: usize,
927        ) -> Retained<Self>;
928
929        /// Create a MPSState holding a temporary MTLTexture
930        ///
931        /// Parameter `cmdBuf`: The command buffer against which the temporary resource is allocated
932        ///
933        /// Parameter `descriptor`: A descriptor for the new temporary texture
934        #[unsafe(method(temporaryStateWithCommandBuffer:textureDescriptor:))]
935        #[unsafe(method_family = none)]
936        pub unsafe fn temporaryStateWithCommandBuffer_textureDescriptor(
937            cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
938            descriptor: &MTLTextureDescriptor,
939        ) -> Retained<Self>;
940
941        /// Create a new autoreleased temporary state object without underlying resource
942        ///
943        /// Parameter `cmdBuf`: The command buffer with which the temporary resource is associated
944        #[unsafe(method(temporaryStateWithCommandBuffer:))]
945        #[unsafe(method_family = none)]
946        pub unsafe fn temporaryStateWithCommandBuffer(
947            cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
948        ) -> Retained<Self>;
949
950        #[unsafe(method(initWithDevice:bufferSize:))]
951        #[unsafe(method_family = init)]
952        pub unsafe fn initWithDevice_bufferSize(
953            this: Allocated<Self>,
954            device: &ProtocolObject<dyn MTLDevice>,
955            buffer_size: usize,
956        ) -> Retained<Self>;
957
958        #[unsafe(method(initWithDevice:textureDescriptor:))]
959        #[unsafe(method_family = init)]
960        pub unsafe fn initWithDevice_textureDescriptor(
961            this: Allocated<Self>,
962            device: &ProtocolObject<dyn MTLDevice>,
963            descriptor: &MTLTextureDescriptor,
964        ) -> Retained<Self>;
965
966        /// Create a MPSState with a non-temporary MTLResource
967        ///
968        /// Parameter `resource`: A MTLBuffer or MTLTexture. May be nil.
969        ///
970        /// # Safety
971        ///
972        /// - `resource` may need to be synchronized.
973        /// - `resource` may be unretained, you must ensure it is kept alive while in use.
974        #[unsafe(method(initWithResource:))]
975        #[unsafe(method_family = init)]
976        pub unsafe fn initWithResource(
977            this: Allocated<Self>,
978            resource: Option<&ProtocolObject<dyn MTLResource>>,
979        ) -> Retained<Self>;
980
981        #[unsafe(method(init))]
982        #[unsafe(method_family = init)]
983        pub unsafe fn init(this: Allocated<Self>) -> Option<Retained<Self>>;
984
985        /// Initialize a non-temporary state to hold a number of textures and buffers
986        ///
987        /// The allocation of each resource will be deferred  until it is needed.
988        /// This occurs when -resource or -resourceAtIndex: is called.
989        ///
990        /// Parameter `resourceList`: The list of resources to create.
991        #[unsafe(method(initWithDevice:resourceList:))]
992        #[unsafe(method_family = init)]
993        pub unsafe fn initWithDevice_resourceList(
994            this: Allocated<Self>,
995            device: &ProtocolObject<dyn MTLDevice>,
996            resource_list: &MPSStateResourceList,
997        ) -> Retained<Self>;
998
999        /// Initialize a temporary state to hold a number of textures and buffers
1000        ///
1001        /// The textures occur first in sequence
1002        #[unsafe(method(temporaryStateWithCommandBuffer:resourceList:))]
1003        #[unsafe(method_family = none)]
1004        pub unsafe fn temporaryStateWithCommandBuffer_resourceList(
1005            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1006            resource_list: &MPSStateResourceList,
1007        ) -> Retained<Self>;
1008
1009        /// Create a state object with a list of MTLResources
1010        ///
1011        /// Because MPS prefers deferred allocation of resources
1012        /// your application should use -initWithTextures:bufferSizes:bufferCount:
1013        /// whenever possible. This method is useful for cases when the
1014        /// MTLResources must be initialized by the CPU.
1015        ///
1016        /// # Safety
1017        ///
1018        /// - `resources` generic may need to be synchronized.
1019        /// - `resources` generic may be unretained, you must ensure it is kept alive while in use.
1020        #[unsafe(method(initWithResources:))]
1021        #[unsafe(method_family = init)]
1022        pub unsafe fn initWithResources(
1023            this: Allocated<Self>,
1024            resources: Option<&NSArray<ProtocolObject<dyn MTLResource>>>,
1025        ) -> Retained<Self>;
1026    );
1027}
1028
1029/// Methods declared on superclass `NSObject`.
1030#[cfg(all(
1031    feature = "MPSCore",
1032    feature = "MPSNNGradientState",
1033    feature = "MPSState"
1034))]
1035impl MPSCNNConvolutionGradientState {
1036    extern_methods!(
1037        #[unsafe(method(new))]
1038        #[unsafe(method_family = new)]
1039        pub unsafe fn new() -> Retained<Self>;
1040    );
1041}
1042
1043/// [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnconvolutiongradientstatebatch?language=objc)
1044#[cfg(all(
1045    feature = "MPSCore",
1046    feature = "MPSNNGradientState",
1047    feature = "MPSState"
1048))]
1049pub type MPSCNNConvolutionGradientStateBatch = NSArray<MPSCNNConvolutionGradientState>;
1050
1051extern_class!(
1052    /// The MPSCNNConvolutionTransposeGradientState is returned by resultStateForSourceImage:sourceStates method on MPSCNNConvolutionTranspose object.
1053    /// Note that resultStateForSourceImage:sourceStates:destinationImage creates the object on autoreleasepool.
1054    /// It will be consumed by MPSCNNConvolutionTransposeGradient. It contains reference to MPSCNNConvolutionGradientState object that connects
1055    /// MPSCNNConvolution and its corresponding MPSCNNConvolutionTranspose in forward pass of autoencoder. In an autoencoder forward pass, MPSCNNConvolutionGradientState is produced
1056    /// by MPSCNNConvolution object and is used by corresponding MPSCNNConvolutionTraspose of forward pass that "undo" the corresponding MPSCNNConvolution. It is used to correctly size
1057    /// destination image that is returned on left hand side by encode call MPSCNNConvolutionTranspose as well as automatically set kernelOffsetX/Y on MPSCNNConvolutionTranspose using
1058    /// the offset and other properties of corresponding MPSCNNConvolution object. During training, same MPSCNNConvolutionGradientState object will be consumed by MPSCNNConvolutionGradient
1059    /// object and the MPSCNNConvolutionTransposeGradientState produced by MPSCNNConvolutionTranspose's resultStateForSourceImage:sourceStates:destinationImage will be consumed by
1060    /// MPSCNNConvolutionTransposeGradient object
1061    ///
1062    /// Note that state objects are not usable across batches i.e. when batch is done you should nuke the state object and create
1063    /// new one for next batch.
1064    /// Weights update process for MPSCNNConvolutionTranspose is same as explained above for MPSCNNConvolution. See comments for MPSCNNConvolutionGradientState.
1065    ///
1066    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnconvolutiontransposegradientstate?language=objc)
1067    #[unsafe(super(MPSCNNConvolutionGradientState, MPSNNGradientState, MPSState, NSObject))]
1068    #[derive(Debug, PartialEq, Eq, Hash)]
1069    #[cfg(all(
1070        feature = "MPSCore",
1071        feature = "MPSNNGradientState",
1072        feature = "MPSState"
1073    ))]
1074    pub struct MPSCNNConvolutionTransposeGradientState;
1075);
1076
1077#[cfg(all(
1078    feature = "MPSCore",
1079    feature = "MPSNNGradientState",
1080    feature = "MPSNeuralNetworkTypes",
1081    feature = "MPSState"
1082))]
1083extern_conformance!(
1084    unsafe impl MPSImageSizeEncodingState for MPSCNNConvolutionTransposeGradientState {}
1085);
1086
1087#[cfg(all(
1088    feature = "MPSCore",
1089    feature = "MPSNNGradientState",
1090    feature = "MPSState"
1091))]
1092extern_conformance!(
1093    unsafe impl NSObjectProtocol for MPSCNNConvolutionTransposeGradientState {}
1094);
1095
1096#[cfg(all(
1097    feature = "MPSCore",
1098    feature = "MPSNNGradientState",
1099    feature = "MPSState"
1100))]
1101impl MPSCNNConvolutionTransposeGradientState {
1102    extern_methods!(
1103        #[cfg(all(feature = "MPSCNNKernel", feature = "MPSKernel"))]
1104        /// The convolutionTranspose filter that produced the state.
1105        #[unsafe(method(convolutionTranspose))]
1106        #[unsafe(method_family = none)]
1107        pub unsafe fn convolutionTranspose(&self) -> Retained<MPSCNNConvolutionTranspose>;
1108    );
1109}
1110
1111/// Methods declared on superclass `MPSState`.
1112#[cfg(all(
1113    feature = "MPSCore",
1114    feature = "MPSNNGradientState",
1115    feature = "MPSState"
1116))]
1117impl MPSCNNConvolutionTransposeGradientState {
1118    extern_methods!(
1119        /// Create a MPSState holding a temporary MTLBuffer
1120        ///
1121        /// Parameter `cmdBuf`: The command buffer against which the temporary resource is allocated
1122        ///
1123        /// Parameter `bufferSize`: The size of the buffer in bytes
1124        #[unsafe(method(temporaryStateWithCommandBuffer:bufferSize:))]
1125        #[unsafe(method_family = none)]
1126        pub unsafe fn temporaryStateWithCommandBuffer_bufferSize(
1127            cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
1128            buffer_size: usize,
1129        ) -> Retained<Self>;
1130
1131        /// Create a MPSState holding a temporary MTLTexture
1132        ///
1133        /// Parameter `cmdBuf`: The command buffer against which the temporary resource is allocated
1134        ///
1135        /// Parameter `descriptor`: A descriptor for the new temporary texture
1136        #[unsafe(method(temporaryStateWithCommandBuffer:textureDescriptor:))]
1137        #[unsafe(method_family = none)]
1138        pub unsafe fn temporaryStateWithCommandBuffer_textureDescriptor(
1139            cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
1140            descriptor: &MTLTextureDescriptor,
1141        ) -> Retained<Self>;
1142
1143        /// Create a new autoreleased temporary state object without underlying resource
1144        ///
1145        /// Parameter `cmdBuf`: The command buffer with which the temporary resource is associated
1146        #[unsafe(method(temporaryStateWithCommandBuffer:))]
1147        #[unsafe(method_family = none)]
1148        pub unsafe fn temporaryStateWithCommandBuffer(
1149            cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
1150        ) -> Retained<Self>;
1151
1152        #[unsafe(method(initWithDevice:bufferSize:))]
1153        #[unsafe(method_family = init)]
1154        pub unsafe fn initWithDevice_bufferSize(
1155            this: Allocated<Self>,
1156            device: &ProtocolObject<dyn MTLDevice>,
1157            buffer_size: usize,
1158        ) -> Retained<Self>;
1159
1160        #[unsafe(method(initWithDevice:textureDescriptor:))]
1161        #[unsafe(method_family = init)]
1162        pub unsafe fn initWithDevice_textureDescriptor(
1163            this: Allocated<Self>,
1164            device: &ProtocolObject<dyn MTLDevice>,
1165            descriptor: &MTLTextureDescriptor,
1166        ) -> Retained<Self>;
1167
1168        /// Create a MPSState with a non-temporary MTLResource
1169        ///
1170        /// Parameter `resource`: A MTLBuffer or MTLTexture. May be nil.
1171        ///
1172        /// # Safety
1173        ///
1174        /// - `resource` may need to be synchronized.
1175        /// - `resource` may be unretained, you must ensure it is kept alive while in use.
1176        #[unsafe(method(initWithResource:))]
1177        #[unsafe(method_family = init)]
1178        pub unsafe fn initWithResource(
1179            this: Allocated<Self>,
1180            resource: Option<&ProtocolObject<dyn MTLResource>>,
1181        ) -> Retained<Self>;
1182
1183        #[unsafe(method(init))]
1184        #[unsafe(method_family = init)]
1185        pub unsafe fn init(this: Allocated<Self>) -> Option<Retained<Self>>;
1186
1187        /// Initialize a non-temporary state to hold a number of textures and buffers
1188        ///
1189        /// The allocation of each resource will be deferred  until it is needed.
1190        /// This occurs when -resource or -resourceAtIndex: is called.
1191        ///
1192        /// Parameter `resourceList`: The list of resources to create.
1193        #[unsafe(method(initWithDevice:resourceList:))]
1194        #[unsafe(method_family = init)]
1195        pub unsafe fn initWithDevice_resourceList(
1196            this: Allocated<Self>,
1197            device: &ProtocolObject<dyn MTLDevice>,
1198            resource_list: &MPSStateResourceList,
1199        ) -> Retained<Self>;
1200
1201        /// Initialize a temporary state to hold a number of textures and buffers
1202        ///
1203        /// The textures occur first in sequence
1204        #[unsafe(method(temporaryStateWithCommandBuffer:resourceList:))]
1205        #[unsafe(method_family = none)]
1206        pub unsafe fn temporaryStateWithCommandBuffer_resourceList(
1207            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1208            resource_list: &MPSStateResourceList,
1209        ) -> Retained<Self>;
1210
1211        /// Create a state object with a list of MTLResources
1212        ///
1213        /// Because MPS prefers deferred allocation of resources
1214        /// your application should use -initWithTextures:bufferSizes:bufferCount:
1215        /// whenever possible. This method is useful for cases when the
1216        /// MTLResources must be initialized by the CPU.
1217        ///
1218        /// # Safety
1219        ///
1220        /// - `resources` generic may need to be synchronized.
1221        /// - `resources` generic may be unretained, you must ensure it is kept alive while in use.
1222        #[unsafe(method(initWithResources:))]
1223        #[unsafe(method_family = init)]
1224        pub unsafe fn initWithResources(
1225            this: Allocated<Self>,
1226            resources: Option<&NSArray<ProtocolObject<dyn MTLResource>>>,
1227        ) -> Retained<Self>;
1228    );
1229}
1230
1231/// Methods declared on superclass `NSObject`.
1232#[cfg(all(
1233    feature = "MPSCore",
1234    feature = "MPSNNGradientState",
1235    feature = "MPSState"
1236))]
1237impl MPSCNNConvolutionTransposeGradientState {
1238    extern_methods!(
1239        #[unsafe(method(new))]
1240        #[unsafe(method_family = new)]
1241        pub unsafe fn new() -> Retained<Self>;
1242    );
1243}
1244
1245/// [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnconvolutiontransposegradientstatebatch?language=objc)
1246#[cfg(all(
1247    feature = "MPSCore",
1248    feature = "MPSNNGradientState",
1249    feature = "MPSState"
1250))]
1251pub type MPSCNNConvolutionTransposeGradientStateBatch =
1252    NSArray<MPSCNNConvolutionTransposeGradientState>;
1253
1254extern_class!(
1255    /// The MPSCNNConvolutionWeightsAndBiasesState is returned by exportWeightsAndBiasesWithCommandBuffer: method on MPSCNNConvolution object.
1256    /// This is mainly used for GPU side weights/biases update process.
1257    /// During training, application can keep a copy of weights, velocity, momentum MTLBuffers in its data source, update the weights (in-place or out of place)
1258    /// with gradients obtained from MPSCNNConvolutionGradientState and call [MPSCNNConvolution reloadWeightsAndBiasesWithCommandBuffer] with resulting updated
1259    /// MTLBuffer. If application does not want to keep a copy of weights/biases, it can call [MPSCNNConvolution exportWeightsAndBiasesWithCommandBuffer:] to get
1260    /// the current weights from convolution itself, do the updated and call reloadWithCommandBuffer.
1261    ///
1262    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnconvolutionweightsandbiasesstate?language=objc)
1263    #[unsafe(super(MPSState, NSObject))]
1264    #[derive(Debug, PartialEq, Eq, Hash)]
1265    #[cfg(all(feature = "MPSCore", feature = "MPSState"))]
1266    pub struct MPSCNNConvolutionWeightsAndBiasesState;
1267);
1268
1269#[cfg(all(feature = "MPSCore", feature = "MPSState"))]
1270extern_conformance!(
1271    unsafe impl NSObjectProtocol for MPSCNNConvolutionWeightsAndBiasesState {}
1272);
1273
1274#[cfg(all(feature = "MPSCore", feature = "MPSState"))]
1275impl MPSCNNConvolutionWeightsAndBiasesState {
1276    extern_methods!(
1277        /// A buffer that contains the weights.
1278        /// Each value in the buffer is a float. The layout of the weights with respect to the weights is the same as
1279        /// the weights layout provided by data source i.e. it can be interpreted as 4D array
1280        ///
1281        /// weights[outputFeatureChannels][kernelHeight][kernelWidth][inputFeatureChannels/groups]
1282        /// for regular convolution. For depthwise convolution
1283        /// weights[outputFeatureChannels][kernelHeight][kernelWidth] as we currently only support channel multiplier of 1.
1284        #[unsafe(method(weights))]
1285        #[unsafe(method_family = none)]
1286        pub unsafe fn weights(&self) -> Retained<ProtocolObject<dyn MTLBuffer>>;
1287
1288        /// A buffer that contains the biases. Each value is float and there are ouputFeatureChannels values.
1289        #[unsafe(method(biases))]
1290        #[unsafe(method_family = none)]
1291        pub unsafe fn biases(&self) -> Option<Retained<ProtocolObject<dyn MTLBuffer>>>;
1292
1293        /// Offset at which weights start in weights buffer
1294        /// Default value is 0.
1295        #[unsafe(method(weightsOffset))]
1296        #[unsafe(method_family = none)]
1297        pub unsafe fn weightsOffset(&self) -> NSUInteger;
1298
1299        /// Offset at which weights start in biases buffer
1300        /// Default value is 0.
1301        #[unsafe(method(biasesOffset))]
1302        #[unsafe(method_family = none)]
1303        pub unsafe fn biasesOffset(&self) -> NSUInteger;
1304
1305        /// Create and initialize MPSCNNConvolutionWeightsAndBiasesState with application
1306        /// provided weights and biases buffers.
1307        ///
1308        /// This is the convinience API when buffers of exact size i.e.
1309        /// [weights length] =  inputFeatureChannels*kernelWidth*kernelHeight*channelMultiplier*sizeof(float)                   // for depthwise convolution
1310        /// outputFeatureChannels*kernelWidth*kernelHeight*(inputChannels/groups)*sizeof(float)      // for regular otherwise
1311        /// and [biases length]  =  outputFeatureChannels*sizeof(float)
1312        ///
1313        /// # Safety
1314        ///
1315        /// - `weights` may need to be synchronized.
1316        /// - `weights` may be unretained, you must ensure it is kept alive while in use.
1317        /// - `weights` contents should be of the correct type.
1318        /// - `biases` may need to be synchronized.
1319        /// - `biases` may be unretained, you must ensure it is kept alive while in use.
1320        /// - `biases` contents should be of the correct type.
1321        #[unsafe(method(initWithWeights:biases:))]
1322        #[unsafe(method_family = init)]
1323        pub unsafe fn initWithWeights_biases(
1324            this: Allocated<Self>,
1325            weights: &ProtocolObject<dyn MTLBuffer>,
1326            biases: Option<&ProtocolObject<dyn MTLBuffer>>,
1327        ) -> Retained<Self>;
1328
1329        /// Create and initialize MPSCNNConvolutionWeightsAndBiasesState with application provided convolution descriptor
1330        ///
1331        /// Create weights and biases buffers of appropriate size
1332        #[unsafe(method(initWithDevice:cnnConvolutionDescriptor:))]
1333        #[unsafe(method_family = init)]
1334        pub unsafe fn initWithDevice_cnnConvolutionDescriptor(
1335            this: Allocated<Self>,
1336            device: &ProtocolObject<dyn MTLDevice>,
1337            descriptor: &MPSCNNConvolutionDescriptor,
1338        ) -> Retained<Self>;
1339
1340        /// Create and initialize temporary MPSCNNConvolutionWeightsAndBiasesState with application provided convolution descriptor
1341        ///
1342        /// Create weights and biases buffers of appropriate size from command buffer cache.
1343        #[unsafe(method(temporaryCNNConvolutionWeightsAndBiasesStateWithCommandBuffer:cnnConvolutionDescriptor:))]
1344        #[unsafe(method_family = none)]
1345        pub unsafe fn temporaryCNNConvolutionWeightsAndBiasesStateWithCommandBuffer_cnnConvolutionDescriptor(
1346            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1347            descriptor: &MPSCNNConvolutionDescriptor,
1348        ) -> Retained<Self>;
1349
1350        /// Create and initialize MPSCNNConvolutionWeightsAndBiasesState with application
1351        /// provided weights and biases buffers.
1352        ///
1353        /// It gives finer allocation control to application e.g. application can pass same buffer for weights and biases with
1354        /// appropriate offsets. Or offset into some larger buffer from application managed heap etc. Number of weights
1355        /// and biases or the length of weights and biases buffer this object owns (will read or write to), starting at offset is
1356        /// determined by MPSCNNConvolutionDescriptor passed in.
1357        /// weightsLength =  inputFeatureChannels*kernelWidth*kernelHeight*channelMultiplier*sizeof(float)                   // for depthwise convolution
1358        /// outputFeatureChannels*kernelWidth*kernelHeight*(inputChannels/groups)*sizeof(float)      // for regular otherwise
1359        /// biasesLength  =  outputFeatureChannels*sizeof(float)
1360        /// Thus filters operating on this object will read or write to NSRange(weightsOffset, weightsLength) of weights buffer
1361        /// and NSRange(biasesOffset, biasesLength) of biases buffer. Thus sizes of buffers provided must be such that
1362        /// weightsOffset + weightsLength
1363        /// <
1364        /// = [weights length]
1365        /// and     biasesOffset + biasesLength
1366        /// <
1367        /// = [biases length]
1368        /// Offsets must of sizeof(float) aligned i.e. multiple of 4.
1369        ///
1370        /// # Safety
1371        ///
1372        /// - `weights` may need to be synchronized.
1373        /// - `weights` may be unretained, you must ensure it is kept alive while in use.
1374        /// - `weights` contents should be of the correct type.
1375        /// - `biases` may need to be synchronized.
1376        /// - `biases` may be unretained, you must ensure it is kept alive while in use.
1377        /// - `biases` contents should be of the correct type.
1378        #[unsafe(method(initWithWeights:weightsOffset:biases:biasesOffset:cnnConvolutionDescriptor:))]
1379        #[unsafe(method_family = init)]
1380        pub unsafe fn initWithWeights_weightsOffset_biases_biasesOffset_cnnConvolutionDescriptor(
1381            this: Allocated<Self>,
1382            weights: &ProtocolObject<dyn MTLBuffer>,
1383            weights_offset: NSUInteger,
1384            biases: Option<&ProtocolObject<dyn MTLBuffer>>,
1385            biases_offset: NSUInteger,
1386            descriptor: &MPSCNNConvolutionDescriptor,
1387        ) -> Retained<Self>;
1388    );
1389}
1390
1391/// Methods declared on superclass `MPSState`.
1392#[cfg(all(feature = "MPSCore", feature = "MPSState"))]
1393impl MPSCNNConvolutionWeightsAndBiasesState {
1394    extern_methods!(
1395        /// Create a MPSState holding a temporary MTLBuffer
1396        ///
1397        /// Parameter `cmdBuf`: The command buffer against which the temporary resource is allocated
1398        ///
1399        /// Parameter `bufferSize`: The size of the buffer in bytes
1400        #[unsafe(method(temporaryStateWithCommandBuffer:bufferSize:))]
1401        #[unsafe(method_family = none)]
1402        pub unsafe fn temporaryStateWithCommandBuffer_bufferSize(
1403            cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
1404            buffer_size: usize,
1405        ) -> Retained<Self>;
1406
1407        /// Create a MPSState holding a temporary MTLTexture
1408        ///
1409        /// Parameter `cmdBuf`: The command buffer against which the temporary resource is allocated
1410        ///
1411        /// Parameter `descriptor`: A descriptor for the new temporary texture
1412        #[unsafe(method(temporaryStateWithCommandBuffer:textureDescriptor:))]
1413        #[unsafe(method_family = none)]
1414        pub unsafe fn temporaryStateWithCommandBuffer_textureDescriptor(
1415            cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
1416            descriptor: &MTLTextureDescriptor,
1417        ) -> Retained<Self>;
1418
1419        /// Create a new autoreleased temporary state object without underlying resource
1420        ///
1421        /// Parameter `cmdBuf`: The command buffer with which the temporary resource is associated
1422        #[unsafe(method(temporaryStateWithCommandBuffer:))]
1423        #[unsafe(method_family = none)]
1424        pub unsafe fn temporaryStateWithCommandBuffer(
1425            cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
1426        ) -> Retained<Self>;
1427
1428        #[unsafe(method(initWithDevice:bufferSize:))]
1429        #[unsafe(method_family = init)]
1430        pub unsafe fn initWithDevice_bufferSize(
1431            this: Allocated<Self>,
1432            device: &ProtocolObject<dyn MTLDevice>,
1433            buffer_size: usize,
1434        ) -> Retained<Self>;
1435
1436        #[unsafe(method(initWithDevice:textureDescriptor:))]
1437        #[unsafe(method_family = init)]
1438        pub unsafe fn initWithDevice_textureDescriptor(
1439            this: Allocated<Self>,
1440            device: &ProtocolObject<dyn MTLDevice>,
1441            descriptor: &MTLTextureDescriptor,
1442        ) -> Retained<Self>;
1443
1444        /// Create a MPSState with a non-temporary MTLResource
1445        ///
1446        /// Parameter `resource`: A MTLBuffer or MTLTexture. May be nil.
1447        ///
1448        /// # Safety
1449        ///
1450        /// - `resource` may need to be synchronized.
1451        /// - `resource` may be unretained, you must ensure it is kept alive while in use.
1452        #[unsafe(method(initWithResource:))]
1453        #[unsafe(method_family = init)]
1454        pub unsafe fn initWithResource(
1455            this: Allocated<Self>,
1456            resource: Option<&ProtocolObject<dyn MTLResource>>,
1457        ) -> Retained<Self>;
1458
1459        #[unsafe(method(init))]
1460        #[unsafe(method_family = init)]
1461        pub unsafe fn init(this: Allocated<Self>) -> Option<Retained<Self>>;
1462
1463        /// Initialize a non-temporary state to hold a number of textures and buffers
1464        ///
1465        /// The allocation of each resource will be deferred  until it is needed.
1466        /// This occurs when -resource or -resourceAtIndex: is called.
1467        ///
1468        /// Parameter `resourceList`: The list of resources to create.
1469        #[unsafe(method(initWithDevice:resourceList:))]
1470        #[unsafe(method_family = init)]
1471        pub unsafe fn initWithDevice_resourceList(
1472            this: Allocated<Self>,
1473            device: &ProtocolObject<dyn MTLDevice>,
1474            resource_list: &MPSStateResourceList,
1475        ) -> Retained<Self>;
1476
1477        /// Initialize a temporary state to hold a number of textures and buffers
1478        ///
1479        /// The textures occur first in sequence
1480        #[unsafe(method(temporaryStateWithCommandBuffer:resourceList:))]
1481        #[unsafe(method_family = none)]
1482        pub unsafe fn temporaryStateWithCommandBuffer_resourceList(
1483            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1484            resource_list: &MPSStateResourceList,
1485        ) -> Retained<Self>;
1486
1487        /// Create a state object with a list of MTLResources
1488        ///
1489        /// Because MPS prefers deferred allocation of resources
1490        /// your application should use -initWithTextures:bufferSizes:bufferCount:
1491        /// whenever possible. This method is useful for cases when the
1492        /// MTLResources must be initialized by the CPU.
1493        ///
1494        /// # Safety
1495        ///
1496        /// - `resources` generic may need to be synchronized.
1497        /// - `resources` generic may be unretained, you must ensure it is kept alive while in use.
1498        #[unsafe(method(initWithResources:))]
1499        #[unsafe(method_family = init)]
1500        pub unsafe fn initWithResources(
1501            this: Allocated<Self>,
1502            resources: Option<&NSArray<ProtocolObject<dyn MTLResource>>>,
1503        ) -> Retained<Self>;
1504    );
1505}
1506
1507/// Methods declared on superclass `NSObject`.
1508#[cfg(all(feature = "MPSCore", feature = "MPSState"))]
1509impl MPSCNNConvolutionWeightsAndBiasesState {
1510    extern_methods!(
1511        #[unsafe(method(new))]
1512        #[unsafe(method_family = new)]
1513        pub unsafe fn new() -> Retained<Self>;
1514    );
1515}
1516
1517extern_protocol!(
1518    /// Provides convolution filter weights and bias terms
1519    ///
1520    /// The MPSCNNConvolutionDataSource protocol declares the methods that an
1521    /// instance of MPSCNNConvolution uses to obtain the weights and bias terms
1522    /// for the CNN convolution filter.
1523    ///
1524    /// Why? CNN weights can be large. If multiple copies of all the weights
1525    /// for all the convolutions are available unpacked in memory at the same
1526    /// time, some devices can run out of memory. The MPSCNNConvolutionDataSource
1527    /// is used to encapsulate a reference to the weights such as a file path,
1528    /// so that unpacking can be deferred until needed, then purged soon thereafter
1529    /// so that not all of the data must be in memory at the same time.
1530    /// MPS does not provide a class that conforms to this protocol. It is up to
1531    /// the developer to craft his own to encapsulate his data.
1532    ///
1533    /// Batch normalization and the neuron activation function are handled using the
1534    /// -descriptor method.
1535    ///
1536    /// Thread safety: The MPSCNNConvolutionDataSource object can be called by
1537    /// threads that are not the main thread. If you will be creating multiple
1538    /// MPSNNGraph objects concurrently in multiple threads and these share
1539    /// MPSCNNConvolutionDataSources, then the data source objects may be called
1540    /// reentrantly.
1541    ///
1542    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnconvolutiondatasource?language=objc)
1543    pub unsafe trait MPSCNNConvolutionDataSource: NSCopying + NSObjectProtocol {
1544        #[cfg(all(feature = "MPSCore", feature = "MPSCoreTypes"))]
1545        /// Alerts MPS what sort of weights are provided by the object
1546        ///
1547        /// For MPSCNNConvolution, MPSDataTypeUInt8, MPSDataTypeFloat16
1548        /// and MPSDataTypeFloat32 are supported for normal convolutions
1549        /// using MPSCNNConvolution. MPSCNNBinaryConvolution assumes weights to be
1550        /// of type MPSDataTypeUInt32 always.
1551        #[unsafe(method(dataType))]
1552        #[unsafe(method_family = none)]
1553        unsafe fn dataType(&self) -> MPSDataType;
1554
1555        /// Return a MPSCNNConvolutionDescriptor as needed
1556        ///
1557        /// MPS will not modify this object other than perhaps to retain it.
1558        /// User should set the appropriate neuron in the creation of convolution descriptor
1559        /// and for batch normalization use:
1560        ///
1561        /// ```text
1562        ///        
1563        ///               -setBatchNormalizationParametersForInferenceWithMean:variance:gamma:beta:epsilon:
1564        /// ```
1565        ///
1566        ///
1567        /// Returns: A MPSCNNConvolutionDescriptor that describes the kernel housed by this object.
1568        #[unsafe(method(descriptor))]
1569        #[unsafe(method_family = none)]
1570        unsafe fn descriptor(&self) -> Retained<MPSCNNConvolutionDescriptor>;
1571
1572        /// Returns a pointer to the weights for the convolution.
1573        ///
1574        /// The type of each entry in array is given by -dataType. The number
1575        /// of entries is equal to:
1576        ///
1577        /// ```text
1578        ///                   inputFeatureChannels * outputFeatureChannels * kernelHeight * kernelWidth
1579        /// ```
1580        ///
1581        /// The layout of filter weight is as a 4D tensor (array)
1582        /// weight[ outputChannels ][ kernelHeight ][ kernelWidth ][ inputChannels / groups ]
1583        ///
1584        /// Frequently, this function is a single line of code to return
1585        /// a pointer to memory allocated in -load.
1586        ///
1587        /// Batch normalization parameters are set using -descriptor.
1588        ///
1589        /// Note: For binary-convolutions the layout of the weights are:
1590        /// weight[ outputChannels ][ kernelHeight ][ kernelWidth ][ floor((inputChannels/groups)+31) / 32 ]
1591        /// with each 32 sub input feature channel index specified in machine byte order, so that for example
1592        /// the 13th feature channel bit can be extracted using bitmask = (1U
1593        /// <
1594        /// <
1595        /// 13).
1596        #[unsafe(method(weights))]
1597        #[unsafe(method_family = none)]
1598        unsafe fn weights(&self) -> NonNull<c_void>;
1599
1600        /// Returns a pointer to the bias terms for the convolution.
1601        ///
1602        /// Each entry in the array is a single precision IEEE-754 float
1603        /// and represents one bias. The number of entries is equal
1604        /// to outputFeatureChannels.
1605        ///
1606        /// Frequently, this function is a single line of code to return
1607        /// a pointer to memory allocated in -load. It may also just
1608        /// return nil.
1609        ///
1610        /// Note: bias terms are always float, even when the weights are not.
1611        #[unsafe(method(biasTerms))]
1612        #[unsafe(method_family = none)]
1613        unsafe fn biasTerms(&self) -> *mut c_float;
1614
1615        /// Alerts the data source that the data will be needed soon
1616        ///
1617        /// Each load alert will be balanced by a purge later, when MPS
1618        /// no longer needs the data from this object.
1619        /// Load will always be called atleast once after initial construction
1620        /// or each purge of the object before anything else is called.
1621        /// Note: load may be called to merely inspect the descriptor.
1622        /// In some circumstances, it may be worthwhile to postpone
1623        /// weight and bias construction until they are actually needed
1624        /// to save touching memory and keep the working set small.
1625        /// The load function is intended to be an opportunity to open
1626        /// files or mark memory no longer purgeable.
1627        ///
1628        /// Returns: Returns YES on success.  If NO is returned, expect MPS
1629        /// object construction to fail.
1630        #[unsafe(method(load))]
1631        #[unsafe(method_family = none)]
1632        unsafe fn load(&self) -> bool;
1633
1634        /// Alerts the data source that the data is no longer needed
1635        ///
1636        /// Each load alert will be balanced by a purge later, when MPS
1637        /// no longer needs the data from this object.
1638        #[unsafe(method(purge))]
1639        #[unsafe(method_family = none)]
1640        unsafe fn purge(&self);
1641
1642        /// A label that is transferred to the convolution at init time
1643        ///
1644        /// Overridden by a MPSCNNConvolutionNode.label if it is non-nil.
1645        #[unsafe(method(label))]
1646        #[unsafe(method_family = none)]
1647        unsafe fn label(&self) -> Option<Retained<NSString>>;
1648
1649        /// A pointer to a 256 entry lookup table containing the values to use for the weight range [0,255]
1650        #[optional]
1651        #[unsafe(method(lookupTableForUInt8Kernel))]
1652        #[unsafe(method_family = none)]
1653        unsafe fn lookupTableForUInt8Kernel(&self) -> NonNull<c_float>;
1654
1655        /// Quantizaiton type of weights. If it returns MPSCNNWeightsQuantizationTypeLookupTable,
1656        /// lookupTableForUInt8Kernel method must be implmented. if it returns MPSCNNWeightsQuantizationTypeLookupLinear,
1657        /// rangesForUInt8Kernel method must be implemented.
1658        #[optional]
1659        #[unsafe(method(weightsQuantizationType))]
1660        #[unsafe(method_family = none)]
1661        unsafe fn weightsQuantizationType(&self) -> MPSCNNWeightsQuantizationType;
1662
1663        #[cfg(all(
1664            feature = "MPSCore",
1665            feature = "MPSNNGradientState",
1666            feature = "MPSState"
1667        ))]
1668        /// Callback for the MPSNNGraph to update the convolution weights on GPU.
1669        ///
1670        /// It is the resposibility of this method to decrement the read count of both the gradientState
1671        /// and the sourceState before returning.  BUG: prior to macOS 10.14, ios/tvos 12.0, the MPSNNGraph
1672        /// incorrectly decrements the readcount of the gradientState after this method is called.
1673        ///
1674        ///
1675        /// Parameter `commandBuffer`: The command buffer on which to do the update.
1676        /// MPSCNNConvolutionGradientNode.MPSNNTrainingStyle controls where you want your update
1677        /// to happen. Provide implementation of this function for GPU side update.
1678        ///
1679        /// Parameter `gradientState`: A state object produced by the MPSCNNConvolution and updated by MPSCNNConvolutionGradient
1680        /// containing weight gradients.
1681        ///
1682        /// Parameter `sourceState`: A state object containing the convolution weights
1683        ///
1684        /// Returns: If NULL, no update occurs. If nonnull, the result will be used to update the
1685        /// weights in the MPSNNGraph
1686        #[optional]
1687        #[unsafe(method(updateWithCommandBuffer:gradientState:sourceState:))]
1688        #[unsafe(method_family = none)]
1689        unsafe fn updateWithCommandBuffer_gradientState_sourceState(
1690            &self,
1691            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1692            gradient_state: &MPSCNNConvolutionGradientState,
1693            source_state: &MPSCNNConvolutionWeightsAndBiasesState,
1694        ) -> Option<Retained<MPSCNNConvolutionWeightsAndBiasesState>>;
1695
1696        #[cfg(all(
1697            feature = "MPSCore",
1698            feature = "MPSNNGradientState",
1699            feature = "MPSState"
1700        ))]
1701        /// Callback for the MPSNNGraph to update the convolution weights on CPU.
1702        /// MPSCNNConvolutionGradientNode.MPSNNTrainingStyle controls where you want your update
1703        /// to happen. Provide implementation of this function for CPU side update.
1704        ///
1705        /// Parameter `gradientState`: A state object produced by the MPSCNNConvolution and updated by MPSCNNConvolutionGradient
1706        /// containing weight gradients. MPSNNGraph is responsible for calling [gradientState synchronizeOnCommandBuffer:]
1707        /// so that application get correct gradients for CPU side update.
1708        ///
1709        /// Parameter `sourceState`: A state object containing the convolution weights used. MPSCNNConvolution and MPSCNNConvolutionGradient reloadWeightsWithDataSource
1710        /// will be called right after this method is called. Note that the weights returned here may not match the weights
1711        /// in your data source due to conversion loss. These are the weights actually used, and should
1712        /// be what you use to calculate the new weights. Your copy may be incorrect. Write the new weights
1713        /// to your copy and return them out the left hand side.
1714        ///
1715        /// Returns: TRUE if success/no error, FALSE in case of failure.
1716        #[optional]
1717        #[unsafe(method(updateWithGradientState:sourceState:))]
1718        #[unsafe(method_family = none)]
1719        unsafe fn updateWithGradientState_sourceState(
1720            &self,
1721            gradient_state: &MPSCNNConvolutionGradientState,
1722            source_state: &MPSCNNConvolutionWeightsAndBiasesState,
1723        ) -> bool;
1724
1725        /// When copyWithZone:device on convolution is called, data source copyWithZone:device
1726        /// will be called if data source object responds to this selector. If not, copyWithZone:
1727        /// will be called if data source responds to it. Otherwise, it is simply retained.
1728        /// This is to allow application to make a separate copy of data source in convolution
1729        /// when convolution itself is coplied, for example when copying training graph for running
1730        /// on second GPU so that weights update on two different GPUs dont end up stomping same
1731        /// data source.
1732        ///
1733        /// # Safety
1734        ///
1735        /// `zone` must be a valid pointer or null.
1736        #[optional]
1737        #[unsafe(method(copyWithZone:device:))]
1738        #[unsafe(method_family = copy)]
1739        unsafe fn copyWithZone_device(
1740            &self,
1741            zone: *mut NSZone,
1742            device: Option<&ProtocolObject<dyn MTLDevice>>,
1743        ) -> Retained<Self>;
1744
1745        /// Layout of weights returned by data source. Currently only OHWI layout is supported which is default.
1746        /// See MPSCNNConvolutionWeightsLayout above.
1747        #[optional]
1748        #[unsafe(method(weightsLayout))]
1749        #[unsafe(method_family = none)]
1750        unsafe fn weightsLayout(&self) -> MPSCNNConvolutionWeightsLayout;
1751
1752        #[cfg(all(feature = "MPSCore", feature = "MPSCoreTypes"))]
1753        /// Alerts MPS what weight precision to use in the CNNConvolution kernel
1754        ///
1755        /// If precision of weights returned by dataType does not match precision returned by
1756        /// kernelWeightsDataType, weights are converted to precision specified by kernelWeightsDataType
1757        /// before being passed to kernel.
1758        /// For MPSCNNConvolution, dataType precisions of MPSDataTypeUInt8 or MPSDataTypeFloat16
1759        /// must return a kernelWeightsDataType of MPSDataTypeFloat16. dataType precisions of
1760        /// MPSDataTypeFloat32 may return kernelWeightsDataType of MPSDataTypeFloat16 or
1761        /// MPSDataTypeFloat32. When kernelWeightsDataType returns MPSDataTypeFloat32 the
1762        /// accumulatorPrecisionOption on the CNNConvolution object must be set to
1763        /// MPSNNConvolutionAccumulatorPrecisionOptionFloat.
1764        /// When kernelWeightsDataType is unimplemented the kernel will use float16 precision.
1765        /// MPSCNNBinaryConvolution assumes weights to be of type MPSDataTypeUInt32 always,
1766        /// and the kernelWeightsDataType is unused.
1767        #[optional]
1768        #[unsafe(method(kernelWeightsDataType))]
1769        #[unsafe(method_family = none)]
1770        unsafe fn kernelWeightsDataType(&self) -> MPSDataType;
1771    }
1772);
1773
1774extern_class!(
1775    /// Dependencies: This depends on Metal.framework
1776    ///
1777    /// The MPSCNNConvolution specifies a convolution.
1778    /// The MPSCNNConvolution convolves the input image with a set of filters, each producing one feature map in the output image.
1779    ///
1780    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnconvolution?language=objc)
1781    #[unsafe(super(MPSCNNKernel, MPSKernel, NSObject))]
1782    #[derive(Debug, PartialEq, Eq, Hash)]
1783    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1784    pub struct MPSCNNConvolution;
1785);
1786
1787#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1788extern_conformance!(
1789    unsafe impl NSCoding for MPSCNNConvolution {}
1790);
1791
1792#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1793extern_conformance!(
1794    unsafe impl NSCopying for MPSCNNConvolution {}
1795);
1796
1797#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1798unsafe impl CopyingHelper for MPSCNNConvolution {
1799    type Result = Self;
1800}
1801
1802#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1803extern_conformance!(
1804    unsafe impl NSObjectProtocol for MPSCNNConvolution {}
1805);
1806
1807#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1808extern_conformance!(
1809    unsafe impl NSSecureCoding for MPSCNNConvolution {}
1810);
1811
1812#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1813impl MPSCNNConvolution {
1814    extern_methods!(
1815        /// The number of feature channels per pixel in the input image.
1816        #[unsafe(method(inputFeatureChannels))]
1817        #[unsafe(method_family = none)]
1818        pub unsafe fn inputFeatureChannels(&self) -> NSUInteger;
1819
1820        /// The number of feature channels per pixel in the output image.
1821        #[unsafe(method(outputFeatureChannels))]
1822        #[unsafe(method_family = none)]
1823        pub unsafe fn outputFeatureChannels(&self) -> NSUInteger;
1824
1825        /// Number of groups input and output channels are divided into.
1826        #[unsafe(method(groups))]
1827        #[unsafe(method_family = none)]
1828        pub unsafe fn groups(&self) -> NSUInteger;
1829
1830        /// dataSource with which convolution object was created
1831        #[unsafe(method(dataSource))]
1832        #[unsafe(method_family = none)]
1833        pub unsafe fn dataSource(
1834            &self,
1835        ) -> Retained<ProtocolObject<dyn MPSCNNConvolutionDataSource>>;
1836
1837        /// Sub pixel scale factor which was passed in as part of MPSCNNConvolutionDescriptor when creating this MPSCNNConvolution object.
1838        #[unsafe(method(subPixelScaleFactor))]
1839        #[unsafe(method_family = none)]
1840        pub unsafe fn subPixelScaleFactor(&self) -> NSUInteger;
1841
1842        #[cfg(feature = "MPSCNNNeuron")]
1843        /// MPSCNNNeuron filter to be applied as part of convolution.
1844        /// Can be nil in wich case no neuron activation fuction is applied.
1845        #[deprecated]
1846        #[unsafe(method(neuron))]
1847        #[unsafe(method_family = none)]
1848        pub unsafe fn neuron(&self) -> Option<Retained<MPSCNNNeuron>>;
1849
1850        #[cfg(feature = "MPSCNNNeuronType")]
1851        /// The type of neuron to append to the convolution
1852        ///
1853        /// Please see class description for a full list. Default is MPSCNNNeuronTypeNone.
1854        #[deprecated]
1855        #[unsafe(method(neuronType))]
1856        #[unsafe(method_family = none)]
1857        pub unsafe fn neuronType(&self) -> MPSCNNNeuronType;
1858
1859        /// Parameter "a" for the neuron.  Default: 1.0f
1860        ///
1861        /// Please see class description for interpretation of a.
1862        #[deprecated]
1863        #[unsafe(method(neuronParameterA))]
1864        #[unsafe(method_family = none)]
1865        pub unsafe fn neuronParameterA(&self) -> c_float;
1866
1867        /// Parameter "b" for the neuron.  Default: 1.0f
1868        ///
1869        /// Please see class description for interpretation of b.
1870        #[deprecated]
1871        #[unsafe(method(neuronParameterB))]
1872        #[unsafe(method_family = none)]
1873        pub unsafe fn neuronParameterB(&self) -> c_float;
1874
1875        /// Parameter "c" for the neuron.  Default: 1.0f
1876        ///
1877        /// Please see class description for interpretation of c.
1878        #[deprecated]
1879        #[unsafe(method(neuronParameterC))]
1880        #[unsafe(method_family = none)]
1881        pub unsafe fn neuronParameterC(&self) -> c_float;
1882
1883        #[cfg(feature = "MPSCNNNeuron")]
1884        /// Fused neuron descritor passed in convolution descriptor for fusion with convolution.
1885        ///
1886        /// Please see class description for interpretation of c.
1887        #[unsafe(method(fusedNeuronDescriptor))]
1888        #[unsafe(method_family = none)]
1889        pub unsafe fn fusedNeuronDescriptor(&self) -> Option<Retained<MPSNNNeuronDescriptor>>;
1890
1891        /// Channel multiplier.
1892        ///
1893        /// For convolution created with MPSCNNDepthWiseConvolutionDescriptor, it is the number of
1894        /// output feature channels for each input channel. See MPSCNNDepthWiseConvolutionDescriptor for more details.
1895        /// Default is 0 which means regular CNN convolution.
1896        #[unsafe(method(channelMultiplier))]
1897        #[unsafe(method_family = none)]
1898        pub unsafe fn channelMultiplier(&self) -> NSUInteger;
1899
1900        #[cfg(feature = "MPSNeuralNetworkTypes")]
1901        /// Precision of accumulator used in convolution.
1902        ///
1903        /// See MPSNeuralNetworkTypes.h for discussion. Default is MPSNNConvolutionAccumulatorPrecisionOptionFloat.
1904        #[unsafe(method(accumulatorPrecisionOption))]
1905        #[unsafe(method_family = none)]
1906        pub unsafe fn accumulatorPrecisionOption(
1907            &self,
1908        ) -> MPSNNConvolutionAccumulatorPrecisionOption;
1909
1910        #[cfg(feature = "MPSNeuralNetworkTypes")]
1911        /// Setter for [`accumulatorPrecisionOption`][Self::accumulatorPrecisionOption].
1912        #[unsafe(method(setAccumulatorPrecisionOption:))]
1913        #[unsafe(method_family = none)]
1914        pub unsafe fn setAccumulatorPrecisionOption(
1915            &self,
1916            accumulator_precision_option: MPSNNConvolutionAccumulatorPrecisionOption,
1917        );
1918
1919        /// Initializes a convolution kernel
1920        ///
1921        /// Parameter `device`: The MTLDevice on which this MPSCNNConvolution filter will be used
1922        ///
1923        /// Parameter `weights`: A pointer to a object that conforms to the MPSCNNConvolutionDataSource
1924        /// protocol. The MPSCNNConvolutionDataSource protocol declares the methods that an
1925        /// instance of MPSCNNConvolution uses to obtain the weights and bias terms
1926        /// for the CNN convolution filter.
1927        ///
1928        ///
1929        /// Returns: A valid MPSCNNConvolution object or nil, if failure.
1930        #[unsafe(method(initWithDevice:weights:))]
1931        #[unsafe(method_family = init)]
1932        pub unsafe fn initWithDevice_weights(
1933            this: Allocated<Self>,
1934            device: &ProtocolObject<dyn MTLDevice>,
1935            weights: &ProtocolObject<dyn MPSCNNConvolutionDataSource>,
1936        ) -> Retained<Self>;
1937
1938        #[cfg(feature = "MPSNeuralNetworkTypes")]
1939        /// Initializes a convolution kernel
1940        /// WARNING:                        This API is depreated and will be removed in the future. It cannot be used
1941        /// when training. Also serialization/unserialization wont work for MPSCNNConvolution
1942        /// objects created with this init. Please move onto using initWithDevice:weights:.
1943        ///
1944        /// Parameter `device`: The MTLDevice on which this MPSCNNConvolution filter will be used
1945        ///
1946        /// Parameter `convolutionDescriptor`: A pointer to a MPSCNNConvolutionDescriptor.
1947        ///
1948        /// Parameter `kernelWeights`: A pointer to a weights array.  Each entry is a float value. The number of entries is =
1949        /// inputFeatureChannels * outputFeatureChannels * kernelHeight * kernelWidth
1950        /// The layout of filter weight is so that it can be reinterpreted as 4D tensor (array)
1951        /// weight[ outputChannels ][ kernelHeight ][ kernelWidth ][ inputChannels / groups ]
1952        /// Weights are converted to half float (fp16) internally for best performance.
1953        ///
1954        /// Parameter `biasTerms`: A pointer to bias terms to be applied to the convolution output.  Each entry is a float value.
1955        /// The number of entries is = numberOfOutputFeatureMaps
1956        ///
1957        /// Parameter `flags`: Currently unused. Pass MPSCNNConvolutionFlagsNone
1958        ///
1959        ///
1960        /// Returns: A valid MPSCNNConvolution object or nil, if failure.
1961        ///
1962        /// # Safety
1963        ///
1964        /// - `kernel_weights` must be a valid pointer.
1965        /// - `bias_terms` must be a valid pointer or null.
1966        #[deprecated]
1967        #[unsafe(method(initWithDevice:convolutionDescriptor:kernelWeights:biasTerms:flags:))]
1968        #[unsafe(method_family = init)]
1969        pub unsafe fn initWithDevice_convolutionDescriptor_kernelWeights_biasTerms_flags(
1970            this: Allocated<Self>,
1971            device: &ProtocolObject<dyn MTLDevice>,
1972            convolution_descriptor: &MPSCNNConvolutionDescriptor,
1973            kernel_weights: NonNull<c_float>,
1974            bias_terms: *const c_float,
1975            flags: MPSCNNConvolutionFlags,
1976        ) -> Retained<Self>;
1977
1978        /// NSSecureCoding compatability
1979        ///
1980        /// While the standard NSSecureCoding/NSCoding method
1981        /// -initWithCoder: should work, since the file can't
1982        /// know which device your data is allocated on, we
1983        /// have to guess and may guess incorrectly.  To avoid
1984        /// that problem, use initWithCoder:device instead.
1985        ///
1986        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
1987        ///
1988        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
1989        ///
1990        /// Returns: A new MPSKernel object, or nil if failure.
1991        ///
1992        /// # Safety
1993        ///
1994        /// `a_decoder` possibly has further requirements.
1995        #[unsafe(method(initWithCoder:device:))]
1996        #[unsafe(method_family = init)]
1997        pub unsafe fn initWithCoder_device(
1998            this: Allocated<Self>,
1999            a_decoder: &NSCoder,
2000            device: &ProtocolObject<dyn MTLDevice>,
2001        ) -> Option<Retained<Self>>;
2002
2003        #[unsafe(method(initWithDevice:))]
2004        #[unsafe(method_family = init)]
2005        pub unsafe fn initWithDevice(
2006            this: Allocated<Self>,
2007            device: &ProtocolObject<dyn MTLDevice>,
2008        ) -> Retained<Self>;
2009
2010        #[cfg(all(
2011            feature = "MPSImage",
2012            feature = "MPSNNGradientState",
2013            feature = "MPSState"
2014        ))]
2015        /// Allocate a MPCNNConvolutionGradientSState to hold the results from a -encodeBatchToCommandBuffer... operation
2016        ///
2017        ///
2018        /// Parameter `sourceImage`: The MPSImage consumed by the associated -encode call.
2019        ///
2020        /// Parameter `sourceStates`: The list of MPSStates consumed by the associated -encode call,
2021        /// for a batch size of 1.
2022        ///
2023        /// Returns: The list of states produced by the -encode call for batch size of 1.
2024        /// -isResultStateReusedAcrossBatch returns YES for MPSCNNConvolution so same
2025        /// state is used across entire batch. State object is not reusasable across batches.
2026        #[unsafe(method(resultStateForSourceImage:sourceStates:destinationImage:))]
2027        #[unsafe(method_family = none)]
2028        pub unsafe fn resultStateForSourceImage_sourceStates_destinationImage(
2029            &self,
2030            source_image: &MPSImage,
2031            source_states: Option<&NSArray<MPSState>>,
2032            destination_image: &MPSImage,
2033        ) -> Option<Retained<MPSCNNConvolutionGradientState>>;
2034
2035        #[cfg(all(
2036            feature = "MPSImage",
2037            feature = "MPSNDArray",
2038            feature = "MPSNNGradientState",
2039            feature = "MPSState"
2040        ))]
2041        #[unsafe(method(resultStateBatchForSourceImage:sourceStates:destinationImage:))]
2042        #[unsafe(method_family = none)]
2043        pub unsafe fn resultStateBatchForSourceImage_sourceStates_destinationImage(
2044            &self,
2045            source_image: &MPSImageBatch,
2046            source_states: Option<&NSArray<MPSStateBatch>>,
2047            destination_image: &MPSImageBatch,
2048        ) -> Option<Retained<MPSCNNConvolutionGradientStateBatch>>;
2049
2050        #[cfg(all(
2051            feature = "MPSImage",
2052            feature = "MPSNNGradientState",
2053            feature = "MPSState"
2054        ))]
2055        #[unsafe(method(temporaryResultStateForCommandBuffer:sourceImage:sourceStates:destinationImage:))]
2056        #[unsafe(method_family = none)]
2057        pub unsafe fn temporaryResultStateForCommandBuffer_sourceImage_sourceStates_destinationImage(
2058            &self,
2059            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2060            source_image: &MPSImage,
2061            source_states: Option<&NSArray<MPSState>>,
2062            destination_image: &MPSImage,
2063        ) -> Option<Retained<MPSCNNConvolutionGradientState>>;
2064
2065        #[cfg(all(
2066            feature = "MPSImage",
2067            feature = "MPSNDArray",
2068            feature = "MPSNNGradientState",
2069            feature = "MPSState"
2070        ))]
2071        #[unsafe(method(temporaryResultStateBatchForCommandBuffer:sourceImage:sourceStates:destinationImage:))]
2072        #[unsafe(method_family = none)]
2073        pub unsafe fn temporaryResultStateBatchForCommandBuffer_sourceImage_sourceStates_destinationImage(
2074            &self,
2075            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2076            source_image: &MPSImageBatch,
2077            source_states: Option<&NSArray<MPSStateBatch>>,
2078            destination_image: &MPSImageBatch,
2079        ) -> Option<Retained<MPSCNNConvolutionGradientStateBatch>>;
2080
2081        /// CPU side reload. Reload the updated weights and biases from data provider into internal weights and bias buffers. Weights and biases
2082        /// gradients needed for update are obtained from MPSCNNConvolutionGradientState object. Data provider passed in init call is used for this purpose.
2083        #[unsafe(method(reloadWeightsAndBiasesFromDataSource))]
2084        #[unsafe(method_family = none)]
2085        pub unsafe fn reloadWeightsAndBiasesFromDataSource(&self);
2086
2087        /// Deprecated. dataSource will be ignored.
2088        #[deprecated]
2089        #[unsafe(method(reloadWeightsAndBiasesWithDataSource:))]
2090        #[unsafe(method_family = none)]
2091        pub unsafe fn reloadWeightsAndBiasesWithDataSource(
2092            &self,
2093            data_source: &ProtocolObject<dyn MPSCNNConvolutionDataSource>,
2094        );
2095
2096        #[cfg(feature = "MPSState")]
2097        /// GPU side reload. Reload the updated weights and biases from update buffer produced by application enqueued metal kernel into internal weights
2098        /// and biases buffer. Weights and biases gradients needed for update are obtained from MPSCNNConvolutionGradientState object's gradientForWeights and gradientForBiases metal buffer.
2099        ///
2100        ///
2101        /// Parameter `commandBuffer`: Metal command buffer on which application update kernel was enqueued consuming MPSCNNConvolutionGradientState's gradientForWeights and gradientForBiases buffers
2102        /// and producing updateBuffer metal buffer.
2103        ///
2104        /// Parameter `state`: MPSCNNConvolutionWeightsAndBiasesState containing weights and biases buffers which have updated weights produced by application's update kernel.
2105        /// The state readcount will be decremented.
2106        #[unsafe(method(reloadWeightsAndBiasesWithCommandBuffer:state:))]
2107        #[unsafe(method_family = none)]
2108        pub unsafe fn reloadWeightsAndBiasesWithCommandBuffer_state(
2109            &self,
2110            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2111            state: &MPSCNNConvolutionWeightsAndBiasesState,
2112        );
2113
2114        #[cfg(feature = "MPSState")]
2115        /// GPU side export. Enqueue a kernel to export current weights and biases stored in MPSCNNConvoltion's internal buffers into weights and biases MTLBuffer
2116        /// returned in MPSCNNConvolutionWeightsAndBiasesState.
2117        ///
2118        ///
2119        /// Parameter `commandBuffer`: Metal command buffer on which export kernel is enqueued.
2120        ///
2121        /// Parameter `resultStateCanBeTemporary`: If FALSE, state returned will be non-temporary. If TRUE, returned state may or may not be temporary.
2122        ///
2123        /// Returns: MPSCNNConvolutionWeightsAndBiasesState containing weights and biases buffer to which weights got exported. This state and be
2124        /// temporary or non-temporary depending on the flag resultStateCanBeTemporary
2125        #[unsafe(method(exportWeightsAndBiasesWithCommandBuffer:resultStateCanBeTemporary:))]
2126        #[unsafe(method_family = none)]
2127        pub unsafe fn exportWeightsAndBiasesWithCommandBuffer_resultStateCanBeTemporary(
2128            &self,
2129            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2130            result_state_can_be_temporary: bool,
2131        ) -> Retained<MPSCNNConvolutionWeightsAndBiasesState>;
2132    );
2133}
2134
2135/// Methods declared on superclass `MPSKernel`.
2136#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2137impl MPSCNNConvolution {
2138    extern_methods!(
2139        /// Called by NSCoder to decode MPSKernels
2140        ///
2141        /// This isn't the right interface to decode a MPSKernel, but
2142        /// it is the one that NSCoder uses. To enable your NSCoder
2143        /// (e.g. NSKeyedUnarchiver) to set which device to use
2144        /// extend the object to adopt the MPSDeviceProvider
2145        /// protocol. Otherwise, the Metal system default device
2146        /// will be used.
2147        ///
2148        /// # Safety
2149        ///
2150        /// `a_decoder` possibly has further requirements.
2151        #[unsafe(method(initWithCoder:))]
2152        #[unsafe(method_family = init)]
2153        pub unsafe fn initWithCoder(
2154            this: Allocated<Self>,
2155            a_decoder: &NSCoder,
2156        ) -> Option<Retained<Self>>;
2157    );
2158}
2159
2160/// Methods declared on superclass `NSObject`.
2161#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2162impl MPSCNNConvolution {
2163    extern_methods!(
2164        #[unsafe(method(init))]
2165        #[unsafe(method_family = init)]
2166        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
2167
2168        #[unsafe(method(new))]
2169        #[unsafe(method_family = new)]
2170        pub unsafe fn new() -> Retained<Self>;
2171    );
2172}
2173
2174/// [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnconvolutiongradientoption?language=objc)
2175// NS_OPTIONS
2176#[repr(transparent)]
2177#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
2178pub struct MPSCNNConvolutionGradientOption(pub NSUInteger);
2179bitflags::bitflags! {
2180    impl MPSCNNConvolutionGradientOption: NSUInteger {
2181        #[doc(alias = "MPSCNNConvolutionGradientOptionGradientWithData")]
2182        const GradientWithData = 1;
2183        #[doc(alias = "MPSCNNConvolutionGradientOptionGradientWithWeightsAndBias")]
2184        const GradientWithWeightsAndBias = 2;
2185        #[doc(alias = "MPSCNNConvolutionGradientOptionAll")]
2186        const All = MPSCNNConvolutionGradientOption::GradientWithData.0|MPSCNNConvolutionGradientOption::GradientWithWeightsAndBias.0;
2187    }
2188}
2189
2190unsafe impl Encode for MPSCNNConvolutionGradientOption {
2191    const ENCODING: Encoding = NSUInteger::ENCODING;
2192}
2193
2194unsafe impl RefEncode for MPSCNNConvolutionGradientOption {
2195    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
2196}
2197
2198extern_class!(
2199    /// Dependencies: This depends on Metal.framework
2200    ///
2201    /// The MPSCNNConvolutionGradient implementents backward propagation of gradient i.e. it computes the gradient of loss function
2202    /// with respect input data of corresonding forward convolution and gradient of loss function with respect to weights and bias
2203    /// of corresponding convolution in forward pass.
2204    ///
2205    /// Gradient with respect to data
2206    /// ==============================
2207    /// Gradient with respect to input data of corresponding forward convolution will be written in destination image passed to
2208    /// encode call of MPSCNNConvolutionGradient.
2209    /// This step is similar to convolution transpose in that the strided convolution in forward pass become zero filled convolution in
2210    /// backward propagation of gradients. The difference between MPSCNNConvolutionTranspose and gradient wrt data is how the
2211    /// weights, that are provided by data source, are interpreted. MPSCNNConvolution and MPSCNNConvolutionTranspose interpret weights
2212    /// provided by data source as
2213    /// weights[outputFeatureChannels][kernelWidth][kernelHeight][inputFeatureChannels]
2214    /// whereas convoution gradient with respect to data interpret the weights as
2215    /// weights[inputFeatureChannels][kernelWidth][kernelHeight][outputFeatureChannels]
2216    /// i.e. weights are transposed in inputFeatureChannels/outputFeatureChannels dimension and also rotated 180 degress in spatial dimension
2217    ///
2218    /// User should use the same data source provider to initialize MPSCNNConvolutionGradient as is used to initialize corresponding
2219    /// forward MPSCNNConvolution. Implementation will do the transposition/shuffling needed.
2220    /// Thus, while the forward MPSCNNConvolution takes sourceImage of inputFeatureChannels and convolves it with
2221    /// Wt[outputFeatureChannels][kernelHeight][kernelWidth][inputFeatureChannels] to produce destinationImage of outputFeatureChannels,
2222    /// MPSConvolutionGradient takes sourceGradient of outputFeatureChannels which is out of previous layer (nomally neuron backward layer),
2223    /// convolves it with transposed and rotated weights and produces destinationGradient of inputFeatureChannels.
2224    /// If the user decide to double buffer data source provider i.e. different data source providers are passed to forward MPSCNNConvolution object and
2225    /// corresponding MPSCNNConvolutionGradient object, it is user responsibility to make sure both data source providers provide same weights/bias data
2226    /// and have same properties in convolution descriptor else behavior is undefined.
2227    ///
2228    /// Gradient with respect to weights and bias
2229    /// =========================================
2230    /// Gradient with respect to weights and bias are returned in MPSCNNConvolutionGradientState object to be used in weights update functions.
2231    /// If I denotes the input image to corresponding MPSCNNConvolution in forward pass and E denoates the loss gradient from previous layer
2232    /// (normally neuron backward layer) in backward pass, gradient of E with respect to weights is
2233    ///
2234    /// delta_E/delta_Wkpqc = sum_i sum_j [ E(i, j, k) * I( secondaryStrideInPixelX*i + secondaryOffset.x + secondaryDilationRateX*p,
2235    /// secondaryStrideinPixelY*i + secondaryOffset.y + secondaryDilationRateY*q, c) ]
2236    ///
2237    /// where i goes over 0..W-1 and j goes over 0..H-1, (W,H) being width and height of E.
2238    /// p in [0, secondaryKernelWidth-1]
2239    /// q in [0, secondaryKernelHeight-1]
2240    /// c in [0, inputeFeatureChannels/groups - 1]
2241    /// k in [0, outputFeatureChannels]
2242    ///
2243    /// and gradient with respect to bias
2244    ///
2245    /// delta_E/delta_bk = sum_i sum_j [ E(i, j, k) ]
2246    ///
2247    /// These gradients with respect to weights and bias are returned as buffers in MPSCNNConvolutionGradientState object passed in the encode call.
2248    /// These are consumed by MPSCNNConvolution object's -updateWeightsAndBias:MPSCNNConvolutionGradientState* method for CPU side update and
2249    /// encodeWeightsAndBiasUpdate:commandBuffer:MPSCNNConvolutionGradientState* method of MPSCNNConvolution object for GPU side update.
2250    /// UPdated weights and biases are computed as
2251    ///
2252    /// Wkpqc_new = Wkpqc_old + delta_E/delta_Wkpqc
2253    /// bk_new = bk_old + delta_E/delta_bk
2254    ///
2255    /// Note that MPSCNNConvolutionGradientState objects's buffers that contain gradients, for CPU side update, will only contain
2256    /// valid data after command buffer is complete so
2257    /// its only makes sense to call -updateWeightsAndBias method on MPSCNNConvolution objects after command bufer is
2258    /// complete. One can achieve this by enqueueing a command buffer completion handler block that make this call.
2259    /// Since MPSCNNConvolutionGradientState is used across command buffers i.e. its created in forward pass, consumed by  MPSCNNConvolutionGradient in backward pass in same command buffer and passed onto MPSCNNConvolution updateWeightsAndBias method
2260    /// after completion of command buffer, it cannot be a temporary state.
2261    ///
2262    /// In order to gaurantee consistency between forward pass (MPSCNNConvolution) and weights gradient computation in this filter, certain requirements
2263    /// must be met.
2264    /// 1) Dimensions of loss gradient E from previous layer in backward pass must be equal to clipRect.size of corresponding MPSCNNConvolution in forward pass.
2265    /// This is to gaurantee that only those pixels for which weights/bias contributed in destination of forward pass end up contributing to weights/bias gradient update.
2266    /// If the dimension of loss gradient E from previous layer is not equal to clipRect.size of corresponding forward MPSCNNConvolution,
2267    /// i) one can insert a slice operation to extract out the region of size clipRect.size from appropriate offset in E and set primaryOffset = 0 Or
2268    /// ii) set primatryOffset to offset in E at which valid data starts and make sure data outside is zeroed.
2269    /// 2) secondaryOffset should be set to what offset property of MPSCNNConvolution was set to in forward pass.
2270    ///
2271    /// Currently back propagation for gradients is only supported for regualar convolution and depthwise convolution. Back propagation
2272    /// sub-pixel convolution are not supported. So channelMultiplier and subPixelScaleFactor must be one.
2273    ///
2274    /// Note on setting correct offsets
2275    /// ===============================
2276    /// If the forward convolution is called with
2277    /// offset = _offset; kernelWidth = kW; kernelHeight = kH; strideInPixelsX = sX; strideInPixelsY = sY;
2278    /// dilationRateX = dX; dilationRateY = dY;
2279    /// thus dilated filter parameters are
2280    /// kW_Dilated = (kW - 1)*dX + 1; kH_Dilated = (kH - 1)*dY + 1;
2281    /// Then the correct offset can be computed as follows.
2282    /// Convoluton Gradient with Data
2283    /// =============================
2284    /// Convolution gradient with data of forward convolution with stride > 1 is essentially normal convoution with unit stride,
2285    /// on an image that is formed by inserting strideInPixelsX-1 zeros in between each column and strideInPixelsY-1 zeros in between each
2286    /// row of input gradient (output gradient of last layer) with kernel weights that are rotated by 180 degrees in spatial dimension (MPSCNNConvolutionGradient
2287    /// does this rotation internally). primaryOffset property defines offset in original input gradient coordinate system. In order to
2288    /// translate it in zero filled intermediate image coordinate system, kernelOffsetX and kernelOffsetY properties can be used as follows
2289    /// offsetInZeroFilledImageX = primaryOffset.x * primaryStrideInPixelsX + kernelOffsetX;
2290    /// offsetInZeroFilledImageY = primaryOffset.y * primaryStrideInPixelsY + kernelOffsetY;
2291    /// This is what internally MPSCNNConvolutionGradient do. In order to correctly match forward convolution offset setting (so that padding policy is
2292    /// consistent), application should set
2293    /// primaryOffset.x = 0; primaryOffset.y = 0;
2294    /// kernelOffset.x = -_offset.x + (~(NSInteger) kW_Dilated
2295    /// &
2296    /// 1L);
2297    /// kernelOffset.y = -_offset.y + (~(NSInteger) kH_Dilated
2298    /// &
2299    /// 1L);
2300    /// Convolution gradient with data does not use secondaryOffset.
2301    ///
2302    /// Convolution Gradient with Weights and Biases
2303    /// ============================================
2304    /// For consistent padding policy with respect to forward convolution,
2305    /// secondaryOffset.x = _offset.x - kW_Dilated/2
2306    /// secondaryOffset.y = _offset.y - kH_Dilated/2
2307    /// Convolution gradient with weights and biases does not use primaryOffset (or it is assumed to be zero) as summation is over entire
2308    /// gradient image and only gradient image without any padding is currently accepted. If previous layer produces gradient image with
2309    /// padding, slice operation should be used to extract out the gradient which will be input to MPSCNNConvolutionGradient.
2310    ///
2311    /// Note that if application uses encode method that return destination gradient on left hand side and consumes MPSCNNConvolutionGradientState
2312    /// object produced by forward MPSCNNConvolution, all these parameters are set automatically for the application i.e. applicaiton does not
2313    /// need to worry about setting these.
2314    ///
2315    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnconvolutiongradient?language=objc)
2316    #[unsafe(super(MPSCNNGradientKernel, MPSCNNBinaryKernel, MPSKernel, NSObject))]
2317    #[derive(Debug, PartialEq, Eq, Hash)]
2318    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2319    pub struct MPSCNNConvolutionGradient;
2320);
2321
2322#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2323extern_conformance!(
2324    unsafe impl NSCoding for MPSCNNConvolutionGradient {}
2325);
2326
2327#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2328extern_conformance!(
2329    unsafe impl NSCopying for MPSCNNConvolutionGradient {}
2330);
2331
2332#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2333unsafe impl CopyingHelper for MPSCNNConvolutionGradient {
2334    type Result = Self;
2335}
2336
2337#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2338extern_conformance!(
2339    unsafe impl NSObjectProtocol for MPSCNNConvolutionGradient {}
2340);
2341
2342#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2343extern_conformance!(
2344    unsafe impl NSSecureCoding for MPSCNNConvolutionGradient {}
2345);
2346
2347#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2348impl MPSCNNConvolutionGradient {
2349    extern_methods!(
2350        /// The number of feature channels per pixel in the gradient image (primarySource) of encode call. This is same is outputFeatureChannels
2351        /// or the feature channels of destination image in forward convolution i.e. dataSource.descriptor.outputFeatureChannels
2352        #[unsafe(method(sourceGradientFeatureChannels))]
2353        #[unsafe(method_family = none)]
2354        pub unsafe fn sourceGradientFeatureChannels(&self) -> NSUInteger;
2355
2356        /// The number of feature channels per pixel in the input image to forward convolution which is used here as secondarySource.
2357        /// This is same as dataSource.descriptor.inputFeatureChannels. This is also the number of feature channels in destinatin image
2358        /// here i.e. gradient with respect to data.
2359        #[unsafe(method(sourceImageFeatureChannels))]
2360        #[unsafe(method_family = none)]
2361        pub unsafe fn sourceImageFeatureChannels(&self) -> NSUInteger;
2362
2363        /// Number of groups input and output channels are divided into.
2364        #[unsafe(method(groups))]
2365        #[unsafe(method_family = none)]
2366        pub unsafe fn groups(&self) -> NSUInteger;
2367
2368        /// Channel multiplier.
2369        ///
2370        /// For convolution created with MPSCNNDepthWiseConvolutionDescriptor, it is the number of
2371        /// output feature channels for each input channel. See MPSCNNDepthWiseConvolutionDescriptor for more details.
2372        /// Default is 0 which means regular CNN convolution. Currently only channelMultiplier of 1 is supported i.e. inputChannels == outputChannels
2373        #[unsafe(method(channelMultiplier))]
2374        #[unsafe(method_family = none)]
2375        pub unsafe fn channelMultiplier(&self) -> NSUInteger;
2376
2377        /// dataSource with which gradient object was created
2378        #[unsafe(method(dataSource))]
2379        #[unsafe(method_family = none)]
2380        pub unsafe fn dataSource(
2381            &self,
2382        ) -> Retained<ProtocolObject<dyn MPSCNNConvolutionDataSource>>;
2383
2384        /// Option to control which gradient to compute. Default is MPSCNNConvolutionGradientOptionAll
2385        /// which means both gradient with respect to data and gradient with respect to weight and bias are computed.
2386        #[unsafe(method(gradientOption))]
2387        #[unsafe(method_family = none)]
2388        pub unsafe fn gradientOption(&self) -> MPSCNNConvolutionGradientOption;
2389
2390        /// Setter for [`gradientOption`][Self::gradientOption].
2391        #[unsafe(method(setGradientOption:))]
2392        #[unsafe(method_family = none)]
2393        pub unsafe fn setGradientOption(&self, gradient_option: MPSCNNConvolutionGradientOption);
2394
2395        /// Property to control serialization of weights and bias.
2396        ///
2397        /// During serialization of convolution object in -encodeWithCoder call, weights and biases are saved so that convolution
2398        /// object can be properly unserialized/restored in -initWithCoder call. If data source provied is NSSecureCoding compliant,
2399        /// data source is serialized else weights and biases are serialized.
2400        /// As weights/biases data may be several MB and these are same for both gradient and forward convolution object,
2401        /// application may already have weights/biases on disk through convolution, it can
2402        /// save disk space by setting this property false so convolution gradient object does not end up storing another copy of weights/biases.
2403        /// Default is NO. When application decides to set it to NO, it MUST call
2404        /// -(void) reloadWeightsAndBiasesFromDataSource
2405        /// after initWithCoder has initialized convolution object.
2406        #[deprecated]
2407        #[unsafe(method(serializeWeightsAndBiases))]
2408        #[unsafe(method_family = none)]
2409        pub unsafe fn serializeWeightsAndBiases(&self) -> bool;
2410
2411        /// Setter for [`serializeWeightsAndBiases`][Self::serializeWeightsAndBiases].
2412        #[deprecated]
2413        #[unsafe(method(setSerializeWeightsAndBiases:))]
2414        #[unsafe(method_family = none)]
2415        pub unsafe fn setSerializeWeightsAndBiases(&self, serialize_weights_and_biases: bool);
2416
2417        /// Initializes a convolution gradient (with respect to weights and bias) object.
2418        ///
2419        /// Parameter `device`: The MTLDevice on which this MPSCNNConvolutionGradient filter will be used
2420        ///
2421        /// Parameter `weights`: A pointer to a object that conforms to the MPSCNNConvolutionDataSource
2422        /// protocol. Note that same data source as provided to forward convolution should be used.
2423        ///
2424        ///
2425        /// Returns: A valid MPSCNNConvolutionGradient object or nil, if failure.
2426        #[unsafe(method(initWithDevice:weights:))]
2427        #[unsafe(method_family = init)]
2428        pub unsafe fn initWithDevice_weights(
2429            this: Allocated<Self>,
2430            device: &ProtocolObject<dyn MTLDevice>,
2431            weights: &ProtocolObject<dyn MPSCNNConvolutionDataSource>,
2432        ) -> Retained<Self>;
2433
2434        /// NSSecureCoding compatability
2435        ///
2436        /// While the standard NSSecureCoding/NSCoding method
2437        /// -initWithCoder: should work, since the file can't
2438        /// know which device your data is allocated on, we
2439        /// have to guess and may guess incorrectly.  To avoid
2440        /// that problem, use initWithCoder:device instead.
2441        ///
2442        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
2443        ///
2444        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
2445        ///
2446        /// Returns: A new MPSKernel object, or nil if failure.
2447        ///
2448        /// # Safety
2449        ///
2450        /// `a_decoder` possibly has further requirements.
2451        #[unsafe(method(initWithCoder:device:))]
2452        #[unsafe(method_family = init)]
2453        pub unsafe fn initWithCoder_device(
2454            this: Allocated<Self>,
2455            a_decoder: &NSCoder,
2456            device: &ProtocolObject<dyn MTLDevice>,
2457        ) -> Option<Retained<Self>>;
2458
2459        #[unsafe(method(initWithDevice:))]
2460        #[unsafe(method_family = init)]
2461        pub unsafe fn initWithDevice(
2462            this: Allocated<Self>,
2463            device: &ProtocolObject<dyn MTLDevice>,
2464        ) -> Retained<Self>;
2465
2466        /// CPU side reload. Reload the updated weights and biases from data provider into internal weights and bias buffers. Weights and biases
2467        /// gradients needed for update are obtained from MPSCNNConvolutionGradientState object. Data provider passed in init call is used for this purpose.
2468        #[unsafe(method(reloadWeightsAndBiasesFromDataSource))]
2469        #[unsafe(method_family = none)]
2470        pub unsafe fn reloadWeightsAndBiasesFromDataSource(&self);
2471
2472        #[cfg(feature = "MPSState")]
2473        /// GPU side reload. Reload the updated weights and biases from update buffer produced by application enqueued metal kernel into internal weights
2474        /// and biases buffer. Weights and biases gradients needed for update are obtained from MPSCNNConvolutionGradientState object's gradientForWeights and gradientForBiases metal buffer.
2475        ///
2476        ///
2477        /// Parameter `commandBuffer`: Metal command buffer on which application update kernel was enqueued consuming MPSCNNConvolutionGradientState's gradientForWeights and gradientForBiases buffer
2478        /// and producing updateBuffer metal buffer.
2479        ///
2480        /// Parameter `state`: MPSCNNConvolutionWeightsAndBiasesState containing weights and biases buffers which have updated weights produced by application's update kernel.
2481        #[unsafe(method(reloadWeightsAndBiasesWithCommandBuffer:state:))]
2482        #[unsafe(method_family = none)]
2483        pub unsafe fn reloadWeightsAndBiasesWithCommandBuffer_state(
2484            &self,
2485            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2486            state: &MPSCNNConvolutionWeightsAndBiasesState,
2487        );
2488    );
2489}
2490
2491/// Methods declared on superclass `MPSKernel`.
2492#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2493impl MPSCNNConvolutionGradient {
2494    extern_methods!(
2495        /// Called by NSCoder to decode MPSKernels
2496        ///
2497        /// This isn't the right interface to decode a MPSKernel, but
2498        /// it is the one that NSCoder uses. To enable your NSCoder
2499        /// (e.g. NSKeyedUnarchiver) to set which device to use
2500        /// extend the object to adopt the MPSDeviceProvider
2501        /// protocol. Otherwise, the Metal system default device
2502        /// will be used.
2503        ///
2504        /// # Safety
2505        ///
2506        /// `a_decoder` possibly has further requirements.
2507        #[unsafe(method(initWithCoder:))]
2508        #[unsafe(method_family = init)]
2509        pub unsafe fn initWithCoder(
2510            this: Allocated<Self>,
2511            a_decoder: &NSCoder,
2512        ) -> Option<Retained<Self>>;
2513    );
2514}
2515
2516/// Methods declared on superclass `NSObject`.
2517#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2518impl MPSCNNConvolutionGradient {
2519    extern_methods!(
2520        #[unsafe(method(init))]
2521        #[unsafe(method_family = init)]
2522        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
2523
2524        #[unsafe(method(new))]
2525        #[unsafe(method_family = new)]
2526        pub unsafe fn new() -> Retained<Self>;
2527    );
2528}
2529
2530extern_class!(
2531    /// Dependencies: This depends on Metal.framework
2532    ///
2533    /// The MPSCNNFullyConnected specifies a fully connected convolution layer a.k.a. Inner product
2534    /// layer. A fully connected CNN layer is one where every input channel is connected
2535    /// to every output channel. The kernel width is equal to width of source image
2536    /// and the kernel height is equal to the height of source image. Width and height of the output
2537    /// is 1x1. Thus, it takes a srcW x srcH x Ni MPSCNNImage, convolves it with Weights[No][SrcW][srcH][Ni]
2538    /// and produces a 1 x 1 x No output. The following must be true:
2539    ///
2540    /// ```text
2541    ///                          kernelWidth  == source.width
2542    ///                          kernelHeight == source.height
2543    ///                          clipRect.size.width == 1
2544    ///                          clipRect.size.height == 1
2545    /// ```
2546    ///
2547    /// One can think of a fully connected layer as a matrix multiplication that flattens an image into a vector of length
2548    /// srcW*srcH*Ni. The weights are arragned in a matrix of dimension No x (srcW*srcH*Ni) for product output vectors
2549    /// of length No. The strideInPixelsX, strideInPixelsY, and group must be 1. Offset is not applicable and is ignored.
2550    /// Since clipRect is clamped to the destination image bounds, if the destination is 1x1, one doesn't need to set the
2551    /// clipRect.
2552    ///
2553    /// Note that one can implement an inner product using MPSCNNConvolution by setting
2554    ///
2555    /// ```text
2556    ///                      offset = (kernelWidth/2,kernelHeight/2)
2557    ///                      clipRect.origin = (ox,oy), clipRect.size = (1,1)
2558    ///                      strideX = strideY = group = 1
2559    /// ```
2560    ///
2561    /// However, using the MPSCNNFullyConnected for this is better for performance as it lets us choose the most
2562    /// performant method which may not be possible when using a general convolution. For example,
2563    /// we may internally use matrix multiplication or special reduction kernels for a specific platform.
2564    ///
2565    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnfullyconnected?language=objc)
2566    #[unsafe(super(MPSCNNConvolution, MPSCNNKernel, MPSKernel, NSObject))]
2567    #[derive(Debug, PartialEq, Eq, Hash)]
2568    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2569    pub struct MPSCNNFullyConnected;
2570);
2571
2572#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2573extern_conformance!(
2574    unsafe impl NSCoding for MPSCNNFullyConnected {}
2575);
2576
2577#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2578extern_conformance!(
2579    unsafe impl NSCopying for MPSCNNFullyConnected {}
2580);
2581
2582#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2583unsafe impl CopyingHelper for MPSCNNFullyConnected {
2584    type Result = Self;
2585}
2586
2587#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2588extern_conformance!(
2589    unsafe impl NSObjectProtocol for MPSCNNFullyConnected {}
2590);
2591
2592#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2593extern_conformance!(
2594    unsafe impl NSSecureCoding for MPSCNNFullyConnected {}
2595);
2596
2597#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2598impl MPSCNNFullyConnected {
2599    extern_methods!(
2600        /// Initializes a fully connected kernel
2601        ///
2602        /// Parameter `device`: The MTLDevice on which this MPSCNNFullyConnected filter will be used
2603        ///
2604        /// Parameter `weights`: A pointer to a object that conforms to the MPSCNNConvolutionDataSource
2605        /// protocol. The MPSCNNConvolutionDataSource protocol declares the methods that an
2606        /// instance of MPSCNNFullyConnected uses to obtain the weights and bias terms
2607        /// for the CNN fully connected filter.
2608        ///
2609        ///
2610        /// Returns: A valid MPSCNNFullyConnected object or nil, if failure.
2611        #[unsafe(method(initWithDevice:weights:))]
2612        #[unsafe(method_family = init)]
2613        pub unsafe fn initWithDevice_weights(
2614            this: Allocated<Self>,
2615            device: &ProtocolObject<dyn MTLDevice>,
2616            weights: &ProtocolObject<dyn MPSCNNConvolutionDataSource>,
2617        ) -> Retained<Self>;
2618
2619        #[cfg(feature = "MPSNeuralNetworkTypes")]
2620        /// Initializes a convolution kernel
2621        /// WARNING:                        This API is depreated and will be removed in the future. It cannot be used
2622        /// when training. Also serialization/unserialization wont work for MPSCNNConvolution
2623        /// objects created with this init. Please move onto using initWithDevice:weights:.
2624        ///
2625        /// Parameter `device`: The MTLDevice on which this MPSCNNConvolution filter will be used
2626        ///
2627        /// Parameter `convolutionDescriptor`: A pointer to a MPSCNNConvolutionDescriptor.
2628        ///
2629        /// Parameter `kernelWeights`: A pointer to a weights array.  Each entry is a float value. The number of entries is =
2630        /// inputFeatureChannels * outputFeatureChannels * kernelHeight * kernelWidth
2631        /// The layout of filter weight is so that it can be reinterpreted as 4D tensor (array)
2632        /// weight[ outputChannels ][ kernelHeight ][ kernelWidth ][ inputChannels / groups ]
2633        /// Weights are converted to half float (fp16) internally for best performance.
2634        ///
2635        /// Parameter `biasTerms`: A pointer to bias terms to be applied to the convolution output.  Each entry is a float value.
2636        /// The number of entries is = numberOfOutputFeatureMaps
2637        ///
2638        /// Parameter `flags`: Currently unused. Pass MPSCNNConvolutionFlagsNone
2639        ///
2640        ///
2641        /// Returns: A valid MPSCNNConvolution object or nil, if failure.
2642        ///
2643        /// # Safety
2644        ///
2645        /// - `kernel_weights` must be a valid pointer.
2646        /// - `bias_terms` must be a valid pointer or null.
2647        #[deprecated]
2648        #[unsafe(method(initWithDevice:convolutionDescriptor:kernelWeights:biasTerms:flags:))]
2649        #[unsafe(method_family = init)]
2650        pub unsafe fn initWithDevice_convolutionDescriptor_kernelWeights_biasTerms_flags(
2651            this: Allocated<Self>,
2652            device: &ProtocolObject<dyn MTLDevice>,
2653            convolution_descriptor: &MPSCNNConvolutionDescriptor,
2654            kernel_weights: NonNull<c_float>,
2655            bias_terms: *const c_float,
2656            flags: MPSCNNConvolutionFlags,
2657        ) -> Retained<Self>;
2658
2659        /// NSSecureCoding compatability
2660        ///
2661        /// While the standard NSSecureCoding/NSCoding method
2662        /// -initWithCoder: should work, since the file can't
2663        /// know which device your data is allocated on, we
2664        /// have to guess and may guess incorrectly.  To avoid
2665        /// that problem, use initWithCoder:device instead.
2666        ///
2667        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
2668        ///
2669        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
2670        ///
2671        /// Returns: A new MPSKernel object, or nil if failure.
2672        ///
2673        /// # Safety
2674        ///
2675        /// `a_decoder` possibly has further requirements.
2676        #[unsafe(method(initWithCoder:device:))]
2677        #[unsafe(method_family = init)]
2678        pub unsafe fn initWithCoder_device(
2679            this: Allocated<Self>,
2680            a_decoder: &NSCoder,
2681            device: &ProtocolObject<dyn MTLDevice>,
2682        ) -> Option<Retained<Self>>;
2683
2684        #[unsafe(method(initWithDevice:))]
2685        #[unsafe(method_family = init)]
2686        pub unsafe fn initWithDevice(
2687            this: Allocated<Self>,
2688            device: &ProtocolObject<dyn MTLDevice>,
2689        ) -> Retained<Self>;
2690    );
2691}
2692
2693/// Methods declared on superclass `MPSKernel`.
2694#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2695impl MPSCNNFullyConnected {
2696    extern_methods!(
2697        /// Called by NSCoder to decode MPSKernels
2698        ///
2699        /// This isn't the right interface to decode a MPSKernel, but
2700        /// it is the one that NSCoder uses. To enable your NSCoder
2701        /// (e.g. NSKeyedUnarchiver) to set which device to use
2702        /// extend the object to adopt the MPSDeviceProvider
2703        /// protocol. Otherwise, the Metal system default device
2704        /// will be used.
2705        ///
2706        /// # Safety
2707        ///
2708        /// `a_decoder` possibly has further requirements.
2709        #[unsafe(method(initWithCoder:))]
2710        #[unsafe(method_family = init)]
2711        pub unsafe fn initWithCoder(
2712            this: Allocated<Self>,
2713            a_decoder: &NSCoder,
2714        ) -> Option<Retained<Self>>;
2715    );
2716}
2717
2718/// Methods declared on superclass `NSObject`.
2719#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2720impl MPSCNNFullyConnected {
2721    extern_methods!(
2722        #[unsafe(method(init))]
2723        #[unsafe(method_family = init)]
2724        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
2725
2726        #[unsafe(method(new))]
2727        #[unsafe(method_family = new)]
2728        pub unsafe fn new() -> Retained<Self>;
2729    );
2730}
2731
2732extern_class!(
2733    /// Dependencies: This depends on Metal.framework
2734    ///
2735    /// Compute the gradient for fully connected layer.
2736    ///
2737    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnfullyconnectedgradient?language=objc)
2738    #[unsafe(super(
2739        MPSCNNConvolutionGradient,
2740        MPSCNNGradientKernel,
2741        MPSCNNBinaryKernel,
2742        MPSKernel,
2743        NSObject
2744    ))]
2745    #[derive(Debug, PartialEq, Eq, Hash)]
2746    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2747    pub struct MPSCNNFullyConnectedGradient;
2748);
2749
2750#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2751extern_conformance!(
2752    unsafe impl NSCoding for MPSCNNFullyConnectedGradient {}
2753);
2754
2755#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2756extern_conformance!(
2757    unsafe impl NSCopying for MPSCNNFullyConnectedGradient {}
2758);
2759
2760#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2761unsafe impl CopyingHelper for MPSCNNFullyConnectedGradient {
2762    type Result = Self;
2763}
2764
2765#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2766extern_conformance!(
2767    unsafe impl NSObjectProtocol for MPSCNNFullyConnectedGradient {}
2768);
2769
2770#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2771extern_conformance!(
2772    unsafe impl NSSecureCoding for MPSCNNFullyConnectedGradient {}
2773);
2774
2775#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2776impl MPSCNNFullyConnectedGradient {
2777    extern_methods!(
2778        /// Initializes a convolution gradient (with respect to weights and bias) object.
2779        ///
2780        /// Parameter `device`: The MTLDevice on which this MPSCNNConvolutionGradient filter will be used
2781        ///
2782        /// Parameter `weights`: A pointer to a object that conforms to the MPSCNNConvolutionDataSource
2783        /// protocol. Note that same data source as provided to forward convolution should be used.
2784        ///
2785        ///
2786        /// Returns: A valid MPSCNNConvolutionGradient object or nil, if failure.
2787        #[unsafe(method(initWithDevice:weights:))]
2788        #[unsafe(method_family = init)]
2789        pub unsafe fn initWithDevice_weights(
2790            this: Allocated<Self>,
2791            device: &ProtocolObject<dyn MTLDevice>,
2792            weights: &ProtocolObject<dyn MPSCNNConvolutionDataSource>,
2793        ) -> Retained<Self>;
2794
2795        /// NSSecureCoding compatability
2796        ///
2797        /// While the standard NSSecureCoding/NSCoding method
2798        /// -initWithCoder: should work, since the file can't
2799        /// know which device your data is allocated on, we
2800        /// have to guess and may guess incorrectly.  To avoid
2801        /// that problem, use initWithCoder:device instead.
2802        ///
2803        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
2804        ///
2805        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
2806        ///
2807        /// Returns: A new MPSKernel object, or nil if failure.
2808        ///
2809        /// # Safety
2810        ///
2811        /// `a_decoder` possibly has further requirements.
2812        #[unsafe(method(initWithCoder:device:))]
2813        #[unsafe(method_family = init)]
2814        pub unsafe fn initWithCoder_device(
2815            this: Allocated<Self>,
2816            a_decoder: &NSCoder,
2817            device: &ProtocolObject<dyn MTLDevice>,
2818        ) -> Option<Retained<Self>>;
2819
2820        #[unsafe(method(initWithDevice:))]
2821        #[unsafe(method_family = init)]
2822        pub unsafe fn initWithDevice(
2823            this: Allocated<Self>,
2824            device: &ProtocolObject<dyn MTLDevice>,
2825        ) -> Retained<Self>;
2826    );
2827}
2828
2829/// Methods declared on superclass `MPSKernel`.
2830#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2831impl MPSCNNFullyConnectedGradient {
2832    extern_methods!(
2833        /// Called by NSCoder to decode MPSKernels
2834        ///
2835        /// This isn't the right interface to decode a MPSKernel, but
2836        /// it is the one that NSCoder uses. To enable your NSCoder
2837        /// (e.g. NSKeyedUnarchiver) to set which device to use
2838        /// extend the object to adopt the MPSDeviceProvider
2839        /// protocol. Otherwise, the Metal system default device
2840        /// will be used.
2841        ///
2842        /// # Safety
2843        ///
2844        /// `a_decoder` possibly has further requirements.
2845        #[unsafe(method(initWithCoder:))]
2846        #[unsafe(method_family = init)]
2847        pub unsafe fn initWithCoder(
2848            this: Allocated<Self>,
2849            a_decoder: &NSCoder,
2850        ) -> Option<Retained<Self>>;
2851    );
2852}
2853
2854/// Methods declared on superclass `NSObject`.
2855#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2856impl MPSCNNFullyConnectedGradient {
2857    extern_methods!(
2858        #[unsafe(method(init))]
2859        #[unsafe(method_family = init)]
2860        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
2861
2862        #[unsafe(method(new))]
2863        #[unsafe(method_family = new)]
2864        pub unsafe fn new() -> Retained<Self>;
2865    );
2866}
2867
2868extern_class!(
2869    /// Dependencies: This depends on Metal.framework
2870    ///
2871    /// The MPSCNNConvolutionTranspose specifies a transposed convolution.
2872    /// The MPSCNNConvolutionTranspose convolves the input image with a set of filters, each producing one feature map in the output image.
2873    ///
2874    /// Some third-party frameworks may rotate the weights spatially by 180 degrees for Convolution Transpose. MPS uses the weights
2875    /// specified by the developer as-is and does not perform any rotation. The developer may need to rotate the weights appropriately
2876    /// in case this rotation is needed before the convolution transpose is applied.
2877    ///
2878    /// When the stride in any dimension is greater than 1, the convolution transpose puts (stride - 1) zeroes in-between the source
2879    /// image pixels to create an expanded image. Then a convolution is done over the expanded image to generate the output of the
2880    /// convolution transpose.
2881    ///
2882    /// Intermediate image size = (srcSize - 1) * Stride + 1
2883    ///
2884    /// Examples:
2885    ///
2886    ///
2887    /// ```text
2888    ///               So in case of sride == 2 (this behaves same in both dimensions)
2889    ///
2890    ///               Source image:
2891    ///                _______________
2892    ///               |   |   |   |   |
2893    ///               | 1 | 2 | 3 | 4 |
2894    ///               |   |   |   |   |
2895    ///                ---------------
2896    ///
2897    ///               Intermediate Image:
2898    ///                ___________________________
2899    ///               |   |   |   |   |   |   |   |
2900    ///               | 1 | 0 | 2 | 0 | 3 | 0 | 4 |
2901    ///               |   |   |   |   |   |   |   |
2902    ///                ---------------------------
2903    ///
2904    ///
2905    ///               NOTE on Offset:
2906    ///               There are 2 types of offsets defined:
2907    ///               1) The Offset defined in MPSCNNKernel from which MPSCNNConvolutionTranspose inherits. This offset is applied to from where
2908    ///                  the kernel will be applied on the source.
2909    ///               2) The kernelOffsetX and kernelOffsetY which is the offset applied to the kernel when it is finally applied on the intermediate
2910    ///                  image.
2911    ///
2912    ///               So totalOffset = Offset * stride + kernelOffset
2913    ///
2914    ///               The offset defined by user refers to the coordinate frame of the expanded image
2915    ///               (we are showing only 1 dimension X it can be extended to Y dimension as well) :
2916    ///
2917    ///               X indicates where the convolution transpose begins:
2918    ///
2919    ///               Intermediate Image:  Offset = 0, kernelOffset = 0
2920    ///                ___________________________
2921    ///               |   |   |   |   |   |   |   |
2922    ///               | 1 | 0 | 2 | 0 | 3 | 0 | 4 |
2923    ///               | X |   |   |   |   |   |   |
2924    ///                ---------------------------
2925    ///
2926    ///
2927    ///               X indicates where the convolution transpose begins:
2928    ///
2929    ///               Intermediate Image:  Offset = 0, kernelOffset = 1
2930    ///                ___________________________
2931    ///               |   |   |   |   |   |   |   |
2932    ///               | 1 | 0 | 2 | 0 | 3 | 0 | 4 |
2933    ///               |   | X |   |   |   |   |   |
2934    ///                ---------------------------
2935    ///
2936    ///
2937    ///               X indicates where the convolution transpose begins:
2938    ///
2939    ///               Intermediate Image:  Offset = 0, kernelOffset = -1
2940    ///                  ___________________________
2941    ///                 |   |   |   |   |   |   |   |
2942    ///               X | 1 | 0 | 2 | 0 | 3 | 0 | 4 |
2943    ///                 |   |   |   |   |   |   |   |
2944    ///                  ---------------------------
2945    ///
2946    ///
2947    ///
2948    ///
2949    ///               So if the user wanted to apply an offset of 2 on the source image of convolution transpose:
2950    ///
2951    ///               Source image:
2952    ///                _______________
2953    ///               |   |   |   |   |
2954    ///               | 1 | 2 | 3 | 4 |
2955    ///               |   |   | X |   |
2956    ///                ---------------
2957    ///
2958    ///               offset = 2, kernelOffset = 0
2959    ///
2960    ///               Intermediate Image:
2961    ///                ___________________________
2962    ///               |   |   |   |   |   |   |   |
2963    ///               | 1 | 0 | 2 | 0 | 3 | 0 | 4 |
2964    ///               |   |   |   |   | X |   |   |
2965    ///                ---------------------------
2966    ///
2967    /// ```
2968    ///
2969    /// Note that if your application is not using MPSCNNConvolutionGradientState to configure the convolution transpose with respect to convolution,
2970    /// your application may do this using padding policy. In such case if convolution uses valid padding policy, than convolution transpose should use
2971    /// full padding policy and vice vera. Full padding remains full.
2972    ///
2973    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnconvolutiontranspose?language=objc)
2974    #[unsafe(super(MPSCNNKernel, MPSKernel, NSObject))]
2975    #[derive(Debug, PartialEq, Eq, Hash)]
2976    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2977    pub struct MPSCNNConvolutionTranspose;
2978);
2979
2980#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2981extern_conformance!(
2982    unsafe impl NSCoding for MPSCNNConvolutionTranspose {}
2983);
2984
2985#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2986extern_conformance!(
2987    unsafe impl NSCopying for MPSCNNConvolutionTranspose {}
2988);
2989
2990#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2991unsafe impl CopyingHelper for MPSCNNConvolutionTranspose {
2992    type Result = Self;
2993}
2994
2995#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2996extern_conformance!(
2997    unsafe impl NSObjectProtocol for MPSCNNConvolutionTranspose {}
2998);
2999
3000#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3001extern_conformance!(
3002    unsafe impl NSSecureCoding for MPSCNNConvolutionTranspose {}
3003);
3004
3005#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3006impl MPSCNNConvolutionTranspose {
3007    extern_methods!(
3008        /// The number of feature channels per pixel in the input image.
3009        #[unsafe(method(inputFeatureChannels))]
3010        #[unsafe(method_family = none)]
3011        pub unsafe fn inputFeatureChannels(&self) -> NSUInteger;
3012
3013        /// The number of feature channels per pixel in the output image.
3014        #[unsafe(method(outputFeatureChannels))]
3015        #[unsafe(method_family = none)]
3016        pub unsafe fn outputFeatureChannels(&self) -> NSUInteger;
3017
3018        /// Offset in X from which the kernel starts sliding
3019        #[unsafe(method(kernelOffsetX))]
3020        #[unsafe(method_family = none)]
3021        pub unsafe fn kernelOffsetX(&self) -> NSInteger;
3022
3023        /// Setter for [`kernelOffsetX`][Self::kernelOffsetX].
3024        #[unsafe(method(setKernelOffsetX:))]
3025        #[unsafe(method_family = none)]
3026        pub unsafe fn setKernelOffsetX(&self, kernel_offset_x: NSInteger);
3027
3028        /// Offset in Y from which the kernel starts sliding
3029        #[unsafe(method(kernelOffsetY))]
3030        #[unsafe(method_family = none)]
3031        pub unsafe fn kernelOffsetY(&self) -> NSInteger;
3032
3033        /// Setter for [`kernelOffsetY`][Self::kernelOffsetY].
3034        #[unsafe(method(setKernelOffsetY:))]
3035        #[unsafe(method_family = none)]
3036        pub unsafe fn setKernelOffsetY(&self, kernel_offset_y: NSInteger);
3037
3038        /// Number of groups input and output channels are divided into.
3039        #[unsafe(method(groups))]
3040        #[unsafe(method_family = none)]
3041        pub unsafe fn groups(&self) -> NSUInteger;
3042
3043        #[cfg(feature = "MPSNeuralNetworkTypes")]
3044        /// Precision of accumulator used in convolution.
3045        ///
3046        /// See MPSNeuralNetworkTypes.h for discussion. Default is MPSNNConvolutionAccumulatorPrecisionOptionFloat.
3047        #[unsafe(method(accumulatorPrecisionOption))]
3048        #[unsafe(method_family = none)]
3049        pub unsafe fn accumulatorPrecisionOption(
3050            &self,
3051        ) -> MPSNNConvolutionAccumulatorPrecisionOption;
3052
3053        #[cfg(feature = "MPSNeuralNetworkTypes")]
3054        /// Setter for [`accumulatorPrecisionOption`][Self::accumulatorPrecisionOption].
3055        #[unsafe(method(setAccumulatorPrecisionOption:))]
3056        #[unsafe(method_family = none)]
3057        pub unsafe fn setAccumulatorPrecisionOption(
3058            &self,
3059            accumulator_precision_option: MPSNNConvolutionAccumulatorPrecisionOption,
3060        );
3061
3062        /// dataSource with which convolution transpose object was created
3063        #[unsafe(method(dataSource))]
3064        #[unsafe(method_family = none)]
3065        pub unsafe fn dataSource(
3066            &self,
3067        ) -> Retained<ProtocolObject<dyn MPSCNNConvolutionDataSource>>;
3068
3069        /// Initializes a convolution transpose kernel
3070        ///
3071        /// Parameter `device`: The MTLDevice on which this MPSCNNConvolutionTranspose filter will be used
3072        ///
3073        /// Parameter `weights`: A pointer to a object that conforms to the MPSCNNConvolutionDataSource
3074        /// protocol. The MPSCNNConvolutionDataSource protocol declares the methods that an
3075        /// instance of MPSCNNConvolutionTranspose uses to obtain the weights and bias terms
3076        /// for the CNN convolutionTranspose filter. Currently we support only Float32 weights.
3077        ///
3078        ///
3079        /// Returns: A valid MPSCNNConvolutionTranspose object.
3080        #[unsafe(method(initWithDevice:weights:))]
3081        #[unsafe(method_family = init)]
3082        pub unsafe fn initWithDevice_weights(
3083            this: Allocated<Self>,
3084            device: &ProtocolObject<dyn MTLDevice>,
3085            weights: &ProtocolObject<dyn MPSCNNConvolutionDataSource>,
3086        ) -> Retained<Self>;
3087
3088        #[unsafe(method(initWithDevice:))]
3089        #[unsafe(method_family = init)]
3090        pub unsafe fn initWithDevice(
3091            this: Allocated<Self>,
3092            device: &ProtocolObject<dyn MTLDevice>,
3093        ) -> Retained<Self>;
3094
3095        /// <NSSecureCoding
3096        /// > support
3097        ///
3098        /// # Safety
3099        ///
3100        /// `a_decoder` possibly has further requirements.
3101        #[unsafe(method(initWithCoder:device:))]
3102        #[unsafe(method_family = init)]
3103        pub unsafe fn initWithCoder_device(
3104            this: Allocated<Self>,
3105            a_decoder: &NSCoder,
3106            device: &ProtocolObject<dyn MTLDevice>,
3107        ) -> Option<Retained<Self>>;
3108
3109        #[cfg(all(
3110            feature = "MPSImage",
3111            feature = "MPSNNGradientState",
3112            feature = "MPSState"
3113        ))]
3114        /// Encode a MPSCNNKernel into a command Buffer. Create a texture to hold the result and return it.
3115        ///
3116        /// In the first iteration on this method, encodeToCommandBuffer:sourceImage:destinationImage:
3117        /// some work was left for the developer to do in the form of correctly setting the offset property
3118        /// and sizing the result buffer. With the introduction of the padding policy (see padding property)
3119        /// the filter can do this work itself. If you would like to have some input into what sort of MPSImage
3120        /// (e.g. temporary vs. regular) or what size it is or where it is allocated, you may set the
3121        /// destinationImageAllocator to allocate the image yourself.
3122        ///
3123        /// This method uses the MPSNNPadding padding property to figure out how to size
3124        /// the result image and to set the offset property. See discussion in MPSNeuralNetworkTypes.h.
3125        ///
3126        /// Note: the regular encodeToCommandBuffer:sourceImage: method may be used when no state is needed,
3127        /// such as when the convolution transpose operation is not balanced by a matching convolution object upstream.
3128        /// These encode methods are for auto encoders where each convolution in inference pass is coupled with convolution
3129        /// transpose. In order for convolution transpose to correctly undo the convolution downsampling, MPSCNNConvolutionGradientState
3130        /// produced by convolution is needed by convolution transpose to correctly size destination image.
3131        /// These methods are only useful for inference only network. For training, use encode methods that take MPSCNNConvolutionTransposeGradientState below.
3132        ///
3133        ///
3134        /// Parameter `commandBuffer`: The command buffer
3135        ///
3136        /// Parameter `sourceImage`: A MPSImage to use as the source images for the filter.
3137        ///
3138        /// Parameter `convolutionGradientState`: A valid MPSCNNConvolutionGradientState from the MPSCNNConvoluton counterpart to this MPSCNNConvolutionTranspose.
3139        /// If there is no forward convolution counterpart, pass NULL here. This state affects the sizing
3140        /// the result.
3141        ///
3142        /// Returns: A MPSImage or MPSTemporaryImage allocated per the destinationImageAllocator containing the output of the graph.
3143        /// The offset property will be adjusted to reflect the offset used during the encode.
3144        /// The returned image will be automatically released when the command buffer completes. If you want to
3145        /// keep it around for longer, retain the image. (ARC will do this for you if you use it later.)
3146        #[unsafe(method(encodeToCommandBuffer:sourceImage:convolutionGradientState:))]
3147        #[unsafe(method_family = none)]
3148        pub unsafe fn encodeToCommandBuffer_sourceImage_convolutionGradientState(
3149            &self,
3150            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
3151            source_image: &MPSImage,
3152            convolution_gradient_state: Option<&MPSCNNConvolutionGradientState>,
3153        ) -> Retained<MPSImage>;
3154
3155        #[cfg(all(
3156            feature = "MPSImage",
3157            feature = "MPSNDArray",
3158            feature = "MPSNNGradientState",
3159            feature = "MPSState"
3160        ))]
3161        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:convolutionGradientStates:))]
3162        #[unsafe(method_family = none)]
3163        pub unsafe fn encodeBatchToCommandBuffer_sourceImages_convolutionGradientStates(
3164            &self,
3165            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
3166            source_image: &MPSImageBatch,
3167            convolution_gradient_state: Option<&MPSCNNConvolutionGradientStateBatch>,
3168        ) -> Retained<MPSImageBatch>;
3169
3170        #[cfg(all(
3171            feature = "MPSImage",
3172            feature = "MPSNNGradientState",
3173            feature = "MPSState"
3174        ))]
3175        #[unsafe(method(encodeToCommandBuffer:sourceImage:convolutionGradientState:destinationImage:))]
3176        #[unsafe(method_family = none)]
3177        pub unsafe fn encodeToCommandBuffer_sourceImage_convolutionGradientState_destinationImage(
3178            &self,
3179            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
3180            source_image: &MPSImage,
3181            convolution_gradient_state: Option<&MPSCNNConvolutionGradientState>,
3182            destination_image: &MPSImage,
3183        );
3184
3185        #[cfg(all(
3186            feature = "MPSImage",
3187            feature = "MPSNDArray",
3188            feature = "MPSNNGradientState",
3189            feature = "MPSState"
3190        ))]
3191        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:convolutionGradientStates:destinationImages:))]
3192        #[unsafe(method_family = none)]
3193        pub unsafe fn encodeBatchToCommandBuffer_sourceImages_convolutionGradientStates_destinationImages(
3194            &self,
3195            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
3196            source_image: &MPSImageBatch,
3197            convolution_gradient_state: Option<&MPSCNNConvolutionGradientStateBatch>,
3198            destination_image: &MPSImageBatch,
3199        );
3200
3201        #[cfg(all(
3202            feature = "MPSImage",
3203            feature = "MPSNNGradientState",
3204            feature = "MPSState"
3205        ))]
3206        /// Allocate a MPCNNConvolutionTransposeGradientState to hold the results from a -encodeBatchToCommandBuffer... operation
3207        ///
3208        ///
3209        /// Parameter `sourceImage`: The MPSImage consumed by the associated -encode call.
3210        ///
3211        /// Parameter `sourceStates`: The list of MPSCNNConvolutionGradientState consumed by the associated -encode call,
3212        /// for a batch size of 1. In auto encoders, this state is produced by corresponding MPSCNNConvolution.
3213        ///
3214        ///
3215        /// Returns: The list of states produced by the -encode call for batch size of 1.
3216        /// -isResultStateReusedAcrossBatch returns YES for MPSCNNConvolutionTranspose so same
3217        /// state is used across entire batch. State object is not reusasable across batches.
3218        #[unsafe(method(resultStateForSourceImage:sourceStates:destinationImage:))]
3219        #[unsafe(method_family = none)]
3220        pub unsafe fn resultStateForSourceImage_sourceStates_destinationImage(
3221            &self,
3222            source_image: &MPSImage,
3223            source_states: Option<&NSArray<MPSCNNConvolutionGradientState>>,
3224            destination_image: &MPSImage,
3225        ) -> Option<Retained<MPSCNNConvolutionTransposeGradientState>>;
3226
3227        #[cfg(all(
3228            feature = "MPSImage",
3229            feature = "MPSNDArray",
3230            feature = "MPSNNGradientState",
3231            feature = "MPSState"
3232        ))]
3233        #[unsafe(method(resultStateBatchForSourceImage:sourceStates:destinationImage:))]
3234        #[unsafe(method_family = none)]
3235        pub unsafe fn resultStateBatchForSourceImage_sourceStates_destinationImage(
3236            &self,
3237            source_image: &MPSImageBatch,
3238            source_states: Option<&NSArray<MPSCNNConvolutionGradientStateBatch>>,
3239            destination_image: &MPSImageBatch,
3240        ) -> Option<Retained<MPSCNNConvolutionTransposeGradientStateBatch>>;
3241
3242        #[cfg(all(
3243            feature = "MPSImage",
3244            feature = "MPSNNGradientState",
3245            feature = "MPSState"
3246        ))]
3247        #[unsafe(method(temporaryResultStateForCommandBuffer:sourceImage:sourceStates:destinationImage:))]
3248        #[unsafe(method_family = none)]
3249        pub unsafe fn temporaryResultStateForCommandBuffer_sourceImage_sourceStates_destinationImage(
3250            &self,
3251            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
3252            source_image: &MPSImage,
3253            source_states: Option<&NSArray<MPSCNNConvolutionGradientState>>,
3254            destination_image: &MPSImage,
3255        ) -> Option<Retained<MPSCNNConvolutionTransposeGradientState>>;
3256
3257        #[cfg(all(
3258            feature = "MPSImage",
3259            feature = "MPSNDArray",
3260            feature = "MPSNNGradientState",
3261            feature = "MPSState"
3262        ))]
3263        #[unsafe(method(temporaryResultStateBatchForCommandBuffer:sourceImage:sourceStates:destinationImage:))]
3264        #[unsafe(method_family = none)]
3265        pub unsafe fn temporaryResultStateBatchForCommandBuffer_sourceImage_sourceStates_destinationImage(
3266            &self,
3267            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
3268            source_image: &MPSImageBatch,
3269            source_states: Option<&NSArray<MPSCNNConvolutionGradientStateBatch>>,
3270            destination_image: &MPSImageBatch,
3271        ) -> Option<Retained<MPSCNNConvolutionTransposeGradientStateBatch>>;
3272
3273        /// CPU side reload. Reload the updated weights and biases from data provider into internal weights and bias buffers. Weights and biases
3274        /// gradients needed for update are obtained from MPSCNNConvolutionTransposeGradientState object. Data provider passed in init call is used for this purpose.
3275        #[unsafe(method(reloadWeightsAndBiasesFromDataSource))]
3276        #[unsafe(method_family = none)]
3277        pub unsafe fn reloadWeightsAndBiasesFromDataSource(&self);
3278
3279        #[cfg(feature = "MPSState")]
3280        /// GPU side reload. Reload the updated weights and biases from update buffer produced by application enqueued metal kernel into internal weights
3281        /// and biases buffer. Weights and biases gradients needed for update are obtained from MPSCNNConvolutionTransposeGradientState object's gradientForWeights and gradientForBiases metal buffer.
3282        ///
3283        ///
3284        /// Parameter `commandBuffer`: Metal command buffer on which application update kernel was enqueued consuming MPSCNNConvolutionGradientState's gradientForWeights and gradientForBiases buffers
3285        /// and producing updateBuffer metal buffer.
3286        ///
3287        /// Parameter `state`: MPSCNNConvolutionWeightsAndBiasesState containing weights and biases buffers which have updated weights produced by application's update kernel.
3288        /// The state readcount will be decremented.
3289        #[unsafe(method(reloadWeightsAndBiasesWithCommandBuffer:state:))]
3290        #[unsafe(method_family = none)]
3291        pub unsafe fn reloadWeightsAndBiasesWithCommandBuffer_state(
3292            &self,
3293            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
3294            state: &MPSCNNConvolutionWeightsAndBiasesState,
3295        );
3296
3297        #[cfg(feature = "MPSState")]
3298        /// GPU side export. Enqueue a kernel to export current weights and biases stored in MPSCNNConvoltionTranspose's internal buffers into weights and biases MTLBuffer
3299        /// returned in MPSCNNConvolutionWeightsAndBiasesState.
3300        ///
3301        ///
3302        /// Parameter `commandBuffer`: Metal command buffer on which export kernel is enqueued.
3303        ///
3304        /// Parameter `resultStateCanBeTemporary`: If FALSE, state returned will be non-temporary. If TRUE, returned state may or may not be temporary.
3305        ///
3306        /// Returns: MPSCNNConvolutionWeightsAndBiasesState containing weights and biases buffer to which weights got exported. This state and be
3307        /// temporary or non-temporary depending on the flag resultStateCanBeTemporary
3308        #[unsafe(method(exportWeightsAndBiasesWithCommandBuffer:resultStateCanBeTemporary:))]
3309        #[unsafe(method_family = none)]
3310        pub unsafe fn exportWeightsAndBiasesWithCommandBuffer_resultStateCanBeTemporary(
3311            &self,
3312            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
3313            result_state_can_be_temporary: bool,
3314        ) -> Retained<MPSCNNConvolutionWeightsAndBiasesState>;
3315
3316        #[cfg(all(
3317            feature = "MPSImage",
3318            feature = "MPSNNGradientState",
3319            feature = "MPSState"
3320        ))]
3321        /// These low level encode functions should be used during training. The first two encode functions, which return
3322        /// destination image on left hand side, takes in MPSCNNConvolutionGradientState that was produced by corresponding
3323        /// MPSCNNConvolution when there is one e.g. auto encoders. This state is used to correctly size destination being returned.
3324        /// These encode methods return MPSCNNConvoltionTransposeGradientState object on auto release pool to be consumed by MPSCNNConvolutionTransposeGradient.
3325        #[unsafe(method(encodeToCommandBuffer:sourceImage:convolutionGradientState:destinationState:destinationStateIsTemporary:))]
3326        #[unsafe(method_family = none)]
3327        pub unsafe fn encodeToCommandBuffer_sourceImage_convolutionGradientState_destinationState_destinationStateIsTemporary(
3328            &self,
3329            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
3330            source_image: &MPSImage,
3331            convolution_gradient_state: Option<&MPSCNNConvolutionGradientState>,
3332            out_state: &mut Option<Retained<MPSCNNConvolutionTransposeGradientState>>,
3333            is_temporary: bool,
3334        ) -> Retained<MPSImage>;
3335
3336        #[cfg(all(
3337            feature = "MPSImage",
3338            feature = "MPSNDArray",
3339            feature = "MPSNNGradientState",
3340            feature = "MPSState"
3341        ))]
3342        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:convolutionGradientStates:destinationStates:destinationStateIsTemporary:))]
3343        #[unsafe(method_family = none)]
3344        pub unsafe fn encodeBatchToCommandBuffer_sourceImages_convolutionGradientStates_destinationStates_destinationStateIsTemporary(
3345            &self,
3346            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
3347            source_images: &MPSImageBatch,
3348            convolution_gradient_states: Option<&MPSCNNConvolutionGradientStateBatch>,
3349            out_states: &mut Option<Retained<MPSCNNConvolutionTransposeGradientStateBatch>>,
3350            is_temporary: bool,
3351        ) -> Retained<MPSImageBatch>;
3352    );
3353}
3354
3355/// Methods declared on superclass `MPSKernel`.
3356#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3357impl MPSCNNConvolutionTranspose {
3358    extern_methods!(
3359        /// Called by NSCoder to decode MPSKernels
3360        ///
3361        /// This isn't the right interface to decode a MPSKernel, but
3362        /// it is the one that NSCoder uses. To enable your NSCoder
3363        /// (e.g. NSKeyedUnarchiver) to set which device to use
3364        /// extend the object to adopt the MPSDeviceProvider
3365        /// protocol. Otherwise, the Metal system default device
3366        /// will be used.
3367        ///
3368        /// # Safety
3369        ///
3370        /// `a_decoder` possibly has further requirements.
3371        #[unsafe(method(initWithCoder:))]
3372        #[unsafe(method_family = init)]
3373        pub unsafe fn initWithCoder(
3374            this: Allocated<Self>,
3375            a_decoder: &NSCoder,
3376        ) -> Option<Retained<Self>>;
3377    );
3378}
3379
3380/// Methods declared on superclass `NSObject`.
3381#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3382impl MPSCNNConvolutionTranspose {
3383    extern_methods!(
3384        #[unsafe(method(init))]
3385        #[unsafe(method_family = init)]
3386        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
3387
3388        #[unsafe(method(new))]
3389        #[unsafe(method_family = new)]
3390        pub unsafe fn new() -> Retained<Self>;
3391    );
3392}
3393
3394extern_class!(
3395    /// Dependencies: This depends on Metal.framework
3396    ///
3397    /// The MPSCNNConvolutionTransposeGradient implementents backward propagation of gradient for MPSCNNConvolutionTranspose forward filter
3398    ///
3399    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnconvolutiontransposegradient?language=objc)
3400    #[unsafe(super(MPSCNNGradientKernel, MPSCNNBinaryKernel, MPSKernel, NSObject))]
3401    #[derive(Debug, PartialEq, Eq, Hash)]
3402    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3403    pub struct MPSCNNConvolutionTransposeGradient;
3404);
3405
3406#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3407extern_conformance!(
3408    unsafe impl NSCoding for MPSCNNConvolutionTransposeGradient {}
3409);
3410
3411#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3412extern_conformance!(
3413    unsafe impl NSCopying for MPSCNNConvolutionTransposeGradient {}
3414);
3415
3416#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3417unsafe impl CopyingHelper for MPSCNNConvolutionTransposeGradient {
3418    type Result = Self;
3419}
3420
3421#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3422extern_conformance!(
3423    unsafe impl NSObjectProtocol for MPSCNNConvolutionTransposeGradient {}
3424);
3425
3426#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3427extern_conformance!(
3428    unsafe impl NSSecureCoding for MPSCNNConvolutionTransposeGradient {}
3429);
3430
3431#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3432impl MPSCNNConvolutionTransposeGradient {
3433    extern_methods!(
3434        /// The number of feature channels per pixel in the gradient image (primarySource) of encode call. This is same is outputFeatureChannels
3435        /// or the feature channels of destination image in forward convolution i.e. dataSource.descriptor.outputFeatureChannels
3436        #[unsafe(method(sourceGradientFeatureChannels))]
3437        #[unsafe(method_family = none)]
3438        pub unsafe fn sourceGradientFeatureChannels(&self) -> NSUInteger;
3439
3440        /// The number of feature channels per pixel in the input image to forward convolution which is used here as secondarySource.
3441        /// This is same as dataSource.descriptor.inputFeatureChannels. This is also the number of feature channels in destinatin image
3442        /// here i.e. gradient with respect to data.
3443        #[unsafe(method(sourceImageFeatureChannels))]
3444        #[unsafe(method_family = none)]
3445        pub unsafe fn sourceImageFeatureChannels(&self) -> NSUInteger;
3446
3447        /// Number of groups input and output channels are divided into.
3448        #[unsafe(method(groups))]
3449        #[unsafe(method_family = none)]
3450        pub unsafe fn groups(&self) -> NSUInteger;
3451
3452        /// dataSource with which gradient object was created
3453        #[unsafe(method(dataSource))]
3454        #[unsafe(method_family = none)]
3455        pub unsafe fn dataSource(
3456            &self,
3457        ) -> Retained<ProtocolObject<dyn MPSCNNConvolutionDataSource>>;
3458
3459        /// Option to control which gradient to compute. Default is MPSCNNConvolutionGradientOptionAll
3460        /// which means both gradient with respect to data and gradient with respect to weight and bias are computed.
3461        #[unsafe(method(gradientOption))]
3462        #[unsafe(method_family = none)]
3463        pub unsafe fn gradientOption(&self) -> MPSCNNConvolutionGradientOption;
3464
3465        /// Setter for [`gradientOption`][Self::gradientOption].
3466        #[unsafe(method(setGradientOption:))]
3467        #[unsafe(method_family = none)]
3468        pub unsafe fn setGradientOption(&self, gradient_option: MPSCNNConvolutionGradientOption);
3469
3470        /// Initializes a convolution transpose gradient (with respect to weights and bias) object.
3471        ///
3472        /// Parameter `device`: The MTLDevice on which this MPSCNNConvolutionGradient filter will be used
3473        ///
3474        /// Parameter `weights`: A pointer to a object that conforms to the MPSCNNConvolutionDataSource
3475        /// protocol. Note that same data source as provided to forward convolution should be used.
3476        ///
3477        ///
3478        /// Returns: A valid MPSCNNConvolutionTransposeGradient object or nil, if failure.
3479        #[unsafe(method(initWithDevice:weights:))]
3480        #[unsafe(method_family = init)]
3481        pub unsafe fn initWithDevice_weights(
3482            this: Allocated<Self>,
3483            device: &ProtocolObject<dyn MTLDevice>,
3484            weights: &ProtocolObject<dyn MPSCNNConvolutionDataSource>,
3485        ) -> Retained<Self>;
3486
3487        /// NSSecureCoding compatability
3488        ///
3489        /// While the standard NSSecureCoding/NSCoding method
3490        /// -initWithCoder: should work, since the file can't
3491        /// know which device your data is allocated on, we
3492        /// have to guess and may guess incorrectly.  To avoid
3493        /// that problem, use initWithCoder:device instead.
3494        ///
3495        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
3496        ///
3497        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
3498        ///
3499        /// Returns: A new MPSKernel object, or nil if failure.
3500        ///
3501        /// # Safety
3502        ///
3503        /// `a_decoder` possibly has further requirements.
3504        #[unsafe(method(initWithCoder:device:))]
3505        #[unsafe(method_family = init)]
3506        pub unsafe fn initWithCoder_device(
3507            this: Allocated<Self>,
3508            a_decoder: &NSCoder,
3509            device: &ProtocolObject<dyn MTLDevice>,
3510        ) -> Option<Retained<Self>>;
3511
3512        #[unsafe(method(initWithDevice:))]
3513        #[unsafe(method_family = init)]
3514        pub unsafe fn initWithDevice(
3515            this: Allocated<Self>,
3516            device: &ProtocolObject<dyn MTLDevice>,
3517        ) -> Retained<Self>;
3518
3519        /// CPU side reload. Reload the updated weights and biases from data provider into internal weights and bias buffers. Weights and biases
3520        /// gradients needed for update are obtained from MPSCNNConvolutionGradientState object. Data provider passed in init call is used for this purpose.
3521        #[unsafe(method(reloadWeightsAndBiasesFromDataSource))]
3522        #[unsafe(method_family = none)]
3523        pub unsafe fn reloadWeightsAndBiasesFromDataSource(&self);
3524
3525        #[cfg(feature = "MPSState")]
3526        /// GPU side reload. Reload the updated weights and biases from update buffer produced by application enqueued metal kernel into internal weights
3527        /// and biases buffer. Weights and biases gradients needed for update are obtained from MPSCNNConvolutionGradientState object's gradientForWeights and gradientForBiases metal buffer.
3528        ///
3529        ///
3530        /// Parameter `commandBuffer`: Metal command buffer on which application update kernel was enqueued consuming MPSCNNConvolutionGradientState's gradientForWeights and gradientForBiases buffer
3531        /// and producing updateBuffer metal buffer.
3532        ///
3533        /// Parameter `state`: MPSCNNConvolutionWeightsAndBiasesState containing weights and biases buffers which have updated weights produced by application's update kernel.
3534        #[unsafe(method(reloadWeightsAndBiasesWithCommandBuffer:state:))]
3535        #[unsafe(method_family = none)]
3536        pub unsafe fn reloadWeightsAndBiasesWithCommandBuffer_state(
3537            &self,
3538            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
3539            state: &MPSCNNConvolutionWeightsAndBiasesState,
3540        );
3541    );
3542}
3543
3544/// Methods declared on superclass `MPSKernel`.
3545#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3546impl MPSCNNConvolutionTransposeGradient {
3547    extern_methods!(
3548        /// Called by NSCoder to decode MPSKernels
3549        ///
3550        /// This isn't the right interface to decode a MPSKernel, but
3551        /// it is the one that NSCoder uses. To enable your NSCoder
3552        /// (e.g. NSKeyedUnarchiver) to set which device to use
3553        /// extend the object to adopt the MPSDeviceProvider
3554        /// protocol. Otherwise, the Metal system default device
3555        /// will be used.
3556        ///
3557        /// # Safety
3558        ///
3559        /// `a_decoder` possibly has further requirements.
3560        #[unsafe(method(initWithCoder:))]
3561        #[unsafe(method_family = init)]
3562        pub unsafe fn initWithCoder(
3563            this: Allocated<Self>,
3564            a_decoder: &NSCoder,
3565        ) -> Option<Retained<Self>>;
3566    );
3567}
3568
3569/// Methods declared on superclass `NSObject`.
3570#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3571impl MPSCNNConvolutionTransposeGradient {
3572    extern_methods!(
3573        #[unsafe(method(init))]
3574        #[unsafe(method_family = init)]
3575        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
3576
3577        #[unsafe(method(new))]
3578        #[unsafe(method_family = new)]
3579        pub unsafe fn new() -> Retained<Self>;
3580    );
3581}
3582
3583extern_class!(
3584    /// Dependencies: This depends on Metal.framework
3585    ///
3586    /// The MPSCNNBinaryConvolution specifies a convolution with binary weights and an input image using binary approximations.
3587    /// The MPSCNNBinaryConvolution optionally first binarizes the input image and then convolves the result with a set of
3588    /// binary-valued filters, each producing one feature map in the output image (which is a normal image)
3589    ///
3590    /// The output is computed as follows:
3591    ///
3592    /// out[i, x, y, c] = ( sum_{dx,dy,f} in[i,x+dx, y+dy, f] x B[c,dx,dy,f] )
3593    /// * scale[c] * beta[i,x,y] + bias[c], where
3594    ///
3595    /// the sum over dx,dy is over the spatial filter kernel window defined by 'kernelWidth' and 'KernelHeight',
3596    /// sum over 'f' is over the input feature channel indices within group, 'B' contains the binary weights, interpreted as
3597    /// {-1,1} or { 0, 1 } and scale[c] is the 'outputScaleTerms' array and bias is the 'outputBiasTerms' array. Above 'i' is
3598    /// the image index in batch the sum over input channels 'f' runs through the group indices.
3599    ///
3600    /// The convolution operator 'x' is defined by MPSCNNBinaryConvolutionType passed in at initialization time of the filter
3601    /// (
3602    ///
3603    /// See: initWithDevice).
3604    /// In case 'type' = MPSCNNBinaryConvolutionTypeBinaryWeights, the input image is not binarized at all
3605    /// and the convolution is computed interpreting the weights as [ 0, 1 ] -> { -1, 1 } with the given scaling terms.
3606    /// In case 'type' = MPSCNNBinaryConvolutionTypeXNOR the convolution is computed by first binarizing the input image
3607    /// using the sign function 'bin(x) = x
3608    /// <
3609    /// 0 ? -1 : 1' and the convolution multiplication is done with the
3610    /// XNOR-operator !(x ^ y) = delta_xy = { (x==y) ? 1 : 0 },
3611    /// and scaled according to the optional scaling operations. Note that we output the values of the bitwise convolutions
3612    /// to interval { -1, 1 }, which means that the output of the XNOR-operator is scaled implicitly as follows:
3613    /// r = 2 * ( !(x ^ y) ) - 1 = { -1, 1 }.
3614    /// This means that for a dot-product of two 32-bit words the result is:
3615    /// r = 2 * popcount(!(x ^ y) ) - 32 = 32 - 2 * popcount( x ^ y ) = { -32, -30, ..., 30, 32 }.
3616    /// In case 'type' = MPSCNNBinaryConvolutionTypeAND the convolution is computed by first binarizing the input image
3617    /// using the sign function 'bin(x) = x
3618    /// <
3619    /// 0 ? -1 : 1' and the convolution multiplication is done with the
3620    /// AND-operator (x
3621    /// &
3622    /// y) = delta_xy * delta_x1 = { (x==y==1) ? 1 : 0 }.
3623    /// and scaled according to the optional scaling operations. Note that we output the values of the AND-operation is
3624    /// assumed to lie in { 0, 1 } interval and hence no more implicit scaling takes place.
3625    /// This means that for a dot-product of two 32-bit words the result is:
3626    /// r = popcount(x
3627    /// &
3628    /// y) = { 0, ..., 31, 32 }.
3629    ///
3630    /// The input data can be pre-offset and scaled by providing the 'inputBiasTerms' and 'inputScaleTerms' parameters for the
3631    /// initialization functions and this can be used for example to accomplish batch normalization of the data. The scaling of
3632    /// input values happens before possible beta-image computation.
3633    ///
3634    /// The parameter 'beta' above is an optional image which is used to compute scaling factors for each spatial position and image index.
3635    /// For the XNOR-Net based networks this is computed as follows: beta[i,x,y] = sum_{dx,dy} A[i, x+dx, y+dy] / (kx * ky), where
3636    /// (dx,dy) are summed over the convolution filter window [ -kx/2, (kx-1)/2], [ -ky/2, (ky-1)/2 ] and
3637    /// A[i,x,y] = sum_{c} abs( in[i,x,y,c] ) / Nc, where 'in' is the original input image (in full precision) and Nc is the
3638    /// number of input channels in the input image. Parameter 'beta' is not passed as input and to enable beta-scaling the user can
3639    /// provide 'MPSCNNBinaryConvolutionFlagsUseBetaScaling' in the flags parameter in the initialization functions.
3640    ///
3641    /// Finally the normal activation neuron is applied and the result is written to the output image.
3642    ///
3643    /// NOTE: MPSCNNBinaryConvolution does not currently support groups > 1.
3644    ///
3645    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnbinaryconvolution?language=objc)
3646    #[unsafe(super(MPSCNNKernel, MPSKernel, NSObject))]
3647    #[derive(Debug, PartialEq, Eq, Hash)]
3648    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3649    pub struct MPSCNNBinaryConvolution;
3650);
3651
3652#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3653extern_conformance!(
3654    unsafe impl NSCoding for MPSCNNBinaryConvolution {}
3655);
3656
3657#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3658extern_conformance!(
3659    unsafe impl NSCopying for MPSCNNBinaryConvolution {}
3660);
3661
3662#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3663unsafe impl CopyingHelper for MPSCNNBinaryConvolution {
3664    type Result = Self;
3665}
3666
3667#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3668extern_conformance!(
3669    unsafe impl NSObjectProtocol for MPSCNNBinaryConvolution {}
3670);
3671
3672#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3673extern_conformance!(
3674    unsafe impl NSSecureCoding for MPSCNNBinaryConvolution {}
3675);
3676
3677#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3678impl MPSCNNBinaryConvolution {
3679    extern_methods!(
3680        #[unsafe(method(inputFeatureChannels))]
3681        #[unsafe(method_family = none)]
3682        pub unsafe fn inputFeatureChannels(&self) -> NSUInteger;
3683
3684        /// The number of feature channels per pixel in the output image.
3685        #[unsafe(method(outputFeatureChannels))]
3686        #[unsafe(method_family = none)]
3687        pub unsafe fn outputFeatureChannels(&self) -> NSUInteger;
3688
3689        #[cfg(feature = "MPSNeuralNetworkTypes")]
3690        /// Initializes a binary convolution kernel with binary weights and a single scaling term.
3691        ///
3692        /// Parameter `device`: The MTLDevice on which this MPSCNNBinaryConvolution filter will be used
3693        ///
3694        /// Parameter `convolutionData`: A pointer to a object that conforms to the MPSCNNConvolutionDataSource protocol.
3695        /// The MPSCNNConvolutionDataSource protocol declares the methods that an
3696        /// instance of MPSCNNBinaryConvolution uses to obtain the weights and bias terms as
3697        /// well as the convolution descriptor.
3698        /// Each entry in the convolutionData:weights array is a 32-bit unsigned integer value
3699        /// and each bit represents one filter weight (given in machine byte order).
3700        /// The featurechannel indices increase from the least significant bit within the 32-bits.
3701        /// The number of entries is =
3702        /// ceil( inputFeatureChannels/32.0 ) * outputFeatureChannels * kernelHeight * kernelWidth
3703        /// The layout of filter weight is so that it can be reinterpreted as a 4D tensor (array)
3704        /// weight[ outputChannels ][ kernelHeight ][ kernelWidth ][ ceil( inputChannels / 32.0 ) ]
3705        /// (The ordering of the reduction from 4D tensor to 1D is per C convention. The index based on
3706        /// inputchannels varies most rapidly, followed by kernelWidth, then kernelHeight and finally
3707        /// outputChannels varies least rapidly.)
3708        ///
3709        /// Parameter `scaleValue`: A floating point value used to scale the entire convolution.
3710        ///
3711        /// Parameter `type`: What kind of binarization strategy is to be used.
3712        ///
3713        /// Parameter `flags`: See documentation above and documentation of MPSCNNBinaryConvolutionFlags.
3714        ///
3715        ///
3716        /// Returns: A valid MPSCNNBinaryConvolution object or nil, if failure.
3717        #[unsafe(method(initWithDevice:convolutionData:scaleValue:type:flags:))]
3718        #[unsafe(method_family = init)]
3719        pub unsafe fn initWithDevice_convolutionData_scaleValue_type_flags(
3720            this: Allocated<Self>,
3721            device: &ProtocolObject<dyn MTLDevice>,
3722            convolution_data: &ProtocolObject<dyn MPSCNNConvolutionDataSource>,
3723            scale_value: c_float,
3724            r#type: MPSCNNBinaryConvolutionType,
3725            flags: MPSCNNBinaryConvolutionFlags,
3726        ) -> Retained<Self>;
3727
3728        #[cfg(feature = "MPSNeuralNetworkTypes")]
3729        /// Initializes a binary convolution kernel with binary weights as well as both pre and post scaling terms.
3730        ///
3731        /// Parameter `device`: The MTLDevice on which this MPSCNNBinaryConvolution filter will be used
3732        ///
3733        /// Parameter `convolutionData`: A pointer to a object that conforms to the MPSCNNConvolutionDataSource protocol.
3734        /// The MPSCNNConvolutionDataSource protocol declares the methods that an
3735        /// instance of MPSCNNBinaryConvolution uses to obtain the weights and the convolution descriptor.
3736        /// Each entry in the convolutionData:weights array is a 32-bit unsigned integer value
3737        /// and each bit represents one filter weight (given in machine byte order).
3738        /// The featurechannel indices increase from the least significant bit within the 32-bits.
3739        /// The number of entries is =
3740        /// ceil( inputFeatureChannels/32.0 ) * outputFeatureChannels * kernelHeight * kernelWidth
3741        /// The layout of filter weight is so that it can be reinterpreted as a 4D tensor (array)
3742        /// weight[ outputChannels ][ kernelHeight ][ kernelWidth ][ ceil( inputChannels / 32.0 ) ]
3743        /// (The ordering of the reduction from 4D tensor to 1D is per C convention. The index based on
3744        /// inputchannels varies most rapidly, followed by kernelWidth, then kernelHeight and finally
3745        /// outputChannels varies least rapidly.)
3746        ///
3747        /// Parameter `outputBiasTerms`: A pointer to bias terms to be applied to the convolution output.  Each entry is a float value.
3748        /// The number of entries is = numberOfOutputFeatureMaps. If nil then 0.0 is used for bias.
3749        /// The values stored in the pointer are copied in and the array can be freed after this function returns.
3750        ///
3751        /// Parameter `outputScaleTerms`: A pointer to scale terms to be applied to binary convolution results per output feature channel.
3752        /// Each entry is a float value. The number of entries is = numberOfOutputFeatureMaps. If nil then 1.0 is used.
3753        /// The values stored in the pointer are copied in and the array can be freed after this function returns.
3754        ///
3755        /// Parameter `inputBiasTerms`: A pointer to offset terms to be applied to the input before convolution and before input scaling.
3756        /// Each entry is a float value. The number of entries is 'inputFeatureChannels'. If NULL then 0.0 is used for bias.
3757        /// The values stored in the pointer are copied in and the array can be freed after this function returns.
3758        ///
3759        /// Parameter `inputScaleTerms`: A pointer to scale terms to be applied to the input before convolution, but after input biasing.
3760        /// Each entry is a float value. The number of entries is 'inputFeatureChannels'. If nil then 1.0 is used.
3761        /// The values stored in the pointer are copied in and the array can be freed after this function returns.
3762        ///
3763        /// Parameter `type`: What kind of binarization strategy is to be used.
3764        ///
3765        /// Parameter `flags`: See documentation above and documentation of MPSCNNBinaryConvolutionFlags.
3766        ///
3767        ///
3768        /// Returns: A valid MPSCNNBinaryConvolution object or nil, if failure.
3769        ///
3770        /// # Safety
3771        ///
3772        /// - `output_bias_terms` must be a valid pointer or null.
3773        /// - `output_scale_terms` must be a valid pointer or null.
3774        /// - `input_bias_terms` must be a valid pointer or null.
3775        /// - `input_scale_terms` must be a valid pointer or null.
3776        #[unsafe(method(initWithDevice:convolutionData:outputBiasTerms:outputScaleTerms:inputBiasTerms:inputScaleTerms:type:flags:))]
3777        #[unsafe(method_family = init)]
3778        pub unsafe fn initWithDevice_convolutionData_outputBiasTerms_outputScaleTerms_inputBiasTerms_inputScaleTerms_type_flags(
3779            this: Allocated<Self>,
3780            device: &ProtocolObject<dyn MTLDevice>,
3781            convolution_data: &ProtocolObject<dyn MPSCNNConvolutionDataSource>,
3782            output_bias_terms: *const c_float,
3783            output_scale_terms: *const c_float,
3784            input_bias_terms: *const c_float,
3785            input_scale_terms: *const c_float,
3786            r#type: MPSCNNBinaryConvolutionType,
3787            flags: MPSCNNBinaryConvolutionFlags,
3788        ) -> Retained<Self>;
3789
3790        /// NSSecureCoding compatability
3791        ///
3792        /// While the standard NSSecureCoding/NSCoding method
3793        /// -initWithCoder: should work, since the file can't
3794        /// know which device your data is allocated on, we
3795        /// have to guess and may guess incorrectly.  To avoid
3796        /// that problem, use initWithCoder:device instead.
3797        ///
3798        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
3799        ///
3800        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
3801        ///
3802        /// Returns: A new MPSKernel object, or nil if failure.
3803        ///
3804        /// # Safety
3805        ///
3806        /// `a_decoder` possibly has further requirements.
3807        #[unsafe(method(initWithCoder:device:))]
3808        #[unsafe(method_family = init)]
3809        pub unsafe fn initWithCoder_device(
3810            this: Allocated<Self>,
3811            a_decoder: &NSCoder,
3812            device: &ProtocolObject<dyn MTLDevice>,
3813        ) -> Option<Retained<Self>>;
3814
3815        #[unsafe(method(initWithDevice:))]
3816        #[unsafe(method_family = init)]
3817        pub unsafe fn initWithDevice(
3818            this: Allocated<Self>,
3819            device: &ProtocolObject<dyn MTLDevice>,
3820        ) -> Retained<Self>;
3821    );
3822}
3823
3824/// Methods declared on superclass `MPSKernel`.
3825#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3826impl MPSCNNBinaryConvolution {
3827    extern_methods!(
3828        /// Called by NSCoder to decode MPSKernels
3829        ///
3830        /// This isn't the right interface to decode a MPSKernel, but
3831        /// it is the one that NSCoder uses. To enable your NSCoder
3832        /// (e.g. NSKeyedUnarchiver) to set which device to use
3833        /// extend the object to adopt the MPSDeviceProvider
3834        /// protocol. Otherwise, the Metal system default device
3835        /// will be used.
3836        ///
3837        /// # Safety
3838        ///
3839        /// `a_decoder` possibly has further requirements.
3840        #[unsafe(method(initWithCoder:))]
3841        #[unsafe(method_family = init)]
3842        pub unsafe fn initWithCoder(
3843            this: Allocated<Self>,
3844            a_decoder: &NSCoder,
3845        ) -> Option<Retained<Self>>;
3846    );
3847}
3848
3849/// Methods declared on superclass `NSObject`.
3850#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3851impl MPSCNNBinaryConvolution {
3852    extern_methods!(
3853        #[unsafe(method(init))]
3854        #[unsafe(method_family = init)]
3855        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
3856
3857        #[unsafe(method(new))]
3858        #[unsafe(method_family = new)]
3859        pub unsafe fn new() -> Retained<Self>;
3860    );
3861}
3862
3863extern_class!(
3864    /// Dependencies: This depends on Metal.framework
3865    ///
3866    /// The MPSCNNBinaryFullyConnected specifies a fully connected convolution layer with binary weights
3867    /// and optionally binarized input image.
3868    /// See
3869    /// MPSCNNFullyConnectedfor details on the fully connected layer and
3870    /// MPSCNNBinaryConvolution for binary convolutions.
3871    ///
3872    /// The default padding policy for MPSCNNBinaryConvolution is different from most
3873    /// filters. It uses MPSNNPaddingMethodSizeValidOnly instead of MPSNNPaddingMethodSizeSame.
3874    ///
3875    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnbinaryfullyconnected?language=objc)
3876    #[unsafe(super(MPSCNNBinaryConvolution, MPSCNNKernel, MPSKernel, NSObject))]
3877    #[derive(Debug, PartialEq, Eq, Hash)]
3878    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3879    pub struct MPSCNNBinaryFullyConnected;
3880);
3881
3882#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3883extern_conformance!(
3884    unsafe impl NSCoding for MPSCNNBinaryFullyConnected {}
3885);
3886
3887#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3888extern_conformance!(
3889    unsafe impl NSCopying for MPSCNNBinaryFullyConnected {}
3890);
3891
3892#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3893unsafe impl CopyingHelper for MPSCNNBinaryFullyConnected {
3894    type Result = Self;
3895}
3896
3897#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3898extern_conformance!(
3899    unsafe impl NSObjectProtocol for MPSCNNBinaryFullyConnected {}
3900);
3901
3902#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3903extern_conformance!(
3904    unsafe impl NSSecureCoding for MPSCNNBinaryFullyConnected {}
3905);
3906
3907#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
3908impl MPSCNNBinaryFullyConnected {
3909    extern_methods!(
3910        #[cfg(feature = "MPSNeuralNetworkTypes")]
3911        /// Initializes a binary fully connected kernel with binary weights and a single scaling term.
3912        ///
3913        ///
3914        /// Parameter `device`: The MTLDevice on which this MPSCNNBinaryFullyConnected filter will be used
3915        ///
3916        /// Parameter `convolutionData`: A pointer to a object that conforms to the MPSCNNConvolutionDataSource protocol.
3917        /// The MPSCNNConvolutionDataSource protocol declares the methods that an
3918        /// instance of MPSCNNBinaryFullyConnected uses to obtain the weights and bias terms as
3919        /// well as the convolution descriptor.
3920        /// Each entry in the convolutionData:weights array is a 32-bit unsigned integer value
3921        /// and each bit represents one filter weight (given in machine byte order).
3922        /// The featurechannel indices increase from the least significant bit within the 32-bits.
3923        /// The number of entries is =
3924        /// ceil( inputFeatureChannels/32.0 ) * outputFeatureChannels * kernelHeight * kernelWidth
3925        /// The layout of filter weight is so that it can be reinterpreted as a 4D tensor (array)
3926        /// weight[ outputChannels ][ kernelHeight ][ kernelWidth ][ ceil( inputChannels / 32.0 ) ]
3927        /// (The ordering of the reduction from 4D tensor to 1D is per C convention. The index based on
3928        /// inputchannels varies most rapidly, followed by kernelWidth, then kernelHeight and finally
3929        /// outputChannels varies least rapidly.)
3930        ///
3931        /// Parameter `scaleValue`: A single floating point value used to scale the entire convolution.
3932        /// Each entry is a float value. The number of entries is 'inputFeatureChannels'. If nil then 1.0 is used.
3933        ///
3934        /// Parameter `type`: What kind of binarization strategy is to be used.
3935        ///
3936        /// Parameter `flags`: See documentation above and documentation of MPSCNNBinaryConvolutionFlags.
3937        ///
3938        ///
3939        /// Returns: A valid MPSCNNBinaryFullyConnected object or nil, if failure.
3940        #[unsafe(method(initWithDevice:convolutionData:scaleValue:type:flags:))]
3941        #[unsafe(method_family = init)]
3942        pub unsafe fn initWithDevice_convolutionData_scaleValue_type_flags(
3943            this: Allocated<Self>,
3944            device: &ProtocolObject<dyn MTLDevice>,
3945            convolution_data: &ProtocolObject<dyn MPSCNNConvolutionDataSource>,
3946            scale_value: c_float,
3947            r#type: MPSCNNBinaryConvolutionType,
3948            flags: MPSCNNBinaryConvolutionFlags,
3949        ) -> Retained<Self>;
3950
3951        #[cfg(feature = "MPSNeuralNetworkTypes")]
3952        /// Initializes a binary fully connected kernel with binary weights as well as both pre and post scaling terms.
3953        ///
3954        ///
3955        /// Parameter `device`: The MTLDevice on which this MPSCNNBinaryFullyConnected filter will be used
3956        ///
3957        /// Parameter `convolutionData`: A pointer to a object that conforms to the MPSCNNConvolutionDataSource protocol.
3958        /// The MPSCNNConvolutionDataSource protocol declares the methods that an
3959        /// instance of MPSCNNBinaryFullyConnected uses to obtain the weights and the convolution descriptor.
3960        /// Each entry in the convolutionData:weights array is a 32-bit unsigned integer value
3961        /// and each bit represents one filter weight (given in machine byte order).
3962        /// The featurechannel indices increase from the least significant bit within the 32-bits.
3963        /// The number of entries is =
3964        /// ceil( inputFeatureChannels/32.0 ) * outputFeatureChannels * kernelHeight * kernelWidth
3965        /// The layout of filter weight is so that it can be reinterpreted as a 4D tensor (array)
3966        /// weight[ outputChannels ][ kernelHeight ][ kernelWidth ][ ceil( inputChannels / 32.0 ) ]
3967        /// (The ordering of the reduction from 4D tensor to 1D is per C convention. The index based on
3968        /// inputchannels varies most rapidly, followed by kernelWidth, then kernelHeight and finally
3969        /// outputChannels varies least rapidly.)
3970        ///
3971        ///
3972        /// Parameter `outputBiasTerms`: A pointer to bias terms to be applied to the convolution output.  Each entry is a float value.
3973        /// The number of entries is = numberOfOutputFeatureMaps. If nil then 0.0 is used for bias.
3974        /// The values stored in the pointer are copied in and the array can be freed after this function returns.
3975        ///
3976        /// Parameter `outputScaleTerms`: A pointer to scale terms to be applied to binary convolution results per output feature channel.
3977        /// Each entry is a float value. The number of entries is = numberOfOutputFeatureMaps. If nil then 1.0 is used.
3978        /// The values stored in the pointer are copied in and the array can be freed after this function returns.
3979        ///
3980        /// Parameter `inputBiasTerms`: A pointer to offset terms to be applied to the input before convolution and before input scaling.
3981        /// Each entry is a float value. The number of entries is 'inputFeatureChannels'. If NULL then 0.0 is used for bias.
3982        /// The values stored in the pointer are copied in and the array can be freed after this function returns.
3983        ///
3984        /// Parameter `inputScaleTerms`: A pointer to scale terms to be applied to the input before convolution, but after input biasing.
3985        /// Each entry is a float value. The number of entries is 'inputFeatureChannels'. If nil then 1.0 is used.
3986        /// The values stored in the pointer are copied in and the array can be freed after this function returns.
3987        ///
3988        /// Parameter `type`: What kind of binarization strategy is to be used.
3989        ///
3990        /// Parameter `flags`: See documentation above and documentation of MPSCNNBinaryConvolutionFlags.
3991        ///
3992        ///
3993        /// Returns: A valid MPSCNNBinaryFullyConnected object or nil, if failure.
3994        ///
3995        /// # Safety
3996        ///
3997        /// - `output_bias_terms` must be a valid pointer or null.
3998        /// - `output_scale_terms` must be a valid pointer or null.
3999        /// - `input_bias_terms` must be a valid pointer or null.
4000        /// - `input_scale_terms` must be a valid pointer or null.
4001        #[unsafe(method(initWithDevice:convolutionData:outputBiasTerms:outputScaleTerms:inputBiasTerms:inputScaleTerms:type:flags:))]
4002        #[unsafe(method_family = init)]
4003        pub unsafe fn initWithDevice_convolutionData_outputBiasTerms_outputScaleTerms_inputBiasTerms_inputScaleTerms_type_flags(
4004            this: Allocated<Self>,
4005            device: &ProtocolObject<dyn MTLDevice>,
4006            convolution_data: &ProtocolObject<dyn MPSCNNConvolutionDataSource>,
4007            output_bias_terms: *const c_float,
4008            output_scale_terms: *const c_float,
4009            input_bias_terms: *const c_float,
4010            input_scale_terms: *const c_float,
4011            r#type: MPSCNNBinaryConvolutionType,
4012            flags: MPSCNNBinaryConvolutionFlags,
4013        ) -> Retained<Self>;
4014
4015        /// NSSecureCoding compatability
4016        ///
4017        /// While the standard NSSecureCoding/NSCoding method
4018        /// -initWithCoder: should work, since the file can't
4019        /// know which device your data is allocated on, we
4020        /// have to guess and may guess incorrectly.  To avoid
4021        /// that problem, use initWithCoder:device instead.
4022        ///
4023        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
4024        ///
4025        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
4026        ///
4027        /// Returns: A new MPSKernel object, or nil if failure.
4028        ///
4029        /// # Safety
4030        ///
4031        /// `a_decoder` possibly has further requirements.
4032        #[unsafe(method(initWithCoder:device:))]
4033        #[unsafe(method_family = init)]
4034        pub unsafe fn initWithCoder_device(
4035            this: Allocated<Self>,
4036            a_decoder: &NSCoder,
4037            device: &ProtocolObject<dyn MTLDevice>,
4038        ) -> Option<Retained<Self>>;
4039
4040        #[unsafe(method(initWithDevice:))]
4041        #[unsafe(method_family = init)]
4042        pub unsafe fn initWithDevice(
4043            this: Allocated<Self>,
4044            device: &ProtocolObject<dyn MTLDevice>,
4045        ) -> Retained<Self>;
4046    );
4047}
4048
4049/// Methods declared on superclass `MPSKernel`.
4050#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4051impl MPSCNNBinaryFullyConnected {
4052    extern_methods!(
4053        /// Called by NSCoder to decode MPSKernels
4054        ///
4055        /// This isn't the right interface to decode a MPSKernel, but
4056        /// it is the one that NSCoder uses. To enable your NSCoder
4057        /// (e.g. NSKeyedUnarchiver) to set which device to use
4058        /// extend the object to adopt the MPSDeviceProvider
4059        /// protocol. Otherwise, the Metal system default device
4060        /// will be used.
4061        ///
4062        /// # Safety
4063        ///
4064        /// `a_decoder` possibly has further requirements.
4065        #[unsafe(method(initWithCoder:))]
4066        #[unsafe(method_family = init)]
4067        pub unsafe fn initWithCoder(
4068            this: Allocated<Self>,
4069            a_decoder: &NSCoder,
4070        ) -> Option<Retained<Self>>;
4071    );
4072}
4073
4074/// Methods declared on superclass `NSObject`.
4075#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4076impl MPSCNNBinaryFullyConnected {
4077    extern_methods!(
4078        #[unsafe(method(init))]
4079        #[unsafe(method_family = init)]
4080        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
4081
4082        #[unsafe(method(new))]
4083        #[unsafe(method_family = new)]
4084        pub unsafe fn new() -> Retained<Self>;
4085    );
4086}
4087
4088extern_class!(
4089    /// Dependencies: This depends on Metal.framework
4090    ///
4091    /// The MPSNNGramMatrixCalculation filter specifies a layer which computes the uncentered cross-correlation
4092    /// values between the image planes of each feature channel of an image. If the input image batch is
4093    /// x = x[b, y, x, c], where 'b' is batch index, 'y' and 'x' are the image coordinate and
4094    /// 'c' is the feature channel index then this filter computes the values:
4095    ///
4096    /// y = y[b, 1, f, c] = alpha * sum_{x,y} x[b,y,x,f] * x[b,y,x,c], where
4097    ///
4098    /// 'alpha' is a scaling factor. This operation can be interpreted to be computing all combinations
4099    /// of fully connected layers between the different image planes of the input image. The results
4100    /// are stored in the feature channel and 'x'-coordinate indices of the output batch.
4101    /// The operation is performed independently on different images in the batch.
4102    ///
4103    /// NOTE: Due to the nature of the operation this filter specifies a special padding policy
4104    /// and hence does not support non-default offset or cliprect properties.
4105    ///
4106    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpsnngrammatrixcalculation?language=objc)
4107    #[unsafe(super(MPSCNNKernel, MPSKernel, NSObject))]
4108    #[derive(Debug, PartialEq, Eq, Hash)]
4109    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4110    pub struct MPSNNGramMatrixCalculation;
4111);
4112
4113#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4114extern_conformance!(
4115    unsafe impl NSCoding for MPSNNGramMatrixCalculation {}
4116);
4117
4118#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4119extern_conformance!(
4120    unsafe impl NSCopying for MPSNNGramMatrixCalculation {}
4121);
4122
4123#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4124unsafe impl CopyingHelper for MPSNNGramMatrixCalculation {
4125    type Result = Self;
4126}
4127
4128#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4129extern_conformance!(
4130    unsafe impl NSObjectProtocol for MPSNNGramMatrixCalculation {}
4131);
4132
4133#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4134extern_conformance!(
4135    unsafe impl NSSecureCoding for MPSNNGramMatrixCalculation {}
4136);
4137
4138#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4139impl MPSNNGramMatrixCalculation {
4140    extern_methods!(
4141        /// Scaling factor for the output. Default: 1.0f.
4142        #[unsafe(method(alpha))]
4143        #[unsafe(method_family = none)]
4144        pub unsafe fn alpha(&self) -> c_float;
4145
4146        /// Setter for [`alpha`][Self::alpha].
4147        #[unsafe(method(setAlpha:))]
4148        #[unsafe(method_family = none)]
4149        pub unsafe fn setAlpha(&self, alpha: c_float);
4150
4151        /// NSSecureCoding compatability
4152        ///
4153        /// While the standard NSSecureCoding/NSCoding method
4154        /// -initWithCoder: should work, since the file can't
4155        /// know which device your data is allocated on, we
4156        /// have to guess and may guess incorrectly.  To avoid
4157        /// that problem, use initWithCoder:device instead.
4158        ///
4159        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
4160        ///
4161        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
4162        ///
4163        /// Returns: A new MPSKernel object, or nil if failure.
4164        ///
4165        /// # Safety
4166        ///
4167        /// `a_decoder` possibly has further requirements.
4168        #[unsafe(method(initWithCoder:device:))]
4169        #[unsafe(method_family = init)]
4170        pub unsafe fn initWithCoder_device(
4171            this: Allocated<Self>,
4172            a_decoder: &NSCoder,
4173            device: &ProtocolObject<dyn MTLDevice>,
4174        ) -> Option<Retained<Self>>;
4175
4176        /// Initializes a MPSNNGramMatrixCalculation kernel.
4177        ///
4178        ///
4179        /// Parameter `device`: The MTLDevice on which this MPSNNGramMatrixCalculation filter will be used.
4180        ///
4181        /// Parameter `alpha`: Scaling factor for the output.
4182        ///
4183        /// Returns: A valid MPSNNGramMatrixCalculation object or nil, if failure.
4184        #[unsafe(method(initWithDevice:alpha:))]
4185        #[unsafe(method_family = init)]
4186        pub unsafe fn initWithDevice_alpha(
4187            this: Allocated<Self>,
4188            device: &ProtocolObject<dyn MTLDevice>,
4189            alpha: c_float,
4190        ) -> Retained<Self>;
4191
4192        /// Initializes a MPSNNGramMatrixCalculation kernel with scaling factor alpha = 1.0f.
4193        ///
4194        ///
4195        /// Parameter `device`: The MTLDevice on which this MPSNNGramMatrixCalculation filter will be used.
4196        ///
4197        /// Returns: A valid MPSNNGramMatrixCalculation object or nil, if failure.
4198        #[unsafe(method(initWithDevice:))]
4199        #[unsafe(method_family = init)]
4200        pub unsafe fn initWithDevice(
4201            this: Allocated<Self>,
4202            device: &ProtocolObject<dyn MTLDevice>,
4203        ) -> Retained<Self>;
4204    );
4205}
4206
4207/// Methods declared on superclass `MPSKernel`.
4208#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4209impl MPSNNGramMatrixCalculation {
4210    extern_methods!(
4211        /// Called by NSCoder to decode MPSKernels
4212        ///
4213        /// This isn't the right interface to decode a MPSKernel, but
4214        /// it is the one that NSCoder uses. To enable your NSCoder
4215        /// (e.g. NSKeyedUnarchiver) to set which device to use
4216        /// extend the object to adopt the MPSDeviceProvider
4217        /// protocol. Otherwise, the Metal system default device
4218        /// will be used.
4219        ///
4220        /// # Safety
4221        ///
4222        /// `a_decoder` possibly has further requirements.
4223        #[unsafe(method(initWithCoder:))]
4224        #[unsafe(method_family = init)]
4225        pub unsafe fn initWithCoder(
4226            this: Allocated<Self>,
4227            a_decoder: &NSCoder,
4228        ) -> Option<Retained<Self>>;
4229    );
4230}
4231
4232/// Methods declared on superclass `NSObject`.
4233#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4234impl MPSNNGramMatrixCalculation {
4235    extern_methods!(
4236        #[unsafe(method(init))]
4237        #[unsafe(method_family = init)]
4238        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
4239
4240        #[unsafe(method(new))]
4241        #[unsafe(method_family = new)]
4242        pub unsafe fn new() -> Retained<Self>;
4243    );
4244}
4245
4246extern_class!(
4247    /// Dependencies: This depends on Metal.framework
4248    ///
4249    /// The MPSNNGramMatrixCalculationGradient defines the gradient filter for MPSNNGramMatrixCalculation.
4250    ///
4251    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpsnngrammatrixcalculationgradient?language=objc)
4252    #[unsafe(super(MPSCNNGradientKernel, MPSCNNBinaryKernel, MPSKernel, NSObject))]
4253    #[derive(Debug, PartialEq, Eq, Hash)]
4254    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4255    pub struct MPSNNGramMatrixCalculationGradient;
4256);
4257
4258#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4259extern_conformance!(
4260    unsafe impl NSCoding for MPSNNGramMatrixCalculationGradient {}
4261);
4262
4263#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4264extern_conformance!(
4265    unsafe impl NSCopying for MPSNNGramMatrixCalculationGradient {}
4266);
4267
4268#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4269unsafe impl CopyingHelper for MPSNNGramMatrixCalculationGradient {
4270    type Result = Self;
4271}
4272
4273#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4274extern_conformance!(
4275    unsafe impl NSObjectProtocol for MPSNNGramMatrixCalculationGradient {}
4276);
4277
4278#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4279extern_conformance!(
4280    unsafe impl NSSecureCoding for MPSNNGramMatrixCalculationGradient {}
4281);
4282
4283#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4284impl MPSNNGramMatrixCalculationGradient {
4285    extern_methods!(
4286        /// Scaling factor for the output. Default: 1.0f. NOTE: the value for alpha is automatically adjusted by
4287        /// the
4288        /// MPSNNGradientStatewhen it is provided in the encode call.
4289        #[unsafe(method(alpha))]
4290        #[unsafe(method_family = none)]
4291        pub unsafe fn alpha(&self) -> c_float;
4292
4293        /// Setter for [`alpha`][Self::alpha].
4294        #[unsafe(method(setAlpha:))]
4295        #[unsafe(method_family = none)]
4296        pub unsafe fn setAlpha(&self, alpha: c_float);
4297
4298        /// NSSecureCoding compatability
4299        ///
4300        /// While the standard NSSecureCoding/NSCoding method
4301        /// -initWithCoder: should work, since the file can't
4302        /// know which device your data is allocated on, we
4303        /// have to guess and may guess incorrectly.  To avoid
4304        /// that problem, use initWithCoder:device instead.
4305        ///
4306        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
4307        ///
4308        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
4309        ///
4310        /// Returns: A new MPSKernel object, or nil if failure.
4311        ///
4312        /// # Safety
4313        ///
4314        /// `a_decoder` possibly has further requirements.
4315        #[unsafe(method(initWithCoder:device:))]
4316        #[unsafe(method_family = init)]
4317        pub unsafe fn initWithCoder_device(
4318            this: Allocated<Self>,
4319            a_decoder: &NSCoder,
4320            device: &ProtocolObject<dyn MTLDevice>,
4321        ) -> Option<Retained<Self>>;
4322
4323        /// Initializes a MPSNNGramMatrixCalculationGradient kernel.
4324        ///
4325        ///
4326        /// Parameter `device`: The MTLDevice on which this MPSNNGramMatrixCalculationGradient filter will be used.
4327        ///
4328        /// Parameter `alpha`: Scaling factor for the output. NOTE: the value for alpha is automatically adjusted by
4329        /// the
4330        /// MPSNNGradientStatewhen it is provided in the encode call.
4331        ///
4332        /// Returns: A valid MPSNNGramMatrixCalculationGradient object or nil, if failure.
4333        #[unsafe(method(initWithDevice:alpha:))]
4334        #[unsafe(method_family = init)]
4335        pub unsafe fn initWithDevice_alpha(
4336            this: Allocated<Self>,
4337            device: &ProtocolObject<dyn MTLDevice>,
4338            alpha: c_float,
4339        ) -> Retained<Self>;
4340
4341        /// Initializes a MPSNNGramMatrixCalculationGradient kernel with scaling factor alpha = 1.0f.
4342        ///
4343        ///
4344        /// Parameter `device`: The MTLDevice on which this MPSNNGramMatrixCalculationGradient filter will be used.
4345        ///
4346        /// Returns: A valid MPSNNGramMatrixCalculationGradient object or nil, if failure.
4347        #[unsafe(method(initWithDevice:))]
4348        #[unsafe(method_family = init)]
4349        pub unsafe fn initWithDevice(
4350            this: Allocated<Self>,
4351            device: &ProtocolObject<dyn MTLDevice>,
4352        ) -> Retained<Self>;
4353    );
4354}
4355
4356/// Methods declared on superclass `MPSKernel`.
4357#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4358impl MPSNNGramMatrixCalculationGradient {
4359    extern_methods!(
4360        /// Called by NSCoder to decode MPSKernels
4361        ///
4362        /// This isn't the right interface to decode a MPSKernel, but
4363        /// it is the one that NSCoder uses. To enable your NSCoder
4364        /// (e.g. NSKeyedUnarchiver) to set which device to use
4365        /// extend the object to adopt the MPSDeviceProvider
4366        /// protocol. Otherwise, the Metal system default device
4367        /// will be used.
4368        ///
4369        /// # Safety
4370        ///
4371        /// `a_decoder` possibly has further requirements.
4372        #[unsafe(method(initWithCoder:))]
4373        #[unsafe(method_family = init)]
4374        pub unsafe fn initWithCoder(
4375            this: Allocated<Self>,
4376            a_decoder: &NSCoder,
4377        ) -> Option<Retained<Self>>;
4378    );
4379}
4380
4381/// Methods declared on superclass `NSObject`.
4382#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
4383impl MPSNNGramMatrixCalculationGradient {
4384    extern_methods!(
4385        #[unsafe(method(init))]
4386        #[unsafe(method_family = init)]
4387        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
4388
4389        #[unsafe(method(new))]
4390        #[unsafe(method_family = new)]
4391        pub unsafe fn new() -> Retained<Self>;
4392    );
4393}