Skip to content

Commit 995c095

Browse files
authored
[MetalPerformanceShaders] Bind missing APIs. (#23785)
1 parent 0452b6f commit 995c095

23 files changed

+2587
-1828
lines changed

runtime/bindings-generator.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2632,6 +2632,15 @@ static IEnumerable<FunctionData> GetFunctionData ()
26322632
}
26332633
);
26342634

2635+
data.Add (
2636+
new FunctionData {
2637+
Comment = " // NVector16b func ()",
2638+
Prefix = "simd__",
2639+
Variants = Variants.NonStret,
2640+
ReturnType = Types.NVector16b,
2641+
}
2642+
);
2643+
26352644
// We must expand functions with native types to their actual type as well.
26362645
for (int i = data.Count - 1; i >= 0; i--) {
26372646
if (!data [i].HasNativeType)
@@ -2798,6 +2807,10 @@ static void MarshalToManaged (StringWriter writer, TypeData type, string nativeV
27982807
writer.WriteLine ("\t{0}{2}min.b = {1}.min [1];", managedVariable, nativeVariable, accessor);
27992808
writer.WriteLine ("\t{0}{2}min.c = {1}.min [2];", managedVariable, nativeVariable, accessor);
28002809
break;
2810+
case "NVector16b":
2811+
writer.WriteLine ("\tfor (int i = 0; i < 16; i++)");
2812+
writer.WriteLine ("\t\t{0}{2}values [i] = {1} [i];", managedVariable, nativeVariable, accessor);
2813+
break;
28012814
default:
28022815
throw new NotImplementedException (string.Format ("MarshalToManaged for: NativeType: {0} ManagedType: {1}", type.NativeType, type.ManagedType));
28032816
}
@@ -2945,6 +2958,10 @@ static void MarshalToNative (StringWriter writer, TypeData type, string nativeVa
29452958
writer.WriteLine ("\t{0}.min [1] = {1}{2}min.b;", nativeVariable, managedVariable, accessor);
29462959
writer.WriteLine ("\t{0}.min [2] = {1}{2}min.c;", nativeVariable, managedVariable, accessor);
29472960
break;
2961+
case "VectorUChar16":
2962+
writer.WriteLine ("\tfor (int i = 0; i < 16; i++)");
2963+
writer.WriteLine ("\t\t{0} [i] = {1}{2}values[i];", nativeVariable, managedVariable, accessor);
2964+
break;
29482965
default:
29492966
throw new NotImplementedException (string.Format ("MarshalToNative for: NativeType: {0} ManagedType: {1}", type.NativeType, type.ManagedType));
29502967
}
@@ -3406,6 +3423,15 @@ public static class Types {
34063423
NativeWrapperType = "struct Vector4d",
34073424
RequireMarshal = true,
34083425
};
3426+
3427+
public static TypeData NVector16b = new TypeData {
3428+
ManagedType = "NVector16b",
3429+
NativeType = "vector_uchar16",
3430+
NativeWrapperType = "struct VectorUChar16",
3431+
RequireMarshal = true,
3432+
IsX64Stret = false,
3433+
};
3434+
34093435
public static TypeData Matrix2f = new TypeData {
34103436
ManagedType = "Matrix2",
34113437
NativeType = "matrix_float2x2",

runtime/bindings.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ typedef __attribute__((__ext_vector_type__(2))) float vector_float2;
8080
typedef __attribute__((__ext_vector_type__(3))) float vector_float3;
8181
typedef __attribute__((__ext_vector_type__(4))) float vector_float4;
8282

83+
typedef __attribute__((__ext_vector_type__(16))) unsigned char vector_uchar16;
84+
8385
typedef struct { vector_float2 columns[2]; } matrix_float2x2;
8486
typedef struct { vector_float3 columns[3]; } matrix_float3x3;
8587
typedef struct { vector_float4 columns[4]; } matrix_float4x4;
@@ -252,6 +254,10 @@ struct MPSAxisAlignedBoundingBoxWrapper {
252254
Vector3f max;
253255
};
254256

257+
struct VectorUChar16 {
258+
unsigned char values[16];
259+
};
260+
255261
static_assert (sizeof (MPSImageHistogramInfoWrapper) == sizeof (MPSImageHistogramInfo), "Sizes aren't equal");
256262

257263
struct Vector4f xamarin_vector_float3__Vector4_objc_msgSend (id self, SEL sel);

src/MetalPerformanceShaders/MPSCnnKernel.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public unsafe MPSCnnBinaryConvolution (IMTLDevice device, IMPSCnnConvolutionData
2323
fixed (void* outputScaleTermsHandle = outputScaleTerms)
2424
fixed (void* inputBiasTermsHandle = inputBiasTerms)
2525
fixed (void* inputScaleTermsHandle = inputScaleTerms)
26-
InitializeHandle (InitWithDevice (device, convolutionData, (IntPtr) outputBiasTermsHandle, (IntPtr) outputScaleTermsHandle, (IntPtr) inputBiasTermsHandle, (IntPtr) inputScaleTermsHandle, type, flags));
26+
InitializeHandle (_InitWithDevice (device, convolutionData, (IntPtr) outputBiasTermsHandle, (IntPtr) outputScaleTermsHandle, (IntPtr) inputBiasTermsHandle, (IntPtr) inputScaleTermsHandle, type, flags));
2727
}
2828
}
2929

@@ -45,7 +45,7 @@ public unsafe MPSCnnBinaryFullyConnected (IMTLDevice device, IMPSCnnConvolutionD
4545
fixed (void* outputScaleTermsHandle = outputScaleTerms)
4646
fixed (void* inputBiasTermsHandle = inputBiasTerms)
4747
fixed (void* inputScaleTermsHandle = inputScaleTerms)
48-
InitializeHandle (InitWithDevice (device, convolutionData, (IntPtr) outputBiasTermsHandle, (IntPtr) outputScaleTermsHandle, (IntPtr) inputBiasTermsHandle, (IntPtr) inputScaleTermsHandle, type, flags));
48+
InitializeHandle (_InitWithDevice (device, convolutionData, (IntPtr) outputBiasTermsHandle, (IntPtr) outputScaleTermsHandle, (IntPtr) inputBiasTermsHandle, (IntPtr) inputScaleTermsHandle, type, flags));
4949
}
5050
}
5151
}

src/MetalPerformanceShaders/MPSEnums.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,13 @@ public enum MPSDataType : uint { // uint32_t
7373
/// <summary>Indicates 32-bit floating point format data.</summary>
7474
Float32 = FloatBit | 32,
7575

76+
[iOS (16, 2), MacCatalyst (16, 2), TV (16, 2)]
77+
ComplexBit = 0x01000000,
78+
[iOS (16, 2), MacCatalyst (16, 2), TV (16, 2)]
79+
ComplexFloat32 = FloatBit | ComplexBit | 64,
80+
[iOS (16, 2), MacCatalyst (16, 2), TV (16, 2)]
81+
ComplexFloat16 = FloatBit | ComplexBit | 32,
82+
7683
/// <summary>To be added.</summary>
7784
SignedBit = 0x20000000,
7885
[TV (18, 4), Mac (15, 4), iOS (18, 4), MacCatalyst (18, 4)]
@@ -104,6 +111,13 @@ public enum MPSDataType : uint { // uint32_t
104111
[MacCatalyst (14, 1)]
105112
UInt64 = 64,
106113

114+
[iOS (15, 0), MacCatalyst (15, 0), TV (15, 0)]
115+
AlternateEncodingBit = 0x80000000,
116+
[iOS (15, 0), MacCatalyst (15, 0), TV (15, 0)]
117+
Bool = AlternateEncodingBit | 8,
118+
[iOS (16, 0), MacCatalyst (16, 0), TV (16, 0), Mac (14, 0)]
119+
BFloat16 = AlternateEncodingBit | Float16,
120+
107121
/// <summary>To be added.</summary>
108122
[MacCatalyst (13, 1)]
109123
NormalizedBit = 0x40000000,
@@ -389,6 +403,18 @@ public enum MPSIntersectionDataType : ulong {
389403
PrimitiveIndexInstanceIndex = 3,
390404
/// <summary>To be added.</summary>
391405
PrimitiveIndexInstanceIndexCoordinates = 4,
406+
407+
[iOS (15, 0), TV (15, 0), MacCatalyst (15, 0)]
408+
PrimitiveIndexBufferIndex = 5,
409+
410+
[iOS (15, 0), TV (15, 0), MacCatalyst (15, 0)]
411+
PrimitiveIndexBufferIndexCoordinates = 6,
412+
413+
[iOS (15, 0), TV (15, 0), MacCatalyst (15, 0)]
414+
PrimitiveIndexBufferIndexInstanceIndex = 7,
415+
416+
[iOS (15, 0), TV (15, 0), MacCatalyst (15, 0)]
417+
PrimitiveIndexBufferIndexInstanceIndexCoordinates = 8,
392418
}
393419

394420
[MacCatalyst (13, 1)]

src/MetalPerformanceShaders/MPSImageBatch.cs

Lines changed: 34 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -84,52 +84,39 @@ public static nuint GetResourceSize (NSArray<MPSImage> imageBatch)
8484
return size;
8585
}
8686

87-
// TODO: Disabled due to 'MPSImageBatchIterate' is not in the native library rdar://47282304.
88-
//[DllImport (Constants.MetalPerformanceShadersLibrary)]
89-
//static extern nint MPSImageBatchIterate (IntPtr batch, IntPtr iterator);
90-
91-
//public delegate nint MPSImageBatchIterator (MPSImage image, nuint index);
92-
93-
//[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
94-
//internal delegate nint DMPSImageBatchIterator (IntPtr block, IntPtr image, nuint index);
95-
96-
//// This class bridges native block invocations that call into C#
97-
//static internal class MPSImageBatchIteratorTrampoline {
98-
// static internal readonly DMPSImageBatchIterator Handler = Invoke;
99-
100-
// [MonoPInvokeCallback (typeof (DMPSImageBatchIterator))]
101-
// static unsafe nint Invoke (IntPtr block, IntPtr image, nuint index)
102-
// {
103-
// var descriptor = (BlockLiteral *) block;
104-
// var del = (MPSImageBatchIterator) descriptor->Target;
105-
// nint retval;
106-
// using (var img = Runtime.GetNSObject<MPSImage> (image)) {
107-
// retval = del (img, index);
108-
// }
109-
// return retval;
110-
// }
111-
//}
112-
113-
//[BindingImpl (BindingImplOptions.Optimizable)]
114-
//public static nint Iterate (NSArray<MPSImage> imageBatch, MPSImageBatchIterator iterator)
115-
//{
116-
// if (imageBatch is null)
117-
// ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (imageBatch));
118-
// if (iterator is null)
119-
// ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (iterator));
120-
// unsafe {
121-
// BlockLiteral* block_ptr_iterator;
122-
// BlockLiteral block_iterator;
123-
// block_iterator = new BlockLiteral ();
124-
// block_ptr_iterator = &block_iterator;
125-
// block_iterator.SetupBlockUnsafe (MPSImageBatchIteratorTrampoline.Handler, iterator);
126-
127-
// nint ret = MPSImageBatchIterate (imageBatch.Handle, (IntPtr) block_ptr_iterator);
128-
129-
// block_ptr_iterator->CleanupBlock ();
130-
131-
// return ret;
132-
// }
133-
//}
87+
[DllImport (Constants.MetalPerformanceShadersLibrary)]
88+
unsafe static extern nint MPSImageBatchIterate (IntPtr batch, BlockLiteral* iterator);
89+
90+
public delegate nint MPSImageBatchIterator (MPSImage image, nuint index);
91+
92+
[UnmanagedCallersOnly]
93+
static unsafe nint InvokeIterator (IntPtr block, IntPtr image, nuint index)
94+
{
95+
var del = (MPSImageBatchIterator) BlockLiteral.GetTarget<MPSImageBatchIterator> (block);
96+
if (del is not null) {
97+
using var img = Runtime.GetNSObject<MPSImage> (image)!;
98+
return del (img, index);
99+
}
100+
return 0;
101+
}
102+
103+
/// <summary>Iterate over the unique images in the image batch.</summary>
104+
/// <param name="imageBatch">The batch of images to iterate over.</param>
105+
/// <param name="iterator">The callback to call for each unique image.</param>
106+
/// <returns>The value returned by the callback for the last image iterated over.</returns>
107+
[BindingImpl (BindingImplOptions.Optimizable)]
108+
public static nint Iterate (NSArray<MPSImage> imageBatch, MPSImageBatchIterator iterator)
109+
{
110+
if (iterator is null)
111+
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (iterator));
112+
113+
unsafe {
114+
delegate* unmanaged<IntPtr, IntPtr, nuint, nint> trampoline = &InvokeIterator;
115+
using var block = new BlockLiteral (trampoline, iterator, typeof (MPSImageBatch), nameof (InvokeIterator));
116+
var rv = MPSImageBatchIterate (imageBatch.GetNonNullHandle (nameof (imageBatch)), &block);
117+
GC.KeepAlive (imageBatch);
118+
return rv;
119+
}
120+
}
134121
}
135122
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
#nullable enable
5+
6+
7+
using System;
8+
9+
using Foundation;
10+
using Metal;
11+
using ObjCRuntime;
12+
13+
namespace MetalPerformanceShaders {
14+
partial class MPSImageCanny {
15+
/// <summary>Create a new <see cref="MPSImageCanny" /> instance.</summary>
16+
/// <param name="device">The device where the filter will run.</param>
17+
/// <param name="transform">An array of 3 floats that describe how to transform rgb pixels to monochrome pixels.</param>
18+
/// <param name="sigma">The standard deviation of a gaussian blur filter.</param>
19+
public MPSImageCanny (IMTLDevice device, float [] transform, float sigma)
20+
: this (NSObjectFlag.Empty)
21+
{
22+
if (transform is null)
23+
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (transform));
24+
if (transform.Length < 3)
25+
ObjCRuntime.ThrowHelper.ThrowArgumentOutOfRangeException (nameof (transform), $"Length must be at least '3'.");
26+
27+
unsafe {
28+
fixed (float* transformPtr = transform) {
29+
InitializeHandle (_InitWithDevice (device, (IntPtr) transformPtr, sigma), "initWithDevice:linearToGrayScaleTransform:sigma:");
30+
}
31+
}
32+
}
33+
34+
/// <summary>Get an array with the 3 floats values that describe how to transform rgb pixels to monochrome pixels.</summary>
35+
public float [] ColorTransform {
36+
get {
37+
var rv = new float [3];
38+
unsafe {
39+
fixed (float* ptr = rv)
40+
NativeMemory.Copy ((void*) WeakColorTransform, ptr, (nuint) (sizeof (float) * rv.Length));
41+
}
42+
return rv;
43+
}
44+
}
45+
}
46+
}

