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:
Pranav Sharma 2019-07-19 13:42:34 -07:00 committed by GitHub
parent 638398e675
commit 4cbc6e1cf5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 176 additions and 96 deletions

View file

@ -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";
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -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) {

View file

@ -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);

View file

@ -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

View file

@ -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");

View file

@ -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()