mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-05-14 20:48:00 +00:00
### Description <!-- Describe your changes. --> MAUI test app with tooling to add model and generated or provided input test data. The app will load the model and validate the output. It can also run a specified number of iterations to provide basic performance information. <img width="401" alt="image" src="https://github.com/microsoft/onnxruntime/assets/979079/daf3af13-fb22-4cbb-9159-486b483a7485"> ### 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. --> Primarily to make it easier to test an arbitrary model on iOS. A MAUI app allows testing on all platforms. --------- Co-authored-by: Edward Chen <18449977+edgchen1@users.noreply.github.com>
115 lines
4.2 KiB
C#
115 lines
4.2 KiB
C#
using Microsoft.ML.OnnxRuntime;
|
|
using System.Diagnostics;
|
|
|
|
namespace MauiModelTester
|
|
{
|
|
public enum ExecutionProviders
|
|
{
|
|
CPU, // CPU execution provider is always available by default
|
|
NNAPI, // NNAPI is available on Android
|
|
CoreML, // CoreML is available on iOS/macOS
|
|
XNNPACK // XNNPACK is available on ARM/ARM64 platforms and benefits 32-bit float models
|
|
}
|
|
|
|
// An inference session runs an ONNX model
|
|
internal class OrtInferenceSession
|
|
{
|
|
public OrtInferenceSession(ExecutionProviders provider = ExecutionProviders.CPU)
|
|
{
|
|
_sessionOptions = new SessionOptions();
|
|
switch (_executionProvider)
|
|
{
|
|
case ExecutionProviders.CPU:
|
|
break;
|
|
case ExecutionProviders.NNAPI:
|
|
_sessionOptions.AppendExecutionProvider_Nnapi();
|
|
break;
|
|
case ExecutionProviders.CoreML:
|
|
_sessionOptions.AppendExecutionProvider_CoreML();
|
|
break;
|
|
case ExecutionProviders.XNNPACK:
|
|
_sessionOptions.AppendExecutionProvider("XNNPACK");
|
|
break;
|
|
}
|
|
|
|
// enable pre/post processing custom operators from onnxruntime-extensions
|
|
_sessionOptions.RegisterOrtExtensions();
|
|
|
|
_perfStats = new PerfStats();
|
|
}
|
|
|
|
// async task to create the inference session which is an expensive operation.
|
|
public async Task Create()
|
|
{
|
|
// create the InferenceSession. this is an expensive operation so only do this when necessary.
|
|
// the InferenceSession supports multiple calls to Run, including concurrent calls.
|
|
var modelBytes = await Utils.LoadResource("test_data/model.onnx");
|
|
|
|
var stopwatch = new Stopwatch();
|
|
stopwatch.Start();
|
|
_inferenceSession = new InferenceSession(modelBytes, _sessionOptions);
|
|
stopwatch.Stop();
|
|
_perfStats.LoadTime = stopwatch.Elapsed;
|
|
|
|
(_inputs, _expectedOutputs) = await Utils.LoadTestData();
|
|
|
|
// warmup
|
|
Run(1, true);
|
|
}
|
|
|
|
public void Run(int iterations = 1, bool isWarmup = false)
|
|
{
|
|
// do all setup outside of the timing
|
|
var runOptions = new RunOptions();
|
|
var outputNames = _inferenceSession.OutputNames;
|
|
|
|
_perfStats.ClearRunTimes();
|
|
|
|
// var stopwatch = new Stopwatch();
|
|
|
|
for (var i = 0; i < iterations; i++)
|
|
{
|
|
// stopwatch.Restart();
|
|
var stopwatch = new Stopwatch();
|
|
stopwatch.Start();
|
|
|
|
using IDisposableReadOnlyCollection<OrtValue> results =
|
|
_inferenceSession.Run(runOptions, _inputs, outputNames);
|
|
|
|
stopwatch.Stop();
|
|
|
|
if (isWarmup)
|
|
{
|
|
_perfStats.WarmupTime = stopwatch.Elapsed;
|
|
|
|
// validate the expected output on the first Run only
|
|
if (_expectedOutputs.Count > 0)
|
|
{
|
|
// create dictionary of output name to results
|
|
var actual = outputNames.Zip(results).ToDictionary(x => x.First, x => x.Second);
|
|
|
|
foreach (var expectedOutput in _expectedOutputs)
|
|
{
|
|
var outputName = expectedOutput.Key;
|
|
Utils.TensorComparer.VerifyTensorResults(outputName, expectedOutput.Value,
|
|
actual[outputName]);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
_perfStats.AddRunTime(stopwatch.Elapsed);
|
|
}
|
|
}
|
|
}
|
|
|
|
public PerfStats PerfStats => _perfStats;
|
|
|
|
private SessionOptions _sessionOptions;
|
|
private InferenceSession _inferenceSession;
|
|
private ExecutionProviders _executionProvider = ExecutionProviders.CPU;
|
|
private Dictionary<string, OrtValue> _inputs;
|
|
private Dictionary<string, OrtValue> _expectedOutputs;
|
|
private PerfStats _perfStats;
|
|
}
|
|
}
|