objc2_metal_performance_shaders/generated/MPSNeuralNetwork/
MPSCNNKernel.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    /// Describes a convolution neural network kernel.
15    ///
16    /// A MPSCNNKernel consumes one MPSImage and produces one MPSImage.
17    ///
18    /// The region overwritten in the destination MPSImage is described
19    /// by the clipRect.  The top left corner of the region consumed (ignoring
20    /// adjustments for filter size -- e.g. convolution filter size) is given
21    /// by the offset. The size of the region consumed is a function of the
22    /// clipRect size and any subsampling caused by pixel strides at work,
23    /// e.g. MPSCNNPooling.strideInPixelsX/Y.  Where the offset + clipRect
24    /// would cause a {x,y} pixel address not in the image to be read, the
25    /// edgeMode is used to determine what value to read there.
26    ///
27    /// The Z/depth component of the offset, clipRect.origin and clipRect.size
28    /// indexes which images to use. If the MPSImage contains only a single image
29    /// then these should be offset.z = 0, clipRect.origin.z = 0
30    /// and clipRect.size.depth = 1. If the MPSImage contains multiple images,
31    /// clipRect.size.depth refers to number of images to process. Both source
32    /// and destination MPSImages must have at least this many images. offset.z
33    /// refers to starting source image index. Thus offset.z + clipRect.size.depth must
34    /// be
35    /// <
36    /// = source.numberOfImages. Similarly, clipRect.origin.z refers to starting
37    /// image index in destination. So clipRect.origin.z + clipRect.size.depth must be
38    /// <
39    /// = destination.numberOfImage.
40    ///
41    /// destinationFeatureChannelOffset property can be used to control where the MPSKernel will
42    /// start writing in feature channel dimension. For example, if the destination image has
43    /// 64 channels, and MPSKernel outputs 32 channels, by default channels 0-31 of destination
44    /// will be populated by MPSKernel. But if we want this MPSKernel to populate channel 32-63
45    /// of the destination, we can set destinationFeatureChannelOffset = 32.
46    /// A good example of this is concat (concatenation) operation in Tensor Flow. Suppose
47    /// we have a src = w x h x Ni which goes through CNNConvolution_0 which produces
48    /// output O0 = w x h x N0 and CNNConvolution_1 which produces output O1 = w x h x N1 followed
49    /// by concatenation which produces O = w x h x (N0 + N1). We can achieve this by creating
50    /// an MPSImage with dimensions O = w x h x (N0 + N1) and using this as destination of
51    /// both convolutions as follows
52    /// CNNConvolution0: destinationFeatureChannelOffset = 0, this will output N0 channels starting at
53    /// channel 0 of destination thus populating [0,N0-1] channels.
54    /// CNNConvolution1: destinationFeatureChannelOffset = N0, this will output N1 channels starting at
55    /// channel N0 of destination thus populating [N0,N0+N1-1] channels.
56    ///
57    /// A MPSCNNKernel can be saved to disk / network using NSCoders such as NSKeyedArchiver.
58    /// When decoding, the system default MTLDevice will be chosen unless the NSCoder adopts
59    /// the
60    /// <MPSDeviceProvider
61    /// > protocol.  To accomplish this you will likely need to subclass your
62    /// unarchiver to add this method.
63    ///
64    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnkernel?language=objc)
65    #[unsafe(super(MPSKernel, NSObject))]
66    #[derive(Debug, PartialEq, Eq, Hash)]
67    #[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
68    pub struct MPSCNNKernel;
69);
70
71#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
72extern_conformance!(
73    unsafe impl NSCoding for MPSCNNKernel {}
74);
75
76#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
77extern_conformance!(
78    unsafe impl NSCopying for MPSCNNKernel {}
79);
80
81#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
82unsafe impl CopyingHelper for MPSCNNKernel {
83    type Result = Self;
84}
85
86#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
87extern_conformance!(
88    unsafe impl NSObjectProtocol for MPSCNNKernel {}
89);
90
91#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
92extern_conformance!(
93    unsafe impl NSSecureCoding for MPSCNNKernel {}
94);
95
96#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
97impl MPSCNNKernel {
98    extern_methods!(
99        /// Standard init with default properties per filter type
100        ///
101        /// Parameter `device`: The device that the filter will be used on. May not be NULL.
102        ///
103        /// Returns: A pointer to the newly initialized object. This will fail, returning
104        /// nil if the device is not supported. Devices must be
105        /// MTLFeatureSet_iOS_GPUFamily2_v1 or later.
106        #[unsafe(method(initWithDevice:))]
107        #[unsafe(method_family = init)]
108        pub unsafe fn initWithDevice(
109            this: Allocated<Self>,
110            device: &ProtocolObject<dyn MTLDevice>,
111        ) -> Retained<Self>;
112
113        #[cfg(feature = "MPSCoreTypes")]
114        /// The position of the destination clip rectangle origin relative to the source buffer.
115        ///
116        /// The offset is defined to be the position of clipRect.origin in source coordinates.
117        /// Default: {0,0,0}, indicating that the top left corners of the clipRect and source image align.
118        /// offset.z is the index of starting source image in batch processing mode.
119        ///
120        /// See Also:
121        /// MetalPerformanceShaders.hsubsubsection_mpsoffset
122        #[unsafe(method(offset))]
123        #[unsafe(method_family = none)]
124        pub unsafe fn offset(&self) -> MPSOffset;
125
126        #[cfg(feature = "MPSCoreTypes")]
127        /// Setter for [`offset`][Self::offset].
128        #[unsafe(method(setOffset:))]
129        #[unsafe(method_family = none)]
130        pub unsafe fn setOffset(&self, offset: MPSOffset);
131
132        /// An optional clip rectangle to use when writing data. Only the pixels in the rectangle will be overwritten.
133        ///
134        /// A MTLRegion that indicates which part of the destination to overwrite. If the clipRect does not lie
135        /// completely within the destination image, the intersection between clip rectangle and destination bounds is
136        /// used.   Default: MPSRectNoClip (MPSKernel::MPSRectNoClip) indicating the entire image.
137        /// clipRect.origin.z is the index of starting destination image in batch processing mode. clipRect.size.depth
138        /// is the number of images to process in batch processing mode.
139        ///
140        /// See Also:
141        /// MetalPerformanceShaders.hsubsubsection_clipRect
142        #[unsafe(method(clipRect))]
143        #[unsafe(method_family = none)]
144        pub unsafe fn clipRect(&self) -> MTLRegion;
145
146        /// Setter for [`clipRect`][Self::clipRect].
147        #[unsafe(method(setClipRect:))]
148        #[unsafe(method_family = none)]
149        pub unsafe fn setClipRect(&self, clip_rect: MTLRegion);
150
151        /// The number of channels in the destination MPSImage to skip before writing output.
152        ///
153        /// This is the starting offset into the destination image in the feature channel dimension
154        /// at which destination data is written.
155        /// This allows an application to pass a subset of all the channels in MPSImage as output of MPSKernel.
156        /// E.g. Suppose MPSImage has 24 channels and a MPSKernel outputs 8 channels. If
157        /// we want channels 8 to 15 of this MPSImage to be used as output, we can set destinationFeatureChannelOffset = 8.
158        /// Note that this offset applies independently to each image when the MPSImage
159        /// is a container for multiple images and the MPSCNNKernel is processing multiple images (clipRect.size.depth > 1).
160        /// The default value is 0 and any value specifed shall be a multiple of 4. If MPSKernel outputs N channels,
161        /// the destination image MUST have at least destinationFeatureChannelOffset + N channels. Using a destination
162        /// image with insufficient number of feature channels will result in an error.
163        /// E.g. if the MPSCNNConvolution outputs 32 channels, and the destination has 64 channels, then it is an error to set
164        /// destinationFeatureChannelOffset > 32.
165        #[unsafe(method(destinationFeatureChannelOffset))]
166        #[unsafe(method_family = none)]
167        pub unsafe fn destinationFeatureChannelOffset(&self) -> NSUInteger;
168
169        /// Setter for [`destinationFeatureChannelOffset`][Self::destinationFeatureChannelOffset].
170        #[unsafe(method(setDestinationFeatureChannelOffset:))]
171        #[unsafe(method_family = none)]
172        pub unsafe fn setDestinationFeatureChannelOffset(
173            &self,
174            destination_feature_channel_offset: NSUInteger,
175        );
176
177        /// The number of channels in the source MPSImage to skip before reading the input.
178        ///
179        /// This is the starting offset into the source image in the feature channel dimension
180        /// at which source data is read. Unit: feature channels
181        /// This allows an application to read a subset of all the channels in MPSImage as input of MPSKernel.
182        /// E.g. Suppose MPSImage has 24 channels and a MPSKernel needs to read 8 channels. If
183        /// we want channels 8 to 15 of this MPSImage to be used as input, we can set sourceFeatureChannelOffset = 8.
184        /// Note that this offset applies independently to each image when the MPSImage
185        /// is a container for multiple images and the MPSCNNKernel is processing multiple images (clipRect.size.depth > 1).
186        /// The default value is 0 and any value specifed shall be a multiple of 4. If MPSKernel inputs N channels,
187        /// the source image MUST have at least sourceFeatureChannelOffset + N channels. Using a source
188        /// image with insufficient number of feature channels will result in an error.
189        /// E.g. if the MPSCNNConvolution inputs 32 channels, and the source has 64 channels, then it is an error to set
190        /// sourceFeatureChannelOffset > 32.
191        #[unsafe(method(sourceFeatureChannelOffset))]
192        #[unsafe(method_family = none)]
193        pub unsafe fn sourceFeatureChannelOffset(&self) -> NSUInteger;
194
195        /// Setter for [`sourceFeatureChannelOffset`][Self::sourceFeatureChannelOffset].
196        #[unsafe(method(setSourceFeatureChannelOffset:))]
197        #[unsafe(method_family = none)]
198        pub unsafe fn setSourceFeatureChannelOffset(
199            &self,
200            source_feature_channel_offset: NSUInteger,
201        );
202
203        /// The maximum number of channels in the source MPSImage to use
204        ///
205        /// Most filters can insert a slice operation into the filter for free.
206        /// Use this to limit the size of the feature channel slice taken from
207        /// the input image. If the value is too large, it is truncated to be
208        /// the remaining size in the image after the sourceFeatureChannelOffset
209        /// is taken into account.  Default: ULONG_MAX
210        #[unsafe(method(sourceFeatureChannelMaxCount))]
211        #[unsafe(method_family = none)]
212        pub unsafe fn sourceFeatureChannelMaxCount(&self) -> NSUInteger;
213
214        /// Setter for [`sourceFeatureChannelMaxCount`][Self::sourceFeatureChannelMaxCount].
215        #[unsafe(method(setSourceFeatureChannelMaxCount:))]
216        #[unsafe(method_family = none)]
217        pub unsafe fn setSourceFeatureChannelMaxCount(
218            &self,
219            source_feature_channel_max_count: NSUInteger,
220        );
221
222        #[cfg(feature = "MPSCoreTypes")]
223        /// The MPSImageEdgeMode to use when texture reads stray off the edge of an image
224        ///
225        /// Most MPSKernel objects can read off the edge of the source image. This can happen
226        /// because of a negative offset property, because the offset + clipRect.size is larger
227        /// than the source image or because the filter looks at neighboring pixels, such as a
228        /// Convolution filter.   Default:  MPSImageEdgeModeZero.
229        ///
230        /// See Also:
231        /// MetalPerformanceShaders.hsubsubsection_edgemode
232        /// Note: For
233        /// MPSCNNPoolingAveragespecifying edge mode
234        /// MPSImageEdgeModeClampis interpreted as a "shrink-to-edge" operation, which shrinks the effective
235        /// filtering window to remain within the source image borders.
236        #[unsafe(method(edgeMode))]
237        #[unsafe(method_family = none)]
238        pub unsafe fn edgeMode(&self) -> MPSImageEdgeMode;
239
240        #[cfg(feature = "MPSCoreTypes")]
241        /// Setter for [`edgeMode`][Self::edgeMode].
242        #[unsafe(method(setEdgeMode:))]
243        #[unsafe(method_family = none)]
244        pub unsafe fn setEdgeMode(&self, edge_mode: MPSImageEdgeMode);
245
246        /// The width of the MPSCNNKernel filter window
247        ///
248        /// This is the horizontal diameter of the region read by the filter for each
249        /// result pixel. If the MPSCNNKernel does not have a filter window, then
250        /// 1 will be returned.
251        ///
252        /// Warning: This property was lowered to this class in ios/tvos 11
253        /// The property may not be available on iOS/tvOS 10 for
254        /// all subclasses of MPSCNNKernel
255        #[unsafe(method(kernelWidth))]
256        #[unsafe(method_family = none)]
257        pub unsafe fn kernelWidth(&self) -> NSUInteger;
258
259        /// The height of the MPSCNNKernel filter window
260        ///
261        /// This is the vertical diameter of the region read by the filter for each
262        /// result pixel. If the MPSCNNKernel does not have a filter window, then
263        /// 1 will be returned.
264        ///
265        /// Warning: This property was lowered to this class in ios/tvos 11
266        /// The property may not be available on iOS/tvOS 10 for
267        /// all subclasses of MPSCNNKernel
268        #[unsafe(method(kernelHeight))]
269        #[unsafe(method_family = none)]
270        pub unsafe fn kernelHeight(&self) -> NSUInteger;
271
272        /// The downsampling (or upsampling if a backwards filter) factor in the horizontal dimension
273        ///
274        /// If the filter does not do up or downsampling, 1 is returned.
275        ///
276        /// Warning: This property was lowered to this class in ios/tvos 11
277        /// The property may not be available on iOS/tvOS 10 for
278        /// all subclasses of MPSCNNKernel
279        #[unsafe(method(strideInPixelsX))]
280        #[unsafe(method_family = none)]
281        pub unsafe fn strideInPixelsX(&self) -> NSUInteger;
282
283        /// The downsampling (or upsampling if a backwards filter) factor in the vertical dimension
284        ///
285        /// If the filter does not do up or downsampling, 1 is returned.
286        ///
287        /// Warning: This property was lowered to this class in ios/tvos 11
288        /// The property may not be available on iOS/tvOS 10 for
289        /// all subclasses of MPSCNNKernel
290        #[unsafe(method(strideInPixelsY))]
291        #[unsafe(method_family = none)]
292        pub unsafe fn strideInPixelsY(&self) -> NSUInteger;
293
294        /// Stride in source coordinates from one kernel tap to the next in the X dimension.
295        #[unsafe(method(dilationRateX))]
296        #[unsafe(method_family = none)]
297        pub unsafe fn dilationRateX(&self) -> NSUInteger;
298
299        /// Stride in source coordinates from one kernel tap to the next in the Y dimension.
300        #[unsafe(method(dilationRateY))]
301        #[unsafe(method_family = none)]
302        pub unsafe fn dilationRateY(&self) -> NSUInteger;
303
304        /// YES if the filter operates backwards.
305        ///
306        /// This influences how strideInPixelsX/Y should be interpreted.
307        /// Most filters either have stride 1 or are reducing, meaning that
308        /// the result image is smaller than the original by roughly a factor
309        /// of the stride.  A few "backward" filters (e.g convolution transpose) are intended
310        /// to "undo" the effects of an earlier forward filter, and so
311        /// enlarge the image. The stride is in the destination coordinate frame
312        /// rather than the source coordinate frame.
313        #[unsafe(method(isBackwards))]
314        #[unsafe(method_family = none)]
315        pub unsafe fn isBackwards(&self) -> bool;
316
317        /// Returns true if the -encode call modifies the state object it accepts.
318        #[unsafe(method(isStateModified))]
319        #[unsafe(method_family = none)]
320        pub unsafe fn isStateModified(&self) -> bool;
321
322        #[cfg(feature = "MPSNeuralNetworkTypes")]
323        /// The padding method used by the filter
324        ///
325        /// This influences how the destination image is sized and how
326        /// the offset into the source image is set.  It is used by the
327        /// -encode methods that return a MPSImage from the left hand side.
328        #[unsafe(method(padding))]
329        #[unsafe(method_family = none)]
330        pub unsafe fn padding(&self) -> Retained<ProtocolObject<dyn MPSNNPadding>>;
331
332        #[cfg(feature = "MPSNeuralNetworkTypes")]
333        /// Setter for [`padding`][Self::padding].
334        #[unsafe(method(setPadding:))]
335        #[unsafe(method_family = none)]
336        pub unsafe fn setPadding(&self, padding: &ProtocolObject<dyn MPSNNPadding>);
337
338        #[cfg(feature = "MPSImage")]
339        /// Method to allocate the result image for -encodeToCommandBuffer:sourceImage:
340        ///
341        /// Default: MPSTemporaryImage.defaultAllocator
342        #[unsafe(method(destinationImageAllocator))]
343        #[unsafe(method_family = none)]
344        pub unsafe fn destinationImageAllocator(
345            &self,
346        ) -> Retained<ProtocolObject<dyn MPSImageAllocator>>;
347
348        #[cfg(feature = "MPSImage")]
349        /// Setter for [`destinationImageAllocator`][Self::destinationImageAllocator].
350        #[unsafe(method(setDestinationImageAllocator:))]
351        #[unsafe(method_family = none)]
352        pub unsafe fn setDestinationImageAllocator(
353            &self,
354            destination_image_allocator: &ProtocolObject<dyn MPSImageAllocator>,
355        );
356
357        /// NSSecureCoding compatability
358        ///
359        /// While the standard NSSecureCoding/NSCoding method
360        /// -initWithCoder: should work, since the file can't
361        /// know which device your data is allocated on, we
362        /// have to guess and may guess incorrectly.  To avoid
363        /// that problem, use initWithCoder:device instead.
364        ///
365        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
366        ///
367        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
368        ///
369        /// Returns: A new MPSKernel object, or nil if failure.
370        ///
371        /// # Safety
372        ///
373        /// `a_decoder` possibly has further requirements.
374        #[unsafe(method(initWithCoder:device:))]
375        #[unsafe(method_family = init)]
376        pub unsafe fn initWithCoder_device(
377            this: Allocated<Self>,
378            a_decoder: &NSCoder,
379            device: &ProtocolObject<dyn MTLDevice>,
380        ) -> Option<Retained<Self>>;
381
382        #[cfg(feature = "MPSImage")]
383        /// Encode a MPSCNNKernel into a command Buffer.  The operation shall proceed out-of-place.
384        ///
385        /// This is the older style of encode which reads the offset, doesn't change it,
386        /// and ignores the padding method.
387        ///
388        /// Parameter `commandBuffer`: A valid MTLCommandBuffer to receive the encoded filter
389        ///
390        /// Parameter `sourceImage`: A valid MPSImage object containing the source image.
391        ///
392        /// Parameter `destinationImage`: A valid MPSImage to be overwritten by result image. destinationImage may not alias sourceImage.
393        #[unsafe(method(encodeToCommandBuffer:sourceImage:destinationImage:))]
394        #[unsafe(method_family = none)]
395        pub unsafe fn encodeToCommandBuffer_sourceImage_destinationImage(
396            &self,
397            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
398            source_image: &MPSImage,
399            destination_image: &MPSImage,
400        );
401
402        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
403        /// Encode a MPSCNNKernel with a destination state into a command Buffer.
404        ///
405        /// This is typically used during training. The state is commonly a MPSNNGradientState.
406        /// Please see -resultStateForSourceImages:SourceStates: and batch+temporary variants.
407        ///
408        /// Parameter `commandBuffer`: A valid MTLCommandBuffer to receive the encoded filter
409        ///
410        /// Parameter `sourceImage`: A valid MPSImage object containing the source image.
411        ///
412        /// Parameter `destinationState`: A state to be overwritten by additional state information.
413        ///
414        /// Parameter `destinationImage`: A valid MPSImage to be overwritten by result image. destinationImage may not alias sourceImage.
415        #[unsafe(method(encodeToCommandBuffer:sourceImage:destinationState:destinationImage:))]
416        #[unsafe(method_family = none)]
417        pub unsafe fn encodeToCommandBuffer_sourceImage_destinationState_destinationImage(
418            &self,
419            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
420            source_image: &MPSImage,
421            destination_state: &MPSState,
422            destination_image: &MPSImage,
423        );
424
425        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray"))]
426        /// Encode a MPSCNNKernel into a command Buffer.  The operation shall proceed out-of-place.
427        ///
428        /// This is the older style of encode which reads the offset, doesn't change it,
429        /// and ignores the padding method.
430        ///
431        /// Parameter `commandBuffer`: A valid MTLCommandBuffer to receive the encoded filter
432        ///
433        /// Parameter `sourceImages`: A valid MPSImage object containing the source images.
434        ///
435        /// Parameter `destinationImages`: A valid MPSImage to be overwritten by result images.
436        /// destinationImages may not alias sourceImages, even at different
437        /// indices.
438        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:destinationImages:))]
439        #[unsafe(method_family = none)]
440        pub unsafe fn encodeBatchToCommandBuffer_sourceImages_destinationImages(
441            &self,
442            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
443            source_images: &MPSImageBatch,
444            destination_images: &MPSImageBatch,
445        );
446
447        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
448        /// Encode a MPSCNNKernel with a destination state into a command Buffer.
449        ///
450        /// This is typically used during training. The state is commonly a MPSNNGradientState.
451        /// Please see -resultStateForSourceImages:SourceStates:destinationImage and batch+temporary variants.
452        ///
453        /// Parameter `commandBuffer`: A valid MTLCommandBuffer to receive the encoded filter
454        ///
455        /// Parameter `sourceImages`: A valid MPSImage object containing the source images.
456        ///
457        /// Parameter `destinationStates`: A list of states to be overwritten by results
458        ///
459        /// Parameter `destinationImages`: A valid MPSImage to be overwritten by result images.
460        /// destinationImages may not alias sourceImages, even at different
461        /// indices.
462        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:destinationStates:destinationImages:))]
463        #[unsafe(method_family = none)]
464        pub unsafe fn encodeBatchToCommandBuffer_sourceImages_destinationStates_destinationImages(
465            &self,
466            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
467            source_images: &MPSImageBatch,
468            destination_states: Option<&MPSStateBatch>,
469            destination_images: &MPSImageBatch,
470        );
471
472        #[cfg(feature = "MPSImage")]
473        /// Encode a MPSCNNKernel into a command Buffer. Create a texture to hold the result and return it.
474        ///
475        /// In the first iteration on this method, encodeToCommandBuffer:sourceImage:destinationImage:
476        /// some work was left for the developer to do in the form of correctly setting the offset property
477        /// and sizing the result buffer. With the introduction of the padding policy (see padding property)
478        /// the filter can do this work itself. If you would like to have some input into what sort of MPSImage
479        /// (e.g. temporary vs. regular) or what size it is or where it is allocated, you may set the
480        /// destinationImageAllocator to allocate the image yourself.
481        ///
482        /// This method uses the MPSNNPadding padding property to figure out how to size
483        /// the result image and to set the offset property. See discussion in MPSNeuralNetworkTypes.h.
484        /// All images in a batch must have MPSImage.numberOfImages = 1.
485        ///
486        ///
487        /// Parameter `commandBuffer`: The command buffer
488        ///
489        /// Parameter `sourceImage`: A MPSImage to use as the source images for the filter.
490        ///
491        /// Returns: A MPSImage or MPSTemporaryImage allocated per the destinationImageAllocator containing the output of the graph.
492        /// The offset property will be adjusted to reflect the offset used during the encode.
493        /// The returned image will be automatically released when the command buffer completes. If you want to
494        /// keep it around for longer, retain the image. (ARC will do this for you if you use it later.)
495        #[unsafe(method(encodeToCommandBuffer:sourceImage:))]
496        #[unsafe(method_family = none)]
497        pub unsafe fn encodeToCommandBuffer_sourceImage(
498            &self,
499            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
500            source_image: &MPSImage,
501        ) -> Retained<MPSImage>;
502
503        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
504        /// Encode a MPSCNNKernel into a command Buffer. Create a texture and state to hold the results and return them.
505        ///
506        /// In the first iteration on this method, encodeToCommandBuffer:sourceImage:destinationState:destinationImage:
507        /// some work was left for the developer to do in the form of correctly setting the offset property
508        /// and sizing the result buffer. With the introduction of the padding policy (see padding property)
509        /// the filter can do this work itself. If you would like to have some input into what sort of MPSImage
510        /// (e.g. temporary vs. regular) or what size it is or where it is allocated, you may set the
511        /// destinationImageAllocator to allocate the image yourself.
512        ///
513        /// This method uses the MPSNNPadding padding property to figure out how to size
514        /// the result image and to set the offset property. See discussion in MPSNeuralNetworkTypes.h.
515        /// All images in a batch must have MPSImage.numberOfImages = 1.
516        ///
517        ///
518        /// Parameter `commandBuffer`: The command buffer
519        ///
520        /// Parameter `sourceImage`: A MPSImage to use as the source images for the filter.
521        ///
522        /// Parameter `outState`: A new state object is returned here.
523        ///
524        /// Returns: A MPSImage or MPSTemporaryImage allocated per the destinationImageAllocator containing the output of the graph.
525        /// The offset property will be adjusted to reflect the offset used during the encode.
526        /// The returned image will be automatically released when the command buffer completes. If you want to
527        /// keep it around for longer, retain the image. (ARC will do this for you if you use it later.)
528        #[unsafe(method(encodeToCommandBuffer:sourceImage:destinationState:destinationStateIsTemporary:))]
529        #[unsafe(method_family = none)]
530        pub unsafe fn encodeToCommandBuffer_sourceImage_destinationState_destinationStateIsTemporary(
531            &self,
532            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
533            source_image: &MPSImage,
534            out_state: &mut Option<Retained<MPSState>>,
535            is_temporary: bool,
536        ) -> Retained<MPSImage>;
537
538        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray"))]
539        /// Encode a MPSCNNKernel into a command Buffer. Create a texture to hold the result and return it.
540        ///
541        /// In the first iteration on this method, encodeToCommandBuffer:sourceImage:destinationImage:
542        /// some work was left for the developer to do in the form of correctly setting the offset property
543        /// and sizing the result buffer. With the introduction of the padding policy (see padding property)
544        /// the filter can do this work itself. If you would like to have some input into what sort of MPSImage
545        /// (e.g. temporary vs. regular) or what size it is or where it is allocated, you may set the
546        /// destinationImageAllocator to allocate the image yourself.
547        ///
548        /// This method uses the MPSNNPadding padding property to figure out how to size
549        /// the result image and to set the offset property. See discussion in MPSNeuralNetworkTypes.h.
550        /// All images in a batch must have MPSImage.numberOfImages = 1.
551        ///
552        ///
553        /// Parameter `commandBuffer`: The command buffer
554        ///
555        /// Parameter `sourceImages`: A MPSImages to use as the source images for the filter.
556        ///
557        /// Returns: An array of MPSImages or MPSTemporaryImages allocated per the destinationImageAllocator
558        /// containing the output of the graph. The offset property will be adjusted to reflect the
559        /// offset used during the encode. The returned images will be automatically released when
560        /// the command buffer completes. If you want to keep them around for longer, retain the images.
561        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:))]
562        #[unsafe(method_family = none)]
563        pub unsafe fn encodeBatchToCommandBuffer_sourceImages(
564            &self,
565            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
566            source_images: &MPSImageBatch,
567        ) -> Retained<MPSImageBatch>;
568
569        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
570        /// Encode a MPSCNNKernel into a command Buffer. Create a MPSImageBatch and MPSStateBatch to hold the results and return them.
571        ///
572        /// In the first iteration on this method, encodeToCommandBuffer:sourceImage:destinationImage:
573        /// some work was left for the developer to do in the form of correctly setting the offset property
574        /// and sizing the result buffer. With the introduction of the padding policy (see padding property)
575        /// the filter can do this work itself. If you would like to have some input into what sort of MPSImage
576        /// (e.g. temporary vs. regular) or what size it is or where it is allocated, you may set the
577        /// destinationImageAllocator to allocate the image yourself.
578        ///
579        /// This method uses the MPSNNPadding padding property to figure out how to size
580        /// the result image and to set the offset property. See discussion in MPSNeuralNetworkTypes.h.
581        /// All images in a batch must have MPSImage.numberOfImages = 1.
582        ///
583        /// Usage:
584        ///
585        /// ```text
586        ///                   MPSStateBatch * outStates = nil;    // autoreleased
587        ///                   MPSImageBatch * result = [k encodeBatchToCommandBuffer: cmdBuf
588        ///                                                             sourceImages: sourceImages
589        ///                                                        destinationStates: &outStates ];
590        /// ```
591        ///
592        ///
593        /// Parameter `commandBuffer`: The command buffer
594        ///
595        /// Parameter `sourceImages`: A MPSImages to use as the source images for the filter.
596        ///
597        /// Parameter `outStates`: A pointer to storage to hold a MPSStateBatch* where output states are returned
598        ///
599        /// Returns: An array of MPSImages or MPSTemporaryImages allocated per the destinationImageAllocator
600        /// containing the output of the graph. The offset property will be adjusted to reflect the
601        /// offset used during the encode. The returned images will be automatically released when
602        /// the command buffer completes. If you want to keep them around for longer, retain the images.
603        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:destinationStates:destinationStateIsTemporary:))]
604        #[unsafe(method_family = none)]
605        pub unsafe fn encodeBatchToCommandBuffer_sourceImages_destinationStates_destinationStateIsTemporary(
606            &self,
607            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
608            source_images: &MPSImageBatch,
609            out_states: &mut Option<Retained<MPSStateBatch>>,
610            is_temporary: bool,
611        ) -> Retained<MPSImageBatch>;
612
613        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
614        /// Allocate a MPSState (subclass) to hold the results from a -encodeBatchToCommandBuffer... operation
615        ///
616        /// A graph may need to allocate storage up front before executing.  This may be
617        /// necessary to avoid using too much memory and to manage large batches.  The function
618        /// should allocate any MPSState objects that will be produced by an -encode call
619        /// with the indicated sourceImages and sourceStates inputs. Though the states
620        /// can be further adjusted in the ensuing -encode call, the states should
621        /// be initialized with all important data and all MTLResource storage allocated.
622        /// The data stored in the MTLResource need not be initialized, unless the ensuing
623        /// -encode call expects it to be.
624        ///
625        /// The MTLDevice used by the result is derived from the source image.
626        /// The padding policy will be applied to the filter before this is called
627        /// to give it the chance to configure any properties like MPSCNNKernel.offset.
628        ///
629        /// CAUTION:
630        /// The kernel must have all properties set to values that will ultimately be
631        /// passed to the -encode call that writes to the state, before
632        /// -resultStateForSourceImages:sourceStates:destinationImage: is called or behavior is undefined.
633        /// Please note that -destinationImageDescriptorForSourceImages:sourceStates:
634        /// will alter some of these properties automatically based on the padding policy.
635        /// If you intend to call that to make the destination image, then you should
636        /// call that before -resultStateForSourceImages:sourceStates:destinationImage:. This will ensure the
637        /// properties used in the encode call and in the destination image creation
638        /// match those used to configure the state.
639        ///
640        /// The following order is recommended:
641        ///
642        /// // Configure MPSCNNKernel properties first
643        /// kernel.edgeMode = MPSImageEdgeModeZero;
644        /// kernel.destinationFeatureChannelOffset = 128; // concatenation without the copy
645        /// ...
646        ///
647        /// // ALERT: will change MPSCNNKernel properties
648        /// MPSImageDescriptor * d = [kernel destinationImageDescriptorForSourceImage: source
649        /// sourceStates: states];
650        /// MPSTemporaryImage * dest = [MPSTemporaryImage temporaryImageWithCommandBuffer: cmdBuf
651        /// imageDescriptor: d];
652        ///
653        /// // Now that all properties are configured properly, we can make the result state
654        /// // and call encode.
655        /// MPSState * __nullable destState = [kernel resultStateForSourceImage: source
656        /// sourceStates: states
657        /// destinationImage: dest];
658        ///
659        /// // This form of -encode will be declared by the MPSCNNKernel subclass
660        /// [kernel encodeToCommandBuffer: cmdBuf
661        /// sourceImage: source
662        /// destinationState: destState
663        /// destinationImage: dest ];
664        ///
665        /// Default: returns nil
666        ///
667        ///
668        /// Parameter `sourceImage`: The MPSImage consumed by the associated -encode call.
669        ///
670        /// Parameter `sourceStates`: The list of MPSStates consumed by the associated -encode call,
671        /// for a batch size of 1.
672        ///
673        /// Parameter `destinationImage`: The destination image for the encode call
674        ///
675        /// Returns: The list of states produced by the -encode call for batch size of 1.
676        /// When the batch size is not 1, this function will be called repeatedly unless
677        /// -isResultStateReusedAcrossBatch returns YES. If  -isResultStateReusedAcrossBatch
678        /// returns YES, then it will be called once per batch and the MPSStateBatch array will
679        /// contain MPSStateBatch.length references to the same object.
680        #[unsafe(method(resultStateForSourceImage:sourceStates:destinationImage:))]
681        #[unsafe(method_family = none)]
682        pub unsafe fn resultStateForSourceImage_sourceStates_destinationImage(
683            &self,
684            source_image: &MPSImage,
685            source_states: Option<&NSArray<MPSState>>,
686            destination_image: &MPSImage,
687        ) -> Option<Retained<MPSState>>;
688
689        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
690        #[unsafe(method(resultStateBatchForSourceImage:sourceStates:destinationImage:))]
691        #[unsafe(method_family = none)]
692        pub unsafe fn resultStateBatchForSourceImage_sourceStates_destinationImage(
693            &self,
694            source_image: &MPSImageBatch,
695            source_states: Option<&NSArray<MPSStateBatch>>,
696            destination_image: &MPSImageBatch,
697        ) -> Option<Retained<MPSStateBatch>>;
698
699        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
700        /// Allocate a temporary MPSState (subclass) to hold the results from a -encodeBatchToCommandBuffer... operation
701        ///
702        /// A graph may need to allocate storage up front before executing.  This may be
703        /// necessary to avoid using too much memory and to manage large batches.  The function
704        /// should allocate any MPSState objects that will be produced by an -encode call
705        /// with the indicated sourceImages and sourceStates inputs. Though the states
706        /// can be further adjusted in the ensuing -encode call, the states should
707        /// be initialized with all important data and all MTLResource storage allocated.
708        /// The data stored in the MTLResource need not be initialized, unless the ensuing
709        /// -encode call expects it to be.
710        ///
711        /// The MTLDevice used by the result is derived from the command buffer.
712        /// The padding policy will be applied to the filter before this is called
713        /// to give it the chance to configure any properties like MPSCNNKernel.offset.
714        ///
715        /// CAUTION:
716        /// The kernel must have all properties set to values that will ultimately be
717        /// passed to the -encode call that writes to the state, before
718        /// -resultStateForSourceImages:sourceStates:destinationImage: is called or behavior is undefined.
719        /// Please note that -destinationImageDescriptorForSourceImages:sourceStates:destinationImage:
720        /// will alter some of these properties automatically based on the padding policy.
721        /// If you intend to call that to make the destination image, then you should
722        /// call that before -resultStateForSourceImages:sourceStates:destinationImage:.  This will ensure the
723        /// properties used in the encode call and in the destination image creation
724        /// match those used to configure the state.
725        ///
726        /// The following order is recommended:
727        ///
728        /// // Configure MPSCNNKernel properties first
729        /// kernel.edgeMode = MPSImageEdgeModeZero;
730        /// kernel.destinationFeatureChannelOffset = 128; // concatenation without the copy
731        /// ...
732        ///
733        /// // ALERT: will change MPSCNNKernel properties
734        /// MPSImageDescriptor * d = [kernel destinationImageDescriptorForSourceImage: source
735        /// sourceStates: states];
736        /// MPSTemporaryImage * dest = [MPSTemporaryImage temporaryImageWithCommandBuffer: cmdBuf
737        /// imageDescriptor: d];
738        ///
739        /// // Now that all properties are configured properly, we can make the result state
740        /// // and call encode.
741        /// MPSState * __nullable destState = [kernel temporaryResultStateForCommandBuffer: cmdBuf
742        /// sourceImage: source
743        /// sourceStates: states];
744        ///
745        /// // This form of -encode will be declared by the MPSCNNKernel subclass
746        /// [kernel encodeToCommandBuffer: cmdBuf
747        /// sourceImage: source
748        /// destinationState: destState
749        /// destinationImage: dest ];
750        ///
751        /// Default: returns nil
752        ///
753        ///
754        /// Parameter `commandBuffer`: The command buffer to allocate the temporary storage against
755        /// The state will only be valid on this command buffer.
756        ///
757        /// Parameter `sourceImage`: The MPSImage consumed by the associated -encode call.
758        ///
759        /// Parameter `sourceStates`: The list of MPSStates consumed by the associated -encode call,
760        /// for a batch size of 1.
761        ///
762        /// Parameter `destinationImage`: The destination image for the encode call
763        ///
764        /// Returns: The list of states produced by the -encode call for batch size of 1.
765        /// When the batch size is not 1, this function will be called repeatedly unless
766        /// -isResultStateReusedAcrossBatch returns YES. If  -isResultStateReusedAcrossBatch
767        /// returns YES, then it will be called once per batch and the MPSStateBatch array will
768        /// contain MPSStateBatch.length references to the same object.
769        #[unsafe(method(temporaryResultStateForCommandBuffer:sourceImage:sourceStates:destinationImage:))]
770        #[unsafe(method_family = none)]
771        pub unsafe fn temporaryResultStateForCommandBuffer_sourceImage_sourceStates_destinationImage(
772            &self,
773            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
774            source_image: &MPSImage,
775            source_states: Option<&NSArray<MPSState>>,
776            destination_image: &MPSImage,
777        ) -> Option<Retained<MPSState>>;
778
779        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
780        #[unsafe(method(temporaryResultStateBatchForCommandBuffer:sourceImage:sourceStates:destinationImage:))]
781        #[unsafe(method_family = none)]
782        pub unsafe fn temporaryResultStateBatchForCommandBuffer_sourceImage_sourceStates_destinationImage(
783            &self,
784            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
785            source_image: &MPSImageBatch,
786            source_states: Option<&NSArray<MPSStateBatch>>,
787            destination_image: &MPSImageBatch,
788        ) -> Option<Retained<MPSStateBatch>>;
789
790        /// Returns YES if the same state is used for every operation in a batch
791        ///
792        /// If NO, then each image in a MPSImageBatch will need a corresponding
793        /// (and different) state to go with it. Set to YES to avoid allocating
794        /// redundant state in the case when the same state is used all the time.
795        /// Default: NO
796        #[unsafe(method(isResultStateReusedAcrossBatch))]
797        #[unsafe(method_family = none)]
798        pub unsafe fn isResultStateReusedAcrossBatch(&self) -> bool;
799
800        /// Returns YES if the filter must be run over the entire batch before its
801        /// results may be used
802        ///
803        /// Nearly all filters do not need to see the entire batch all at once and can
804        /// operate correctly with partial batches. This allows the graph to
805        /// strip-mine the problem, processing the graph top to bottom on a subset
806        /// of the batch at a time, dramatically reducing memory usage. As the full
807        /// nominal working set for a graph is often so large that it may not fit
808        /// in memory, sub-batching may be required forward progress.
809        ///
810        /// Batch normalization statistics on the other hand must complete the batch
811        /// before the statistics may be used to normalize the images in the batch
812        /// in the ensuing normalization filter. Consequently, batch normalization statistics
813        /// requests the graph insert a batch barrier following it by returning
814        /// YES from -appendBatchBarrier. This tells the graph to complete the batch
815        /// before any dependent filters can start. Note that the filter itself may
816        /// still be subject to sub-batching in its operation. All filters must be able to
817        /// function without seeing the entire batch in a single -encode call. Carry
818        /// over state that is accumulated across sub-batches is commonly carried in
819        /// a shared MPSState containing a MTLBuffer. See -isResultStateReusedAcrossBatch.
820        ///
821        /// Caution: on most supported devices, the working set may be so large
822        /// that the graph may be forced to throw away and recalculate most
823        /// intermediate images in cases where strip-mining can not occur because
824        /// -appendBatchBarrier returns YES. A single batch barrier can commonly
825        /// cause a memory size increase and/or performance reduction by many fold
826        /// over the entire graph.  Filters of this variety should be avoided.
827        ///
828        /// Default: NO
829        #[unsafe(method(appendBatchBarrier))]
830        #[unsafe(method_family = none)]
831        pub unsafe fn appendBatchBarrier(&self) -> bool;
832
833        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
834        /// Get a suggested destination image descriptor for a source image
835        ///
836        /// Your application is certainly free to pass in any destinationImage
837        /// it likes to encodeToCommandBuffer:sourceImage:destinationImage,
838        /// within reason. This is the basic design for iOS 10. This method
839        /// is therefore not required.
840        ///
841        /// However, calculating the MPSImage size and MPSCNNKernel properties
842        /// for each filter can be tedious and complicated work, so this method
843        /// is made available to automate the process. The application may
844        /// modify the properties of the descriptor before a MPSImage is made from
845        /// it, so long as the choice is sensible for the kernel in question.
846        /// Please see individual kernel descriptions for restrictions.
847        ///
848        /// The expected timeline for use is as follows:
849        ///
850        /// 1) This method is called:
851        /// a) The default MPS padding calculation is applied. It
852        /// uses the MPSNNPaddingMethod of the .padding property to
853        /// provide a consistent addressing scheme over the graph.
854        /// It creates the MPSImageDescriptor and adjusts the .offset
855        /// property of the MPSNNKernel. When using a MPSNNGraph, the
856        /// padding is set using the MPSNNFilterNode as a proxy.
857        ///
858        /// b) This method may be overridden by MPSCNNKernel subclass
859        /// to achieve any customization appropriate to the object type.
860        ///
861        /// c) Source states are then applied in order. These may modify the
862        /// descriptor and may update other object properties. See:
863        /// -destinationImageDescriptorForSourceImages:sourceStates:
864        /// forKernel:suggestedDescriptor:  This is the typical way
865        /// in which MPS may attempt to influence the operation of
866        /// its kernels.
867        ///
868        /// d) If the .padding property has a custom padding policy method
869        /// of the same name, it is called. Similarly, it may also adjust
870        /// the descriptor and any MPSCNNKernel properties. This is the
871        /// typical way in which your application may attempt to influence
872        /// the operation of the MPS kernels.
873        ///
874        /// 2) A result is returned from this method and the caller
875        /// may further adjust the descriptor and kernel properties
876        /// directly.
877        ///
878        /// 3) The caller uses the descriptor to make a new MPSImage to
879        /// use as the destination image for the -encode call in step 5.
880        ///
881        /// 4) The caller calls -resultStateForSourceImage:sourceStates:destinationImage:
882        /// to make any result states needed for the kernel. If there isn't
883        /// one, it will return nil. A variant is available to return a
884        /// temporary state instead.
885        ///
886        /// 5) a -encode method is called to encode the kernel.
887        ///
888        /// The entire process 1-5 is more simply achieved by just calling an -encode...
889        /// method that returns a MPSImage out the left hand sid of the method. Simpler
890        /// still, use the MPSNNGraph to coordinate the entire process from end to end.
891        /// Opportunities to influence the process are of course reduced, as (2) is no longer
892        /// possible with either method. Your application may opt to use the five step method
893        /// if it requires greater customization as described, or if it would like to estimate
894        /// storage in advance based on the sum of MPSImageDescriptors before processing
895        /// a graph. Storage estimation is done by using the MPSImageDescriptor to create
896        /// a MPSImage (without passing it a texture), and then call -resourceSize. As long
897        /// as the MPSImage is not used in an encode call and the .texture property is not
898        /// invoked, the underlying MTLTexture is not created.
899        ///
900        /// No destination state or destination image is provided as an argument to this
901        /// function because it is expected they will be made / configured after this
902        /// is called. This method is expected to auto-configure important object properties
903        /// that may be needed in the ensuing destination image and state creation steps.
904        ///
905        ///
906        /// Parameter `sourceImages`: A array of source images that will be passed into the -encode call
907        /// Since MPSCNNKernel is a unary kernel, it is an array of length 1.
908        ///
909        /// Parameter `sourceStates`: An optional array of source states that will be passed into the -encode call
910        ///
911        /// Returns: an image descriptor allocated on the autorelease pool
912        #[unsafe(method(destinationImageDescriptorForSourceImages:sourceStates:))]
913        #[unsafe(method_family = none)]
914        pub unsafe fn destinationImageDescriptorForSourceImages_sourceStates(
915            &self,
916            source_images: &NSArray<MPSImage>,
917            source_states: Option<&NSArray<MPSState>>,
918        ) -> Retained<MPSImageDescriptor>;
919
920        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
921        /// The size of extra MPS heap storage allocated while the kernel is encoding
922        ///
923        /// This is best effort and just describes things that are likely to end up on the MPS heap. It does not
924        /// describe all allocation done by the -encode call.  It is intended for use with high water calculations
925        /// for MTLHeap sizing. Allocations are typically for temporary storage needed for multipass algorithms.
926        /// This interface should not be used to detect multipass algorithms.
927        #[unsafe(method(encodingStorageSizeForSourceImage:sourceStates:destinationImage:))]
928        #[unsafe(method_family = none)]
929        pub unsafe fn encodingStorageSizeForSourceImage_sourceStates_destinationImage(
930            &self,
931            source_image: &MPSImage,
932            source_states: Option<&NSArray<MPSState>>,
933            destination_image: Option<&MPSImage>,
934        ) -> NSUInteger;
935
936        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
937        /// The size of extra MPS heap storage allocated while the kernel is encoding a batch
938        ///
939        /// This is best effort and just describes things that are likely to end up on the MPS heap. It does not
940        /// describe all allocation done by the -encode call.  It is intended for use with high water calculations
941        /// for MTLHeap sizing. Allocations are typically for temporary storage needed for multipass algorithms.
942        /// This interface should not be used to detect multipass algorithms.
943        #[unsafe(method(batchEncodingStorageSizeForSourceImage:sourceStates:destinationImage:))]
944        #[unsafe(method_family = none)]
945        pub unsafe fn batchEncodingStorageSizeForSourceImage_sourceStates_destinationImage(
946            &self,
947            source_image: &MPSImageBatch,
948            source_states: Option<&NSArray<MPSStateBatch>>,
949            destination_image: Option<&MPSImageBatch>,
950        ) -> NSUInteger;
951    );
952}
953
954/// Methods declared on superclass `MPSKernel`.
955#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
956impl MPSCNNKernel {
957    extern_methods!(
958        /// Called by NSCoder to decode MPSKernels
959        ///
960        /// This isn't the right interface to decode a MPSKernel, but
961        /// it is the one that NSCoder uses. To enable your NSCoder
962        /// (e.g. NSKeyedUnarchiver) to set which device to use
963        /// extend the object to adopt the MPSDeviceProvider
964        /// protocol. Otherwise, the Metal system default device
965        /// will be used.
966        ///
967        /// # Safety
968        ///
969        /// `a_decoder` possibly has further requirements.
970        #[unsafe(method(initWithCoder:))]
971        #[unsafe(method_family = init)]
972        pub unsafe fn initWithCoder(
973            this: Allocated<Self>,
974            a_decoder: &NSCoder,
975        ) -> Option<Retained<Self>>;
976    );
977}
978
979/// Methods declared on superclass `NSObject`.
980#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
981impl MPSCNNKernel {
982    extern_methods!(
983        #[unsafe(method(init))]
984        #[unsafe(method_family = init)]
985        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
986
987        #[unsafe(method(new))]
988        #[unsafe(method_family = new)]
989        pub unsafe fn new() -> Retained<Self>;
990    );
991}
992
993extern_class!(
994    /// Dependencies: This depends on Metal.framework
995    ///
996    /// Describes a convolution neural network kernel.
997    ///
998    /// A MPSCNNKernel consumes two MPSImages, primary and secondary, and produces one MPSImage.
999    ///
1000    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnbinarykernel?language=objc)
1001    #[unsafe(super(MPSKernel, NSObject))]
1002    #[derive(Debug, PartialEq, Eq, Hash)]
1003    #[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
1004    pub struct MPSCNNBinaryKernel;
1005);
1006
1007#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
1008extern_conformance!(
1009    unsafe impl NSCoding for MPSCNNBinaryKernel {}
1010);
1011
1012#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
1013extern_conformance!(
1014    unsafe impl NSCopying for MPSCNNBinaryKernel {}
1015);
1016
1017#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
1018unsafe impl CopyingHelper for MPSCNNBinaryKernel {
1019    type Result = Self;
1020}
1021
1022#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
1023extern_conformance!(
1024    unsafe impl NSObjectProtocol for MPSCNNBinaryKernel {}
1025);
1026
1027#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
1028extern_conformance!(
1029    unsafe impl NSSecureCoding for MPSCNNBinaryKernel {}
1030);
1031
1032#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
1033impl MPSCNNBinaryKernel {
1034    extern_methods!(
1035        /// Standard init with default properties per filter type
1036        ///
1037        /// Parameter `device`: The device that the filter will be used on. May not be NULL.
1038        ///
1039        /// Returns: A pointer to the newly initialized object. This will fail, returning
1040        /// nil if the device is not supported. Devices must be
1041        /// MTLFeatureSet_iOS_GPUFamily2_v1 or later.
1042        #[unsafe(method(initWithDevice:))]
1043        #[unsafe(method_family = init)]
1044        pub unsafe fn initWithDevice(
1045            this: Allocated<Self>,
1046            device: &ProtocolObject<dyn MTLDevice>,
1047        ) -> Retained<Self>;
1048
1049        #[cfg(feature = "MPSCoreTypes")]
1050        /// The position of the destination clip rectangle origin relative to the primary source buffer.
1051        ///
1052        /// The offset is defined to be the position of clipRect.origin in source coordinates.
1053        /// Default: {0,0,0}, indicating that the top left corners of the clipRect and primary source image align.
1054        /// offset.z is the index of starting source image in batch processing mode.
1055        ///
1056        /// See Also:
1057        /// subsubsection_mpsoffset
1058        #[unsafe(method(primaryOffset))]
1059        #[unsafe(method_family = none)]
1060        pub unsafe fn primaryOffset(&self) -> MPSOffset;
1061
1062        #[cfg(feature = "MPSCoreTypes")]
1063        /// Setter for [`primaryOffset`][Self::primaryOffset].
1064        #[unsafe(method(setPrimaryOffset:))]
1065        #[unsafe(method_family = none)]
1066        pub unsafe fn setPrimaryOffset(&self, primary_offset: MPSOffset);
1067
1068        #[cfg(feature = "MPSCoreTypes")]
1069        /// The position of the destination clip rectangle origin relative to the secondary source buffer.
1070        ///
1071        /// The offset is defined to be the position of clipRect.origin in source coordinates.
1072        /// Default: {0,0,0}, indicating that the top left corners of the clipRect and secondary source image align.
1073        /// offset.z is the index of starting source image in batch processing mode.
1074        ///
1075        /// See Also:
1076        /// subsubsection_mpsoffset
1077        #[unsafe(method(secondaryOffset))]
1078        #[unsafe(method_family = none)]
1079        pub unsafe fn secondaryOffset(&self) -> MPSOffset;
1080
1081        #[cfg(feature = "MPSCoreTypes")]
1082        /// Setter for [`secondaryOffset`][Self::secondaryOffset].
1083        #[unsafe(method(setSecondaryOffset:))]
1084        #[unsafe(method_family = none)]
1085        pub unsafe fn setSecondaryOffset(&self, secondary_offset: MPSOffset);
1086
1087        /// An optional clip rectangle to use when writing data. Only the pixels in the rectangle will be overwritten.
1088        ///
1089        /// A MTLRegion that indicates which part of the destination to overwrite. If the clipRect does not lie
1090        /// completely within the destination image, the intersection between clip rectangle and destination bounds is
1091        /// used.   Default: MPSRectNoClip (MPSKernel::MPSRectNoClip) indicating the entire image.
1092        /// clipRect.origin.z is the index of starting destination image in batch processing mode. clipRect.size.depth
1093        /// is the number of images to process in batch processing mode.
1094        ///
1095        /// See Also:
1096        /// subsubsection_clipRect
1097        #[unsafe(method(clipRect))]
1098        #[unsafe(method_family = none)]
1099        pub unsafe fn clipRect(&self) -> MTLRegion;
1100
1101        /// Setter for [`clipRect`][Self::clipRect].
1102        #[unsafe(method(setClipRect:))]
1103        #[unsafe(method_family = none)]
1104        pub unsafe fn setClipRect(&self, clip_rect: MTLRegion);
1105
1106        /// The number of channels in the destination MPSImage to skip before writing output.
1107        ///
1108        /// This is the starting offset into the destination image in the feature channel dimension
1109        /// at which destination data is written.
1110        /// This allows an application to pass a subset of all the channels in MPSImage as output of MPSKernel.
1111        /// E.g. Suppose MPSImage has 24 channels and a MPSKernel outputs 8 channels. If
1112        /// we want channels 8 to 15 of this MPSImage to be used as output, we can set destinationFeatureChannelOffset = 8.
1113        /// Note that this offset applies independently to each image when the MPSImage
1114        /// is a container for multiple images and the MPSCNNKernel is processing multiple images (clipRect.size.depth > 1).
1115        /// The default value is 0 and any value specifed shall be a multiple of 4. If MPSKernel outputs N channels,
1116        /// destination image MUST have at least destinationFeatureChannelOffset + N channels. Using a destination
1117        /// image with insufficient number of feature channels result in an error.
1118        /// E.g. if the MPSCNNConvolution outputs 32 channels, and destination has 64 channels, then it is an error to set
1119        /// destinationFeatureChannelOffset > 32.
1120        #[unsafe(method(destinationFeatureChannelOffset))]
1121        #[unsafe(method_family = none)]
1122        pub unsafe fn destinationFeatureChannelOffset(&self) -> NSUInteger;
1123
1124        /// Setter for [`destinationFeatureChannelOffset`][Self::destinationFeatureChannelOffset].
1125        #[unsafe(method(setDestinationFeatureChannelOffset:))]
1126        #[unsafe(method_family = none)]
1127        pub unsafe fn setDestinationFeatureChannelOffset(
1128            &self,
1129            destination_feature_channel_offset: NSUInteger,
1130        );
1131
1132        /// The number of channels in the primary source MPSImage to skip before reading the input.
1133        ///
1134        /// This is the starting offset into the primary source image in the feature channel dimension
1135        /// at which source data is read. Unit: feature channels
1136        /// This allows an application to read a subset of all the channels in MPSImage as input of MPSKernel.
1137        /// E.g. Suppose MPSImage has 24 channels and a MPSKernel needs to read 8 channels. If
1138        /// we want channels 8 to 15 of this MPSImage to be used as input, we can set primarySourceFeatureChannelOffset = 8.
1139        /// Note that this offset applies independently to each image when the MPSImage
1140        /// is a container for multiple images and the MPSCNNKernel is processing multiple images (clipRect.size.depth > 1).
1141        /// The default value is 0 and any value specifed shall be a multiple of 4. If MPSKernel inputs N channels,
1142        /// the source image MUST have at least primarySourceFeatureChannelOffset + N channels. Using a source
1143        /// image with insufficient number of feature channels will result in an error.
1144        /// E.g. if the MPSCNNConvolution inputs 32 channels, and the source has 64 channels, then it is an error to set
1145        /// primarySourceFeatureChannelOffset > 32.
1146        #[unsafe(method(primarySourceFeatureChannelOffset))]
1147        #[unsafe(method_family = none)]
1148        pub unsafe fn primarySourceFeatureChannelOffset(&self) -> NSUInteger;
1149
1150        /// Setter for [`primarySourceFeatureChannelOffset`][Self::primarySourceFeatureChannelOffset].
1151        #[unsafe(method(setPrimarySourceFeatureChannelOffset:))]
1152        #[unsafe(method_family = none)]
1153        pub unsafe fn setPrimarySourceFeatureChannelOffset(
1154            &self,
1155            primary_source_feature_channel_offset: NSUInteger,
1156        );
1157
1158        /// The number of channels in the secondary source MPSImage to skip before reading the input.
1159        ///
1160        /// This is the starting offset into the secondary source image in the feature channel dimension
1161        /// at which source data is read. Unit: feature channels
1162        /// This allows an application to read a subset of all the channels in MPSImage as input of MPSKernel.
1163        /// E.g. Suppose MPSImage has 24 channels and a MPSKernel needs to read 8 channels. If
1164        /// we want channels 8 to 15 of this MPSImage to be used as input, we can set secondarySourceFeatureChannelOffset = 8.
1165        /// Note that this offset applies independently to each image when the MPSImage
1166        /// is a container for multiple images and the MPSCNNKernel is processing multiple images (clipRect.size.depth > 1).
1167        /// The default value is 0 and any value specifed shall be a multiple of 4. If MPSKernel inputs N channels,
1168        /// the source image MUST have at least primarySourceFeatureChannelOffset + N channels. Using a source
1169        /// image with insufficient number of feature channels will result in an error.
1170        /// E.g. if the MPSCNNConvolution inputs 32 channels, and the source has 64 channels, then it is an error to set
1171        /// primarySourceFeatureChannelOffset > 32.
1172        #[unsafe(method(secondarySourceFeatureChannelOffset))]
1173        #[unsafe(method_family = none)]
1174        pub unsafe fn secondarySourceFeatureChannelOffset(&self) -> NSUInteger;
1175
1176        /// Setter for [`secondarySourceFeatureChannelOffset`][Self::secondarySourceFeatureChannelOffset].
1177        #[unsafe(method(setSecondarySourceFeatureChannelOffset:))]
1178        #[unsafe(method_family = none)]
1179        pub unsafe fn setSecondarySourceFeatureChannelOffset(
1180            &self,
1181            secondary_source_feature_channel_offset: NSUInteger,
1182        );
1183
1184        /// The maximum number of channels in the primary source MPSImage to use
1185        ///
1186        /// Most filters can insert a slice operation into the filter for free.
1187        /// Use this to limit the size of the feature channel slice taken from
1188        /// the input image. If the value is too large, it is truncated to be
1189        /// the remaining size in the image after the sourceFeatureChannelOffset
1190        /// is taken into account.  Default: ULONG_MAX
1191        #[unsafe(method(primarySourceFeatureChannelMaxCount))]
1192        #[unsafe(method_family = none)]
1193        pub unsafe fn primarySourceFeatureChannelMaxCount(&self) -> NSUInteger;
1194
1195        /// Setter for [`primarySourceFeatureChannelMaxCount`][Self::primarySourceFeatureChannelMaxCount].
1196        #[unsafe(method(setPrimarySourceFeatureChannelMaxCount:))]
1197        #[unsafe(method_family = none)]
1198        pub unsafe fn setPrimarySourceFeatureChannelMaxCount(
1199            &self,
1200            primary_source_feature_channel_max_count: NSUInteger,
1201        );
1202
1203        /// The maximum number of channels in the secondary source MPSImage to use
1204        ///
1205        /// Most filters can insert a slice operation into the filter for free.
1206        /// Use this to limit the size of the feature channel slice taken from
1207        /// the input image. If the value is too large, it is truncated to be
1208        /// the remaining size in the image after the sourceFeatureChannelOffset
1209        /// is taken into account.  Default: ULONG_MAX
1210        #[unsafe(method(secondarySourceFeatureChannelMaxCount))]
1211        #[unsafe(method_family = none)]
1212        pub unsafe fn secondarySourceFeatureChannelMaxCount(&self) -> NSUInteger;
1213
1214        /// Setter for [`secondarySourceFeatureChannelMaxCount`][Self::secondarySourceFeatureChannelMaxCount].
1215        #[unsafe(method(setSecondarySourceFeatureChannelMaxCount:))]
1216        #[unsafe(method_family = none)]
1217        pub unsafe fn setSecondarySourceFeatureChannelMaxCount(
1218            &self,
1219            secondary_source_feature_channel_max_count: NSUInteger,
1220        );
1221
1222        #[cfg(feature = "MPSCoreTypes")]
1223        /// The MPSImageEdgeMode to use when texture reads stray off the edge of the primary source image
1224        ///
1225        /// Most MPSKernel objects can read off the edge of the source image. This can happen
1226        /// because of a negative offset property, because the offset + clipRect.size is larger
1227        /// than the source image or because the filter looks at neighboring pixels, such as a
1228        /// Convolution filter.   Default:  MPSImageEdgeModeZero.
1229        ///
1230        /// See Also:
1231        /// subsubsection_edgemode
1232        #[unsafe(method(primaryEdgeMode))]
1233        #[unsafe(method_family = none)]
1234        pub unsafe fn primaryEdgeMode(&self) -> MPSImageEdgeMode;
1235
1236        #[cfg(feature = "MPSCoreTypes")]
1237        /// Setter for [`primaryEdgeMode`][Self::primaryEdgeMode].
1238        #[unsafe(method(setPrimaryEdgeMode:))]
1239        #[unsafe(method_family = none)]
1240        pub unsafe fn setPrimaryEdgeMode(&self, primary_edge_mode: MPSImageEdgeMode);
1241
1242        #[cfg(feature = "MPSCoreTypes")]
1243        /// The MPSImageEdgeMode to use when texture reads stray off the edge of the primary source image
1244        ///
1245        /// Most MPSKernel objects can read off the edge of the source image. This can happen
1246        /// because of a negative offset property, because the offset + clipRect.size is larger
1247        /// than the source image or because the filter looks at neighboring pixels, such as a
1248        /// Convolution filter.   Default:  MPSImageEdgeModeZero.
1249        ///
1250        /// See Also:
1251        /// subsubsection_edgemode
1252        #[unsafe(method(secondaryEdgeMode))]
1253        #[unsafe(method_family = none)]
1254        pub unsafe fn secondaryEdgeMode(&self) -> MPSImageEdgeMode;
1255
1256        #[cfg(feature = "MPSCoreTypes")]
1257        /// Setter for [`secondaryEdgeMode`][Self::secondaryEdgeMode].
1258        #[unsafe(method(setSecondaryEdgeMode:))]
1259        #[unsafe(method_family = none)]
1260        pub unsafe fn setSecondaryEdgeMode(&self, secondary_edge_mode: MPSImageEdgeMode);
1261
1262        /// The width of the MPSCNNBinaryKernel filter window
1263        ///
1264        /// This is the horizontal diameter of the region read by the filter for each
1265        /// result pixel. If the MPSCNNKernel does not have a filter window, then
1266        /// 1 will be returned.
1267        #[unsafe(method(primaryKernelWidth))]
1268        #[unsafe(method_family = none)]
1269        pub unsafe fn primaryKernelWidth(&self) -> NSUInteger;
1270
1271        /// The height of the MPSCNNBinaryKernel filter window
1272        ///
1273        /// This is the vertical diameter of the region read by the filter for each
1274        /// result pixel. If the MPSCNNKernel does not have a filter window, then
1275        /// 1 will be returned.
1276        #[unsafe(method(primaryKernelHeight))]
1277        #[unsafe(method_family = none)]
1278        pub unsafe fn primaryKernelHeight(&self) -> NSUInteger;
1279
1280        /// The width of the MPSCNNBinaryKernel filter window for the second image source
1281        ///
1282        /// This is the horizontal diameter of the region read by the filter for each
1283        /// result pixel. If the MPSCNNBinaryKernel does not have a filter window, then
1284        /// 1 will be returned.
1285        #[unsafe(method(secondaryKernelWidth))]
1286        #[unsafe(method_family = none)]
1287        pub unsafe fn secondaryKernelWidth(&self) -> NSUInteger;
1288
1289        /// The height of the MPSCNNBinaryKernel filter window for the second image source
1290        ///
1291        /// This is the vertical diameter of the region read by the filter for each
1292        /// result pixel. If the MPSCNNBinaryKernel does not have a filter window, then
1293        /// 1 will be returned.
1294        #[unsafe(method(secondaryKernelHeight))]
1295        #[unsafe(method_family = none)]
1296        pub unsafe fn secondaryKernelHeight(&self) -> NSUInteger;
1297
1298        /// The downsampling (or upsampling if a backwards filter) factor in the horizontal dimension
1299        /// for the primary source image
1300        ///
1301        /// If the filter does not do up or downsampling, 1 is returned.
1302        #[unsafe(method(primaryStrideInPixelsX))]
1303        #[unsafe(method_family = none)]
1304        pub unsafe fn primaryStrideInPixelsX(&self) -> NSUInteger;
1305
1306        /// Setter for [`primaryStrideInPixelsX`][Self::primaryStrideInPixelsX].
1307        #[unsafe(method(setPrimaryStrideInPixelsX:))]
1308        #[unsafe(method_family = none)]
1309        pub unsafe fn setPrimaryStrideInPixelsX(&self, primary_stride_in_pixels_x: NSUInteger);
1310
1311        /// The downsampling (or upsampling if a backwards filter) factor in the vertical dimension
1312        /// for the primary source image
1313        ///
1314        /// If the filter does not do up or downsampling, 1 is returned.
1315        #[unsafe(method(primaryStrideInPixelsY))]
1316        #[unsafe(method_family = none)]
1317        pub unsafe fn primaryStrideInPixelsY(&self) -> NSUInteger;
1318
1319        /// Setter for [`primaryStrideInPixelsY`][Self::primaryStrideInPixelsY].
1320        #[unsafe(method(setPrimaryStrideInPixelsY:))]
1321        #[unsafe(method_family = none)]
1322        pub unsafe fn setPrimaryStrideInPixelsY(&self, primary_stride_in_pixels_y: NSUInteger);
1323
1324        /// The downsampling (or upsampling if a backwards filter) factor in the horizontal dimension
1325        /// for the secondary source image
1326        ///
1327        /// If the filter does not do up or downsampling, 1 is returned.
1328        #[unsafe(method(secondaryStrideInPixelsX))]
1329        #[unsafe(method_family = none)]
1330        pub unsafe fn secondaryStrideInPixelsX(&self) -> NSUInteger;
1331
1332        /// Setter for [`secondaryStrideInPixelsX`][Self::secondaryStrideInPixelsX].
1333        #[unsafe(method(setSecondaryStrideInPixelsX:))]
1334        #[unsafe(method_family = none)]
1335        pub unsafe fn setSecondaryStrideInPixelsX(&self, secondary_stride_in_pixels_x: NSUInteger);
1336
1337        /// The downsampling (or upsampling if a backwards filter) factor in the vertical dimension
1338        /// for the secondary source image
1339        ///
1340        /// If the filter does not do up or downsampling, 1 is returned.
1341        #[unsafe(method(secondaryStrideInPixelsY))]
1342        #[unsafe(method_family = none)]
1343        pub unsafe fn secondaryStrideInPixelsY(&self) -> NSUInteger;
1344
1345        /// Setter for [`secondaryStrideInPixelsY`][Self::secondaryStrideInPixelsY].
1346        #[unsafe(method(setSecondaryStrideInPixelsY:))]
1347        #[unsafe(method_family = none)]
1348        pub unsafe fn setSecondaryStrideInPixelsY(&self, secondary_stride_in_pixels_y: NSUInteger);
1349
1350        /// Stride in source coordinates from one kernel tap to the next in the X dimension.
1351        #[unsafe(method(primaryDilationRateX))]
1352        #[unsafe(method_family = none)]
1353        pub unsafe fn primaryDilationRateX(&self) -> NSUInteger;
1354
1355        /// Stride in source coordinates from one kernel tap to the next in the Y dimension.
1356        #[unsafe(method(primaryDilationRateY))]
1357        #[unsafe(method_family = none)]
1358        pub unsafe fn primaryDilationRateY(&self) -> NSUInteger;
1359
1360        /// Stride in source coordinates from one kernel tap to the next in the X dimension.
1361        ///
1362        /// As applied to the secondary source image.
1363        #[unsafe(method(secondaryDilationRateX))]
1364        #[unsafe(method_family = none)]
1365        pub unsafe fn secondaryDilationRateX(&self) -> NSUInteger;
1366
1367        /// Stride in source coordinates from one kernel tap to the next in the Y dimension.
1368        ///
1369        /// As applied to the secondary source image.
1370        #[unsafe(method(secondaryDilationRateY))]
1371        #[unsafe(method_family = none)]
1372        pub unsafe fn secondaryDilationRateY(&self) -> NSUInteger;
1373
1374        /// YES if the filter operates backwards.
1375        ///
1376        /// This influences how strideInPixelsX/Y should be interpreted.
1377        #[unsafe(method(isBackwards))]
1378        #[unsafe(method_family = none)]
1379        pub unsafe fn isBackwards(&self) -> bool;
1380
1381        /// Returns true if the -encode call modifies the state object it accepts.
1382        #[unsafe(method(isStateModified))]
1383        #[unsafe(method_family = none)]
1384        pub unsafe fn isStateModified(&self) -> bool;
1385
1386        #[cfg(feature = "MPSNeuralNetworkTypes")]
1387        /// The padding method used by the filter
1388        ///
1389        /// This influences how strideInPixelsX/Y should be interpreted.
1390        /// Default:  MPSNNPaddingMethodAlignCentered | MPSNNPaddingMethodAddRemainderToTopLeft | MPSNNPaddingMethodSizeSame
1391        /// Some object types (e.g. MPSCNNFullyConnected) may override this default with something appropriate to its operation.
1392        #[unsafe(method(padding))]
1393        #[unsafe(method_family = none)]
1394        pub unsafe fn padding(&self) -> Retained<ProtocolObject<dyn MPSNNPadding>>;
1395
1396        #[cfg(feature = "MPSNeuralNetworkTypes")]
1397        /// Setter for [`padding`][Self::padding].
1398        #[unsafe(method(setPadding:))]
1399        #[unsafe(method_family = none)]
1400        pub unsafe fn setPadding(&self, padding: &ProtocolObject<dyn MPSNNPadding>);
1401
1402        #[cfg(feature = "MPSImage")]
1403        /// Method to allocate the result image for -encodeToCommandBuffer:sourceImage:
1404        ///
1405        /// Default: MPSTemporaryImage.defaultAllocator
1406        #[unsafe(method(destinationImageAllocator))]
1407        #[unsafe(method_family = none)]
1408        pub unsafe fn destinationImageAllocator(
1409            &self,
1410        ) -> Retained<ProtocolObject<dyn MPSImageAllocator>>;
1411
1412        #[cfg(feature = "MPSImage")]
1413        /// Setter for [`destinationImageAllocator`][Self::destinationImageAllocator].
1414        #[unsafe(method(setDestinationImageAllocator:))]
1415        #[unsafe(method_family = none)]
1416        pub unsafe fn setDestinationImageAllocator(
1417            &self,
1418            destination_image_allocator: &ProtocolObject<dyn MPSImageAllocator>,
1419        );
1420
1421        /// NSSecureCoding compatability
1422        ///
1423        /// While the standard NSSecureCoding/NSCoding method
1424        /// -initWithCoder: should work, since the file can't
1425        /// know which device your data is allocated on, we
1426        /// have to guess and may guess incorrectly.  To avoid
1427        /// that problem, use initWithCoder:device instead.
1428        ///
1429        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
1430        ///
1431        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
1432        ///
1433        /// Returns: A new MPSKernel object, or nil if failure.
1434        ///
1435        /// # Safety
1436        ///
1437        /// `a_decoder` possibly has further requirements.
1438        #[unsafe(method(initWithCoder:device:))]
1439        #[unsafe(method_family = init)]
1440        pub unsafe fn initWithCoder_device(
1441            this: Allocated<Self>,
1442            a_decoder: &NSCoder,
1443            device: &ProtocolObject<dyn MTLDevice>,
1444        ) -> Option<Retained<Self>>;
1445
1446        #[cfg(feature = "MPSImage")]
1447        /// Encode a MPSCNNKernel into a command Buffer.  The operation shall proceed out-of-place.
1448        ///
1449        /// This is the older style of encode which reads the offset, doesn't change it,
1450        /// and ignores the padding method.
1451        ///
1452        /// Parameter `commandBuffer`: A valid MTLCommandBuffer to receive the encoded filter
1453        ///
1454        /// Parameter `primaryImage`: A valid MPSImage object containing the primary source image.
1455        ///
1456        /// Parameter `secondaryImage`: A valid MPSImage object containing the secondary source image.
1457        ///
1458        /// Parameter `destinationImage`: A valid MPSImage to be overwritten by result image. destinationImage may not alias primarySourceImage or secondarySourceImage.
1459        #[unsafe(method(encodeToCommandBuffer:primaryImage:secondaryImage:destinationImage:))]
1460        #[unsafe(method_family = none)]
1461        pub unsafe fn encodeToCommandBuffer_primaryImage_secondaryImage_destinationImage(
1462            &self,
1463            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1464            primary_image: &MPSImage,
1465            secondary_image: &MPSImage,
1466            destination_image: &MPSImage,
1467        );
1468
1469        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray"))]
1470        /// Encode a MPSCNNKernel into a command Buffer.  The operation shall proceed out-of-place.
1471        ///
1472        /// This is the older style of encode which reads the offset, doesn't change it,
1473        /// and ignores the padding method. Multiple images are processed concurrently.
1474        /// All images must have MPSImage.numberOfImages = 1.
1475        ///
1476        /// Parameter `commandBuffer`: A valid MTLCommandBuffer to receive the encoded filter
1477        ///
1478        /// Parameter `primaryImages`: An array of MPSImage objects containing the primary source images.
1479        ///
1480        /// Parameter `secondaryImages`: An array MPSImage objects containing the secondary source images.
1481        ///
1482        /// Parameter `destinationImages`: An array of MPSImage objects to contain the result images.
1483        /// destinationImages may not alias primarySourceImages or secondarySourceImages
1484        /// in any manner.
1485        #[unsafe(method(encodeBatchToCommandBuffer:primaryImages:secondaryImages:destinationImages:))]
1486        #[unsafe(method_family = none)]
1487        pub unsafe fn encodeBatchToCommandBuffer_primaryImages_secondaryImages_destinationImages(
1488            &self,
1489            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1490            primary_images: &MPSImageBatch,
1491            secondary_images: &MPSImageBatch,
1492            destination_images: &MPSImageBatch,
1493        );
1494
1495        #[cfg(feature = "MPSImage")]
1496        /// Encode a MPSCNNKernel into a command Buffer. Create a texture to hold the result and return it.
1497        ///
1498        /// In the first iteration on this method, encodeToCommandBuffer:sourceImage:destinationImage:
1499        /// some work was left for the developer to do in the form of correctly setting the offset property
1500        /// and sizing the result buffer. With the introduction of the padding policy (see padding property)
1501        /// the filter can do this work itself. If you would like to have some input into what sort of MPSImage
1502        /// (e.g. temporary vs. regular) or what size it is or where it is allocated, you may set the
1503        /// destinationImageAllocator to allocate the image yourself.
1504        ///
1505        /// This method uses the MPSNNPadding padding property to figure out how to size
1506        /// the result image and to set the offset property.  See discussion in MPSNeuralNetworkTypes.h.
1507        ///
1508        ///
1509        /// Parameter `commandBuffer`: The command buffer
1510        ///
1511        /// Parameter `primaryImage`: A MPSImages to use as the primary source images for the filter.
1512        ///
1513        /// Parameter `secondaryImage`: A MPSImages to use as the secondary source images for the filter.
1514        ///
1515        /// Returns: A MPSImage or MPSTemporaryImage allocated per the destinationImageAllocator containing the output of the graph.
1516        /// The returned image will be automatically released when the command buffer completes. If you want to
1517        /// keep it around for longer, retain the image. (ARC will do this for you if you use it later.)
1518        #[unsafe(method(encodeToCommandBuffer:primaryImage:secondaryImage:))]
1519        #[unsafe(method_family = none)]
1520        pub unsafe fn encodeToCommandBuffer_primaryImage_secondaryImage(
1521            &self,
1522            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1523            primary_image: &MPSImage,
1524            secondary_image: &MPSImage,
1525        ) -> Retained<MPSImage>;
1526
1527        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray"))]
1528        /// Encode a MPSCNNKernel into a command Buffer. Create textures to hold the results and return them.
1529        ///
1530        /// In the first iteration on this method, encodeBatchToCommandBuffer:sourceImage:destinationImage:
1531        /// some work was left for the developer to do in the form of correctly setting the offset property
1532        /// and sizing the result buffer. With the introduction of the padding policy (see padding property)
1533        /// the filter can do this work itself. If you would like to have some input into what sort of MPSImage
1534        /// (e.g. temporary vs. regular) or what size it is or where it is allocated, you may set the
1535        /// destinationImageAllocator to allocate the image yourself.
1536        ///
1537        /// This method uses the MPSNNPadding padding property to figure out how to size
1538        /// the result image and to set the offset property.  See discussion in MPSNeuralNetworkTypes.h.
1539        /// All images in a batch must have MPSImage.numberOfImages = 1.
1540        ///
1541        ///
1542        /// Parameter `commandBuffer`: The command buffer
1543        ///
1544        /// Parameter `primaryImage`: A MPSImages to use as the primary source images for the filter.
1545        ///
1546        /// Parameter `secondaryImage`: A MPSImages to use as the secondary source images for the filter.
1547        ///
1548        /// Returns: A MPSImage or MPSTemporaryImage allocated per the destinationImageAllocator containing the output of the graph.
1549        /// The returned image will be automatically released when the command buffer completes. If you want to
1550        /// keep it around for longer, retain the image. (ARC will do this for you if you use it later.)
1551        #[unsafe(method(encodeBatchToCommandBuffer:primaryImages:secondaryImages:))]
1552        #[unsafe(method_family = none)]
1553        pub unsafe fn encodeBatchToCommandBuffer_primaryImages_secondaryImages(
1554            &self,
1555            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1556            primary_image: &MPSImageBatch,
1557            secondary_image: &MPSImageBatch,
1558        ) -> Retained<MPSImageBatch>;
1559
1560        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
1561        /// Encode a MPSCNNKernel into a command Buffer. Create a texture and state to hold the results and return them.
1562        ///
1563        /// In the first iteration on this method, encodeToCommandBuffer:sourceImage:destinationState:destinationImage:
1564        /// some work was left for the developer to do in the form of correctly setting the offset property
1565        /// and sizing the result buffer. With the introduction of the padding policy (see padding property)
1566        /// the filter can do this work itself. If you would like to have some input into what sort of MPSImage
1567        /// (e.g. temporary vs. regular) or what size it is or where it is allocated, you may set the
1568        /// destinationImageAllocator to allocate the image yourself.
1569        ///
1570        /// This method uses the MPSNNPadding padding property to figure out how to size
1571        /// the result image and to set the offset property. See discussion in MPSNeuralNetworkTypes.h.
1572        /// All images in a batch must have MPSImage.numberOfImages = 1.
1573        ///
1574        ///
1575        /// Parameter `commandBuffer`: The command buffer
1576        ///
1577        /// Parameter `primaryImage`: A MPSImage to use as the source images for the filter.
1578        ///
1579        /// Parameter `secondaryImage`: A MPSImage to use as the source images for the filter.
1580        ///
1581        /// Parameter `outState`: The address of location to write the pointer to the result state of the operation
1582        ///
1583        /// Parameter `isTemporary`: YES if the outState should be a temporary object
1584        ///
1585        /// Returns: A MPSImage or MPSTemporaryImage allocated per the destinationImageAllocator containing the output of the graph.
1586        /// The offset property will be adjusted to reflect the offset used during the encode.
1587        /// The returned image will be automatically released when the command buffer completes. If you want to
1588        /// keep it around for longer, retain the image. (ARC will do this for you if you use it later.)
1589        #[unsafe(method(encodeToCommandBuffer:primaryImage:secondaryImage:destinationState:destinationStateIsTemporary:))]
1590        #[unsafe(method_family = none)]
1591        pub unsafe fn encodeToCommandBuffer_primaryImage_secondaryImage_destinationState_destinationStateIsTemporary(
1592            &self,
1593            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1594            primary_image: &MPSImage,
1595            secondary_image: &MPSImage,
1596            out_state: &mut Option<Retained<MPSState>>,
1597            is_temporary: bool,
1598        ) -> Retained<MPSImage>;
1599
1600        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
1601        /// Encode a MPSCNNKernel into a command Buffer. Create a texture and state to hold the results and return them.
1602        ///
1603        /// In the first iteration on this method, encodeToCommandBuffer:sourceImage:destinationState:destinationImage:
1604        /// some work was left for the developer to do in the form of correctly setting the offset property
1605        /// and sizing the result buffer. With the introduction of the padding policy (see padding property)
1606        /// the filter can do this work itself. If you would like to have some input into what sort of MPSImage
1607        /// (e.g. temporary vs. regular) or what size it is or where it is allocated, you may set the
1608        /// destinationImageAllocator to allocate the image yourself.
1609        ///
1610        /// This method uses the MPSNNPadding padding property to figure out how to size
1611        /// the result image and to set the offset property. See discussion in MPSNeuralNetworkTypes.h.
1612        /// All images in a batch must have MPSImage.numberOfImages = 1.
1613        ///
1614        ///
1615        /// Parameter `commandBuffer`: The command buffer
1616        ///
1617        /// Parameter `primaryImages`: A MPSImage to use as the source images for the filter.
1618        ///
1619        /// Parameter `secondaryImages`: A MPSImage to use as the source images for the filter.
1620        ///
1621        /// Parameter `outState`: A new state object is returned here.
1622        ///
1623        /// Parameter `isTemporary`: YES if the outState should be a temporary object
1624        ///
1625        /// Returns: A MPSImage or MPSTemporaryImage allocated per the destinationImageAllocator containing the output of the graph.
1626        /// The offset property will be adjusted to reflect the offset used during the encode.
1627        /// The returned image will be automatically released when the command buffer completes. If you want to
1628        /// keep it around for longer, retain the image. (ARC will do this for you if you use it later.)
1629        #[unsafe(method(encodeBatchToCommandBuffer:primaryImages:secondaryImages:destinationStates:destinationStateIsTemporary:))]
1630        #[unsafe(method_family = none)]
1631        pub unsafe fn encodeBatchToCommandBuffer_primaryImages_secondaryImages_destinationStates_destinationStateIsTemporary(
1632            &self,
1633            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1634            primary_images: &MPSImageBatch,
1635            secondary_images: &MPSImageBatch,
1636            out_state: &mut Option<Retained<MPSStateBatch>>,
1637            is_temporary: bool,
1638        ) -> Retained<MPSImageBatch>;
1639
1640        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
1641        /// Allocate a MPSState (subclass) to hold the results from a -encodeBatchToCommandBuffer... operation
1642        ///
1643        /// A graph may need to allocate storage up front before executing.  This may be
1644        /// necessary to avoid using too much memory and to manage large batches.  The function
1645        /// should allocate a MPSState object (if any) that will be produced by an -encode call
1646        /// with the indicated sourceImages and sourceStates inputs. Though the states
1647        /// can be further adjusted in the ensuing -encode call, the states should
1648        /// be initialized with all important data and all MTLResource storage allocated.
1649        /// The data stored in the MTLResource need not be initialized, unless the ensuing
1650        /// -encode call expects it to be.
1651        ///
1652        /// The MTLDevice used by the result is derived from the source image.
1653        /// The padding policy will be applied to the filter before this is called
1654        /// to give it the chance to configure any properties like MPSCNNKernel.offset.
1655        ///
1656        /// CAUTION: the result state should be made after the kernel properties are
1657        /// configured for the -encode call that will write to the state, and
1658        /// after -destinationImageDescriptorForSourceImages:sourceStates:
1659        /// is called (if it is called). Otherwise, behavior is undefined.
1660        /// Please see the description of
1661        /// -[MPSCNNKernel resultStateForSourceImage:sourceStates:destinationImage:] for more.
1662        ///
1663        /// Default: returns nil
1664        ///
1665        ///
1666        /// Parameter `primaryImage`: The MPSImage consumed by the associated -encode call.
1667        ///
1668        /// Parameter `secondaryImage`: The MPSImage consumed by the associated -encode call.
1669        ///
1670        /// Parameter `sourceStates`: The list of MPSStates consumed by the associated -encode call,
1671        /// for a batch size of 1.
1672        ///
1673        /// Returns: The list of states produced by the -encode call for batch size of 1.
1674        /// When the batch size is not 1, this function will be called repeatedly unless
1675        /// -isResultStateReusedAcrossBatch returns YES. If  -isResultStateReusedAcrossBatch
1676        /// returns YES, then it will be called once per batch and the MPSStateBatch array will
1677        /// contain MPSStateBatch.length references to the same object.
1678        #[unsafe(method(resultStateForPrimaryImage:secondaryImage:sourceStates:destinationImage:))]
1679        #[unsafe(method_family = none)]
1680        pub unsafe fn resultStateForPrimaryImage_secondaryImage_sourceStates_destinationImage(
1681            &self,
1682            primary_image: &MPSImage,
1683            secondary_image: &MPSImage,
1684            source_states: Option<&NSArray<MPSState>>,
1685            destination_image: &MPSImage,
1686        ) -> Option<Retained<MPSState>>;
1687
1688        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
1689        #[unsafe(method(resultStateBatchForPrimaryImage:secondaryImage:sourceStates:destinationImage:))]
1690        #[unsafe(method_family = none)]
1691        pub unsafe fn resultStateBatchForPrimaryImage_secondaryImage_sourceStates_destinationImage(
1692            &self,
1693            primary_image: &MPSImageBatch,
1694            secondary_image: &MPSImageBatch,
1695            source_states: Option<&NSArray<MPSStateBatch>>,
1696            destination_image: &MPSImageBatch,
1697        ) -> Option<Retained<MPSStateBatch>>;
1698
1699        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
1700        /// Allocate a temporary MPSState (subclass) to hold the results from a -encodeBatchToCommandBuffer... operation
1701        ///
1702        /// A graph may need to allocate storage up front before executing.  This may be
1703        /// necessary to avoid using too much memory and to manage large batches.  The function
1704        /// should allocate any MPSState objects that will be produced by an -encode call
1705        /// with the indicated sourceImages and sourceStates inputs. Though the states
1706        /// can be further adjusted in the ensuing -encode call, the states should
1707        /// be initialized with all important data and all MTLResource storage allocated.
1708        /// The data stored in the MTLResource need not be initialized, unless the ensuing
1709        /// -encode call expects it to be.
1710        ///
1711        /// The MTLDevice used by the result is derived from the command buffer.
1712        /// The padding policy will be applied to the filter before this is called
1713        /// to give it the chance to configure any properties like MPSCNNKernel.offset.
1714        ///
1715        /// CAUTION: the result state should be made after the kernel properties are
1716        /// configured for the -encode call that will write to the state, and
1717        /// after -destinationImageDescriptorForSourceImages:sourceStates:
1718        /// is called (if it is called). Otherwise, behavior is undefined.
1719        /// Please see the description of
1720        /// -[MPSCNNKernel resultStateForSourceImage:sourceStates:destinationImage] for more.
1721        ///
1722        /// Default: returns nil
1723        ///
1724        ///
1725        /// Parameter `commandBuffer`: The command buffer to allocate the temporary storage against
1726        /// The state will only be valid on this command buffer.
1727        ///
1728        /// Parameter `primaryImage`: The MPSImage consumed by the associated -encode call.
1729        ///
1730        /// Parameter `secondaryImage`: The MPSImage consumed by the associated -encode call.
1731        ///
1732        /// Parameter `sourceStates`: The list of MPSStates consumed by the associated -encode call,
1733        /// for a batch size of 1.
1734        ///
1735        /// Returns: The list of states produced by the -encode call for batch size of 1.
1736        /// When the batch size is not 1, this function will be called repeatedly unless
1737        /// -isResultStateReusedAcrossBatch returns YES. If  -isResultStateReusedAcrossBatch
1738        /// returns YES, then it will be called once per batch and the MPSStateBatch array will
1739        /// contain MPSStateBatch.length references to the same object.
1740        #[unsafe(method(temporaryResultStateForCommandBuffer:primaryImage:secondaryImage:sourceStates:destinationImage:))]
1741        #[unsafe(method_family = none)]
1742        pub unsafe fn temporaryResultStateForCommandBuffer_primaryImage_secondaryImage_sourceStates_destinationImage(
1743            &self,
1744            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1745            primary_image: &MPSImage,
1746            secondary_image: &MPSImage,
1747            source_states: Option<&NSArray<MPSState>>,
1748            destination_image: &MPSImage,
1749        ) -> Option<Retained<MPSState>>;
1750
1751        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
1752        #[unsafe(method(temporaryResultStateBatchForCommandBuffer:primaryImage:secondaryImage:sourceStates:destinationImage:))]
1753        #[unsafe(method_family = none)]
1754        pub unsafe fn temporaryResultStateBatchForCommandBuffer_primaryImage_secondaryImage_sourceStates_destinationImage(
1755            &self,
1756            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
1757            primary_image: &MPSImageBatch,
1758            secondary_image: &MPSImageBatch,
1759            source_states: Option<&NSArray<MPSStateBatch>>,
1760            destination_image: &MPSImageBatch,
1761        ) -> Option<Retained<MPSStateBatch>>;
1762
1763        /// Returns YES if the same state is used for every operation in a batch
1764        ///
1765        /// If NO, then each image in a MPSImageBatch will need a corresponding
1766        /// (and different) state to go with it. Set to YES to avoid allocating
1767        /// redundant state in the case when the same state is used all the time.
1768        /// Default: NO
1769        #[unsafe(method(isResultStateReusedAcrossBatch))]
1770        #[unsafe(method_family = none)]
1771        pub unsafe fn isResultStateReusedAcrossBatch(&self) -> bool;
1772
1773        /// Returns YES if the filter must be run over the entire batch before its
1774        /// results may be considered complete
1775        ///
1776        /// The MPSNNGraph may split batches into sub-batches to save memory. However,
1777        /// some filters, like batch statistics calculations, need to operate over
1778        /// the entire batch to calculate a valid result, in this case, the mean and
1779        /// variance per channel over the set of images.
1780        ///
1781        /// In such cases, the accumulated result is commonly stored in a MPSState
1782        /// containing a MTLBuffer. (MTLTextures may not be able to be read from
1783        /// and written to in the same filter on some devices.) -isResultStateReusedAcrossBatch
1784        /// is set to YES, so that the state is allocated once and passed in for each
1785        /// sub-batch and the filter accumulates its results into it, one sub-batch
1786        /// at a time. Note that sub-batches may frequently be as small as 1.
1787        ///
1788        /// Default: NO
1789        #[unsafe(method(appendBatchBarrier))]
1790        #[unsafe(method_family = none)]
1791        pub unsafe fn appendBatchBarrier(&self) -> bool;
1792
1793        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
1794        /// Get a suggested destination image descriptor for a source image
1795        ///
1796        /// Your application is certainly free to pass in any destinationImage
1797        /// it likes to encodeToCommandBuffer:sourceImage:destinationImage,
1798        /// within reason. This is the basic design for iOS 10. This method
1799        /// is therefore not required.
1800        ///
1801        /// However, calculating the MPSImage size and MPSCNNBinaryKernel properties
1802        /// for each filter can be tedious and complicated work, so this method
1803        /// is made available to automate the process. The application may
1804        /// modify the properties of the descriptor before a MPSImage is made from
1805        /// it, so long as the choice is sensible for the kernel in question.
1806        /// Please see individual kernel descriptions for restrictions.
1807        ///
1808        /// The expected timeline for use is as follows:
1809        ///
1810        /// 1) This method is called:
1811        /// a) The default MPS padding calculation is applied. It
1812        /// uses the MPSNNPaddingMethod of the .padding property to
1813        /// provide a consistent addressing scheme over the graph.
1814        /// It creates the MPSImageDescriptor and adjusts the .offset
1815        /// property of the MPSNNKernel. When using a MPSNNGraph, the
1816        /// padding is set using the MPSNNFilterNode as a proxy.
1817        ///
1818        /// b) This method may be overridden by MPSCNNBinaryKernel subclass
1819        /// to achieve any customization appropriate to the object type.
1820        ///
1821        /// c) Source states are then applied in order. These may modify the
1822        /// descriptor and may update other object properties. See:
1823        /// -destinationImageDescriptorForSourceImages:sourceStates:
1824        /// forKernel:suggestedDescriptor:  This is the typical way
1825        /// in which MPS may attempt to influence the operation of
1826        /// its kernels.
1827        ///
1828        /// d) If the .padding property has a custom padding policy method
1829        /// of the same name, it is called. Similarly, it may also adjust
1830        /// the descriptor and any MPSCNNBinaryKernel properties. This is the
1831        /// typical way in which your application may attempt to influence
1832        /// the operation of the MPS kernels.
1833        ///
1834        /// 2) A result is returned from this method and the caller
1835        /// may further adjust the descriptor and kernel properties
1836        /// directly.
1837        ///
1838        /// 3) The caller uses the descriptor to make a new MPSImage to
1839        /// use as the destination image for the -encode call in step 5.
1840        ///
1841        /// 4) The caller calls -resultStateForSourceImage:sourceStates:destinationImage:
1842        /// to make any result states needed for the kernel. If there isn't
1843        /// one, it will return nil. A variant is available to return a
1844        /// temporary state instead.
1845        ///
1846        /// 5) a -encode method is called to encode the kernel.
1847        ///
1848        /// The entire process 1-5 is more simply achieved by just calling an -encode...
1849        /// method that returns a MPSImage out the left hand sid of the method. Simpler
1850        /// still, use the MPSNNGraph to coordinate the entire process from end to end.
1851        /// Opportunities to influence the process are of course reduced, as (2) is no longer
1852        /// possible with either method. Your application may opt to use the five step method
1853        /// if it requires greater customization as described, or if it would like to estimate
1854        /// storage in advance based on the sum of MPSImageDescriptors before processing
1855        /// a graph. Storage estimation is done by using the MPSImageDescriptor to create
1856        /// a MPSImage (without passing it a texture), and then call -resourceSize. As long
1857        /// as the MPSImage is not used in an encode call and the .texture property is not
1858        /// invoked, the underlying MTLTexture is not created.
1859        ///
1860        /// No destination state or destination image is provided as an argument to this
1861        /// function because it is expected they will be made / configured after this
1862        /// is called. This method is expected to auto-configure important object properties
1863        /// that may be needed in the ensuing destination image and state creation steps.
1864        ///
1865        ///
1866        /// Parameter `sourceImages`: A array of source images that will be passed into the -encode call
1867        /// Since MPSCNNBinaryKernel is a binary kernel, it is an array of length 2.
1868        ///
1869        /// Parameter `sourceStates`: An optional array of source states that will be passed into the -encode call
1870        ///
1871        /// Returns: an image descriptor allocated on the autorelease pool
1872        #[unsafe(method(destinationImageDescriptorForSourceImages:sourceStates:))]
1873        #[unsafe(method_family = none)]
1874        pub unsafe fn destinationImageDescriptorForSourceImages_sourceStates(
1875            &self,
1876            source_images: &NSArray<MPSImage>,
1877            source_states: Option<&NSArray<MPSState>>,
1878        ) -> Retained<MPSImageDescriptor>;
1879
1880        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
1881        /// The size of extra MPS heap storage allocated while the kernel is encoding
1882        ///
1883        /// This is best effort and just describes things that are likely to end up on the MPS heap. It does not
1884        /// describe all allocation done by the -encode call.  It is intended for use with high water calculations
1885        /// for MTLHeap sizing. Allocations are typically for temporary storage needed for multipass algorithms.
1886        /// This interface should not be used to detect multipass algorithms.
1887        #[unsafe(method(encodingStorageSizeForPrimaryImage:secondaryImage:sourceStates:destinationImage:))]
1888        #[unsafe(method_family = none)]
1889        pub unsafe fn encodingStorageSizeForPrimaryImage_secondaryImage_sourceStates_destinationImage(
1890            &self,
1891            primary_image: &MPSImage,
1892            secondary_image: &MPSImage,
1893            source_states: Option<&NSArray<MPSState>>,
1894            destination_image: Option<&MPSImage>,
1895        ) -> NSUInteger;
1896
1897        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
1898        /// The size of extra MPS heap storage allocated while the kernel is encoding a batch
1899        ///
1900        /// This is best effort and just describes things that are likely to end up on the MPS heap. It does not
1901        /// describe all allocation done by the -encode call.  It is intended for use with high water calculations
1902        /// for MTLHeap sizing. Allocations are typically for temporary storage needed for multipass algorithms.
1903        /// This interface should not be used to detect multipass algorithms.
1904        #[unsafe(method(batchEncodingStorageSizeForPrimaryImage:secondaryImage:sourceStates:destinationImage:))]
1905        #[unsafe(method_family = none)]
1906        pub unsafe fn batchEncodingStorageSizeForPrimaryImage_secondaryImage_sourceStates_destinationImage(
1907            &self,
1908            primary_image: &MPSImageBatch,
1909            secondary_image: &MPSImageBatch,
1910            source_states: Option<&NSArray<MPSStateBatch>>,
1911            destination_image: Option<&MPSImageBatch>,
1912        ) -> NSUInteger;
1913    );
1914}
1915
1916/// Methods declared on superclass `MPSKernel`.
1917#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
1918impl MPSCNNBinaryKernel {
1919    extern_methods!(
1920        /// Called by NSCoder to decode MPSKernels
1921        ///
1922        /// This isn't the right interface to decode a MPSKernel, but
1923        /// it is the one that NSCoder uses. To enable your NSCoder
1924        /// (e.g. NSKeyedUnarchiver) to set which device to use
1925        /// extend the object to adopt the MPSDeviceProvider
1926        /// protocol. Otherwise, the Metal system default device
1927        /// will be used.
1928        ///
1929        /// # Safety
1930        ///
1931        /// `a_decoder` possibly has further requirements.
1932        #[unsafe(method(initWithCoder:))]
1933        #[unsafe(method_family = init)]
1934        pub unsafe fn initWithCoder(
1935            this: Allocated<Self>,
1936            a_decoder: &NSCoder,
1937        ) -> Option<Retained<Self>>;
1938    );
1939}
1940
1941/// Methods declared on superclass `NSObject`.
1942#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
1943impl MPSCNNBinaryKernel {
1944    extern_methods!(
1945        #[unsafe(method(init))]
1946        #[unsafe(method_family = init)]
1947        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
1948
1949        #[unsafe(method(new))]
1950        #[unsafe(method_family = new)]
1951        pub unsafe fn new() -> Retained<Self>;
1952    );
1953}
1954
1955extern_class!(
1956    /// Gradient kernels are the backwards pass of a MPSCNNKernel
1957    /// used during training to calculate gradient back propagation.
1958    /// These take as arguments the gradient result from the next filter
1959    /// and the source image for the forward version of the filter.
1960    /// There is also a MPSNNGradientState passed from MPSCNNKernel
1961    /// to MPSCNNGradientKernel that contains information about the
1962    /// MPSCNNKernel parameters at the time it encoded and possibly
1963    /// also additional MTLResources to enable it to do its job.
1964    ///
1965    /// ```text
1966    ///           Training graph (partial):
1967    ///
1968    ///               ---> input image ---------> MPSCNNKernel ------>  resultImage ------>-->-->-->.
1969    ///                              \                  |                                           |
1970    ///                               '------.    MPSNNGradientState                         loss estimation
1971    ///                                       \         |                                           |
1972    ///                                        V        V                                           V
1973    ///               <--- result gradient <- MPSCNNGradientKernel <---  input gradient <--<--<--<---'
1974    ///
1975    ///               In general operation, starting with the input image, the sequence of events is:
1976    ///               1a)  Invoke padding policy to find result size for MPSCNNKernel.  This
1977    ///                    also configures some MPSCNNKernel parameters such as offset.
1978    ///               1b)  Use the MPSImageDescriptor from 1a to make resultImage.
1979    ///               1c)  Call MPSCNNKernel -encode...
1980    ///               2) stages 1a-c are repeated for other forward passes in the inference portion of the graph
1981    ///               3) We estimate the loss resulting from the whole inference computation so far (see MPSCNNLoss.h>
1982    ///               4) stages 5a-c are repeated for corresponding backward gradient passes in the graph
1983    ///               5a) Invoke padding policy on the MPSCNNGradientKernel shown above. This sets the
1984    ///                   MPSCNNGradientKernel parameters to correspond with those in the forward pass
1985    ///               5b) The result gradient for the MPSCNNGradientKernel is created from the MPSImageDescriptor from 5a
1986    ///               5c) Call MPSCNNGradientKernel -encode with the input image, input gradient, result gradient and MPSNNGradientState
1987    ///               6) pass the result gradient on to leftward gradient passes.
1988    /// ```
1989    ///
1990    /// For MPSCNNKernels that are trained, there may be other accompanying training kernels that
1991    /// need to be called in addition to the gradient kernel to update convolution weights or batch
1992    /// normalization parameters, for example. Steps 1a-c and 5a-c can be combined in a single -encode
1993    /// call. These return the result image or gradient out the left hand side.
1994    ///
1995    /// For purposes of inheritance the gradient image is the MPSCNNBinaryKernel primary image
1996    /// and the source image is the MPSCNNBinaryKernel secondary image. Various secondary properties
1997    /// such as kernel size are copies of the forward inference pass parameters of similar name
1998    /// are set automatically when -[MPSCNNGradientKernel destinationImageDescriptorForSourceImages:sourceStates:]
1999    /// is called.
2000    ///
2001    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnngradientkernel?language=objc)
2002    #[unsafe(super(MPSCNNBinaryKernel, MPSKernel, NSObject))]
2003    #[derive(Debug, PartialEq, Eq, Hash)]
2004    #[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2005    pub struct MPSCNNGradientKernel;
2006);
2007
2008#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2009extern_conformance!(
2010    unsafe impl NSCoding for MPSCNNGradientKernel {}
2011);
2012
2013#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2014extern_conformance!(
2015    unsafe impl NSCopying for MPSCNNGradientKernel {}
2016);
2017
2018#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2019unsafe impl CopyingHelper for MPSCNNGradientKernel {
2020    type Result = Self;
2021}
2022
2023#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2024extern_conformance!(
2025    unsafe impl NSObjectProtocol for MPSCNNGradientKernel {}
2026);
2027
2028#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2029extern_conformance!(
2030    unsafe impl NSSecureCoding for MPSCNNGradientKernel {}
2031);
2032
2033#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2034impl MPSCNNGradientKernel {
2035    extern_methods!(
2036        /// Standard init with default properties per filter type
2037        ///
2038        /// Parameter `device`: The device that the filter will be used on. May not be NULL.
2039        ///
2040        /// Returns: A pointer to the newly initialized object. This will fail, returning
2041        /// nil if the device is not supported. Devices must be
2042        /// MTLFeatureSet_iOS_GPUFamily2_v1 or later.
2043        #[unsafe(method(initWithDevice:))]
2044        #[unsafe(method_family = init)]
2045        pub unsafe fn initWithDevice(
2046            this: Allocated<Self>,
2047            device: &ProtocolObject<dyn MTLDevice>,
2048        ) -> Retained<Self>;
2049
2050        /// NSSecureCoding compatability
2051        ///
2052        /// While the standard NSSecureCoding/NSCoding method
2053        /// -initWithCoder: should work, since the file can't
2054        /// know which device your data is allocated on, we
2055        /// have to guess and may guess incorrectly.  To avoid
2056        /// that problem, use initWithCoder:device instead.
2057        ///
2058        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
2059        ///
2060        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
2061        ///
2062        /// Returns: A new MPSKernel object, or nil if failure.
2063        ///
2064        /// # Safety
2065        ///
2066        /// `a_decoder` possibly has further requirements.
2067        #[unsafe(method(initWithCoder:device:))]
2068        #[unsafe(method_family = init)]
2069        pub unsafe fn initWithCoder_device(
2070            this: Allocated<Self>,
2071            a_decoder: &NSCoder,
2072            device: &ProtocolObject<dyn MTLDevice>,
2073        ) -> Option<Retained<Self>>;
2074
2075        /// Offset in the kernel reference frame to position the kernel in the X dimension
2076        ///
2077        /// In some cases, the input gradient must be upsampled with zero insertion
2078        /// to account for things like strides in the forward MPSCNNKernel pass.
2079        /// As such, the offset, which describes a X,Y offset in the source coordinate
2080        /// space is insufficient to fully describe the offset applied to a kernel.
2081        /// The kernel offset is the offset after upsampling. Both the source offset
2082        /// and kernel offset are additive:  effective offset = source offset * stride + kernel offset.
2083        /// The offset is applied to the (upsampled) source gradient
2084        #[unsafe(method(kernelOffsetX))]
2085        #[unsafe(method_family = none)]
2086        pub unsafe fn kernelOffsetX(&self) -> NSInteger;
2087
2088        /// Setter for [`kernelOffsetX`][Self::kernelOffsetX].
2089        #[unsafe(method(setKernelOffsetX:))]
2090        #[unsafe(method_family = none)]
2091        pub unsafe fn setKernelOffsetX(&self, kernel_offset_x: NSInteger);
2092
2093        /// Offset in the kernel reference frame to position the kernel in the Y dimension
2094        ///
2095        /// In some cases, the input gradient must be upsampled with zero insertion
2096        /// to account for things like strides in the forward MPSCNNKernel pass.
2097        /// As such, the offset, which describes a X,Y offset in the source coordinate
2098        /// space is insufficient to fully describe the offset applied to a kernel.
2099        /// The kernel offset is the offset after upsampling. Both the source offset
2100        /// and kernel offset are additive:  effective offset = source offset * stride + kernel offset.
2101        /// The offset is applied to the (upsampled) source gradient
2102        #[unsafe(method(kernelOffsetY))]
2103        #[unsafe(method_family = none)]
2104        pub unsafe fn kernelOffsetY(&self) -> NSInteger;
2105
2106        /// Setter for [`kernelOffsetY`][Self::kernelOffsetY].
2107        #[unsafe(method(setKernelOffsetY:))]
2108        #[unsafe(method_family = none)]
2109        pub unsafe fn setKernelOffsetY(&self, kernel_offset_y: NSInteger);
2110
2111        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
2112        /// Encode a gradient filter and return a gradient
2113        ///
2114        /// During training, gradient filters are used to calculate the gradient
2115        /// associated with the loss for each feature channel in the forward pass
2116        /// source image. For those nodes that are trainable, these are then used
2117        /// to refine the value used in the trainable parameter. They consume
2118        /// a source gradient image which contains the gradients corresponding
2119        /// with the forward pass destination image, and calculate the gradients
2120        /// corresponding to the forward pass source image.
2121        ///
2122        /// A gradient filter consumes a MPSNNGradientState object which captured
2123        /// various forward pass properties such as offset and edgeMode at the time
2124        /// the forward pass was encoded. These are transferred to the MPSCNNBinaryKernel
2125        /// secondary image properties automatically when this method creates its
2126        /// destination image.
2127        ///
2128        ///
2129        /// Parameter `commandBuffer`: The MTLCommandBuffer on which to encode
2130        ///
2131        /// Parameter `sourceGradient`: The gradient image from the "next" filter in the graph (in the inference direction)
2132        ///
2133        /// Parameter `sourceImage`: The image used as source image by the forward inference pass
2134        ///
2135        /// Parameter `gradientState`: The MPSNNGradientState or MPSNNBinaryGradientState subclass produced by the forward
2136        /// inference pass
2137        ///
2138        /// Returns: The result gradient from the gradient filter
2139        #[unsafe(method(encodeToCommandBuffer:sourceGradient:sourceImage:gradientState:))]
2140        #[unsafe(method_family = none)]
2141        pub unsafe fn encodeToCommandBuffer_sourceGradient_sourceImage_gradientState(
2142            &self,
2143            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2144            source_gradient: &MPSImage,
2145            source_image: &MPSImage,
2146            gradient_state: &MPSState,
2147        ) -> Retained<MPSImage>;
2148
2149        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
2150        /// Encode a gradient filter and return a gradient
2151        ///
2152        /// During training, gradient filters are used to calculate the gradient
2153        /// associated with the loss for each feature channel in the forward pass
2154        /// source image. For those nodes that are trainable, these are then used
2155        /// to refine the value used in the trainable parameter. They consume
2156        /// a source gradient image which contains the gradients corresponding
2157        /// with the forward pass destination image, and calculate the gradients
2158        /// corresponding to the forward pass source image.
2159        ///
2160        /// A gradient filter consumes a MPSNNGradientState object which captured
2161        /// various forward pass properties such as offset and edgeMode at the time
2162        /// the forward pass was encoded. These are transferred to the MPSCNNBinaryKernel
2163        /// secondary image properties automatically when you use -[MPSCNNGradientKernel
2164        /// destinationImageDescriptorForSourceImages:sourceStates:]. If you do not call
2165        /// this method, then you are responsible for configuring all of the primary and
2166        /// secondary image properties in MPSCNNBinaryKernel. Please see class description
2167        /// for expected ordering of operations.
2168        ///
2169        ///
2170        /// Parameter `commandBuffer`: The MTLCommandBuffer on which to encode
2171        ///
2172        /// Parameter `sourceGradient`: The gradient image from the "next" filter in the graph
2173        ///
2174        /// Parameter `sourceImage`: The image used as source image from the forward pass
2175        ///
2176        /// Parameter `gradientState`: The MPSNNGradientState and MPSNNBinaryGradientState subclass produced by the
2177        /// forward pass
2178        ///
2179        /// Parameter `destinationGradient`: The MPSImage into which to write the filter result
2180        #[unsafe(method(encodeToCommandBuffer:sourceGradient:sourceImage:gradientState:destinationGradient:))]
2181        #[unsafe(method_family = none)]
2182        pub unsafe fn encodeToCommandBuffer_sourceGradient_sourceImage_gradientState_destinationGradient(
2183            &self,
2184            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2185            source_gradient: &MPSImage,
2186            source_image: &MPSImage,
2187            gradient_state: &MPSState,
2188            destination_gradient: &MPSImage,
2189        );
2190
2191        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
2192        /// Encode a gradient filter and return a gradient
2193        ///
2194        /// During training, gradient filters are used to calculate the gradient
2195        /// associated with the loss for each feature channel in the forward pass
2196        /// source image. For those nodes that are trainable, these are then used
2197        /// to refine the value used in the trainable parameter. They consume
2198        /// a source gradient image which contains the gradients corresponding
2199        /// with the forward pass destination image, and calculate the gradients
2200        /// corresponding to the forward pass source image.
2201        ///
2202        /// A gradient filter consumes a MPSNNGradientState object which captured
2203        /// various forward pass properties such as offset and edgeMode at the time
2204        /// the forward pass was encoded. These are transferred to the MPSCNNBinaryKernel
2205        /// secondary image properties automatically when this method creates its
2206        /// destination image.
2207        ///
2208        /// Parameter `commandBuffer`: The MTLCommandBuffer on which to encode
2209        ///
2210        /// Parameter `sourceGradients`: The gradient images from the "next" filter in the graph
2211        ///
2212        /// Parameter `sourceImages`: The images used as source image from the forward pass
2213        ///
2214        /// Parameter `gradientStates`: The MPSNNGradientState or MPSNNBinaryGradientState subclass produced by the
2215        /// forward pass
2216        #[unsafe(method(encodeBatchToCommandBuffer:sourceGradients:sourceImages:gradientStates:))]
2217        #[unsafe(method_family = none)]
2218        pub unsafe fn encodeBatchToCommandBuffer_sourceGradients_sourceImages_gradientStates(
2219            &self,
2220            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2221            source_gradients: &MPSImageBatch,
2222            source_images: &MPSImageBatch,
2223            gradient_states: &MPSStateBatch,
2224        ) -> Retained<MPSImageBatch>;
2225
2226        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
2227        /// Encode a gradient filter and return a gradient
2228        ///
2229        /// During training, gradient filters are used to calculate the gradient
2230        /// associated with the loss for each feature channel in the forward pass
2231        /// source image. For those nodes that are trainable, these are then used
2232        /// to refine the value used in the trainable parameter. They consume
2233        /// a source gradient image which contains the gradients corresponding
2234        /// with the forward pass destination image, and calculate the gradients
2235        /// corresponding to the forward pass source image.
2236        ///
2237        /// A gradient filter consumes a MPSNNGradientState object which captured
2238        /// various forward pass properties such as offset and edgeMode at the time
2239        /// the forward pass was encoded. These are transferred to the MPSCNNBinaryKernel
2240        /// secondary image properties automatically when you use -[MPSCNNGradientKernel
2241        /// destinationImageDescriptorForSourceImages:sourceStates:]. If you do not call
2242        /// this method, then you are responsible for configuring all of the primary and
2243        /// secondary image properties in MPSCNNBinaryKernel. Please see class description
2244        /// for expected ordering of operations.
2245        ///
2246        /// Parameter `commandBuffer`: The MTLCommandBuffer on which to encode
2247        ///
2248        /// Parameter `sourceGradients`: The gradient images from the "next" filter in the graph
2249        ///
2250        /// Parameter `sourceImages`: The image used as source images from the forward pass
2251        ///
2252        /// Parameter `gradientStates`: An array of the MPSNNGradientState or MPSNNBinaryGradientState subclass
2253        /// produced by the forward pass
2254        ///
2255        /// Parameter `destinationGradients`: The MPSImages into which to write the filter result
2256        #[unsafe(method(encodeBatchToCommandBuffer:sourceGradients:sourceImages:gradientStates:destinationGradients:))]
2257        #[unsafe(method_family = none)]
2258        pub unsafe fn encodeBatchToCommandBuffer_sourceGradients_sourceImages_gradientStates_destinationGradients(
2259            &self,
2260            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2261            source_gradients: &MPSImageBatch,
2262            source_images: &MPSImageBatch,
2263            gradient_states: &MPSStateBatch,
2264            destination_gradients: &MPSImageBatch,
2265        );
2266    );
2267}
2268
2269/// Methods declared on superclass `MPSKernel`.
2270#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2271impl MPSCNNGradientKernel {
2272    extern_methods!(
2273        /// Called by NSCoder to decode MPSKernels
2274        ///
2275        /// This isn't the right interface to decode a MPSKernel, but
2276        /// it is the one that NSCoder uses. To enable your NSCoder
2277        /// (e.g. NSKeyedUnarchiver) to set which device to use
2278        /// extend the object to adopt the MPSDeviceProvider
2279        /// protocol. Otherwise, the Metal system default device
2280        /// will be used.
2281        ///
2282        /// # Safety
2283        ///
2284        /// `a_decoder` possibly has further requirements.
2285        #[unsafe(method(initWithCoder:))]
2286        #[unsafe(method_family = init)]
2287        pub unsafe fn initWithCoder(
2288            this: Allocated<Self>,
2289            a_decoder: &NSCoder,
2290        ) -> Option<Retained<Self>>;
2291    );
2292}
2293
2294/// Methods declared on superclass `NSObject`.
2295#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2296impl MPSCNNGradientKernel {
2297    extern_methods!(
2298        #[unsafe(method(init))]
2299        #[unsafe(method_family = init)]
2300        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
2301
2302        #[unsafe(method(new))]
2303        #[unsafe(method_family = new)]
2304        pub unsafe fn new() -> Retained<Self>;
2305    );
2306}
2307
2308extern_class!(
2309    /// Dependencies: This depends on Metal.framework
2310    ///
2311    /// Describes a  neural network kernel with multiple image sources.
2312    ///
2313    /// A MPSCNNKernel consumes multiple MPSImages, possibly a MPSState, and produces one MPSImage.
2314    ///
2315    /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpscnnmultiarykernel?language=objc)
2316    #[unsafe(super(MPSKernel, NSObject))]
2317    #[derive(Debug, PartialEq, Eq, Hash)]
2318    #[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2319    pub struct MPSCNNMultiaryKernel;
2320);
2321
2322#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2323extern_conformance!(
2324    unsafe impl NSCoding for MPSCNNMultiaryKernel {}
2325);
2326
2327#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2328extern_conformance!(
2329    unsafe impl NSCopying for MPSCNNMultiaryKernel {}
2330);
2331
2332#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2333unsafe impl CopyingHelper for MPSCNNMultiaryKernel {
2334    type Result = Self;
2335}
2336
2337#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2338extern_conformance!(
2339    unsafe impl NSObjectProtocol for MPSCNNMultiaryKernel {}
2340);
2341
2342#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2343extern_conformance!(
2344    unsafe impl NSSecureCoding for MPSCNNMultiaryKernel {}
2345);
2346
2347#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
2348impl MPSCNNMultiaryKernel {
2349    extern_methods!(
2350        /// Standard init with default properties per filter type
2351        ///
2352        /// Parameter `device`: The device that the filter will be used on. May not be NULL.
2353        ///
2354        /// Parameter `sourceCount`: The number of source images or MPSImageBatches
2355        ///
2356        /// Returns: A pointer to the newly initialized object. This will fail, returning
2357        /// nil if the device is not supported. Devices must be
2358        /// MTLFeatureSet_iOS_GPUFamily2_v1 or later.
2359        #[unsafe(method(initWithDevice:sourceCount:))]
2360        #[unsafe(method_family = init)]
2361        pub unsafe fn initWithDevice_sourceCount(
2362            this: Allocated<Self>,
2363            device: &ProtocolObject<dyn MTLDevice>,
2364            source_count: NSUInteger,
2365        ) -> Retained<Self>;
2366
2367        #[unsafe(method(initWithDevice:))]
2368        #[unsafe(method_family = init)]
2369        pub unsafe fn initWithDevice(
2370            this: Allocated<Self>,
2371            device: &ProtocolObject<dyn MTLDevice>,
2372        ) -> Retained<Self>;
2373
2374        /// The number of source images accepted by the kernel
2375        #[unsafe(method(sourceCount))]
2376        #[unsafe(method_family = none)]
2377        pub unsafe fn sourceCount(&self) -> NSUInteger;
2378
2379        /// An optional clip rectangle to use when writing data. Only the pixels in the rectangle will be overwritten.
2380        ///
2381        /// A MTLRegion that indicates which part of the destination to overwrite. If the clipRect does not lie
2382        /// completely within the destination image, the intersection between clip rectangle and destination bounds is
2383        /// used.   Default: MPSRectNoClip (MPSKernel::MPSRectNoClip) indicating the entire image.
2384        /// clipRect.origin.z is the index of starting destination image in batch processing mode. clipRect.size.depth
2385        /// is the number of images to process in batch processing mode.
2386        ///
2387        /// See Also:
2388        /// subsubsection_clipRect
2389        #[unsafe(method(clipRect))]
2390        #[unsafe(method_family = none)]
2391        pub unsafe fn clipRect(&self) -> MTLRegion;
2392
2393        /// Setter for [`clipRect`][Self::clipRect].
2394        #[unsafe(method(setClipRect:))]
2395        #[unsafe(method_family = none)]
2396        pub unsafe fn setClipRect(&self, clip_rect: MTLRegion);
2397
2398        /// The number of channels in the destination MPSImage to skip before writing output.
2399        ///
2400        /// This is the starting offset into the destination image in the feature channel dimension
2401        /// at which destination data is written.
2402        /// This allows an application to pass a subset of all the channels in MPSImage as output of MPSKernel.
2403        /// E.g. Suppose MPSImage has 24 channels and a MPSKernel outputs 8 channels. If
2404        /// we want channels 8 to 15 of this MPSImage to be used as output, we can set destinationFeatureChannelOffset = 8.
2405        /// Note that this offset applies independently to each image when the MPSImage
2406        /// is a container for multiple images and the MPSCNNKernel is processing multiple images (clipRect.size.depth > 1).
2407        /// The default value is 0 and any value specifed shall be a multiple of 4. If MPSKernel outputs N channels,
2408        /// destination image MUST have at least destinationFeatureChannelOffset + N channels. Using a destination
2409        /// image with insufficient number of feature channels result in an error.
2410        /// E.g. if the MPSCNNConvolution outputs 32 channels, and destination has 64 channels, then it is an error to set
2411        /// destinationFeatureChannelOffset > 32.
2412        #[unsafe(method(destinationFeatureChannelOffset))]
2413        #[unsafe(method_family = none)]
2414        pub unsafe fn destinationFeatureChannelOffset(&self) -> NSUInteger;
2415
2416        /// Setter for [`destinationFeatureChannelOffset`][Self::destinationFeatureChannelOffset].
2417        #[unsafe(method(setDestinationFeatureChannelOffset:))]
2418        #[unsafe(method_family = none)]
2419        pub unsafe fn setDestinationFeatureChannelOffset(
2420            &self,
2421            destination_feature_channel_offset: NSUInteger,
2422        );
2423
2424        /// YES if the filter operates backwards.
2425        ///
2426        /// This influences how strideInPixelsX/Y should be interpreted.
2427        #[unsafe(method(isBackwards))]
2428        #[unsafe(method_family = none)]
2429        pub unsafe fn isBackwards(&self) -> bool;
2430
2431        /// Returns true if the -encode call modifies the state object it accepts.
2432        #[unsafe(method(isStateModified))]
2433        #[unsafe(method_family = none)]
2434        pub unsafe fn isStateModified(&self) -> bool;
2435
2436        #[cfg(feature = "MPSNeuralNetworkTypes")]
2437        /// The padding method used by the filter
2438        ///
2439        /// This influences how strideInPixelsX/Y should be interpreted.
2440        /// Default:  MPSNNPaddingMethodAlignCentered | MPSNNPaddingMethodAddRemainderToTopLeft | MPSNNPaddingMethodSizeSame
2441        /// Some object types (e.g. MPSCNNFullyConnected) may override this default with something appropriate to its operation.
2442        #[unsafe(method(padding))]
2443        #[unsafe(method_family = none)]
2444        pub unsafe fn padding(&self) -> Retained<ProtocolObject<dyn MPSNNPadding>>;
2445
2446        #[cfg(feature = "MPSNeuralNetworkTypes")]
2447        /// Setter for [`padding`][Self::padding].
2448        #[unsafe(method(setPadding:))]
2449        #[unsafe(method_family = none)]
2450        pub unsafe fn setPadding(&self, padding: &ProtocolObject<dyn MPSNNPadding>);
2451
2452        #[cfg(feature = "MPSImage")]
2453        /// Method to allocate the result image for -encodeToCommandBuffer:sourceImage:
2454        ///
2455        /// Default: MPSTemporaryImage.defaultAllocator
2456        #[unsafe(method(destinationImageAllocator))]
2457        #[unsafe(method_family = none)]
2458        pub unsafe fn destinationImageAllocator(
2459            &self,
2460        ) -> Retained<ProtocolObject<dyn MPSImageAllocator>>;
2461
2462        #[cfg(feature = "MPSImage")]
2463        /// Setter for [`destinationImageAllocator`][Self::destinationImageAllocator].
2464        #[unsafe(method(setDestinationImageAllocator:))]
2465        #[unsafe(method_family = none)]
2466        pub unsafe fn setDestinationImageAllocator(
2467            &self,
2468            destination_image_allocator: &ProtocolObject<dyn MPSImageAllocator>,
2469        );
2470
2471        #[cfg(feature = "MPSCoreTypes")]
2472        /// The positon of the destination clip rectangle origin relative to each source buffer
2473        ///
2474        /// The offset is defined to be the position of clipRect.origin in source coordinates.
2475        /// Default: {0,0,0}, indicating that the top left corners of the clipRect and source image align.
2476        /// offset.z is the index of starting source image in batch processing mode.
2477        ///
2478        /// Parameter `index`: The index of the source image described by the offset
2479        ///
2480        /// Returns: A MPSOffset for that image
2481        #[unsafe(method(offsetAtIndex:))]
2482        #[unsafe(method_family = none)]
2483        pub unsafe fn offsetAtIndex(&self, index: NSUInteger) -> MPSOffset;
2484
2485        #[cfg(feature = "MPSCoreTypes")]
2486        /// Set the positon of the destination clip rectangle origin relative to each source buffer
2487        ///
2488        /// The offset is defined to be the position of clipRect.origin in source coordinates.
2489        /// Default: {0,0,0}, indicating that the top left corners of the clipRect and source image align.
2490        /// offset.z is the index of starting source image in batch processing mode.
2491        ///
2492        /// Parameter `offset`: The new offset
2493        ///
2494        /// Parameter `index`: The index of the source image described by the offset
2495        #[unsafe(method(setOffset:atIndex:))]
2496        #[unsafe(method_family = none)]
2497        pub unsafe fn setOffset_atIndex(&self, offset: MPSOffset, index: NSUInteger);
2498
2499        /// The number of channels in the source MPSImage to skip before reading the input.
2500        ///
2501        /// This is the starting offset into the  source image in the feature channel dimension
2502        /// at which source data is read. Unit: feature channels
2503        /// This allows an application to read a subset of all the channels in MPSImage as input of MPSKernel.
2504        /// E.g. Suppose MPSImage has 24 channels and a MPSKernel needs to read 8 channels. If
2505        /// we want channels 8 to 15 of this MPSImage to be used as input, we can set sourceFeatureChannelOffset[0] = 8.
2506        /// Note that this offset applies independently to each image when the MPSImage
2507        /// is a container for multiple images and the MPSCNNKernel is processing multiple images (clipRect.size.depth > 1).
2508        /// The default value is 0 and any value specifed shall be a multiple of 4. If MPSKernel inputs N channels,
2509        /// the source image MUST have at least primarySourceFeatureChannelOffset + N channels. Using a source
2510        /// image with insufficient number of feature channels will result in an error.
2511        /// E.g. if the MPSCNNConvolution inputs 32 channels, and the source has 64 channels, then it is an error to set
2512        /// primarySourceFeatureChannelOffset > 32.
2513        ///
2514        /// Parameter `index`: The index of the source image that the feature channel offset describes
2515        ///
2516        /// Returns: The source feature channel offset
2517        #[unsafe(method(sourceFeatureChannelOffsetAtIndex:))]
2518        #[unsafe(method_family = none)]
2519        pub unsafe fn sourceFeatureChannelOffsetAtIndex(&self, index: NSUInteger) -> NSUInteger;
2520
2521        /// Set the number of channels in the source MPSImage to skip before reading the input.
2522        ///
2523        /// This is the starting offset into the  source image in the feature channel dimension
2524        /// at which source data is read. Unit: feature channels
2525        /// This allows an application to read a subset of all the channels in MPSImage as input of MPSKernel.
2526        /// E.g. Suppose MPSImage has 24 channels and a MPSKernel needs to read 8 channels. If
2527        /// we want channels 8 to 15 of this MPSImage to be used as input, we can set sourceFeatureChannelOffset[0] = 8.
2528        /// Note that this offset applies independently to each image when the MPSImage
2529        /// is a container for multiple images and the MPSCNNKernel is processing multiple images (clipRect.size.depth > 1).
2530        /// The default value is 0 and any value specifed shall be a multiple of 4. If MPSKernel inputs N channels,
2531        /// the source image MUST have at least primarySourceFeatureChannelOffset + N channels. Using a source
2532        /// image with insufficient number of feature channels will result in an error.
2533        /// E.g. if the MPSCNNConvolution inputs 32 channels, and the source has 64 channels, then it is an error to set
2534        /// primarySourceFeatureChannelOffset > 32.
2535        ///
2536        /// Parameter `index`: The index of the source image that the feature channel offset describes
2537        ///
2538        /// Parameter `offset`: The source feature channel offset
2539        #[unsafe(method(setSourceFeatureChannelOffset:atIndex:))]
2540        #[unsafe(method_family = none)]
2541        pub unsafe fn setSourceFeatureChannelOffset_atIndex(
2542            &self,
2543            offset: NSUInteger,
2544            index: NSUInteger,
2545        );
2546
2547        /// The maximum number of channels in the source MPSImage to use
2548        ///
2549        /// Most filters can insert a slice operation into the filter for free.
2550        /// Use this to limit the size of the feature channel slice taken from
2551        /// the input image. If the value is too large, it is truncated to be
2552        /// the remaining size in the image after the sourceFeatureChannelOffset
2553        /// is taken into account.  Default: ULONG_MAX
2554        ///
2555        /// Parameter `index`: The index of the source image to which the max count refers
2556        ///
2557        /// Returns: The source feature channel max count
2558        #[unsafe(method(sourceFeatureChannelMaxCountAtIndex:))]
2559        #[unsafe(method_family = none)]
2560        pub unsafe fn sourceFeatureChannelMaxCountAtIndex(&self, index: NSUInteger) -> NSUInteger;
2561
2562        /// Set the maximum number of channels in the source MPSImage to use
2563        ///
2564        /// Most filters can insert a slice operation into the filter for free.
2565        /// Use this to limit the size of the feature channel slice taken from
2566        /// the input image. If the value is too large, it is truncated to be
2567        /// the remaining size in the image after the sourceFeatureChannelOffset
2568        /// is taken into account.  Default: ULONG_MAX
2569        ///
2570        /// Parameter `count`: The new source feature channel max count
2571        ///
2572        /// Parameter `index`: The index of the source image to which the max count refers
2573        #[unsafe(method(setSourceFeatureChannelMaxCount:atIndex:))]
2574        #[unsafe(method_family = none)]
2575        pub unsafe fn setSourceFeatureChannelMaxCount_atIndex(
2576            &self,
2577            count: NSUInteger,
2578            index: NSUInteger,
2579        );
2580
2581        #[cfg(feature = "MPSCoreTypes")]
2582        /// The MPSImageEdgeMode to use when texture reads stray off the edge of the primary source image
2583        ///
2584        /// Most MPSKernel objects can read off the edge of the source image. This can happen
2585        /// because of a negative offset property, because the offset + clipRect.size is larger
2586        /// than the source image or because the filter looks at neighboring pixels, such as a
2587        /// Convolution filter.   Default:  MPSImageEdgeModeZero.
2588        ///
2589        /// See Also:
2590        /// subsubsection_edgemode
2591        /// Parameter `index`: The index of the source image to which the edge mode refers
2592        ///
2593        /// Returns: The edge mode for that source image
2594        #[unsafe(method(edgeModeAtIndex:))]
2595        #[unsafe(method_family = none)]
2596        pub unsafe fn edgeModeAtIndex(&self, index: NSUInteger) -> MPSImageEdgeMode;
2597
2598        #[cfg(feature = "MPSCoreTypes")]
2599        /// Set the MPSImageEdgeMode to use when texture reads stray off the edge of the primary source image
2600        ///
2601        /// Most MPSKernel objects can read off the edge of the source image. This can happen
2602        /// because of a negative offset property, because the offset + clipRect.size is larger
2603        /// than the source image or because the filter looks at neighboring pixels, such as a
2604        /// Convolution filter.   Default:  MPSImageEdgeModeZero.
2605        ///
2606        /// See Also:
2607        /// subsubsection_edgemode
2608        /// Parameter `edgeMode`: The new edge mode to use
2609        ///
2610        /// Parameter `index`: The index of the source image to which the edge mode refers
2611        #[unsafe(method(setEdgeMode:atIndex:))]
2612        #[unsafe(method_family = none)]
2613        pub unsafe fn setEdgeMode_atIndex(&self, edge_mode: MPSImageEdgeMode, index: NSUInteger);
2614
2615        /// The width of the kernel filter window
2616        ///
2617        /// This is the horizontal diameter of the region read by the filter for each
2618        /// result pixel. If the MPSCNNKernel does not have a filter window, then
2619        /// 1 will be returned.
2620        ///
2621        /// Parameter `index`: The index of the source image to which the kernel width refers
2622        #[unsafe(method(kernelWidthAtIndex:))]
2623        #[unsafe(method_family = none)]
2624        pub unsafe fn kernelWidthAtIndex(&self, index: NSUInteger) -> NSUInteger;
2625
2626        /// Set the width of the kernel filter window
2627        ///
2628        /// This is the horizontal diameter of the region read by the filter for each
2629        /// result pixel. If the MPSCNNKernel does not have a filter window, then
2630        /// 1 will be returned.
2631        ///
2632        /// Parameter `width`: The new width
2633        ///
2634        /// Parameter `index`: The index of the source image to which the kernel width refers
2635        #[unsafe(method(setKernelWidth:atIndex:))]
2636        #[unsafe(method_family = none)]
2637        pub unsafe fn setKernelWidth_atIndex(&self, width: NSUInteger, index: NSUInteger);
2638
2639        /// The height of the kernel filter window
2640        ///
2641        /// This is the horizontal diameter of the region read by the filter for each
2642        /// result pixel. If the MPSCNNKernel does not have a filter window, then
2643        /// 1 will be returned.
2644        ///
2645        /// Parameter `index`: The index of the source image to which the kernel width refers
2646        #[unsafe(method(kernelHeightAtIndex:))]
2647        #[unsafe(method_family = none)]
2648        pub unsafe fn kernelHeightAtIndex(&self, index: NSUInteger) -> NSUInteger;
2649
2650        /// Set the height of the kernel filter window
2651        ///
2652        /// This is the horizontal diameter of the region read by the filter for each
2653        /// result pixel. If the MPSCNNKernel does not have a filter window, then
2654        /// 1 will be returned.
2655        ///
2656        /// Parameter `height`: The new width
2657        ///
2658        /// Parameter `index`: The index of the source image to which the kernel width refers
2659        #[unsafe(method(setKernelHeight:atIndex:))]
2660        #[unsafe(method_family = none)]
2661        pub unsafe fn setKernelHeight_atIndex(&self, height: NSUInteger, index: NSUInteger);
2662
2663        /// The downsampling factor in the horizontal dimension for the source image
2664        ///
2665        /// Parameter `index`: The index of the source Image
2666        ///
2667        /// If the filter does not do up or downsampling, 1 is returned.
2668        ///
2669        /// Returns: The stride
2670        #[unsafe(method(strideInPixelsXatIndex:))]
2671        #[unsafe(method_family = none)]
2672        pub unsafe fn strideInPixelsXatIndex(&self, index: NSUInteger) -> NSUInteger;
2673
2674        /// The downsampling factor in the horizontal dimension for the source image
2675        ///
2676        /// If the filter does not do up or downsampling, 1 is returned.  Default: 1
2677        ///
2678        /// Parameter `index`: The index of the source Image
2679        ///
2680        /// Parameter `stride`: The stride for the source image
2681        #[unsafe(method(setStrideInPixelsX:atIndex:))]
2682        #[unsafe(method_family = none)]
2683        pub unsafe fn setStrideInPixelsX_atIndex(&self, stride: NSUInteger, index: NSUInteger);
2684
2685        /// The downsampling factor in the vertical dimension for the source image
2686        ///
2687        /// Parameter `index`: The index of the source Image
2688        ///
2689        /// If the filter does not do up or downsampling, 1 is returned.
2690        ///
2691        /// Returns: The stride
2692        #[unsafe(method(strideInPixelsYatIndex:))]
2693        #[unsafe(method_family = none)]
2694        pub unsafe fn strideInPixelsYatIndex(&self, index: NSUInteger) -> NSUInteger;
2695
2696        /// The downsampling factor in the vertical dimension for the source image
2697        ///
2698        /// If the filter does not do up or downsampling, 1 is returned.  Default: 1
2699        ///
2700        /// Parameter `index`: The index of the source Image
2701        ///
2702        /// Parameter `stride`: The stride for the source image
2703        #[unsafe(method(setStrideInPixelsY:atIndex:))]
2704        #[unsafe(method_family = none)]
2705        pub unsafe fn setStrideInPixelsY_atIndex(&self, stride: NSUInteger, index: NSUInteger);
2706
2707        /// Stride in source coordinates from one kernel tap to the next in the X dimension.
2708        ///
2709        /// Parameter `index`: The index of the source image to which the dilation rate applies
2710        ///
2711        /// Returns: The dilation rate
2712        #[unsafe(method(dilationRateXatIndex:))]
2713        #[unsafe(method_family = none)]
2714        pub unsafe fn dilationRateXatIndex(&self, index: NSUInteger) -> NSUInteger;
2715
2716        /// Set the stride in source coordinates from one kernel tap to the next in the X dimension.
2717        ///
2718        /// Parameter `index`: The index of the source image to which the dilation rate applies
2719        ///
2720        /// Parameter `dilationRate`: The dilation rate
2721        #[unsafe(method(setDilationRateX:atIndex:))]
2722        #[unsafe(method_family = none)]
2723        pub unsafe fn setDilationRateX_atIndex(&self, dilation_rate: NSUInteger, index: NSUInteger);
2724
2725        /// Stride in source coordinates from one kernel tap to the next in the Y dimension.
2726        ///
2727        /// Parameter `index`: The index of the source image to which the dilation rate applies
2728        ///
2729        /// Returns: The dilation rate
2730        #[unsafe(method(dilationRateYatIndex:))]
2731        #[unsafe(method_family = none)]
2732        pub unsafe fn dilationRateYatIndex(&self, index: NSUInteger) -> NSUInteger;
2733
2734        /// Set the stride in source coordinates from one kernel tap to the next in the Y dimension.
2735        ///
2736        /// Parameter `index`: The index of the source image to which the dilation rate applies
2737        ///
2738        /// Parameter `dilationRate`: The dilation rate
2739        #[unsafe(method(setDilationRateY:atIndex:))]
2740        #[unsafe(method_family = none)]
2741        pub unsafe fn setDilationRateY_atIndex(&self, dilation_rate: NSUInteger, index: NSUInteger);
2742
2743        /// NSSecureCoding compatability
2744        ///
2745        /// While the standard NSSecureCoding/NSCoding method
2746        /// -initWithCoder: should work, since the file can't
2747        /// know which device your data is allocated on, we
2748        /// have to guess and may guess incorrectly.  To avoid
2749        /// that problem, use initWithCoder:device instead.
2750        ///
2751        /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
2752        ///
2753        /// Parameter `device`: The MTLDevice on which to make the MPSKernel
2754        ///
2755        /// Returns: A new MPSKernel object, or nil if failure.
2756        ///
2757        /// # Safety
2758        ///
2759        /// `a_decoder` possibly has further requirements.
2760        #[unsafe(method(initWithCoder:device:))]
2761        #[unsafe(method_family = init)]
2762        pub unsafe fn initWithCoder_device(
2763            this: Allocated<Self>,
2764            a_decoder: &NSCoder,
2765            device: &ProtocolObject<dyn MTLDevice>,
2766        ) -> Option<Retained<Self>>;
2767
2768        #[cfg(feature = "MPSImage")]
2769        /// Encode a MPSCNNKernel into a command Buffer.  The operation shall proceed out-of-place.
2770        ///
2771        /// This is the older style of encode which reads the offset, doesn't change it,
2772        /// and ignores the padding method.
2773        ///
2774        /// Parameter `commandBuffer`: A valid MTLCommandBuffer to receive the encoded filter
2775        ///
2776        /// Parameter `sourceImages`: An array containing the source images
2777        ///
2778        /// Parameter `destinationImage`: A valid MPSImage to be overwritten by result image. destinationImage may not alias primarySourceImage or secondarySourceImage.
2779        #[unsafe(method(encodeToCommandBuffer:sourceImages:destinationImage:))]
2780        #[unsafe(method_family = none)]
2781        pub unsafe fn encodeToCommandBuffer_sourceImages_destinationImage(
2782            &self,
2783            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2784            source_images: &NSArray<MPSImage>,
2785            destination_image: &MPSImage,
2786        );
2787
2788        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray"))]
2789        /// Encode a MPSCNNKernel into a command Buffer.  The operation shall proceed out-of-place.
2790        ///
2791        /// This is the older style of encode which reads the offset, doesn't change it,
2792        /// and ignores the padding method. Multiple images are processed concurrently.
2793        /// All images must have MPSImage.numberOfImages = 1.
2794        ///
2795        /// Parameter `commandBuffer`: A valid MTLCommandBuffer to receive the encoded filter
2796        ///
2797        /// Parameter `sourceImages`: An array of image batches containing the source images.
2798        ///
2799        /// Parameter `destinationImages`: An array of MPSImage objects to contain the result images.
2800        /// destinationImages may not alias primarySourceImages or secondarySourceImages
2801        /// in any manner.
2802        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:destinationImages:))]
2803        #[unsafe(method_family = none)]
2804        pub unsafe fn encodeBatchToCommandBuffer_sourceImages_destinationImages(
2805            &self,
2806            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2807            source_images: &NSArray<MPSImageBatch>,
2808            destination_images: &MPSImageBatch,
2809        );
2810
2811        #[cfg(feature = "MPSImage")]
2812        /// Encode a MPSCNNKernel into a command Buffer. Create a texture to hold the result and return it.
2813        ///
2814        /// In the first iteration on this method, encodeToCommandBuffer:sourceImage:destinationImage:
2815        /// some work was left for the developer to do in the form of correctly setting the offset property
2816        /// and sizing the result buffer. With the introduction of the padding policy (see padding property)
2817        /// the filter can do this work itself. If you would like to have some input into what sort of MPSImage
2818        /// (e.g. temporary vs. regular) or what size it is or where it is allocated, you may set the
2819        /// destinationImageAllocator to allocate the image yourself.
2820        ///
2821        /// This method uses the MPSNNPadding padding property to figure out how to size
2822        /// the result image and to set the offset property.  See discussion in MPSNeuralNetworkTypes.h.
2823        ///
2824        ///
2825        /// Parameter `commandBuffer`: The command buffer
2826        ///
2827        /// Parameter `sourceImages`: An array of MPSImages to use as the source images for the filter.
2828        ///
2829        /// Returns: A MPSImage or MPSTemporaryImage allocated per the destinationImageAllocator containing the output of the graph.
2830        /// The returned image will be automatically released when the command buffer completes. If you want to
2831        /// keep it around for longer, retain the image. (ARC will do this for you if you use it later.)
2832        #[unsafe(method(encodeToCommandBuffer:sourceImages:))]
2833        #[unsafe(method_family = none)]
2834        pub unsafe fn encodeToCommandBuffer_sourceImages(
2835            &self,
2836            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2837            source_images: &NSArray<MPSImage>,
2838        ) -> Retained<MPSImage>;
2839
2840        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray"))]
2841        /// Encode a MPSCNNKernel into a command Buffer. Create textures to hold the results and return them.
2842        ///
2843        /// In the first iteration on this method, encodeBatchToCommandBuffer:sourceImage:destinationImage:
2844        /// some work was left for the developer to do in the form of correctly setting the offset property
2845        /// and sizing the result buffer. With the introduction of the padding policy (see padding property)
2846        /// the filter can do this work itself. If you would like to have some input into what sort of MPSImage
2847        /// (e.g. temporary vs. regular) or what size it is or where it is allocated, you may set the
2848        /// destinationImageAllocator to allocate the image yourself.
2849        ///
2850        /// This method uses the MPSNNPadding padding property to figure out how to size
2851        /// the result image and to set the offset property.  See discussion in MPSNeuralNetworkTypes.h.
2852        /// All images in a batch must have MPSImage.numberOfImages = 1.
2853        ///
2854        ///
2855        /// Parameter `commandBuffer`: The command buffer
2856        ///
2857        /// Parameter `sourceImageBatches`: An array of image batches to use as the source images for the filter.
2858        ///
2859        /// Returns: A MPSImage or MPSTemporaryImage allocated per the destinationImageAllocator containing the output of the graph.
2860        /// The returned image will be automatically released when the command buffer completes. If you want to
2861        /// keep it around for longer, retain the image. (ARC will do this for you if you use it later.)
2862        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:))]
2863        #[unsafe(method_family = none)]
2864        pub unsafe fn encodeBatchToCommandBuffer_sourceImages(
2865            &self,
2866            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2867            source_image_batches: &NSArray<MPSImageBatch>,
2868        ) -> Retained<MPSImageBatch>;
2869
2870        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
2871        /// Encode a MPSCNNKernel into a command Buffer. Create a texture and state to hold the results and return them.
2872        ///
2873        /// In the first iteration on this method, encodeToCommandBuffer:sourceImage:destinationState:destinationImage:
2874        /// some work was left for the developer to do in the form of correctly setting the offset property
2875        /// and sizing the result buffer. With the introduction of the padding policy (see padding property)
2876        /// the filter can do this work itself. If you would like to have some input into what sort of MPSImage
2877        /// (e.g. temporary vs. regular) or what size it is or where it is allocated, you may set the
2878        /// destinationImageAllocator to allocate the image yourself.
2879        ///
2880        /// This method uses the MPSNNPadding padding property to figure out how to size
2881        /// the result image and to set the offset property. See discussion in MPSNeuralNetworkTypes.h.
2882        /// All images in a batch must have MPSImage.numberOfImages = 1.
2883        ///
2884        ///
2885        /// Parameter `commandBuffer`: The command buffer
2886        ///
2887        /// Parameter `sourceImages`: An array of MPSImages to use as the source images for the filter.
2888        ///
2889        /// Parameter `outState`: The address of location to write the pointer to the result state of the operation
2890        ///
2891        /// Parameter `isTemporary`: YES if the outState should be a temporary object
2892        ///
2893        /// Returns: A MPSImage or MPSTemporaryImage allocated per the destinationImageAllocator containing the output of the graph.
2894        /// The offset property will be adjusted to reflect the offset used during the encode.
2895        /// The returned image will be automatically released when the command buffer completes. If you want to
2896        /// keep it around for longer, retain the image. (ARC will do this for you if you use it later.)
2897        #[unsafe(method(encodeToCommandBuffer:sourceImages:destinationState:destinationStateIsTemporary:))]
2898        #[unsafe(method_family = none)]
2899        pub unsafe fn encodeToCommandBuffer_sourceImages_destinationState_destinationStateIsTemporary(
2900            &self,
2901            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2902            source_images: &NSArray<MPSImage>,
2903            out_state: &mut Option<Retained<MPSState>>,
2904            is_temporary: bool,
2905        ) -> Retained<MPSImage>;
2906
2907        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
2908        /// Encode a MPSCNNKernel into a command Buffer. Create a texture and state to hold the results and return them.
2909        ///
2910        /// In the first iteration on this method, encodeToCommandBuffer:sourceImage:destinationState:destinationImage:
2911        /// some work was left for the developer to do in the form of correctly setting the offset property
2912        /// and sizing the result buffer. With the introduction of the padding policy (see padding property)
2913        /// the filter can do this work itself. If you would like to have some input into what sort of MPSImage
2914        /// (e.g. temporary vs. regular) or what size it is or where it is allocated, you may set the
2915        /// destinationImageAllocator to allocate the image yourself.
2916        ///
2917        /// This method uses the MPSNNPadding padding property to figure out how to size
2918        /// the result image and to set the offset property. See discussion in MPSNeuralNetworkTypes.h.
2919        /// All images in a batch must have MPSImage.numberOfImages = 1.
2920        ///
2921        ///
2922        /// Parameter `commandBuffer`: The command buffer
2923        ///
2924        /// Parameter `sourceImageBatches`: An array of batches to use as the source images for the filter.
2925        ///
2926        /// Parameter `outState`: A new state object is returned here.
2927        ///
2928        /// Parameter `isTemporary`: YES if the outState should be a temporary object
2929        ///
2930        /// Returns: A MPSImage or MPSTemporaryImage allocated per the destinationImageAllocator containing the output of the graph.
2931        /// The offset property will be adjusted to reflect the offset used during the encode.
2932        /// The returned image will be automatically released when the command buffer completes. If you want to
2933        /// keep it around for longer, retain the image. (ARC will do this for you if you use it later.)
2934        #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:destinationStates:destinationStateIsTemporary:))]
2935        #[unsafe(method_family = none)]
2936        pub unsafe fn encodeBatchToCommandBuffer_sourceImages_destinationStates_destinationStateIsTemporary(
2937            &self,
2938            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
2939            source_image_batches: &NSArray<MPSImageBatch>,
2940            out_state: &mut Option<Retained<MPSStateBatch>>,
2941            is_temporary: bool,
2942        ) -> Retained<MPSImageBatch>;
2943
2944        /// Returns YES if the same state is used for every operation in a batch
2945        ///
2946        /// If NO, then each image in a MPSImageBatch will need a corresponding
2947        /// (and different) state to go with it. Set to YES to avoid allocating
2948        /// redundant state in the case when the same state is used all the time.
2949        /// Default: NO
2950        #[unsafe(method(isResultStateReusedAcrossBatch))]
2951        #[unsafe(method_family = none)]
2952        pub unsafe fn isResultStateReusedAcrossBatch(&self) -> bool;
2953
2954        /// Returns YES if the filter must be run over the entire batch before its
2955        /// results may be used
2956        ///
2957        /// Nearly all filters do not need to see the entire batch all at once and can
2958        /// operate correctly with partial batches. This allows the graph to
2959        /// strip-mine the problem, processing the graph top to bottom on a subset
2960        /// of the batch at a time, dramatically reducing memory usage. As the full
2961        /// nominal working set for a graph is often so large that it may not fit
2962        /// in memory, sub-batching may be required forward progress.
2963        ///
2964        /// Batch normalization statistics on the other hand must complete the batch
2965        /// before the statistics may be used to normalize the images in the batch
2966        /// in the ensuing normalization filter. Consequently, batch normalization statistics
2967        /// requests the graph insert a batch barrier following it by returning
2968        /// YES from -appendBatchBarrier. This tells the graph to complete the batch
2969        /// before any dependent filters can start. Note that the filter itself may
2970        /// still be subject to sub-batching in its operation. All filters must be able to
2971        /// function without seeing the entire batch in a single -encode call. Carry
2972        /// over state that is accumulated across sub-batches is commonly carried in
2973        /// a shared MPSState containing a MTLBuffer. See -isResultStateReusedAcrossBatch.
2974        ///
2975        /// Caution: on most supported devices, the working set may be so large
2976        /// that the graph may be forced to throw away and recalculate most
2977        /// intermediate images in cases where strip-mining can not occur because
2978        /// -appendBatchBarrier returns YES. A single batch barrier can commonly
2979        /// cause a memory size increase and/or performance reduction by many fold
2980        /// over the entire graph.  Filters of this variety should be avoided.
2981        ///
2982        /// Default: NO
2983        #[unsafe(method(appendBatchBarrier))]
2984        #[unsafe(method_family = none)]
2985        pub unsafe fn appendBatchBarrier(&self) -> bool;
2986
2987        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
2988        /// Allocate a MPSState (subclass) to hold the results from a -encodeBatchToCommandBuffer... operation
2989        ///
2990        /// A graph may need to allocate storage up front before executing.  This may be
2991        /// necessary to avoid using too much memory and to manage large batches.  The function
2992        /// should allocate any MPSState objects that will be produced by an -encode call
2993        /// with the indicated sourceImages and sourceStates inputs. Though the states
2994        /// can be further adjusted in the ensuing -encode call, the states should
2995        /// be initialized with all important data and all MTLResource storage allocated.
2996        /// The data stored in the MTLResource need not be initialized, unless the ensuing
2997        /// -encode call expects it to be.
2998        ///
2999        /// The MTLDevice used by the result is derived from the source image.
3000        /// The padding policy will be applied to the filter before this is called
3001        /// to give it the chance to configure any properties like MPSCNNKernel.offset.
3002        ///
3003        /// CAUTION:
3004        /// The kernel must have all properties set to values that will ultimately be
3005        /// passed to the -encode call that writes to the state, before
3006        /// -resultStateForSourceImages:sourceStates:destinationImage: is called or behavior is undefined.
3007        /// Please note that -destinationImageDescriptorForSourceImages:sourceStates:
3008        /// will alter some of these properties automatically based on the padding policy.
3009        /// If you intend to call that to make the destination image, then you should
3010        /// call that before -resultStateForSourceImages:sourceStates:destinationImage:. This will ensure the
3011        /// properties used in the encode call and in the destination image creation
3012        /// match those used to configure the state.
3013        ///
3014        /// The following order is recommended:
3015        ///
3016        /// // Configure MPSCNNKernel properties first
3017        /// kernel.edgeMode = MPSImageEdgeModeZero;
3018        /// kernel.destinationFeatureChannelOffset = 128; // concatenation without the copy
3019        /// ...
3020        ///
3021        /// // ALERT: will change MPSCNNKernel properties
3022        /// MPSImageDescriptor * d = [kernel destinationImageDescriptorForSourceImage: source
3023        /// sourceStates: states];
3024        /// MPSTemporaryImage * dest = [MPSTemporaryImage temporaryImageWithCommandBuffer: cmdBuf
3025        /// imageDescriptor: d];
3026        ///
3027        /// // Now that all properties are configured properly, we can make the result state
3028        /// // and call encode.
3029        /// MPSState * __nullable destState = [kernel resultStateForSourceImage: source
3030        /// sourceStates: states
3031        /// destinationImage: dest];
3032        ///
3033        /// // This form of -encode will be declared by the MPSCNNKernel subclass
3034        /// [kernel encodeToCommandBuffer: cmdBuf
3035        /// sourceImage: source
3036        /// destinationState: destState
3037        /// destinationImage: dest ];
3038        ///
3039        /// Default: returns nil
3040        ///
3041        ///
3042        /// Parameter `sourceImages`: The MPSImage consumed by the associated -encode call.
3043        ///
3044        /// Parameter `sourceStates`: The list of MPSStates consumed by the associated -encode call,
3045        /// for a batch size of 1.
3046        ///
3047        /// Parameter `destinationImage`: The destination image for the encode call
3048        ///
3049        /// Returns: The list of states produced by the -encode call for batch size of 1.
3050        /// When the batch size is not 1, this function will be called repeatedly unless
3051        /// -isResultStateReusedAcrossBatch returns YES. If  -isResultStateReusedAcrossBatch
3052        /// returns YES, then it will be called once per batch and the MPSStateBatch array will
3053        /// contain MPSStateBatch.length references to the same object.
3054        #[unsafe(method(resultStateForSourceImages:sourceStates:destinationImage:))]
3055        #[unsafe(method_family = none)]
3056        pub unsafe fn resultStateForSourceImages_sourceStates_destinationImage(
3057            &self,
3058            source_images: &NSArray<MPSImage>,
3059            source_states: Option<&NSArray<MPSState>>,
3060            destination_image: &MPSImage,
3061        ) -> Option<Retained<MPSState>>;
3062
3063        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
3064        #[unsafe(method(resultStateBatchForSourceImages:sourceStates:destinationImage:))]
3065        #[unsafe(method_family = none)]
3066        pub unsafe fn resultStateBatchForSourceImages_sourceStates_destinationImage(
3067            &self,
3068            source_images: &NSArray<MPSImageBatch>,
3069            source_states: Option<&NSArray<MPSStateBatch>>,
3070            destination_image: &MPSImageBatch,
3071        ) -> Option<Retained<MPSStateBatch>>;
3072
3073        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
3074        /// Allocate a temporary MPSState (subclass) to hold the results from a -encodeBatchToCommandBuffer... operation
3075        ///
3076        /// A graph may need to allocate storage up front before executing.  This may be
3077        /// necessary to avoid using too much memory and to manage large batches.  The function
3078        /// should allocate any MPSState objects that will be produced by an -encode call
3079        /// with the indicated sourceImages and sourceStates inputs. Though the states
3080        /// can be further adjusted in the ensuing -encode call, the states should
3081        /// be initialized with all important data and all MTLResource storage allocated.
3082        /// The data stored in the MTLResource need not be initialized, unless the ensuing
3083        /// -encode call expects it to be.
3084        ///
3085        /// The MTLDevice used by the result is derived from the command buffer.
3086        /// The padding policy will be applied to the filter before this is called
3087        /// to give it the chance to configure any properties like MPSCNNKernel.offset.
3088        ///
3089        /// CAUTION:
3090        /// The kernel must have all properties set to values that will ultimately be
3091        /// passed to the -encode call that writes to the state, before
3092        /// -resultStateForSourceImages:sourceStates:destinationImage: is called or behavior is undefined.
3093        /// Please note that -destinationImageDescriptorForSourceImages:sourceStates:destinationImage:
3094        /// will alter some of these properties automatically based on the padding policy.
3095        /// If you intend to call that to make the destination image, then you should
3096        /// call that before -resultStateForSourceImages:sourceStates:destinationImage:.  This will ensure the
3097        /// properties used in the encode call and in the destination image creation
3098        /// match those used to configure the state.
3099        ///
3100        /// The following order is recommended:
3101        ///
3102        /// // Configure MPSCNNKernel properties first
3103        /// kernel.edgeMode = MPSImageEdgeModeZero;
3104        /// kernel.destinationFeatureChannelOffset = 128; // concatenation without the copy
3105        /// ...
3106        ///
3107        /// // ALERT: will change MPSCNNKernel properties
3108        /// MPSImageDescriptor * d = [kernel destinationImageDescriptorForSourceImage: source
3109        /// sourceStates: states];
3110        /// MPSTemporaryImage * dest = [MPSTemporaryImage temporaryImageWithCommandBuffer: cmdBuf
3111        /// imageDescriptor: d];
3112        ///
3113        /// // Now that all properties are configured properly, we can make the result state
3114        /// // and call encode.
3115        /// MPSState * __nullable destState = [kernel temporaryResultStateForCommandBuffer: cmdBuf
3116        /// sourceImage: source
3117        /// sourceStates: states];
3118        ///
3119        /// // This form of -encode will be declared by the MPSCNNKernel subclass
3120        /// [kernel encodeToCommandBuffer: cmdBuf
3121        /// sourceImage: source
3122        /// destinationState: destState
3123        /// destinationImage: dest ];
3124        ///
3125        /// Default: returns nil
3126        ///
3127        ///
3128        /// Parameter `commandBuffer`: The command buffer to allocate the temporary storage against
3129        /// The state will only be valid on this command buffer.
3130        ///
3131        /// Parameter `sourceImage`: The MPSImage consumed by the associated -encode call.
3132        ///
3133        /// Parameter `sourceStates`: The list of MPSStates consumed by the associated -encode call,
3134        /// for a batch size of 1.
3135        ///
3136        /// Parameter `destinationImage`: The destination image for the encode call
3137        ///
3138        /// Returns: The list of states produced by the -encode call for batch size of 1.
3139        /// When the batch size is not 1, this function will be called repeatedly unless
3140        /// -isResultStateReusedAcrossBatch returns YES. If  -isResultStateReusedAcrossBatch
3141        /// returns YES, then it will be called once per batch and the MPSStateBatch array will
3142        /// contain MPSStateBatch.length references to the same object.
3143        #[unsafe(method(temporaryResultStateForCommandBuffer:sourceImages:sourceStates:destinationImage:))]
3144        #[unsafe(method_family = none)]
3145        pub unsafe fn temporaryResultStateForCommandBuffer_sourceImages_sourceStates_destinationImage(
3146            &self,
3147            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
3148            source_image: &NSArray<MPSImage>,
3149            source_states: Option<&NSArray<MPSState>>,
3150            destination_image: &MPSImage,
3151        ) -> Option<Retained<MPSState>>;
3152
3153        #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
3154        #[unsafe(method(temporaryResultStateBatchForCommandBuffer:sourceImages:sourceStates:destinationImage:))]
3155        #[unsafe(method_family = none)]
3156        pub unsafe fn temporaryResultStateBatchForCommandBuffer_sourceImages_sourceStates_destinationImage(
3157            &self,
3158            command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
3159            source_image: &NSArray<MPSImageBatch>,
3160            source_states: Option<&NSArray<MPSStateBatch>>,
3161            destination_image: &MPSImageBatch,
3162        ) -> Option<Retained<MPSStateBatch>>;
3163
3164        #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
3165        /// Get a suggested destination image descriptor for a source image
3166        ///
3167        /// Your application is certainly free to pass in any destinationImage
3168        /// it likes to encodeToCommandBuffer:sourceImage:destinationImage,
3169        /// within reason. This is the basic design for iOS 10. This method
3170        /// is therefore not required.
3171        ///
3172        /// However, calculating the MPSImage size and MPSCNNKernel properties
3173        /// for each filter can be tedious and complicated work, so this method
3174        /// is made available to automate the process. The application may
3175        /// modify the properties of the descriptor before a MPSImage is made from
3176        /// it, so long as the choice is sensible for the kernel in question.
3177        /// Please see individual kernel descriptions for restrictions.
3178        ///
3179        /// The expected timeline for use is as follows:
3180        ///
3181        /// 1) This method is called:
3182        /// a) The default MPS padding calculation is applied. It
3183        /// uses the MPSNNPaddingMethod of the .padding property to
3184        /// provide a consistent addressing scheme over the graph.
3185        /// It creates the MPSImageDescriptor and adjusts the .offset
3186        /// property of the MPSNNKernel. When using a MPSNNGraph, the
3187        /// padding is set using the MPSNNFilterNode as a proxy.
3188        ///
3189        /// b) This method may be overridden by MPSCNNKernel subclass
3190        /// to achieve any customization appropriate to the object type.
3191        ///
3192        /// c) Source states are then applied in order. These may modify the
3193        /// descriptor and may update other object properties. See:
3194        /// -destinationImageDescriptorForSourceImages:sourceStates:
3195        /// forKernel:suggestedDescriptor:  This is the typical way
3196        /// in which MPS may attempt to influence the operation of
3197        /// its kernels.
3198        ///
3199        /// d) If the .padding property has a custom padding policy method
3200        /// of the same name, it is called. Similarly, it may also adjust
3201        /// the descriptor and any MPSCNNKernel properties. This is the
3202        /// typical way in which your application may attempt to influence
3203        /// the operation of the MPS kernels.
3204        ///
3205        /// 2) A result is returned from this method and the caller
3206        /// may further adjust the descriptor and kernel properties
3207        /// directly.
3208        ///
3209        /// 3) The caller uses the descriptor to make a new MPSImage to
3210        /// use as the destination image for the -encode call in step 5.
3211        ///
3212        /// 4) The caller calls -resultStateForSourceImage:sourceStates:destinationImage:
3213        /// to make any result states needed for the kernel. If there isn't
3214        /// one, it will return nil. A variant is available to return a
3215        /// temporary state instead.
3216        ///
3217        /// 5) a -encode method is called to encode the kernel.
3218        ///
3219        /// The entire process 1-5 is more simply achieved by just calling an -encode...
3220        /// method that returns a MPSImage out the left hand sid of the method. Simpler
3221        /// still, use the MPSNNGraph to coordinate the entire process from end to end.
3222        /// Opportunities to influence the process are of course reduced, as (2) is no longer
3223        /// possible with either method. Your application may opt to use the five step method
3224        /// if it requires greater customization as described, or if it would like to estimate
3225        /// storage in advance based on the sum of MPSImageDescriptors before processing
3226        /// a graph. Storage estimation is done by using the MPSImageDescriptor to create
3227        /// a MPSImage (without passing it a texture), and then call -resourceSize. As long
3228        /// as the MPSImage is not used in an encode call and the .texture property is not
3229        /// invoked, the underlying MTLTexture is not created.
3230        ///
3231        /// No destination state or destination image is provided as an argument to this
3232        /// function because it is expected they will be made / configured after this
3233        /// is called. This method is expected to auto-configure important object properties
3234        /// that may be needed in the ensuing destination image and state creation steps.
3235        ///
3236        ///
3237        /// Parameter `sourceImages`: A array of source images that will be passed into the -encode call
3238        /// Since MPSCNNKernel is a unary kernel, it is an array of length 1.
3239        ///
3240        /// Parameter `sourceStates`: An optional array of source states that will be passed into the -encode call
3241        ///
3242        /// Returns: an image descriptor allocated on the autorelease pool
3243        #[unsafe(method(destinationImageDescriptorForSourceImages:sourceStates:))]
3244        #[unsafe(method_family = none)]
3245        pub unsafe fn destinationImageDescriptorForSourceImages_sourceStates(
3246            &self,
3247            source_images: &NSArray<MPSImage>,
3248            source_states: Option<&NSArray<MPSState>>,
3249        ) -> Retained<MPSImageDescriptor>;
3250    );
3251}
3252
3253/// Methods declared on superclass `MPSKernel`.
3254#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
3255impl MPSCNNMultiaryKernel {
3256    extern_methods!(
3257        /// Called by NSCoder to decode MPSKernels
3258        ///
3259        /// This isn't the right interface to decode a MPSKernel, but
3260        /// it is the one that NSCoder uses. To enable your NSCoder
3261        /// (e.g. NSKeyedUnarchiver) to set which device to use
3262        /// extend the object to adopt the MPSDeviceProvider
3263        /// protocol. Otherwise, the Metal system default device
3264        /// will be used.
3265        ///
3266        /// # Safety
3267        ///
3268        /// `a_decoder` possibly has further requirements.
3269        #[unsafe(method(initWithCoder:))]
3270        #[unsafe(method_family = init)]
3271        pub unsafe fn initWithCoder(
3272            this: Allocated<Self>,
3273            a_decoder: &NSCoder,
3274        ) -> Option<Retained<Self>>;
3275    );
3276}
3277
3278/// Methods declared on superclass `NSObject`.
3279#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
3280impl MPSCNNMultiaryKernel {
3281    extern_methods!(
3282        #[unsafe(method(init))]
3283        #[unsafe(method_family = init)]
3284        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
3285
3286        #[unsafe(method(new))]
3287        #[unsafe(method_family = new)]
3288        pub unsafe fn new() -> Retained<Self>;
3289    );
3290}