Skip to content

Commit c162ab6

Browse files
committed
Merge remote-tracking branch 'origin/main' into snnn/rn
2 parents 76d47d1 + 06a3ccf commit c162ab6

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

onnxruntime/python/onnxruntime_pybind_state.cc

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2300,7 +2300,50 @@ Applies to session load, initialization, etc. Default is 0.)pbdoc")
23002300
ORT_UNUSED_PARAMETER(ort_values);
23012301
ORT_THROW("External initializers are not supported in this build.");
23022302
#endif
2303-
});
2303+
})
2304+
.def("add_external_initializers_from_files_in_memory", [](PySessionOptions* options, std::vector<std::string> names, std::vector<py::buffer> buffers, std::vector<size_t> lengths) -> void {
2305+
#if !defined(ORT_MINIMAL_BUILD) && !defined(DISABLE_EXTERNAL_INITIALIZERS)
2306+
const auto num = names.size();
2307+
ORT_ENFORCE(num == buffers.size() && num == lengths.size(),
2308+
"add_external_initializers_from_files_in_memory: expecting 'names', 'buffers' and 'lengths' to have equal length");
2309+
2310+
InlinedVector<PathString> file_names;
2311+
InlinedVector<std::pair<char*, const size_t>> files_buffers;
2312+
file_names.reserve(num);
2313+
files_buffers.reserve(num);
2314+
2315+
for (size_t i = 0; i < num; ++i) {
2316+
// Convert name and buffer using pybind-provided conversions
2317+
file_names.emplace_back(ToPathString(names[i]));
2318+
2319+
// buffers[i] is a py::buffer; request() retrieves pointer without copying
2320+
py::buffer_info info = buffers[i].request();
2321+
char* data_ptr = static_cast<char*>(info.ptr);
2322+
2323+
files_buffers.emplace_back(std::make_pair(data_ptr, lengths[i]));
2324+
}
2325+
2326+
ORT_THROW_IF_ERROR(options->value.AddExternalInitializersFromFilesInMemory(file_names, files_buffers));
2327+
#else
2328+
ORT_UNUSED_PARAMETER(options);
2329+
ORT_UNUSED_PARAMETER(names);
2330+
ORT_UNUSED_PARAMETER(buffers);
2331+
ORT_UNUSED_PARAMETER(lengths);
2332+
ORT_THROW("External initializers are not supported in this build.");
2333+
#endif
2334+
},
2335+
R"pbdoc(
2336+
Provide external initializer file contents from memory.
2337+
2338+
Args:
2339+
names: sequence[str] of external file names (as referenced by the model's external_data locations).
2340+
buffers: sequence[bytes-like] objects exposing the buffer protocol (e.g., bytes, bytearray, memoryview, numpy uint8 array) containing the corresponding file contents.
2341+
lengths: sequence[int] sizes in bytes for each buffer.
2342+
2343+
Notes:
2344+
- Keep the provided buffers alive until after session creation completes. ONNX Runtime copies needed data during session creation.
2345+
- The bytestream must match the external file layout expected by the model (raw tensor bytes at the specified offsets).
2346+
)pbdoc");
23042347

23052348
py::class_<RunOptions>(m, "RunOptions", R"pbdoc(Configuration information for a single Run.)pbdoc")
23062349
.def(py::init())

onnxruntime/test/python/onnxruntime_test_python.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,6 +1305,25 @@ def test_session_options_add_external_initializers(self):
13051305
providers=["CPUExecutionProvider"],
13061306
)
13071307

1308+
def test_session_options_add_external_initializers_from_files_in_memory(self):
1309+
# Provide external initializer file content directly from memory
1310+
# The model references an external file named "Pads_not_on_disk.bin" for the initializer
1311+
pads_bytes = np.array([0, 0, 1, 1], dtype=np.int64).tobytes()
1312+
1313+
so = onnxrt.SessionOptions()
1314+
so.add_external_initializers_from_files_in_memory(
1315+
["Pads_not_on_disk.bin"],
1316+
[pads_bytes],
1317+
[len(pads_bytes)],
1318+
)
1319+
1320+
# This should not throw
1321+
onnxrt.InferenceSession(
1322+
get_name("model_with_external_initializer_come_from_user.onnx"),
1323+
sess_options=so,
1324+
providers=["CPUExecutionProvider"],
1325+
)
1326+
13081327
def test_register_custom_ops_library(self):
13091328
if sys.platform.startswith("win"):
13101329
shared_library = os.path.abspath("custom_op_library.dll")

0 commit comments

Comments
 (0)