From 1bc6dadf1032246cb40661805499c04d441f350e Mon Sep 17 00:00:00 2001 From: Tom Finley <tfinley@microsoft.com> Date: Wed, 13 Jun 2018 15:01:01 -0700 Subject: [PATCH 1/2] Use HideEnumValueAttribute for both manifest and C# API generation. --- src/Microsoft.ML/CSharpApi.cs | 19 +++--------- .../JsonUtils/JsonManifestUtils.cs | 2 +- .../Internal/Tools/CSharpApiGenerator.cs | 3 ++ .../Internal/Tools/CSharpGeneratorUtils.cs | 17 +++++++++-- .../Common/EntryPoints/core_manifest.json | 30 +++---------------- 5 files changed, 27 insertions(+), 44 deletions(-) diff --git a/src/Microsoft.ML/CSharpApi.cs b/src/Microsoft.ML/CSharpApi.cs index e943e76bca..75e06f0b98 100644 --- a/src/Microsoft.ML/CSharpApi.cs +++ b/src/Microsoft.ML/CSharpApi.cs @@ -11058,14 +11058,10 @@ namespace Transforms { public enum NAHandleTransformReplacementKind { - Default = 0, - Def = 0, DefaultValue = 0, Mean = 1, Minimum = 2, - Min = 2, - Maximum = 3, - Max = 3 + Maximum = 3 } @@ -11153,7 +11149,7 @@ public void AddColumn(string outputColumn, string inputColumn) /// <summary> /// The replacement method to utilize /// </summary> - public NAHandleTransformReplacementKind ReplaceWith { get; set; } = NAHandleTransformReplacementKind.Def; + public NAHandleTransformReplacementKind ReplaceWith { get; set; } = NAHandleTransformReplacementKind.DefaultValue; /// <summary> /// Whether to impute values by slot @@ -11527,17 +11523,10 @@ namespace Transforms { public enum NAReplaceTransformReplacementKind { - Default = 0, DefaultValue = 0, - Def = 0, Mean = 1, - Min = 2, Minimum = 2, - Max = 3, - Maximum = 3, - SpecifiedValue = 4, - Val = 4, - Value = 4 + Maximum = 3 } @@ -11625,7 +11614,7 @@ public void AddColumn(string outputColumn, string inputColumn) /// <summary> /// The replacement method to utilize /// </summary> - public NAReplaceTransformReplacementKind ReplacementKind { get; set; } = NAReplaceTransformReplacementKind.Def; + public NAReplaceTransformReplacementKind ReplacementKind { get; set; } = NAReplaceTransformReplacementKind.DefaultValue; /// <summary> /// Whether to impute values by slot diff --git a/src/Microsoft.ML/Runtime/EntryPoints/JsonUtils/JsonManifestUtils.cs b/src/Microsoft.ML/Runtime/EntryPoints/JsonUtils/JsonManifestUtils.cs index 7950975a22..fd76ad8565 100644 --- a/src/Microsoft.ML/Runtime/EntryPoints/JsonUtils/JsonManifestUtils.cs +++ b/src/Microsoft.ML/Runtime/EntryPoints/JsonUtils/JsonManifestUtils.cs @@ -344,7 +344,7 @@ private static JToken BuildTypeToken(IExceptionContext ectx, FieldInfo fieldInfo case TlcModule.DataKind.Enum: jo = new JObject(); jo[FieldNames.Kind] = typeEnum.ToString(); - var values = Enum.GetNames(type); + var values = Enum.GetNames(type).Where(n => type.GetField(n).GetCustomAttribute<HideEnumValueAttribute>() == null); jo[FieldNames.Values] = new JArray(values); return jo; case TlcModule.DataKind.Array: diff --git a/src/Microsoft.ML/Runtime/Internal/Tools/CSharpApiGenerator.cs b/src/Microsoft.ML/Runtime/Internal/Tools/CSharpApiGenerator.cs index ad714a4998..db7c1d490d 100644 --- a/src/Microsoft.ML/Runtime/Internal/Tools/CSharpApiGenerator.cs +++ b/src/Microsoft.ML/Runtime/Internal/Tools/CSharpApiGenerator.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.Reflection; using Microsoft.ML.Runtime; using Microsoft.ML.Runtime.CommandLine; using Microsoft.ML.Runtime.Data; @@ -156,6 +157,8 @@ private void GenerateEnums(IndentingTextWriter writer, Type inputType, string cu for (int i = 0; i < names.Length; i++) { var name = names[i]; + if (type.GetField(name).GetCustomAttribute<HideEnumValueAttribute>() != null) + continue; var value = values.GetValue(i); writer.WriteLine(prefix); if (enumType == typeof(int)) diff --git a/src/Microsoft.ML/Runtime/Internal/Tools/CSharpGeneratorUtils.cs b/src/Microsoft.ML/Runtime/Internal/Tools/CSharpGeneratorUtils.cs index fc9fabb758..cca73a21f9 100644 --- a/src/Microsoft.ML/Runtime/Internal/Tools/CSharpGeneratorUtils.cs +++ b/src/Microsoft.ML/Runtime/Internal/Tools/CSharpGeneratorUtils.cs @@ -6,6 +6,7 @@ using System.CodeDom; using System.Collections.Generic; using System.Linq; +using System.Reflection; using Microsoft.CSharp; using Microsoft.ML.Runtime.CommandLine; using Microsoft.ML.Runtime.EntryPoints; @@ -279,10 +280,22 @@ public static string GetValue(ModuleCatalog catalog, Type fieldType, object fiel case TlcModule.DataKind.Bool: return (bool)fieldValue ? "true" : "false"; case TlcModule.DataKind.Enum: + string enumAsString = fieldValue.ToString(); + if (fieldType.GetField(enumAsString).GetCustomAttribute<HideEnumValueAttribute>() != null) + { + // The default value for the enum has the hiding attribute on it. We will search for + // alternate names. Regrettably I see no way beyond a manual scan. + + string unhiddenName = Enum.GetNames(fieldType).Zip(Enum.GetValues(fieldType).Cast<object>(), (name, val) => (name, val)) + .Where(pair => pair.val.Equals(fieldValue)) + .Where(pair => fieldType.GetField(pair.name).GetCustomAttribute<HideEnumValueAttribute>() == null) + .Select(pair => pair.name).FirstOrDefault(); + enumAsString = unhiddenName ?? throw Contracts.Except($"Could not find unhidden alternative for '{fieldValue}' in type '{fieldType}'"); + } if (generatedClasses.IsGenerated(fieldType.FullName)) - return generatedClasses.GetApiName(fieldType, rootNameSpace) + "." + fieldValue; + return generatedClasses.GetApiName(fieldType, rootNameSpace) + "." + enumAsString; else - return generatedClasses.GetApiName(fieldType, "Runtime") + "." + fieldValue; + return generatedClasses.GetApiName(fieldType, "Runtime") + "." + enumAsString; case TlcModule.DataKind.Char: return $"'{GetCharAsString((char)fieldValue)}'"; case TlcModule.DataKind.Component: diff --git a/test/BaselineOutput/Common/EntryPoints/core_manifest.json b/test/BaselineOutput/Common/EntryPoints/core_manifest.json index ea1a86a2e8..427b9c23b5 100644 --- a/test/BaselineOutput/Common/EntryPoints/core_manifest.json +++ b/test/BaselineOutput/Common/EntryPoints/core_manifest.json @@ -15390,14 +15390,10 @@ "Type": { "Kind": "Enum", "Values": [ - "Default", - "Def", "DefaultValue", "Mean", "Minimum", - "Min", - "Maximum", - "Max" + "Maximum" ] }, "Desc": "The replacement method to utilize", @@ -15478,14 +15474,10 @@ "Type": { "Kind": "Enum", "Values": [ - "Default", - "Def", "DefaultValue", "Mean", "Minimum", - "Min", - "Maximum", - "Max" + "Maximum" ] }, "Desc": "The replacement method to utilize", @@ -15780,17 +15772,10 @@ "Type": { "Kind": "Enum", "Values": [ - "Default", "DefaultValue", - "Def", "Mean", - "Min", "Minimum", - "Max", - "Maximum", - "SpecifiedValue", - "Val", - "Value" + "Maximum" ] }, "Desc": "The replacement method to utilize", @@ -15856,17 +15841,10 @@ "Type": { "Kind": "Enum", "Values": [ - "Default", "DefaultValue", - "Def", "Mean", - "Min", "Minimum", - "Max", - "Maximum", - "SpecifiedValue", - "Val", - "Value" + "Maximum" ] }, "Desc": "The replacement method to utilize", From 7f94dd0d9c4b8c76b2ffc9e46144b55e11bf3fea Mon Sep 17 00:00:00 2001 From: Tom Finley <tfinley@microsoft.com> Date: Fri, 15 Jun 2018 10:15:34 -0700 Subject: [PATCH 2/2] Unhide NAReplaceTransform.ReplacementKind.SpecifiedValue. --- src/Microsoft.ML.Transforms/NAReplaceTransform.cs | 3 +-- src/Microsoft.ML/CSharpApi.cs | 3 ++- test/BaselineOutput/Common/EntryPoints/core_manifest.json | 8 +++++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Microsoft.ML.Transforms/NAReplaceTransform.cs b/src/Microsoft.ML.Transforms/NAReplaceTransform.cs index 522237e303..52989472fc 100644 --- a/src/Microsoft.ML.Transforms/NAReplaceTransform.cs +++ b/src/Microsoft.ML.Transforms/NAReplaceTransform.cs @@ -43,6 +43,7 @@ public enum ReplacementKind Mean, Minimum, Maximum, + SpecifiedValue, [HideEnumValue] Def = DefaultValue, @@ -53,8 +54,6 @@ public enum ReplacementKind [HideEnumValue] Max = Maximum, - [HideEnumValue] - SpecifiedValue, [HideEnumValue] Val = SpecifiedValue, [HideEnumValue] diff --git a/src/Microsoft.ML/CSharpApi.cs b/src/Microsoft.ML/CSharpApi.cs index 75e06f0b98..05edec3cd9 100644 --- a/src/Microsoft.ML/CSharpApi.cs +++ b/src/Microsoft.ML/CSharpApi.cs @@ -11526,7 +11526,8 @@ public enum NAReplaceTransformReplacementKind DefaultValue = 0, Mean = 1, Minimum = 2, - Maximum = 3 + Maximum = 3, + SpecifiedValue = 4 } diff --git a/test/BaselineOutput/Common/EntryPoints/core_manifest.json b/test/BaselineOutput/Common/EntryPoints/core_manifest.json index 427b9c23b5..02cfd2c0c7 100644 --- a/test/BaselineOutput/Common/EntryPoints/core_manifest.json +++ b/test/BaselineOutput/Common/EntryPoints/core_manifest.json @@ -15775,7 +15775,8 @@ "DefaultValue", "Mean", "Minimum", - "Maximum" + "Maximum", + "SpecifiedValue" ] }, "Desc": "The replacement method to utilize", @@ -15844,7 +15845,8 @@ "DefaultValue", "Mean", "Minimum", - "Maximum" + "Maximum", + "SpecifiedValue" ] }, "Desc": "The replacement method to utilize", @@ -15854,7 +15856,7 @@ "Required": false, "SortOrder": 150.0, "IsNullable": false, - "Default": "Def" + "Default": "Default" }, { "Name": "ImputeBySlot",