objc2_metal_performance_shaders/generated/MPSNeuralNetwork/
MPSCNNLoss.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 MPSCNNLossDataDescriptor specifies a loss data descriptor.
15    /// The same descriptor can be used to initialize both the
16    /// labels and the optional weights data.
17    ///
18    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnlossdatadescriptor?language=objc)
19    #[unsafe(super(NSObject))]
20    #[derive(Debug, PartialEq, Eq, Hash)]
21    pub struct MPSCNNLossDataDescriptor;
22);
23
24extern_conformance!(
25    unsafe impl NSCopying for MPSCNNLossDataDescriptor {}
26);
27
28unsafe impl CopyingHelper for MPSCNNLossDataDescriptor {
29    type Result = Self;
30}
31
32extern_conformance!(
33    unsafe impl NSObjectProtocol for MPSCNNLossDataDescriptor {}
34);
35
36impl MPSCNNLossDataDescriptor {
37    extern_methods!(
38        #[cfg(all(feature = "MPSCore", feature = "MPSImage"))]
39        /// Data layout of loss data. See MPSImage.h for more information.
40        ///
41        /// This parameter specifies the layout of loss data.
42        #[unsafe(method(layout))]
43        #[unsafe(method_family = none)]
44        pub unsafe fn layout(&self) -> MPSDataLayout;
45
46        /// Size of loss data: (width, height, feature channels}.
47        ///
48        /// This parameter specifies the size of loss data.
49        #[unsafe(method(size))]
50        #[unsafe(method_family = none)]
51        pub unsafe fn size(&self) -> MTLSize;
52
53        /// Row bytes of loss data.
54        ///
55        /// This parameter specifies the row bytes of loss data.
56        #[unsafe(method(bytesPerRow))]
57        #[unsafe(method_family = none)]
58        pub unsafe fn bytesPerRow(&self) -> NSUInteger;
59
60        /// Setter for [`bytesPerRow`][Self::bytesPerRow].
61        #[unsafe(method(setBytesPerRow:))]
62        #[unsafe(method_family = none)]
63        pub unsafe fn setBytesPerRow(&self, bytes_per_row: NSUInteger);
64
65        /// Slice bytes of loss data.
66        ///
67        /// This parameter specifies the slice bytes of loss data.
68        #[unsafe(method(bytesPerImage))]
69        #[unsafe(method_family = none)]
70        pub unsafe fn bytesPerImage(&self) -> NSUInteger;
71
72        /// Setter for [`bytesPerImage`][Self::bytesPerImage].
73        #[unsafe(method(setBytesPerImage:))]
74        #[unsafe(method_family = none)]
75        pub unsafe fn setBytesPerImage(&self, bytes_per_image: NSUInteger);
76
77        #[unsafe(method(init))]
78        #[unsafe(method_family = init)]
79        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
80
81        #[cfg(all(feature = "MPSCore", feature = "MPSImage"))]
82        /// Make a descriptor loss data. The bytesPerRow and bytesPerImage
83        /// are automatically calculated assuming a dense array. If it is
84        /// not a dense array, adjust bytesPerRow and bytesPerImage to the
85        /// right value by changing properties.
86        ///
87        /// Parameter `data`: The per-element loss data. The data must be in floating point format.
88        ///
89        /// Parameter `layout`: The data layout of loss data.
90        ///
91        /// Parameter `size`: The size of loss data.
92        ///
93        /// Returns: A valid MPSCNNLossDataDescriptor object or nil, if failure.
94        #[unsafe(method(cnnLossDataDescriptorWithData:layout:size:))]
95        #[unsafe(method_family = none)]
96        pub unsafe fn cnnLossDataDescriptorWithData_layout_size(
97            data: &NSData,
98            layout: MPSDataLayout,
99            size: MTLSize,
100        ) -> Option<Retained<MPSCNNLossDataDescriptor>>;
101    );
102}
103
104/// Methods declared on superclass `NSObject`.
105impl MPSCNNLossDataDescriptor {
106    extern_methods!(
107        #[unsafe(method(new))]
108        #[unsafe(method_family = new)]
109        pub unsafe fn new() -> Retained<Self>;
110    );
111}
112
113extern_class!(
114    /// Dependencies: This depends on Metal.framework.
115    ///
116    /// The MPSCNNLossLabels is used to hold the per-element weights buffer
117    /// used by both MPSCNNLoss forward filter and MPSNNLossGradient backward filter.
118    /// The MPSCNNLoss forward filter populates the MPSCNNLossLabels object
119    /// and the MPSNNLossGradient backward filter consumes the state object.
120    ///
121    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnlosslabels?language=objc)
122    #[unsafe(super(MPSState, NSObject))]
123    #[derive(Debug, PartialEq, Eq, Hash)]
124    #[cfg(all(feature = "MPSCore", feature = "MPSState"))]
125    pub struct MPSCNNLossLabels;
126);
127
128#[cfg(all(feature = "MPSCore", feature = "MPSState"))]
129extern_conformance!(
130    unsafe impl NSObjectProtocol for MPSCNNLossLabels {}
131);
132
133#[cfg(all(feature = "MPSCore", feature = "MPSState"))]
134impl MPSCNNLossLabels {
135    extern_methods!(
136        /// Use one of the interfaces below instead.
137        #[unsafe(method(init))]
138        #[unsafe(method_family = init)]
139        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
140
141        /// Set labels (aka targets, ground truth) for the MPSCNNLossLabels object.
142        ///
143        /// The labels and weights data are copied into internal storage. The computed loss can either be a
144        /// scalar value (in batch mode, a single value per image in a batch) or it
145        /// can be one value per feature channel. Thus, the size of the loss image
146        /// must either match the size of the input source image or be {1, 1, 1},
147        /// which results in a scalar value. In this convinience initializer, the
148        /// assumed size of the loss image is {1, 1, 1}.
149        ///
150        /// Parameter `device`: Device the state resources will be created on.
151        ///
152        /// Parameter `labelsDescriptor`: Describes the labels data. This includes:
153        /// - The per-element labels data. The data must be in floating point format.
154        /// - Data layout of labels data. See MPSImage.h for more information.
155        /// - Size of labels data: (width, height, feature channels}.
156        /// - Optionally, row bytes of labels data.
157        /// - Optionally, slice bytes of labels data.
158        #[unsafe(method(initWithDevice:labelsDescriptor:))]
159        #[unsafe(method_family = init)]
160        pub unsafe fn initWithDevice_labelsDescriptor(
161            this: Allocated<Self>,
162            device: &ProtocolObject<dyn MTLDevice>,
163            labels_descriptor: &MPSCNNLossDataDescriptor,
164        ) -> Retained<Self>;
165
166        /// Set labels (aka targets, ground truth) and weights for the MPSCNNLossLabels object.
167        /// Weights are optional.
168        ///
169        /// The labels and weights data are copied into internal storage.
170        ///
171        /// Parameter `device`: Device the state resources will be created on.
172        ///
173        /// Parameter `lossImageSize`: The size of the resulting loss image: { width, height, featureChannels }.
174        /// The computed loss can either be a scalar value (in batch mode, a single
175        /// value per image in a batch) or it can be one value per feature channel.
176        /// Thus, the size of the loss image must either match the size of the input
177        /// source image or be {1, 1, 1}, which results in a scalar value.
178        ///
179        /// Parameter `labelsDescriptor`: Describes the labels data. This includes:
180        /// - The per-element labels data. The data must be in floating point format.
181        /// - Data layout of labels data. See MPSImage.h for more information.
182        /// - Size of labels data: (width, height, feature channels}.
183        /// - Optionally, row bytes of labels data.
184        /// - Optionally, slice bytes of labels data.
185        ///
186        /// Parameter `weightsDescriptor`: Describes the weights data. This includes:
187        /// - The per-element weights data. The data must be in floating point format.
188        /// - Data layout of weights data. See MPSImage.h for more information.
189        /// - Size of weights data: (width, height, feature channels}.
190        /// - Optionally, row bytes of weights data.
191        /// - Optionally, slice bytes of weights data.
192        /// This parameter is optional. If you are using a single weight, please use the
193        /// weight property of the MPSCNNLossDescriptor object.
194        #[unsafe(method(initWithDevice:lossImageSize:labelsDescriptor:weightsDescriptor:))]
195        #[unsafe(method_family = init)]
196        pub unsafe fn initWithDevice_lossImageSize_labelsDescriptor_weightsDescriptor(
197            this: Allocated<Self>,
198            device: &ProtocolObject<dyn MTLDevice>,
199            loss_image_size: MTLSize,
200            labels_descriptor: &MPSCNNLossDataDescriptor,
201            weights_descriptor: Option<&MPSCNNLossDataDescriptor>,
202        ) -> Retained<Self>;
203
204        #[cfg(feature = "MPSImage")]
205        /// Set labels (aka targets, ground truth) and weights for the MPSCNNLossLabels object.
206        /// Weights are optional.
207        ///
208        /// The labels and weights images are retained - it is the users responsibility to make sure that they contain
209        /// the right data when the loss filter is run on the device.
210        ///
211        /// Parameter `device`: Device the state resources will be created on.
212        ///
213        /// Parameter `lossImageSize`: The size of the resulting loss image: { width, height, featureChannels }.
214        /// The computed loss can either be a scalar value (in batch mode, a single
215        /// value per image in a batch) or it can be one value per feature channel.
216        /// Thus, the size of the loss image must either match the size of the input
217        /// source image or be {1, 1, 1}, which results in a scalar value.
218        ///
219        /// Parameter `labelsImage`: Describes the labels data.
220        ///
221        /// Parameter `weightsImage`: Describes the weights data.
222        /// This parameter is optional. If you are using a single weight, please use the
223        /// weight property of the MPSCNNLossDescriptor object.
224        #[unsafe(method(initWithDevice:lossImageSize:labelsImage:weightsImage:))]
225        #[unsafe(method_family = init)]
226        pub unsafe fn initWithDevice_lossImageSize_labelsImage_weightsImage(
227            this: Allocated<Self>,
228            device: &ProtocolObject<dyn MTLDevice>,
229            loss_image_size: MTLSize,
230            labels_image: &MPSImage,
231            weights_image: Option<&MPSImage>,
232        ) -> Retained<Self>;
233
234        #[cfg(feature = "MPSImage")]
235        /// Loss image accessor method.
236        ///
237        /// Returns: An autoreleased MPSImage object, containing the loss data.
238        /// The loss data is populated in the -encode call, thus the contents
239        /// are undefined until you -encode the filter.
240        ///
241        /// In order to guarantee that the image is correctly synchronized for CPU side access,
242        /// it is the application's responsibility to call the [gradientState synchronizeOnCommandBuffer:]
243        /// method before accessing the data in the image.
244        #[unsafe(method(lossImage))]
245        #[unsafe(method_family = none)]
246        pub unsafe fn lossImage(&self) -> Retained<MPSImage>;
247
248        #[cfg(feature = "MPSImage")]
249        /// Labels image accessor method.
250        ///
251        /// Returns: An autoreleased MPSImage object, containing the labels data.
252        /// The labels data is populated in the -initWithDevice call.
253        ///
254        /// In order to guarantee that the image is correctly synchronized for CPU side access,
255        /// it is the application's responsibility to call the [gradientState synchronizeOnCommandBuffer:]
256        /// method before accessing the data in the image.
257        #[unsafe(method(labelsImage))]
258        #[unsafe(method_family = none)]
259        pub unsafe fn labelsImage(&self) -> Retained<MPSImage>;
260
261        #[cfg(feature = "MPSImage")]
262        /// Weights image accessor method.
263        ///
264        /// Returns: An autoreleased MPSImage object, containing the weights data.
265        /// The weights data is populated in the -initWithDevice call.
266        ///
267        /// In order to guarantee that the image is correctly synchronized for CPU side access,
268        /// it is the application's responsibility to call the [gradientState synchronizeOnCommandBuffer:]
269        /// method before accessing the data in the image.
270        #[unsafe(method(weightsImage))]
271        #[unsafe(method_family = none)]
272        pub unsafe fn weightsImage(&self) -> Retained<MPSImage>;
273    );
274}
275
276/// Methods declared on superclass `MPSState`.
277#[cfg(all(feature = "MPSCore", feature = "MPSState"))]
278impl MPSCNNLossLabels {
279    extern_methods!(
280        /// Create a MPSState holding a temporary MTLBuffer
281        ///
282        /// Parameter `cmdBuf`: The command buffer against which the temporary resource is allocated
283        ///
284        /// Parameter `bufferSize`: The size of the buffer in bytes
285        #[unsafe(method(temporaryStateWithCommandBuffer:bufferSize:))]
286        #[unsafe(method_family = none)]
287        pub unsafe fn temporaryStateWithCommandBuffer_bufferSize(
288            cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
289            buffer_size: usize,
290        ) -> Retained<Self>;
291
292        /// Create a MPSState holding a temporary MTLTexture
293        ///
294        /// Parameter `cmdBuf`: The command buffer against which the temporary resource is allocated
295        ///
296        /// Parameter `descriptor`: A descriptor for the new temporary texture
297        #[unsafe(method(temporaryStateWithCommandBuffer:textureDescriptor:))]
298        #[unsafe(method_family = none)]
299        pub unsafe fn temporaryStateWithCommandBuffer_textureDescriptor(
300            cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
301            descriptor: &MTLTextureDescriptor,
302        ) -> Retained<Self>;
303
304        /// Create a new autoreleased temporary state object without underlying resource
305        ///
306        /// Parameter `cmdBuf`: The command buffer with which the temporary resource is associated
307        #[unsafe(method(temporaryStateWithCommandBuffer:))]
308        #[unsafe(method_family = none)]
309        pub unsafe fn temporaryStateWithCommandBuffer(
310            cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
311        ) -> Retained<Self>;
312
313        #[unsafe(method(initWithDevice:bufferSize:))]
314        #[unsafe(method_family = init)]
315        pub unsafe fn initWithDevice_bufferSize(
316            this: Allocated<Self>,
317            device: &ProtocolObject<dyn MTLDevice>,
318            buffer_size: usize,
319        ) -> Retained<Self>;
320
321        #[unsafe(method(initWithDevice:textureDescriptor:))]
322        #[unsafe(method_family = init)]
323        pub unsafe fn initWithDevice_textureDescriptor(
324            this: Allocated<Self>,
325            device: &ProtocolObject<dyn MTLDevice>,
326            descriptor: &MTLTextureDescriptor,
327        ) -> Retained<Self>;
328
329        /// Create a MPSState with a non-temporary MTLResource
330        ///
331        /// Parameter `resource`: A MTLBuffer or MTLTexture. May be nil.
332        ///
333        /// # Safety
334        ///
335        /// - `resource` may need to be synchronized.
336        /// - `resource` may be unretained, you must ensure it is kept alive while in use.
337        #[unsafe(method(initWithResource:))]
338        #[unsafe(method_family = init)]
339        pub unsafe fn initWithResource(
340            this: Allocated<Self>,
341            resource: Option<&ProtocolObject<dyn MTLResource>>,
342        ) -> Retained<Self>;
343
344        /// Initialize a non-temporary state to hold a number of textures and buffers
345        ///
346        /// The allocation of each resource will be deferred  until it is needed.
347        /// This occurs when -resource or -resourceAtIndex: is called.
348        ///
349        /// Parameter `resourceList`: The list of resources to create.
350        #[unsafe(method(initWithDevice:resourceList:))]
351        #[unsafe(method_family = init)]
352        pub unsafe fn initWithDevice_resourceList(
353            this: Allocated<Self>,
354            device: &ProtocolObject<dyn MTLDevice>,
355            resource_list: &MPSStateResourceList,
356        ) -> Retained<Self>;
357
358        /// Initialize a temporary state to hold a number of textures and buffers
359        ///
360        /// The textures occur first in sequence
361        #[unsafe(method(temporaryStateWithCommandBuffer:resourceList:))]
362        #[unsafe(method_family = none)]
363        pub unsafe fn temporaryStateWithCommandBuffer_resourceList(
364            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
365            resource_list: &MPSStateResourceList,
366        ) -> Retained<Self>;
367
368        /// Create a state object with a list of MTLResources
369        ///
370        /// Because MPS prefers deferred allocation of resources
371        /// your application should use -initWithTextures:bufferSizes:bufferCount:
372        /// whenever possible. This method is useful for cases when the
373        /// MTLResources must be initialized by the CPU.
374        ///
375        /// # Safety
376        ///
377        /// - `resources` generic may need to be synchronized.
378        /// - `resources` generic may be unretained, you must ensure it is kept alive while in use.
379        #[unsafe(method(initWithResources:))]
380        #[unsafe(method_family = init)]
381        pub unsafe fn initWithResources(
382            this: Allocated<Self>,
383            resources: Option<&NSArray<ProtocolObject<dyn MTLResource>>>,
384        ) -> Retained<Self>;
385    );
386}
387
388/// Methods declared on superclass `NSObject`.
389#[cfg(all(feature = "MPSCore", feature = "MPSState"))]
390impl MPSCNNLossLabels {
391    extern_methods!(
392        #[unsafe(method(new))]
393        #[unsafe(method_family = new)]
394        pub unsafe fn new() -> Retained<Self>;
395    );
396}
397
398/// [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnlosslabelsbatch?language=objc)
399#[cfg(all(feature = "MPSCore", feature = "MPSState"))]
400pub type MPSCNNLossLabelsBatch = NSArray<MPSCNNLossLabels>;
401
402extern_class!(
403    /// Dependencies: This depends on Metal.framework.
404    ///
405    /// The MPSCNNLossDescriptor specifies a loss filter descriptor.
406    /// The same descriptor can be used to initialize both the
407    /// MPSCNNLoss and the MPSNNLossGradient filters.
408    ///
409    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnlossdescriptor?language=objc)
410    #[unsafe(super(NSObject))]
411    #[derive(Debug, PartialEq, Eq, Hash)]
412    pub struct MPSCNNLossDescriptor;
413);
414
415extern_conformance!(
416    unsafe impl NSCopying for MPSCNNLossDescriptor {}
417);
418
419unsafe impl CopyingHelper for MPSCNNLossDescriptor {
420    type Result = Self;
421}
422
423extern_conformance!(
424    unsafe impl NSObjectProtocol for MPSCNNLossDescriptor {}
425);
426
427impl MPSCNNLossDescriptor {
428    extern_methods!(
429        #[cfg(feature = "MPSCNNTypes")]
430        /// The type of a loss filter.
431        ///
432        /// This parameter specifies the type of a loss filter.
433        #[unsafe(method(lossType))]
434        #[unsafe(method_family = none)]
435        pub unsafe fn lossType(&self) -> MPSCNNLossType;
436
437        #[cfg(feature = "MPSCNNTypes")]
438        /// Setter for [`lossType`][Self::lossType].
439        #[unsafe(method(setLossType:))]
440        #[unsafe(method_family = none)]
441        pub unsafe fn setLossType(&self, loss_type: MPSCNNLossType);
442
443        #[cfg(feature = "MPSCNNTypes")]
444        /// The type of a reduction operation performed in the loss filter.
445        ///
446        /// This parameter specifies the type of a reduction operation
447        /// performed in the loss filter.
448        #[unsafe(method(reductionType))]
449        #[unsafe(method_family = none)]
450        pub unsafe fn reductionType(&self) -> MPSCNNReductionType;
451
452        #[cfg(feature = "MPSCNNTypes")]
453        /// Setter for [`reductionType`][Self::reductionType].
454        #[unsafe(method(setReductionType:))]
455        #[unsafe(method_family = none)]
456        pub unsafe fn setReductionType(&self, reduction_type: MPSCNNReductionType);
457
458        /// If set to YES then the reduction operation is applied also across the batch-index dimension,
459        /// ie. the loss value is summed over images in the batch and the result of the reduction is written
460        /// on the first loss image in the batch while the other loss images will be set to zero.
461        /// If set to NO, then no reductions are performed across the batch dimension and each image in the batch
462        /// will contain the loss value associated with that one particular image.
463        /// NOTE: If reductionType == MPSCNNReductionTypeNone, then this flag has no effect on results,
464        /// that is no reductions are done in this case.
465        /// NOTE: If reduceAcrossBatch is set to YES and reductionType == MPSCNNReductionTypeMean then
466        /// the final forward loss value is computed by first summing over the components and then by
467        /// dividing the result with: number of feature channels * width * height * number of images in the batch.
468        /// The default value is NO.
469        #[unsafe(method(reduceAcrossBatch))]
470        #[unsafe(method_family = none)]
471        pub unsafe fn reduceAcrossBatch(&self) -> bool;
472
473        /// Setter for [`reduceAcrossBatch`][Self::reduceAcrossBatch].
474        #[unsafe(method(setReduceAcrossBatch:))]
475        #[unsafe(method_family = none)]
476        pub unsafe fn setReduceAcrossBatch(&self, reduce_across_batch: bool);
477
478        /// The scale factor to apply to each element of a result.
479        ///
480        /// Each element of a result is multiplied by the weight value.
481        /// The default value is 1.0f.
482        #[unsafe(method(weight))]
483        #[unsafe(method_family = none)]
484        pub unsafe fn weight(&self) -> c_float;
485
486        /// Setter for [`weight`][Self::weight].
487        #[unsafe(method(setWeight:))]
488        #[unsafe(method_family = none)]
489        pub unsafe fn setWeight(&self, weight: c_float);
490
491        /// The label smoothing parameter. The default value is 0.0f.
492        ///
493        /// This parameter is valid only for the loss functions of the following type(s):
494        /// MPSCNNLossFunctionTypeSoftmaxCrossEntropy, MPSCNNLossFunctionTypeSigmoidCrossEntropy.
495        ///
496        /// MPSCNNLossFunctionTypeSoftmaxCrossEntropy: given labels (ground truth), it is applied in the following way:
497        /// labels = labelSmoothing > 0 ? labels * (1 - labelSmoothing) + labelSmoothing / numberOfClasses : labels
498        ///
499        /// MPSCNNLossFunctionTypeSigmoidCrossEntropy: given labels (ground truth), it is applied in the following way:
500        /// labels = labelSmoothing > 0 ? labels * (1 - labelSmoothing) + 0.5 * labelSmoothing : labels
501        #[unsafe(method(labelSmoothing))]
502        #[unsafe(method_family = none)]
503        pub unsafe fn labelSmoothing(&self) -> c_float;
504
505        /// Setter for [`labelSmoothing`][Self::labelSmoothing].
506        #[unsafe(method(setLabelSmoothing:))]
507        #[unsafe(method_family = none)]
508        pub unsafe fn setLabelSmoothing(&self, label_smoothing: c_float);
509
510        /// The number of classes parameter. The default value is 1.
511        ///
512        /// This parameter is valid only for the loss functions of the following type(s):
513        /// MPSCNNLossFunctionTypeSoftmaxCrossEntropy.
514        ///
515        /// Given labels (ground truth), it is applied in the following way:
516        /// labels = labelSmoothing > 0 ? labels * (1 - labelSmoothing) + labelSmoothing / numberOfClasses : labels
517        #[unsafe(method(numberOfClasses))]
518        #[unsafe(method_family = none)]
519        pub unsafe fn numberOfClasses(&self) -> NSUInteger;
520
521        /// Setter for [`numberOfClasses`][Self::numberOfClasses].
522        #[unsafe(method(setNumberOfClasses:))]
523        #[unsafe(method_family = none)]
524        pub unsafe fn setNumberOfClasses(&self, number_of_classes: NSUInteger);
525
526        /// The epsilon parameter. The default value is 1e-7.
527        ///
528        /// This parameter is valid only for the loss functions of the following type(s):
529        /// MPSCNNLossTypeLog.
530        ///
531        /// Given predictions and labels (ground truth), it is applied in the following way:
532        /// -(labels * log(predictions + epsilon)) - ((1 - labels) * log(1 - predictions + epsilon))
533        #[unsafe(method(epsilon))]
534        #[unsafe(method_family = none)]
535        pub unsafe fn epsilon(&self) -> c_float;
536
537        /// Setter for [`epsilon`][Self::epsilon].
538        #[unsafe(method(setEpsilon:))]
539        #[unsafe(method_family = none)]
540        pub unsafe fn setEpsilon(&self, epsilon: c_float);
541
542        /// The delta parameter. The default value is 1.0f.
543        ///
544        /// This parameter is valid only for the loss functions of the following type(s):
545        /// MPSCNNLossTypeHuber.
546        ///
547        /// Given predictions and labels (ground truth), it is applied in the following way:
548        /// if (|predictions - labels|
549        /// <
550        /// = delta, loss = 0.5f * predictions^2
551        /// if (|predictions - labels| >  delta, loss = 0.5 * delta^2 + delta * (|predictions - labels| - delta)
552        #[unsafe(method(delta))]
553        #[unsafe(method_family = none)]
554        pub unsafe fn delta(&self) -> c_float;
555
556        /// Setter for [`delta`][Self::delta].
557        #[unsafe(method(setDelta:))]
558        #[unsafe(method_family = none)]
559        pub unsafe fn setDelta(&self, delta: c_float);
560
561        #[unsafe(method(init))]
562        #[unsafe(method_family = init)]
563        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
564
565        #[cfg(feature = "MPSCNNTypes")]
566        /// Make a descriptor for a MPSCNNLoss or MPSNNLossGradient object.
567        ///
568        /// Parameter `lossType`: The type of a loss filter.
569        ///
570        /// Parameter `reductionType`: The type of a reduction operation to apply.
571        /// This argument is ignored in the MPSNNLossGradient filter.
572        ///
573        /// Returns: A valid MPSCNNLossDescriptor object or nil, if failure.
574        #[unsafe(method(cnnLossDescriptorWithType:reductionType:))]
575        #[unsafe(method_family = none)]
576        pub unsafe fn cnnLossDescriptorWithType_reductionType(
577            loss_type: MPSCNNLossType,
578            reduction_type: MPSCNNReductionType,
579        ) -> Retained<MPSCNNLossDescriptor>;
580    );
581}
582
583/// Methods declared on superclass `NSObject`.
584impl MPSCNNLossDescriptor {
585    extern_methods!(
586        #[unsafe(method(new))]
587        #[unsafe(method_family = new)]
588        pub unsafe fn new() -> Retained<Self>;
589    );
590}
591
592extern_class!(
593    /// Dependencies: This depends on Metal.framework.
594    ///
595    /// The MPSCNNLoss filter is only used for training. This filter performs both the forward and
596    /// backward pass computations. Specifically, it computes the loss between the input (predictions)
597    /// and target data (labels) and the loss gradient. The loss value can be a 1 x 1 x 1 image containing
598    /// a scalar loss value or an image (of the same size as the input source image) with per feature
599    /// channel losses. The loss value is used to determine whether to continue the training operation or
600    /// to terminate it, once satisfactory results are achieved. The loss gradient is the first gradient
601    /// computed for the backward pass and serves as input to the next gradient filter (in the backward
602    /// direction).
603    ///
604    /// The MPSCNNLoss filter is created with a MPSCNNLossDescriptor describing the type of a loss filter
605    /// and the type of a reduction to use for computing the overall loss.
606    ///
607    /// The MPSCNNLoss filter takes the output of the inference pass (predictions) as input. It also
608    /// requires the target data (labels) and optionally, weights for the labels. If per-label weights
609    /// are not supplied, there is an option to use a single weight value by setting the 'weight' properly
610    /// on the MPSCNNLossDescriptor object. The labels and optional weights need to be supplied by the user
611    /// using the MPSCNNLossLabels object. The labels and weights are described via the MPSCNNLossDataDescriptor
612    /// objects, which are in turn used to initialize the MPSCNNLossLabels object.
613    ///
614    /// If the specified reduction operation is MPSCNNReductionTypeNone, the destinationImage should be
615    /// at least as large as the specified clipRect. The destinationImage will then contain per-element
616    /// losses. Otherse, a reduction operation will be performed, according to the specified reduction
617    /// type, and the filter will return a scalar value containing the overall loss. For more information
618    /// on the available reduction types, see MPSCNNTypes.h. Also see MPSCNNLossDescriptor for the
619    /// description of optional parameters.
620    ///
621    /// Here is a code example:
622    ///
623    /// // Setup
624    /// MPSCNNLossDataDescriptor* labelsDescriptor =
625    /// [MPSCNNLossDataDescriptor cnnLossDataDescriptorWithData: labelsData
626    /// layout: MPSDataLayoutHeightxWidthxFeatureChannels
627    /// size: labelsDataSize];
628    /// MPSCNNLossLabels* labels = [[MPSCNNLossLabels alloc] initWithDevice: device
629    /// labelsDescriptor: labelsDescriptor];
630    /// MPSCNNLossDescriptor *lossDescriptor =
631    /// [MPSCNNLossDescriptor cnnLossDescriptorWithType: (MPSCNNLossType)MPSCNNLossTypeMeanAbsoluteError
632    /// reductionType: (MPSCNNReductionType)MPSCNNReductionTypeSum];
633    /// MPSCNNLoss* lossFilter = [[MPSCNNLoss alloc] initWithDevice: device lossDescriptor: lossDescriptor];
634    ///
635    /// // Encode loss filter.
636    /// // The sourceImage is the output of a previous layer, for example, the SoftMax layer. The lossGradientsImage
637    /// // is the sourceGradient input image to the first gradient layer (in the backward direction), for example,
638    /// // the SoftMax gradient filter.
639    /// [lossFilter encodeToCommandBuffer: commandBuffer sourceImage: sourceImage
640    /// labels: labels
641    /// destinationImage: lossGradientsImage];
642    ///
643    /// // In order to guarantee that the loss image data is correctly synchronized for CPU side access,
644    /// // it is the application's responsibility to call the [labels synchronizeOnCommandBuffer:]
645    /// // method before accessing the loss image data.
646    /// [labels synchronizeOnCommandBuffer:commandBuffer];
647    /// MPSImage* lossImage = [labels lossImage];
648    ///
649    /// For predictions (y) and labels (t), the available loss filter types are the following:
650    ///
651    /// Mean Absolute Error loss filter. This filter measures the absolute error of the element-wise
652    /// difference between the predictions and labels.
653    /// This loss function is computed according to the following formulas:
654    /// Compute losses:          losses = |y - t|
655    /// Compute weighted losses: weighted_losses = weight(s) * losses
656    /// Compute overall loss:    loss = reduce(weighted_losses, reductionType)
657    ///
658    /// Mean Squared Error loss filter. This filter measures the squared error of the element-wise
659    /// difference between the predictions and labels.
660    /// This loss function is computed according to the following formulas:
661    /// Compute losses:          losses = (y - t)^2
662    /// Compute weighted losses: weighted_losses = weight(s) * losses
663    /// Compute overall loss:    loss = reduce(weighted_losses, reductionType)
664    ///
665    /// SoftMax Cross Entropy loss filter. This loss filter is applied element-wise.
666    /// This loss filter combines the LogSoftMax and Negative Log Likelihood operations in a
667    /// single filter. It is useful for training a classification problem with multiple classes.
668    /// This loss function is computed according to the following formulas:
669    /// Compute losses:          losses = -t * LogSoftMax(y)
670    /// Compute weighted losses: weighted_losses = weight(s) * losses
671    /// Compute overall loss:    loss = reduce(weighted_losses, reductionType)
672    /// If reductionType is MPSCNNReductionTypeMean, the accumulated
673    /// loss value is divided by width * height instead of
674    /// width * height * featureChannels.
675    ///
676    /// Sigmoid Cross Entropy loss filter. This loss filter is applied element-wise.
677    /// This loss function is computed according to the following formulas:
678    /// Compute losses:          losses = max(y, 0) - y * t + log(1 + exp(-|y|))
679    /// Compute weighted losses: weighted_losses = weight(s) * losses
680    /// Compute overall loss:    loss = reduce(weighted_losses, reductionType)
681    ///
682    /// Categorical Cross Entropy loss filter. This loss filter is applied element-wise.
683    /// This loss function is computed according to the following formulas:
684    /// Compute losses:          losses = -t * log(y)
685    /// Compute weighted losses: weighted_losses = weight(s) * losses
686    /// Compute overall loss:    loss = reduce(weighted_losses, reductionType)
687    ///
688    /// Hinge loss filter. This loss filter is applied element-wise.
689    /// The labels are expected to be 0.0 or 1.0.
690    /// This loss function is computed according to the following formulas:
691    /// Compute losses:          losses = max(1 - (t * y), 0.0f)
692    /// Compute weighted losses: weighted_losses = weight(s) * losses
693    /// Compute overall loss:    loss = reduce(weighted_losses, reductionType)
694    ///
695    /// Huber loss filter. This loss filter is applied element-wise.
696    /// This loss function is computed according to the following formulas:
697    /// Compute losses:          if (|y - t|
698    /// <
699    /// = delta, losses = 0.5 * y^2
700    /// if (|y - t| >  delta, losses = 0.5 * delta^2 + delta * (|y - t| - delta)
701    /// Compute weighted losses: weighted_losses = weight(s) * losses
702    /// Compute overall loss:    loss = reduce(weighted_losses, reductionType)
703    ///
704    /// Cosine Distance loss filter. This loss filter is applied element-wise.
705    /// The only valid reduction type for this loss filter is MPSCNNReductionTypeSum.
706    /// This loss function is computed according to the following formulas:
707    /// Compute losses:          loss = 1 - reduce_sum(y * t)
708    /// Compute overall loss:    weighted_loss = weight * loss
709    ///
710    /// Log loss filter. This loss filter is applied element-wise.
711    /// This loss function is computed according to the following formulas:
712    /// Compute losses:          losses = -(t * log(y + epsilon)) - ((1 - t) * log(1 - y + epsilon))
713    /// Compute weighted losses: weighted_losses = weight(s) * losses
714    /// Compute overall loss:    loss = reduce(weighted_losses, reductionType)
715    ///
716    /// Kullback-Leibler Divergence loss filter. This loss filter is applied element-wise.
717    /// The input (predictions) is expected to contain log-probabilities.
718    /// This loss function is computed according to the following formulas:
719    /// Compute losses:          losses = t * (log(t) - y)
720    /// Compute weighted losses: weighted_losses = weight(s) * losses
721    /// Compute overall loss:    loss = reduce(weighted_losses, reductionType)
722    ///
723    /// For predictions (y) and labels (t), the loss gradient for each available loss filter type
724    /// is computed as follows:
725    ///
726    /// Mean Absolute Error loss.
727    /// The loss gradient is computed according to the following formulas:
728    /// Compute gradient:          d/dy = (y - t) / |y - t|
729    /// Compute weighted gradient: weighted_gradient = weight(s) * gradient
730    ///
731    /// Mean Squared Error loss.
732    /// The loss gradient is computed according to the following formulas:
733    /// Compute gradient:          d/dy = 2 * (y - t)
734    /// Compute weighted gradient: weighted_gradient = weight(s) * gradient
735    ///
736    /// SoftMax Cross Entropy loss.
737    /// The loss gradient is computed according to the following formulas:
738    /// First, apply the same label smoothing as in the MPSCNNLoss filter.
739    /// Compute gradient:          d/dy = y - t
740    /// Compute weighted gradient: weighted_gradient = weight(s) * gradient
741    ///
742    /// Sigmoid Cross Entropy loss.
743    /// The loss gradient is computed according to the following formulas:
744    /// First, apply the same label smoothing as in the MPSCNNLoss filter.
745    /// Compute gradient:          d/dy = (1 / (1 + exp(-y)) - t
746    /// Compute weighted gradient: weighted_gradient = weight(s) * gradient
747    ///
748    /// Categorical Cross Entropy loss.
749    /// The loss gradient is computed according to the following formulas:
750    /// Compute gradient:          d/dy = -t / y
751    /// Compute weighted gradient: weighted_gradient = weight(s) * gradient
752    ///
753    /// Hinge loss.
754    /// The loss gradient is computed according to the following formulas:
755    /// Compute gradient:          d/dy = ((1 + ((1 - (2 * t)) * y)) > 0) ? 1 - (2 * t) : 0
756    /// Compute weighted gradient: weighted_gradient = weight(s) * gradient
757    ///
758    /// Huber loss.
759    /// The loss gradient is computed according to the following formulas:
760    /// Compute gradient:          d/dy = |y - t| > delta ? delta : y - t
761    /// Compute weighted gradient: weighted_gradient = weight(s) * gradient
762    ///
763    /// Cosine Distance loss.
764    /// The loss gradient is computed according to the following formulas:
765    /// Compute gradient:          d/dy = -t
766    /// Compute weighted gradient: weighted_gradient = weight(s) * gradient
767    ///
768    /// Log loss.
769    /// The loss gradient is computed according to the following formulas:
770    /// Compute gradient:          d/dy = (-2 * epsilon * t - t + y + epsilon) / (y * (1 - y) + epsilon * (epsilon + 1))
771    /// Compute weighted gradient: weighted_gradient = weight(s) * gradient
772    ///
773    /// Kullback-Leibler Divergence loss.
774    /// The loss gradient is computed according to the following formulas:
775    /// Compute gradient:          d/dy = -t / y
776    /// Compute weighted gradient: weighted_gradient = weight(s) * gradient
777    ///
778    /// The number of output feature channels remains the same as the number of input feature
779    /// channels.
780    ///
781    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnloss?language=objc)
782    #[unsafe(super(MPSCNNKernel, MPSKernel, NSObject))]
783    #[derive(Debug, PartialEq, Eq, Hash)]
784    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
785    pub struct MPSCNNLoss;
786);
787
788#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
789extern_conformance!(
790    unsafe impl NSCoding for MPSCNNLoss {}
791);
792
793#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
794extern_conformance!(
795    unsafe impl NSCopying for MPSCNNLoss {}
796);
797
798#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
799unsafe impl CopyingHelper for MPSCNNLoss {
800    type Result = Self;
801}
802
803#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
804extern_conformance!(
805    unsafe impl NSObjectProtocol for MPSCNNLoss {}
806);
807
808#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
809extern_conformance!(
810    unsafe impl NSSecureCoding for MPSCNNLoss {}
811);
812
813#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
814impl MPSCNNLoss {
815    extern_methods!(
816        #[cfg(feature = "MPSCNNTypes")]
817        /// See MPSCNNLossDescriptor for information about the following properties.
818        #[unsafe(method(lossType))]
819        #[unsafe(method_family = none)]
820        pub unsafe fn lossType(&self) -> MPSCNNLossType;
821
822        #[cfg(feature = "MPSCNNTypes")]
823        #[unsafe(method(reductionType))]
824        #[unsafe(method_family = none)]
825        pub unsafe fn reductionType(&self) -> MPSCNNReductionType;
826
827        #[unsafe(method(weight))]
828        #[unsafe(method_family = none)]
829        pub unsafe fn weight(&self) -> c_float;
830
831        #[unsafe(method(labelSmoothing))]
832        #[unsafe(method_family = none)]
833        pub unsafe fn labelSmoothing(&self) -> c_float;
834
835        #[unsafe(method(numberOfClasses))]
836        #[unsafe(method_family = none)]
837        pub unsafe fn numberOfClasses(&self) -> NSUInteger;
838
839        #[unsafe(method(epsilon))]
840        #[unsafe(method_family = none)]
841        pub unsafe fn epsilon(&self) -> c_float;
842
843        #[unsafe(method(delta))]
844        #[unsafe(method_family = none)]
845        pub unsafe fn delta(&self) -> c_float;
846
847        #[unsafe(method(reduceAcrossBatch))]
848        #[unsafe(method_family = none)]
849        pub unsafe fn reduceAcrossBatch(&self) -> bool;
850
851        #[unsafe(method(initWithDevice:))]
852        #[unsafe(method_family = init)]
853        pub unsafe fn initWithDevice(
854            this: Allocated<Self>,
855            device: &ProtocolObject<dyn MTLDevice>,
856        ) -> Retained<Self>;
857
858        /// Initialize the loss filter with a loss descriptor.
859        ///
860        /// Parameter `device`: The device the filter will run on.
861        ///
862        /// Parameter `lossDescriptor`: The loss descriptor.
863        ///
864        /// Returns: A valid MPSCNNLoss object or nil, if failure.
865        #[unsafe(method(initWithDevice:lossDescriptor:))]
866        #[unsafe(method_family = init)]
867        pub unsafe fn initWithDevice_lossDescriptor(
868            this: Allocated<Self>,
869            device: &ProtocolObject<dyn MTLDevice>,
870            loss_descriptor: &MPSCNNLossDescriptor,
871        ) -> Retained<Self>;
872
873        /// <NSSecureCoding
874        /// > support
875        ///
876        /// # Safety
877        ///
878        /// `a_decoder` possibly has further requirements.
879        #[unsafe(method(initWithCoder:device:))]
880        #[unsafe(method_family = init)]
881        pub unsafe fn initWithCoder_device(
882            this: Allocated<Self>,
883            a_decoder: &NSCoder,
884            device: &ProtocolObject<dyn MTLDevice>,
885        ) -> Option<Retained<Self>>;
886
887        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
888        /// Encode a MPSCNNLoss filter and return a gradient in the destinationImage.
889        ///
890        /// This filter consumes the output of a previous layer, for example, the SoftMax layer containing
891        /// predictions, and the MPSCNNLossLabels object containing the target data (labels) and optionally,
892        /// weights for the labels. The destinationImage contains the computed gradient for the loss layer.
893        /// It serves as a source gradient input image to the first gradient layer (in the backward direction),
894        /// in our example, the SoftMax gradient layer.
895        ///
896        ///
897        /// Parameter `commandBuffer`: The MTLCommandBuffer on which to encode.
898        ///
899        /// Parameter `sourceImage`: The source image from the previous filter in the graph (in the inference direction).
900        ///
901        /// Parameter `labels`: The object containing the target data (labels) and optionally, weights for the labels.
902        ///
903        /// Parameter `destinationImage`: The MPSImage into which to write the gradient result.
904        #[unsafe(method(encodeToCommandBuffer:sourceImage:labels:destinationImage:))]
905        #[unsafe(method_family = none)]
906        pub unsafe fn encodeToCommandBuffer_sourceImage_labels_destinationImage(
907            &self,
908            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
909            source_image: &MPSImage,
910            labels: &MPSCNNLossLabels,
911            destination_image: &MPSImage,
912        );
913
914        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
915        /// Encode a MPSCNNLoss filter and return a gradient.
916        ///
917        /// This -encode call is similar to the encodeToCommandBuffer:sourceImage:labels:destinationImage: above,
918        /// except that it creates and returns the MPSImage with the loss gradient result.
919        ///
920        ///
921        /// Parameter `commandBuffer`: The MTLCommandBuffer on which to encode.
922        ///
923        /// Parameter `sourceImage`: The source image from the previous filter in the graph (in the inference direction).
924        ///
925        /// Parameter `labels`: The object containing the target data (labels) and optionally, weights for the labels.
926        ///
927        /// Returns: The MPSImage containing the gradient result.
928        #[unsafe(method(encodeToCommandBuffer:sourceImage:labels:))]
929        #[unsafe(method_family = none)]
930        pub unsafe fn encodeToCommandBuffer_sourceImage_labels(
931            &self,
932            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
933            source_image: &MPSImage,
934            labels: &MPSCNNLossLabels,
935        ) -> Retained<MPSImage>;
936
937        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
938        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:labels:destinationImages:))]
939        #[unsafe(method_family = none)]
940        pub unsafe fn encodeBatchToCommandBuffer_sourceImages_labels_destinationImages(
941            &self,
942            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
943            source_image: &MPSImageBatch,
944            labels: &MPSCNNLossLabelsBatch,
945            destination_image: &MPSImageBatch,
946        );
947
948        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
949        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:labels:))]
950        #[unsafe(method_family = none)]
951        pub unsafe fn encodeBatchToCommandBuffer_sourceImages_labels(
952            &self,
953            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
954            source_image: &MPSImageBatch,
955            labels: &MPSCNNLossLabelsBatch,
956        ) -> Retained<MPSImageBatch>;
957    );
958}
959
960/// Methods declared on superclass `MPSKernel`.
961#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
962impl MPSCNNLoss {
963    extern_methods!(
964        /// Called by NSCoder to decode MPSKernels
965        ///
966        /// This isn't the right interface to decode a MPSKernel, but
967        /// it is the one that NSCoder uses. To enable your NSCoder
968        /// (e.g. NSKeyedUnarchiver) to set which device to use
969        /// extend the object to adopt the MPSDeviceProvider
970        /// protocol. Otherwise, the Metal system default device
971        /// will be used.
972        ///
973        /// # Safety
974        ///
975        /// `a_decoder` possibly has further requirements.
976        #[unsafe(method(initWithCoder:))]
977        #[unsafe(method_family = init)]
978        pub unsafe fn initWithCoder(
979            this: Allocated<Self>,
980            a_decoder: &NSCoder,
981        ) -> Option<Retained<Self>>;
982    );
983}
984
985/// Methods declared on superclass `NSObject`.
986#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
987impl MPSCNNLoss {
988    extern_methods!(
989        #[unsafe(method(init))]
990        #[unsafe(method_family = init)]
991        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
992
993        #[unsafe(method(new))]
994        #[unsafe(method_family = new)]
995        pub unsafe fn new() -> Retained<Self>;
996    );
997}
998
999extern_class!(
1000    /// Dependencies: This depends on Metal.framework.
1001    ///
1002    /// The MPSCNNYOLOLossDescriptor specifies a loss filter descriptor
1003    /// that is used to create a MPSCNNLoss filter. The MPSCNNYOLOLoss is a filter that
1004    /// has been specialized for object detection tasks and follows a specific layout
1005    /// for the feature-channels of the input, output, weight and label data.
1006    ///
1007    /// The layout of the data within the feature-channels is as follows:
1008    ///
1009    /// Each anchorbox uses ( 2+2+1 + numberOfClasses = 5 + numberOfClasses ) feature channels.
1010    ///
1011    /// Therefore the total number of feature channels used is: (5 + numberOfClasses) * numberOfAnchorBoxes.
1012    /// The first feature channel for anchorbox index 'anchorIdx' is at fcIndex = (5 + numberOfClasses) * anchorIdx,
1013    /// and the feature channels within each anchorbox are stored in the layout: 'XYWHCFFFFFF...', where (XY) are
1014    /// the so-called raw x and y coordinates of the bounding box within each gridcell and (WH) are the corresponding
1015    /// width and height. 'C' signifies a confidence for having an object in the cell and FFFFF... are the feature channel
1016    /// values for each class of object to be classified in the object detector.
1017    ///
1018    /// The YOLO-loss filter works by operating mostly independently on each anchorbox:
1019    /// *   The XY-channels of the inputs are first transformed to relative XY-values by applying the sigmoid-neuron on them,
1020    /// after which they are passed through the loss function defined by
1021    /// XYLossDescriptor,which is typically chosen
1022    /// to be the
1023    /// MPSCNNLossTypeMeanSquaredErrortype loss function.
1024    /// *   The WH-channels contain the raw width and height of the bounding box and they are operated with the
1025    /// loss function defined by
1026    /// WHLossDescriptor,which is typically of type
1027    /// MPSCNNLossTypeHuber.*   The C-channel contains the confidence value of having an object in the bounding box and it is operated
1028    /// by the loss function defined by
1029    /// confidenceLossDescriptor,which is typically chosen to be
1030    /// MPSCNNLossTypeSigmoidCrossEntropy.*   The FFFFF... (number of channels is number of classes) channels contains the raw feature channels for
1031    /// object classes, used to identify which objects are the most probable ones in the bounding box and
1032    /// these channels are passed through the loss function defined by
1033    /// classesLossDescriptor,which in
1034    /// typical cases is of the type
1035    /// MPSCNNLossTypeSoftMaxCrossEntropy.
1036    /// For details on how to set up the label values and anchorboxes see https://arxiv.org/abs/1612.08242
1037    ///
1038    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnyololossdescriptor?language=objc)
1039    #[unsafe(super(NSObject))]
1040    #[derive(Debug, PartialEq, Eq, Hash)]
1041    pub struct MPSCNNYOLOLossDescriptor;
1042);
1043
1044extern_conformance!(
1045    unsafe impl NSCopying for MPSCNNYOLOLossDescriptor {}
1046);
1047
1048unsafe impl CopyingHelper for MPSCNNYOLOLossDescriptor {
1049    type Result = Self;
1050}
1051
1052extern_conformance!(
1053    unsafe impl NSObjectProtocol for MPSCNNYOLOLossDescriptor {}
1054);
1055
1056impl MPSCNNYOLOLossDescriptor {
1057    extern_methods!(
1058        /// The type of a loss filter.
1059        ///
1060        /// This parameter specifies the type of a loss filter.
1061        #[unsafe(method(XYLossDescriptor))]
1062        #[unsafe(method_family = none)]
1063        pub unsafe fn XYLossDescriptor(&self) -> Retained<MPSCNNLossDescriptor>;
1064
1065        /// Setter for [`XYLossDescriptor`][Self::XYLossDescriptor].
1066        #[unsafe(method(setXYLossDescriptor:))]
1067        #[unsafe(method_family = none)]
1068        pub unsafe fn setXYLossDescriptor(&self, xy_loss_descriptor: &MPSCNNLossDescriptor);
1069
1070        /// The type of a loss filter.
1071        ///
1072        /// This parameter specifies the type of a loss filter.
1073        #[unsafe(method(WHLossDescriptor))]
1074        #[unsafe(method_family = none)]
1075        pub unsafe fn WHLossDescriptor(&self) -> Retained<MPSCNNLossDescriptor>;
1076
1077        /// Setter for [`WHLossDescriptor`][Self::WHLossDescriptor].
1078        #[unsafe(method(setWHLossDescriptor:))]
1079        #[unsafe(method_family = none)]
1080        pub unsafe fn setWHLossDescriptor(&self, wh_loss_descriptor: &MPSCNNLossDescriptor);
1081
1082        /// The type of a loss filter.
1083        ///
1084        /// This parameter specifies the type of a loss filter.
1085        #[unsafe(method(confidenceLossDescriptor))]
1086        #[unsafe(method_family = none)]
1087        pub unsafe fn confidenceLossDescriptor(&self) -> Retained<MPSCNNLossDescriptor>;
1088
1089        /// Setter for [`confidenceLossDescriptor`][Self::confidenceLossDescriptor].
1090        #[unsafe(method(setConfidenceLossDescriptor:))]
1091        #[unsafe(method_family = none)]
1092        pub unsafe fn setConfidenceLossDescriptor(
1093            &self,
1094            confidence_loss_descriptor: &MPSCNNLossDescriptor,
1095        );
1096
1097        /// The type of a loss filter.
1098        ///
1099        /// This parameter specifies the type of a loss filter.
1100        #[unsafe(method(classesLossDescriptor))]
1101        #[unsafe(method_family = none)]
1102        pub unsafe fn classesLossDescriptor(&self) -> Retained<MPSCNNLossDescriptor>;
1103
1104        /// Setter for [`classesLossDescriptor`][Self::classesLossDescriptor].
1105        #[unsafe(method(setClassesLossDescriptor:))]
1106        #[unsafe(method_family = none)]
1107        pub unsafe fn setClassesLossDescriptor(
1108            &self,
1109            classes_loss_descriptor: &MPSCNNLossDescriptor,
1110        );
1111
1112        #[cfg(feature = "MPSCNNTypes")]
1113        /// ReductionType shared accross all losses (so they may generate same sized output)
1114        #[unsafe(method(reductionType))]
1115        #[unsafe(method_family = none)]
1116        pub unsafe fn reductionType(&self) -> MPSCNNReductionType;
1117
1118        #[cfg(feature = "MPSCNNTypes")]
1119        /// Setter for [`reductionType`][Self::reductionType].
1120        #[unsafe(method(setReductionType:))]
1121        #[unsafe(method_family = none)]
1122        pub unsafe fn setReductionType(&self, reduction_type: MPSCNNReductionType);
1123
1124        /// If set to YES then the reduction operation is applied also across the batch-index dimension,
1125        /// ie. the loss value is summed over images in the batch and the result of the reduction is written
1126        /// on the first loss image in the batch while the other loss images will be set to zero.
1127        /// If set to NO, then no reductions are performed across the batch dimension and each image in the batch
1128        /// will contain the loss value associated with that one particular image.
1129        /// NOTE: If reductionType == MPSCNNReductionTypeNone, then this flag has no effect on results,
1130        /// that is no reductions are done in this case.
1131        /// NOTE: If reduceAcrossBatch is set to YES and reductionType == MPSCNNReductionTypeMean then
1132        /// the final forward loss value is computed by first summing over the components and then by
1133        /// dividing the result with: number of feature channels * width * height * number of images in the batch.
1134        /// The default value is NO.
1135        #[unsafe(method(reduceAcrossBatch))]
1136        #[unsafe(method_family = none)]
1137        pub unsafe fn reduceAcrossBatch(&self) -> bool;
1138
1139        /// Setter for [`reduceAcrossBatch`][Self::reduceAcrossBatch].
1140        #[unsafe(method(setReduceAcrossBatch:))]
1141        #[unsafe(method_family = none)]
1142        pub unsafe fn setReduceAcrossBatch(&self, reduce_across_batch: bool);
1143
1144        /// Rescore pertains to multiplying the confidence groundTruth with IOU (intersection over union)
1145        /// of predicted bounding box and the groundTruth boundingBox. Default is YES
1146        #[unsafe(method(rescore))]
1147        #[unsafe(method_family = none)]
1148        pub unsafe fn rescore(&self) -> bool;
1149
1150        /// Setter for [`rescore`][Self::rescore].
1151        #[unsafe(method(setRescore:))]
1152        #[unsafe(method_family = none)]
1153        pub unsafe fn setRescore(&self, rescore: bool);
1154
1155        /// scale factor for XY loss and loss gradient default is 10.0
1156        #[unsafe(method(scaleXY))]
1157        #[unsafe(method_family = none)]
1158        pub unsafe fn scaleXY(&self) -> c_float;
1159
1160        /// Setter for [`scaleXY`][Self::scaleXY].
1161        #[unsafe(method(setScaleXY:))]
1162        #[unsafe(method_family = none)]
1163        pub unsafe fn setScaleXY(&self, scale_xy: c_float);
1164
1165        /// scale factor for WH loss and loss gradient default is 10.0
1166        #[unsafe(method(scaleWH))]
1167        #[unsafe(method_family = none)]
1168        pub unsafe fn scaleWH(&self) -> c_float;
1169
1170        /// Setter for [`scaleWH`][Self::scaleWH].
1171        #[unsafe(method(setScaleWH:))]
1172        #[unsafe(method_family = none)]
1173        pub unsafe fn setScaleWH(&self, scale_wh: c_float);
1174
1175        /// scale factor for no object confidence loss and loss gradient default is 5.0
1176        #[unsafe(method(scaleNoObject))]
1177        #[unsafe(method_family = none)]
1178        pub unsafe fn scaleNoObject(&self) -> c_float;
1179
1180        /// Setter for [`scaleNoObject`][Self::scaleNoObject].
1181        #[unsafe(method(setScaleNoObject:))]
1182        #[unsafe(method_family = none)]
1183        pub unsafe fn setScaleNoObject(&self, scale_no_object: c_float);
1184
1185        /// scale factor for no object confidence loss and loss gradient default is 100.0
1186        #[unsafe(method(scaleObject))]
1187        #[unsafe(method_family = none)]
1188        pub unsafe fn scaleObject(&self) -> c_float;
1189
1190        /// Setter for [`scaleObject`][Self::scaleObject].
1191        #[unsafe(method(setScaleObject:))]
1192        #[unsafe(method_family = none)]
1193        pub unsafe fn setScaleObject(&self, scale_object: c_float);
1194
1195        /// scale factor for no object classes loss and loss gradient default is 2.0
1196        #[unsafe(method(scaleClass))]
1197        #[unsafe(method_family = none)]
1198        pub unsafe fn scaleClass(&self) -> c_float;
1199
1200        /// Setter for [`scaleClass`][Self::scaleClass].
1201        #[unsafe(method(setScaleClass:))]
1202        #[unsafe(method_family = none)]
1203        pub unsafe fn setScaleClass(&self, scale_class: c_float);
1204
1205        /// If the prediction IOU with groundTruth is higher than this
1206        /// value we consider it a confident object presence, default is 0.7
1207        #[unsafe(method(minIOUForObjectPresence))]
1208        #[unsafe(method_family = none)]
1209        pub unsafe fn minIOUForObjectPresence(&self) -> c_float;
1210
1211        /// Setter for [`minIOUForObjectPresence`][Self::minIOUForObjectPresence].
1212        #[unsafe(method(setMinIOUForObjectPresence:))]
1213        #[unsafe(method_family = none)]
1214        pub unsafe fn setMinIOUForObjectPresence(&self, min_iou_for_object_presence: c_float);
1215
1216        /// If the prediction IOU with groundTruth is lower than this
1217        /// value we consider it a confident object absence, default is 0.3
1218        #[unsafe(method(maxIOUForObjectAbsence))]
1219        #[unsafe(method_family = none)]
1220        pub unsafe fn maxIOUForObjectAbsence(&self) -> c_float;
1221
1222        /// Setter for [`maxIOUForObjectAbsence`][Self::maxIOUForObjectAbsence].
1223        #[unsafe(method(setMaxIOUForObjectAbsence:))]
1224        #[unsafe(method_family = none)]
1225        pub unsafe fn setMaxIOUForObjectAbsence(&self, max_iou_for_object_absence: c_float);
1226
1227        /// number of anchor boxes used to detect object per grid cell
1228        #[unsafe(method(numberOfAnchorBoxes))]
1229        #[unsafe(method_family = none)]
1230        pub unsafe fn numberOfAnchorBoxes(&self) -> NSUInteger;
1231
1232        /// Setter for [`numberOfAnchorBoxes`][Self::numberOfAnchorBoxes].
1233        #[unsafe(method(setNumberOfAnchorBoxes:))]
1234        #[unsafe(method_family = none)]
1235        pub unsafe fn setNumberOfAnchorBoxes(&self, number_of_anchor_boxes: NSUInteger);
1236
1237        /// NSData containing the width and height for numberOfAnchorBoxes anchor boxes
1238        /// This NSData should have 2 float values per anchor box which represent the width
1239        /// and height of the anchor box.
1240        ///
1241        /// ```text
1242        ///               typedef struct anchorBox{
1243        ///                   float width;
1244        ///                   float height;
1245        ///               }anchorBox;
1246        ///
1247        ///
1248        ///               anchorBox_t gAnchorBoxes[MAX_NUM_ANCHOR_BOXES] = {
1249        ///                   {.width = 1.f, .height = 2.f},
1250        ///                   {.width = 1.f, .height = 1.f},
1251        ///                   {.width = 2.f, .height = 1.f},
1252        ///               };
1253        ///               NSData* labelsInputData = [NSData dataWithBytes: gAnchorBoxes length: MAX_NUM_ANCHOR_BOXES * sizeof(anchorBox)];
1254        /// ```
1255        #[unsafe(method(anchorBoxes))]
1256        #[unsafe(method_family = none)]
1257        pub unsafe fn anchorBoxes(&self) -> Retained<NSData>;
1258
1259        /// Setter for [`anchorBoxes`][Self::anchorBoxes].
1260        #[unsafe(method(setAnchorBoxes:))]
1261        #[unsafe(method_family = none)]
1262        pub unsafe fn setAnchorBoxes(&self, anchor_boxes: &NSData);
1263
1264        #[unsafe(method(init))]
1265        #[unsafe(method_family = init)]
1266        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
1267
1268        #[cfg(feature = "MPSCNNTypes")]
1269        /// Make a descriptor for a MPSCNNYOLOLoss object.
1270        ///
1271        /// Parameter `XYLossType`: The type of spatial position loss filter.
1272        ///
1273        /// Parameter `WHLossType`: The type of spatial size loss filter.
1274        ///
1275        /// Parameter `confidenceLossType`: The type of confidence filter.
1276        ///
1277        /// Parameter `classesLossType`: The type of classes filter.
1278        ///
1279        /// Parameter `reductionType`: The type of a reduction operation to apply.
1280        ///
1281        /// Parameter `anchorBoxes`: This is an NSData which has an array of anchorBoxes defined as a struct{ float width; float height; };
1282        ///
1283        /// Returns: A valid MPSCNNYOLOLossDescriptor object or nil, if failure.
1284        #[unsafe(method(cnnLossDescriptorWithXYLossType:WHLossType:confidenceLossType:classesLossType:reductionType:anchorBoxes:numberOfAnchorBoxes:))]
1285        #[unsafe(method_family = none)]
1286        pub unsafe fn cnnLossDescriptorWithXYLossType_WHLossType_confidenceLossType_classesLossType_reductionType_anchorBoxes_numberOfAnchorBoxes(
1287            xy_loss_type: MPSCNNLossType,
1288            wh_loss_type: MPSCNNLossType,
1289            confidence_loss_type: MPSCNNLossType,
1290            classes_loss_type: MPSCNNLossType,
1291            reduction_type: MPSCNNReductionType,
1292            anchor_boxes: &NSData,
1293            number_of_anchor_boxes: NSUInteger,
1294        ) -> Retained<MPSCNNYOLOLossDescriptor>;
1295    );
1296}
1297
1298/// Methods declared on superclass `NSObject`.
1299impl MPSCNNYOLOLossDescriptor {
1300    extern_methods!(
1301        #[unsafe(method(new))]
1302        #[unsafe(method_family = new)]
1303        pub unsafe fn new() -> Retained<Self>;
1304    );
1305}
1306
1307extern_class!(
1308    /// [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnyololoss?language=objc)
1309    #[unsafe(super(MPSCNNKernel, MPSKernel, NSObject))]
1310    #[derive(Debug, PartialEq, Eq, Hash)]
1311    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1312    pub struct MPSCNNYOLOLoss;
1313);
1314
1315#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1316extern_conformance!(
1317    unsafe impl NSCoding for MPSCNNYOLOLoss {}
1318);
1319
1320#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1321extern_conformance!(
1322    unsafe impl NSCopying for MPSCNNYOLOLoss {}
1323);
1324
1325#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1326unsafe impl CopyingHelper for MPSCNNYOLOLoss {
1327    type Result = Self;
1328}
1329
1330#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1331extern_conformance!(
1332    unsafe impl NSObjectProtocol for MPSCNNYOLOLoss {}
1333);
1334
1335#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1336extern_conformance!(
1337    unsafe impl NSSecureCoding for MPSCNNYOLOLoss {}
1338);
1339
1340#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1341impl MPSCNNYOLOLoss {
1342    extern_methods!(
1343        /// loss filter for prediction of bounding box position
1344        #[unsafe(method(lossXY))]
1345        #[unsafe(method_family = none)]
1346        pub unsafe fn lossXY(&self) -> Retained<MPSCNNLoss>;
1347
1348        /// loss filter for prediction of bounding box size
1349        #[unsafe(method(lossWH))]
1350        #[unsafe(method_family = none)]
1351        pub unsafe fn lossWH(&self) -> Retained<MPSCNNLoss>;
1352
1353        /// loss filter for prediction of bounding box probability of presence of object
1354        #[unsafe(method(lossConfidence))]
1355        #[unsafe(method_family = none)]
1356        pub unsafe fn lossConfidence(&self) -> Retained<MPSCNNLoss>;
1357
1358        /// loss filter for prediction of bounding box predicted class of the detected object
1359        #[unsafe(method(lossClasses))]
1360        #[unsafe(method_family = none)]
1361        pub unsafe fn lossClasses(&self) -> Retained<MPSCNNLoss>;
1362
1363        /// See MPSCNNYOLOLossDescriptor for information about the following properties.
1364        #[unsafe(method(scaleXY))]
1365        #[unsafe(method_family = none)]
1366        pub unsafe fn scaleXY(&self) -> c_float;
1367
1368        #[unsafe(method(scaleWH))]
1369        #[unsafe(method_family = none)]
1370        pub unsafe fn scaleWH(&self) -> c_float;
1371
1372        #[unsafe(method(scaleNoObject))]
1373        #[unsafe(method_family = none)]
1374        pub unsafe fn scaleNoObject(&self) -> c_float;
1375
1376        #[unsafe(method(scaleObject))]
1377        #[unsafe(method_family = none)]
1378        pub unsafe fn scaleObject(&self) -> c_float;
1379
1380        #[unsafe(method(scaleClass))]
1381        #[unsafe(method_family = none)]
1382        pub unsafe fn scaleClass(&self) -> c_float;
1383
1384        #[unsafe(method(minIOUForObjectPresence))]
1385        #[unsafe(method_family = none)]
1386        pub unsafe fn minIOUForObjectPresence(&self) -> c_float;
1387
1388        #[unsafe(method(maxIOUForObjectAbsence))]
1389        #[unsafe(method_family = none)]
1390        pub unsafe fn maxIOUForObjectAbsence(&self) -> c_float;
1391
1392        #[cfg(feature = "MPSCNNTypes")]
1393        #[unsafe(method(reductionType))]
1394        #[unsafe(method_family = none)]
1395        pub unsafe fn reductionType(&self) -> MPSCNNReductionType;
1396
1397        #[unsafe(method(numberOfAnchorBoxes))]
1398        #[unsafe(method_family = none)]
1399        pub unsafe fn numberOfAnchorBoxes(&self) -> NSUInteger;
1400
1401        #[unsafe(method(anchorBoxes))]
1402        #[unsafe(method_family = none)]
1403        pub unsafe fn anchorBoxes(&self) -> Retained<NSData>;
1404
1405        #[unsafe(method(reduceAcrossBatch))]
1406        #[unsafe(method_family = none)]
1407        pub unsafe fn reduceAcrossBatch(&self) -> bool;
1408
1409        #[unsafe(method(initWithDevice:))]
1410        #[unsafe(method_family = init)]
1411        pub unsafe fn initWithDevice(
1412            this: Allocated<Self>,
1413            device: &ProtocolObject<dyn MTLDevice>,
1414        ) -> Retained<Self>;
1415
1416        /// Initialize the loss filter with a loss descriptor.
1417        ///
1418        /// Parameter `device`: The device the filter will run on.
1419        ///
1420        /// Parameter `lossDescriptor`: The loss descriptor.
1421        ///
1422        /// Returns: A valid MPSCNNLoss object or nil, if failure.
1423        #[unsafe(method(initWithDevice:lossDescriptor:))]
1424        #[unsafe(method_family = init)]
1425        pub unsafe fn initWithDevice_lossDescriptor(
1426            this: Allocated<Self>,
1427            device: &ProtocolObject<dyn MTLDevice>,
1428            loss_descriptor: &MPSCNNYOLOLossDescriptor,
1429        ) -> Retained<Self>;
1430
1431        /// <NSSecureCoding
1432        /// > support
1433        ///
1434        /// # Safety
1435        ///
1436        /// `a_decoder` possibly has further requirements.
1437        #[unsafe(method(initWithCoder:device:))]
1438        #[unsafe(method_family = init)]
1439        pub unsafe fn initWithCoder_device(
1440            this: Allocated<Self>,
1441            a_decoder: &NSCoder,
1442            device: &ProtocolObject<dyn MTLDevice>,
1443        ) -> Option<Retained<Self>>;
1444
1445        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
1446        /// Encode a MPSCNNYOLOLoss filter and return a gradient in the destinationImage.
1447        ///
1448        /// This filter consumes the output of a previous layer and the MPSCNNLossLabels object containing
1449        /// the target data (labels) and optionally, weights for the labels.
1450        /// The destinationImage contains the computed gradient for the loss layer.
1451        /// It serves as a source gradient input image to the first gradient layer (in the backward direction).
1452        /// For information on the data-layout see
1453        /// MPSCNNYOLOLossDescriptor.
1454        ///
1455        /// Parameter `commandBuffer`: The MTLCommandBuffer on which to encode.
1456        ///
1457        /// Parameter `sourceImage`: The source image from the previous filter in the graph (in the inference direction).
1458        ///
1459        /// Parameter `labels`: The object containing the target data (labels) and optionally, weights for the labels.
1460        ///
1461        /// Parameter `destinationImage`: The MPSImage into which to write the gradient result.
1462        #[unsafe(method(encodeToCommandBuffer:sourceImage:labels:destinationImage:))]
1463        #[unsafe(method_family = none)]
1464        pub unsafe fn encodeToCommandBuffer_sourceImage_labels_destinationImage(
1465            &self,
1466            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1467            source_image: &MPSImage,
1468            labels: &MPSCNNLossLabels,
1469            destination_image: &MPSImage,
1470        );
1471
1472        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
1473        /// Encode a MPSCNNLoss filter and return a gradient.
1474        ///
1475        /// This -encode call is similar to the encodeToCommandBuffer:sourceImage:labels:destinationImage: above,
1476        /// except that it creates and returns the MPSImage with the loss gradient result.
1477        ///
1478        ///
1479        /// Parameter `commandBuffer`: The MTLCommandBuffer on which to encode.
1480        ///
1481        /// Parameter `sourceImage`: The source image from the previous filter in the graph (in the inference direction).
1482        ///
1483        /// Parameter `labels`: The object containing the target data (labels) and optionally, weights for the labels.
1484        ///
1485        /// Returns: The MPSImage containing the gradient result.
1486        #[unsafe(method(encodeToCommandBuffer:sourceImage:labels:))]
1487        #[unsafe(method_family = none)]
1488        pub unsafe fn encodeToCommandBuffer_sourceImage_labels(
1489            &self,
1490            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1491            source_image: &MPSImage,
1492            labels: &MPSCNNLossLabels,
1493        ) -> Retained<MPSImage>;
1494
1495        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
1496        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:labels:destinationImages:))]
1497        #[unsafe(method_family = none)]
1498        pub unsafe fn encodeBatchToCommandBuffer_sourceImages_labels_destinationImages(
1499            &self,
1500            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1501            source_image: &MPSImageBatch,
1502            labels: &MPSCNNLossLabelsBatch,
1503            destination_image: &MPSImageBatch,
1504        );
1505
1506        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
1507        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:labels:))]
1508        #[unsafe(method_family = none)]
1509        pub unsafe fn encodeBatchToCommandBuffer_sourceImages_labels(
1510            &self,
1511            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1512            source_image: &MPSImageBatch,
1513            labels: &MPSCNNLossLabelsBatch,
1514        ) -> Retained<MPSImageBatch>;
1515    );
1516}
1517
1518/// Methods declared on superclass `MPSKernel`.
1519#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1520impl MPSCNNYOLOLoss {
1521    extern_methods!(
1522        /// Called by NSCoder to decode MPSKernels
1523        ///
1524        /// This isn't the right interface to decode a MPSKernel, but
1525        /// it is the one that NSCoder uses. To enable your NSCoder
1526        /// (e.g. NSKeyedUnarchiver) to set which device to use
1527        /// extend the object to adopt the MPSDeviceProvider
1528        /// protocol. Otherwise, the Metal system default device
1529        /// will be used.
1530        ///
1531        /// # Safety
1532        ///
1533        /// `a_decoder` possibly has further requirements.
1534        #[unsafe(method(initWithCoder:))]
1535        #[unsafe(method_family = init)]
1536        pub unsafe fn initWithCoder(
1537            this: Allocated<Self>,
1538            a_decoder: &NSCoder,
1539        ) -> Option<Retained<Self>>;
1540    );
1541}
1542
1543/// Methods declared on superclass `NSObject`.
1544#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1545impl MPSCNNYOLOLoss {
1546    extern_methods!(
1547        #[unsafe(method(init))]
1548        #[unsafe(method_family = init)]
1549        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
1550
1551        #[unsafe(method(new))]
1552        #[unsafe(method_family = new)]
1553        pub unsafe fn new() -> Retained<Self>;
1554    );
1555}
1556
1557extern_class!(
1558    /// Dependencies: This depends on Metal.framework.
1559    ///
1560    /// The MPSNNForwardLoss filter specifies a version of the loss filter which separates the forward
1561    /// computation from the gradient computation. In order to compute gradients for the loss filter
1562    /// use
1563    /// MPSNNLossGradientfilter and in order to start the gradient computation of an arbitrary
1564    /// image use the
1565    /// MPSNNInitialGradientfilter.
1566    /// NOTE: This filter does not support non-default offset or cliprects and setting them to other
1567    /// than default values will result in undefined results.
1568    ///
1569    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpsnnforwardloss?language=objc)
1570    #[unsafe(super(MPSCNNKernel, MPSKernel, NSObject))]
1571    #[derive(Debug, PartialEq, Eq, Hash)]
1572    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1573    pub struct MPSNNForwardLoss;
1574);
1575
1576#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1577extern_conformance!(
1578    unsafe impl NSCoding for MPSNNForwardLoss {}
1579);
1580
1581#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1582extern_conformance!(
1583    unsafe impl NSCopying for MPSNNForwardLoss {}
1584);
1585
1586#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1587unsafe impl CopyingHelper for MPSNNForwardLoss {
1588    type Result = Self;
1589}
1590
1591#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1592extern_conformance!(
1593    unsafe impl NSObjectProtocol for MPSNNForwardLoss {}
1594);
1595
1596#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1597extern_conformance!(
1598    unsafe impl NSSecureCoding for MPSNNForwardLoss {}
1599);
1600
1601#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1602impl MPSNNForwardLoss {
1603    extern_methods!(
1604        #[cfg(feature = "MPSCNNTypes")]
1605        /// See MPSCNNLossDescriptor for information about the following properties.
1606        #[unsafe(method(lossType))]
1607        #[unsafe(method_family = none)]
1608        pub unsafe fn lossType(&self) -> MPSCNNLossType;
1609
1610        #[cfg(feature = "MPSCNNTypes")]
1611        #[unsafe(method(reductionType))]
1612        #[unsafe(method_family = none)]
1613        pub unsafe fn reductionType(&self) -> MPSCNNReductionType;
1614
1615        #[unsafe(method(reduceAcrossBatch))]
1616        #[unsafe(method_family = none)]
1617        pub unsafe fn reduceAcrossBatch(&self) -> bool;
1618
1619        #[unsafe(method(numberOfClasses))]
1620        #[unsafe(method_family = none)]
1621        pub unsafe fn numberOfClasses(&self) -> NSUInteger;
1622
1623        #[unsafe(method(weight))]
1624        #[unsafe(method_family = none)]
1625        pub unsafe fn weight(&self) -> c_float;
1626
1627        /// Setter for [`weight`][Self::weight].
1628        #[unsafe(method(setWeight:))]
1629        #[unsafe(method_family = none)]
1630        pub unsafe fn setWeight(&self, weight: c_float);
1631
1632        #[unsafe(method(labelSmoothing))]
1633        #[unsafe(method_family = none)]
1634        pub unsafe fn labelSmoothing(&self) -> c_float;
1635
1636        /// Setter for [`labelSmoothing`][Self::labelSmoothing].
1637        #[unsafe(method(setLabelSmoothing:))]
1638        #[unsafe(method_family = none)]
1639        pub unsafe fn setLabelSmoothing(&self, label_smoothing: c_float);
1640
1641        #[unsafe(method(epsilon))]
1642        #[unsafe(method_family = none)]
1643        pub unsafe fn epsilon(&self) -> c_float;
1644
1645        /// Setter for [`epsilon`][Self::epsilon].
1646        #[unsafe(method(setEpsilon:))]
1647        #[unsafe(method_family = none)]
1648        pub unsafe fn setEpsilon(&self, epsilon: c_float);
1649
1650        #[unsafe(method(delta))]
1651        #[unsafe(method_family = none)]
1652        pub unsafe fn delta(&self) -> c_float;
1653
1654        /// Setter for [`delta`][Self::delta].
1655        #[unsafe(method(setDelta:))]
1656        #[unsafe(method_family = none)]
1657        pub unsafe fn setDelta(&self, delta: c_float);
1658
1659        #[unsafe(method(initWithDevice:))]
1660        #[unsafe(method_family = init)]
1661        pub unsafe fn initWithDevice(
1662            this: Allocated<Self>,
1663            device: &ProtocolObject<dyn MTLDevice>,
1664        ) -> Retained<Self>;
1665
1666        /// Initialize the loss forward pass filter with a loss descriptor.
1667        ///
1668        /// Parameter `device`: The device the filter will run on.
1669        ///
1670        /// Parameter `lossDescriptor`: The loss descriptor.
1671        ///
1672        /// Returns: A valid MPSNNForwardLoss object or nil, if failure.
1673        #[unsafe(method(initWithDevice:lossDescriptor:))]
1674        #[unsafe(method_family = init)]
1675        pub unsafe fn initWithDevice_lossDescriptor(
1676            this: Allocated<Self>,
1677            device: &ProtocolObject<dyn MTLDevice>,
1678            loss_descriptor: &MPSCNNLossDescriptor,
1679        ) -> Retained<Self>;
1680
1681        /// <NSSecureCoding
1682        /// > support
1683        ///
1684        /// # Safety
1685        ///
1686        /// `a_decoder` possibly has further requirements.
1687        #[unsafe(method(initWithCoder:device:))]
1688        #[unsafe(method_family = init)]
1689        pub unsafe fn initWithCoder_device(
1690            this: Allocated<Self>,
1691            a_decoder: &NSCoder,
1692            device: &ProtocolObject<dyn MTLDevice>,
1693        ) -> Option<Retained<Self>>;
1694
1695        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
1696        /// Encode a MPSNNForwardLoss filter and return the result in the destinationImage.
1697        ///
1698        ///
1699        /// Parameter `commandBuffer`: The MTLCommandBuffer on which to encode.
1700        ///
1701        /// Parameter `sourceImages`: The source images that contains the network prediction (logits).
1702        ///
1703        /// Parameter `labels`: The source images that contains the labels (targets).
1704        ///
1705        /// Parameter `weights`: The object containing weights for the labels. Optional.
1706        ///
1707        /// Parameter `destinationStates`: Optional gradient state - carries dynamical property values to the gradient pass
1708        /// (weight, labelSmoothing, epsilon, delta). Create state using resultStateBatchForSourceImage: or
1709        /// temporaryResultStateBatchForCommandBuffer:.
1710        ///
1711        /// Parameter `destinationImages`: The MPSImages into which to write the loss results.
1712        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:labels:weights:destinationStates:destinationImages:))]
1713        #[unsafe(method_family = none)]
1714        pub unsafe fn encodeBatchToCommandBuffer_sourceImages_labels_weights_destinationStates_destinationImages(
1715            &self,
1716            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1717            source_images: &MPSImageBatch,
1718            labels: &MPSImageBatch,
1719            weights: Option<&MPSImageBatch>,
1720            destination_states: Option<&MPSStateBatch>,
1721            destination_images: &MPSImageBatch,
1722        );
1723
1724        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
1725        /// Encode a MPSNNForwardLoss filter and return the loss result image(s).
1726        ///
1727        /// This -encode call is similar to the encodeBatchToCommandBuffer:sourceImages:labels:destinationImages: above,
1728        /// except that it creates and returns the MPSImages with the loss result.
1729        ///
1730        ///
1731        /// Parameter `commandBuffer`: The MTLCommandBuffer on which to encode.
1732        ///
1733        /// Parameter `sourceImages`: The source images that contains the network prediction (logits).
1734        ///
1735        /// Parameter `labels`: The source images that contains the labels (targets).
1736        ///
1737        /// Parameter `weights`: The object containing weights for the labels. Optional.
1738        ///
1739        /// Parameter `outStates`: Optional gradient state - carries dynamical property values to the gradient pass
1740        /// (weight, labelSmoothing, epsilon, delta).
1741        ///
1742        /// Parameter `isTemporary`: Whether the returned state (if any) should be temporary or not.
1743        ///
1744        /// Returns: The MPSImages containing the loss computation results.
1745        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:labels:weights:destinationStates:destinationStateIsTemporary:))]
1746        #[unsafe(method_family = none)]
1747        pub unsafe fn encodeBatchToCommandBuffer_sourceImages_labels_weights_destinationStates_destinationStateIsTemporary(
1748            &self,
1749            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1750            source_images: &MPSImageBatch,
1751            labels: &MPSImageBatch,
1752            weights: Option<&MPSImageBatch>,
1753            out_states: Option<&mut Option<Retained<MPSStateBatch>>>,
1754            is_temporary: bool,
1755        ) -> Retained<MPSImageBatch>;
1756    );
1757}
1758
1759/// Methods declared on superclass `MPSKernel`.
1760#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1761impl MPSNNForwardLoss {
1762    extern_methods!(
1763        /// Called by NSCoder to decode MPSKernels
1764        ///
1765        /// This isn't the right interface to decode a MPSKernel, but
1766        /// it is the one that NSCoder uses. To enable your NSCoder
1767        /// (e.g. NSKeyedUnarchiver) to set which device to use
1768        /// extend the object to adopt the MPSDeviceProvider
1769        /// protocol. Otherwise, the Metal system default device
1770        /// will be used.
1771        ///
1772        /// # Safety
1773        ///
1774        /// `a_decoder` possibly has further requirements.
1775        #[unsafe(method(initWithCoder:))]
1776        #[unsafe(method_family = init)]
1777        pub unsafe fn initWithCoder(
1778            this: Allocated<Self>,
1779            a_decoder: &NSCoder,
1780        ) -> Option<Retained<Self>>;
1781    );
1782}
1783
1784/// Methods declared on superclass `NSObject`.
1785#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1786impl MPSNNForwardLoss {
1787    extern_methods!(
1788        #[unsafe(method(init))]
1789        #[unsafe(method_family = init)]
1790        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
1791
1792        #[unsafe(method(new))]
1793        #[unsafe(method_family = new)]
1794        pub unsafe fn new() -> Retained<Self>;
1795    );
1796}
1797
1798extern_class!(
1799    /// Dependencies: This depends on Metal.framework.
1800    ///
1801    /// The MPSNNLossGradient filter specifies the gradient filter for
1802    /// MPSNNForwardLoss.
1803    ///
1804    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpsnnlossgradient?language=objc)
1805    #[unsafe(super(MPSCNNBinaryKernel, MPSKernel, NSObject))]
1806    #[derive(Debug, PartialEq, Eq, Hash)]
1807    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1808    pub struct MPSNNLossGradient;
1809);
1810
1811#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1812extern_conformance!(
1813    unsafe impl NSCoding for MPSNNLossGradient {}
1814);
1815
1816#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1817extern_conformance!(
1818    unsafe impl NSCopying for MPSNNLossGradient {}
1819);
1820
1821#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1822unsafe impl CopyingHelper for MPSNNLossGradient {
1823    type Result = Self;
1824}
1825
1826#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1827extern_conformance!(
1828    unsafe impl NSObjectProtocol for MPSNNLossGradient {}
1829);
1830
1831#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1832extern_conformance!(
1833    unsafe impl NSSecureCoding for MPSNNLossGradient {}
1834);
1835
1836#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
1837impl MPSNNLossGradient {
1838    extern_methods!(
1839        #[cfg(feature = "MPSCNNTypes")]
1840        /// See MPSCNNLossDescriptor for information about the following properties.
1841        #[unsafe(method(lossType))]
1842        #[unsafe(method_family = none)]
1843        pub unsafe fn lossType(&self) -> MPSCNNLossType;
1844
1845        #[cfg(feature = "MPSCNNTypes")]
1846        #[unsafe(method(reductionType))]
1847        #[unsafe(method_family = none)]
1848        pub unsafe fn reductionType(&self) -> MPSCNNReductionType;
1849
1850        #[unsafe(method(reduceAcrossBatch))]
1851        #[unsafe(method_family = none)]
1852        pub unsafe fn reduceAcrossBatch(&self) -> bool;
1853
1854        #[unsafe(method(numberOfClasses))]
1855        #[unsafe(method_family = none)]
1856        pub unsafe fn numberOfClasses(&self) -> NSUInteger;
1857
1858        #[unsafe(method(weight))]
1859        #[unsafe(method_family = none)]
1860        pub unsafe fn weight(&self) -> c_float;
1861
1862        /// Setter for [`weight`][Self::weight].
1863        #[unsafe(method(setWeight:))]
1864        #[unsafe(method_family = none)]
1865        pub unsafe fn setWeight(&self, weight: c_float);
1866
1867        #[unsafe(method(labelSmoothing))]
1868        #[unsafe(method_family = none)]
1869        pub unsafe fn labelSmoothing(&self) -> c_float;
1870
1871        /// Setter for [`labelSmoothing`][Self::labelSmoothing].
1872        #[unsafe(method(setLabelSmoothing:))]
1873        #[unsafe(method_family = none)]
1874        pub unsafe fn setLabelSmoothing(&self, label_smoothing: c_float);
1875
1876        #[unsafe(method(epsilon))]
1877        #[unsafe(method_family = none)]
1878        pub unsafe fn epsilon(&self) -> c_float;
1879
1880        /// Setter for [`epsilon`][Self::epsilon].
1881        #[unsafe(method(setEpsilon:))]
1882        #[unsafe(method_family = none)]
1883        pub unsafe fn setEpsilon(&self, epsilon: c_float);
1884
1885        #[unsafe(method(delta))]
1886        #[unsafe(method_family = none)]
1887        pub unsafe fn delta(&self) -> c_float;
1888
1889        /// Setter for [`delta`][Self::delta].
1890        #[unsafe(method(setDelta:))]
1891        #[unsafe(method_family = none)]
1892        pub unsafe fn setDelta(&self, delta: c_float);
1893
1894        /// The computeLabelGradients property is used to control whether the loss gradient
1895        /// filter computes gradients for the primary (predictions) or secondary (labels) source image from the forward pass.
1896        /// Default: NO.
1897        #[unsafe(method(computeLabelGradients))]
1898        #[unsafe(method_family = none)]
1899        pub unsafe fn computeLabelGradients(&self) -> bool;
1900
1901        /// Setter for [`computeLabelGradients`][Self::computeLabelGradients].
1902        #[unsafe(method(setComputeLabelGradients:))]
1903        #[unsafe(method_family = none)]
1904        pub unsafe fn setComputeLabelGradients(&self, compute_label_gradients: bool);
1905
1906        #[unsafe(method(initWithDevice:))]
1907        #[unsafe(method_family = init)]
1908        pub unsafe fn initWithDevice(
1909            this: Allocated<Self>,
1910            device: &ProtocolObject<dyn MTLDevice>,
1911        ) -> Retained<Self>;
1912
1913        /// Initialize the loss gradient filter with a loss descriptor.
1914        ///
1915        /// Parameter `device`: The device the filter will run on.
1916        ///
1917        /// Parameter `lossDescriptor`: The loss descriptor.
1918        ///
1919        /// Returns: A valid MPSNNLossGradient object or nil, if failure.
1920        #[unsafe(method(initWithDevice:lossDescriptor:))]
1921        #[unsafe(method_family = init)]
1922        pub unsafe fn initWithDevice_lossDescriptor(
1923            this: Allocated<Self>,
1924            device: &ProtocolObject<dyn MTLDevice>,
1925            loss_descriptor: &MPSCNNLossDescriptor,
1926        ) -> Retained<Self>;
1927
1928        /// <NSSecureCoding
1929        /// > support
1930        ///
1931        /// # Safety
1932        ///
1933        /// `a_decoder` possibly has further requirements.
1934        #[unsafe(method(initWithCoder:device:))]
1935        #[unsafe(method_family = init)]
1936        pub unsafe fn initWithCoder_device(
1937            this: Allocated<Self>,
1938            a_decoder: &NSCoder,
1939            device: &ProtocolObject<dyn MTLDevice>,
1940        ) -> Option<Retained<Self>>;
1941
1942        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
1943        /// Encode the loss gradient filter and return a gradient
1944        ///
1945        /// Parameter `commandBuffer`: The MTLCommandBuffer on which to encode
1946        ///
1947        /// Parameter `sourceGradients`: The gradient images from the "next" filter in the graph
1948        ///
1949        /// Parameter `sourceImages`: The images used as source image from the forward pass
1950        ///
1951        /// Parameter `labels`: The source images that contains the labels (targets).
1952        ///
1953        /// Parameter `weights`: The object containing weights for the labels. Optional.
1954        ///
1955        /// Parameter `sourceStates`: Optional gradient state - carries dynamical property values from the forward pass
1956        /// (weight, labelSmoothing, epsilon, delta).
1957        #[unsafe(method(encodeBatchToCommandBuffer:sourceGradients:sourceImages:labels:weights:sourceStates:))]
1958        #[unsafe(method_family = none)]
1959        pub unsafe fn encodeBatchToCommandBuffer_sourceGradients_sourceImages_labels_weights_sourceStates(
1960            &self,
1961            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1962            source_gradients: &MPSImageBatch,
1963            source_images: &MPSImageBatch,
1964            labels: &MPSImageBatch,
1965            weights: Option<&MPSImageBatch>,
1966            source_states: Option<&MPSStateBatch>,
1967        ) -> Retained<MPSImageBatch>;
1968
1969        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
1970        /// Encode the loss gradient filter and return a gradient
1971        ///
1972        /// Parameter `commandBuffer`: The MTLCommandBuffer on which to encode
1973        ///
1974        /// Parameter `sourceGradients`: The gradient images from the "next" filter in the graph
1975        ///
1976        /// Parameter `sourceImages`: The image used as source images from the forward pass
1977        ///
1978        /// Parameter `labels`: The source images that contains the labels (targets).
1979        ///
1980        /// Parameter `weights`: The object containing weights for the labels. Optional.
1981        ///
1982        /// Parameter `sourceStates`: Optional gradient state - carries dynamical property values from the forward pass
1983        /// (weight, labelSmoothing, epsilon, delta).
1984        ///
1985        /// Parameter `destinationGradients`: The MPSImages into which to write the filter result
1986        #[unsafe(method(encodeBatchToCommandBuffer:sourceGradients:sourceImages:labels:weights:sourceStates:destinationGradients:))]
1987        #[unsafe(method_family = none)]
1988        pub unsafe fn encodeBatchToCommandBuffer_sourceGradients_sourceImages_labels_weights_sourceStates_destinationGradients(
1989            &self,
1990            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1991            source_gradients: &MPSImageBatch,
1992            source_images: &MPSImageBatch,
1993            labels: &MPSImageBatch,
1994            weights: Option<&MPSImageBatch>,
1995            source_states: Option<&MPSStateBatch>,
1996            destination_gradients: &MPSImageBatch,
1997        );
1998    );
1999}
2000
2001/// Methods declared on superclass `MPSKernel`.
2002#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2003impl MPSNNLossGradient {
2004    extern_methods!(
2005        /// Called by NSCoder to decode MPSKernels
2006        ///
2007        /// This isn't the right interface to decode a MPSKernel, but
2008        /// it is the one that NSCoder uses. To enable your NSCoder
2009        /// (e.g. NSKeyedUnarchiver) to set which device to use
2010        /// extend the object to adopt the MPSDeviceProvider
2011        /// protocol. Otherwise, the Metal system default device
2012        /// will be used.
2013        ///
2014        /// # Safety
2015        ///
2016        /// `a_decoder` possibly has further requirements.
2017        #[unsafe(method(initWithCoder:))]
2018        #[unsafe(method_family = init)]
2019        pub unsafe fn initWithCoder(
2020            this: Allocated<Self>,
2021            a_decoder: &NSCoder,
2022        ) -> Option<Retained<Self>>;
2023    );
2024}
2025
2026/// Methods declared on superclass `NSObject`.
2027#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2028impl MPSNNLossGradient {
2029    extern_methods!(
2030        #[unsafe(method(init))]
2031        #[unsafe(method_family = init)]
2032        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
2033
2034        #[unsafe(method(new))]
2035        #[unsafe(method_family = new)]
2036        pub unsafe fn new() -> Retained<Self>;
2037    );
2038}
2039
2040extern_class!(
2041    /// Dependencies: This depends on Metal.framework
2042    ///
2043    /// The MPSCNNInitialGradient filter specifies a layer which computes the initial gradient for
2044    /// an aribitrary input image. The operation itself is extremely simple: it computes the gradient of the input image
2045    /// with itself, resulting in an output image which is filled with '1's for all the inputs that were used.
2046    /// This serves as the starting point for the computation of gradients between arbitrary images in a network.
2047    /// Example:
2048    /// Suppose that we want to compute gradients for a function that multiplies together two losses:
2049    /// f = f(L1, L2) = L1 * L2
2050    /// The losses themselves are computed from some inputs x1,x2:
2051    /// L1 = L1(x1),
2052    /// L2 = L2(x2)
2053    /// The filters to compute f, L1, L2 are:
2054    /// f = MPSCNNMultiply(L1, L2), where
2055    /// L1 = MPSNNForwardLoss1(x1) and
2056    /// L2 = MPSNNForwardLoss1(x2)
2057    ///
2058    /// To compute df/dx1 we apply the chain rule:
2059    ///
2060    /// df/dx1 = d(L1 * L2)/dx1 = d(L1 * L2)/dL1 * dL1/dx1 + d(L1 * L2)/dL2 * dL2/dx1
2061    /// = d(L1 * L2)/dL1 * dL1/dx1 = L2 * dL1/dx1
2062    ///
2063    /// The MPSCNNMultiplyGradient filter computes for f = L1 * L2 forward op:
2064    /// dL/dL1 = dL/df * df/dL1 = dL/df * L2 and
2065    /// dL/dL2 = dL/df * df/dL2 = dL/df * L1 where
2066    /// dL/df is the input gradient of the chain rule / backpropagation algorithm.
2067    /// But in our case we want MPSCNNMultiplyGradient to compute the gradient:
2068    /// df/dL1 = d(L1 * L2)/dL1 = L2,
2069    /// which shows that
2070    /// L = f, which means that dL/dL1 = df/df * df/dL1 = 1 * L2, which
2071    /// shows that we get the correct gradient by providing unit input as input gradient to
2072    /// the MPSCNNMultiplyGradient.
2073    ///
2074    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpsnninitialgradient?language=objc)
2075    #[unsafe(super(MPSCNNKernel, MPSKernel, NSObject))]
2076    #[derive(Debug, PartialEq, Eq, Hash)]
2077    #[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2078    pub struct MPSNNInitialGradient;
2079);
2080
2081#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2082extern_conformance!(
2083    unsafe impl NSCoding for MPSNNInitialGradient {}
2084);
2085
2086#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2087extern_conformance!(
2088    unsafe impl NSCopying for MPSNNInitialGradient {}
2089);
2090
2091#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2092unsafe impl CopyingHelper for MPSNNInitialGradient {
2093    type Result = Self;
2094}
2095
2096#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2097extern_conformance!(
2098    unsafe impl NSObjectProtocol for MPSNNInitialGradient {}
2099);
2100
2101#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2102extern_conformance!(
2103    unsafe impl NSSecureCoding for MPSNNInitialGradient {}
2104);
2105
2106#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2107impl MPSNNInitialGradient {
2108    extern_methods!(
2109        /// Initializes a MPSNNInitialGradient kernel.
2110        ///
2111        ///
2112        /// Parameter `device`: The MTLDevice on which this MPSNNInitialGradient filter will be used.
2113        ///
2114        /// Returns: A valid MPSNNInitialGradient object or nil, if failure.
2115        #[unsafe(method(initWithDevice:))]
2116        #[unsafe(method_family = init)]
2117        pub unsafe fn initWithDevice(
2118            this: Allocated<Self>,
2119            device: &ProtocolObject<dyn MTLDevice>,
2120        ) -> Retained<Self>;
2121    );
2122}
2123
2124/// Methods declared on superclass `MPSCNNKernel`.
2125#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2126impl MPSNNInitialGradient {
2127    extern_methods!(
2128        /// NSSecureCoding compatability
2129        ///
2130        /// While the standard NSSecureCoding/NSCoding method
2131        /// -initWithCoder: should work, since the file can't
2132        /// know which device your data is allocated on, we
2133        /// have to guess and may guess incorrectly.  To avoid
2134        /// that problem, use initWithCoder:device instead.
2135        ///
2136        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
2137        ///
2138        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
2139        ///
2140        /// Returns: A new MPSKernel object, or nil if failure.
2141        ///
2142        /// # Safety
2143        ///
2144        /// `a_decoder` possibly has further requirements.
2145        #[unsafe(method(initWithCoder:device:))]
2146        #[unsafe(method_family = init)]
2147        pub unsafe fn initWithCoder_device(
2148            this: Allocated<Self>,
2149            a_decoder: &NSCoder,
2150            device: &ProtocolObject<dyn MTLDevice>,
2151        ) -> Option<Retained<Self>>;
2152    );
2153}
2154
2155/// Methods declared on superclass `MPSKernel`.
2156#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2157impl MPSNNInitialGradient {
2158    extern_methods!(
2159        /// Called by NSCoder to decode MPSKernels
2160        ///
2161        /// This isn't the right interface to decode a MPSKernel, but
2162        /// it is the one that NSCoder uses. To enable your NSCoder
2163        /// (e.g. NSKeyedUnarchiver) to set which device to use
2164        /// extend the object to adopt the MPSDeviceProvider
2165        /// protocol. Otherwise, the Metal system default device
2166        /// will be used.
2167        ///
2168        /// # Safety
2169        ///
2170        /// `a_decoder` possibly has further requirements.
2171        #[unsafe(method(initWithCoder:))]
2172        #[unsafe(method_family = init)]
2173        pub unsafe fn initWithCoder(
2174            this: Allocated<Self>,
2175            a_decoder: &NSCoder,
2176        ) -> Option<Retained<Self>>;
2177    );
2178}
2179
2180/// Methods declared on superclass `NSObject`.
2181#[cfg(all(feature = "MPSCNNKernel", feature = "MPSCore", feature = "MPSKernel"))]
2182impl MPSNNInitialGradient {
2183    extern_methods!(
2184        #[unsafe(method(init))]
2185        #[unsafe(method_family = init)]
2186        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
2187
2188        #[unsafe(method(new))]
2189        #[unsafe(method_family = new)]
2190        pub unsafe fn new() -> Retained<Self>;
2191    );
2192}