diff --git a/onnxruntime/core/optimizer/initializer.cc b/onnxruntime/core/optimizer/initializer.cc index 05b880a88952d..05523e82a3c4e 100644 --- a/onnxruntime/core/optimizer/initializer.cc +++ b/onnxruntime/core/optimizer/initializer.cc @@ -72,10 +72,6 @@ Initializer::Initializer(const Graph& graph, const ONNX_NAMESPACE::TensorProto& data_ = GetTensor(ort_value_); return; } -#if !defined(__wasm__) - ORT_ENFORCE(!model_path.empty(), - "model_path must not be empty. Ensure that a path is provided when the model is created or loaded."); -#endif } Tensor tensor; diff --git a/onnxruntime/test/optimizer/initializer_test.cc b/onnxruntime/test/optimizer/initializer_test.cc index 6f340e9a9b734..9cd87c6f5b40f 100644 --- a/onnxruntime/test/optimizer/initializer_test.cc +++ b/onnxruntime/test/optimizer/initializer_test.cc @@ -17,6 +17,11 @@ #include "test/util/include/asserts.h" #include "test/util/include/file_util.h" +#include "core/framework/data_types.h" +#include "core/framework/tensor.h" +#include "core/graph/model.h" +#include "test/test_environment.h" + namespace onnxruntime { namespace test { #if !defined(__wasm__) @@ -270,5 +275,26 @@ TEST(OptimizerInitializerTest, DataField) { TestInitializerDataField(); } +// An in-memory external-data initializer with no registered OrtValue must load without a model_path. +TEST(OptimizerInitializerTest, InMemoryExternalDataWithoutOrtValueOrModelPath) { + std::vector backing(64); // 256 bytes > kSmallTensorExternalDataThreshold + std::iota(backing.begin(), backing.end(), 1.0f); + + Tensor src(DataTypeImpl::GetType(), TensorShape({static_cast(backing.size())}), + backing.data(), CPUAllocator::DefaultInstance()->Info()); + auto tensor_proto = utils::TensorToTensorProto(src, "in_memory_init", /*use_tensor_buffer=*/true); + ASSERT_TRUE(utils::HasExternalDataInMemory(tensor_proto)); + + Model model("InMemoryExternalDataInitializer", false, DefaultLoggingManager().DefaultLogger()); + const Graph& graph = model.MainGraph(); + const Initializer init(graph, tensor_proto, std::filesystem::path{}, /*check_outer_scope=*/false); + + ASSERT_EQ(init.size(), backing.size()); + const auto values = init.DataAsSpan(); + for (size_t i = 0; i < backing.size(); ++i) { + EXPECT_EQ(values[i], backing[i]) << "Mismatch at index " << i; + } +} + } // namespace test } // namespace onnxruntime