Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CoreML] Add Xcode 9 Beta 1 bindings #2275

Merged
merged 7 commits into from
Jun 30, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Constants.iOS.cs.in
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
}
3 changes: 3 additions & 0 deletions src/Constants.mac.cs.in
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
}
1 change: 1 addition & 0 deletions src/Constants.tvos.cs.in
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
}
4 changes: 3 additions & 1 deletion src/Constants.watch.cs.in
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
}
25 changes: 25 additions & 0 deletions src/CoreML/MLDictionaryFeatureProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// MLDictionaryFeatureProvider.cs
//
// Authors:
// Alex Soto <alexsoto@microsoft.com>
//
// 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
32 changes: 32 additions & 0 deletions src/CoreML/MLMultiArray.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
//
// MLMultiArray.cs
//
// Authors:
// Alex Soto <alexsoto@microsoft.com>
//
// 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
1 change: 1 addition & 0 deletions src/Foundation/NSObject.mac.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
270 changes: 270 additions & 0 deletions src/coreml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,270 @@
//
// CoreML C# bindings
//
// Authors:
// Alex Soto <alexsoto@microsoft.com>
//
// 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 {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whitespace. Same applies to the rest of the new interfaces

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I always leave a Whitespace between the interface line definition and the first member definition and this is the first time I've been called out :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a single empty line is fine to delimit code and help readability
whitespace changes are specially bad when updating files since they make larger diffs and contaminate git history/blame

[Export ("dictionary")]
NSDictionary<NSString, MLFeatureValue> Dictionary { get; }

[Export ("initWithDictionary:error:")]
IntPtr Constructor (NSDictionary<NSString, NSObject> 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<NSString> 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<NSObject, NSNumber> 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);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not the name it FromUndefined to match other static methods ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Br my reading, It's creating an undefined feature value from a feature type. Normally it'd just be "fromThpe", but needs something to indicate the "undefined" part

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@spouliot What @timrisi said, just extending a little

The selector name is undefinedFeatureValueWithType: which from my reading states that you will get an undefined feature from the given type so FromUndefined from my reading says that what is undefined is the type parameter, not the object I am getting back that is why I think CreateUndefined matches a little better the intent of the above selector (give me an undefined object with the following type).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense but let's double check if Apple documentation is available (and match).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From docs:

Declares a value as undefined.

From Headers:

Represent an undefined value of a specified type

@spouliot should I change it? I think the later makes sense with CreateUndefined. Naming is hard heh.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right :) Create makes more sense, it's the output (not in input) that's undefined.


[Static]
[Export ("featureValueWithDictionary:error:")]
[return: NullAllowed]
MLFeatureValue FromDictionary (NSDictionary<NSObject, NSNumber> 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<NSString, MLFeatureDescription> InputDescriptionsByName { get; }

[Export ("outputDescriptionsByName")]
NSDictionary<NSString, MLFeatureDescription> 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")]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could/should this use BindAs (does BindAs support NSNumber arrays)?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, docs are not clear on the type we should use here nor is swift
var shape: [NSNumber]

NSNumber [] Shape { get; }

[Export ("strides")]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, docs are not clear on the type we should use here nor is swift
var strides: [NSNumber]

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<IntPtr> 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
3 changes: 3 additions & 0 deletions src/frameworks.sources
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down Expand Up @@ -1528,6 +1530,7 @@ SHARED_SOURCES = \
COMMON_FRAMEWORKS = \
AVFoundation \
CoreFoundation \
CoreML \
Foundation \
GameKit \
SceneKit \
Expand Down
Loading