Skip to content

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

Merged
merged 7 commits into from
Dec 13, 2018
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
3 changes: 2 additions & 1 deletion src/Microsoft.ML.Core/CommandLine/CmdLexer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,8 @@ public static string UnquoteValue(string str)
}
}

public sealed class CmdQuoter
[BestFriend]
internal sealed class CmdQuoter
{
private readonly string _str;
private StringBuilder _sb;
Expand Down
14 changes: 4 additions & 10 deletions src/Microsoft.ML.Core/CommandLine/CmdParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -537,16 +537,10 @@ private static ArgumentInfo GetArgumentInfo(Type type, object defaults)

private static ArgumentAttribute GetAttribute(FieldInfo field)
{
var attrs = field.GetCustomAttributes(typeof(ArgumentAttribute), false).ToArray();
if (attrs.Length == 1)
{
var argumentAttribute = (ArgumentAttribute)attrs[0];
if (argumentAttribute.Visibility == ArgumentAttribute.VisibilityType.EntryPointsOnly)
return null;
return argumentAttribute;
}
Contracts.Assert(attrs.Length == 0);
return null;
var argumentAttribute = field.GetCustomAttribute<ArgumentAttribute>(false);
if (argumentAttribute?.Visibility == ArgumentAttribute.VisibilityType.EntryPointsOnly)
return null;
return argumentAttribute;
}

private void ReportUnrecognizedArgument(string argument)
Expand Down
81 changes: 54 additions & 27 deletions src/Microsoft.ML.Core/ComponentModel/ComponentCatalog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Copy link
Member

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.

Copy link
Contributor Author

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.

{
public readonly string Name;
public readonly string Description;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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();
}
Expand All @@ -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);
Expand All @@ -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");
Expand All @@ -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();

Expand All @@ -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.
Expand All @@ -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);
Expand All @@ -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)
Copy link
Member

Choose a reason for hiding this comment

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

same as above, they could prove useful a public.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

AFAIK, the plan around ComponentCatalog is that the only publicly accessible member on it will be the thing to register assemblies, as well as whatever we wind up doing to register for custom transformers, right?

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));
Expand All @@ -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");
Expand All @@ -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");
Expand All @@ -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");
Expand All @@ -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");
Expand All @@ -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.
Expand All @@ -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))
Expand Down Expand Up @@ -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;
Expand All @@ -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));
Expand Down
3 changes: 2 additions & 1 deletion src/Microsoft.ML.Core/ComponentModel/ComponentFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ public interface IComponentFactory<in TArg1, in TArg2, in TArg3, out TComponent>
/// <summary>
/// A utility class for creating <see cref="IComponentFactory"/> instances.
/// </summary>
public static class ComponentFactoryUtils
[BestFriend]
internal static class ComponentFactoryUtils
{
/// <summary>
/// Creates a component factory with no extra parameters (other than an <see cref="IHostEnvironment"/>)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ namespace Microsoft.ML.Runtime
/// <summary>
/// Common signature type with no extra parameters.
/// </summary>
public delegate void SignatureDefault();
[BestFriend]
internal delegate void SignatureDefault();

[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
public sealed class LoadableClassAttribute : LoadableClassAttributeBase
[BestFriend]
internal sealed class LoadableClassAttribute : LoadableClassAttributeBase
{
/// <summary>
/// Assembly attribute used to specify that a class is loadable by a machine learning
Expand Down Expand Up @@ -98,7 +100,7 @@ public LoadableClassAttribute(string summary, Type instType, Type loaderType, Ty
}
}

public abstract class LoadableClassAttributeBase : Attribute
internal abstract class LoadableClassAttributeBase : Attribute
{
// Note: these properties have private setters to make attribute parsing easier - the values
// are all guaranteed to be in the ConstructorArguments of the CustomAttributeData
Expand Down
3 changes: 2 additions & 1 deletion src/Microsoft.ML.Core/Data/DataKind.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ public enum DataKind : byte
/// <summary>
/// Extension methods related to the DataKind enum.
/// </summary>
public static class DataKindExtensions
[BestFriend]
internal static class DataKindExtensions
{
public const DataKind KindMin = DataKind.I1;
public const DataKind KindLim = DataKind.U16 + 1;
Expand Down
3 changes: 2 additions & 1 deletion src/Microsoft.ML.Core/Data/IHostEnvironment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ public interface IChannel : IPipe<ChannelMessage>
/// that do not belong in more specific areas, for example, <see cref="Contracts"/> or
/// component creation.
/// </summary>
public static class HostExtensions
[BestFriend]
internal static class HostExtensions
{
public static T Apply<T>(this IHost host, string channelName, Func<IChannel, T> func)
{
Expand Down
6 changes: 4 additions & 2 deletions src/Microsoft.ML.Core/Data/IValueMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ namespace Microsoft.ML.Runtime.Data
/// <summary>
/// Delegate type to map/convert a value.
/// </summary>
public delegate void ValueMapper<TSrc, TDst>(in TSrc src, ref TDst dst);
[BestFriend]
internal delegate void ValueMapper<TSrc, TDst>(in TSrc src, ref TDst dst);

/// <summary>
/// Delegate type to map/convert among three values, for example, one input with two
/// outputs, or two inputs with one output.
/// </summary>
public delegate void ValueMapper<TVal1, TVal2, TVal3>(in TVal1 val1, ref TVal2 val2, ref TVal3 val3);
[BestFriend]
internal delegate void ValueMapper<TVal1, TVal2, TVal3>(in TVal1 val1, ref TVal2 val2, ref TVal3 val3);

/// <summary>
/// Interface for mapping a single input value (of an indicated ColumnType) to
Expand Down
3 changes: 2 additions & 1 deletion src/Microsoft.ML.Core/Data/RoleMappedSchema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,8 @@ public RoleMappedSchema(Schema schema, string label, string feature,
/// Note that the schema of <see cref="RoleMappedSchema.Schema"/> of <see cref="Schema"/> is
/// guaranteed to equal the the <see cref="IDataView.Schema"/> of <see cref="Data"/>.
/// </summary>
public sealed class RoleMappedData
[BestFriend]
internal sealed class RoleMappedData
{
/// <summary>
/// The data.
Expand Down
14 changes: 0 additions & 14 deletions src/Microsoft.ML.Core/EntryPoints/IMlState.cs

This file was deleted.

Loading