1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;
use objc2_foundation::*;
use objc2_metal::*;
use crate::*;
extern_class!(
/// Dependencies: This depends on Metal.framework
///
/// A MPSNDArrayDescriptor object describes a attributes of MPSNDArray and is used to
/// create one (see MPSNDArray discussion below)
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpsndarraydescriptor?language=objc)
#[unsafe(super(NSObject))]
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct MPSNDArrayDescriptor;
);
extern_conformance!(
unsafe impl NSObjectProtocol for MPSNDArrayDescriptor {}
);
impl MPSNDArrayDescriptor {
extern_methods!(
#[cfg(feature = "MPSCoreTypes")]
/// Data Type of the MPSNDArray elements
#[unsafe(method(dataType))]
#[unsafe(method_family = none)]
pub unsafe fn dataType(&self) -> MPSDataType;
#[cfg(feature = "MPSCoreTypes")]
/// Setter for [`dataType`][Self::dataType].
#[unsafe(method(setDataType:))]
#[unsafe(method_family = none)]
pub unsafe fn setDataType(&self, data_type: MPSDataType);
/// The number of dimensions in the NDArray.
///
/// May not exceed 16. A 0-diumension MPSNDArray is a single scalar value.
/// Undefined dimensions are implicitly length 1.
#[unsafe(method(numberOfDimensions))]
#[unsafe(method_family = none)]
pub unsafe fn numberOfDimensions(&self) -> NSUInteger;
/// Setter for [`numberOfDimensions`][Self::numberOfDimensions].
#[unsafe(method(setNumberOfDimensions:))]
#[unsafe(method_family = none)]
pub unsafe fn setNumberOfDimensions(&self, number_of_dimensions: NSUInteger);
/// If YES, then new NDArrays created with this descriptor will pack the rows. Default: NO.
#[unsafe(method(preferPackedRows))]
#[unsafe(method_family = none)]
pub unsafe fn preferPackedRows(&self) -> bool;
/// Setter for [`preferPackedRows`][Self::preferPackedRows].
#[unsafe(method(setPreferPackedRows:))]
#[unsafe(method_family = none)]
pub unsafe fn setPreferPackedRows(&self, prefer_packed_rows: bool);
/// The number of elements of type dataType in the indicated dimension.
///
/// If dimensionIndex >= numberOfDimensions, 1 will be returned.
///
/// Parameter `dimensionIndex`: dimension the MPSNDArray for which to return the length
///
/// Returns: The number of elements in that dimension.
#[unsafe(method(lengthOfDimension:))]
#[unsafe(method_family = none)]
pub unsafe fn lengthOfDimension(&self, dimension_index: NSUInteger) -> NSUInteger;
#[cfg(feature = "MPSCoreTypes")]
/// The slice dimensions for each dimension
///
/// A slice is a subregion of a dimension. It is
/// used to calve off a fraction of a larger NDArray.
///
/// Parameter `dimensionIndex`: The index of the dimension
///
/// Returns: Returns the slice range for the index. If the
/// dimensionIndex >= numberOfDimensions, {0,1} is returned.
#[unsafe(method(sliceRangeForDimension:))]
#[unsafe(method_family = none)]
pub unsafe fn sliceRangeForDimension(
&self,
dimension_index: NSUInteger,
) -> MPSDimensionSlice;
#[cfg(feature = "MPSCoreTypes")]
/// The slice dimensions for each dimension
///
/// A slice is a subregion of a dimension. It is
/// used to calve off a fraction of a larger NDArray.
///
/// Default: NSRange(0, lengthOfDimension(i))
///
///
/// Parameter `subRange`: The region of the slice, start value is wrt dimensionLength of the NDArray.
///
/// Parameter `dimensionIndex`: The index of the dimension. Must be
/// <
/// numberOfDimensions
#[unsafe(method(sliceDimension:withSubrange:))]
#[unsafe(method_family = none)]
pub unsafe fn sliceDimension_withSubrange(
&self,
dimension_index: NSUInteger,
sub_range: MPSDimensionSlice,
);
/// transpose two dimensions
///
/// If the intention is to insert a length 1 dimension, increment the numberOfDimensions first.
///
/// Parameter `dimensionIndex`: The first dimension. Must be
/// <
/// numberOfDimensions
///
/// Parameter `dimensionIndex2`: The second dimension. Must be
/// <
/// number of Dimensions.
#[unsafe(method(transposeDimension:withDimension:))]
#[unsafe(method_family = none)]
pub unsafe fn transposeDimension_withDimension(
&self,
dimension_index: NSUInteger,
dimension_index2: NSUInteger,
);
/// Permutes the dimensions of the current descriptor
///
/// Parameter `dimensionOrder`: A permutation of the dimensions of the NDArray.
/// dimensionOrder[i] must contain the new postion of dimenson i.
/// Size of the array must be equal to the original number of dimensions in the descriptor.
/// Must have all the indices in [0, numberOfDimensions) present uniquely.
///
///
/// This permutation is applied on top of whatever transpostions/permutations that may have been performed on the descriptor before.
///
/// # Safety
///
/// `dimension_order` must be a valid pointer.
#[unsafe(method(permuteWithDimensionOrder:))]
#[unsafe(method_family = none)]
pub unsafe fn permuteWithDimensionOrder(&self, dimension_order: NonNull<NSUInteger>);
/// Returns the shape of the NDArray as MPSShape
///
/// The length of the array is the number of dimensions and the size of the fastest running dimension is the last element in the array.
#[unsafe(method(getShape))]
#[unsafe(method_family = none)]
pub unsafe fn getShape(&self) -> Retained<NSArray<NSNumber>>;
#[cfg(feature = "MPSCoreTypes")]
/// Create an MPSNDArrayDescriptor object for a given size of dimensions.
///
/// Sample code:
///
/// ```text
/// // Creates an NDArrayDescriptor of dimensions [32, 6, 5, 3]
/// NSUInteger sizes[] = {3,5,6,32};
/// [ MPSNDArray descriptorWithDataType: MPSDataTypeFloat32
/// dimensionCount: 4
/// dimensionSizes: sizes ]; // array of numberOfDimensions dimensions. Starts with dimension 0
/// ```
///
///
/// Parameter `dataType`: MPSDataType of elements in the MPSNDArray
///
/// Parameter `numberOfDimensions`: Number of dimensions in the NDArray. May not exceed 16.
///
/// Parameter `dimensionSizes`: An array of NSUIntegers where dimension lengths provided by the user goes from fastest
/// moving to slowest moving dimension.
/// The product of all dimension lengths must be less than 2**31.
/// Additional system memory limits may apply
///
/// Returns: A valid MPSNDArrayDescriptor object or nil, if failure.
///
/// # Safety
///
/// `dimension_sizes` must be a valid pointer.
#[unsafe(method(descriptorWithDataType:dimensionCount:dimensionSizes:))]
#[unsafe(method_family = none)]
pub unsafe fn descriptorWithDataType_dimensionCount_dimensionSizes(
data_type: MPSDataType,
number_of_dimensions: NSUInteger,
dimension_sizes: NonNull<NSUInteger>,
) -> Retained<Self>;
#[cfg(feature = "MPSCoreTypes")]
/// A convenience function to create an MPSNDArrayDescriptor object for a given size of dimensions.
///
/// Sample code:
///
/// ```text
/// // Creates an NDArrayDescriptor of dimensions [32, 6, 5, 3]
/// NSArray<NSNumber *> sizes = {@32,@6,@5,@3};
/// [ MPSNDArray descriptorWithDataType: MPSDataTypeFloat32
/// shape: &sizes];
/// ```
///
///
/// Parameter `dataType`: MPSDataType of elements in the MPSNDArray
///
/// Parameter `shape`: An array of NSUIntegers where dimension lengths provided by the user goes from slowest
/// moving to fastest moving dimension. This is same order as MLMultiArray in coreML and most frameworks in Python
/// The product of all dimension lengths must be less than 2**31.
/// Additional system memory limits may apply
///
/// Returns: A valid MPSNDArrayDescriptor object or nil, if failure.
#[unsafe(method(descriptorWithDataType:shape:))]
#[unsafe(method_family = none)]
pub unsafe fn descriptorWithDataType_shape(
data_type: MPSDataType,
shape: &NSArray<NSNumber>,
) -> Retained<Self>;
/// Changes dimension sizes and number of dimensions on the current descriptor
///
/// Parameter `numberOfDimensions`: Number of dimensions in the NDArray. May not exceed 16.
///
/// Parameter `dimensionSizes`: An array of NSUIntegers where dimension lengths provided by the user goes from fastest
/// moving to slowest moving dimension.
/// The product of all dimension lengths must be less than 2**31.
/// Additional system memory limits may apply
///
/// # Safety
///
/// `dimension_sizes` must be a valid pointer.
#[unsafe(method(reshapeWithDimensionCount:dimensionSizes:))]
#[unsafe(method_family = none)]
pub unsafe fn reshapeWithDimensionCount_dimensionSizes(
&self,
number_of_dimensions: NSUInteger,
dimension_sizes: NonNull<NSUInteger>,
);
/// Changes dimension sizes and number of dimensions on the current descriptor
///
/// Parameter `shape`: An array of NSUIntegers where dimension lengths provided by the user goes from slowest
/// moving to fastest moving dimension. This is same order as MLMultiArray in coreML and most frameworks in Python
/// The product of all dimension lengths must be less than 2**31.
/// Additional system memory limits may apply
#[unsafe(method(reshapeWithShape:))]
#[unsafe(method_family = none)]
pub unsafe fn reshapeWithShape(&self, shape: &NSArray<NSNumber>);
/// Use -descriptorWithDataType:... instead
#[unsafe(method(init))]
#[unsafe(method_family = init)]
pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
);
}
/// Methods declared on superclass `NSObject`.
impl MPSNDArrayDescriptor {
extern_methods!(
#[unsafe(method(new))]
#[unsafe(method_family = new)]
pub unsafe fn new() -> Retained<Self>;
);
}
extern_protocol!(
/// [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpsndarrayallocator?language=objc)
pub unsafe trait MPSNDArrayAllocator:
NSObjectProtocol + NSSecureCoding + NSCopying
{
#[cfg(feature = "MPSKernel")]
/// Create a new MPSNDArray
///
/// See class description for sample implementation
///
/// Parameter `cmdBuf`: The MTLCommandBuffer on which the array will be initialized.
/// cmdBuf.device encodes the MTLDevice.
///
/// Parameter `descriptor`: A MPSNDArrayDescriptor containing the array parameters to use.
/// This format is the result of your MPSPadding policy.
///
/// Parameter `kernel`: The kernel that will overwrite the array returned by the filter.
/// Note that the MPS implementations of this protocol don't need
/// this field. It is provided for your convenience.
///
///
/// Returns: A valid MPSNDArray or MPSTemporaryNDArray. It will be automatically released when the command buffer completes.
#[unsafe(method(arrayForCommandBuffer:arrayDescriptor:kernel:))]
#[unsafe(method_family = none)]
unsafe fn arrayForCommandBuffer_arrayDescriptor_kernel(
&self,
cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
descriptor: &MPSNDArrayDescriptor,
kernel: &MPSKernel,
) -> Retained<MPSNDArray>;
}
);
extern_class!(
/// A MPSNDArray object is a MTLBuffer based storage container for multi-dimensional data.
///
/// Operations on MPSNDArrays will commonly implicitly reshape the multidimensional
/// structure into a 2-dimensional structure by reinterpreting higher dimensions as a single dimensional
/// array of matrix rows. For example a [a, b, c, d] NDArray passed to a matrix multiplication may
/// be implicitly reinterpreted as a [a*b*c, d] matrix and a 2D matrix multiplication performed.
/// In practice, the major row (the dimension in which successive elements appear adjacent to one
/// another in memory) is the 0th dimension (represented as 'd' in the above example). It has both a
/// dimension size indicating the number of elements and a storage size which may be slightly bigger
/// to allow for performance improvement arising from better data alignment in memory. In principle,
/// the rowBytes may also be used to create a 0th-dimension slice out of a larger array stored in the
/// underlying MTLBuffer.
///
/// MPS will automatically manage the storage size of the major row ("rowBytes") though you may
/// set it in the descriptor if you have a need to do so. Generally, it should be at least a multiple
/// of 16 bytes. Dimensions after the 0th are a densely packed array of rows of size rowBytes.
/// Thus, the 1st dimension is an array of rows. The 2nd dimension is an array of arrays of rows with
/// identical size, and so forth. When the reduction to 2 dimensions is done, no data is moved. MPS
/// just reinterprets a higher order N-1 dimensions of matrix rows as a single large 1-dimensional
/// array of rows.
///
/// It is a common desire to reorder the dimensions of NDArrays or define a subregion thereof. A transpose
/// or slice operation is performed by making a MPSNDArray view of the original. The dimensions to transpose
/// or slice are given by the descriptor for the new view. If both a transpose and slice operation are defined,
/// then the slice is performed first and the result of the slice is transposed. Because many MPS kernels can
/// operate on transposed data at speed, MPS will usually defer doing a physical transpose operation until later,
/// when it becomes clear that one is actually required. For this reason, conversions to formats that do not
/// support deferred transposes and slices such as MPSMatrix MPSVector view or using -exportWithCommandBuffer:
/// toBuffer:offset:rowStrides, may cause substantial new computation to be done and new memory to be allocated.
/// These should be avoided except when necessary. As a general rule, transposes that do not involve the 0th
/// dimension should be able to be handled by nearly everything natively. MPSNDArrayMatrixMultiplication and reductions
/// can handle 0th dimension transposes. Other filters may insert a physical repacking operation. If you wish
/// to force a physical repacking use MPSAliasingStrategyShallNotAlias. To avoid confusion with aliased NDArrays
/// the parent property is provided. MPSNDArrays that alias share a common ancestor.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpsndarray?language=objc)
#[unsafe(super(NSObject))]
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct MPSNDArray;
);
extern_conformance!(
unsafe impl NSObjectProtocol for MPSNDArray {}
);
impl MPSNDArray {
extern_methods!(
/// Get a well known
/// <MPSNDArrayAllocator
/// > that makes standard MTLBuffers
#[unsafe(method(defaultAllocator))]
#[unsafe(method_family = none)]
pub unsafe fn defaultAllocator() -> Retained<ProtocolObject<dyn MPSNDArrayAllocator>>;
/// A used specified string to help identify the array during debugging.
///
/// May be externally visible to tools like Instruments
#[unsafe(method(label))]
#[unsafe(method_family = none)]
pub unsafe fn label(&self) -> Option<Retained<NSString>>;
/// Setter for [`label`][Self::label].
///
/// This is [copied][objc2_foundation::NSCopying::copy] when set.
#[unsafe(method(setLabel:))]
#[unsafe(method_family = none)]
pub unsafe fn setLabel(&self, label: Option<&NSString>);
#[cfg(feature = "MPSCoreTypes")]
/// The type of data stored by each element in the array
#[unsafe(method(dataType))]
#[unsafe(method_family = none)]
pub unsafe fn dataType(&self) -> MPSDataType;
/// The size of one element in the MPSNDArray
#[unsafe(method(dataTypeSize))]
#[unsafe(method_family = none)]
pub unsafe fn dataTypeSize(&self) -> usize;
/// Number of dimensions in the NDArray
#[unsafe(method(numberOfDimensions))]
#[unsafe(method_family = none)]
pub unsafe fn numberOfDimensions(&self) -> NSUInteger;
/// The number of elements in the dimension at dimensionIndex
///
/// The dimension length is at least as large as the existing
/// slice length. Views of this MPSNDArray may have differing
/// dimension lengths.
#[unsafe(method(lengthOfDimension:))]
#[unsafe(method_family = none)]
pub unsafe fn lengthOfDimension(&self, dimension_index: NSUInteger) -> NSUInteger;
/// The device on which the MSPNDArray may be used
#[unsafe(method(device))]
#[unsafe(method_family = none)]
pub unsafe fn device(&self) -> Retained<ProtocolObject<dyn MTLDevice>>;
/// Create a MPSNDArrayDescriptor that describes this MPSNDArray
///
/// The descriptor will describe the shape of the MPSNDArray
/// after all deferred slicing and transposes have completed.
/// A new descriptor is created each time to allow for
/// further customization of the descriptor by the application.
///
/// Returns: A new autoreleased MPSNDArrayDescriptor that matches the
/// shape of the MPSNDArray, suitable for introduction of slice,
/// cast and transpose operations.
#[unsafe(method(descriptor))]
#[unsafe(method_family = none)]
pub unsafe fn descriptor(&self) -> Retained<MPSNDArrayDescriptor>;
#[unsafe(method(init))]
#[unsafe(method_family = init)]
pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
/// Initialize an MPSNDArrayDescriptor object on a device
/// for given dimension sizes in descriptor.
///
///
/// Parameter `device`: The device on which the data type will be created.
///
///
/// Parameter `descriptor`: The MPSNDArrayDescriptor used for initializing the the NDArray
///
///
/// Returns: A valid MPSNDArray object or nil, if failure.
#[unsafe(method(initWithDevice:descriptor:))]
#[unsafe(method_family = init)]
pub unsafe fn initWithDevice_descriptor(
this: Allocated<Self>,
device: &ProtocolObject<dyn MTLDevice>,
descriptor: &MPSNDArrayDescriptor,
) -> Retained<Self>;
/// Create a 1-Dimensional length=1 NDArray to hold a scalar
#[unsafe(method(initWithDevice:scalar:))]
#[unsafe(method_family = init)]
pub unsafe fn initWithDevice_scalar(
this: Allocated<Self>,
device: &ProtocolObject<dyn MTLDevice>,
value: c_double,
) -> Retained<Self>;
/// Initialize an MPSNDArray object from a Metal Buffer with a given descriptor and offset in bytes.
///
///
/// Parameter `buffer`: The buffer used for initializing. The NDArray will alias to this buffer at the given offset.
///
/// Parameter `offset`: Offset in bytes to the buffer.
///
/// Parameter `descriptor`: The MPSNDArrayDescriptor used for initializing the the NDArray.
///
///
/// Returns: A valid MPSNDArray object or nil, if failure.
///
/// # Safety
///
/// - `buffer` may need to be synchronized.
/// - `buffer` may be unretained, you must ensure it is kept alive while in use.
/// - `buffer` contents should be of the correct type.
#[unsafe(method(initWithBuffer:offset:descriptor:))]
#[unsafe(method_family = init)]
pub unsafe fn initWithBuffer_offset_descriptor(
this: Allocated<Self>,
buffer: &ProtocolObject<dyn MTLBuffer>,
offset: NSUInteger,
descriptor: &MPSNDArrayDescriptor,
) -> Retained<Self>;
/// Returns the user buffer in case the NDArray was initialized with an MTLBuffer.
///
/// Returns: The user-provided MTLBuffer that was used to initialize this MPSNDArray or nil, in case it was not..
#[unsafe(method(userBuffer))]
#[unsafe(method_family = none)]
pub unsafe fn userBuffer(&self) -> Option<Retained<ProtocolObject<dyn MTLBuffer>>>;
/// Get the number of bytes used to allocate underyling MTLResources
///
/// This is the size of the backing store of underlying MTLResources.
/// It does not include all storage used by the object, for example
/// the storage used to hold the MPSNDArray instantiation and MTLBuffer
/// is not included. It only measures the size of the allocation used
/// to hold the MPSNDArray data in the MTLBuffer. This value is subject to
/// change between different devices and operating systems.
///
/// Except when -initWithBuffer:descriptor: is used, most MPSNDArrays are allocated
/// initiallly without a backing store. The backing store is allocated lazily when
/// it is needed, typically when the MPSNDArray is written to the first time.
/// Consequently, in most cases, it should be inexpensive to make
/// a MPSImage to see how much memory it will need, and release it
/// if it is too large.
#[unsafe(method(resourceSize))]
#[unsafe(method_family = none)]
pub unsafe fn resourceSize(&self) -> NSUInteger;
#[cfg(feature = "MPSCoreTypes")]
/// Make a new representation of a MPSNDArray with a slice, transpose or other change in property
///
/// If possible, the views will merely record the slice or transpose without performing the
/// operation. Many MPSKernels are able to operate on subregions of a MPSNDArray or operate on transposed
/// data, so making a new copy of the data for these operations would be wasteful. A copy may be forced by
/// a change in dataType, rowBytes, or when using a view with a MPSKernel that does not support
/// the deferred operation. To force an operation to occur immediately, use MPSAliasingStrategyShallNotAlias
/// Otherwise, it is likely that the new MPSNDArray will share a MTLBuffer with the parent and alias
/// its memory.
///
/// Parameter `cmdBuf`: The command buffer on which to perform physical copies if any are required
///
/// Parameter `descriptor`: A MPSNDArrayDescriptor describing the shape of the new view of the data
///
/// Parameter `aliasing`: A aliasing strategy to direct MPS how to respond to cases when aliasing can or can not
/// be performed.
///
/// Returns: A new MPSNDArray, if it is possible to make one. Otherwise nil is returned. The MPSNDArray is autoreleased.
#[unsafe(method(arrayViewWithCommandBuffer:descriptor:aliasing:))]
#[unsafe(method_family = none)]
pub unsafe fn arrayViewWithCommandBuffer_descriptor_aliasing(
&self,
cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
descriptor: &MPSNDArrayDescriptor,
aliasing: MPSAliasingStrategy,
) -> Option<Retained<MPSNDArray>>;
/// Make a new representation of a MPSNDArray with a slice, transpose or other change in property, trying to alias to result.
///
/// The same as `arrayViewWithCommandBuffer`, except that tries to always alias, and therefore does not require a commanbuffer.
/// If aliasing is not possible nil is returned.
/// This method is useful in making aliasing transposes and slices, that are guaranteed to be able to alias. For reshapes it is recommended
/// to use the `MPSNDArrayIdentity` methods.
///
/// Parameter `descriptor`: A MPSNDArrayDescriptor describing the shape of the new view of the data
///
/// Returns: A new MPSNDArray, if it is possible to make one. Otherwise nil is returned. The MPSNDArray is autoreleased.
#[unsafe(method(arrayViewWithDescriptor:))]
#[unsafe(method_family = none)]
pub unsafe fn arrayViewWithDescriptor(
&self,
descriptor: &MPSNDArrayDescriptor,
) -> Option<Retained<MPSNDArray>>;
#[cfg(feature = "MPSCoreTypes")]
/// Make a new representation of a MPSNDArray with given strides and a new shape.
///
/// This operation always returns a new view of the same underlying MTLBuffer, but works only with contiguous buffers.
///
///
/// Parameter `shape`: The new shape for the NDArray. Fastest running dimension last. If nil then current shape is used.
///
/// Parameter `strides`: The strides for each dimension. Must be at least length of new shape. Last number must be one. Must be non-increasing.
///
///
/// Returns: A new MPSNDArray, if it is possible to make one. Otherwise nil is returned. The MPSNDArray is autoreleased.
#[unsafe(method(arrayViewWithShape:strides:))]
#[unsafe(method_family = none)]
pub unsafe fn arrayViewWithShape_strides(
&self,
shape: Option<&MPSShape>,
strides: &MPSShape,
) -> Option<Retained<MPSNDArray>>;
/// Make a new representation of a MPSNDArray with given strides and a new shape.
///
/// This operation always returns a new view of the same underlying MTLBuffer, but works only with contiguous buffers.
///
///
/// Parameter `numberOfDimensions`: Number of dimensions in the new view.
///
/// Parameter `dimensionSizes`: Size of each new dimension. Fastest running dimension first. Must be of length numberOfDimensions.
///
/// Parameter `dimStrides`: The strides for each dimension. First number must be one. Must be non-decreasing. Must be of length numberOfDimensions.
///
///
/// Returns: A new MPSNDArray, if it is possible to make one. Otherwise nil is returned. The MPSNDArray is autoreleased.
///
/// # Safety
///
/// - `dimension_sizes` must be a valid pointer.
/// - `dim_strides` must be a valid pointer.
#[unsafe(method(arrayViewWithDimensionCount:dimensionSizes:strides:))]
#[unsafe(method_family = none)]
pub unsafe fn arrayViewWithDimensionCount_dimensionSizes_strides(
&self,
number_of_dimensions: NSUInteger,
dimension_sizes: NonNull<NSUInteger>,
dim_strides: NonNull<NSUInteger>,
) -> Option<Retained<MPSNDArray>>;
/// The parent MPSNDArray that this object aliases
///
/// If the MPSNDArray was createrd as a array view of another MPSNDArray object, and aliases content
/// in the same MTLBuffer, the original MPSNDArray will be retained as the parent here. Two MPSNDArrays
/// alias if they share a common ancestor. Note that the parent may itself have a parent, and so forth.
#[unsafe(method(parent))]
#[unsafe(method_family = none)]
pub unsafe fn parent(&self) -> Option<Retained<MPSNDArray>>;
#[cfg(feature = "MPSCoreTypes")]
/// Do a GPU side copy of the contents of a MPSNDArray to a MTLBuffer
///
/// To do a transpose or slice as part of the operation, make a MPSNDArray view first that encodes that operation.
///
/// Parameter `cmdBuf`: The command buffer on which to encode the operation
///
/// Parameter `buffer`: The destination to overwrite
///
/// Parameter `destinationDataType`: The destination data type.
///
/// Parameter `offset`: The byte offset to where the {0,0,0...}th element will be written
///
/// Parameter `rowStrides`: An optional array of (numberOfDimensions-1) byte counts which describe
/// the byte offset from position 0 of the respective dimension to position 1.
///
/// # Safety
///
/// - `buffer` may need to be synchronized.
/// - `buffer` may be unretained, you must ensure it is kept alive while in use.
/// - `buffer` contents should be of the correct type.
/// - `row_strides` must be a valid pointer or null.
#[unsafe(method(exportDataWithCommandBuffer:toBuffer:destinationDataType:offset:rowStrides:))]
#[unsafe(method_family = none)]
pub unsafe fn exportDataWithCommandBuffer_toBuffer_destinationDataType_offset_rowStrides(
&self,
cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
buffer: &ProtocolObject<dyn MTLBuffer>,
destination_data_type: MPSDataType,
offset: NSUInteger,
row_strides: *mut NSInteger,
);
#[cfg(feature = "MPSCoreTypes")]
/// Do a GPU side copy of the contents of a MTLBuffer into a MPSNDArray
///
/// Copy data from provided buffer to the NDArray. Implicit transposes and slicing shall be honored.
///
/// Parameter `cmdBuf`: The command buffer on which to encode the operation
///
/// Parameter `buffer`: The destination to read from
///
/// Parameter `sourceDataType`: The source data type.
///
/// Parameter `offset`: The byte offset in the buffer from where the {0,0,0...}th element is to be read.
///
/// Parameter `rowStrides`: An optional array of (numberOfDimensions-1) byte counts which describe
/// the byte offset from position 0 of the respective dimension to position 1.
///
/// # Safety
///
/// - `buffer` may need to be synchronized.
/// - `buffer` may be unretained, you must ensure it is kept alive while in use.
/// - `buffer` contents should be of the correct type.
/// - `row_strides` must be a valid pointer or null.
#[unsafe(method(importDataWithCommandBuffer:fromBuffer:sourceDataType:offset:rowStrides:))]
#[unsafe(method_family = none)]
pub unsafe fn importDataWithCommandBuffer_fromBuffer_sourceDataType_offset_rowStrides(
&self,
cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
buffer: &ProtocolObject<dyn MTLBuffer>,
source_data_type: MPSDataType,
offset: NSUInteger,
row_strides: *mut NSInteger,
);
#[cfg(all(feature = "MPSCoreTypes", feature = "MPSImage"))]
/// Do a GPU side copy of the contents of a MPSNDArray to a MPSImageBatch.
///
/// To do a transpose or slice as part of the operation, make a MPSNDArray view first that encodes that operation.
/// The shape of the array must be [ C, W, H, N, 1, 1, ... ], where C is dimension 0 (normally the fastest running index)
/// and is mapped to feature channels in the destination image, W and H are mapped to x and y coordinates in the destination
/// image and N is mapped to the image batch index. You can use arrayViewWithCommandBuffer: to transpose, slice and reshape
/// the source array to layout the data in the desired way for the image(s).
///
///
/// Parameter `cmdBuf`: The command buffer on which to encode the operation/
///
/// Parameter `images`: The destination images. NOTE: you can use [images subarrayWithRange:...] to get a sub-batch of images.
///
/// Parameter `offset`: The offset to the image where to write - the size of the operation is defined by the source array.
/// Note: offset.featureChannel must be multiple of four, otherwise results are undefined.
#[unsafe(method(exportDataWithCommandBuffer:toImages:offset:))]
#[unsafe(method_family = none)]
pub unsafe fn exportDataWithCommandBuffer_toImages_offset(
&self,
cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
images: &MPSImageBatch,
offset: MPSImageCoordinate,
);
#[cfg(all(feature = "MPSCoreTypes", feature = "MPSImage"))]
/// Do a GPU side copy of the contents of a MPSImageBatch into a MPSNDArray.
///
/// This reverses exportDataWithCommandBuffer:toImages: function.
///
/// Parameter `cmdBuf`: The command buffer on which to encode the operation.
///
/// Parameter `images`: The source images. NOTE: you can use [images subarrayWithRange:...] to get a sub-batch of images.
///
/// Parameter `offset`: The offset to the image where to read - the size of the operation is defined by the destination array.
#[unsafe(method(importDataWithCommandBuffer:fromImages:offset:))]
#[unsafe(method_family = none)]
pub unsafe fn importDataWithCommandBuffer_fromImages_offset(
&self,
cmd_buf: &ProtocolObject<dyn MTLCommandBuffer>,
images: &MPSImageBatch,
offset: MPSImageCoordinate,
);
/// Copy bytes from MPSNDArray into buffer
///
/// The dimensionality and size of the copy region is given by the size of the MPSNDArray
/// For subregions, use a MPSNDArray view.
///
/// Parameter `buffer`: A pointer to memory where to write the data
///
/// Parameter `strideBytesPerDimension`: An optional array of numberOfDimensions sizes, which gives the distance
/// in bytes from one element to the next in that dimension in buffer. The first value
/// is typically dataTypeSize. The next is a row bytes. The next is 2d matrix bytes,
/// and so forth. If the value is nil, these are calculated for you assuming that the
/// data is packed without additional space in between elements, rows, etc.
/// 0 and negative values are permitted.
///
/// # Safety
///
/// - `buffer` must be a valid pointer.
/// - `stride_bytes_per_dimension` must be a valid pointer or null.
#[unsafe(method(readBytes:strideBytes:))]
#[unsafe(method_family = none)]
pub unsafe fn readBytes_strideBytes(
&self,
buffer: NonNull<c_void>,
stride_bytes_per_dimension: *mut NSInteger,
);
/// Copy bytes from a buffer into the MPSNDArray
///
/// The dimensionality and size of the copy region is given by the size of the MPSNDArray
/// For subregions, use a MPSNDArray view.
///
/// Parameter `buffer`: A pointer to memory where to read the data
///
/// Parameter `strideBytesPerDimension`: An optional array of numberOfDimensions sizes, which gives the distance
/// in bytes from one element to the next in that dimension in buffer. The first value
/// is typically dataTypeSize. The next is a row bytes. The next is 2d matrix bytes,
/// and so forth. If strideBytesPerDimension is nil, these are calculated for you assuming that the
/// data is packed without additional space in between elements, rows, etc.
/// 0 and negative values are permitted.
///
/// # Safety
///
/// - `buffer` must be a valid pointer.
/// - `stride_bytes_per_dimension` must be a valid pointer or null.
#[unsafe(method(writeBytes:strideBytes:))]
#[unsafe(method_family = none)]
pub unsafe fn writeBytes_strideBytes(
&self,
buffer: NonNull<c_void>,
stride_bytes_per_dimension: *mut NSInteger,
);
/// Use a blit encoder if a discrete device to update CPU contents of underlying buffer with latest GPU value
///
/// Parameter `commandBuffer`: The commandBuffer on which we transfer the contents.
#[unsafe(method(synchronizeOnCommandBuffer:))]
#[unsafe(method_family = none)]
pub unsafe fn synchronizeOnCommandBuffer(
&self,
command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
);
);
}
/// Methods declared on superclass `NSObject`.
impl MPSNDArray {
extern_methods!(
#[unsafe(method(new))]
#[unsafe(method_family = new)]
pub unsafe fn new() -> Retained<Self>;
);
}
extern_class!(
/// A MPSNDArray that uses command buffer specific memory to store the array data
///
/// Temporary memory is command buffer specific memory, and is useful for MPSNDArray allocations
/// with limited lifetime within a single command buffer. Typically, most MPSNDArrays that
/// are not read or written to by the CPU or needed in other command buffers should be
/// MPSTemporaryNDArray. This will greatly reduce time spent allocating new memory, reduce memory usage
/// and help improve memory locality.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/metalperformanceshaders/mpstemporaryndarray?language=objc)
#[unsafe(super(MPSNDArray, NSObject))]
#[derive(Debug, PartialEq, Eq, Hash)]
pub struct MPSTemporaryNDArray;
);
extern_conformance!(
unsafe impl NSObjectProtocol for MPSTemporaryNDArray {}
);
impl MPSTemporaryNDArray {
extern_methods!(
/// Get a well known
/// <MPSNDArrayAllocator
/// > that makes temporary MTLBuffers
#[unsafe(method(defaultAllocator))]
#[unsafe(method_family = none)]
pub unsafe fn defaultAllocator() -> Retained<ProtocolObject<dyn MPSNDArrayAllocator>>;
/// Initialize a MPSTemporaryNDArray for use on a MTLCommandBuffer
///
/// Parameter `commandBuffer`: The MTLCommandBuffer on which the MPSTemporaryNDArray will be exclusively used
///
/// Parameter `descriptor`: A valid MPSNDArrayDescriptor describing the MPSNDArray format to create
///
/// Returns: A valid MPSTemporaryNDArray. The object is not managed by a NSAutoreleasePool. The object will be
/// released when the command buffer is committed. The underlying buffer will become invalid before
/// this time due to the action of the readCount property. Please read and understand the use of
/// the readCount property before using this object.
#[unsafe(method(temporaryNDArrayWithCommandBuffer:descriptor:))]
#[unsafe(method_family = none)]
pub unsafe fn temporaryNDArrayWithCommandBuffer_descriptor(
command_buffer: &ProtocolObject<dyn MTLCommandBuffer>,
descriptor: &MPSNDArrayDescriptor,
) -> Retained<Self>;
/// Please use temporaryNDArrayWithCommandBuffer:descriptor: instead
#[unsafe(method(initWithDevice:descriptor:))]
#[unsafe(method_family = init)]
pub unsafe fn initWithDevice_descriptor(
this: Allocated<Self>,
device: &ProtocolObject<dyn MTLDevice>,
descriptor: &MPSNDArrayDescriptor,
) -> Retained<Self>;
/// The number of times a temporary MPSNDArray may be read by a MPSNDArray... kernel
/// before its contents become undefined.
///
///
/// MPSTemporaryNDArrays must release their underlying buffers for reuse
/// immediately after last use. So as to facilitate *prompt* convenient
/// memory recycling, each time a MPSTemporaryNDArray is read by a
/// MPSNDArray... -encode... method, its readCount is automatically
/// decremented. When the readCount reaches 0, the underlying buffer is
/// automatically made available for reuse to MPS for its own needs and for
/// other MPSTemporaryNDArrays prior to return from the -encode.. function.
/// The contents of the buffer become undefined at this time.
///
/// By default, the readCount is initialized to 1, indicating a MPSNDArray that
/// may be overwritten any number of times, but read only once.
///
/// You may change the readCount as desired to allow MPSNDArrayKernels to read
/// the MPSTemporaryNDArray additional times. However, it is an error to change
/// the readCount once it is zero. It is an error to read or write to a
/// MPSTemporaryNDArray with a zero readCount. You may set the readCount to 0
/// yourself to cause the underlying buffer to be returned to MPS. Writing
/// to a MPSTemporaryNDArray does not adjust the readCount.
///
/// The Metal API Validation layer will assert if a MPSTemporaryNDArray is
/// deallocated with non-zero readCount to help identify cases when resources
/// are not returned promptly.
#[unsafe(method(readCount))]
#[unsafe(method_family = none)]
pub unsafe fn readCount(&self) -> NSUInteger;
/// Setter for [`readCount`][Self::readCount].
#[unsafe(method(setReadCount:))]
#[unsafe(method_family = none)]
pub unsafe fn setReadCount(&self, read_count: NSUInteger);
);
}
/// Methods declared on superclass `MPSNDArray`.
impl MPSTemporaryNDArray {
extern_methods!(
#[unsafe(method(init))]
#[unsafe(method_family = init)]
pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
/// Create a 1-Dimensional length=1 NDArray to hold a scalar
#[unsafe(method(initWithDevice:scalar:))]
#[unsafe(method_family = init)]
pub unsafe fn initWithDevice_scalar(
this: Allocated<Self>,
device: &ProtocolObject<dyn MTLDevice>,
value: c_double,
) -> Retained<Self>;
/// Initialize an MPSNDArray object from a Metal Buffer with a given descriptor and offset in bytes.
///
///
/// Parameter `buffer`: The buffer used for initializing. The NDArray will alias to this buffer at the given offset.
///
/// Parameter `offset`: Offset in bytes to the buffer.
///
/// Parameter `descriptor`: The MPSNDArrayDescriptor used for initializing the the NDArray.
///
///
/// Returns: A valid MPSNDArray object or nil, if failure.
///
/// # Safety
///
/// - `buffer` may need to be synchronized.
/// - `buffer` may be unretained, you must ensure it is kept alive while in use.
/// - `buffer` contents should be of the correct type.
#[unsafe(method(initWithBuffer:offset:descriptor:))]
#[unsafe(method_family = init)]
pub unsafe fn initWithBuffer_offset_descriptor(
this: Allocated<Self>,
buffer: &ProtocolObject<dyn MTLBuffer>,
offset: NSUInteger,
descriptor: &MPSNDArrayDescriptor,
) -> Retained<Self>;
);
}
/// Methods declared on superclass `NSObject`.
impl MPSTemporaryNDArray {
extern_methods!(
#[unsafe(method(new))]
#[unsafe(method_family = new)]
pub unsafe fn new() -> Retained<Self>;
);
}