private Delegate MakeStringTensorGetter(DataViewRow input, int iinfo, INamedOnnxValueGetter[] srcNamedValueGetters, string[] activeOutputColNames) { Host.AssertValue(input); var outputCacher = new OnnxRuntimeOutputCacher(); ValueGetter <VBuffer <ReadOnlyMemory <char> > > valueGetter = (ref VBuffer <ReadOnlyMemory <char> > dst) => { UpdateCacheIfNeeded(input.Position, srcNamedValueGetters, activeOutputColNames, outputCacher); var namedOnnxValue = outputCacher.Outputs[_parent.Outputs[iinfo]]; var tensor = namedOnnxValue.AsTensor <string>() as System.Numerics.Tensors.DenseTensor <string>; if (tensor == null) { throw Host.Except($"Output column {namedOnnxValue.Name} doesn't contain a DenseTensor of expected type {typeof(string)}"); } // Create VBufferEditor to fill "dst" with the values in "denseTensor". var editor = VBufferEditor.Create(ref dst, (int)tensor.Length); for (int i = 0; i < tensor.Length; ++i) { // Cast because string in ML.NET is typed to ReadOnlyMemory<char>. editor.Values[i] = tensor.GetValue(i).AsMemory(); } dst = editor.Commit(); }; return(valueGetter); }
private Delegate MakeObjectGetter <T>(DataViewRow input, int iinfo, INamedOnnxValueGetter[] srcNamedValueGetters, string[] activeOutputColNames) { Host.AssertValue(input); var outputCache = new OnnxRuntimeOutputCacher(); ValueGetter <T> valueGetter = (ref T dst) => { UpdateCacheIfNeeded(input.Position, srcNamedValueGetters, activeOutputColNames, outputCache); var namedOnnxValue = outputCache.Outputs[_parent.Outputs[iinfo]]; var trueValue = namedOnnxValue.AsEnumerable <NamedOnnxValue>().Select(value => value.AsDictionary <string, float>()); var caster = _parent.Model.ModelInfo.OutputsInfo[iinfo].Caster; dst = (T)caster(namedOnnxValue); }; return(valueGetter); }
private Delegate MakeTensorGetter <T>(DataViewRow input, int iinfo, INamedOnnxValueGetter[] srcNamedValueGetters, string[] activeOutputColNames) { Host.AssertValue(input); var outputCacher = new OnnxRuntimeOutputCacher(); ValueGetter <VBuffer <T> > valueGetter = (ref VBuffer <T> dst) => { UpdateCacheIfNeeded(input.Position, srcNamedValueGetters, activeOutputColNames, outputCacher); var namedOnnxValue = outputCacher.Outputs[_parent.Outputs[iinfo]]; var tensor = namedOnnxValue.AsTensor <T>() as System.Numerics.Tensors.DenseTensor <T>; if (tensor == null) { throw Host.Except($"Output column {namedOnnxValue.Name} doesn't contain a DenseTensor of expected type {typeof(T)}"); } var editor = VBufferEditor.Create(ref dst, (int)tensor.Length); tensor.Buffer.Span.CopyTo(editor.Values); dst = editor.Commit(); }; return(valueGetter); }
public override Delegate[] CreateGetters(DataViewRow input, Func <int, bool> activeOutput, out Action disposer) { Contracts.Assert(input.Schema == InputSchema); OnnxRuntimeOutputCacher outputCacher = new OnnxRuntimeOutputCacher(); int n = OutputColumns.Value.Length; var result = new Delegate[n]; for (int i = 0; i < n; i++) { if (!activeOutput(i)) { continue; } result[i] = CreateGetter(input, i, activeOutput, outputCacher); } disposer = () => { outputCacher.Dispose(); }; return(result); }
private void UpdateCacheIfNeeded(long position, INamedOnnxValueGetter[] srcNamedOnnxValueGetters, string[] activeOutputColNames, OnnxRuntimeOutputCacher outputCache) { if (outputCache.Position != position) { var inputNameOnnxValues = new List <NamedOnnxValue>(); for (int i = 0; i < _inputColIndices.Length; i++) { inputNameOnnxValues.Add(srcNamedOnnxValueGetters[i].GetNamedOnnxValue()); } var outputNamedOnnxValues = _parent.Model.Run(inputNameOnnxValues); Contracts.Assert(outputNamedOnnxValues.Count > 0); foreach (var outputNameOnnxValue in outputNamedOnnxValues) { outputCache.Outputs[outputNameOnnxValue.Name] = outputNameOnnxValue; } outputCache.Position = position; } }
private Delegate CreateGetter(DataViewRow input, int iinfo, Func <int, bool> activeOutput, OnnxRuntimeOutputCacher outputCacher) { Host.AssertValue(input); var activeOutputColNames = _parent.Outputs.Where((x, i) => activeOutput(i)).ToArray(); if (_parent.Model.ModelInfo.OutputsInfo[_parent.MapDataViewColumnToOnnxOutputTensor(iinfo)].DataViewType is VectorDataViewType vectorType) { var elemRawType = vectorType.ItemType.RawType; var srcNamedValueGetters = GetNamedOnnxValueGetters(input, _inputColIndices, _inputOnnxTypes, _inputTensorShapes); if (vectorType.ItemType is TextDataViewType) { return(MakeStringTensorGetter(input, iinfo, srcNamedValueGetters, activeOutputColNames, outputCacher)); } else { return(Utils.MarshalInvoke(MakeTensorGetter <int>, elemRawType, input, iinfo, srcNamedValueGetters, activeOutputColNames, outputCacher)); } } else { var type = _parent.Model.ModelInfo.OutputsInfo[_parent.MapDataViewColumnToOnnxOutputTensor(iinfo)].DataViewType.RawType; var srcNamedValueGetters = GetNamedOnnxValueGetters(input, _inputColIndices, _inputOnnxTypes, _inputTensorShapes); return(Utils.MarshalInvoke(MakeObjectGetter <int>, type, input, iinfo, srcNamedValueGetters, activeOutputColNames, outputCacher)); } }