mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-23 19:32:23 +00:00
Disable external initializers build option (#7635)
* Merge set custom allocator to master * Add documentation for the new API. Reset global env in testCustomArenaAllocator so won't have a registered allocator of type arena (from previous test) * Add a session option config that will allow to disable loading model with initializers that have an external data (+test it). * Add the model used for the test and its external initializers data * Change the session config option that disable external initializers to a build option. * Addressing PR comments
This commit is contained in:
parent
6c868341e3
commit
374acf1423
7 changed files with 130 additions and 13 deletions
|
|
@ -124,6 +124,7 @@ option(onnxruntime_EXTENDED_MINIMAL_BUILD "onnxruntime_MINIMAL_BUILD with suppor
|
|||
option(onnxruntime_MINIMAL_BUILD_CUSTOM_OPS "Add custom operator kernels support to a minimal build." OFF)
|
||||
option(onnxruntime_REDUCED_OPS_BUILD "Reduced set of kernels are registered in build via modification of the kernel registration source files." OFF)
|
||||
option(onnxruntime_DISABLE_ORT_FORMAT_LOAD "Disable loading an ORT format model when onnxruntime_MINIMAL_BUILD=OFF (i.e. in a full build)." OFF)
|
||||
option(onnxruntime_DISABLE_EXTERNAL_INITIALIZERS "Don't allow models to load external data" OFF)
|
||||
|
||||
#A special option just for debugging and sanitize check. Please do not enable in option in retail builds.
|
||||
#The option has no effect on Windows.
|
||||
|
|
@ -363,6 +364,10 @@ if (onnxruntime_REDUCED_OPS_BUILD)
|
|||
add_compile_definitions(REDUCED_OPS_BUILD)
|
||||
endif()
|
||||
|
||||
if(onnxruntime_DISABLE_EXTERNAL_INITIALIZERS)
|
||||
add_definitions(-DDISABLE_EXTERNAL_INITIALIZERS=1)
|
||||
endif()
|
||||
|
||||
if(onnxruntime_DISABLE_RTTI)
|
||||
add_compile_definitions(ORT_NO_RTTI GOOGLE_PROTOBUF_NO_RTTI)
|
||||
if(MSVC)
|
||||
|
|
|
|||
|
|
@ -785,13 +785,13 @@ struct OrtApi {
|
|||
* \name - name of the attribute to be parsed
|
||||
* \out - pointer to memory where the attribute's contents are to be stored
|
||||
* \size - actual size of string attribute
|
||||
* (If `out` is nullptr, the value of `size` is set to the true size of the string
|
||||
* (If `out` is nullptr, the value of `size` is set to the true size of the string
|
||||
attribute, and a success status is returned.
|
||||
|
||||
|
||||
If the `size` parameter is greater than or equal to the actual string attribute's size,
|
||||
the value of `size` is set to the true size of the string attribute, the provided memory
|
||||
is filled with the attribute's contents, and a success status is returned.
|
||||
|
||||
|
||||
If the `size` parameter is lesser than the actual string attribute's size and `out`
|
||||
is not nullptr, the value of `size` is set to the true size of the string attribute
|
||||
and a failure status is returned.)
|
||||
|
|
@ -1258,14 +1258,14 @@ struct OrtApi {
|
|||
* \name - name of the attribute to be parsed
|
||||
* \out - pointer to memory where the attribute's contents are to be stored
|
||||
* \size - actual size of attribute array
|
||||
* (If `out` is nullptr, the value of `size` is set to the true size of the attribute
|
||||
* (If `out` is nullptr, the value of `size` is set to the true size of the attribute
|
||||
array's size, and a success status is returned.
|
||||
|
||||
|
||||
If the `size` parameter is greater than or equal to the actual attribute array's size,
|
||||
the value of `size` is set to the true size of the attribute array's size,
|
||||
the provided memory is filled with the attribute's contents,
|
||||
the provided memory is filled with the attribute's contents,
|
||||
and a success status is returned.
|
||||
|
||||
|
||||
If the `size` parameter is lesser than the actual attribute array's size and `out`
|
||||
is not nullptr, the value of `size` is set to the true size of the attribute array's size
|
||||
and a failure status is returned.)
|
||||
|
|
@ -1279,14 +1279,14 @@ struct OrtApi {
|
|||
* \name - name of the attribute to be parsed
|
||||
* \out - pointer to memory where the attribute's contents are to be stored
|
||||
* \size - actual size of attribute array
|
||||
* (If `out` is nullptr, the value of `size` is set to the true size of the attribute
|
||||
* (If `out` is nullptr, the value of `size` is set to the true size of the attribute
|
||||
array's size, and a success status is returned.
|
||||
|
||||
|
||||
If the `size` parameter is greater than or equal to the actual attribute array's size,
|
||||
the value of `size` is set to the true size of the attribute array's size,
|
||||
the provided memory is filled with the attribute's contents,
|
||||
the provided memory is filled with the attribute's contents,
|
||||
and a success status is returned.
|
||||
|
||||
|
||||
If the `size` parameter is lesser than the actual attribute array's size and `out`
|
||||
is not nullptr, the value of `size` is set to the true size of the attribute array's size
|
||||
and a failure status is returned.)
|
||||
|
|
|
|||
|
|
@ -1160,6 +1160,18 @@ common::Status InferenceSession::Initialize() {
|
|||
have_cpu_ep = execution_providers_.Get(onnxruntime::kCpuExecutionProvider) != nullptr;
|
||||
}
|
||||
|
||||
// Verify that there are no external initializers in the graph if external data is disabled.
|
||||
onnxruntime::Graph& graph = model_->MainGraph();
|
||||
#ifdef DISABLE_EXTERNAL_INITIALIZERS
|
||||
const InitializedTensorSet& initializers = graph.GetAllInitializedTensors();
|
||||
for (const auto& it: initializers) {
|
||||
if (utils::HasExternalData(*it.second)) {
|
||||
return common::Status(common::ONNXRUNTIME, common::FAIL,
|
||||
"Initializer tensors with external data is not allowed.");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Register default CPUExecutionProvider if user didn't provide it through the Register() calls.
|
||||
// RegisterExecutionProvider locks the session_mutex_ so we can't be holding it when we call that
|
||||
if (!have_cpu_ep) {
|
||||
|
|
@ -1210,8 +1222,6 @@ common::Status InferenceSession::Initialize() {
|
|||
session_options_.enable_mem_reuse,
|
||||
prepacked_weights_container_);
|
||||
|
||||
onnxruntime::Graph& graph = model_->MainGraph();
|
||||
|
||||
// Collect the kernel registries from execution provider instances;
|
||||
// There are 2 kinds of kernel registries with priority from high to low as below,
|
||||
// 1. Custom execution provider type specific kernel registries.
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
// Licensed under the MIT License.
|
||||
|
||||
#include "core/session/onnxruntime_cxx_api.h"
|
||||
#include "onnxruntime_session_options_config_keys.h"
|
||||
#include "test/util/include/asserts.h"
|
||||
#ifdef USE_CUDA
|
||||
#include "core/providers/cuda/cuda_provider_factory.h"
|
||||
#endif
|
||||
|
|
@ -57,5 +59,20 @@ TEST(CApiTest, model_from_array) {
|
|||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DISABLE_EXTERNAL_INITIALIZERS
|
||||
TEST(CApiTest, TestDisableExternalInitiliazers) {
|
||||
|
||||
const char* model_path = "testdata/model_with_external_initializers.onnx";
|
||||
|
||||
Ort::SessionOptions so;
|
||||
try {
|
||||
Ort::Session session(*ort_env.get(), model_path, so);
|
||||
ASSERT_TRUE(false) << "Creation of session should have thrown exception";
|
||||
} catch (const std::exception& ex) {
|
||||
ASSERT_THAT(ex.what(), testing::HasSubstr("Initializer tensors with external data is not allowed."));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} // namespace test
|
||||
} // namespace onnxruntime
|
||||
|
|
|
|||
BIN
onnxruntime/test/testdata/Pads.bin
vendored
Normal file
BIN
onnxruntime/test/testdata/Pads.bin
vendored
Normal file
Binary file not shown.
19
onnxruntime/test/testdata/model_with_external_initializers.onnx
vendored
Normal file
19
onnxruntime/test/testdata/model_with_external_initializers.onnx
vendored
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
onnx-example:–
|
||||
&
|
||||
X
|
||||
PadsY"Pad*
|
||||
mode"constant
|
||||
test-model*"BPadsj
|
||||
locationPads.binpZ
|
||||
X
|
||||
|
||||
|
||||
Z
|
||||
Pads
|
||||
|
||||
|
||||
b
|
||||
Y
|
||||
|
||||
|
||||
B
|
||||
66
onnxruntime/test/testdata/model_with_external_initializers.py
vendored
Normal file
66
onnxruntime/test/testdata/model_with_external_initializers.py
vendored
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
# Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
# Licensed under the MIT License.
|
||||
|
||||
import onnx
|
||||
import numpy as np
|
||||
from onnx import helper
|
||||
from onnx import TensorProto
|
||||
from onnx.numpy_helper import from_array
|
||||
from onnx.external_data_helper import set_external_data
|
||||
|
||||
|
||||
def create_external_data_tensor(value, tensor_name): # type: (List[Any], Text) -> TensorProto
|
||||
tensor = from_array(np.array(value))
|
||||
tensor.name = tensor_name
|
||||
tensor_filename = "{}.bin".format(tensor_name)
|
||||
set_external_data(tensor, location=tensor_filename)
|
||||
|
||||
with open(os.path.join(tensor_filename), 'wb') as data_file:
|
||||
data_file.write(tensor.raw_data)
|
||||
tensor.ClearField('raw_data')
|
||||
tensor.data_location = onnx.TensorProto.EXTERNAL
|
||||
return tensor
|
||||
|
||||
|
||||
def GenerateModel(model_name):
|
||||
# Create one input (ValueInfoProto)
|
||||
X = helper.make_tensor_value_info('X', TensorProto.FLOAT, [1, 2])
|
||||
|
||||
# Create second input (ValueInfoProto)
|
||||
Pads = helper.make_tensor_value_info('Pads', TensorProto.INT64, [4])
|
||||
|
||||
# Create one output (ValueInfoProto)
|
||||
Y = helper.make_tensor_value_info('Y', TensorProto.FLOAT, [1, 4])
|
||||
|
||||
# Create a node (NodeProto)
|
||||
node_def = helper.make_node(
|
||||
'Pad', # node name
|
||||
['X', 'Pads'], # inputs
|
||||
['Y'], # outputs
|
||||
mode='constant', # Attributes
|
||||
)
|
||||
|
||||
# Create the graph (GraphProto)
|
||||
graph_def = helper.make_graph(
|
||||
[node_def],
|
||||
"test-model",
|
||||
[X, Pads],
|
||||
[Y],
|
||||
[create_external_data_tensor([0, 0, 1, 1, ], "Pads")]
|
||||
)
|
||||
|
||||
# Create the model (ModelProto)
|
||||
model_def = helper.make_model(graph_def,
|
||||
producer_name='onnx-example')
|
||||
|
||||
print('The ir_version in model: {}\n'.format(model_def.ir_version))
|
||||
print('The producer_name in model: {}\n'.format(model_def.producer_name))
|
||||
print('The graph in model:\n{}'.format(model_def.graph))
|
||||
onnx.checker.check_model(model_def)
|
||||
print('The model is checked!')
|
||||
with open(model_name, "wb") as model_file:
|
||||
model_file.write(model_def.SerializeToString())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
GenerateModel('model_with_external_initializers.onnx')
|
||||
Loading…
Reference in a new issue