-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Much more core internalization (Phase 3) #1870
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
Changes from all commits
a457ccb
6b4ce56
415e3cd
f52cade
f96af11
ba139ec
e895d4c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,7 +40,8 @@ internal ComponentCatalog() | |
/// <summary> | ||
/// Provides information on an instantiatable component, aka, loadable class. | ||
/// </summary> | ||
public sealed class LoadableClassInfo | ||
[BestFriend] | ||
internal sealed class LoadableClassInfo | ||
{ | ||
/// <summary> | ||
/// Used for dictionary lookup based on signature and name. | ||
|
@@ -264,7 +265,8 @@ public object CreateArguments() | |
/// <summary> | ||
/// A description of a single entry point. | ||
/// </summary> | ||
public sealed class EntryPointInfo | ||
[BestFriend] | ||
internal sealed class EntryPointInfo | ||
{ | ||
public readonly string Name; | ||
public readonly string Description; | ||
|
@@ -333,7 +335,8 @@ private Type[] FindEntryPointKinds(Type type) | |
/// The 'component' is a non-standalone building block that is used to parametrize entry points or other ML.NET components. | ||
/// For example, 'Loss function', or 'similarity calculator' could be components. | ||
/// </summary> | ||
public sealed class ComponentInfo | ||
[BestFriend] | ||
internal sealed class ComponentInfo | ||
{ | ||
public readonly string Name; | ||
public readonly string Description; | ||
|
@@ -616,7 +619,8 @@ public void RegisterAssembly(Assembly assembly, bool throwOnError = true) | |
/// Return an array containing information for all instantiatable components. | ||
/// If provided, the given set of assemblies is loaded first. | ||
/// </summary> | ||
public LoadableClassInfo[] GetAllClasses() | ||
[BestFriend] | ||
internal LoadableClassInfo[] GetAllClasses() | ||
{ | ||
return _classes.ToArray(); | ||
} | ||
|
@@ -625,7 +629,8 @@ public LoadableClassInfo[] GetAllClasses() | |
/// Return an array containing information for instantiatable components with the given | ||
/// signature and base type. If provided, the given set of assemblies is loaded first. | ||
/// </summary> | ||
public LoadableClassInfo[] GetAllDerivedClasses(Type typeBase, Type typeSig) | ||
[BestFriend] | ||
internal LoadableClassInfo[] GetAllDerivedClasses(Type typeBase, Type typeSig) | ||
{ | ||
Contracts.CheckValue(typeBase, nameof(typeBase)); | ||
Contracts.CheckValueOrNull(typeSig); | ||
|
@@ -643,15 +648,17 @@ public LoadableClassInfo[] GetAllDerivedClasses(Type typeBase, Type typeSig) | |
/// Return an array containing all the known signature types. If provided, the given set of assemblies | ||
/// is loaded first. | ||
/// </summary> | ||
public Type[] GetAllSignatureTypes() | ||
[BestFriend] | ||
internal Type[] GetAllSignatureTypes() | ||
{ | ||
return _signatures.Select(kvp => kvp.Key).ToArray(); | ||
} | ||
|
||
/// <summary> | ||
/// Returns a string name for a given signature type. | ||
/// </summary> | ||
public static string SignatureToString(Type sig) | ||
[BestFriend] | ||
internal static string SignatureToString(Type sig) | ||
{ | ||
Contracts.CheckValue(sig, nameof(sig)); | ||
Contracts.CheckParam(sig.BaseType == typeof(MulticastDelegate), nameof(sig), "Must be a delegate type"); | ||
|
@@ -670,7 +677,8 @@ private LoadableClassInfo FindClassCore(LoadableClassInfo.Key key) | |
return null; | ||
} | ||
|
||
public LoadableClassInfo[] FindLoadableClasses(string name) | ||
[BestFriend] | ||
internal LoadableClassInfo[] FindLoadableClasses(string name) | ||
{ | ||
name = name.ToLowerInvariant().Trim(); | ||
|
||
|
@@ -680,14 +688,16 @@ public LoadableClassInfo[] FindLoadableClasses(string name) | |
return res; | ||
} | ||
|
||
public LoadableClassInfo[] FindLoadableClasses<TSig>() | ||
[BestFriend] | ||
internal LoadableClassInfo[] FindLoadableClasses<TSig>() | ||
{ | ||
return _classes | ||
.Where(ci => ci.SignatureTypes.Contains(typeof(TSig))) | ||
.ToArray(); | ||
} | ||
|
||
public LoadableClassInfo[] FindLoadableClasses<TArgs, TSig>() | ||
[BestFriend] | ||
internal LoadableClassInfo[] FindLoadableClasses<TArgs, TSig>() | ||
{ | ||
// REVIEW: this and above methods perform a linear search over all the loadable classes. | ||
// On 6/15/2015, TLC release build contained 431 of them, so adding extra lookups looks unnecessary at this time. | ||
|
@@ -696,12 +706,14 @@ public LoadableClassInfo[] FindLoadableClasses<TArgs, TSig>() | |
.ToArray(); | ||
} | ||
|
||
public LoadableClassInfo GetLoadableClassInfo<TSig>(string loadName) | ||
[BestFriend] | ||
internal LoadableClassInfo GetLoadableClassInfo<TSig>(string loadName) | ||
{ | ||
return GetLoadableClassInfo(loadName, typeof(TSig)); | ||
} | ||
|
||
public LoadableClassInfo GetLoadableClassInfo(string loadName, Type signatureType) | ||
[BestFriend] | ||
internal LoadableClassInfo GetLoadableClassInfo(string loadName, Type signatureType) | ||
{ | ||
Contracts.CheckParam(signatureType.BaseType == typeof(MulticastDelegate), nameof(signatureType), "signatureType must be a delegate type"); | ||
Contracts.CheckValueOrNull(loadName); | ||
|
@@ -712,18 +724,21 @@ public LoadableClassInfo GetLoadableClassInfo(string loadName, Type signatureTyp | |
/// <summary> | ||
/// Get all registered entry points. | ||
/// </summary> | ||
public IEnumerable<EntryPointInfo> AllEntryPoints() | ||
[BestFriend] | ||
internal IEnumerable<EntryPointInfo> AllEntryPoints() | ||
{ | ||
return _entryPoints.AsEnumerable(); | ||
} | ||
|
||
public bool TryFindEntryPoint(string name, out EntryPointInfo entryPoint) | ||
[BestFriend] | ||
internal bool TryFindEntryPoint(string name, out EntryPointInfo entryPoint) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above, they could prove useful a public. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AFAIK, the plan around I think if we go function by function by what "might" prove useful we'll identify everything as potentially useful -- after all, everything was written for a reason. I think though we might want to be a bit more picky about those scenarios we're actually trying to hit for v1. |
||
{ | ||
Contracts.CheckNonEmpty(name, nameof(name)); | ||
return _entryPointMap.TryGetValue(name, out entryPoint); | ||
} | ||
|
||
public bool TryFindComponent(string kind, string alias, out ComponentInfo component) | ||
[BestFriend] | ||
internal bool TryFindComponent(string kind, string alias, out ComponentInfo component) | ||
{ | ||
Contracts.CheckNonEmpty(kind, nameof(kind)); | ||
Contracts.CheckNonEmpty(alias, nameof(alias)); | ||
|
@@ -733,15 +748,17 @@ public bool TryFindComponent(string kind, string alias, out ComponentInfo compon | |
return _componentMap.TryGetValue($"{kind}:{alias}", out component); | ||
} | ||
|
||
public bool TryFindComponent(Type argumentType, out ComponentInfo component) | ||
[BestFriend] | ||
internal bool TryFindComponent(Type argumentType, out ComponentInfo component) | ||
{ | ||
Contracts.CheckValue(argumentType, nameof(argumentType)); | ||
|
||
component = _components.FirstOrDefault(x => x.ArgumentType == argumentType); | ||
return component != null; | ||
} | ||
|
||
public bool TryFindComponent(Type interfaceType, Type argumentType, out ComponentInfo component) | ||
[BestFriend] | ||
internal bool TryFindComponent(Type interfaceType, Type argumentType, out ComponentInfo component) | ||
{ | ||
Contracts.CheckValue(interfaceType, nameof(interfaceType)); | ||
Contracts.CheckParam(interfaceType.IsInterface, nameof(interfaceType), "Must be interface"); | ||
|
@@ -751,7 +768,8 @@ public bool TryFindComponent(Type interfaceType, Type argumentType, out Componen | |
return component != null; | ||
} | ||
|
||
public bool TryFindComponent(Type interfaceType, string alias, out ComponentInfo component) | ||
[BestFriend] | ||
internal bool TryFindComponent(Type interfaceType, string alias, out ComponentInfo component) | ||
{ | ||
Contracts.CheckValue(interfaceType, nameof(interfaceType)); | ||
Contracts.CheckParam(interfaceType.IsInterface, nameof(interfaceType), "Must be interface"); | ||
|
@@ -764,7 +782,8 @@ public bool TryFindComponent(Type interfaceType, string alias, out ComponentInfo | |
/// Akin to <see cref="TryFindComponent(Type, string, out ComponentInfo)"/>, except if the regular (case sensitive) comparison fails, it will | ||
/// attempt to back off to a case-insensitive comparison. | ||
/// </summary> | ||
public bool TryFindComponentCaseInsensitive(Type interfaceType, string alias, out ComponentInfo component) | ||
[BestFriend] | ||
internal bool TryFindComponentCaseInsensitive(Type interfaceType, string alias, out ComponentInfo component) | ||
{ | ||
Contracts.CheckValue(interfaceType, nameof(interfaceType)); | ||
Contracts.CheckParam(interfaceType.IsInterface, nameof(interfaceType), "Must be interface"); | ||
|
@@ -786,15 +805,17 @@ private static bool AnyMatch(string name, string[] aliases) | |
/// <summary> | ||
/// Returns all valid component kinds. | ||
/// </summary> | ||
public IEnumerable<string> GetAllComponentKinds() | ||
[BestFriend] | ||
internal IEnumerable<string> GetAllComponentKinds() | ||
{ | ||
return _components.Select(x => x.Kind).Distinct().OrderBy(x => x); | ||
} | ||
|
||
/// <summary> | ||
/// Returns all components of the specified kind. | ||
/// </summary> | ||
public IEnumerable<ComponentInfo> GetAllComponents(string kind) | ||
[BestFriend] | ||
internal IEnumerable<ComponentInfo> GetAllComponents(string kind) | ||
{ | ||
Contracts.CheckNonEmpty(kind, nameof(kind)); | ||
Contracts.CheckParam(IsValidName(kind), nameof(kind), "Invalid component kind"); | ||
|
@@ -804,13 +825,15 @@ public IEnumerable<ComponentInfo> GetAllComponents(string kind) | |
/// <summary> | ||
/// Returns all components that implement the specified interface. | ||
/// </summary> | ||
public IEnumerable<ComponentInfo> GetAllComponents(Type interfaceType) | ||
[BestFriend] | ||
internal IEnumerable<ComponentInfo> GetAllComponents(Type interfaceType) | ||
{ | ||
Contracts.CheckValue(interfaceType, nameof(interfaceType)); | ||
return _components.Where(x => x.InterfaceType == interfaceType).OrderBy(x => x.Name); | ||
} | ||
|
||
public bool TryGetComponentKind(Type signatureType, out string kind) | ||
[BestFriend] | ||
internal bool TryGetComponentKind(Type signatureType, out string kind) | ||
{ | ||
Contracts.CheckValue(signatureType, nameof(signatureType)); | ||
// REVIEW: replace with a dictionary lookup. | ||
|
@@ -821,7 +844,8 @@ public bool TryGetComponentKind(Type signatureType, out string kind) | |
return faceAttr != null; | ||
} | ||
|
||
public bool TryGetComponentShortName(Type type, out string name) | ||
[BestFriend] | ||
internal bool TryGetComponentShortName(Type type, out string name) | ||
{ | ||
ComponentInfo component; | ||
if (!TryFindComponent(type, out component)) | ||
|
@@ -850,7 +874,8 @@ private static bool IsValidName(string name) | |
/// <summary> | ||
/// Create an instance of the indicated component with the given extra parameters. | ||
/// </summary> | ||
public static TRes CreateInstance<TRes>(IHostEnvironment env, Type signatureType, string name, string options, params object[] extra) | ||
[BestFriend] | ||
internal static TRes CreateInstance<TRes>(IHostEnvironment env, Type signatureType, string name, string options, params object[] extra) | ||
where TRes : class | ||
{ | ||
TRes result; | ||
|
@@ -863,13 +888,15 @@ public static TRes CreateInstance<TRes>(IHostEnvironment env, Type signatureType | |
/// Try to create an instance of the indicated component and settings with the given extra parameters. | ||
/// If there is no such component in the catalog, returns false. Any other error results in an exception. | ||
/// </summary> | ||
public static bool TryCreateInstance<TRes, TSig>(IHostEnvironment env, out TRes result, string name, string options, params object[] extra) | ||
[BestFriend] | ||
internal static bool TryCreateInstance<TRes, TSig>(IHostEnvironment env, out TRes result, string name, string options, params object[] extra) | ||
where TRes : class | ||
{ | ||
return TryCreateInstance<TRes>(env, typeof(TSig), out result, name, options, extra); | ||
} | ||
|
||
private static bool TryCreateInstance<TRes>(IHostEnvironment env, Type signatureType, out TRes result, string name, string options, params object[] extra) | ||
[BestFriend] | ||
internal static bool TryCreateInstance<TRes>(IHostEnvironment env, Type signatureType, out TRes result, string name, string options, params object[] extra) | ||
where TRes : class | ||
{ | ||
Contracts.CheckValue(env, nameof(env)); | ||
|
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
heads up that if we build entry-point based tooling around ML.Net, it would be convenient to be able to access this, rather than replicate it in his own data models.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That may be @sfilipi , however this does not align with the current thinking around entry-points as I understand it, which involves (1) getting the entry-point manifest and then (2) auto-generating an API out of that manifest. Of course, we could imagine that a C# API to entry-points might be something worth having, but I generally prefer to have a solid scenario in mind before I start designing an API for it. Anyway: AFAIK it's our intention that any dependency-injection style stuff not be part of the V1 API, unless that has changed in the last week or so.