mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-06-25 02:50:42 +00:00
Delete onnxruntime_exec
This commit is contained in:
parent
d23f01dcd9
commit
34afa0a598
7 changed files with 0 additions and 790 deletions
|
|
@ -418,21 +418,6 @@ if(WIN32)
|
|||
target_compile_options(onnx_test_runner_common PRIVATE -D_CRT_SECURE_NO_WARNINGS)
|
||||
endif()
|
||||
|
||||
set(onnxruntime_exec_src_dir ${TEST_SRC_DIR}/onnxruntime_exec)
|
||||
file(GLOB onnxruntime_exec_src
|
||||
"${onnxruntime_exec_src_dir}/*.cc"
|
||||
"${onnxruntime_exec_src_dir}/*.h"
|
||||
)
|
||||
|
||||
add_executable(onnxruntime_exec ${onnxruntime_exec_src})
|
||||
|
||||
target_include_directories(onnxruntime_exec PRIVATE ${ONNXRUNTIME_ROOT})
|
||||
# we need to force these dependencies to build first. just using target_link_libraries isn't sufficient
|
||||
add_dependencies(onnxruntime_exec ${onnxruntime_EXTERNAL_DEPENDENCIES})
|
||||
onnxruntime_add_include_to_target(onnxruntime_exec gsl)
|
||||
target_link_libraries(onnxruntime_exec PRIVATE ${onnx_test_libs})
|
||||
set_target_properties(onnxruntime_exec PROPERTIES FOLDER "ONNXRuntimeTest")
|
||||
|
||||
add_test(NAME onnx_test_pytorch_converted
|
||||
COMMAND onnx_test_runner ${PROJECT_SOURCE_DIR}/external/onnx/onnx/backend/test/data/pytorch-converted)
|
||||
add_test(NAME onnx_test_pytorch_operator
|
||||
|
|
|
|||
|
|
@ -1,32 +0,0 @@
|
|||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
class CmdParser {
|
||||
public:
|
||||
CmdParser(int argc, const char* argsv[]) {
|
||||
if (argc > 2) {
|
||||
for (int i = 1; i < argc; i += 2) {
|
||||
cmd_map_.insert({argsv[i], argsv[i + 1]});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const std::string* GetCommandArg(const std::string& option) const {
|
||||
auto value = cmd_map_.find(option);
|
||||
if (value != cmd_map_.cend()) {
|
||||
return &value->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<const std::string, const std::string> cmd_map_;
|
||||
};
|
||||
|
|
@ -1,113 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <iostream>
|
||||
#if !defined(_MSC_VER)
|
||||
// HRESULT is a 4-byte long on MSVC. We'll just make it a signed int here.
|
||||
typedef int HRESULT;
|
||||
// Success codes
|
||||
#define S_OK ((HRESULT)0L)
|
||||
#define S_FALSE ((HRESULT)1L)
|
||||
#endif
|
||||
|
||||
#include "Runtime.h"
|
||||
|
||||
enum class ExecutionStatus {
|
||||
OK = 0,
|
||||
MODEL_LOADING_FAILURE = 1,
|
||||
DATA_LOADING_FAILURE = 2,
|
||||
PREDICTION_FAILURE = 3,
|
||||
ORT_NOT_IMPLEMENTED = 5
|
||||
};
|
||||
|
||||
class Model {
|
||||
public:
|
||||
Model(const std::string& modelfile) {
|
||||
runtime_ = std::make_unique<WinMLRuntime>();
|
||||
LoadModel(modelfile);
|
||||
}
|
||||
|
||||
void Execute(const std::string& datafile) {
|
||||
struct stat s;
|
||||
if (stat(datafile.c_str(), &s) == 0) {
|
||||
if (s.st_mode & S_IFDIR) {
|
||||
exec_status_ = ExecutionStatus::ORT_NOT_IMPLEMENTED;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto input_reader = LoadTestFile(datafile);
|
||||
if (!input_reader) {
|
||||
exec_status_ = ExecutionStatus::DATA_LOADING_FAILURE;
|
||||
return;
|
||||
}
|
||||
|
||||
int sample = 0;
|
||||
while (!input_reader->Eof()) {
|
||||
std::map<std::string, std::vector<float>> outputs;
|
||||
|
||||
// Perform the test
|
||||
int hr = runtime_->Run(*input_reader);
|
||||
if (hr != 0) {
|
||||
std::cerr << "Failed to execute example" << std::endl;
|
||||
exec_status_ = ExecutionStatus::PREDICTION_FAILURE;
|
||||
return;
|
||||
}
|
||||
sample++;
|
||||
}
|
||||
}
|
||||
|
||||
ExecutionStatus GetStatus() const {
|
||||
return exec_status_;
|
||||
}
|
||||
|
||||
std::string GetStatusString() const {
|
||||
return GetStatusString(exec_status_);
|
||||
}
|
||||
|
||||
static std::string GetStatusString(ExecutionStatus exec_status) {
|
||||
switch (exec_status) {
|
||||
case ExecutionStatus::OK:
|
||||
return "OK";
|
||||
case ExecutionStatus::MODEL_LOADING_FAILURE:
|
||||
return "MODEL_LOADING_FAILURE";
|
||||
case ExecutionStatus::DATA_LOADING_FAILURE:
|
||||
return "DATA_LOADING_FAILURE";
|
||||
case ExecutionStatus::PREDICTION_FAILURE:
|
||||
return "PREDICTION_FAILURE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void LoadModel(const std::string& strfilepath) {
|
||||
std::wstring filepath(strfilepath.begin(), strfilepath.end());
|
||||
|
||||
auto status = runtime_->LoadModel(filepath);
|
||||
if (status.IsOK()) {
|
||||
std::cerr << "'" << strfilepath.c_str() << "' loaded successfully." << std::endl;
|
||||
} else {
|
||||
std::cerr << "Loading failed for '" << strfilepath.c_str() << "'" << std::endl;
|
||||
std::cerr << "-----------------------------" << std::endl;
|
||||
std::cerr << status.ErrorMessage() << std::endl;
|
||||
exec_status_ = ExecutionStatus::MODEL_LOADING_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<TestDataReader> LoadTestFile(const std::string& filepath) {
|
||||
std::wstring testfilepath(filepath.begin(), filepath.end());
|
||||
auto reader = TestDataReader::OpenReader(testfilepath);
|
||||
|
||||
if (!reader) {
|
||||
std::cerr << "Unable to load test data file " << filepath << std::endl;
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
||||
std::unique_ptr<WinMLRuntime> runtime_;
|
||||
ExecutionStatus exec_status_ = ExecutionStatus::OK;
|
||||
};
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
# Compile and Build Onnxruntime Executor
|
||||
```
|
||||
>> bld.bat
|
||||
```
|
||||
|
||||
Assuming the command was executed from (PATH_2_MONTREAL)\tests\onnxruntime_exec folder. This command will retrieve the latest version of Onnxruntime and build it in debug mode.
|
||||
Once build is done, open the onnxruntime_exec.sln and build it in debug mode for debugging.
|
||||
|
||||
# Loading Model
|
||||
```
|
||||
>> loturt_exec.exe -m modelfile
|
||||
```
|
||||
|
||||
The above command will load the model from modelfile and return the status of model loading [success/fail].
|
||||
|
||||
# Predicting with Model
|
||||
```
|
||||
>> loturt_exec.exe -m modelfile [-t testfile]
|
||||
```
|
||||
|
||||
[-t testfile] is optional. When specified, the loturt_exec.exe will compute prediction/score/probability/etc. on every row of the file using the model and output it to stdout in CSV form.
|
||||
The format of input testfile is CSV without any header. As of now 11/14, only ints/floats are supported type in CSV.
|
||||
|
||||
|
||||
# Model Debugging
|
||||
* Install python runtime for project Montreal.
|
||||
|
||||
```
|
||||
>> Powershell ./build.ps1
|
||||
```
|
||||
|
||||
* The first run will take the longest time. This is because we are setting up a python environment for the first time. Subsequent times will be quicker.
|
||||
* The python environment is located at runtime\Python
|
||||
* The build script will create and install the winmltools python package. To update this package, you will need to re-run the build script or copy the changed files into python\lib\site-packages\winmltools.
|
||||
|
||||
* Install CoreMLTools for Python 3:
|
||||
```
|
||||
mkdir coremltools
|
||||
git clone --recursive https://github.com/apple/coremltools.git
|
||||
runtime\python\python.exe -m pip install -e coremltools/
|
||||
```
|
||||
|
||||
* Run the test in local mode (don't run the following script in 'mode' other than local model for your testing.). You can use any python enviroment as long as winmltools are there.
|
||||
|
||||
```
|
||||
>> $(PATH_2_MONTREAL)\runtime\Python\python.exe fn_model_conversion.py -m local -j TAEF_JSONS -s MODEL_SAVE_PATH
|
||||
```
|
||||
|
||||
* Investigate the stdout of the above script to see where the model has problem. The model file is save in MODEL_SAVE_PATH. If its MODEL_LOADING_FAILURE or PREDICTION_FAILURE, run it through loturt_exec.exe. Unless loturt_exec.exe returns some prediction the model has problem.
|
||||
|
||||
|
||||
* Please note that **loturt_exec.exe is currently not working on Image models.**
|
||||
|
||||
* Get text representation of coreml model on console
|
||||
```
|
||||
tests\scrtips\model_viewer_coreml.py model.mlmodel
|
||||
```
|
||||
|
||||
* Get text representation of winml(onnx) model on console.
|
||||
```
|
||||
tests\scrtips\model_viewer.py model.onnx
|
||||
```
|
||||
|
|
@ -1,378 +0,0 @@
|
|||
//
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "TestDataReader.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <codecvt>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "core/graph/onnx_protobuf.h"
|
||||
#include "core/common/logging/sinks/clog_sink.h"
|
||||
#include "core/common/logging/logging.h"
|
||||
#include "core/framework/environment.h"
|
||||
#include "core/framework/data_types.h"
|
||||
#include "core/session/inference_session.h"
|
||||
#include "core/providers/cpu/cpu_execution_provider.h"
|
||||
|
||||
#include "test/compare_mlvalue.h"
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define ERROR_FILE_NOT_FOUND 2L
|
||||
#define ERROR_BAD_FORMAT 11L
|
||||
|
||||
#define O_BINARY 0x0000
|
||||
#endif
|
||||
|
||||
class WinMLRuntime {
|
||||
public:
|
||||
WinMLRuntime() {
|
||||
using namespace onnxruntime;
|
||||
using namespace ::onnxruntime::logging;
|
||||
|
||||
static std::unique_ptr<::onnxruntime::Environment> onnxruntime_env = nullptr;
|
||||
static std::once_flag env_flag;
|
||||
std::call_once(env_flag, []() { ::onnxruntime::Environment::Create(onnxruntime_env); });
|
||||
|
||||
static LoggingManager& s_default_logging_manager = DefaultLoggingManager();
|
||||
SessionOptions so;
|
||||
so.session_logid = "WinMLRuntime";
|
||||
|
||||
inference_session_ = std::make_unique<::onnxruntime::InferenceSession>(so, &s_default_logging_manager);
|
||||
}
|
||||
|
||||
::onnxruntime::common::Status LoadModel(const std::wstring& model_path) {
|
||||
::onnxruntime::common::Status result = inference_session_->Load(wstr2str(model_path));
|
||||
if (result.IsOK())
|
||||
result = inference_session_->Initialize();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void FillInBatchSize(std::vector<int64_t>& shape, int input_size, int feature_size) {
|
||||
if ((input_size % feature_size != 0) && (feature_size != -1))
|
||||
throw DataValidationException("Input count is not a multiple of dimension.");
|
||||
|
||||
int batch_size = feature_size == -1 ? 1 : input_size / feature_size;
|
||||
shape.insert(shape.begin(), batch_size);
|
||||
}
|
||||
|
||||
::onnxruntime::MLValue ReadTensorStrings(::onnxruntime::AllocatorPtr alloc, TestDataReader& inputs_reader,
|
||||
int feature_size, std::vector<int64_t> dims, bool variable_batch_size) {
|
||||
using namespace onnxruntime;
|
||||
|
||||
auto vec = inputs_reader.GetSampleStrings(feature_size, variable_batch_size);
|
||||
|
||||
std::vector<std::string> vec2;
|
||||
for (int i = 0; i < vec.size(); i++) {
|
||||
std::string str(vec[i].begin(), vec[i].end());
|
||||
vec2.push_back(str);
|
||||
}
|
||||
|
||||
if (variable_batch_size)
|
||||
FillInBatchSize(dims, gsl::narrow_cast<int>(vec.size()), feature_size);
|
||||
|
||||
TensorShape shape(dims);
|
||||
auto element_type = DataTypeImpl::GetType<std::string>();
|
||||
|
||||
void* buffer = alloc->Alloc(sizeof(std::string) * shape.Size());
|
||||
std::unique_ptr<Tensor> p_tensor = std::make_unique<Tensor>(element_type,
|
||||
shape,
|
||||
buffer,
|
||||
alloc->Info(), alloc);
|
||||
|
||||
std::string* p = p_tensor->template MutableData<std::string>();
|
||||
for (int i = 0; i < vec.size(); i++) {
|
||||
p[i] = std::string(vec[i].begin(), vec[i].end());
|
||||
}
|
||||
|
||||
::onnxruntime::MLValue result;
|
||||
result.Init(p_tensor.release(),
|
||||
DataTypeImpl::GetType<Tensor>(),
|
||||
DataTypeImpl::GetType<Tensor>()->GetDeleteFunc());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
::onnxruntime::MLValue ReadTensor(::onnxruntime::AllocatorPtr alloc, TestDataReader& inputs_reader,
|
||||
int feature_size, std::vector<int64_t> dims, bool variable_batch_size) {
|
||||
using namespace onnxruntime;
|
||||
|
||||
auto vec = inputs_reader.GetSample<T>(feature_size, variable_batch_size);
|
||||
|
||||
if (variable_batch_size)
|
||||
FillInBatchSize(dims, gsl::narrow_cast<int>(vec.size()), feature_size);
|
||||
|
||||
::onnxruntime::TensorShape shape(dims);
|
||||
auto location = alloc->Info();
|
||||
auto element_type = ::onnxruntime::DataTypeImpl::GetType<T>();
|
||||
void* buffer = alloc->Alloc(element_type->Size() * shape.Size());
|
||||
|
||||
if (vec.size() > 0) {
|
||||
memcpy(buffer, &vec[0], element_type->Size() * shape.Size());
|
||||
}
|
||||
|
||||
std::unique_ptr<Tensor> p_tensor = std::make_unique<::onnxruntime::Tensor>(element_type,
|
||||
shape,
|
||||
buffer,
|
||||
location,
|
||||
alloc);
|
||||
|
||||
::onnxruntime::MLValue result;
|
||||
result.Init(p_tensor.release(),
|
||||
::onnxruntime::DataTypeImpl::GetType<::onnxruntime::Tensor>(),
|
||||
::onnxruntime::DataTypeImpl::GetType<::onnxruntime::Tensor>()->GetDeleteFunc());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template <typename V>
|
||||
onnxruntime::MLValue ReadTensorForMapStringToScalar(TestDataReader& inputs_reader) {
|
||||
auto vec = inputs_reader.GetSample<V>(-1);
|
||||
|
||||
auto data = std::make_unique<std::map<std::string, V>>();
|
||||
for (int i = 0; i < vec.size(); i++) {
|
||||
// keys start at "1" so convert index to string key based on that
|
||||
data->insert({std::to_string(i + 1), vec[i]});
|
||||
}
|
||||
|
||||
::onnxruntime::MLValue result;
|
||||
result.Init(data.release(),
|
||||
::onnxruntime::DataTypeImpl::GetType<std::map<std::string, V>>(),
|
||||
::onnxruntime::DataTypeImpl::GetType<std::map<std::string, V>>()->GetDeleteFunc());
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int Run(TestDataReader& inputs_reader) {
|
||||
using namespace onnxruntime;
|
||||
int hr = 0;
|
||||
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
|
||||
|
||||
// Create CPU input tensors
|
||||
::onnxruntime::NameMLValMap feed;
|
||||
inputs_reader.BufferNextSample();
|
||||
if (inputs_reader.Eof())
|
||||
return 0;
|
||||
|
||||
bool variable_batch_size = false;
|
||||
auto inputs_pairs = inference_session_->GetModelInputs();
|
||||
if (!inputs_pairs.first.IsOK()) {
|
||||
auto error = inputs_pairs.first.ErrorMessage();
|
||||
return inputs_pairs.first.Code();
|
||||
}
|
||||
|
||||
auto& inputs = *(inputs_pairs.second);
|
||||
for (size_t index = 0, end = inputs.size(); index < end; ++index) {
|
||||
MLValue mlvalue;
|
||||
const onnxruntime::NodeArg& input = *(inputs[index]);
|
||||
const ONNX_NAMESPACE::TensorShapeProto* input_shape = input.Shape();
|
||||
if (input.Name().empty())
|
||||
continue;
|
||||
|
||||
auto type = input.Type();
|
||||
|
||||
std::vector<int64_t> shape;
|
||||
int feature_size = -1;
|
||||
|
||||
//Previous graph input was variable length that consumed entire input line_ so fetch new input line_.
|
||||
if (variable_batch_size)
|
||||
inputs_reader.BufferNextSample();
|
||||
|
||||
//This graph input may or may not be variable length.
|
||||
//REVIEW mzs: this can cause issues if we had variable-input followed by fixed input followed by variable-input where
|
||||
//fixed-input consumed all of the input line_. *Ideally each graph input should be on its own line_*.
|
||||
variable_batch_size = false;
|
||||
|
||||
//If the shape is not available then read everything into the input tensor.
|
||||
//feature_size = -1 indicates this condition.
|
||||
if (input_shape) {
|
||||
feature_size = 0;
|
||||
auto dims = input_shape->dim();
|
||||
for (auto dim : dims) {
|
||||
if (dim.has_dim_param())
|
||||
variable_batch_size = true;
|
||||
else {
|
||||
auto dim_value = dim.dim_value();
|
||||
shape.push_back(dim_value);
|
||||
feature_size = gsl::narrow_cast<int>(feature_size ? feature_size * dim_value : dim_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//REVIEW mzs: Here an assumption is made that all the input columns are for the map.
|
||||
//The supported map types in onnxruntime seen so far are <string, string> or <string, int64>.
|
||||
if (*type == "map(string,tensor(int64))") {
|
||||
// check if really map(string, int64), which is all we currently support
|
||||
bool is_map_value_scalar = input.TypeAsProto()->map_type().value_type().tensor_type().shape().dim_size() == 0;
|
||||
|
||||
if (is_map_value_scalar) {
|
||||
mlvalue = ReadTensorForMapStringToScalar<int64_t>(inputs_reader);
|
||||
feed.insert(std::make_pair(input.Name(), mlvalue));
|
||||
} else {
|
||||
throw DataValidationException("Unsupported input type: " + std::string(*type));
|
||||
}
|
||||
} else if (*type == "map(string,tensor(float))" || *type == "map(string,tensor(double))") {
|
||||
// check if really map(string, float) or map(string, double), which is all we currently support
|
||||
bool is_map_value_scalar = input.TypeAsProto()->map_type().value_type().tensor_type().shape().dim_size() == 0;
|
||||
|
||||
if (is_map_value_scalar) {
|
||||
mlvalue = ReadTensorForMapStringToScalar<float>(inputs_reader);
|
||||
feed.insert({input.Name(), mlvalue});
|
||||
} else {
|
||||
throw DataValidationException("Unsupported input type: " + std::string(*type));
|
||||
}
|
||||
} else {
|
||||
if (*type == "tensor(double)" || *type == "tensor(float)") {
|
||||
// If double is used in the following statement, following error occurs.
|
||||
// Tensor type mismatch, caller expects elements to be float while tensor contains double Error from operator
|
||||
mlvalue = ReadTensor<float>(TestCPUExecutionProvider().GetAllocator(0, OrtMemTypeDefault), inputs_reader, feature_size, shape, variable_batch_size);
|
||||
} else if (*type == "tensor(int64)")
|
||||
mlvalue = ReadTensor<int64_t>(TestCPUExecutionProvider().GetAllocator(0, OrtMemTypeDefault), inputs_reader, feature_size, shape, variable_batch_size);
|
||||
else if (*type == "tensor(string)")
|
||||
mlvalue = ReadTensorStrings(TestCPUExecutionProvider().GetAllocator(0, OrtMemTypeDefault), inputs_reader, feature_size, shape, variable_batch_size);
|
||||
else
|
||||
throw DataValidationException("Unsupported input type: " + std::string(*type));
|
||||
|
||||
feed.insert(std::make_pair(input.Name(), mlvalue));
|
||||
}
|
||||
}
|
||||
|
||||
// Create output feed
|
||||
std::vector<std::string> output_names;
|
||||
for (auto const& outp : *(inference_session_->GetModelOutputs().second)) {
|
||||
output_names.push_back(outp->Name());
|
||||
}
|
||||
|
||||
std::cout.precision(12);
|
||||
std::string separator = "";
|
||||
// Invoke the net
|
||||
std::vector<::onnxruntime::MLValue> outputMLValue;
|
||||
RunOptions run_options;
|
||||
::onnxruntime::common::Status result = inference_session_->Run(run_options, feed, output_names, &outputMLValue);
|
||||
if (result.IsOK()) {
|
||||
auto outputMeta = inference_session_->GetModelOutputs().second;
|
||||
// Peel the data off the CPU
|
||||
for (unsigned int i = 0; i < output_names.size(); i++) {
|
||||
::onnxruntime::MLValue& output = outputMLValue[i];
|
||||
const ::onnxruntime::Tensor* ctensor = nullptr;
|
||||
|
||||
if (output.IsTensor()) {
|
||||
ctensor = &output.Get<Tensor>();
|
||||
|
||||
ONNX_NAMESPACE::ValueInfoProto expected_output_info = (*outputMeta)[i]->ToProto();
|
||||
std::pair<COMPARE_RESULT, std::string> ret = VerifyValueInfo(expected_output_info, (OrtValue*)&output);
|
||||
COMPARE_RESULT compare_result = ret.first;
|
||||
compare_result = ret.first;
|
||||
if (compare_result != COMPARE_RESULT::SUCCESS) {
|
||||
switch (compare_result) {
|
||||
case COMPARE_RESULT::NOT_SUPPORT:
|
||||
throw std::runtime_error("Unsupported output type in onnxruntime model: " + std::string((*outputMeta)[i]->Name()));
|
||||
break;
|
||||
case COMPARE_RESULT::SHAPE_MISMATCH:
|
||||
throw std::runtime_error("Output shape mismatch in onnxruntime model: " + std::string((*outputMeta)[i]->Name()));
|
||||
break;
|
||||
case COMPARE_RESULT::TYPE_MISMATCH:
|
||||
throw std::runtime_error("Output type mismatch in onnxruntime model: " + std::string((*outputMeta)[i]->Name()));
|
||||
break;
|
||||
default:
|
||||
throw std::runtime_error("Unknown error in onnxruntime model: " + std::string((*outputMeta)[i]->Name()));
|
||||
}
|
||||
}
|
||||
|
||||
//REVIEW mzs: Map output types are not tested because I couldn't find any tests for that.
|
||||
if (ctensor->DataType() == ::onnxruntime::DataTypeImpl::GetType<std::map<int64_t, float>>()) {
|
||||
const std::map<int64_t, float>* ci = &output.Get<std::map<int64_t, float>>();
|
||||
for (const auto& p : *ci) {
|
||||
std::cout << separator << p.second;
|
||||
separator = ",";
|
||||
}
|
||||
} else if (ctensor->DataType() == ::onnxruntime::DataTypeImpl::GetType<std::map<std::string, float>>()) {
|
||||
const std::map<std::string, float>* ci = &output.Get<std::map<std::string, float>>();
|
||||
for (const auto& p : *ci) {
|
||||
std::cout << separator << p.second;
|
||||
separator = ",";
|
||||
}
|
||||
} else if (ctensor->DataType() == ::onnxruntime::DataTypeImpl::GetType<float>()) {
|
||||
const float* cdata = ctensor->template Data<float>();
|
||||
for (int ci = 0; ci < ctensor->Shape().Size(); ci++) {
|
||||
std::cout << separator << cdata[ci];
|
||||
separator = ",";
|
||||
}
|
||||
} else if (ctensor->DataType() == ::onnxruntime::DataTypeImpl::GetType<int64_t>()) {
|
||||
const int64_t* cdata = ctensor->template Data<int64_t>();
|
||||
for (int ci = 0; ci < ctensor->Shape().Size(); ci++) {
|
||||
std::cout << separator << cdata[ci];
|
||||
separator = ",";
|
||||
}
|
||||
} else if (ctensor->DataType() == ::onnxruntime::DataTypeImpl::GetType<std::string>()) {
|
||||
const std::string* cdata = ctensor->template Data<std::string>();
|
||||
for (int ci = 0; ci < ctensor->Shape().Size(); ci++) {
|
||||
std::cout << separator << cdata[ci];
|
||||
separator = ",";
|
||||
}
|
||||
} else {
|
||||
throw DataValidationException("Unsupported output type in onnxruntime model: " + std::string((*outputMeta)[i]->Name()));
|
||||
}
|
||||
} else if (output.Type() == ::onnxruntime::DataTypeImpl::GetType<::onnxruntime::VectorMapStringToFloat>()) {
|
||||
auto& cdata = output.Get<::onnxruntime::VectorMapStringToFloat>();
|
||||
for (int ci = 0; ci < cdata.size(); ci++) {
|
||||
for (const auto& p : cdata[ci]) {
|
||||
std::cout << separator << p.second;
|
||||
separator = ",";
|
||||
}
|
||||
}
|
||||
} else if (output.Type() == ::onnxruntime::DataTypeImpl::GetType<::onnxruntime::VectorMapInt64ToFloat>()) {
|
||||
auto& cdata = output.Get<::onnxruntime::VectorMapInt64ToFloat>();
|
||||
for (int ci = 0; ci < cdata.size(); ci++) {
|
||||
for (const auto& p : cdata[ci]) {
|
||||
std::cout << separator << p.second;
|
||||
separator = ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
} else {
|
||||
std::cerr << result.ErrorMessage() << std::endl;
|
||||
hr = result.Code();
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<::onnxruntime::InferenceSession> inference_session_;
|
||||
|
||||
static ::onnxruntime::logging::LoggingManager& DefaultLoggingManager() {
|
||||
using namespace onnxruntime;
|
||||
std::string default_logger_id{"Default"};
|
||||
|
||||
static logging::LoggingManager default_logging_manager{
|
||||
std::unique_ptr<logging::ISink>{new ::onnxruntime::logging::CLogSink{}},
|
||||
logging::Severity::kWARNING, false,
|
||||
logging::LoggingManager::InstanceType::Default,
|
||||
&default_logger_id};
|
||||
|
||||
return default_logging_manager;
|
||||
}
|
||||
|
||||
static ::onnxruntime::IExecutionProvider& TestCPUExecutionProvider() {
|
||||
static ::onnxruntime::CPUExecutionProviderInfo info;
|
||||
static ::onnxruntime::CPUExecutionProvider cpu_provider(info);
|
||||
return cpu_provider;
|
||||
}
|
||||
};
|
||||
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <cmath>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <cmath>
|
||||
#include <locale>
|
||||
#include <codecvt>
|
||||
|
||||
std::string wstr2str(const std::wstring& wstr) {
|
||||
std::string str = std::wstring_convert<std::codecvt_utf8<wchar_t>>().to_bytes(wstr);
|
||||
return str;
|
||||
}
|
||||
|
||||
class DataValidationException : public std::exception {
|
||||
public:
|
||||
DataValidationException(const std::string& str) : str_(str) {
|
||||
}
|
||||
const char* what() const noexcept override {
|
||||
return str_.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string str_;
|
||||
};
|
||||
|
||||
class TestDataReader {
|
||||
public:
|
||||
static std::unique_ptr<TestDataReader> OpenReader(std::wstring data_file);
|
||||
|
||||
void BufferNextSample();
|
||||
bool Eof();
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> GetSample(int sample_count, bool variable_batch_size = false);
|
||||
|
||||
std::vector<std::wstring> GetSampleStrings(int sample_count, bool variable_batch_size = false);
|
||||
|
||||
private:
|
||||
std::wstring line_;
|
||||
std::wifstream reader_stream_;
|
||||
std::unique_ptr<std::wstringstream> row_stream_;
|
||||
};
|
||||
|
||||
bool TestDataReader::Eof() {
|
||||
return reader_stream_.eof();
|
||||
}
|
||||
|
||||
void TestDataReader::BufferNextSample() {
|
||||
if (Eof())
|
||||
return;
|
||||
|
||||
std::getline(reader_stream_, line_);
|
||||
|
||||
if (Eof())
|
||||
return;
|
||||
|
||||
row_stream_ = std::make_unique<std::wstringstream>(line_);
|
||||
std::wstring feature;
|
||||
std::getline(*row_stream_, feature, L','); //Skip the Label which is actually.
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
std::vector<T> TestDataReader::GetSample(int sample_count, bool variable_batch_size) {
|
||||
assert(sample_count == -1 || sample_count > 0);
|
||||
|
||||
std::wstring feature;
|
||||
std::vector<T> result;
|
||||
|
||||
int s = 0;
|
||||
while ((s++ < sample_count || sample_count == -1 || variable_batch_size) &&
|
||||
std::getline(*row_stream_, feature, L',')) // -1 means read all data in the sample
|
||||
{
|
||||
T feature_value;
|
||||
std::wstringstream feature_convert(feature);
|
||||
feature_convert >> feature_value;
|
||||
if (feature_convert.fail()) {
|
||||
feature_value = (T)NAN;
|
||||
}
|
||||
|
||||
result.push_back(feature_value);
|
||||
}
|
||||
|
||||
if (line_.length() > 0 && line_.back() == L',')
|
||||
result.push_back((T)NAN);
|
||||
|
||||
if (sample_count != -1 && !variable_batch_size) {
|
||||
//Remove the last NAN inserted if it is not part of this feature.
|
||||
if (result.size() == sample_count + 1)
|
||||
result.pop_back();
|
||||
|
||||
if (result.size() != sample_count)
|
||||
throw DataValidationException("Not enough features in sample.");
|
||||
}
|
||||
|
||||
if (variable_batch_size && (result.size() % sample_count != 0) && (sample_count != -1))
|
||||
throw DataValidationException("Input count is not a multiple of dimension.");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<std::wstring> TestDataReader::GetSampleStrings(int sample_count, bool variable_batch_size) {
|
||||
std::wstring feature;
|
||||
std::vector<std::wstring> result;
|
||||
|
||||
int s = 0;
|
||||
while (s < sample_count || sample_count == -1 || variable_batch_size) // -1 means read all data in the sample
|
||||
{
|
||||
if (std::getline(*row_stream_, feature, L','))
|
||||
result.push_back(feature);
|
||||
else {
|
||||
if (sample_count == -1 || variable_batch_size)
|
||||
break;
|
||||
|
||||
throw DataValidationException("Not enough features in sample.");
|
||||
}
|
||||
s++;
|
||||
}
|
||||
|
||||
if (line_.length() > 0 && line_.back() == L',')
|
||||
result.push_back(L"");
|
||||
|
||||
if (variable_batch_size && (result.size() % sample_count != 0) && (sample_count != -1))
|
||||
throw DataValidationException("Input count is not a multiple of dimension.");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::unique_ptr<TestDataReader> TestDataReader::OpenReader(std::wstring dataFile) {
|
||||
auto reader = std::make_unique<TestDataReader>();
|
||||
|
||||
reader->reader_stream_.open(wstr2str(dataFile));
|
||||
if (!reader->reader_stream_) {
|
||||
reader = nullptr;
|
||||
}
|
||||
|
||||
return reader;
|
||||
}
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "CmdParser.h"
|
||||
#include "Model.h"
|
||||
#include "TestDataReader.h"
|
||||
|
||||
void print_cmd_option() {
|
||||
std::cerr << "onnxruntime_exec.exe -m model_file [-t testdata]" << std::endl;
|
||||
}
|
||||
|
||||
int main(int argc, const char* args[]) {
|
||||
try {
|
||||
CmdParser parser(argc, args);
|
||||
const std::string* modelfile = parser.GetCommandArg("-m");
|
||||
if (!modelfile) {
|
||||
std::cerr << "WinML model file is required." << std::endl;
|
||||
print_cmd_option();
|
||||
return -1;
|
||||
}
|
||||
|
||||
Model model(*modelfile);
|
||||
|
||||
if (model.GetStatus() == ExecutionStatus::OK) {
|
||||
std::cerr << "Done loading model: " << modelfile->c_str() << std::endl;
|
||||
const std::string* testfile = parser.GetCommandArg("-t");
|
||||
if (testfile) {
|
||||
model.Execute(*testfile);
|
||||
}
|
||||
}
|
||||
|
||||
std::cerr << "Execution Status: " << model.GetStatusString() << std::endl;
|
||||
} catch (const DataValidationException& e) {
|
||||
std::cerr << "Execution Status: " << Model::GetStatusString(ExecutionStatus::DATA_LOADING_FAILURE) << std::endl;
|
||||
std::cout << "Exception msg: " << e.what() << std::endl;
|
||||
} catch (const std::exception& e) {
|
||||
std::cerr << "Execution Status: " << Model::GetStatusString(ExecutionStatus::PREDICTION_FAILURE) << std::endl;
|
||||
std::cout << "Exception msg: " << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue