mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-06-18 01:54:05 +00:00
Update test to use 128 bytes for initializer so it can be allocated externally.
This commit is contained in:
parent
d360f76626
commit
0dcf0864d3
2 changed files with 68 additions and 56 deletions
|
|
@ -4097,7 +4097,7 @@ ONNX_NAMESPACE::GraphProto Graph::ToGraphProto() const {
|
|||
// This is used for constructing full path for external data
|
||||
// if it exists
|
||||
|
||||
auto add_initializer = [](TensorList& output_initializers, const TensorProto& initializer) -> Status {
|
||||
auto add_initializer = [](TensorList& output_initializers, const TensorProto& initializer) -> void {
|
||||
TensorProto& output = *output_initializers.Add();
|
||||
output = initializer;
|
||||
|
||||
|
|
@ -4108,7 +4108,7 @@ ONNX_NAMESPACE::GraphProto Graph::ToGraphProto() const {
|
|||
onnxruntime::FileOffsetType file_offset;
|
||||
SafeInt<size_t> tensor_byte_size;
|
||||
|
||||
ORT_RETURN_IF_ERROR(utils::GetExternalDataInfo(initializer, ignored, location, file_offset, tensor_byte_size));
|
||||
ORT_THROW_IF_ERROR(utils::GetExternalDataInfo(initializer, ignored, location, file_offset, tensor_byte_size));
|
||||
|
||||
if (location == onnxruntime::utils::kTensorProtoMemoryAddressTag) {
|
||||
// file_offset is address
|
||||
|
|
@ -4119,8 +4119,6 @@ ONNX_NAMESPACE::GraphProto Graph::ToGraphProto() const {
|
|||
output.set_raw_data(data, tensor_byte_size);
|
||||
}
|
||||
}
|
||||
|
||||
return Status::OK();
|
||||
};
|
||||
|
||||
auto* mutable_initializers = result.mutable_initializer();
|
||||
|
|
@ -4129,27 +4127,24 @@ ONNX_NAMESPACE::GraphProto Graph::ToGraphProto() const {
|
|||
const auto& model_path = ModelPath();
|
||||
// We want to make sure that sparse initializers do not appear
|
||||
// as dense duplicates within the initializers list.
|
||||
if (!sparse_tensor_names_.empty()) {
|
||||
const auto sparse_end = sparse_tensor_names_.end();
|
||||
for (const auto& initializer : graph_proto_->initializer()) {
|
||||
if (sparse_end == sparse_tensor_names_.find(initializer.name())) {
|
||||
add_initializer(*mutable_initializers, initializer);
|
||||
} else {
|
||||
auto& sparse_initializer = *result.add_sparse_initializer();
|
||||
auto status = utils::DenseTensorToSparseTensorProto(initializer, model_path, sparse_initializer);
|
||||
ORT_ENFORCE(status.IsOK(), "Failed to convert dense initializer to sparse");
|
||||
}
|
||||
}
|
||||
} else
|
||||
#else
|
||||
{
|
||||
for (const auto& initializer : graph_proto_->initializer()) {
|
||||
const bool has_sparse_initializers = !sparse_tensor_names_.empty();
|
||||
const auto sparse_end = sparse_tensor_names_.end();
|
||||
for (const auto& initializer : graph_proto_->initializer()) {
|
||||
if (!has_sparse_initializers || sparse_end == sparse_tensor_names_.find(initializer.name())) {
|
||||
add_initializer(*mutable_initializers, initializer);
|
||||
} else {
|
||||
auto& sparse_initializer = *result.add_sparse_initializer();
|
||||
auto status = utils::DenseTensorToSparseTensorProto(initializer, model_path, sparse_initializer);
|
||||
ORT_ENFORCE(status.IsOK(), "Failed to convert dense initializer to sparse");
|
||||
}
|
||||
}
|
||||
#else
|
||||
for (const auto& initializer : graph_proto_->initializer()) {
|
||||
add_initializer(*mutable_initializers, initializer);
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
return result;
|
||||
}
|
||||
|
||||
Status Graph::AddExternalInitializersToGraphProtoImpl(
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ Ort::Session CreateSession(Ort::Env& env,
|
|||
: default_session_options;
|
||||
|
||||
// Set this to save the model if you want to debug.
|
||||
// session_options.SetOptimizedModelFilePath(ORT_TSTR("model_builder_output.onnx"));
|
||||
session_options.SetOptimizedModelFilePath(ORT_TSTR("model_builder_output.onnx"));
|
||||
|
||||
Ort::Session session(env, graph_api_model, session_options);
|
||||
|
||||
|
|
@ -141,14 +141,14 @@ TEST(ModelBuilderAPITest, Basic_CApi) {
|
|||
Ort::ThrowOnError(model_builder_api.CreateGraph(&graph));
|
||||
|
||||
//
|
||||
// Create OrtModel with a Gemm. X input is 3x2, Y input is 2x3, Z output is 3x3.
|
||||
// Create OrtModel with a Gemm. X input is 3x2, Y input is 2x8, Z output is 3x8.
|
||||
// X is model input. Y is initializer.
|
||||
// Set the alpha attribute of the Gemm node to 2.0 to test attribute handling.
|
||||
//
|
||||
|
||||
// model input
|
||||
OrtTensorTypeAndShapeInfo* tensor_type_info = nullptr;
|
||||
std::vector<int64_t> input_dims = {3, 2};
|
||||
std::vector<int64_t> input_dims = {3, 4};
|
||||
// can use api.SetSymbolicDimensions to set symbolic dimensions.
|
||||
// the input array should have the same rank as the call to SetDimensions.
|
||||
// e.g. call SetDimensions with {-1, 3, 2} and SetSymbolicDimensions with {"N", nullptr, nullptr} to create
|
||||
|
|
@ -170,7 +170,7 @@ TEST(ModelBuilderAPITest, Basic_CApi) {
|
|||
|
||||
// model outputs
|
||||
OrtTypeInfo* output_type_info = nullptr;
|
||||
std::vector<int64_t> output_dims = {3, 3};
|
||||
std::vector<int64_t> output_dims = {3, 8};
|
||||
|
||||
Ort::ThrowOnError(api.CreateTensorTypeAndShapeInfo(&tensor_type_info));
|
||||
Ort::ThrowOnError(api.SetTensorElementType(tensor_type_info, ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT));
|
||||
|
|
@ -209,11 +209,13 @@ TEST(ModelBuilderAPITest, Basic_CApi) {
|
|||
node = nullptr; // graph now owns node
|
||||
|
||||
// Y input
|
||||
std::vector<int64_t> y_dims = {2, 3};
|
||||
deleter.weights.emplace_back(
|
||||
std::make_unique<std::vector<float>>(std::initializer_list<float>{1.0f, 2.0f, 3.0f,
|
||||
4.0f, 5.0f, 6.0f}));
|
||||
// As it's 128 bytes it could either be allocated using CreateTensorAsOrtValue or use existing memory.
|
||||
// Under 128 bytes must use CreateTensorAsOrtValue.
|
||||
std::vector<int64_t> y_dims = {4, 8};
|
||||
|
||||
deleter.weights.emplace_back(std::make_unique<std::vector<float>>(32));
|
||||
auto& y_values = *deleter.weights.back();
|
||||
std::iota(y_values.begin(), y_values.end(), 1.0f);
|
||||
|
||||
// create an initializer for the Y input. add to `weights` so the memory remains valid.
|
||||
OrtValue* y_tensor = nullptr;
|
||||
|
|
@ -228,18 +230,24 @@ TEST(ModelBuilderAPITest, Basic_CApi) {
|
|||
y_tensor = nullptr; // graph now owns
|
||||
|
||||
if (use_constant_node) {
|
||||
// Test that a Constant node is converted to an intializer
|
||||
// Test that a Constant node is converted to an initializer
|
||||
|
||||
// create Constant node that is used as the Max in a Clip to limit the output
|
||||
OrtOpAttr* value_attr = nullptr;
|
||||
float max = 60.0f;
|
||||
Ort::ThrowOnError(api.CreateOpAttr("value", &max, sizeof(max), ORT_OP_ATTR_FLOAT, &value_attr));
|
||||
|
||||
node = CreateNode(model_builder_api, "Constant", "clip_max", {}, {"max"}, {value_attr});
|
||||
// create Constant nodes for min/max to limit output range
|
||||
OrtOpAttr* min_attr = nullptr;
|
||||
float min = 400.0f;
|
||||
Ort::ThrowOnError(api.CreateOpAttr("value", &min, sizeof(min), ORT_OP_ATTR_FLOAT, &min_attr));
|
||||
node = CreateNode(model_builder_api, "Constant", "clip_min", {}, {"min"}, {min_attr});
|
||||
Ort::ThrowOnError(model_builder_api.AddNodeToGraph(graph, node));
|
||||
node = nullptr; // graph now owns node
|
||||
|
||||
node = CreateNode(model_builder_api, "Clip", "Clip1", {gemm_output_name.c_str(), "", "max"}, {"Z"});
|
||||
OrtOpAttr* max_attr = nullptr;
|
||||
float max = 900.0f;
|
||||
Ort::ThrowOnError(api.CreateOpAttr("value", &max, sizeof(max), ORT_OP_ATTR_FLOAT, &max_attr));
|
||||
node = CreateNode(model_builder_api, "Constant", "clip_max", {}, {"max"}, {max_attr});
|
||||
Ort::ThrowOnError(model_builder_api.AddNodeToGraph(graph, node));
|
||||
node = nullptr; // graph now owns node
|
||||
|
||||
node = CreateNode(model_builder_api, "Clip", "Clip1", {gemm_output_name.c_str(), "min", "max"}, {"Z"});
|
||||
Ort::ThrowOnError(model_builder_api.AddNodeToGraph(graph, node));
|
||||
node = nullptr; // graph now owns node
|
||||
}
|
||||
|
|
@ -261,22 +269,25 @@ TEST(ModelBuilderAPITest, Basic_CApi) {
|
|||
std::vector<Input<float>> inputs(1);
|
||||
auto& input = inputs[0];
|
||||
input.name = "X";
|
||||
input.dims = {3, 2};
|
||||
input.values = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f};
|
||||
input.dims = {3, 4};
|
||||
input.values = {1.0f, 2.0f, 3.0f, 4.0f,
|
||||
8.0f, 7.0f, 6.0f, 5.0f,
|
||||
9.0f, 3.0f, 5.0f, 7.0f};
|
||||
|
||||
std::vector<int64_t> expected_dims = {3, 3};
|
||||
std::vector<int64_t> expected_dims = {3, 8};
|
||||
ModelBuilderAPI::Model cxx_model(model);
|
||||
auto session = CreateSession(*ort_env, cxx_model);
|
||||
|
||||
std::vector<float> expected_output;
|
||||
if (use_constant_node) {
|
||||
expected_output = {18.0f, 24.0f, 30.0f,
|
||||
38.0f, 52.0f, 60.0f, // clipped
|
||||
58.0f, 60.0f, 60.0f}; // clipped
|
||||
// clipped with max 160
|
||||
expected_output = {400.0f, 400.0f, 400.0f, 400.0f, 420.0f, 440.0f, 460.0f, 480.0f,
|
||||
596.0f, 648.0f, 700.0f, 752.0f, 804.0f, 856.0f, 900.0f, 900.0f,
|
||||
592.0f, 640.0f, 688.0f, 736.0f, 784.0f, 832.0f, 880.0f, 900.0f};
|
||||
} else {
|
||||
expected_output = {18.0f, 24.0f, 30.0f,
|
||||
38.0f, 52.0f, 66.0f,
|
||||
58.0f, 80.0f, 102.0f};
|
||||
expected_output = {340.0f, 360.0f, 380.0f, 400.0f, 420.0f, 440.0f, 460.0f, 480.0f,
|
||||
596.0f, 648.0f, 700.0f, 752.0f, 804.0f, 856.0f, 908.0f, 960.0f,
|
||||
592.0f, 640.0f, 688.0f, 736.0f, 784.0f, 832.0f, 880.0f, 928.0f};
|
||||
}
|
||||
|
||||
TestInference<float>(session, inputs, "Z", expected_dims, expected_output);
|
||||
|
|
@ -306,7 +317,7 @@ TEST(ModelBuilderAPITest, Basic_CxxApi) {
|
|||
std::vector<ModelBuilderAPI::ValueInfo> graph_outputs;
|
||||
|
||||
// model input. it's {3, 2} but use a symbolic dim to test that works.
|
||||
std::vector<int64_t> input_dims({-1, 2});
|
||||
std::vector<int64_t> input_dims({-1, 4});
|
||||
std::vector<std::string> input_symbolic_dims({"multiple_of_3", ""});
|
||||
TensorTypeAndShapeInfo input_tensor_info(ONNXTensorElementDataType::ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT,
|
||||
input_dims,
|
||||
|
|
@ -315,7 +326,7 @@ TEST(ModelBuilderAPITest, Basic_CxxApi) {
|
|||
graph_inputs.emplace_back("X", input_type_info.GetConst());
|
||||
|
||||
// model outputs
|
||||
std::vector<int64_t> output_dims = {-1, 3};
|
||||
std::vector<int64_t> output_dims = {-1, 8};
|
||||
std::vector<std::string> output_symbolic_dims({"multiple_of_3", ""});
|
||||
TensorTypeAndShapeInfo output_tensor_info(ONNXTensorElementDataType::ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT,
|
||||
output_dims,
|
||||
|
|
@ -340,10 +351,14 @@ TEST(ModelBuilderAPITest, Basic_CxxApi) {
|
|||
|
||||
// create an initializer for the Y input.
|
||||
// add to `weights` so it remains valid for the lifetime of the session and we can avoid copying the data.
|
||||
std::vector<int64_t> y_dims = {2, 3};
|
||||
weights.emplace_back(std::make_unique<std::vector<float>>(std::initializer_list<float>{1.0f, 2.0f, 3.0f,
|
||||
4.0f, 5.0f, 6.0f}));
|
||||
// As it's 128 bytes it could either be allocated using CreateTensorAsOrtValue or use existing memory.
|
||||
// Under 128 bytes must use CreateTensorAsOrtValue.
|
||||
std::vector<int64_t> y_dims = {4, 8};
|
||||
|
||||
weights.emplace_back(std::make_unique<std::vector<float>>(32));
|
||||
auto& y_values = *weights.back();
|
||||
std::iota(y_values.begin(), y_values.end(), 1.0f);
|
||||
|
||||
auto info = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeDefault);
|
||||
|
||||
// if you use this API the initializer data MUST remain valid for the lifetime of the InferenceSession
|
||||
|
|
@ -357,16 +372,18 @@ TEST(ModelBuilderAPITest, Basic_CxxApi) {
|
|||
std::vector<Input<float>> inputs(1);
|
||||
auto& input = inputs[0];
|
||||
input.name = "X";
|
||||
input.dims = {3, 2};
|
||||
input.values = {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f};
|
||||
input.dims = {3, 4};
|
||||
input.values = {1.0f, 2.0f, 3.0f, 4.0f,
|
||||
8.0f, 7.0f, 6.0f, 5.0f,
|
||||
9.0f, 3.0f, 5.0f, 7.0f};
|
||||
|
||||
std::vector<int64_t> expected_dims = {3, 3};
|
||||
std::vector<int64_t> expected_dims = {3, 8};
|
||||
|
||||
auto session = CreateSession(*ort_env, model);
|
||||
TestInference<float>(session, inputs, "Z", expected_dims,
|
||||
{18.0f, 24.0f, 30.0f,
|
||||
38.0f, 52.0f, 66.0f,
|
||||
58.0f, 80.0f, 102.0f});
|
||||
{340.0f, 360.0f, 380.0f, 400.0f, 420.0f, 440.0f, 460.0f, 480.0f,
|
||||
596.0f, 648.0f, 700.0f, 752.0f, 804.0f, 856.0f, 908.0f, 960.0f,
|
||||
592.0f, 640.0f, 688.0f, 736.0f, 784.0f, 832.0f, 880.0f, 928.0f});
|
||||
}
|
||||
|
||||
TEST(ModelBuilderAPITest, BasicModelEdit_CxxApi) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue