diff --git a/src/Constants.iOS.cs.in b/src/Constants.iOS.cs.in index 64fecf3cdf25..3e6d172685d8 100644 --- a/src/Constants.iOS.cs.in +++ b/src/Constants.iOS.cs.in @@ -111,5 +111,6 @@ namespace MonoTouch { public const string CoreNFCLibrary = "/System/Library/Frameworks/CoreNFC.framework/CoreNFC"; public const string DeviceCheckLibrary = "/System/Library/Frameworks/DeviceCheck.framework/DeviceCheck"; public const string IdentityLookupLibrary = "/System/Library/Frameworks/IdentityLookup.framework/IdentityLookup"; + public const string CoreMLLibrary = "/System/Library/Frameworks/CoreML.framework/CoreML"; } } diff --git a/src/Constants.mac.cs.in b/src/Constants.mac.cs.in index 629560446c24..d69aa27fa623 100644 --- a/src/Constants.mac.cs.in +++ b/src/Constants.mac.cs.in @@ -125,5 +125,8 @@ namespace MonoMac { public const string PhotosLibrary = "/System/Library/Frameworks/Photos.framework/Photos"; public const string IntentsLibrary = "/System/Library/Frameworks/Intents.framework/Intents"; public const string MediaPlayerLibrary = "/System/Library/Frameworks/MediaPlayer.framework/MediaPlayer"; + + // macOS 10.13 + public const string CoreMLLibrary = "/System/Library/Frameworks/CoreML.framework/CoreML"; } } diff --git a/src/Constants.tvos.cs.in b/src/Constants.tvos.cs.in index 975d60f9bcba..7e44a6684bbc 100644 --- a/src/Constants.tvos.cs.in +++ b/src/Constants.tvos.cs.in @@ -71,5 +71,6 @@ namespace ObjCRuntime { public const string VideoToolboxLibrary = "/System/Library/Frameworks/VideoToolbox.framework/VideoToolbox"; // tvOS 11.0 public const string DeviceCheckLibrary = "/System/Library/Frameworks/DeviceCheck.framework/DeviceCheck"; + public const string CoreMLLibrary = "/System/Library/Frameworks/CoreML.framework/CoreML"; } } diff --git a/src/Constants.watch.cs.in b/src/Constants.watch.cs.in index df181fa9691a..475ce36c526e 100644 --- a/src/Constants.watch.cs.in +++ b/src/Constants.watch.cs.in @@ -42,6 +42,8 @@ namespace ObjCRuntime { // WatchOS 3.2 public const string IntentsLibrary = "/System/Library/Frameworks/Intents.framework/Intents"; - + + // WatchOS 4.0 + public const string CoreMLLibrary = "/System/Library/Frameworks/CoreML.framework/CoreML"; } } diff --git a/src/CoreML/MLDictionaryFeatureProvider.cs b/src/CoreML/MLDictionaryFeatureProvider.cs new file mode 100644 index 000000000000..b426a8d4395a --- /dev/null +++ b/src/CoreML/MLDictionaryFeatureProvider.cs @@ -0,0 +1,25 @@ +// +// MLDictionaryFeatureProvider.cs +// +// Authors: +// Alex Soto +// +// Copyright 2017 Xamarin Inc. All rights reserved. +// + +#if XAMCORE_2_0 + +using System; +using XamCore.Foundation; +using XamCore.ObjCRuntime; + +namespace XamCore.CoreML { + public partial class MLDictionaryFeatureProvider { + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + public MLFeatureValue this [string featureName] { + get { return GetFeatureValue (featureName); } + } + } +} +#endif diff --git a/src/CoreML/MLMultiArray.cs b/src/CoreML/MLMultiArray.cs new file mode 100644 index 000000000000..d4557f599105 --- /dev/null +++ b/src/CoreML/MLMultiArray.cs @@ -0,0 +1,32 @@ +// +// MLMultiArray.cs +// +// Authors: +// Alex Soto +// +// Copyright 2017 Xamarin Inc. All rights reserved. +// + +#if XAMCORE_2_0 + +using System; +using XamCore.Foundation; +using XamCore.ObjCRuntime; + +namespace XamCore.CoreML { + public partial class MLMultiArray { + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + public NSNumber this [nint idx] { + get { return GetObject (idx); } + set { SetObject (value, idx); } + } + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + public NSNumber this [NSNumber [] key] { + get { return GetObject (key); } + set { SetObject (value, key); } + } + } +} +#endif diff --git a/src/Foundation/NSObject.mac.cs b/src/Foundation/NSObject.mac.cs index 74a4225d1d7c..97d72118c263 100644 --- a/src/Foundation/NSObject.mac.cs +++ b/src/Foundation/NSObject.mac.cs @@ -97,6 +97,7 @@ public partial class NSObject : INativeObject static IntPtr pl = Dlfcn.dlopen (Constants.PhotosLibrary, 1); static IntPtr mp = Dlfcn.dlopen (Constants.MediaPlayerLibrary, 1); static IntPtr pc = Dlfcn.dlopen (Constants.PrintCoreLibrary, 1); + static IntPtr cml = Dlfcn.dlopen (Constants.CoreMLLibrary, 1); #endif // ** IF YOU ADD ITEMS HERE PLEASE UPDATE linker/ObjCExtensions.cs and mmp/linker/MonoMac.Tuner/MonoMacNamespaces.cs diff --git a/src/coreml.cs b/src/coreml.cs new file mode 100644 index 000000000000..2e362210f2bd --- /dev/null +++ b/src/coreml.cs @@ -0,0 +1,270 @@ +// +// CoreML C# bindings +// +// Authors: +// Alex Soto +// +// Copyright 2017 Xamarin Inc. All rights reserved. +// + +#if XAMCORE_2_0 + +using System; +using XamCore.ObjCRuntime; +using XamCore.CoreFoundation; +using XamCore.Foundation; + +#if !WATCH +using XamCore.CoreVideo; +#endif + +namespace XamCore.CoreML { + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + [Native] + public enum MLFeatureType : nint { + Invalid = 0, + Int64 = 1, + Double = 2, + String = 3, + Image = 4, + MultiArray = 5, + Dictionary = 6 + } + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + [ErrorDomain ("MLModelErrorDomain")] + [Native] + public enum MLModelError : nint { + Generic = 0, + FeatureType = 1, + DescriptionMismatch = 2, + Io = 3 + } + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + [Native] + public enum MLMultiArrayDataType : nint { + Double = 65536 | 64, + Float32 = 65536 | 32, + Int32 = 131072 | 32 + } + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + [BaseType (typeof (NSObject))] + interface MLDictionaryFeatureProvider : MLFeatureProvider { + + [Export ("dictionary")] + NSDictionary Dictionary { get; } + + [Export ("initWithDictionary:error:")] + IntPtr Constructor (NSDictionary dictionary, out NSError error); + } + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + [BaseType (typeof (NSObject))] + interface MLFeatureDescription : NSCopying { + + [Export ("name")] + string Name { get; } + + [Export ("type")] + MLFeatureType Type { get; } + + [Export ("optional")] + bool Optional { [Bind ("isOptional")] get; } + + [Export ("isAllowedValue:")] + bool IsAllowed (MLFeatureValue value); + } + + interface IMLFeatureProvider { } + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + [Protocol] + interface MLFeatureProvider { + + [Abstract] + [Export ("featureNames")] + NSSet FeatureNames { get; } + + [Abstract] + [Export ("featureValueForName:")] + [return: NullAllowed] + MLFeatureValue GetFeatureValue (string featureName); + } + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + [BaseType (typeof (NSObject))] + interface MLFeatureValue : NSCopying { + + [Export ("type")] + MLFeatureType Type { get; } + + [Export ("undefined")] + bool Undefined { [Bind ("isUndefined")] get; } + + [Export ("int64Value")] + long Int64Value { get; } + + [Export ("doubleValue")] + double DoubleValue { get; } + + [Export ("stringValue")] + string StringValue { get; } + + [NullAllowed, Export ("multiArrayValue")] + MLMultiArray MultiArrayValue { get; } + + [Export ("dictionaryValue")] + NSDictionary DictionaryValue { get; } + +#if !WATCH + [NullAllowed, Export ("imageBufferValue")] + CVPixelBuffer ImageBufferValue { get; } + + [Static] + [Export ("featureValueWithPixelBuffer:")] + MLFeatureValue FromPixelBuffer (CVPixelBuffer value); +#endif + [Static] + [Export ("featureValueWithInt64:")] + MLFeatureValue FromInt64 (long value); + + [Static] + [Export ("featureValueWithDouble:")] + MLFeatureValue FromDouble (double value); + + [Static] + [Export ("featureValueWithString:")] + MLFeatureValue FromString (string value); + + [Static] + [Export ("featureValueWithMultiArray:")] + MLFeatureValue FromMultiArray (MLMultiArray value); + + [Static] + [Export ("undefinedFeatureValueWithType:")] + MLFeatureValue CreateUndefined (MLFeatureType type); + + [Static] + [Export ("featureValueWithDictionary:error:")] + [return: NullAllowed] + MLFeatureValue FromDictionary (NSDictionary value, out NSError error); + + [Export ("isEqualToFeatureValue:")] + bool IsEqual (MLFeatureValue value); + } + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + [BaseType (typeof (NSObject))] + interface MLModel { + + [Export ("modelDescription")] + MLModelDescription ModelDescription { get; } + + [Static] + [Export ("modelWithContentsOfURL:error:")] + [return: NullAllowed] + MLModel FromUrl (NSUrl url, [NullAllowed] out NSError error); + + [Export ("predictionFromFeatures:error:")] + [return: NullAllowed] + IMLFeatureProvider GetPrediction (IMLFeatureProvider input, out NSError error); + } + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + [BaseType (typeof (NSObject))] + interface MLModelDescription { + + [Export ("inputDescriptionsByName")] + NSDictionary InputDescriptionsByName { get; } + + [Export ("outputDescriptionsByName")] + NSDictionary OutputDescriptionsByName { get; } + + [NullAllowed, Export ("predictedFeatureName")] + string PredictedFeatureName { get; } + + [NullAllowed, Export ("predictedProbabilitiesName")] + string PredictedProbabilitiesName { get; } + + [Export ("metadata")] + [Internal] + NSDictionary _Metadata { get; } + + [Wrap ("_Metadata")] + MLModelMetadata Metadata { get; } + } + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + [Internal] + [Static] + interface MLModelMetadataKeys { + + [Field ("MLModelDescriptionKey")] + NSString DescriptionKey { get; } + + [Field ("MLModelVersionStringKey")] + NSString VersionStringKey { get; } + + [Field ("MLModelAuthorKey")] + NSString AuthorKey { get; } + + [Field ("MLModelLicenseKey")] + NSString LicenseKey { get; } + } + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + [StrongDictionary ("MLModelMetadataKeys")] + interface MLModelMetadata { + string Description { get; } + string VersionString { get; } + string Author { get; } + string License { get; } + } + + [Watch (4,0), TV (11,0), Mac (10,13, onlyOn64: true), iOS (11,0)] + [DisableDefaultCtor] + [BaseType (typeof (NSObject))] + interface MLMultiArray { + + [Export ("dataPointer")] + IntPtr DataPointer { get; } + + [Export ("dataType")] + MLMultiArrayDataType DataType { get; } + + [Export ("shape")] + NSNumber [] Shape { get; } + + [Export ("strides")] + NSNumber [] Strides { get; } + + [Export ("count")] + nint Count { get; } + + // From MLMultiArray (Creation) Category + + [Export ("initWithShape:dataType:error:")] + IntPtr Constructor (NSNumber [] shape, MLMultiArrayDataType dataType, out NSError error); + + [Export ("initWithDataPointer:shape:dataType:strides:deallocator:error:")] + IntPtr Constructor (IntPtr dataPointer, NSNumber [] shape, MLMultiArrayDataType dataType, NSNumber [] strides, Action deallocator, out NSError error); + + // From MLMultiArray (NSNumberDataAccess) Category + + [Export ("objectAtIndexedSubscript:")] + NSNumber GetObject (nint idx); + + [Export ("objectForKeyedSubscript:")] + NSNumber GetObject (NSNumber [] key); + + [Export ("setObject:atIndexedSubscript:")] + void SetObject (NSNumber obj, nint idx); + + [Export ("setObject:forKeyedSubscript:")] + void SetObject (NSNumber obj, NSNumber [] key); + } +} +#endif // XAMCORE_2_0 diff --git a/src/frameworks.sources b/src/frameworks.sources index 5f6e48608b9e..c15350fd7b3e 100644 --- a/src/frameworks.sources +++ b/src/frameworks.sources @@ -1477,6 +1477,8 @@ SHARED_SOURCES = \ ../runtime/Delegates.generated.cs \ MonoNativeFunctionWrapperAttribute.cs \ NativeTypes/NMath.cs \ + CoreML/MLDictionaryFeatureProvider.cs \ + CoreML/MLMultiArray.cs \ ObjCRuntime/AdoptsAttribute.cs \ ObjCRuntime/BackingField.cs \ ObjCRuntime/BaseWrapper.cs \ @@ -1528,6 +1530,7 @@ SHARED_SOURCES = \ COMMON_FRAMEWORKS = \ AVFoundation \ CoreFoundation \ + CoreML \ Foundation \ GameKit \ SceneKit \ diff --git a/tests/xtro-sharpie/common.pending b/tests/xtro-sharpie/common.pending index ca4145edfd70..a429e4757e49 100644 --- a/tests/xtro-sharpie/common.pending +++ b/tests/xtro-sharpie/common.pending @@ -648,4 +648,9 @@ !incorrect-protocol-member! MDLObjectContainerComponent::objectAtIndexedSubscript: is REQUIRED and should be abstract !incorrect-protocol-member! MDLTransformComponent::keyTimes is REQUIRED and should be abstract !incorrect-protocol-member! MDLTransformComponent::resetsTransform is REQUIRED and should be abstract -!incorrect-protocol-member! MDLTransformComponent::setResetsTransform: is REQUIRED and should be abstract \ No newline at end of file +!incorrect-protocol-member! MDLTransformComponent::setResetsTransform: is REQUIRED and should be abstract + +# CoreML +## we do not have NSFastEnumeration and decided to not bind objectForKeyedSubscript using a local method instead +!missing-protocol-conformance! MLDictionaryFeatureProvider should conform to NSFastEnumeration +!missing-selector! MLDictionaryFeatureProvider::objectForKeyedSubscript: not bound \ No newline at end of file diff --git a/tools/common/Frameworks.cs b/tools/common/Frameworks.cs index 56e35a91c5f2..5222e0b7036c 100644 --- a/tools/common/Frameworks.cs +++ b/tools/common/Frameworks.cs @@ -138,6 +138,8 @@ public static Frameworks MacFrameworks { { "Intents", 10, 12 }, { "SafariServices", "SafariServices", 10, 12 }, { "MediaPlayer", "MediaPlayer", 10, 12, 1 }, + + { "CoreML", "CoreML", 10, 13 }, }; } return mac_frameworks; @@ -246,6 +248,7 @@ public static Frameworks GetiOSFrameworks (Application app) { "CoreNFC", "CoreNFC", 11 }, { "DeviceCheck", "DeviceCheck", 11 }, { "IdentityLookup", "IdentityLookup", 11 }, + { "CoreML", "CoreML", 11 }, }; } return ios_frameworks; @@ -286,6 +289,8 @@ public static Frameworks GetwatchOSFrameworks (Application app) { "SpriteKit", "SpriteKit", 3 }, { "UserNotifications", "UserNotifications", 3 }, { "Intents", "Intents", 3,2 }, + + { "CoreML", "CoreML", 4 }, }; } return watch_frameworks; @@ -351,6 +356,7 @@ public static Frameworks TVOSFrameworks { { "VideoToolbox", "VideoToolbox", 10,2 }, { "DeviceCheck", "DeviceCheck", 11 }, + { "CoreML", "CoreML", 11 }, }; } return tvos_frameworks; diff --git a/tools/linker/ObjCExtensions.cs b/tools/linker/ObjCExtensions.cs index 05ca8540c5fc..28bb6a689825 100644 --- a/tools/linker/ObjCExtensions.cs +++ b/tools/linker/ObjCExtensions.cs @@ -57,6 +57,7 @@ internal static void Initialize () ModelIO = profile.GetNamespace ("ModelIO"); Intents = profile.GetNamespace ("Intents"); Photos = profile.GetNamespace ("Photos"); + CoreML = profile.GetNamespace ("CoreML"); #if MONOMAC IOBluetooth = profile.GetNamespace ("IOBluetooth"); IOBluetoothUI = profile.GetNamespace ("IOBluetoothUI"); @@ -134,6 +135,8 @@ internal static void Initialize () public static string Photos { get; private set; } + public static string CoreML { get; private set; } + #if MONOMAC public static string IOBluetooth { get; private set; } public static string IOBluetoothUI { get; private set; } diff --git a/tools/mmp/linker/MonoMac.Tuner/MonoMacNamespaces.cs b/tools/mmp/linker/MonoMac.Tuner/MonoMacNamespaces.cs index 9a87c908e138..106b409a27e8 100644 --- a/tools/mmp/linker/MonoMac.Tuner/MonoMacNamespaces.cs +++ b/tools/mmp/linker/MonoMac.Tuner/MonoMacNamespaces.cs @@ -68,7 +68,9 @@ public class MonoMacNamespaces : IStep { { Constants.MediaPlayerLibrary, Namespaces.MediaPlayer }, { Constants.IntentsLibrary, Namespaces.Intents }, { Constants.PhotosLibrary, Namespaces.Photos }, - { Constants.PrintCoreLibrary, Namespaces.PrintCore} }; + { Constants.PrintCoreLibrary, Namespaces.PrintCore }, + { Constants.CoreMLLibrary, Namespaces.CoreML }, + }; public void Process (LinkContext context) {