mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-30 20:18:08 +00:00
Validate input shapes. (#1352)
* Validate input shapes. * Cache some input def metadata * Make some methods const and check for negative values of dims instead of just -1. * Fix shape inferencing test. * Fix testLabelEncoder test * Fix more tests * Fix more tests * Use size_t for loop variable
This commit is contained in:
parent
638398e675
commit
4cbc6e1cf5
16 changed files with 176 additions and 96 deletions
|
|
@ -62,7 +62,7 @@ namespace Microsoft.ML.OnnxRuntime.Tests
|
|||
// Set the graph optimization level for this session.
|
||||
SessionOptions options = new SessionOptions();
|
||||
options.SetSessionGraphOptimizationLevel(graphOptimizationLevel);
|
||||
if(disableSequentialExecution) options.DisableSequentialExecution();
|
||||
if (disableSequentialExecution) options.DisableSequentialExecution();
|
||||
|
||||
using (var session = new InferenceSession(modelPath, options))
|
||||
{
|
||||
|
|
@ -141,25 +141,6 @@ namespace Microsoft.ML.OnnxRuntime.Tests
|
|||
session.Dispose();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
private void ThrowWrongDimensions()
|
||||
{
|
||||
var tuple = OpenSessionSqueezeNet();
|
||||
var session = tuple.Item1;
|
||||
var inputMeta = session.InputMetadata;
|
||||
var container = new List<NamedOnnxValue>();
|
||||
var inputData = new float[] { 0.1f, 0.2f, 0.3f };
|
||||
var tensor = new DenseTensor<float>(inputData, new int[] { 1, 3 });
|
||||
container.Add(NamedOnnxValue.CreateFromTensor<float>("data_0", tensor));
|
||||
var ex = Assert.Throws<OnnxRuntimeException>(() => session.Run(container));
|
||||
Assert.True(
|
||||
!string.IsNullOrEmpty(ex.Message) &&
|
||||
ex.Message.StartsWith("[ErrorCode:Fail]") &&
|
||||
ex.Message.Contains("X num_dims does not match W num_dims. X: {1,3} W: {64,3,3,3}")
|
||||
);
|
||||
session.Dispose();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
private void ThrowExtraInputs()
|
||||
{
|
||||
|
|
@ -220,7 +201,8 @@ namespace Microsoft.ML.OnnxRuntime.Tests
|
|||
|
||||
var disableContribOpsEnvVar = Environment.GetEnvironmentVariable("DisableContribOps");
|
||||
var isContribOpsDisabled = (disableContribOpsEnvVar != null) ? disableContribOpsEnvVar.Equals("ON") : false;
|
||||
if (isContribOpsDisabled) {
|
||||
if (isContribOpsDisabled)
|
||||
{
|
||||
skipModels.Add("test_tiny_yolov2");
|
||||
}
|
||||
|
||||
|
|
@ -661,7 +643,7 @@ namespace Microsoft.ML.OnnxRuntime.Tests
|
|||
{
|
||||
var gpu = Environment.GetEnvironmentVariable("TESTONGPU");
|
||||
var tuple = OpenSessionSqueezeNet(0); // run on deviceID 0
|
||||
float[] expectedOutput = LoadTensorFromFile(@"bench.expected_out");
|
||||
float[] expectedOutput = LoadTensorFromFile(@"bench.expected_out");
|
||||
|
||||
using (var session = tuple.Item1)
|
||||
{
|
||||
|
|
@ -671,7 +653,7 @@ namespace Microsoft.ML.OnnxRuntime.Tests
|
|||
var container = new List<NamedOnnxValue>();
|
||||
container.Add(NamedOnnxValue.CreateFromTensor<float>("data_0", tensor));
|
||||
var res = session.Run(container);
|
||||
var resultArray = res.First().AsTensor<float>().ToArray();
|
||||
var resultArray = res.First().AsTensor<float>().ToArray();
|
||||
Assert.Equal(expectedOutput, resultArray, new floatComparer());
|
||||
}
|
||||
}
|
||||
|
|
@ -782,8 +764,8 @@ namespace Microsoft.ML.OnnxRuntime.Tests
|
|||
{
|
||||
public GpuFact()
|
||||
{
|
||||
var testOnGpu = System.Environment.GetEnvironmentVariable("TESTONGPU");
|
||||
if (testOnGpu == null || !testOnGpu.Equals("ON") )
|
||||
var testOnGpu = System.Environment.GetEnvironmentVariable("TESTONGPU");
|
||||
if (testOnGpu == null || !testOnGpu.Equals("ON"))
|
||||
{
|
||||
Skip = "GPU testing not enabled";
|
||||
}
|
||||
|
|
|
|||
BIN
csharp/testdata/test_types_DOUBLE.pb
vendored
BIN
csharp/testdata/test_types_DOUBLE.pb
vendored
Binary file not shown.
BIN
csharp/testdata/test_types_FLOAT.pb
vendored
BIN
csharp/testdata/test_types_FLOAT.pb
vendored
Binary file not shown.
BIN
csharp/testdata/test_types_INT16.pb
vendored
BIN
csharp/testdata/test_types_INT16.pb
vendored
Binary file not shown.
BIN
csharp/testdata/test_types_INT32.pb
vendored
BIN
csharp/testdata/test_types_INT32.pb
vendored
Binary file not shown.
BIN
csharp/testdata/test_types_INT64.pb
vendored
BIN
csharp/testdata/test_types_INT64.pb
vendored
Binary file not shown.
BIN
csharp/testdata/test_types_UINT16.pb
vendored
BIN
csharp/testdata/test_types_UINT16.pb
vendored
Binary file not shown.
BIN
csharp/testdata/test_types_UINT32.pb
vendored
BIN
csharp/testdata/test_types_UINT32.pb
vendored
Binary file not shown.
BIN
csharp/testdata/test_types_UINT64.pb
vendored
BIN
csharp/testdata/test_types_UINT64.pb
vendored
Binary file not shown.
BIN
csharp/testdata/test_types_UINT8.pb
vendored
BIN
csharp/testdata/test_types_UINT8.pb
vendored
Binary file not shown.
|
|
@ -11,7 +11,7 @@ namespace onnxruntime {
|
|||
TensorShape::TensorShape(const std::vector<int64_t>& dims) : std::vector<int64_t>(dims) {
|
||||
}
|
||||
|
||||
TensorShape::TensorShape(std::vector<int64_t>&& dims) : std::vector<int64_t>(dims) {
|
||||
TensorShape::TensorShape(std::vector<int64_t>&& dims) : std::vector<int64_t>(std::move(dims)) {
|
||||
}
|
||||
|
||||
TensorShape::TensorShape(const std::initializer_list<int64_t>& dims) : std::vector<int64_t>(dims) {
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ inline std::basic_string<T> GetCurrentTimeString() {
|
|||
} // namespace
|
||||
|
||||
InferenceSession::InferenceSession(const SessionOptions& session_options,
|
||||
logging::LoggingManager* logging_manager)
|
||||
logging::LoggingManager* logging_manager)
|
||||
: session_options_{session_options},
|
||||
graph_transformation_mgr_{session_options_.max_num_graph_transformation_steps},
|
||||
logging_manager_{logging_manager},
|
||||
|
|
@ -559,7 +559,41 @@ int InferenceSession::GetCurrentNumRuns() const {
|
|||
return current_num_runs_.load();
|
||||
}
|
||||
|
||||
common::Status InferenceSession::CheckTypes(MLDataType actual, MLDataType expected) {
|
||||
common::Status InferenceSession::CheckShapes(const std::string& input_name,
|
||||
const TensorShape& input_shape,
|
||||
const TensorShape& expected_shape) const {
|
||||
auto input_shape_sz = input_shape.NumDimensions();
|
||||
auto expected_shape_sz = expected_shape.NumDimensions();
|
||||
if (input_shape_sz != expected_shape_sz) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "Invalid rank for input: ",
|
||||
input_name,
|
||||
" Got: ", input_shape_sz, " Expected: ", expected_shape_sz);
|
||||
}
|
||||
|
||||
std::vector<int> invalid_dim_indices;
|
||||
for (size_t i = 0; i < input_shape_sz; ++i) {
|
||||
if (expected_shape[i] < 0) {
|
||||
continue; // this represents a symbolic shape dimension
|
||||
}
|
||||
if (input_shape[i] != expected_shape[i]) {
|
||||
invalid_dim_indices.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (!invalid_dim_indices.empty()) {
|
||||
std::ostringstream ostr;
|
||||
ostr << "Got invalid dimensions for input: " << input_name << " for the following indices\n";
|
||||
for (size_t i = 0, end = invalid_dim_indices.size(); i < end; ++i) {
|
||||
int idx = invalid_dim_indices[i];
|
||||
ostr << " index: " << idx << " Got: " << input_shape[idx] << " Expected: " << expected_shape[idx] << "\n";
|
||||
}
|
||||
return Status(ONNXRUNTIME, INVALID_ARGUMENT, ostr.str());
|
||||
}
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
static common::Status CheckTypes(MLDataType actual, MLDataType expected) {
|
||||
if (actual == expected) {
|
||||
return Status::OK();
|
||||
}
|
||||
|
|
@ -570,7 +604,7 @@ common::Status InferenceSession::CheckTypes(MLDataType actual, MLDataType expect
|
|||
}
|
||||
|
||||
common::Status InferenceSession::ValidateInputs(const std::vector<std::string>& feed_names,
|
||||
const std::vector<OrtValue>& feeds) {
|
||||
const std::vector<OrtValue>& feeds) const {
|
||||
if (feed_names.size() != feeds.size()) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT,
|
||||
"Size mismatch: feed_names has ",
|
||||
|
|
@ -587,12 +621,25 @@ common::Status InferenceSession::ValidateInputs(const std::vector<std::string>&
|
|||
"Invalid Feed Input Name:", feed_name);
|
||||
}
|
||||
|
||||
auto expected_type = utils::GetMLDataType(*iter->second);
|
||||
auto expected_type = iter->second.ml_data_type;
|
||||
auto& input_ml_value = feeds.at(i);
|
||||
if (input_ml_value.IsTensor()) {
|
||||
// check for type
|
||||
if (!expected_type->IsTensorType()) {
|
||||
return ORT_MAKE_STATUS(ONNXRUNTIME, INVALID_ARGUMENT, "Input with name: ",
|
||||
feed_name, " is not expected to be of type tensor.");
|
||||
}
|
||||
|
||||
auto expected_element_type = expected_type->AsTensorType()->GetElementType();
|
||||
auto input_element_type = input_ml_value.Get<Tensor>().DataType();
|
||||
ORT_RETURN_IF_ERROR(CheckTypes(input_element_type, expected_element_type));
|
||||
|
||||
// check for shape
|
||||
const auto& expected_shape = iter->second.tensor_shape;
|
||||
if (expected_shape.NumDimensions() > 0) {
|
||||
const auto& input_shape = input_ml_value.Get<Tensor>().Shape();
|
||||
ORT_RETURN_IF_ERROR(CheckShapes(feed_name, input_shape, expected_shape));
|
||||
}
|
||||
} else {
|
||||
auto input_type = input_ml_value.Type();
|
||||
ORT_RETURN_IF_ERROR(CheckTypes(input_type, expected_type));
|
||||
|
|
@ -603,7 +650,7 @@ common::Status InferenceSession::ValidateInputs(const std::vector<std::string>&
|
|||
}
|
||||
|
||||
common::Status InferenceSession::ValidateOutputs(const std::vector<std::string>& output_names,
|
||||
const std::vector<OrtValue>* p_fetches) {
|
||||
const std::vector<OrtValue>* p_fetches) const {
|
||||
if (p_fetches == nullptr) {
|
||||
return common::Status(common::ONNXRUNTIME, common::INVALID_ARGUMENT,
|
||||
"Output vector pointer is NULL");
|
||||
|
|
@ -839,7 +886,13 @@ common::Status InferenceSession::SaveModelMetadata(const onnxruntime::Model& mod
|
|||
auto add_inputs = [this](const InputDefList& inputs) {
|
||||
input_def_map_.reserve(inputs.size());
|
||||
for (auto elem : inputs) {
|
||||
input_def_map_.insert({elem->Name(), elem});
|
||||
auto elem_type = utils::GetMLDataType(*elem);
|
||||
auto elem_shape_proto = elem->Shape();
|
||||
input_def_map_.insert({elem->Name(), InputDefMetaData(elem,
|
||||
elem_type,
|
||||
elem_shape_proto
|
||||
? utils::GetTensorShapeFromTensorShapeProto(*elem_shape_proto)
|
||||
: TensorShape())});
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -889,7 +942,7 @@ const logging::Logger& InferenceSession::CreateLoggerForRun(const RunOptions& ru
|
|||
severity = session_logger_->GetSeverity();
|
||||
} else {
|
||||
ORT_ENFORCE(run_options.run_log_severity_level >= 0 &&
|
||||
run_options.run_log_severity_level <= static_cast<int>(logging::Severity::kFATAL),
|
||||
run_options.run_log_severity_level <= static_cast<int>(logging::Severity::kFATAL),
|
||||
"Invalid run log severity level. Not a valid onnxruntime::logging::Severity value: ",
|
||||
run_options.run_log_severity_level);
|
||||
severity = static_cast<logging::Severity>(run_options.run_log_severity_level);
|
||||
|
|
@ -919,7 +972,7 @@ void InferenceSession::InitLogger(logging::LoggingManager* logging_manager) {
|
|||
severity = logging::LoggingManager::DefaultLogger().GetSeverity();
|
||||
} else {
|
||||
ORT_ENFORCE(session_options_.session_log_severity_level >= 0 &&
|
||||
session_options_.session_log_severity_level <= static_cast<int>(logging::Severity::kFATAL),
|
||||
session_options_.session_log_severity_level <= static_cast<int>(logging::Severity::kFATAL),
|
||||
"Invalid session log severity level. Not a valid onnxruntime::logging::Severity value: ",
|
||||
session_options_.session_log_severity_level);
|
||||
severity = static_cast<logging::Severity>(session_options_.session_log_severity_level);
|
||||
|
|
|
|||
|
|
@ -367,11 +367,13 @@ class InferenceSession {
|
|||
|
||||
void InitLogger(logging::LoggingManager* logging_manager);
|
||||
|
||||
static common::Status CheckTypes(MLDataType actual, MLDataType expected);
|
||||
common::Status CheckShapes(const std::string& input_name,
|
||||
const TensorShape& input_shape,
|
||||
const TensorShape& expected_shape) const;
|
||||
|
||||
common::Status ValidateInputs(const std::vector<std::string>& feed_names, const std::vector<OrtValue>& feeds);
|
||||
common::Status ValidateInputs(const std::vector<std::string>& feed_names, const std::vector<OrtValue>& feeds) const;
|
||||
|
||||
common::Status ValidateOutputs(const std::vector<std::string>& output_names, const std::vector<OrtValue>* p_fetches);
|
||||
common::Status ValidateOutputs(const std::vector<std::string>& output_names, const std::vector<OrtValue>* p_fetches) const;
|
||||
|
||||
common::Status WaitForNotification(Notification* p_executor_done, int64_t timeout_in_ms);
|
||||
|
||||
|
|
@ -416,7 +418,16 @@ class InferenceSession {
|
|||
|
||||
ModelMetadata model_metadata_;
|
||||
std::unordered_set<std::string> required_inputs_;
|
||||
std::unordered_map<std::string, const NodeArg*> input_def_map_;
|
||||
|
||||
struct InputDefMetaData {
|
||||
InputDefMetaData(const NodeArg* node_arg0, MLDataType ml_data_type0, TensorShape&& tensor_shape0)
|
||||
: node_arg(node_arg0), ml_data_type(ml_data_type0), tensor_shape(std::move(tensor_shape0)) {
|
||||
}
|
||||
const NodeArg* node_arg;
|
||||
MLDataType ml_data_type;
|
||||
TensorShape tensor_shape; // not applicable if the input is non-tensor type
|
||||
};
|
||||
std::unordered_map<std::string, InputDefMetaData> input_def_map_;
|
||||
OutputDefList output_def_list_;
|
||||
|
||||
// Threadpool for this session
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -164,7 +164,11 @@ void NchwcOptimizerTester(const std::function<void(NchwcTestHelper& helper)>& bu
|
|||
ASSERT_TRUE(session.Initialize().IsOK());
|
||||
|
||||
RunOptions run_options;
|
||||
ASSERT_TRUE(session.Run(run_options, helper.feeds_, helper.output_names_, &fetches).IsOK());
|
||||
auto status = session.Run(run_options, helper.feeds_, helper.output_names_, &fetches);
|
||||
if (!status.IsOK()) {
|
||||
std::cout << "Run failed with status message: " << status.ErrorMessage() << std::endl;
|
||||
}
|
||||
ASSERT_TRUE(status.IsOK());
|
||||
|
||||
if (level == TransformerLevel::Level3) {
|
||||
check_nchwc_graph(session);
|
||||
|
|
@ -702,7 +706,7 @@ TEST(NchwcOptimizerTests, ShapeInferencing) {
|
|||
ONNX_NAMESPACE::TypeProto type_proto;
|
||||
type_proto.mutable_tensor_type()->set_elem_type(ONNX_NAMESPACE::TensorProto_DataType_FLOAT);
|
||||
type_proto.mutable_tensor_type()->mutable_shape()->add_dim()->set_dim_value(1);
|
||||
type_proto.mutable_tensor_type()->mutable_shape()->add_dim()->set_dim_value(32);
|
||||
type_proto.mutable_tensor_type()->mutable_shape()->add_dim()->set_dim_value(3);
|
||||
type_proto.mutable_tensor_type()->mutable_shape()->add_dim()->set_dim_param("input_height");
|
||||
type_proto.mutable_tensor_type()->mutable_shape()->add_dim()->set_dim_param("input_width");
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import threading
|
|||
|
||||
|
||||
class TestInferenceSession(unittest.TestCase):
|
||||
|
||||
|
||||
def get_name(self, name):
|
||||
if os.path.exists(name):
|
||||
return name
|
||||
|
|
@ -22,14 +22,17 @@ class TestInferenceSession(unittest.TestCase):
|
|||
res = os.path.join(data, name)
|
||||
if os.path.exists(res):
|
||||
return res
|
||||
raise FileNotFoundError("Unable to find '{0}' or '{1}' or '{2}'".format(name, rel, res))
|
||||
raise FileNotFoundError(
|
||||
"Unable to find '{0}' or '{1}' or '{2}'".format(name, rel, res))
|
||||
|
||||
def run_model(self, session_object, run_options):
|
||||
x = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype=np.float32)
|
||||
input_name = session_object.get_inputs()[0].name
|
||||
res = session_object.run([], {input_name: x}, run_options=run_options)
|
||||
output_expected = np.array([[1.0, 4.0], [9.0, 16.0], [25.0, 36.0]], dtype=np.float32)
|
||||
np.testing.assert_allclose(output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
output_expected = np.array(
|
||||
[[1.0, 4.0], [9.0, 16.0], [25.0, 36.0]], dtype=np.float32)
|
||||
np.testing.assert_allclose(
|
||||
output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
def testRunModel(self):
|
||||
sess = onnxrt.InferenceSession(self.get_name("mul_1.onnx"))
|
||||
|
|
@ -43,8 +46,10 @@ class TestInferenceSession(unittest.TestCase):
|
|||
output_shape = sess.get_outputs()[0].shape
|
||||
self.assertEqual(output_shape, [3, 2])
|
||||
res = sess.run([output_name], {input_name: x})
|
||||
output_expected = np.array([[1.0, 4.0], [9.0, 16.0], [25.0, 36.0]], dtype=np.float32)
|
||||
np.testing.assert_allclose(output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
output_expected = np.array(
|
||||
[[1.0, 4.0], [9.0, 16.0], [25.0, 36.0]], dtype=np.float32)
|
||||
np.testing.assert_allclose(
|
||||
output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
def testRunModelFromBytes(self):
|
||||
with open(self.get_name("mul_1.onnx"), "rb") as f:
|
||||
|
|
@ -60,8 +65,10 @@ class TestInferenceSession(unittest.TestCase):
|
|||
output_shape = sess.get_outputs()[0].shape
|
||||
self.assertEqual(output_shape, [3, 2])
|
||||
res = sess.run([output_name], {input_name: x})
|
||||
output_expected = np.array([[1.0, 4.0], [9.0, 16.0], [25.0, 36.0]], dtype=np.float32)
|
||||
np.testing.assert_allclose(output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
output_expected = np.array(
|
||||
[[1.0, 4.0], [9.0, 16.0], [25.0, 36.0]], dtype=np.float32)
|
||||
np.testing.assert_allclose(
|
||||
output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
def testRunModel2(self):
|
||||
sess = onnxrt.InferenceSession(self.get_name("matmul_1.onnx"))
|
||||
|
|
@ -76,19 +83,21 @@ class TestInferenceSession(unittest.TestCase):
|
|||
self.assertEqual(output_shape, [3, 1])
|
||||
res = sess.run([output_name], {input_name: x})
|
||||
output_expected = np.array([[5.0], [11.0], [17.0]], dtype=np.float32)
|
||||
np.testing.assert_allclose(output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
np.testing.assert_allclose(
|
||||
output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
def testRunModelMultipleThreads(self):
|
||||
so = onnxrt.SessionOptions()
|
||||
so.session_log_verbosity_level = 1
|
||||
so.session_logid = "MultiThreadsTest"
|
||||
sess = onnxrt.InferenceSession(self.get_name("mul_1.onnx"), sess_options=so)
|
||||
sess = onnxrt.InferenceSession(
|
||||
self.get_name("mul_1.onnx"), sess_options=so)
|
||||
ro1 = onnxrt.RunOptions()
|
||||
ro1.run_tag = "thread1"
|
||||
t1 = threading.Thread(target=self.run_model, args = (sess, ro1))
|
||||
ro1.run_tag = "thread1"
|
||||
t1 = threading.Thread(target=self.run_model, args=(sess, ro1))
|
||||
ro2 = onnxrt.RunOptions()
|
||||
ro2.run_tag = "thread2"
|
||||
t2 = threading.Thread(target=self.run_model, args = (sess, ro2))
|
||||
t2 = threading.Thread(target=self.run_model, args=(sess, ro2))
|
||||
t1.start()
|
||||
t2.start()
|
||||
t1.join()
|
||||
|
|
@ -113,7 +122,8 @@ class TestInferenceSession(unittest.TestCase):
|
|||
self.assertEqual(output_shape, [None, 1])
|
||||
res = sess.run([output_name], {input_name: x})
|
||||
output_expected = np.array([[5.0], [11.0], [17.0]], dtype=np.float32)
|
||||
np.testing.assert_allclose(output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
np.testing.assert_allclose(
|
||||
output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
def testBooleanInputs(self):
|
||||
sess = onnxrt.InferenceSession(self.get_name("logicaland.onnx"))
|
||||
|
|
@ -121,7 +131,7 @@ class TestInferenceSession(unittest.TestCase):
|
|||
b = np.array([[True, False], [True, False]], dtype=np.bool)
|
||||
|
||||
# input1:0 is first in the protobuf, and input:0 is second
|
||||
# and we maintain the original order.
|
||||
# and we maintain the original order.
|
||||
a_name = sess.get_inputs()[0].name
|
||||
self.assertEqual(a_name, "input1:0")
|
||||
a_shape = sess.get_inputs()[0].shape
|
||||
|
|
@ -143,13 +153,15 @@ class TestInferenceSession(unittest.TestCase):
|
|||
output_type = sess.get_outputs()[0].type
|
||||
self.assertEqual(output_type, 'tensor(bool)')
|
||||
|
||||
output_expected = np.array([[True, False], [False, False]], dtype=np.bool)
|
||||
output_expected = np.array(
|
||||
[[True, False], [False, False]], dtype=np.bool)
|
||||
res = sess.run([output_name], {a_name: a, b_name: b})
|
||||
np.testing.assert_equal(output_expected, res[0])
|
||||
|
||||
def testStringInput1(self):
|
||||
sess = onnxrt.InferenceSession(self.get_name("identity_string.onnx"))
|
||||
x = np.array(['this', 'is', 'identity', 'test'], dtype=np.str).reshape((2,2))
|
||||
x = np.array(['this', 'is', 'identity', 'test'],
|
||||
dtype=np.str).reshape((2, 2))
|
||||
|
||||
x_name = sess.get_inputs()[0].name
|
||||
self.assertEqual(x_name, "input:0")
|
||||
|
|
@ -170,7 +182,8 @@ class TestInferenceSession(unittest.TestCase):
|
|||
|
||||
def testStringInput2(self):
|
||||
sess = onnxrt.InferenceSession(self.get_name("identity_string.onnx"))
|
||||
x = np.array(['Olá', '你好', '여보세요', 'hello'], dtype=np.unicode).reshape((2,2))
|
||||
x = np.array(['Olá', '你好', '여보세요', 'hello'],
|
||||
dtype=np.unicode).reshape((2, 2))
|
||||
|
||||
x_name = sess.get_inputs()[0].name
|
||||
self.assertEqual(x_name, "input:0")
|
||||
|
|
@ -188,10 +201,10 @@ class TestInferenceSession(unittest.TestCase):
|
|||
|
||||
res = sess.run([output_name], {x_name: x})
|
||||
np.testing.assert_equal(x, res[0])
|
||||
|
||||
|
||||
def testInputBytes(self):
|
||||
sess = onnxrt.InferenceSession(self.get_name("identity_string.onnx"))
|
||||
x = np.array([b'this', b'is', b'identity', b'test']).reshape((2,2))
|
||||
x = np.array([b'this', b'is', b'identity', b'test']).reshape((2, 2))
|
||||
|
||||
x_name = sess.get_inputs()[0].name
|
||||
self.assertEqual(x_name, "input:0")
|
||||
|
|
@ -208,11 +221,12 @@ class TestInferenceSession(unittest.TestCase):
|
|||
self.assertEqual(output_type, 'tensor(string)')
|
||||
|
||||
res = sess.run([output_name], {x_name: x})
|
||||
np.testing.assert_equal(x, res[0].astype('|S8'))
|
||||
np.testing.assert_equal(x, res[0].astype('|S8'))
|
||||
|
||||
def testInputObject(self):
|
||||
sess = onnxrt.InferenceSession(self.get_name("identity_string.onnx"))
|
||||
x = np.array(['this', 'is', 'identity', 'test'], object).reshape((2,2))
|
||||
x = np.array(['this', 'is', 'identity', 'test'],
|
||||
object).reshape((2, 2))
|
||||
|
||||
x_name = sess.get_inputs()[0].name
|
||||
self.assertEqual(x_name, "input:0")
|
||||
|
|
@ -229,11 +243,12 @@ class TestInferenceSession(unittest.TestCase):
|
|||
self.assertEqual(output_type, 'tensor(string)')
|
||||
|
||||
res = sess.run([output_name], {x_name: x})
|
||||
np.testing.assert_equal(x, res[0])
|
||||
np.testing.assert_equal(x, res[0])
|
||||
|
||||
def testInputVoid(self):
|
||||
sess = onnxrt.InferenceSession(self.get_name("identity_string.onnx"))
|
||||
x = np.array([b'this', b'is', b'identity', b'test'], np.void).reshape((2,2))
|
||||
x = np.array([b'this', b'is', b'identity', b'test'],
|
||||
np.void).reshape((2, 2))
|
||||
|
||||
x_name = sess.get_inputs()[0].name
|
||||
self.assertEqual(x_name, "input:0")
|
||||
|
|
@ -250,14 +265,14 @@ class TestInferenceSession(unittest.TestCase):
|
|||
self.assertEqual(output_type, 'tensor(string)')
|
||||
|
||||
res = sess.run([output_name], {x_name: x})
|
||||
|
||||
|
||||
expr = np.array([['this\x00\x00\x00\x00', 'is\x00\x00\x00\x00\x00\x00'],
|
||||
['identity', 'test\x00\x00\x00\x00']], dtype=object)
|
||||
np.testing.assert_equal(expr, res[0])
|
||||
|
||||
def testConvAutoPad(self):
|
||||
sess = onnxrt.InferenceSession(self.get_name("conv_autopad.onnx"))
|
||||
x = np.array(25 * [1.0], dtype=np.float32).reshape((1,1,5,5))
|
||||
x = np.array(25 * [1.0], dtype=np.float32).reshape((1, 1, 5, 5))
|
||||
|
||||
x_name = sess.get_inputs()[0].name
|
||||
self.assertEqual(x_name, "Input4")
|
||||
|
|
@ -282,8 +297,10 @@ class TestInferenceSession(unittest.TestCase):
|
|||
np.testing.assert_allclose(output_expected, res[0])
|
||||
|
||||
def testZipMapStringFloat(self):
|
||||
sess = onnxrt.InferenceSession(self.get_name("zipmap_stringfloat.onnx"))
|
||||
x = np.array([1.0, 0.0, 3.0, 44.0, 23.0, 11.0], dtype=np.float32).reshape((2,3))
|
||||
sess = onnxrt.InferenceSession(
|
||||
self.get_name("zipmap_stringfloat.onnx"))
|
||||
x = np.array([1.0, 0.0, 3.0, 44.0, 23.0, 11.0],
|
||||
dtype=np.float32).reshape((2, 3))
|
||||
|
||||
x_name = sess.get_inputs()[0].name
|
||||
self.assertEqual(x_name, "X")
|
||||
|
|
@ -302,7 +319,8 @@ class TestInferenceSession(unittest.TestCase):
|
|||
|
||||
def testZipMapInt64Float(self):
|
||||
sess = onnxrt.InferenceSession(self.get_name("zipmap_int64float.onnx"))
|
||||
x = np.array([1.0, 0.0, 3.0, 44.0, 23.0, 11.0], dtype=np.float32).reshape((2,3))
|
||||
x = np.array([1.0, 0.0, 3.0, 44.0, 23.0, 11.0],
|
||||
dtype=np.float32).reshape((2, 3))
|
||||
|
||||
x_name = sess.get_inputs()[0].name
|
||||
self.assertEqual(x_name, "X")
|
||||
|
|
@ -314,7 +332,8 @@ class TestInferenceSession(unittest.TestCase):
|
|||
output_type = sess.get_outputs()[0].type
|
||||
self.assertEqual(output_type, 'seq(map(int64,tensor(float)))')
|
||||
|
||||
output_expected = [{10: 1.0, 20: 0.0, 30: 3.0}, {10: 44.0, 20: 23.0, 30: 11.0}]
|
||||
output_expected = [{10: 1.0, 20: 0.0, 30: 3.0},
|
||||
{10: 44.0, 20: 23.0, 30: 11.0}]
|
||||
res = sess.run([output_name], {x_name: x})
|
||||
self.assertEqual(output_expected, res[0])
|
||||
|
||||
|
|
@ -340,7 +359,8 @@ class TestInferenceSession(unittest.TestCase):
|
|||
def testProfilerWithSessionOptions(self):
|
||||
so = onnxrt.SessionOptions()
|
||||
so.enable_profiling = True
|
||||
sess = onnxrt.InferenceSession(self.get_name("mul_1.onnx"), sess_options=so)
|
||||
sess = onnxrt.InferenceSession(
|
||||
self.get_name("mul_1.onnx"), sess_options=so)
|
||||
x = np.array([[1.0, 2.0], [3.0, 4.0], [5.0, 6.0]], dtype=np.float32)
|
||||
sess.run([], {'X': x})
|
||||
profile_file = sess.end_profiling()
|
||||
|
|
@ -355,7 +375,8 @@ class TestInferenceSession(unittest.TestCase):
|
|||
self.assertTrue(']' in lines[8])
|
||||
|
||||
def testDictVectorizer(self):
|
||||
sess = onnxrt.InferenceSession(self.get_name("pipeline_vectorize.onnx"))
|
||||
sess = onnxrt.InferenceSession(
|
||||
self.get_name("pipeline_vectorize.onnx"))
|
||||
input_name = sess.get_inputs()[0].name
|
||||
self.assertEqual(input_name, "float_input")
|
||||
input_type = str(sess.get_inputs()[0].type)
|
||||
|
|
@ -368,35 +389,40 @@ class TestInferenceSession(unittest.TestCase):
|
|||
self.assertEqual(output_type, "tensor(float)")
|
||||
output_shape = sess.get_outputs()[0].shape
|
||||
self.assertEqual(output_shape, [1, 1])
|
||||
|
||||
|
||||
# Python type
|
||||
x = {0: 25.0, 1: 5.13, 2: 0.0, 3: 0.453, 4: 5.966}
|
||||
res = sess.run([output_name], {input_name: x})
|
||||
output_expected = np.array([[49.752754]], dtype=np.float32)
|
||||
np.testing.assert_allclose(output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
np.testing.assert_allclose(
|
||||
output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
xwrong = x.copy()
|
||||
xwrong["a"] = 5.6
|
||||
try:
|
||||
res = sess.run([output_name], {input_name: xwrong})
|
||||
except RuntimeError as e:
|
||||
self.assertIn("Unexpected key type <class 'str'>, it cannot be linked to C type int64_t", str(e))
|
||||
self.assertIn(
|
||||
"Unexpected key type <class 'str'>, it cannot be linked to C type int64_t", str(e))
|
||||
|
||||
# numpy type
|
||||
x = {np.int64(k): np.float32(v) for k, v in x.items()}
|
||||
res = sess.run([output_name], {input_name: x})
|
||||
output_expected = np.array([[49.752754]], dtype=np.float32)
|
||||
np.testing.assert_allclose(output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
np.testing.assert_allclose(
|
||||
output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
x = {np.int64(k): np.float64(v) for k, v in x.items()}
|
||||
res = sess.run([output_name], {input_name: x})
|
||||
output_expected = np.array([[49.752754]], dtype=np.float32)
|
||||
np.testing.assert_allclose(output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
np.testing.assert_allclose(
|
||||
output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
x = {np.int32(k): np.float64(v) for k, v in x.items()}
|
||||
res = sess.run([output_name], {input_name: x})
|
||||
output_expected = np.array([[49.752754]], dtype=np.float32)
|
||||
np.testing.assert_allclose(output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
np.testing.assert_allclose(
|
||||
output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
def testLabelEncoder(self):
|
||||
sess = onnxrt.InferenceSession(self.get_name("LabelEncoder.onnx"))
|
||||
|
|
@ -412,50 +438,54 @@ class TestInferenceSession(unittest.TestCase):
|
|||
self.assertEqual(output_type, "tensor(int64)")
|
||||
output_shape = sess.get_outputs()[0].shape
|
||||
self.assertEqual(output_shape, [1, 1])
|
||||
|
||||
|
||||
# Array
|
||||
x = np.array([['4']])
|
||||
res = sess.run([output_name], {input_name: x})
|
||||
output_expected = np.array([[3]], dtype=np.int64)
|
||||
np.testing.assert_allclose(output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
np.testing.assert_allclose(
|
||||
output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
# Python type
|
||||
x = np.array(['4'])
|
||||
x = np.array(['4'], ndmin=2)
|
||||
res = sess.run([output_name], {input_name: x})
|
||||
output_expected = np.array([3], dtype=np.int64)
|
||||
np.testing.assert_allclose(output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
output_expected = np.array([3], ndmin=2, dtype=np.int64)
|
||||
np.testing.assert_allclose(
|
||||
output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
x = np.array(['4'], dtype=np.object)
|
||||
x = np.array(['4'], ndmin=2, dtype=np.object)
|
||||
res = sess.run([output_name], {input_name: x})
|
||||
output_expected = np.array([3], dtype=np.int64)
|
||||
np.testing.assert_allclose(output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
output_expected = np.array([3], ndmin=2, dtype=np.int64)
|
||||
np.testing.assert_allclose(
|
||||
output_expected, res[0], rtol=1e-05, atol=1e-08)
|
||||
|
||||
def test_run_model_mlnet(self):
|
||||
sess = onnxrt.InferenceSession(self.get_name("mlnet_encoder.onnx"))
|
||||
names = [_.name for _ in sess.get_outputs()]
|
||||
self.assertEqual(['C00', 'C12'], names)
|
||||
c0 = np.array([5.], dtype=np.float32).reshape(1, 1);
|
||||
|
||||
c0 = np.array([5.], dtype=np.float32).reshape(1, 1)
|
||||
|
||||
c1 = np.array([b'A\0A\0', b"B\0B\0", b"C\0C\0"], np.void).reshape(1, 3)
|
||||
res = sess.run(None, {'C0': c0, 'C1': c1})
|
||||
mat = res[1]
|
||||
total = mat.sum()
|
||||
self.assertEqual(total, 2)
|
||||
self.assertEqual(list(mat.ravel()),
|
||||
self.assertEqual(list(mat.ravel()),
|
||||
list(np.array([[[0., 0., 0., 0.], [1., 0., 0., 0.], [0., 0., 1., 0.]]]).ravel()))
|
||||
|
||||
# In memory, the size of each element is fixed and equal to the
|
||||
|
||||
# In memory, the size of each element is fixed and equal to the
|
||||
# longest element. We cannot use bytes because numpy is trimming
|
||||
# every final 0 for strings and bytes before creating the array
|
||||
# (to save space). It does not have this behaviour for void
|
||||
# but as a result, numpy does not know anymore the size
|
||||
# of each element, they all have the same size.
|
||||
c1 = np.array([b'A\0A\0\0', b"B\0B\0", b"C\0C\0"], np.void).reshape(1, 3)
|
||||
c1 = np.array([b'A\0A\0\0', b"B\0B\0", b"C\0C\0"],
|
||||
np.void).reshape(1, 3)
|
||||
res = sess.run(None, {'C0': c0, 'C1': c1})
|
||||
mat = res[1]
|
||||
total = mat.sum()
|
||||
self.assertEqual(total, 0)
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
|
|
|||
Loading…
Reference in a new issue