Skip to content

Commit d6ad1b4

Browse files
authored
Delete IColumn (#1801)
* Stop using IColumn in predicted label scorers. * Stop using IColumn in static schema shape analysis. * Stop using IColumn in linear model statistics creation. * Stop using IColumn in FastTree statistics creation. * Stop using IColumn in benchmarking. * Stop using IColumn in many tests. * Add minor conveniences to metadata builder. * Allow metadata builder to have metadata of metadata. * Add appropriate validation in certain places. * Put warnings on an inappropriate method dealing with Batch that should not exist. * Remove IColumn.
1 parent 0678df5 commit d6ad1b4

File tree

16 files changed

+238
-840
lines changed

16 files changed

+238
-840
lines changed

src/Microsoft.ML.Core/Data/MetadataBuilder.cs

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@ namespace Microsoft.ML.Data
1616
/// </summary>
1717
public sealed class MetadataBuilder
1818
{
19-
private readonly List<(string Name, ColumnType Type, Delegate Getter)> _items;
19+
private readonly List<(string Name, ColumnType Type, Delegate Getter, Schema.Metadata Metadata)> _items;
2020

2121
public MetadataBuilder()
2222
{
23-
_items = new List<(string Name, ColumnType Type, Delegate Getter)>();
23+
_items = new List<(string Name, ColumnType Type, Delegate Getter, Schema.Metadata Metadata)>();
2424
}
2525

2626
/// <summary>
@@ -40,7 +40,7 @@ public void Add(Schema.Metadata metadata, Func<string, bool> selector)
4040
foreach (var column in metadata.Schema)
4141
{
4242
if (selector(column.Name))
43-
_items.Add((column.Name, column.Type, metadata.Getters[column.Index]));
43+
_items.Add((column.Name, column.Type, metadata.Getters[column.Index], column.Metadata));
4444
}
4545
}
4646

@@ -51,13 +51,17 @@ public void Add(Schema.Metadata metadata, Func<string, bool> selector)
5151
/// <param name="name">The metadata name.</param>
5252
/// <param name="type">The metadata type.</param>
5353
/// <param name="getter">The getter delegate.</param>
54-
public void Add<TValue>(string name, ColumnType type, ValueGetter<TValue> getter)
54+
/// <param name="metadata">Metadata of the input column. Note that metadata on a metadata column is somewhat rare
55+
/// except for certain types (for example, slot names for a vector, key values for something of key type).</param>
56+
public void Add<TValue>(string name, ColumnType type, ValueGetter<TValue> getter, Schema.Metadata metadata = null)
5557
{
5658
Contracts.CheckNonEmpty(name, nameof(name));
5759
Contracts.CheckValue(type, nameof(type));
5860
Contracts.CheckValue(getter, nameof(getter));
59-
Contracts.CheckParam(type.RawType == typeof(TValue), nameof(getter));
60-
_items.Add((name, type, getter));
61+
Contracts.CheckParam(type.RawType == typeof(TValue), nameof(type));
62+
Contracts.CheckValueOrNull(metadata);
63+
64+
_items.Add((name, type, getter, metadata));
6165
}
6266

6367
/// <summary>
@@ -67,11 +71,31 @@ public void Add<TValue>(string name, ColumnType type, ValueGetter<TValue> getter
6771
/// <param name="type">The metadata type.</param>
6872
/// <param name="getter">The getter delegate that provides the value. Note that the type of the getter is still checked
6973
/// inside this method.</param>
70-
public void Add(string name, ColumnType type, Delegate getter)
74+
/// <param name="metadata">Metadata of the input column. Note that metadata on a metadata column is somewhat rare
75+
/// except for certain types (for example, slot names for a vector, key values for something of key type).</param>
76+
public void Add(string name, ColumnType type, Delegate getter, Schema.Metadata metadata = null)
7177
{
7278
Contracts.CheckNonEmpty(name, nameof(name));
7379
Contracts.CheckValue(type, nameof(type));
74-
Utils.MarshalActionInvoke(AddDelegate<int>, type.RawType, name, type, getter);
80+
Contracts.CheckValueOrNull(metadata);
81+
Utils.MarshalActionInvoke(AddDelegate<int>, type.RawType, name, type, getter, metadata);
82+
}
83+
84+
/// <summary>
85+
/// Add one metadata column for a primitive value type.
86+
/// </summary>
87+
/// <param name="name">The metadata name.</param>
88+
/// <param name="type">The metadata type.</param>
89+
/// <param name="value">The value of the metadata.</param>
90+
/// <param name="metadata">Metadata of the input column. Note that metadata on a metadata column is somewhat rare
91+
/// except for certain types (for example, slot names for a vector, key values for something of key type).</param>
92+
public void AddPrimitiveValue<TValue>(string name, PrimitiveType type, TValue value, Schema.Metadata metadata = null)
93+
{
94+
Contracts.CheckNonEmpty(name, nameof(name));
95+
Contracts.CheckValue(type, nameof(type));
96+
Contracts.CheckParam(type.RawType == typeof(TValue), nameof(type));
97+
Contracts.CheckValueOrNull(metadata);
98+
Add(name, type, (ref TValue dst) => dst = value, metadata);
7599
}
76100

77101
/// <summary>
@@ -100,19 +124,19 @@ public Schema.Metadata GetMetadata()
100124
{
101125
var builder = new SchemaBuilder();
102126
foreach (var item in _items)
103-
builder.AddColumn(item.Name, item.Type, null);
127+
builder.AddColumn(item.Name, item.Type, item.Metadata);
104128
return new Schema.Metadata(builder.GetSchema(), _items.Select(x => x.Getter).ToArray());
105129
}
106130

107-
private void AddDelegate<TValue>(string name, ColumnType type, Delegate getter)
131+
private void AddDelegate<TValue>(string name, ColumnType type, Delegate getter, Schema.Metadata metadata)
108132
{
109133
Contracts.AssertNonEmpty(name);
110134
Contracts.AssertValue(type);
111135
Contracts.AssertValue(getter);
112136

113137
var typedGetter = getter as ValueGetter<TValue>;
114138
Contracts.CheckParam(typedGetter != null, nameof(getter));
115-
_items.Add((name, type, typedGetter));
139+
_items.Add((name, type, typedGetter, metadata));
116140
}
117141
}
118142
}

