onnxruntime/csharp/tools/MauiModelTester/Utils.cs
raoanag 424107a82a
Merge main to WindowsAI (#18122)
### Description
Merge main to WindowsAI



### Motivation and Context
<!-- - Why is this change required? What problem does it solve?
- If it fixes an open issue, please link to the issue here. -->

---------

Signed-off-by: Nash <george.nash@intel.com>
Signed-off-by: Yiming Hu <yiming.hu@amd.com>
Signed-off-by: Liqun Fu <liqfu@microsoft.com>
Co-authored-by: Kaz Nishimura <kazssym@linuxfront.com>
Co-authored-by: Tianlei Wu <tlwu@microsoft.com>
Co-authored-by: Nat Kershaw (MSFT) <nakersha@microsoft.com>
Co-authored-by: Yulong Wang <7679871+fs-eire@users.noreply.github.com>
Co-authored-by: Changming Sun <chasun@microsoft.com>
Co-authored-by: zesongw <zesong.wang@intel.com>
Co-authored-by: Yi Zhang <zhanyi@microsoft.com>
Co-authored-by: Dmitri Smirnov <yuslepukhin@users.noreply.github.com>
Co-authored-by: Yifan Li <109183385+yf711@users.noreply.github.com>
Co-authored-by: simonjub <78098752+simonjub@users.noreply.github.com>
Co-authored-by: PeixuanZuo <94887879+PeixuanZuo@users.noreply.github.com>
Co-authored-by: Adrian Lizarraga <adlizarraga@microsoft.com>
Co-authored-by: Edward Chen <18449977+edgchen1@users.noreply.github.com>
Co-authored-by: Arthur Islamov <arthur@islamov.ai>
Co-authored-by: Jambay Kinley <jambaykinley@microsoft.com>
Co-authored-by: Justin Chu <justinchuby@users.noreply.github.com>
Co-authored-by: Wei-Sheng Chin <wschin@outlook.com>
Co-authored-by: Bowen Bao <bowbao@microsoft.com>
Co-authored-by: Hariharan Seshadri <shariharan91@gmail.com>
Co-authored-by: Numfor Tiapo <numsmt2@gmail.com>
Co-authored-by: Vincent Wang <wangwchpku@outlook.com>
Co-authored-by: Pranav Sharma <prs@microsoft.com>
Co-authored-by: George Nash <george.nash@intel.com>
Co-authored-by: Abhishek Jindal <abjindal@microsoft.com>
Co-authored-by: pengwa <pengwa@microsoft.com>
Co-authored-by: Yiming Hu <woinck@users.noreply.github.com>
Co-authored-by: Jiajia Qin <jiajia.qin@intel.com>
Co-authored-by: Lukas Berbuer <36054362+lukasberbuer@users.noreply.github.com>
Co-authored-by: Wanming Lin <wanming.lin@intel.com>
Co-authored-by: Xavier Dupré <xadupre@users.noreply.github.com>
Co-authored-by: aimilefth <60664743+aimilefth@users.noreply.github.com>
Co-authored-by: Baiju Meswani <bmeswani@microsoft.com>
Co-authored-by: Adam Pocock <adam.pocock@oracle.com>
Co-authored-by: Chi Lo <54722500+chilo-ms@users.noreply.github.com>
Co-authored-by: RandySheriffH <48490400+RandySheriffH@users.noreply.github.com>
Co-authored-by: Randy Shuai <rashuai@microsoft.com>
Co-authored-by: Vadym Stupakov <vadim.stupakov@gmail.com>
Co-authored-by: Jian Chen <cjian@microsoft.com>
Co-authored-by: Brian Lambert <98757707+brian-pieces@users.noreply.github.com>
Co-authored-by: Nicolò Lucchesi <nicolo.lucchesi@gmail.com>
Co-authored-by: liqun Fu <liqfu@microsoft.com>
Co-authored-by: trajep <trajepl@gmail.com>
Co-authored-by: Scott McKay <skottmckay@gmail.com>
Co-authored-by: Mustafa Ateş Uzun <mustafauzun0@gmail.com>
Co-authored-by: MistEO <mistereo@hotmail.com>
Co-authored-by: satyajandhyala <satya.k.jandhyala@gmail.com>
Co-authored-by: shaahji <96227573+shaahji@users.noreply.github.com>
Co-authored-by: Rachel Guo <35738743+YUNQIUGUO@users.noreply.github.com>
Co-authored-by: rachguo <rachguo@rachguos-Mini.attlocal.net>
Co-authored-by: Caroline Zhu <wolfivyaura@gmail.com>
Co-authored-by: Caroline Zhu <carolinezhu@microsoft.com>
Co-authored-by: Guenther Schmuelling <guschmue@microsoft.com>
Co-authored-by: xhcao <xinghua.cao@intel.com>
Co-authored-by: Ella Charlaix <80481427+echarlaix@users.noreply.github.com>
Co-authored-by: Xu Xing <xing.xu@intel.com>
Co-authored-by: Hector Li <hecli@microsoft.com>
Co-authored-by: Ye Wang <52801275+wangyems@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Benedikt Hilmes <benedikt.hilmes@rwth-aachen.de>
Co-authored-by: rachguo <rachguo@rachguos-Mac-mini.local>
Co-authored-by: George Wu <jywu@microsoft.com>
Co-authored-by: JiCheng <wejoncy@163.com>
Co-authored-by: Sheil Kumar <smk2007@gmail.com>
Co-authored-by: Sheil Kumar <sheilk@microsoft.com>
Co-authored-by: cloudhan <guangyunhan@microsoft.com>
Co-authored-by: kyoshisuki <143475866+kyoshisuki@users.noreply.github.com>
Co-authored-by: aciddelgado <139922440+aciddelgado@users.noreply.github.com>
Co-authored-by: tlwu@microsoft.com <tlwu@a100.crj0ad2y1kku1j4yxl4sj10o4e.gx.internal.cloudapp.net>
Co-authored-by: Maximilian Müller <44298237+gedoensmax@users.noreply.github.com>
Co-authored-by: Tang, Cheng <souptc@gmail.com>
Co-authored-by: Cheng Tang <chenta@microsoft.com@orttrainingdev9.d32nl1ml4oruzj4qz3bqlggovf.px.internal.cloudapp.net>
Co-authored-by: Cheng Tang <chenta@microsoft.com>
Co-authored-by: Jeff Daily <jeff.daily@amd.com>
Co-authored-by: cloudhan <cloudhan@outlook.com>
Co-authored-by: Yufeng Li <liyufeng1987@gmail.com>
Co-authored-by: Zhang Lei <zhang.huanning@hotmail.com>
Co-authored-by: Dwayne Robinson <fdwr@hotmail.com>
Co-authored-by: Zhipeng Han <zhipeng.han@outlook.com>
Co-authored-by: Thiago Crepaldi <thiago.crepaldi@microsoft.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Patrice Vignola <vignola.patrice@gmail.com>
Co-authored-by: kunal-vaishnavi <115581922+kunal-vaishnavi@users.noreply.github.com>
Co-authored-by: snadampal <87143774+snadampal@users.noreply.github.com>
Co-authored-by: Sumit Agarwal <sumitagarwal330@gmail.com>
Co-authored-by: Ashwini Khade <askhade@microsoft.com>
Co-authored-by: Yang Gu <yang.gu@intel.com>
Co-authored-by: Cheng Tang <chenta@a100.crj0ad2y1kku1j4yxl4sj10o4e.gx.internal.cloudapp.net>
Co-authored-by: mindest <30493312+mindest@users.noreply.github.com>
Co-authored-by: Scott McKay <Scott.McKay@microsoft.com>
Co-authored-by: Xavier Dupre <xadupre@microsoft.com@orttrainingdev9.d32nl1ml4oruzj4qz3bqlggovf.px.internal.cloudapp.net>
Co-authored-by: guyang3532 <62738430+guyang3532@users.noreply.github.com>
Co-authored-by: Carson M <carson@pyke.io>
Co-authored-by: sophies927 <107952697+sophies927@users.noreply.github.com>
2023-10-27 17:08:01 -07:00

248 lines
10 KiB
C#

using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using Microsoft.ML.OnnxRuntime.Tests;
using System.Reflection;
namespace MauiModelTester
{
internal class Utils
{
internal static async Task<byte[]> LoadResource(string name)
{
using Stream fileStream = await FileSystem.Current.OpenAppPackageFileAsync(name);
using MemoryStream memoryStream = new MemoryStream();
fileStream.CopyTo(memoryStream);
return memoryStream.ToArray();
}
internal static async Task<(Dictionary<string, OrtValue>, Dictionary<string, OrtValue>)> LoadTestData()
{
var loadData = async (string prefix) =>
{
var data = new Dictionary<string, OrtValue>();
int idx = 0;
do
{
var filename = "test_data/test_data_set_0/" + prefix + idx + ".pb";
var exists = await FileSystem.Current.AppPackageFileExistsAsync(filename);
if (!exists)
{
// we expect sequentially named files for all inputs so as soon as one is missing we're done
break;
}
var tensorProtoData = await LoadResource(filename);
// get name and tensor data and create OrtValue
Onnx.TensorProto tensorProto = null;
tensorProto = Onnx.TensorProto.Parser.ParseFrom(tensorProtoData);
var ortValue = CreateOrtValueFromTensorProto(tensorProto);
data[tensorProto.Name] = ortValue;
idx++;
}
while (true);
return data;
};
var inputData = await loadData("input_");
var outputData = await loadData("output_");
return (inputData, outputData);
}
internal static OrtValue CreateOrtValueFromTensorProto(Onnx.TensorProto tensorProto)
{
Type tensorElementType = GetElementType((TensorElementType)tensorProto.DataType);
OrtValue ortValue = null;
// special case for strings
if (tensorElementType == typeof(string))
{
var numElements = tensorProto.Dims.Aggregate(1L, (x, y) => x * y);
ortValue = OrtValue.CreateTensorWithEmptyStrings(OrtAllocator.DefaultInstance,
tensorProto.Dims.ToArray());
int idx = 0;
foreach (var str in tensorProto.StringData)
{
ortValue.StringTensorSetElementAt(str.Span, idx++);
}
}
else
{
// use reflection to call generic method
var func = typeof(Utils)
.GetMethod(nameof(TensorProtoToOrtValue), BindingFlags.Static | BindingFlags.NonPublic)
.MakeGenericMethod(tensorElementType);
ortValue = (OrtValue)func.Invoke(null, new[] { tensorProto });
}
return ortValue;
}
internal static Type GetElementType(TensorElementType elemType)
{
switch (elemType)
{
case TensorElementType.Float:
return typeof(float);
case TensorElementType.Double:
return typeof(double);
case TensorElementType.Int16:
return typeof(short);
case TensorElementType.UInt16:
return typeof(ushort);
case TensorElementType.Int32:
return typeof(int);
case TensorElementType.UInt32:
return typeof(uint);
case TensorElementType.Int64:
return typeof(long);
case TensorElementType.UInt64:
return typeof(ulong);
case TensorElementType.UInt8:
return typeof(byte);
case TensorElementType.Int8:
return typeof(sbyte);
case TensorElementType.String:
return typeof(string);
case TensorElementType.Bool:
return typeof(bool);
default:
throw new ArgumentException("Unexpected element type of " + elemType);
}
}
static OrtValue TensorProtoToOrtValue<T>(Onnx.TensorProto tensorProto)
where T : unmanaged
{
unsafe
{
var elementSize = sizeof(T);
T[] data = new T[tensorProto.RawData.Length / elementSize];
fixed(byte *bytes = tensorProto.RawData.Span) fixed(void *target = data)
{
Buffer.MemoryCopy(bytes, target, tensorProto.RawData.Length, tensorProto.RawData.Length);
}
return OrtValue.CreateTensorValueFromMemory(data, tensorProto.Dims.ToArray());
}
}
internal class TensorComparer
{
// we need to use a delegate in the checker func to handle string as well as numeric types
private delegate ReadOnlySpan<T> GetDataFn<T>(OrtValue ortValue);
private static ReadOnlySpan<T> GetData<T>(OrtValue ortValue)
where T : unmanaged
{
return ortValue.GetTensorDataAsSpan<T>();
}
private static ReadOnlySpan<string> GetStringData(OrtValue ortValue)
{
return ortValue.GetStringTensorAsArray();
}
private static void CheckEqual<T>(string name, OrtValue expected, OrtValue actual,
IEqualityComparer<T> comparer, GetDataFn<T> getDataFn)
{
var expectedTypeAndShape = expected.GetTypeInfo().TensorTypeAndShapeInfo;
var actualTypeAndShape = actual.GetTypeInfo().TensorTypeAndShapeInfo;
if (expectedTypeAndShape.ElementCount != actualTypeAndShape.ElementCount)
{
throw new ArithmeticException(
$"Element count mismatch for {name}. " +
$"Expected:{expectedTypeAndShape.ElementCount} Actual:{actualTypeAndShape.ElementCount}");
}
var expectedData = getDataFn(expected);
var actualData = getDataFn(actual);
List<string> mismatches = new List<string>();
for (int i = 0; i < expectedData.Length; i++)
{
if (!comparer.Equals(expectedData[i], actualData[i]))
{
mismatches.Add($"[{i}] {expectedData[i]} != {actualData[i]}");
}
}
if (mismatches.Count > 0)
{
throw new ArithmeticException(
$"Result mismatch for {name}. Mismatched entries:{string.Join(',', mismatches)}");
}
}
private static void CheckEqual<T>(string name, OrtValue expected, OrtValue actual,
IEqualityComparer<T> comparer)
where T : unmanaged
{
CheckEqual(name, expected, actual, comparer, GetData<T>);
}
internal static void VerifyTensorResults(string name, OrtValue expected, OrtValue actual)
{
var tensorElementType = expected.GetTypeInfo().TensorTypeAndShapeInfo.ElementDataType;
switch (tensorElementType)
{
case TensorElementType.Float:
CheckEqual(name, expected, actual, new FloatComparer());
break;
case TensorElementType.Double:
CheckEqual(name, expected, actual, new DoubleComparer());
break;
case TensorElementType.Int32:
CheckEqual(name, expected, actual, new ExactComparer<int>());
break;
case TensorElementType.UInt32:
CheckEqual(name, expected, actual, new ExactComparer<uint>());
break;
case TensorElementType.Int16:
CheckEqual(name, expected, actual, new ExactComparer<short>());
break;
case TensorElementType.UInt16:
CheckEqual(name, expected, actual, new ExactComparer<ushort>());
break;
case TensorElementType.Int64:
CheckEqual(name, expected, actual, new ExactComparer<long>());
break;
case TensorElementType.UInt64:
CheckEqual(name, expected, actual, new ExactComparer<ulong>());
break;
case TensorElementType.UInt8:
CheckEqual(name, expected, actual, new ExactComparer<byte>());
break;
case TensorElementType.Int8:
CheckEqual(name, expected, actual, new ExactComparer<sbyte>());
break;
case TensorElementType.Bool:
CheckEqual(name, expected, actual, new ExactComparer<bool>());
break;
case TensorElementType.Float16:
CheckEqual(name, expected, actual, new Float16Comparer { tolerance = 2 });
break;
case TensorElementType.BFloat16:
CheckEqual(name, expected, actual, new BFloat16Comparer { tolerance = 2 });
break;
case TensorElementType.String:
CheckEqual<string>(name, expected, actual, new ExactComparer<string>(), GetStringData);
break;
default:
throw new ArgumentException($"Unexpected data type of {tensorElementType}");
}
}
}
}
}