objc2_core_ml/generated/MLMultiArray.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::*;
6#[cfg(feature = "objc2-core-video")]
7use objc2_core_video::*;
8use objc2_foundation::*;
9
10use crate::*;
11
12/// The data type of scalars in the multi-array.
13///
14/// See also [Apple's documentation](https://developer.apple.com/documentation/coreml/mlmultiarraydatatype?language=objc)
15// NS_ENUM
16#[repr(transparent)]
17#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
18pub struct MLMultiArrayDataType(pub NSInteger);
19impl MLMultiArrayDataType {
20 #[doc(alias = "MLMultiArrayDataTypeDouble")]
21 pub const Double: Self = Self(0x10000 | 64);
22 #[doc(alias = "MLMultiArrayDataTypeFloat64")]
23 pub const Float64: Self = Self(0x10000 | 64);
24 #[doc(alias = "MLMultiArrayDataTypeFloat32")]
25 pub const Float32: Self = Self(0x10000 | 32);
26 #[doc(alias = "MLMultiArrayDataTypeFloat16")]
27 pub const Float16: Self = Self(0x10000 | 16);
28 #[doc(alias = "MLMultiArrayDataTypeFloat")]
29 pub const Float: Self = Self(0x10000 | 32);
30 #[doc(alias = "MLMultiArrayDataTypeInt32")]
31 pub const Int32: Self = Self(0x20000 | 32);
32 #[doc(alias = "MLMultiArrayDataTypeInt8")]
33 pub const Int8: Self = Self(0x20000 | 8);
34}
35
36unsafe impl Encode for MLMultiArrayDataType {
37 const ENCODING: Encoding = NSInteger::ENCODING;
38}
39
40unsafe impl RefEncode for MLMultiArrayDataType {
41 const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
42}
43
44extern_class!(
45 /// Use `MLMultiArray` to store a multi-dimensional value.
46 ///
47 /// Unlike `MLShapedArray` or `MLTensor`, `MLMultiArray` can be used in Obj-C code. Unlike `MLTensor`, `MLMultiArray` is
48 /// always backed by a concrete storage.
49 ///
50 /// The object has properties to define the interpretation of the storage.
51 ///
52 /// `.dataType` defines the interpretation of raw bytes into a numeric scalar value. For example,
53 /// `MLMultiArrayDataTypeFloat32` means the backing storage uses IEEE 754 Float32 encoding.
54 ///
55 /// `.shape` defines the multi-dimensional space. For example, 30 x 20 image with three color components (Red, Green,
56 /// Blue) could be defined using the shape `[3, 20, 30]`.
57 ///
58 /// `.strides` defines the offset addressing of the scalar for a given coordinates. For example, the image above might
59 /// use `[640, 32, 1]` as the `strides`. Then, the scalar at (1, 10, 15) is stored at `640 * 1 + 32 * 10 + 1 * 15`, or
60 /// 975th scalar in the storage. In general, the scalar offset for coordinates `index` and strides `strides` is:
61 ///
62 /// ```text
63 /// scalarOffset = sum_d index[d]*strides[d]
64 /// ```
65 ///
66 /// The backing storage can be a heap allocated buffer or CVPixelBuffer. Though CVPixelBuffer backing supports limited
67 /// data types, `MLModel` could share the storage with backend hardware such as Apple Neural Engine without copy.
68 ///
69 /// See also [Apple's documentation](https://developer.apple.com/documentation/coreml/mlmultiarray?language=objc)
70 #[unsafe(super(NSObject))]
71 #[derive(Debug, PartialEq, Eq, Hash)]
72 pub struct MLMultiArray;
73);
74
75extern_conformance!(
76 unsafe impl NSCoding for MLMultiArray {}
77);
78
79extern_conformance!(
80 unsafe impl NSObjectProtocol for MLMultiArray {}
81);
82
83extern_conformance!(
84 unsafe impl NSSecureCoding for MLMultiArray {}
85);
86
87impl MLMultiArray {
88 extern_methods!(
89 /// Unsafe pointer to underlying buffer holding the data
90 #[deprecated = "Use getBytesWithHandler or getMutableBytesWithHandler instead. For Swift, use withUnsafeBytes or withUnsafeMutableBytes."]
91 #[unsafe(method(dataPointer))]
92 #[unsafe(method_family = none)]
93 pub unsafe fn dataPointer(&self) -> NonNull<c_void>;
94
95 /// Scalar's data type.
96 #[unsafe(method(dataType))]
97 #[unsafe(method_family = none)]
98 pub unsafe fn dataType(&self) -> MLMultiArrayDataType;
99
100 /// Shape of the multi-dimensional space that this instance represents.
101 #[unsafe(method(shape))]
102 #[unsafe(method_family = none)]
103 pub unsafe fn shape(&self) -> Retained<NSArray<NSNumber>>;
104
105 /// Strides.
106 ///
107 /// It defines the offset of the scalar of a given coordinate index in the storage, which is:
108 /// ```text
109 /// scalarOffset = sum_d index[d]*strides[d]
110 /// ```
111 #[unsafe(method(strides))]
112 #[unsafe(method_family = none)]
113 pub unsafe fn strides(&self) -> Retained<NSArray<NSNumber>>;
114
115 /// Count of total number of addressable scalars.
116 ///
117 /// The value is same as `product_d shape[d]`.
118 #[unsafe(method(count))]
119 #[unsafe(method_family = none)]
120 pub unsafe fn count(&self) -> NSInteger;
121
122 #[cfg(feature = "objc2-core-video")]
123 /// Returns the backing pixel buffer if exists, otherwise nil.
124 #[unsafe(method(pixelBuffer))]
125 #[unsafe(method_family = none)]
126 pub unsafe fn pixelBuffer(&self) -> Option<Retained<CVPixelBuffer>>;
127 );
128}
129
130/// Methods declared on superclass `NSObject`.
131impl MLMultiArray {
132 extern_methods!(
133 #[unsafe(method(init))]
134 #[unsafe(method_family = init)]
135 pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
136
137 #[unsafe(method(new))]
138 #[unsafe(method_family = new)]
139 pub unsafe fn new() -> Retained<Self>;
140 );
141}
142
143/// Creation.
144impl MLMultiArray {
145 extern_methods!(
146 /// Creates the object.
147 ///
148 /// The contents of the object are left uninitialized; the client must initialize it.
149 ///
150 /// The scalars will use the first-major contiguous layout.
151 ///
152 /// - Parameters:
153 /// - shape: The shape
154 /// - dataType: The data type
155 /// - error: Filled with error information on error.
156 #[unsafe(method(initWithShape:dataType:error:_))]
157 #[unsafe(method_family = init)]
158 pub unsafe fn initWithShape_dataType_error(
159 this: Allocated<Self>,
160 shape: &NSArray<NSNumber>,
161 data_type: MLMultiArrayDataType,
162 ) -> Result<Retained<Self>, Retained<NSError>>;
163
164 /// Creates the object with specified strides.
165 ///
166 /// The contents of the object are left uninitialized; the client must initialize it.
167 ///
168 /// ```swift
169 /// let shape = [2, 3];
170 /// let strides = [4, 1]
171 ///
172 /// let multiArray = MLMultiArray(shape: shape, dataType: .float32, strides: strides)
173 /// XCTAssertEqual(multiArray.shape, shape as [NSNumber])
174 /// XCTAssertEqual(multiArray.strides, strides as [NSNumber])
175 /// ```
176 ///
177 /// ```objc
178 /// NSArray
179 /// <NSNumber
180 /// *> *shape =
181 /// @
182 /// [
183 /// @
184 /// 2,
185 /// @
186 /// 3];
187 /// NSArray
188 /// <NSNumber
189 /// *> *strides =
190 /// @
191 /// [
192 /// @
193 /// 4,
194 /// @
195 /// 1];
196 ///
197 /// MLMultiArray *multiArray = [[MLMultiArray alloc] initWithShape:shape
198 /// dataType:MLMultiArrayDataTypeFloat32
199 /// strides:strides];
200 /// XCTAssertEqualObjects(multiArray.shape, shape);
201 /// XCTAssertEqualObjects(multiArray.strides, strides);
202 /// ```
203 ///
204 /// - Parameters:
205 /// - shape: The shape
206 /// - dataType: The data type
207 /// - strides: The strides.
208 #[unsafe(method(initWithShape:dataType:strides:))]
209 #[unsafe(method_family = init)]
210 pub unsafe fn initWithShape_dataType_strides(
211 this: Allocated<Self>,
212 shape: &NSArray<NSNumber>,
213 data_type: MLMultiArrayDataType,
214 strides: &NSArray<NSNumber>,
215 ) -> Retained<Self>;
216
217 #[cfg(feature = "block2")]
218 /// Creates the object with existing data without copy.
219 ///
220 /// Use this initializer to reference the existing buffer as the storage without copy.
221 ///
222 /// ```objc
223 /// int32_t *buffer = malloc(sizeof(int32_t) * 2 * 3 * 4);
224 /// MLMultiArray *multiArray = [[MLMultiArray alloc] initWithDataPointer:buffer
225 /// shape:
226 /// @
227 /// [
228 /// @
229 /// 2,
230 /// @
231 /// 3,
232 /// @
233 /// 4]
234 /// dataType:MLMultiArrayDataTypeInt32
235 /// strides:
236 /// @
237 /// [
238 /// @
239 /// 12,
240 /// @
241 /// 4,
242 /// @
243 /// 1]
244 /// deallocator:^(void *bytes) { free(bytes); }
245 /// error:NULL];
246 /// ```
247 ///
248 /// - Parameters:
249 /// - dataPointer: The pointer to the buffer.
250 /// - shape: The shape
251 /// - dataType: The data type
252 /// - strides: The strides.
253 /// - deallocator: Block to be called on the deallocation of the instance.
254 /// - error: Filled with error information on error.
255 ///
256 /// # Safety
257 ///
258 /// `data_pointer` must be a valid pointer.
259 #[unsafe(method(initWithDataPointer:shape:dataType:strides:deallocator:error:_))]
260 #[unsafe(method_family = init)]
261 pub unsafe fn initWithDataPointer_shape_dataType_strides_deallocator_error(
262 this: Allocated<Self>,
263 data_pointer: NonNull<c_void>,
264 shape: &NSArray<NSNumber>,
265 data_type: MLMultiArrayDataType,
266 strides: &NSArray<NSNumber>,
267 deallocator: Option<&block2::DynBlock<dyn Fn(NonNull<c_void>)>>,
268 ) -> Result<Retained<Self>, Retained<NSError>>;
269
270 #[cfg(feature = "objc2-core-video")]
271 /// Create by wrapping a pixel buffer.
272 ///
273 /// Use this initializer to create an IOSurface backed MLMultiArray, which can reduce the inference latency by avoiding the buffer copy.
274 ///
275 /// The instance will own the pixel buffer and release it on the deallocation.
276 ///
277 /// The pixel buffer's pixel format type must be either `kCVPixelFormatType_OneComponent16Half` for `MLMultiArrayDataTypeFloat16` or
278 /// `kCVPixelFormatType_OneComponent8` for `MLMultiArrayDataTypeInt8`.
279 ///
280 /// ```objc
281 /// CVPixelBufferRef pixelBuffer = NULL;
282 /// NSDictionary* pixelBufferAttributes =
283 /// @
284 /// {
285 /// (id)kCVPixelBufferIOSurfacePropertiesKey:
286 /// @
287 /// {}
288 /// };
289 ///
290 /// // Since shape == [2, 3, 4], width is 4 (= shape[2]) and height is 6 (= shape[0] * shape[1]).
291 /// CVPixelBufferCreate(kCFAllocatorDefault, 4, 6, kCVPixelFormatType_OneComponent16Half, (__bridge CFDictionaryRef)pixelBufferAttributes,
292 /// &pixelBuffer
293 /// );
294 /// MLMultiArray *multiArray = [[MLMultiArray alloc] initWithPixelBuffer:pixelBuffer shape:
295 /// @
296 /// [
297 /// @
298 /// 2,
299 /// @
300 /// 3,
301 /// @
302 /// 4]];
303 /// ```
304 ///
305 /// - Parameters:
306 /// - pixelBuffer: The pixel buffer to be owned by the instance.
307 /// - shape: The shape of the MLMultiArray. The last dimension of `shape` must match the pixel buffer's width. The product of the rest of the dimensions must match the height.
308 #[unsafe(method(initWithPixelBuffer:shape:))]
309 #[unsafe(method_family = init)]
310 pub unsafe fn initWithPixelBuffer_shape(
311 this: Allocated<Self>,
312 pixel_buffer: &CVPixelBuffer,
313 shape: &NSArray<NSNumber>,
314 ) -> Retained<Self>;
315 );
316}
317
318/// ScopedBufferAccess.
319impl MLMultiArray {
320 extern_methods!(
321 #[cfg(feature = "block2")]
322 /// Get the underlying buffer pointer to read.
323 ///
324 /// The buffer pointer is valid only within the block.
325 ///
326 /// ```objc
327 /// MLMultiArray * A = [[MLMultiArray alloc] initWithShape:
328 /// @
329 /// [
330 /// @
331 /// 3,
332 /// @
333 /// 2] dataType:MLMultiArrayDataTypeInt32 error:NULL];
334 /// A[
335 /// @
336 /// [
337 /// @
338 /// 1,
339 /// @
340 /// 2]] =
341 /// @
342 /// 42;
343 /// [A getBytesWithHandler:^(const void *bytes, NSInteger size) {
344 /// const int32_t *scalarBuffer = (const int32_t *)bytes;
345 /// const int strideY = A.strides[0].intValue;
346 /// // Print 42
347 /// NSLog(
348 /// "
349 /// Scalar at (1, 2): %d", scalarBuffer[1 * strideY + 2]);
350 /// }];
351 /// ```
352 /// - Parameters:
353 /// - handler: The block to receive the buffer pointer and its size in bytes.
354 #[unsafe(method(getBytesWithHandler:))]
355 #[unsafe(method_family = none)]
356 pub unsafe fn getBytesWithHandler(
357 &self,
358 handler: &block2::DynBlock<dyn Fn(NonNull<c_void>, NSInteger) + '_>,
359 );
360
361 #[cfg(feature = "block2")]
362 /// Get the underlying buffer pointer to mutate.
363 ///
364 /// The buffer pointer is valid only within the block.
365 ///
366 /// Use `strides` parameter passed in the block because the method may switch to a new backing buffer with different strides.
367 ///
368 /// ```objc
369 /// MLMultiArray * A = [[MLMultiArray alloc] initWithShape:
370 /// @
371 /// [
372 /// @
373 /// 3,
374 /// @
375 /// 2] dataType:MLMultiArrayDataTypeInt32 error:NULL];
376 /// [A getMutableBytesWithHandler:^(void *bytes, NSInteger __unused size, NSArray
377 /// <NSNumber
378 /// *> *strides) {
379 /// int32_t *scalarBuffer = (int32_t *)bytes;
380 /// const int strideY = strides[0].intValue;
381 /// scalarBuffer[1 * strideY + 2] = 42; // Set 42 at A[1, 2]
382 /// }];
383 /// ```
384 ///
385 /// - Parameters:
386 /// - handler: The block to receive the buffer pointer, size in bytes, and strides.
387 #[unsafe(method(getMutableBytesWithHandler:))]
388 #[unsafe(method_family = none)]
389 pub unsafe fn getMutableBytesWithHandler(
390 &self,
391 handler: &block2::DynBlock<
392 dyn Fn(NonNull<c_void>, NSInteger, NonNull<NSArray<NSNumber>>) + '_,
393 >,
394 );
395 );
396}
397
398/// Concatenating.
399impl MLMultiArray {
400 extern_methods!(
401 /// Concatenate MLMultiArrays to form a new MLMultiArray.
402 ///
403 /// All the source MLMultiArrays must have a same shape except the specified axis. The resultant
404 /// MLMultiArray has the same shape as inputs except this axis, which dimension will be the sum of
405 /// all the input dimensions of the axis.
406 ///
407 /// For example,
408 ///
409 /// ```swift
410 /// // Swift
411 /// let A = try MLMultiArray(shape: [2, 3], dataType: .int32)
412 /// let B = try MLMultiArray(shape: [2, 2], dataType: .int32)
413 /// let C = MLMultiArray(concatenating: [A, B], axis: 1, dataType: .int32)
414 /// assert(C.shape == [2, 5])
415 /// ```
416 ///
417 /// ```objc
418 /// // Obj-C
419 /// MLMultiArray *A = [[MLMultiArray alloc] initWithShape:
420 /// @
421 /// [
422 /// @
423 /// 2,
424 /// @
425 /// 3] dataType:MLMultiArrayDataTypeInt32 error:NULL];
426 /// MLMultiArray *B = [[MLMultiArray alloc] initWithShape:
427 /// @
428 /// [
429 /// @
430 /// 2,
431 /// @
432 /// 2] dataType:MLMultiArrayDataTypeInt32 error:NULL];
433 /// MLMultiArray *C = [MLMultiArray multiArrayByConcatenatingMultiArrays:
434 /// @
435 /// [A, B] alongAxis:1 dataType:MLMultiArrayDataTypeInt32];
436 /// assert(C.shape ==
437 /// @
438 /// [
439 /// @
440 /// 2,
441 /// @
442 /// 5])
443 /// ```
444 ///
445 /// Numeric data will be up or down casted as needed.
446 ///
447 /// The method raises NSInvalidArgumentException if the shapes of input multi arrays are not
448 /// compatible for concatenation.
449 ///
450 /// - Parameters:
451 /// - multiArrays: Array of MLMultiArray instances to be concatenated.
452 /// - axis: Axis index with which the concatenation will performed. The value is wrapped by the dimension of the axis. For example, -1 is the last axis.
453 /// - dataType: The data type of the resultant MLMultiArray.
454 #[unsafe(method(multiArrayByConcatenatingMultiArrays:alongAxis:dataType:))]
455 #[unsafe(method_family = none)]
456 pub unsafe fn multiArrayByConcatenatingMultiArrays_alongAxis_dataType(
457 multi_arrays: &NSArray<MLMultiArray>,
458 axis: NSInteger,
459 data_type: MLMultiArrayDataType,
460 ) -> Retained<Self>;
461 );
462}
463
464/// NSNumberDataAccess.
465impl MLMultiArray {
466 extern_methods!(
467 /// Get a value by its linear index (assumes C-style index ordering)
468 #[unsafe(method(objectAtIndexedSubscript:))]
469 #[unsafe(method_family = none)]
470 pub unsafe fn objectAtIndexedSubscript(&self, idx: NSInteger) -> Retained<NSNumber>;
471
472 /// Get a value by its multidimensional index (NSArray
473 /// <NSNumber
474 /// *>)
475 #[unsafe(method(objectForKeyedSubscript:))]
476 #[unsafe(method_family = none)]
477 pub unsafe fn objectForKeyedSubscript(&self, key: &NSArray<NSNumber>)
478 -> Retained<NSNumber>;
479
480 /// Set a value by its linear index (assumes C-style index ordering)
481 #[unsafe(method(setObject:atIndexedSubscript:))]
482 #[unsafe(method_family = none)]
483 pub unsafe fn setObject_atIndexedSubscript(&self, obj: &NSNumber, idx: NSInteger);
484
485 /// Set a value by subindicies (NSArray
486 /// <NSNumber
487 /// *>)
488 #[unsafe(method(setObject:forKeyedSubscript:))]
489 #[unsafe(method_family = none)]
490 pub unsafe fn setObject_forKeyedSubscript(&self, obj: &NSNumber, key: &NSArray<NSNumber>);
491 );
492}
493
494/// Transferring.
495impl MLMultiArray {
496 extern_methods!(
497 /// Transfer the contents to the destination multi-array.
498 ///
499 /// Numeric data will be up or down casted as needed. It can transfer to a multi-array with different layout (strides).
500 ///
501 /// ```swift
502 /// let sourceMultiArray: MLMultiArray = ... // shape is [2, 3] and data type is Float64
503 ///
504 /// let newStrides = [4, 1]
505 /// let destinationMultiArray = MLMultiArray(shape: [2, 3],
506 /// dataType: .float32,
507 /// strides: newStrides)
508 /// sourceMultiArray.transfer(to: destinationMultiArray)
509 /// ```
510 ///
511 /// ```objc
512 /// NSArray
513 /// <NSNumber
514 /// *> *shape =
515 /// @
516 /// [
517 /// @
518 /// 2,
519 /// @
520 /// 3];
521 /// NSArray
522 /// <NSNumber
523 /// *> *sourceStrides =
524 /// @
525 /// [
526 /// @
527 /// 3,
528 /// @
529 /// 1];
530 /// NSArray
531 /// <NSNumber
532 /// *> *destinationStrides =
533 /// @
534 /// [
535 /// @
536 /// 4,
537 /// @
538 /// 1];
539 /// MLMultiArray *source = [[MLMultiArray alloc] initWithShape:shape
540 /// dataType:MLMultiArrayDataTypeDouble
541 /// strides:sourceStrides];
542 /// // Initialize source...
543 ///
544 /// MLMultiArray *destination = [[MLMultiArray alloc] initWithShape:shape
545 /// dataType:MLMultiArrayDataTypeFloat32
546 /// strides:destinationStrides];
547 /// [source transferToMultiArray:destination];
548 /// ```
549 ///
550 /// - Parameters:
551 /// - destinationMultiArray: The transfer destination.
552 #[unsafe(method(transferToMultiArray:))]
553 #[unsafe(method_family = none)]
554 pub unsafe fn transferToMultiArray(&self, destination_multi_array: &MLMultiArray);
555 );
556}