src/Microsoft.ML.Core/Data/MetadataUtils.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,5 +494,34 @@ public static bool TryGetCategoricalFeatureIndices(Schema schema, int colIndex,
494494
cols.AddRange(GetTrainerOutputMetadata());
495495
return cols;
496496
}
497+
498+
private sealed class MetadataRow : IRow
499+
{
500+
private readonly Schema.Metadata _metadata;
501+
502+
public MetadataRow(Schema.Metadata metadata)
503+
{
504+
Contracts.AssertValue(metadata);
505+
_metadata = metadata;
506+
}
507+
508+
public Schema Schema => _metadata.Schema;
509+
public long Position => 0;
510+
public long Batch => 0;
511+
public ValueGetter<TValue> GetGetter<TValue>(int col) => _metadata.GetGetter<TValue>(col);
512+
public ValueGetter<UInt128> GetIdGetter() => (ref UInt128 dst) => dst = default;
513+
public bool IsColumnActive(int col) => true;
514+
}
515+
516+
/// <summary>
517+
/// Presents a <see cref="Schema.Metadata"/> as a an <see cref="IRow"/>.
518+
/// </summary>
519+
/// <param name="metadata">The metadata to wrap.</param>
520+
/// <returns>A row that wraps an input metadata.</returns>
521+
public static IRow MetadataAsRow(Schema.Metadata metadata)
522+
{
523+
Contracts.CheckValue(metadata, nameof(metadata));
524+
return new MetadataRow(metadata);
525+
}
497526
}
498527
}

src/Microsoft.ML.Core/Data/Schema.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ public sealed class Metadata
194194
/// </summary>
195195
public Schema Schema { get; }
196196

197-
public static Metadata Empty { get; } = new Metadata(new Schema(Enumerable.Empty<Column>()), new Delegate[0]);
197+
public static Metadata Empty { get; } = new Metadata(new Schema(new Column[0]), new Delegate[0]);
198198

199199
/// <summary>
200200
/// Create a metadata row by supplying the schema columns and the getter delegates for all the values.
@@ -256,11 +256,12 @@ public void GetValue<TValue>(string kind, ref TValue value)
256256
/// <summary>
257257
/// This constructor should only be called by <see cref="SchemaBuilder"/>.
258258
/// </summary>
259-
internal Schema(IEnumerable<Column> columns)
259+
/// <param name="columns">The input columns. The constructed instance takes ownership of the array.</param>
260+
internal Schema(Column[] columns)
260261
{
261262
Contracts.CheckValue(columns, nameof(columns));
262263

263-
_columns = columns.ToArray();
264+
_columns = columns;
264265
_nameMap = new Dictionary<string, int>();
265266
for (int i = 0; i < _columns.Length; i++)
266267
{

src/Microsoft.ML.Core/Data/SchemaBuilder.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// The .NET Foundation licenses this file to you under the MIT license.
33
// See the LICENSE file in the project root for more information.
44

5+
using Microsoft.ML.Runtime;
56
using Microsoft.ML.Runtime.Data;
67
using System;
78
using System.Collections.Generic;
@@ -32,6 +33,9 @@ public SchemaBuilder()
3233
/// <param name="metadata">The column metadata.</param>
3334
public void AddColumn(string name, ColumnType type, Schema.Metadata metadata)
3435
{
36+
Contracts.CheckNonEmpty(name, nameof(name));
37+
Contracts.CheckValue(type, nameof(type));
38+
Contracts.CheckValueOrNull(metadata);
3539
_items.Add((name, type, metadata));
3640
}
3741

src/Microsoft.ML.Core/Utilities/Utils.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,15 @@ public static void MarshalActionInvoke<TArg1, TArg2, TArg3>(Action<TArg1, TArg2,
10761076
meth.Invoke(act.Target, new object[] { arg1, arg2, arg3 });
10771077
}
10781078

1079+
/// <summary>
1080+
/// A four-argument version of <see cref="MarshalActionInvoke(Action, Type)"/>.
1081+
/// </summary>
1082+
public static void MarshalActionInvoke<TArg1, TArg2, TArg3, TArg4>(Action<TArg1, TArg2, TArg3, TArg4> act, Type genArg, TArg1 arg1, TArg2 arg2, TArg3 arg3, TArg4 arg4)
1083+
{
1084+
var meth = MarshalActionInvokeCheckAndCreate(genArg, act);
1085+
meth.Invoke(act.Target, new object[] { arg1, arg2, arg3, arg4 });
1086+
}
1087+
10791088
public static string GetDescription(this Enum value)
10801089
{
10811090
Type type = value.GetType();

0 commit comments

Comments
 (0)