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}