objc2_metal_performance_shaders/generated/MPSNeuralNetwork/MPSNNGraph.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
11/// A notification when computeAsyncWithSourceImages:completionHandler: has finished
12///
13/// Parameter `result`: If no error, the image produced by the graph operation.
14///
15/// Parameter `error`: If an error occurs, more information might be found here.
16///
17/// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpsnngraphcompletionhandler?language=objc)
18#[cfg(all(feature = "MPSCore", feature = "MPSImage", feature = "block2"))]
19pub type MPSNNGraphCompletionHandler = *mut block2::DynBlock<dyn Fn(*mut MPSImage, *mut NSError)>;
20
21extern_class!(
22 /// Optimized representation of a graph of MPSNNImageNodes and MPSNNFilterNodes
23 ///
24 /// Once you have prepared a graph of MPSNNImageNodes and MPSNNFilterNodes
25 /// (and if needed MPSNNStateNodes), you may initialize a MPSNNGraph using
26 /// the MPSNNImageNode that you wish to appear as the result. The MPSNNGraph
27 /// object will introspect the graph representation and determine which nodes
28 /// are needed for inputs, and which nodes are produced as output state (if any).
29 /// Nodes which are not needed to calculate the result image node are ignored.
30 /// Some nodes may be internally concatenated with other nodes for better
31 /// performance.
32 ///
33 /// Note: the MPSNNImageNode that you choose as the result node may be interior
34 /// to a graph. This feature is provided as a means to examine intermediate
35 /// computations in the full graph for debugging purposes.
36 ///
37 /// During MPSNNGraph construction, the graph attached to the result node will
38 /// be parsed and reduced to an optimized representation. This representation may
39 /// be saved using the NSSecureCoding protocol for later recall.
40 ///
41 /// When decoding a MPSNNGraph using a NSCoder, it will be created against
42 /// the system default MTLDevice. If you would like to set the MTLDevice,
43 /// your NSCoder should conform to the
44 /// <MPSDeviceProvider
45 /// > protocol.
46 ///
47 /// You may find it helpful to set MPSKernelOptionsVerbose on the graph when
48 /// debugging. To turn this on during MPSKernel initialization (including
49 /// MPSNNGraph initialization) set the MPS_LOG_INFO environment variable.
50 /// There is a lot of information about what optimizations are done to your
51 /// graph, including some information on why certain optimizations were not
52 /// made.
53 ///
54 /// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpsnngraph?language=objc)
55 #[unsafe(super(MPSKernel, NSObject))]
56 #[derive(Debug, PartialEq, Eq, Hash)]
57 #[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
58 pub struct MPSNNGraph;
59);
60
61#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
62extern_conformance!(
63 unsafe impl NSCoding for MPSNNGraph {}
64);
65
66#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
67extern_conformance!(
68 unsafe impl NSCopying for MPSNNGraph {}
69);
70
71#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
72unsafe impl CopyingHelper for MPSNNGraph {
73 type Result = Self;
74}
75
76#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
77extern_conformance!(
78 unsafe impl NSObjectProtocol for MPSNNGraph {}
79);
80
81#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
82extern_conformance!(
83 unsafe impl NSSecureCoding for MPSNNGraph {}
84);
85
86#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
87impl MPSNNGraph {
88 extern_methods!(
89 #[cfg(feature = "MPSNNGraphNodes")]
90 /// Initialize a MPSNNGraph object on a device starting with resultImage working backward
91 ///
92 /// The MPSNNGraph constructor will start with the indicated result image, and look
93 /// to see what MPSNNFilterNode produced it, then look to its dependencies and so
94 /// forth to reveal the subsection of the graph necessary to compute the image.
95 ///
96 /// Parameter `device`: The MTLDevice on which to run the graph
97 ///
98 /// Parameter `resultImage`: The MPSNNImageNode corresponding to the last image in the graph.
99 /// This is the image that will be returned. Note: the imageAllocator
100 /// for this node is ignored and the MPSNNGraph.destinationImageAllocator
101 /// is used for this node instead.
102 ///
103 /// Parameter `resultIsNeeded`: Commonly, when training a graph, the last MPSImage out of the
104 /// graph is not used. The final gradient filter is run solely to update
105 /// some weights. If resultIsNeeded is set to NO, nil will
106 /// be returned from the left hand side of the -encode call instead,
107 /// and computation to produce the last image may be pruned away.
108 ///
109 /// Returns: A new MPSNNGraph.
110 #[unsafe(method(initWithDevice:resultImage:resultImageIsNeeded:))]
111 #[unsafe(method_family = init)]
112 pub unsafe fn initWithDevice_resultImage_resultImageIsNeeded(
113 this: Allocated<Self>,
114 device: &ProtocolObject<dyn MTLDevice>,
115 result_image: &MPSNNImageNode,
116 result_is_needed: bool,
117 ) -> Option<Retained<Self>>;
118
119 #[cfg(feature = "MPSNNGraphNodes")]
120 #[unsafe(method(graphWithDevice:resultImage:resultImageIsNeeded:))]
121 #[unsafe(method_family = none)]
122 pub unsafe fn graphWithDevice_resultImage_resultImageIsNeeded(
123 device: &ProtocolObject<dyn MTLDevice>,
124 result_image: &MPSNNImageNode,
125 result_is_needed: bool,
126 ) -> Option<Retained<Self>>;
127
128 #[cfg(feature = "MPSNNGraphNodes")]
129 /// Initialize a MPSNNGraph object on a device starting with resultImage working backward
130 ///
131 /// The MPSNNGraph constructor will start with the indicated result images, and look
132 /// to see what MPSNNFilterNode produced them, then look to its dependencies and so
133 /// forth to reveal the subsection of the graph necessary to compute the image. This variant
134 /// is provided to support graphs and subgraphs with multiple image outputs.
135 ///
136 /// Parameter `device`: The MTLDevice on which to run the graph
137 ///
138 /// Parameter `resultImages`: The MPSNNImageNodes corresponding to the last images in the graph.
139 /// The first image in the array will be returned from the -encode method
140 /// LHS. The rest will be included in the list of intermediate images.
141 ///
142 /// Parameter `areResultsNeeded`: An array of BOOL values with count equal to resultImages.count.
143 /// If NO is passed for a given image, the image itself is marked unneeded
144 /// and might be skipped. The graph will prune this branch back to the
145 /// first requred filter. A filter is required if it generates a needed
146 /// result image, or is needed to update training parameters.
147 ///
148 /// Returns: A new MPSNNGraph.
149 ///
150 /// # Safety
151 ///
152 /// `are_results_needed` must be a valid pointer or null.
153 #[unsafe(method(initWithDevice:resultImages:resultsAreNeeded:))]
154 #[unsafe(method_family = init)]
155 pub unsafe fn initWithDevice_resultImages_resultsAreNeeded(
156 this: Allocated<Self>,
157 device: &ProtocolObject<dyn MTLDevice>,
158 result_images: &NSArray<MPSNNImageNode>,
159 are_results_needed: *mut Bool,
160 ) -> Option<Retained<Self>>;
161
162 #[cfg(feature = "MPSNNGraphNodes")]
163 /// # Safety
164 ///
165 /// `are_results_needed` must be a valid pointer or null.
166 #[unsafe(method(graphWithDevice:resultImages:resultsAreNeeded:))]
167 #[unsafe(method_family = none)]
168 pub unsafe fn graphWithDevice_resultImages_resultsAreNeeded(
169 device: &ProtocolObject<dyn MTLDevice>,
170 result_images: &NSArray<MPSNNImageNode>,
171 are_results_needed: *mut Bool,
172 ) -> Option<Retained<Self>>;
173
174 #[cfg(feature = "MPSNNGraphNodes")]
175 #[deprecated]
176 #[unsafe(method(initWithDevice:resultImage:))]
177 #[unsafe(method_family = init)]
178 pub unsafe fn initWithDevice_resultImage(
179 this: Allocated<Self>,
180 device: &ProtocolObject<dyn MTLDevice>,
181 result_image: &MPSNNImageNode,
182 ) -> Option<Retained<Self>>;
183
184 #[cfg(feature = "MPSNNGraphNodes")]
185 #[deprecated]
186 #[unsafe(method(graphWithDevice:resultImage:))]
187 #[unsafe(method_family = none)]
188 pub unsafe fn graphWithDevice_resultImage(
189 device: &ProtocolObject<dyn MTLDevice>,
190 result_image: &MPSNNImageNode,
191 ) -> Option<Retained<Self>>;
192
193 /// NSSecureCoding compatability
194 ///
195 /// While the standard NSSecureCoding/NSCoding method
196 /// -initWithCoder: should work, since the file can't
197 /// know which device your data is allocated on, we
198 /// have to guess and may guess incorrectly. To avoid
199 /// that problem, use initWithCoder:device instead.
200 ///
201 /// Parameter `aDecoder`: The NSCoder subclass with your serialized MPSKernel
202 ///
203 /// Parameter `device`: The MTLDevice on which to make the MPSKernel
204 ///
205 /// Returns: A new MPSKernel object, or nil if failure.
206 ///
207 /// # Safety
208 ///
209 /// `a_decoder` possibly has further requirements.
210 #[unsafe(method(initWithCoder:device:))]
211 #[unsafe(method_family = init)]
212 pub unsafe fn initWithCoder_device(
213 this: Allocated<Self>,
214 a_decoder: &NSCoder,
215 device: &ProtocolObject<dyn MTLDevice>,
216 ) -> Option<Retained<Self>>;
217
218 /// Use initWithDevice:resultImage: instead
219 #[unsafe(method(initWithDevice:))]
220 #[unsafe(method_family = init)]
221 pub unsafe fn initWithDevice(
222 this: Allocated<Self>,
223 device: &ProtocolObject<dyn MTLDevice>,
224 ) -> Retained<Self>;
225
226 #[cfg(feature = "MPSNNGraphNodes")]
227 /// Get a list of identifiers for source images needed to calculate the result image
228 #[unsafe(method(sourceImageHandles))]
229 #[unsafe(method_family = none)]
230 pub unsafe fn sourceImageHandles(&self)
231 -> Retained<NSArray<ProtocolObject<dyn MPSHandle>>>;
232
233 #[cfg(feature = "MPSNNGraphNodes")]
234 /// Get a list of identifiers for source state objects needed to calculate the result image
235 ///
236 /// Not guaranteed to be in the same order as resultStateHandles
237 #[unsafe(method(sourceStateHandles))]
238 #[unsafe(method_family = none)]
239 pub unsafe fn sourceStateHandles(
240 &self,
241 ) -> Option<Retained<NSArray<ProtocolObject<dyn MPSHandle>>>>;
242
243 #[cfg(feature = "MPSNNGraphNodes")]
244 /// Get a list of identifiers for intermediate images objects produced by the graph
245 #[unsafe(method(intermediateImageHandles))]
246 #[unsafe(method_family = none)]
247 pub unsafe fn intermediateImageHandles(
248 &self,
249 ) -> Option<Retained<NSArray<ProtocolObject<dyn MPSHandle>>>>;
250
251 #[cfg(feature = "MPSNNGraphNodes")]
252 /// Get a list of identifiers for result state objects produced by the graph
253 ///
254 /// Not guaranteed to be in the same order as sourceStateHandles
255 #[unsafe(method(resultStateHandles))]
256 #[unsafe(method_family = none)]
257 pub unsafe fn resultStateHandles(
258 &self,
259 ) -> Option<Retained<NSArray<ProtocolObject<dyn MPSHandle>>>>;
260
261 #[cfg(feature = "MPSNNGraphNodes")]
262 /// Get a handle for the graph result image
263 #[unsafe(method(resultHandle))]
264 #[unsafe(method_family = none)]
265 pub unsafe fn resultHandle(&self) -> Option<Retained<ProtocolObject<dyn MPSHandle>>>;
266
267 /// Should MPSState objects produced by -encodeToCommandBuffer... be temporary objects.
268 ///
269 /// See MPSState description. Default: NO
270 #[unsafe(method(outputStateIsTemporary))]
271 #[unsafe(method_family = none)]
272 pub unsafe fn outputStateIsTemporary(&self) -> bool;
273
274 /// Setter for [`outputStateIsTemporary`][Self::outputStateIsTemporary].
275 #[unsafe(method(setOutputStateIsTemporary:))]
276 #[unsafe(method_family = none)]
277 pub unsafe fn setOutputStateIsTemporary(&self, output_state_is_temporary: bool);
278
279 #[cfg(feature = "MPSImage")]
280 /// Method to allocate the result image from -encodeToCommandBuffer...
281 ///
282 /// This property overrides the allocator for the final result image in
283 /// the graph. Default: MPSImage.defaultAllocator
284 #[unsafe(method(destinationImageAllocator))]
285 #[unsafe(method_family = none)]
286 pub unsafe fn destinationImageAllocator(
287 &self,
288 ) -> Retained<ProtocolObject<dyn MPSImageAllocator>>;
289
290 #[cfg(feature = "MPSImage")]
291 /// Setter for [`destinationImageAllocator`][Self::destinationImageAllocator].
292 #[unsafe(method(setDestinationImageAllocator:))]
293 #[unsafe(method_family = none)]
294 pub unsafe fn setDestinationImageAllocator(
295 &self,
296 destination_image_allocator: &ProtocolObject<dyn MPSImageAllocator>,
297 );
298
299 #[cfg(feature = "MPSCoreTypes")]
300 /// The default storage format used for graph intermediate images
301 ///
302 /// This doesn't affect how data is stored in buffers in states.
303 /// Nor does it affect the storage format for weights
304 /// such as convolution weights stored by individual filters.
305 /// Default: MPSImageFeatureChannelFormatFloat16
306 #[unsafe(method(format))]
307 #[unsafe(method_family = none)]
308 pub unsafe fn format(&self) -> MPSImageFeatureChannelFormat;
309
310 #[cfg(feature = "MPSCoreTypes")]
311 /// Setter for [`format`][Self::format].
312 #[unsafe(method(setFormat:))]
313 #[unsafe(method_family = none)]
314 pub unsafe fn setFormat(&self, format: MPSImageFeatureChannelFormat);
315
316 /// Set at -init time.
317 ///
318 /// If NO, nil will be returned from -encode calls and some computation
319 /// may be omitted.
320 #[unsafe(method(resultImageIsNeeded))]
321 #[unsafe(method_family = none)]
322 pub unsafe fn resultImageIsNeeded(&self) -> bool;
323
324 /// Reinitialize all graph nodes from data sources
325 ///
326 /// A number of the nodes that make up a graph have a data source
327 /// associated with them, for example a MPSCNNConvolutionDataSource
328 /// or a MPSCNNBatchNormalizationDataSource. Generally, the data
329 /// is read from these once at graph initialization time and then
330 /// not looked at again, except during the weight / parameter update
331 /// phase of the corresponding gradient nodes and then only if CPU
332 /// updates are requested. Otherwise, update occurs on the GPU,
333 /// and the data in the data source is thereafter ignored.
334 ///
335 /// It can happen, though, that your application has determined the
336 /// graph should load a new set of weights from the data source.
337 /// When this method is called, the graph will find all nodes that
338 /// support reloading and direct them to reinitialize themselves
339 /// based on their data source.
340 ///
341 /// This process occurs immediately. Your application will
342 /// need to make sure any GPU work being done by the graph is complete
343 /// to ensure data coherency. Most nodes do not have a data source
344 /// and will not be modified. Nodes that are not used by the graph
345 /// will not be updated.
346 #[unsafe(method(reloadFromDataSources))]
347 #[unsafe(method_family = none)]
348 pub unsafe fn reloadFromDataSources(&self);
349
350 #[cfg(all(feature = "MPSImage", feature = "MPSState"))]
351 /// Encode the graph to a MTLCommandBuffer
352 ///
353 /// Parameter `commandBuffer`: The command buffer. If the command buffer is a MPSCommandBuffer,
354 /// the work will be committed to Metal in small pieces so that
355 /// the CPU-side latency is much reduced.
356 ///
357 /// Parameter `sourceImages`: A list of MPSImages to use as the source images for the graph.
358 /// These should be in the same order as the list returned from MPSNNGraph.sourceImageHandles.
359 /// The images may be image arrays. Typically, this is only one or two images
360 /// such as a .JPG decoded into a MPSImage*. If the sourceImages are MPSTemporaryImages,
361 /// the graph will decrement the readCount by 1, even if the graph actually
362 /// reads an image multiple times.
363 ///
364 /// Parameter `sourceStates`: A list of MPSState objects to use as state for a graph.
365 /// These should be in the same order as the list returned from MPSNNGraph.sourceStateHandles.
366 /// May be nil, if there is no source state. If the sourceStates are temporary,
367 /// the graph will decrement the readCount by 1, even if the graph actually
368 /// reads the state multiple times.
369 ///
370 /// Parameter `intermediateImages`: An optional NSMutableArray to receive any MPSImage objects exported as part of its operation.
371 /// These are only the images that were tagged with MPSNNImageNode.exportFromGraph = YES. The
372 /// identity of the states is given by -resultStateHandles. If temporary, each intermediateImage
373 /// will have a readCount of 1. If the result was tagged exportFromGraph = YES, it will be here
374 /// too, with a readCount of 2. To be able to access the images from outside the graph on the CPU,
375 /// your application must also set MPSNNImageNode.synchronizeResource = YES,
376 /// and MPSNNImageNode.imageAllocator = [MPSImage defaultAllocator]; The defaultAllocator creates
377 /// a permanent image that can be read with readBytes.
378 ///
379 /// Parameter `destinationStates`: An optional NSMutableArray to receive any MPSState objects created as part of its operation.
380 /// The identity of the states is given by -resultStateHandles.
381 ///
382 /// Returns: A MPSImage or MPSTemporaryImage allocated per the destinationImageAllocator containing the output of the graph.
383 /// It will be automatically released when commandBuffer completes.
384 #[unsafe(method(encodeToCommandBuffer:sourceImages:sourceStates:intermediateImages:destinationStates:))]
385 #[unsafe(method_family = none)]
386 pub unsafe fn encodeToCommandBuffer_sourceImages_sourceStates_intermediateImages_destinationStates(
387 &self,
388 command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
389 source_images: &NSArray<MPSImage>,
390 source_states: Option<&NSArray<MPSState>>,
391 intermediate_images: Option<&NSMutableArray<MPSImage>>,
392 destination_states: Option<&NSMutableArray<MPSState>>,
393 ) -> Option<Retained<MPSImage>>;
394
395 #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
396 /// Encode the graph to a MTLCommandBuffer
397 ///
398 /// This interface is like the other except that it operates on a batch of images all
399 /// at once. In addition, you may specify whether the result is needed.
400 ///
401 /// Parameter `commandBuffer`: The command buffer. If the command buffer is a MPSCommandBuffer,
402 /// the work will be committed to Metal in small pieces so that
403 /// the CPU-side latency is much reduced.
404 ///
405 /// Parameter `sourceImages`: A list of MPSImages to use as the source images for the graph.
406 /// These should be in the same order as the list returned from MPSNNGraph.sourceImageHandles.
407 /// The images may be image arrays. Typically, this is only one or two images
408 /// such as a .JPG decoded into a MPSImage*. If the sourceImages are MPSTemporaryImages,
409 /// the graph will decrement the readCount by 1, even if the graph actually
410 /// reads an image multiple times.
411 ///
412 /// Parameter `sourceStates`: A list of MPSState objects to use as state for a graph.
413 /// These should be in the same order as the list returned from MPSNNGraph.sourceStateHandles.
414 /// May be nil, if there is no source state. If the sourceStates are temporary,
415 /// the graph will decrement the readCount by 1, even if the graph actually
416 /// reads the state multiple times.
417 ///
418 /// Parameter `intermediateImages`: An optional NSMutableArray to receive any MPSImage objects exported as part of its operation.
419 /// These are only the images that were tagged with MPSNNImageNode.exportFromGraph = YES. The
420 /// identity of the states is given by -resultStateHandles. If temporary, each intermediateImage
421 /// will have a readCount of 1. If the result was tagged exportFromGraph = YES, it will be here
422 /// too, with a readCount of 2. To be able to access the images from outside the graph on the CPU,
423 /// your application must also set MPSNNImageNode.synchronizeResource = YES,
424 /// and MPSNNImageNode.imageAllocator = [MPSImage defaultAllocator]; The defaultAllocator creates
425 /// a permanent image that can be read with readBytes.
426 ///
427 /// Parameter `destinationStates`: An optional NSMutableArray to receive any MPSState objects created as part of its operation.
428 /// The identity of the states is given by -resultStateHandles.
429 ///
430 /// Returns: A MPSImageBatch or MPSTemporaryImageBatch allocated per the destinationImageAllocator containing the output of the graph.
431 /// It will be automatically released when commandBuffer completes. If resultIsNeeded == NO, then this
432 /// will return nil.
433 #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:sourceStates:intermediateImages:destinationStates:))]
434 #[unsafe(method_family = none)]
435 pub unsafe fn encodeBatchToCommandBuffer_sourceImages_sourceStates_intermediateImages_destinationStates(
436 &self,
437 command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
438 source_images: &NSArray<MPSImageBatch>,
439 source_states: Option<&NSArray<MPSStateBatch>>,
440 intermediate_images: Option<&NSMutableArray<MPSImageBatch>>,
441 destination_states: Option<&NSMutableArray<MPSStateBatch>>,
442 ) -> Option<Retained<MPSImageBatch>>;
443
444 #[cfg(feature = "MPSImage")]
445 /// Encode the graph to a MTLCommandBuffer
446 ///
447 ///
448 /// IMPORTANT: Please use [MTLCommandBuffer addCompletedHandler:] to determine when this work is
449 /// done. Use CPU time that would have been spent waiting for the GPU to encode the next command
450 /// buffer and commit it too. That way, the work for the next command buffer is ready to go the
451 /// moment the GPU is done. This will keep the GPU busy and running at top speed.
452 ///
453 /// Those who ignore this advice and use [MTLCommandBuffer waitUntilCompleted] instead will likely
454 /// cause their code to slow down by a factor of two or more. The CPU clock spins down while it
455 /// waits for the GPU. When the GPU completes, the CPU runs slowly for a while until it spins up.
456 /// The GPU has to wait for the CPU to encode more work (at low clock), giving it plenty of time to
457 /// spin its own clock down. In typical CNN graph usage, neither may ever reach maximum clock
458 /// frequency, causing slow down far beyond what otherwise would be expected from simple failure
459 /// to schedule CPU and GPU work concurrently. Regrattably, it is probable that every performance
460 /// benchmark you see on the net will be based on [MTLCommandBuffer waitUntilCompleted].
461 ///
462 ///
463 /// Parameter `commandBuffer`: The command buffer. If the command buffer is a MPSCommandBuffer,
464 /// the work will be committed to Metal in small pieces so that
465 /// the CPU-side latency is much reduced.
466 ///
467 /// Parameter `sourceImages`: A list of MPSImages to use as the source images for the graph.
468 /// These should be in the same order as the list returned from MPSNNGraph.sourceImageHandles.
469 ///
470 /// Returns: A MPSImage or MPSTemporaryImage allocated per the destinationImageAllocator containing the output of the graph.
471 /// It will be automatically released when commandBuffer completes. It can be nil if resultImageIsNeeded == NO
472 #[unsafe(method(encodeToCommandBuffer:sourceImages:))]
473 #[unsafe(method_family = none)]
474 pub unsafe fn encodeToCommandBuffer_sourceImages(
475 &self,
476 command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
477 source_images: &NSArray<MPSImage>,
478 ) -> Option<Retained<MPSImage>>;
479
480 #[cfg(all(feature = "MPSImage", feature = "MPSNDArray", feature = "MPSState"))]
481 /// Convenience method to encode a batch of images
482 #[unsafe(method(encodeBatchToCommandBuffer:sourceImages:sourceStates:))]
483 #[unsafe(method_family = none)]
484 pub unsafe fn encodeBatchToCommandBuffer_sourceImages_sourceStates(
485 &self,
486 command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
487 source_images: &NSArray<MPSImageBatch>,
488 source_states: Option<&NSArray<MPSStateBatch>>,
489 ) -> Option<Retained<MPSImageBatch>>;
490
491 #[cfg(all(feature = "MPSImage", feature = "block2"))]
492 /// Convenience method to execute a graph without having to manage many Metal details
493 ///
494 /// This function will synchronously encode the graph on a private command buffer,
495 /// commit it to a MPS internal command queue and return. The GPU will start working.
496 /// When the GPU is done, the completion handler will be called. You should use
497 /// the intervening time to encode other work for execution on the GPU, so that
498 /// the GPU stays busy and doesn't clock down.
499 ///
500 /// The work will be performed on the MTLDevice that hosts the source images.
501 ///
502 /// This is a convenience API. There are a few situations it does not handle optimally.
503 /// These may be better handled using [encodeToCommandBuffer:sourceImages:].
504 /// Specifically:
505 ///
506 /// ```text
507 /// o If the graph needs to be run multiple times for different images,
508 /// it would be better to encode the graph multiple times on the same
509 /// command buffer using [encodeToCommandBuffer:sourceImages:] This
510 /// will allow the multiple graphs to share memory for intermediate
511 /// storage, dramatically reducing memory usage.
512 ///
513 /// o If preprocessing or post-processing of the MPSImage is required,
514 /// such as resizing or normalization outside of a convolution, it would
515 /// be better to encode those things on the same command buffer.
516 /// Memory may be saved here too for intermediate storage. (MPSTemporaryImage
517 /// lifetime does not span multiple command buffers.)
518 /// ```
519 ///
520 ///
521 /// Parameter `sourceImages`: A list of MPSImages to use as the source images for the graph.
522 /// These should be in the same order as the list returned from
523 /// MPSNNGraph.sourceImageHandles. They should be allocated against
524 /// the same MTLDevice. There must be at least one source image.
525 /// Note: this array is intended to handle the case where multiple
526 /// input images are required to generate a single graph result.
527 /// That is, the graph itself has multiple inputs. If you need to
528 /// execute the graph multiple times, then call this API multiple
529 /// times, or (faster) make use of MPSImageBatches using
530 /// -executeBatchToCommandBuffer:sourceImages:sourceStates:...
531 /// (See discussion)
532 ///
533 ///
534 /// Parameter `handler`: A block to receive any errors generated. This block may run
535 /// on any thread and may be called before this method returns.
536 /// The image, if any, passed to this callback is the same image
537 /// as that returned from the left hand side.
538 ///
539 ///
540 /// Returns: A MPSImage to receive the result. The data in the image will not be valid until
541 /// the completionHandler is called.
542 ///
543 /// # Safety
544 ///
545 /// `handler` must be a valid pointer.
546 #[unsafe(method(executeAsyncWithSourceImages:completionHandler:))]
547 #[unsafe(method_family = none)]
548 pub unsafe fn executeAsyncWithSourceImages_completionHandler(
549 &self,
550 source_images: &NSArray<MPSImage>,
551 handler: MPSNNGraphCompletionHandler,
552 ) -> Retained<MPSImage>;
553
554 /// Find the number of times a image will be read by the graph *
555 ///
556 /// From the set of images (or image batches) passed in to the graph, find
557 /// the number of times the graph will read an image. This may be needed
558 /// by your application to correctly set the MPSImage.readCount property.
559 ///
560 /// Parameter `index`: The index of the image. The index of the image matches the index of the image in the array returned
561 /// by the sourceImageHandles property.
562 ///
563 /// Returns: The read count of the image(s) at the index will be reduced by the value returned
564 /// when the graph is finished encoding. The readcount of the image(s) must be at least
565 /// this value when it is passed into the -encode... method.
566 #[unsafe(method(readCountForSourceImageAtIndex:))]
567 #[unsafe(method_family = none)]
568 pub unsafe fn readCountForSourceImageAtIndex(&self, index: NSUInteger) -> NSUInteger;
569
570 /// Find the number of times a state will be read by the graph *
571 ///
572 /// From the set of state (or state batches) passed in to the graph, find
573 /// the number of times the graph will read a state. This may be needed
574 /// by your application to correctly set the MPSState.readCount property.
575 ///
576 /// Parameter `index`: The index of the state. The index of the state matches the index of the state in the array returned
577 /// by the sourceStateHandles property.
578 ///
579 /// Returns: The read count of the state(s) at the index will be reduced by the value returned
580 /// when the graph is finished encoding. The read count of the state(s) must be at least
581 /// this value when it is passed into the -encode... method.
582 #[unsafe(method(readCountForSourceStateAtIndex:))]
583 #[unsafe(method_family = none)]
584 pub unsafe fn readCountForSourceStateAtIndex(&self, index: NSUInteger) -> NSUInteger;
585 );
586}
587
588/// Methods declared on superclass `MPSKernel`.
589#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
590impl MPSNNGraph {
591 extern_methods!(
592 /// Called by NSCoder to decode MPSKernels
593 ///
594 /// This isn't the right interface to decode a MPSKernel, but
595 /// it is the one that NSCoder uses. To enable your NSCoder
596 /// (e.g. NSKeyedUnarchiver) to set which device to use
597 /// extend the object to adopt the MPSDeviceProvider
598 /// protocol. Otherwise, the Metal system default device
599 /// will be used.
600 ///
601 /// # Safety
602 ///
603 /// `a_decoder` possibly has further requirements.
604 #[unsafe(method(initWithCoder:))]
605 #[unsafe(method_family = init)]
606 pub unsafe fn initWithCoder(
607 this: Allocated<Self>,
608 a_decoder: &NSCoder,
609 ) -> Option<Retained<Self>>;
610 );
611}
612
613/// Methods declared on superclass `NSObject`.
614#[cfg(all(feature = "MPSCore", feature = "MPSKernel"))]
615impl MPSNNGraph {
616 extern_methods!(
617 #[unsafe(method(init))]
618 #[unsafe(method_family = init)]
619 pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
620
621 #[unsafe(method(new))]
622 #[unsafe(method_family = new)]
623 pub unsafe fn new() -> Retained<Self>;
624 );
625}