src/MetalPerformanceShaders/MPSNNGraph.cs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
14
#nullable enable
25

36
using System;
@@ -9,14 +12,58 @@
912

1013
namespace MetalPerformanceShaders {
1114
public partial class MPSNNGraph {
15+
/// <summary>Create a new <see cref="MPSNNGraph" /> instance.</summary>
16+
/// <param name="device">The device where the filter will run.</param>
17+
/// <param name="resultImages">The last images in the graph.</param>
18+
/// <param name="resultsAreNeeded">An array of boolean for each element in the <paramref name="resultImages" /> array.</param>
19+
/// <returns>A new <see cref="MPSNNGraph" /> if successful, <see langword="null" /> otherwise.</returns>
1220
[SupportedOSPlatform ("tvos13.0")]
1321
[SupportedOSPlatform ("macos")]
1422
[SupportedOSPlatform ("ios13.0")]
1523
[SupportedOSPlatform ("maccatalyst")]
16-
public unsafe static MPSNNGraph? Create (IMTLDevice device, MPSNNImageNode [] resultImages, bool [] resultsAreNeeded)
24+
public unsafe static MPSNNGraph? Create (IMTLDevice device, MPSNNImageNode [] resultImages, bool []? resultsAreNeeded)
1725
{
18-
fixed (void* resultsAreNeededHandle = resultsAreNeeded)
19-
return Create (device, resultImages, (IntPtr) resultsAreNeededHandle);
26+
ValidateParameters (resultImages, resultsAreNeeded, out var results);
27+
28+
unsafe {
29+
fixed (void* resultsPointer = results)
30+
return Create (device, resultImages, (IntPtr) resultsPointer);
31+
}
32+
}
33+
34+
/// <summary>Create a new <see cref="MPSNNGraph" /> instance.</summary>
35+
/// <param name="device">The device where the filter will run.</param>
36+
/// <param name="resultImages">The last images in the graph.</param>
37+
/// <param name="resultsAreNeeded">An array of boolean for each element in the <paramref name="resultImages" /> array.</param>
38+
[SupportedOSPlatform ("tvos13.0")]
39+
[SupportedOSPlatform ("macos")]
40+
[SupportedOSPlatform ("ios13.0")]
41+
[SupportedOSPlatform ("maccatalyst")]
42+
public MPSNNGraph (IMTLDevice device, MPSNNImageNode [] resultImages, bool []? resultsAreNeeded)
43+
: base (NSObjectFlag.Empty)
44+
{
45+
ValidateParameters (resultImages, resultsAreNeeded, out var results);
46+
47+
unsafe {
48+
fixed (void* resultsPointer = results)
49+
InitializeHandle (_InitWithDevice (device, resultImages, (IntPtr) resultsPointer), "initWithDevice:resultImages:resultsAreNeeded:");
50+
}
51+
}
52+
53+
static void ValidateParameters (MPSNNImageNode [] resultImages, bool []? resultsAreNeeded, out byte []? results)
54+
{
55+
if (resultImages is null)
56+
ObjCRuntime.ThrowHelper.ThrowArgumentNullException (nameof (resultImages));
57+
58+
if (resultsAreNeeded is not null && resultsAreNeeded.Length < resultImages.Length)
59+
ObjCRuntime.ThrowHelper.ThrowArgumentOutOfRangeException (nameof (resultsAreNeeded), "The length of 'resultsAreNeeded' must be at least as much as the length of 'resultImages' (or null).");
60+
61+
results = null;
62+
if (resultsAreNeeded is not null) {
63+
results = new byte [resultsAreNeeded.Length];
64+
for (var i = 0; i < resultsAreNeeded.Length; i++)
65+
results [i] = resultsAreNeeded [i].AsByte ();
66+
}
2067
}
2168
}
2269
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright (c) Microsoft Corporation.
2+
// Licensed under the MIT License.
3+
4+
#nullable enable
5+
6+
using System;
7+
8+
using Foundation;
9+
using Metal;
10+
using ObjCRuntime;
11+
12+
namespace MetalPerformanceShaders {
13+
partial class MPSNNOptimizerStochasticGradientDescent {
14+
#if !XAMCORE_5_0
15+
/// <summary>Create a new <see cref="MPSNNOptimizerStochasticGradientDescent" /> instance.</summary>
16+
/// <param name="device">The device where the filter will run.</param>
17+
/// <param name="momentumScale">The scale to use when updating the momentum for the values.</param>
18+
/// <param name="useNestrovMomentum">The Nesterov-style momentum update.</param>
19+
/// <param name="optimizerDescriptor">Any additional properties to apply.</param>
20+
public MPSNNOptimizerStochasticGradientDescent (IMTLDevice device, float momentumScale, bool useNestrovMomentum, MPSNNOptimizerDescriptor optimizerDescriptor)
21+
#else
22+
/// <summary>Create a new <see cref="MPSNNOptimizerStochasticGradientDescent" /> instance.</summary>
23+
/// <param name="device">The device where the filter will run.</param>
24+
/// <param name="momentumScale">The scale to use when updating the momentum for the values.</param>
25+
/// <param name="useNesterovMomentum">The Nesterov-style momentum update.</param>
26+
/// <param name="optimizerDescriptor">Any additional properties to apply.</param>
27+
public MPSNNOptimizerStochasticGradientDescent (IMTLDevice device, float momentumScale, bool useNesterovMomentum, MPSNNOptimizerDescriptor optimizerDescriptor)
28+
#endif
29+
: this (NSObjectFlag.Empty)
30+
{
31+
#if !XAMCORE_5_0
32+
var useNesterovMomentum = useNestrovMomentum;
33+
#endif
34+
35+
if (!SystemVersion.IsAtLeastXcode12) {
36+
InitializeHandle (_InitWithNestrovMomentum (device, momentumScale, useNesterovMomentum, optimizerDescriptor), "initWithDevice:momentumScale:useNestrovMomentum:optimizerDescriptor:");
37+
return;
38+
}
39+
40+
InitializeHandle (_InitWithNesterovMomentum (device, momentumScale, useNesterovMomentum, optimizerDescriptor), "initWithDevice:momentumScale:useNestrovMomentum:optimizerDescriptor:");
41+
}
42+
}
43+
}

0 commit comments

Comments
 (0)