private ReadOnlyMemory <char> GetSlotName(int index, VBuffer <ReadOnlyMemory <char> > slotNames) { _env.Assert(0 <= index && index < slotNames.Length); var slotName = slotNames.GetItemOrDefault(index); return(slotName.IsEmpty ? new ReadOnlyMemory <char>($"f{index}".ToCharArray()) : slotName); }
private ReadOnlyMemory <char> GetSlotName(int index, VBuffer <ReadOnlyMemory <char> > slotNames) { var count = slotNames.GetValues().Length; _env.Assert(count > index || count == 0 && slotNames.Length > index); var slotName = slotNames.GetItemOrDefault(index); return(slotName.IsEmpty ? new ReadOnlyMemory <char>($"f{index}".ToCharArray()) : slotName); }
/// <summary> /// Gets the mapping from T into a StringBuilder representation, using various heuristics. /// This StringBuilder representation will be a component of the composed KeyValues for the /// hash outputs. /// </summary> public static ValueMapper <T, StringBuilder> GetSimpleMapper <T>(ISchema schema, int col) { Contracts.AssertValue(schema); Contracts.Assert(0 <= col && col < schema.ColumnCount); var type = schema.GetColumnType(col).ItemType; Contracts.Assert(type.RawType == typeof(T)); var conv = Conversion.Conversions.Instance; // First: if not key, then get the standard string converison. if (!type.IsKey) { return(conv.GetStringConversion <T>(type)); } bool identity; // Second choice: if key, utilize the KeyValues metadata for that key, if it has one and is text. if (schema.HasKeyNames(col, type.KeyCount)) { // REVIEW: Non-textual KeyValues are certainly possible. Should we handle them? // Get the key names. VBuffer <ReadOnlyMemory <char> > keyValues = default; schema.GetMetadata(MetadataUtils.Kinds.KeyValues, col, ref keyValues); ReadOnlyMemory <char> value = default; // REVIEW: We could optimize for identity, but it's probably not worthwhile. var keyMapper = conv.GetStandardConversion <T, uint>(type, NumberType.U4, out identity); return ((ref T src, ref StringBuilder dst) => { ClearDst(ref dst); uint intermediate = 0; keyMapper(ref src, ref intermediate); if (intermediate == 0) { return; } keyValues.GetItemOrDefault((int)(intermediate - 1), ref value); dst.AppendMemory(value); }); } // Third choice: just use the key value itself, subject to offsetting by the min. return(conv.GetKeyStringConversion <T>(type.AsKey)); }
public override Delegate[] CreateGetters(IRow input, Func <int, bool> activeOutput, out Action disposer) { disposer = null; var getters = new Delegate[3]; if (!activeOutput(ClusterIdCol) && !activeOutput(SortedClusterCol) && !activeOutput(SortedClusterScoreCol)) { return(getters); } long cachedPosition = -1; VBuffer <Single> scores = default(VBuffer <Single>); var scoresArr = new Single[_numClusters]; int[] sortedIndices = new int[_numClusters]; var scoreGetter = input.GetGetter <VBuffer <Single> >(ScoreIndex); Action updateCacheIfNeeded = () => { if (cachedPosition != input.Position) { scoreGetter(ref scores); scores.CopyTo(scoresArr); int j = 0; foreach (var index in Enumerable.Range(0, scoresArr.Length).OrderBy(i => scoresArr[i])) { sortedIndices[j++] = index; } cachedPosition = input.Position; } }; if (activeOutput(ClusterIdCol)) { ValueGetter <uint> assignedFn = (ref uint dst) => { updateCacheIfNeeded(); dst = (uint)sortedIndices[0] + 1; }; getters[ClusterIdCol] = assignedFn; } if (activeOutput(SortedClusterScoreCol)) { ValueGetter <VBuffer <Single> > topKScoresFn = (ref VBuffer <Single> dst) => { updateCacheIfNeeded(); var values = dst.Values; if (Utils.Size(values) < _numClusters) { values = new Single[_numClusters]; } for (int i = 0; i < _numClusters; i++) { values[i] = scores.GetItemOrDefault(sortedIndices[i]); } dst = new VBuffer <Single>(_numClusters, values); }; getters[SortedClusterScoreCol] = topKScoresFn; } if (activeOutput(SortedClusterCol)) { ValueGetter <VBuffer <uint> > topKClassesFn = (ref VBuffer <uint> dst) => { updateCacheIfNeeded(); var values = dst.Values; if (Utils.Size(values) < _numClusters) { values = new uint[_numClusters]; } for (int i = 0; i < _numClusters; i++) { values[i] = (uint)sortedIndices[i] + 1; } dst = new VBuffer <uint>(_numClusters, values); }; getters[SortedClusterCol] = topKClassesFn; } return(getters); }