internal static ValueGetter <VBuffer <Single> > GetLabelGetter(SlotCursor cursor) { var type = cursor.GetSlotType().ItemType; if (type == NumberDataViewType.Single) { return(cursor.GetGetter <Single>()); } if (type == NumberDataViewType.Double || type is BooleanDataViewType) { return(GetVecGetterAs <Single>(NumberDataViewType.Single, cursor)); } if (!(type is KeyType keyType)) { throw Contracts.Except("Only floating point number, boolean, and key type values can be used as label."); } Contracts.Assert(TestGetLabelGetter(type) == null); ulong keyMax = (ulong)keyType.Count; if (keyMax == 0) { keyMax = ulong.MaxValue; } var getSrc = RowCursorUtils.GetVecGetterAs <ulong>(NumberDataViewType.UInt64, cursor); VBuffer <ulong> src = default(VBuffer <ulong>); return ((ref VBuffer <Single> dst) => { getSrc(ref src); // Unfortunately defaults in one to not translate to defaults of the other, // so this will not be sparsity preserving. Assume a dense output. var editor = VBufferEditor.Create(ref dst, src.Length); foreach (var kv in src.Items(all: true)) { if (0 < kv.Value && kv.Value <= keyMax) { editor.Values[kv.Key] = kv.Value - 1; } else { editor.Values[kv.Key] = Single.NaN; } } dst = editor.Commit(); }); }
internal override void InitializeNextPass(Row row, RoleMappedSchema schema) { Contracts.Assert(PassNum < 1); Contracts.Assert(schema.Label.HasValue); var score = schema.GetUniqueColumn(MetadataUtils.Const.ScoreValueKind.Score); _labelGetter = RowCursorUtils.GetVecGetterAs <Float>(NumberType.Float, row, schema.Label.Value.Index); _scoreGetter = row.GetGetter <VBuffer <Float> >(score.Index); Contracts.AssertValue(_labelGetter); Contracts.AssertValue(_scoreGetter); if (schema.Weight.HasValue) { _weightGetter = row.GetGetter <Float>(schema.Weight.Value.Index); } }
private protected override Delegate[] CreateGettersCore(Row input, Func <int, bool> activeCols, out Action disposer) { Host.Assert(LabelIndex >= 0); Host.Assert(ScoreIndex >= 0); disposer = null; long cachedPosition = -1; var label = default(VBuffer <Float>); var score = default(VBuffer <Float>); ValueGetter <VBuffer <Float> > nullGetter = (ref VBuffer <Float> vec) => vec = default(VBuffer <Float>); var labelGetter = activeCols(LabelOutput) || activeCols(L1Output) || activeCols(L2Output) || activeCols(DistCol) ? RowCursorUtils.GetVecGetterAs <Float>(NumberType.Float, input, LabelIndex) : nullGetter; var scoreGetter = activeCols(ScoreOutput) || activeCols(L1Output) || activeCols(L2Output) || activeCols(DistCol) ? input.GetGetter <VBuffer <Float> >(ScoreIndex) : nullGetter; Action updateCacheIfNeeded = () => { if (cachedPosition != input.Position) { labelGetter(ref label); scoreGetter(ref score); cachedPosition = input.Position; } }; var getters = new Delegate[5]; if (activeCols(LabelOutput)) { ValueGetter <VBuffer <Float> > labelFn = (ref VBuffer <Float> dst) => { updateCacheIfNeeded(); label.CopyTo(ref dst); }; getters[LabelOutput] = labelFn; } if (activeCols(ScoreOutput)) { ValueGetter <VBuffer <Float> > scoreFn = (ref VBuffer <Float> dst) => { updateCacheIfNeeded(); score.CopyTo(ref dst); }; getters[ScoreOutput] = scoreFn; } if (activeCols(L1Output)) { ValueGetter <double> l1Fn = (ref double dst) => { updateCacheIfNeeded(); dst = VectorUtils.L1Distance(in label, in score); }; getters[L1Output] = l1Fn; }