2018-11-20 00:48:22 +00:00
|
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
|
// Licensed under the MIT License.
|
|
|
|
|
|
|
|
|
|
#include "core/framework/execution_frame.h"
|
|
|
|
|
#include "core/framework/op_kernel.h"
|
|
|
|
|
#include "core/framework/session_state.h"
|
|
|
|
|
#include "core/graph/model.h"
|
|
|
|
|
#include "core/providers/cpu/cpu_execution_provider.h"
|
2019-07-09 04:59:07 +00:00
|
|
|
#include "core/session/inference_session.h"
|
2018-11-20 00:48:22 +00:00
|
|
|
#include "test_utils.h"
|
2019-07-09 04:59:07 +00:00
|
|
|
#include "test/test_environment.h"
|
|
|
|
|
|
2018-11-20 00:48:22 +00:00
|
|
|
#include "gtest/gtest.h"
|
2019-07-09 04:59:07 +00:00
|
|
|
#include "gmock/gmock.h"
|
2018-11-20 00:48:22 +00:00
|
|
|
|
|
|
|
|
using namespace ONNX_NAMESPACE;
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
namespace onnxruntime {
|
|
|
|
|
namespace test {
|
|
|
|
|
typedef std::vector<onnxruntime::NodeArg*> ArgMap;
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<onnxruntime::Model> DummyGraphWithClip() {
|
|
|
|
|
auto model = std::make_shared<onnxruntime::Model>("test");
|
|
|
|
|
onnxruntime::Graph& graph = model->MainGraph();
|
|
|
|
|
TypeProto tensor_float;
|
|
|
|
|
tensor_float.mutable_tensor_type()->set_elem_type(TensorProto_DataType_FLOAT);
|
|
|
|
|
onnxruntime::NodeArg input_def("X", &tensor_float), output_def("Y", &tensor_float);
|
|
|
|
|
|
|
|
|
|
graph.AddNode("node1", "Clip", "clip operator", ArgMap{&input_def}, ArgMap{&output_def});
|
|
|
|
|
return model;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<IExecutionProvider> CreateCPUExecutionProvider() {
|
|
|
|
|
CPUExecutionProviderInfo info;
|
2019-10-01 19:43:29 +00:00
|
|
|
return onnxruntime::make_unique<CPUExecutionProvider>(info);
|
2018-11-20 00:48:22 +00:00
|
|
|
}
|
|
|
|
|
|
2019-08-16 20:21:15 +00:00
|
|
|
class ExecutionFrameTest : public ::testing::Test {
|
|
|
|
|
protected:
|
|
|
|
|
concurrency::ThreadPool tp_{"test", 1};
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
TEST_F(ExecutionFrameTest, TensorAllocationTest) {
|
2018-11-20 00:48:22 +00:00
|
|
|
onnxruntime::Model model("test");
|
|
|
|
|
onnxruntime::Graph& graph = model.MainGraph();
|
|
|
|
|
TypeProto tensor_float;
|
|
|
|
|
tensor_float.mutable_tensor_type()->set_elem_type(TensorProto_DataType_FLOAT);
|
|
|
|
|
onnxruntime::NodeArg input_def("X", &tensor_float), output_def("Y", &tensor_float);
|
|
|
|
|
|
2019-08-22 17:26:35 +00:00
|
|
|
onnxruntime::Node* node = &graph.AddNode("node1", "Relu", "Relu operator", ArgMap{&input_def}, ArgMap{&output_def});
|
|
|
|
|
node->SetExecutionProviderType(kCpuExecutionProvider);
|
2018-11-20 00:48:22 +00:00
|
|
|
Status status = graph.Resolve();
|
|
|
|
|
EXPECT_TRUE(status.IsOK()) << status.ErrorMessage();
|
|
|
|
|
|
|
|
|
|
auto cpu_xp = CreateCPUExecutionProvider();
|
|
|
|
|
auto xp_typ = cpu_xp->Type();
|
|
|
|
|
ExecutionProviders execution_providers;
|
|
|
|
|
execution_providers.Add(xp_typ, std::move(cpu_xp));
|
2019-02-20 19:57:36 +00:00
|
|
|
KernelRegistryManager kernel_registry_manager;
|
|
|
|
|
status = kernel_registry_manager.RegisterKernels(execution_providers);
|
|
|
|
|
EXPECT_TRUE(status.IsOK()) << status.ErrorMessage();
|
2018-11-20 00:48:22 +00:00
|
|
|
|
2019-09-19 05:36:23 +00:00
|
|
|
SessionState state{execution_providers, true, &tp_, nullptr};
|
2019-08-22 17:26:35 +00:00
|
|
|
status = state.SetGraphAndCreateKernels(graph, kernel_registry_manager);
|
|
|
|
|
EXPECT_TRUE(status.IsOK()) << status.ErrorMessage();
|
2018-11-20 00:48:22 +00:00
|
|
|
|
|
|
|
|
node->SetExecutionProviderType(xp_typ);
|
|
|
|
|
|
|
|
|
|
std::unique_ptr<SequentialExecutionPlan> p_seq_exec_plan;
|
|
|
|
|
// TODO below line is for testing only. In production use SequentialPlanner::CreatePlan()
|
2019-05-16 21:39:09 +00:00
|
|
|
SequentialPlannerContext context(false);
|
2019-03-18 20:55:59 +00:00
|
|
|
status = SequentialPlanner::CreatePlan(nullptr, GraphViewer(graph), {}, execution_providers, kernel_registry_manager,
|
2019-08-22 17:26:35 +00:00
|
|
|
state.GetOrtValueNameIdxMap(), context, p_seq_exec_plan);
|
2018-11-20 00:48:22 +00:00
|
|
|
EXPECT_TRUE(status.IsOK()) << status.ErrorMessage();
|
|
|
|
|
state.SetExecutionPlan(std::move(p_seq_exec_plan));
|
|
|
|
|
|
2019-05-17 14:52:59 +00:00
|
|
|
vector<OrtValue> outputs;
|
2019-02-20 02:12:17 +00:00
|
|
|
ExecutionFrame frame({}, {}, {}, outputs, {}, state);
|
2018-11-20 00:48:22 +00:00
|
|
|
|
2019-02-01 00:55:49 +00:00
|
|
|
int start_index = frame.GetNodeOffset(node->Index());
|
2018-11-20 00:48:22 +00:00
|
|
|
EXPECT_EQ(start_index, 0);
|
|
|
|
|
|
|
|
|
|
TensorShape shape(std::vector<int64_t>{2, 3});
|
2019-05-17 14:52:59 +00:00
|
|
|
OrtValue& mlvalue0 = *frame.GetMutableNodeInputOrOutputMLValue(start_index);
|
2019-02-27 23:46:50 +00:00
|
|
|
status = frame.AllocateMLValueTensorSelfOwnBuffer(mlvalue0, start_index, DataTypeImpl::GetType<float>(),
|
2019-02-01 00:55:49 +00:00
|
|
|
execution_providers.Get(xp_typ)->GetAllocator(0, OrtMemTypeDefault)->Info(), shape);
|
2018-11-20 00:48:22 +00:00
|
|
|
EXPECT_TRUE(status.IsOK()) << status.ErrorMessage();
|
|
|
|
|
|
2019-05-17 14:52:59 +00:00
|
|
|
OrtValue* p_ml_value = frame.GetMutableNodeInputOrOutputMLValue(0);
|
2018-11-20 00:48:22 +00:00
|
|
|
Tensor* p_tensor = p_ml_value ? p_ml_value->GetMutable<Tensor>() : nullptr;
|
|
|
|
|
EXPECT_TRUE(p_tensor);
|
|
|
|
|
EXPECT_EQ(p_tensor->Shape(), shape);
|
|
|
|
|
EXPECT_EQ(p_tensor->DataType(), DataTypeImpl::GetType<float>());
|
|
|
|
|
|
|
|
|
|
//test share memory from tensor
|
|
|
|
|
TensorShape shape2(std::vector<int64_t>{3, 2});
|
2019-05-17 14:52:59 +00:00
|
|
|
OrtValue& mlvalue1 = *frame.GetMutableNodeInputOrOutputMLValue(start_index + 1);
|
2019-02-27 23:46:50 +00:00
|
|
|
status = frame.AllocateMLValueTensorPreAllocateBuffer(mlvalue1,
|
2019-02-01 00:55:49 +00:00
|
|
|
start_index,
|
|
|
|
|
DataTypeImpl::GetType<float>(),
|
|
|
|
|
p_tensor->Location(),
|
|
|
|
|
shape2);
|
2018-11-20 00:48:22 +00:00
|
|
|
EXPECT_TRUE(status.IsOK()) << status.ErrorMessage();
|
|
|
|
|
|
2019-05-17 14:52:59 +00:00
|
|
|
const OrtValue* p_ml_value_const = frame.GetNodeInputOrOutputMLValue(1);
|
2018-11-20 00:48:22 +00:00
|
|
|
auto tensor2 = p_ml_value_const ? &(p_ml_value_const->Get<Tensor>()) : nullptr;
|
|
|
|
|
EXPECT_TRUE(tensor2);
|
|
|
|
|
EXPECT_EQ(tensor2->Shape(), shape2);
|
|
|
|
|
EXPECT_EQ(tensor2->template Data<float>(), p_tensor->template Data<float>());
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-16 20:21:15 +00:00
|
|
|
TEST_F(ExecutionFrameTest, FeedInDataTest) {
|
2019-08-22 17:26:35 +00:00
|
|
|
onnxruntime::Model model("test", false, ModelMetaData(), IOnnxRuntimeOpSchemaRegistryList(),
|
|
|
|
|
std::unordered_map<std::string, int>{{"", 10}});
|
2018-11-20 00:48:22 +00:00
|
|
|
onnxruntime::Graph& graph = model.MainGraph();
|
|
|
|
|
TypeProto tensor_float;
|
|
|
|
|
tensor_float.mutable_tensor_type()->set_elem_type(TensorProto_DataType_FLOAT);
|
|
|
|
|
onnxruntime::NodeArg input_def("X", &tensor_float), output_def("Y", &tensor_float);
|
|
|
|
|
|
2019-08-22 17:26:35 +00:00
|
|
|
graph.AddNode("node1", "Clip", "Clip operator", ArgMap{&input_def}, ArgMap{&output_def})
|
|
|
|
|
.SetExecutionProviderType(kCpuExecutionProvider);
|
2018-11-20 00:48:22 +00:00
|
|
|
graph.Resolve();
|
|
|
|
|
auto element_type = DataTypeImpl::GetType<float>();
|
|
|
|
|
TensorShape shape({3, 2});
|
2019-08-22 17:26:35 +00:00
|
|
|
std::vector<float> fdata(static_cast<size_t>(shape.Size()));
|
2018-11-20 00:48:22 +00:00
|
|
|
//create fake ml value with owned buffer.
|
2019-09-05 21:20:37 +00:00
|
|
|
OrtMemoryInfo cpuinfo(kCpuExecutionProvider, OrtDeviceAllocator);
|
2019-10-01 19:43:29 +00:00
|
|
|
std::unique_ptr<Tensor> p_tensor = onnxruntime::make_unique<Tensor>(element_type, shape, fdata.data(), cpuinfo);
|
2019-05-17 14:52:59 +00:00
|
|
|
OrtValue value;
|
2018-11-20 00:48:22 +00:00
|
|
|
value.Init(p_tensor.release(),
|
|
|
|
|
DataTypeImpl::GetType<Tensor>(),
|
|
|
|
|
DataTypeImpl::GetType<Tensor>()->GetDeleteFunc());
|
|
|
|
|
|
|
|
|
|
auto cpu_xp = CreateCPUExecutionProvider();
|
|
|
|
|
auto xp_typ = cpu_xp->Type();
|
|
|
|
|
|
|
|
|
|
KernelRegistryManager kernel_registry_manager;
|
|
|
|
|
ExecutionProviders execution_providers;
|
2019-02-20 19:57:36 +00:00
|
|
|
execution_providers.Add(xp_typ, std::move(cpu_xp));
|
|
|
|
|
EXPECT_TRUE(kernel_registry_manager.RegisterKernels(execution_providers).IsOK());
|
2019-09-19 05:36:23 +00:00
|
|
|
SessionState state{execution_providers, true, &tp_, nullptr};
|
2019-08-22 17:26:35 +00:00
|
|
|
auto status = state.SetGraphAndCreateKernels(graph, kernel_registry_manager);
|
|
|
|
|
EXPECT_TRUE(status.IsOK()) << status.ErrorMessage();
|
2018-11-20 00:48:22 +00:00
|
|
|
|
2019-08-22 17:26:35 +00:00
|
|
|
const OrtValueNameIdxMap& mlvalue_name_idx_map = state.GetOrtValueNameIdxMap();
|
|
|
|
|
int x_idx, y_idx;
|
|
|
|
|
ASSERT_TRUE(mlvalue_name_idx_map.GetIdx("X", x_idx).IsOK());
|
|
|
|
|
ASSERT_TRUE(mlvalue_name_idx_map.GetIdx("Y", y_idx).IsOK());
|
2019-02-01 00:55:49 +00:00
|
|
|
|
2019-05-17 14:52:59 +00:00
|
|
|
vector<OrtValue> outputs;
|
2019-02-20 02:12:17 +00:00
|
|
|
ExecutionFrame frame({x_idx}, {value}, {y_idx}, outputs, {}, state);
|
2018-11-20 00:48:22 +00:00
|
|
|
|
2019-05-17 14:52:59 +00:00
|
|
|
OrtValue* p_ml_value = frame.GetMutableNodeInputOrOutputMLValue(0);
|
2018-11-20 00:48:22 +00:00
|
|
|
Tensor* p_tensor_arg_0 = p_ml_value ? p_ml_value->GetMutable<Tensor>() : nullptr;
|
|
|
|
|
EXPECT_TRUE(p_tensor_arg_0);
|
|
|
|
|
EXPECT_EQ(p_tensor_arg_0->Shape(), shape);
|
|
|
|
|
EXPECT_EQ(p_tensor_arg_0->DataType(), DataTypeImpl::GetType<float>());
|
2019-03-06 05:27:12 +00:00
|
|
|
EXPECT_EQ(p_tensor_arg_0->MutableData<float>(), value.GetMutable<Tensor>()->MutableData<float>());
|
2018-11-20 00:48:22 +00:00
|
|
|
}
|
|
|
|
|
|
2019-08-16 20:21:15 +00:00
|
|
|
TEST_F(ExecutionFrameTest, MemPatternTest) {
|
2018-11-20 00:48:22 +00:00
|
|
|
auto cpu_xp = CreateCPUExecutionProvider();
|
|
|
|
|
auto xp_type = cpu_xp->Type();
|
|
|
|
|
std::unordered_map<std::string, int> domain_to_version;
|
|
|
|
|
domain_to_version[onnxruntime::kOnnxDomain] = 7;
|
|
|
|
|
onnxruntime::Model model("test", true, ModelMetaData(), IOnnxRuntimeOpSchemaRegistryList(), domain_to_version);
|
|
|
|
|
onnxruntime::Graph& graph = model.MainGraph();
|
|
|
|
|
TypeProto tensor_float;
|
|
|
|
|
tensor_float.mutable_tensor_type()->set_elem_type(TensorProto_DataType_FLOAT);
|
|
|
|
|
onnxruntime::NodeArg input_def1("X1", &tensor_float),
|
|
|
|
|
input_def2("X2", &tensor_float),
|
|
|
|
|
input_def3("X3", &tensor_float),
|
|
|
|
|
gemm1_out_def("T1", &tensor_float),
|
|
|
|
|
gemm2_out_def("T2", &tensor_float),
|
|
|
|
|
clip_out_def("T3", &tensor_float);
|
|
|
|
|
|
|
|
|
|
graph.AddNode("node1", "MatMul", "gemm1", ArgMap{&input_def1, &input_def2}, ArgMap{&gemm1_out_def})
|
2018-11-28 16:42:11 +00:00
|
|
|
.SetExecutionProviderType(xp_type);
|
2018-11-20 00:48:22 +00:00
|
|
|
graph.AddNode("node2", "MatMul", "gemm2", ArgMap{&gemm1_out_def, &input_def3}, ArgMap{&gemm2_out_def})
|
2018-11-28 16:42:11 +00:00
|
|
|
.SetExecutionProviderType(xp_type);
|
2018-11-20 00:48:22 +00:00
|
|
|
graph.AddNode("node3", "Clip", "clip1", ArgMap{&gemm2_out_def}, ArgMap{&clip_out_def})
|
2018-11-28 16:42:11 +00:00
|
|
|
.SetExecutionProviderType(xp_type);
|
2018-11-20 00:48:22 +00:00
|
|
|
|
|
|
|
|
auto status = graph.Resolve();
|
|
|
|
|
EXPECT_TRUE(status.IsOK()) << status.ErrorMessage();
|
|
|
|
|
|
|
|
|
|
KernelRegistryManager kernel_registry_manager;
|
|
|
|
|
|
|
|
|
|
ExecutionProviders execution_providers;
|
|
|
|
|
execution_providers.Add(xp_type, std::move(cpu_xp));
|
2019-05-16 21:39:09 +00:00
|
|
|
kernel_registry_manager.RegisterKernels(execution_providers);
|
2018-11-20 00:48:22 +00:00
|
|
|
//1. prepare input
|
2019-09-19 05:36:23 +00:00
|
|
|
SessionState state{execution_providers, true, &tp_, nullptr};
|
2019-08-22 17:26:35 +00:00
|
|
|
status = state.SetGraphAndCreateKernels(graph, kernel_registry_manager);
|
|
|
|
|
EXPECT_TRUE(status.IsOK()) << status.ErrorMessage();
|
|
|
|
|
|
|
|
|
|
const OrtValueNameIdxMap& mlvalue_name_idx_map{state.GetOrtValueNameIdxMap()};
|
2018-11-20 00:48:22 +00:00
|
|
|
|
2019-08-22 17:26:35 +00:00
|
|
|
int x1_idx, x2_idx, x3_idx;
|
|
|
|
|
int t1_idx, t2_idx, t3_idx;
|
|
|
|
|
ASSERT_TRUE(mlvalue_name_idx_map.GetIdx("X1", x1_idx).IsOK());
|
|
|
|
|
ASSERT_TRUE(mlvalue_name_idx_map.GetIdx("X2", x2_idx).IsOK());
|
|
|
|
|
ASSERT_TRUE(mlvalue_name_idx_map.GetIdx("X3", x3_idx).IsOK());
|
2018-11-20 00:48:22 +00:00
|
|
|
|
2019-08-22 17:26:35 +00:00
|
|
|
ASSERT_TRUE(mlvalue_name_idx_map.GetIdx("T1", t1_idx).IsOK());
|
|
|
|
|
ASSERT_TRUE(mlvalue_name_idx_map.GetIdx("T2", t2_idx).IsOK());
|
|
|
|
|
ASSERT_TRUE(mlvalue_name_idx_map.GetIdx("T3", t3_idx).IsOK());
|
2018-11-20 00:48:22 +00:00
|
|
|
|
2018-12-14 22:54:23 +00:00
|
|
|
auto cpu_allocator = execution_providers.Get(xp_type)->GetAllocator(0, OrtMemTypeDefault);
|
2018-11-20 00:48:22 +00:00
|
|
|
|
2019-05-17 14:52:59 +00:00
|
|
|
OrtValue v1, v2, v3;
|
2018-11-20 00:48:22 +00:00
|
|
|
CreateMLValue<float>(cpu_allocator,
|
|
|
|
|
std::vector<int64_t>{1, 2},
|
|
|
|
|
std::vector<float>{1.0f, 1.0f}, &v1);
|
|
|
|
|
CreateMLValue<float>(cpu_allocator,
|
|
|
|
|
std::vector<int64_t>{2, 2},
|
|
|
|
|
std::vector<float>(4, 1.0f), &v2);
|
|
|
|
|
CreateMLValue<float>(cpu_allocator,
|
|
|
|
|
std::vector<int64_t>{2, 3},
|
|
|
|
|
std::vector<float>(6, 1.0f), &v3);
|
|
|
|
|
|
2019-10-01 19:43:29 +00:00
|
|
|
std::unique_ptr<SequentialExecutionPlan> p_seq_exec_plan = onnxruntime::make_unique<SequentialExecutionPlan>();
|
2019-05-16 21:39:09 +00:00
|
|
|
SequentialPlannerContext context(false);
|
2019-03-18 20:55:59 +00:00
|
|
|
status = SequentialPlanner::CreatePlan(nullptr, GraphViewer(graph), {}, execution_providers, kernel_registry_manager,
|
2019-05-16 21:39:09 +00:00
|
|
|
mlvalue_name_idx_map, context, p_seq_exec_plan);
|
2018-11-20 00:48:22 +00:00
|
|
|
EXPECT_TRUE(status.IsOK()) << status.ErrorMessage();
|
|
|
|
|
|
|
|
|
|
state.SetExecutionPlan(std::move(p_seq_exec_plan));
|
|
|
|
|
|
2019-05-17 14:52:59 +00:00
|
|
|
vector<OrtValue> outputs;
|
2019-02-20 02:12:17 +00:00
|
|
|
ExecutionFrame frame({x1_idx, x2_idx, x3_idx}, {v1, v2, v3}, {t3_idx}, outputs, {}, state);
|
2018-11-20 00:48:22 +00:00
|
|
|
|
2019-05-17 14:52:59 +00:00
|
|
|
OrtValue& mlvalue3 = *frame.GetMutableNodeInputOrOutputMLValue(3);
|
|
|
|
|
OrtValue& mlvalue4 = *frame.GetMutableNodeInputOrOutputMLValue(4);
|
|
|
|
|
OrtValue& mlvalue5 = *frame.GetMutableNodeInputOrOutputMLValue(5);
|
2019-02-27 23:46:50 +00:00
|
|
|
|
|
|
|
|
status = frame.AllocateMLValueTensorSelfOwnBuffer(mlvalue3, 3,
|
2018-11-20 00:48:22 +00:00
|
|
|
DataTypeImpl::GetType<float>(),
|
|
|
|
|
cpu_allocator->Info(),
|
|
|
|
|
TensorShape(std::vector<int64_t>{2, 2}));
|
|
|
|
|
EXPECT_TRUE(status.IsOK()) << status.ErrorMessage();
|
|
|
|
|
|
2019-02-27 23:46:50 +00:00
|
|
|
status = frame.AllocateMLValueTensorSelfOwnBuffer(mlvalue4, 4,
|
2018-11-20 00:48:22 +00:00
|
|
|
DataTypeImpl::GetType<float>(),
|
|
|
|
|
cpu_allocator->Info(),
|
|
|
|
|
TensorShape(std::vector<int64_t>{2, 3}));
|
|
|
|
|
EXPECT_TRUE(status.IsOK()) << status.ErrorMessage();
|
|
|
|
|
|
2019-02-27 23:46:50 +00:00
|
|
|
status = frame.AllocateMLValueTensorSelfOwnBuffer(mlvalue5, 5,
|
2018-11-20 00:48:22 +00:00
|
|
|
DataTypeImpl::GetType<float>(),
|
|
|
|
|
cpu_allocator->Info(),
|
|
|
|
|
TensorShape(std::vector<int64_t>{2, 3}));
|
|
|
|
|
EXPECT_TRUE(status.IsOK()) << status.ErrorMessage();
|
|
|
|
|
|
|
|
|
|
MemoryPatternGroup pattern;
|
|
|
|
|
status = frame.GeneratePatterns(&pattern);
|
|
|
|
|
EXPECT_TRUE(status.IsOK()) << status.ErrorMessage();
|
|
|
|
|
|
|
|
|
|
EXPECT_EQ(pattern.patterns.size(), pattern.locations.size());
|
|
|
|
|
EXPECT_EQ(pattern.patterns.size(), 1);
|
|
|
|
|
auto p = pattern.GetPatterns(cpu_allocator->Info());
|
2019-02-01 00:55:49 +00:00
|
|
|
EXPECT_EQ(p->PeakSize(), 2 * 64); // each allocation is 64-byte aligned
|
2018-11-20 00:48:22 +00:00
|
|
|
EXPECT_EQ(p->GetBlock(3)->offset_, 0);
|
2018-12-19 21:45:04 +00:00
|
|
|
EXPECT_EQ(p->GetBlock(4)->offset_, 64);
|
2018-11-20 00:48:22 +00:00
|
|
|
}
|
2019-07-09 04:59:07 +00:00
|
|
|
|
2019-09-21 01:15:16 +00:00
|
|
|
// TODO: Re-enable after registering a kernel for opset 11 'ReduceSum' op
|
|
|
|
|
TEST(ExecutionFrameTestWithoutSessionState, DISABLED_BadModelInvalidDimParamUsage) {
|
2019-07-09 04:59:07 +00:00
|
|
|
// load model with 2 Scan ops that both incorrectly use shapes of { 'None', 'None' } for their outputs.
|
|
|
|
|
// as 'None' is not a special value it's treated as a variable name, leading to a runtime error when we
|
|
|
|
|
// attempt to re-use the output from the first Scan node for the second. validate we detect this and error out.
|
|
|
|
|
SessionOptions so;
|
|
|
|
|
so.session_logid = "BadModelInvalidDimParamUsage";
|
|
|
|
|
|
|
|
|
|
InferenceSession session_object{so, &DefaultLoggingManager()};
|
|
|
|
|
Status st;
|
|
|
|
|
ASSERT_TRUE((st = session_object.Load("testdata/invalid_dim_param_value_repetition.onnx")).IsOK()) << st;
|
|
|
|
|
ASSERT_TRUE((st = session_object.Initialize()).IsOK()) << st;
|
|
|
|
|
|
|
|
|
|
std::vector<int64_t> dims_X = {10, 6};
|
|
|
|
|
std::vector<float> values_X;
|
|
|
|
|
values_X.reserve(60);
|
|
|
|
|
for (int i = 0; i < 60; ++i) {
|
|
|
|
|
values_X.push_back(float(i));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
OrtValue ml_value;
|
|
|
|
|
CreateMLValue<float>(TestCPUExecutionProvider()->GetAllocator(0, OrtMemTypeDefault), dims_X, values_X, &ml_value);
|
|
|
|
|
NameMLValMap feeds;
|
|
|
|
|
feeds.insert(std::make_pair("X", ml_value));
|
|
|
|
|
|
|
|
|
|
// prepare outputs
|
|
|
|
|
std::vector<std::string> output_names;
|
|
|
|
|
output_names.push_back("Y");
|
|
|
|
|
std::vector<OrtValue> fetches;
|
|
|
|
|
|
|
|
|
|
// Now run
|
|
|
|
|
RunOptions run_options;
|
|
|
|
|
st = session_object.Run(run_options, feeds, output_names, &fetches);
|
|
|
|
|
|
|
|
|
|
EXPECT_FALSE(st.IsOK()) << st;
|
|
|
|
|
EXPECT_THAT(st.ErrorMessage(), testing::HasSubstr("Shape mismatch attempting to re-use buffer."));
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-20 00:48:22 +00:00
|
|
|
} // namespace test
|
|
|
|
|
} // namespace onnxruntime
|