2018-11-28 03:01:28 +00:00
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
|
// Licensed under the MIT License.
|
|
|
|
|
|
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
2019-08-16 00:28:47 +00:00
|
|
|
using Microsoft.ML.OnnxRuntime.Tensors;
|
2018-11-28 03:01:28 +00:00
|
|
|
using System.Diagnostics;
|
2019-04-05 19:05:56 +00:00
|
|
|
using CommandLine;
|
2018-11-28 03:01:28 +00:00
|
|
|
|
|
|
|
|
namespace Microsoft.ML.OnnxRuntime.PerfTool
|
|
|
|
|
{
|
|
|
|
|
public enum TimingPoint
|
|
|
|
|
{
|
|
|
|
|
Start = 0,
|
|
|
|
|
ModelLoaded = 1,
|
|
|
|
|
InputLoaded = 2,
|
|
|
|
|
RunComplete = 3,
|
|
|
|
|
TotalCount = 4
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-05 19:05:56 +00:00
|
|
|
class CommandOptions
|
2018-11-28 03:01:28 +00:00
|
|
|
{
|
2019-04-05 19:05:56 +00:00
|
|
|
[Option('m', "model_file", Required = true, HelpText = "Model Path.")]
|
|
|
|
|
public string ModelFile { get; set; }
|
2018-11-28 03:01:28 +00:00
|
|
|
|
2019-04-05 19:05:56 +00:00
|
|
|
[Option('i', "input_file", Required = true, HelpText = "Input path.")]
|
|
|
|
|
public string InputFile { get; set; }
|
2018-11-28 03:01:28 +00:00
|
|
|
|
2019-04-05 19:05:56 +00:00
|
|
|
[Option('c', "iteration_count", Required = true, HelpText = "Iteration to run.")]
|
|
|
|
|
public int IterationCount { get; set; }
|
2018-11-28 03:01:28 +00:00
|
|
|
|
2019-04-05 19:05:56 +00:00
|
|
|
[Option('p', Required = false, HelpText = "Run with parallel exection. Default is false")]
|
|
|
|
|
public bool ParallelExecution { get; set; } = false;
|
2018-11-28 03:01:28 +00:00
|
|
|
|
2020-01-13 22:05:38 +00:00
|
|
|
[Option('o', "optimization_level", Required = false, HelpText = "Optimization Level. Default is 99, all optimization.")]
|
|
|
|
|
public GraphOptimizationLevel OptimizationLevel { get; set; } = GraphOptimizationLevel.ORT_ENABLE_ALL;
|
2019-04-05 19:05:56 +00:00
|
|
|
}
|
2018-11-28 03:01:28 +00:00
|
|
|
|
2019-04-05 19:05:56 +00:00
|
|
|
class Program
|
|
|
|
|
{
|
|
|
|
|
public static void Main(string[] args)
|
|
|
|
|
{
|
|
|
|
|
var cmdOptions = Parser.Default.ParseArguments<CommandOptions>(args);
|
|
|
|
|
cmdOptions.WithParsed(
|
2019-08-15 00:12:08 +00:00
|
|
|
options =>
|
|
|
|
|
{
|
2019-04-27 07:41:26 +00:00
|
|
|
Run(options);
|
2019-04-05 19:05:56 +00:00
|
|
|
});
|
|
|
|
|
}
|
2019-04-27 07:41:26 +00:00
|
|
|
public static void Run(CommandOptions options)
|
2019-04-05 19:05:56 +00:00
|
|
|
{
|
|
|
|
|
string modelPath = options.ModelFile;
|
|
|
|
|
string inputPath = options.InputFile;
|
|
|
|
|
int iteration = options.IterationCount;
|
|
|
|
|
bool parallelExecution = options.ParallelExecution;
|
2019-08-15 00:12:08 +00:00
|
|
|
GraphOptimizationLevel optLevel = options.OptimizationLevel;
|
2019-04-05 19:05:56 +00:00
|
|
|
Console.WriteLine("Running model {0} in OnnxRuntime:", modelPath);
|
|
|
|
|
Console.WriteLine("input:{0}", inputPath);
|
|
|
|
|
Console.WriteLine("iteration count:{0}", iteration);
|
|
|
|
|
Console.WriteLine("parallel execution:{0}", parallelExecution);
|
|
|
|
|
Console.WriteLine("optimization level:{0}", optLevel);
|
|
|
|
|
DateTime[] timestamps = new DateTime[(int)TimingPoint.TotalCount];
|
|
|
|
|
|
|
|
|
|
RunModelOnnxRuntime(modelPath, inputPath, iteration, timestamps, parallelExecution, optLevel);
|
2018-11-28 03:01:28 +00:00
|
|
|
PrintReport(timestamps, iteration);
|
|
|
|
|
Console.WriteLine("Done");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static float[] LoadTensorFromFile(string filename)
|
|
|
|
|
{
|
|
|
|
|
var tensorData = new List<float>();
|
|
|
|
|
|
|
|
|
|
// read data from file
|
|
|
|
|
using (var inputFile = new System.IO.StreamReader(filename))
|
|
|
|
|
{
|
|
|
|
|
inputFile.ReadLine(); //skip the input name
|
|
|
|
|
string[] dataStr = inputFile.ReadLine().Split(new char[] { ',', '[', ']' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
for (int i = 0; i < dataStr.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
tensorData.Add(Single.Parse(dataStr[i]));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return tensorData.ToArray();
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-15 00:12:08 +00:00
|
|
|
static void RunModelOnnxRuntime(string modelPath, string inputPath, int iteration, DateTime[] timestamps, bool parallelExecution, GraphOptimizationLevel optLevel)
|
2018-11-28 03:01:28 +00:00
|
|
|
{
|
|
|
|
|
if (timestamps.Length != (int)TimingPoint.TotalCount)
|
|
|
|
|
{
|
2019-08-15 00:12:08 +00:00
|
|
|
throw new ArgumentException("Timestamps array must have " + (int)TimingPoint.TotalCount + " size");
|
2018-11-28 03:01:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
timestamps[(int)TimingPoint.Start] = DateTime.Now;
|
2019-04-05 19:05:56 +00:00
|
|
|
SessionOptions options = new SessionOptions();
|
2019-10-14 16:48:19 +00:00
|
|
|
if (parallelExecution) options.ExecutionMode = ExecutionMode.ORT_PARALLEL;
|
2019-08-14 19:02:02 +00:00
|
|
|
options.GraphOptimizationLevel = optLevel;
|
2019-04-05 19:05:56 +00:00
|
|
|
using (var session = new InferenceSession(modelPath, options))
|
2018-11-28 03:01:28 +00:00
|
|
|
{
|
|
|
|
|
timestamps[(int)TimingPoint.ModelLoaded] = DateTime.Now;
|
|
|
|
|
var inputMeta = session.InputMetadata;
|
|
|
|
|
|
|
|
|
|
var container = new List<NamedOnnxValue>();
|
|
|
|
|
foreach (var name in inputMeta.Keys)
|
|
|
|
|
{
|
|
|
|
|
float[] rawData = LoadTensorFromFile(inputPath);
|
|
|
|
|
var tensor = new DenseTensor<float>(rawData, inputMeta[name].Dimensions);
|
|
|
|
|
container.Add(NamedOnnxValue.CreateFromTensor<float>(name, tensor));
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-15 00:12:08 +00:00
|
|
|
|
2018-11-28 03:01:28 +00:00
|
|
|
|
|
|
|
|
timestamps[(int)TimingPoint.InputLoaded] = DateTime.Now;
|
|
|
|
|
|
|
|
|
|
// Run the inference
|
2019-08-15 00:12:08 +00:00
|
|
|
for (int i = 0; i < iteration; i++)
|
2018-11-28 03:01:28 +00:00
|
|
|
{
|
|
|
|
|
var results = session.Run(container); // results is an IReadOnlyList<NamedOnnxValue> container
|
|
|
|
|
Debug.Assert(results != null);
|
|
|
|
|
Debug.Assert(results.Count == 1);
|
|
|
|
|
//results = null;
|
|
|
|
|
//GC.Collect();
|
|
|
|
|
//GC.WaitForPendingFinalizers();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
timestamps[(int)TimingPoint.RunComplete] = DateTime.Now;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void PrintUsage()
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Usage:\n"
|
2019-08-15 00:12:08 +00:00
|
|
|
+ "dotnet Microsoft.ML.OnnxRuntime.PerfTool <onnx-model-path> <input-file-path> <iteration-count>"
|
2018-11-28 03:01:28 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void PrintReport(DateTime[] timestamps, int iterations)
|
|
|
|
|
{
|
|
|
|
|
Console.WriteLine("Model Load Time = " + (timestamps[(int)TimingPoint.ModelLoaded] - timestamps[(int)TimingPoint.Start]).TotalMilliseconds);
|
|
|
|
|
Console.WriteLine("Input Load Time = " + (timestamps[(int)TimingPoint.InputLoaded] - timestamps[(int)TimingPoint.ModelLoaded]).TotalMilliseconds);
|
|
|
|
|
|
|
|
|
|
double totalRuntime = (timestamps[(int)TimingPoint.RunComplete] - timestamps[(int)TimingPoint.InputLoaded]).TotalMilliseconds;
|
|
|
|
|
double perIterationTime = totalRuntime / iterations;
|
|
|
|
|
|
|
|
|
|
Console.WriteLine("Total Run time for {0} iterations = {1}", iterations, totalRuntime);
|
|
|
|
|
Console.WriteLine("Per iteration time = {0}", perIterationTime);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|