@@ -129,6 +129,21 @@ int ParseSpinDurationUs(std::string_view str, const char* config_key,
129129 return spin_us;
130130}
131131
132+ #if !defined(ORT_MINIMAL_BUILD)
133+ // Returns the virtual model path derived from the
134+ // kOrtSessionOptionsModelExternalInitializersFileFolderPath config option, or an empty
135+ // PathString when the option is not set. When set, external initializers are resolved
136+ // relative to this folder, overriding the model's own directory.
137+ PathString GetExternalInitializersFolderModelPath (const ConfigOptions& config_options) {
138+ const std::string external_data_folder_path = config_options.GetConfigOrDefault (
139+ kOrtSessionOptionsModelExternalInitializersFileFolderPath , " " );
140+ if (external_data_folder_path.empty ()) {
141+ return PathString{};
142+ }
143+ return ToPathString (external_data_folder_path + " /virtual_model.onnx" );
144+ }
145+ #endif // !defined(ORT_MINIMAL_BUILD)
146+
132147// Parse a spin backoff max config value (exponential-backoff cap). Defaults to
133148// 1 (no backoff, one SpinPause() per iteration). Values >= 2 enable backoff.
134149unsigned int ParseSpinBackoffMax (std::string_view str, const char * config_key,
@@ -1171,7 +1186,7 @@ common::Status InferenceSession::LoadWithLoader(std::function<common::Status(std
11711186
11721187common::Status InferenceSession::LoadOnnxModel (const PathString& model_uri) {
11731188 model_location_ = model_uri;
1174- auto loader = [this ](std::shared_ptr<onnxruntime::Model>& model) {
1189+ auto loader = [this , model_uri ](std::shared_ptr<onnxruntime::Model>& model) {
11751190#ifdef ENABLE_LANGUAGE_INTEROP_OPS
11761191 LoadInterOp (model_location_, interop_domains_, [&](const char * msg) { LOGS (*session_logger_, WARNING ) << msg; });
11771192 InlinedVector<OrtCustomOpDomain*> domain_ptrs;
@@ -1182,10 +1197,19 @@ common::Status InferenceSession::LoadOnnxModel(const PathString& model_uri) {
11821197
11831198 const bool strict_shape_type_inference = session_options_.config_options .GetConfigOrDefault (
11841199 kOrtSessionOptionsConfigStrictShapeTypeInference , " 0" ) == " 1" ;
1200+ ModelOptions model_opts (true , strict_shape_type_inference, check_load_cancellation_fn_);
1201+
1202+ // When set, the external initializers folder overrides the model's own directory as the
1203+ // base for resolving external data. The model bytes are still read from model_uri.
1204+ PathString external_data_model_path = GetExternalInitializersFolderModelPath (session_options_.config_options );
1205+ if (!external_data_model_path.empty ()) {
1206+ model_location_ = external_data_model_path;
1207+ return onnxruntime::Model::Load (model_uri, model_location_, model,
1208+ HasLocalSchema () ? &custom_schema_registries_ : nullptr ,
1209+ *session_logger_, model_opts);
1210+ }
11851211 return onnxruntime::Model::Load (model_location_, model, HasLocalSchema () ? &custom_schema_registries_ : nullptr ,
1186- *session_logger_,
1187- ModelOptions (true , strict_shape_type_inference,
1188- check_load_cancellation_fn_));
1212+ *session_logger_, model_opts);
11891213 };
11901214
11911215 common::Status st = LoadWithLoader (loader, " model_loading_uri" );
@@ -1270,10 +1294,9 @@ common::Status InferenceSession::Load(const void* model_data, int model_data_len
12701294 const bool strict_shape_type_inference = session_options_.config_options .GetConfigOrDefault (
12711295 kOrtSessionOptionsConfigStrictShapeTypeInference , " 0" ) == " 1" ;
12721296
1273- std::string external_data_folder_path = session_options_.config_options .GetConfigOrDefault (
1274- kOrtSessionOptionsModelExternalInitializersFileFolderPath , " " );
1275- if (!external_data_folder_path.empty () && model_location_.empty ()) {
1276- model_location_ = ToPathString (external_data_folder_path + " /virtual_model.onnx" );
1297+ PathString external_data_model_path = GetExternalInitializersFolderModelPath (session_options_.config_options );
1298+ if (!external_data_model_path.empty ()) {
1299+ model_location_ = external_data_model_path;
12771300 }
12781301
12791302 return onnxruntime::Model::Load (std::move (model_proto), model_location_, model,
@@ -1308,10 +1331,9 @@ common::Status InferenceSession::LoadOnnxModel(ModelProto model_proto) {
13081331 const bool strict_shape_type_inference = session_options_.config_options .GetConfigOrDefault (
13091332 kOrtSessionOptionsConfigStrictShapeTypeInference , " 0" ) == " 1" ;
13101333
1311- std::string external_data_folder_path = session_options_.config_options .GetConfigOrDefault (
1312- kOrtSessionOptionsModelExternalInitializersFileFolderPath , " " );
1313- if (!external_data_folder_path.empty () && model_location_.empty ()) {
1314- model_location_ = ToPathString (external_data_folder_path + " /virtual_model.onnx" );
1334+ PathString external_data_model_path = GetExternalInitializersFolderModelPath (session_options_.config_options );
1335+ if (!external_data_model_path.empty ()) {
1336+ model_location_ = external_data_model_path;
13151337 }
13161338
13171339 // This call will move model_proto to the constructed model instance
@@ -1354,10 +1376,9 @@ common::Status InferenceSession::Load(std::istream& model_istream, bool allow_re
13541376 strict_shape_type_inference,
13551377 check_load_cancellation_fn_);
13561378
1357- std::string external_data_folder_path = session_options_.config_options .GetConfigOrDefault (
1358- kOrtSessionOptionsModelExternalInitializersFileFolderPath , " " );
1359- if (!external_data_folder_path.empty () && model_location_.empty ()) {
1360- model_location_ = ToPathString (external_data_folder_path + " /virtual_model.onnx" );
1379+ PathString external_data_model_path = GetExternalInitializersFolderModelPath (session_options_.config_options );
1380+ if (!external_data_model_path.empty ()) {
1381+ model_location_ = external_data_model_path;
13611382 }
13621383
13631384 return onnxruntime::Model::Load (std::move (model_proto), model_location_, model,
@@ -1388,6 +1409,11 @@ common::Status InferenceSession::Load() {
13881409 const bool allow_released_opsets_only = session_options_.config_options .GetConfigOrDefault (
13891410 kOrtSessionOptionsConfigStrictAllowReleasedOpsetsOnly , " 1" ) == " 1" ;
13901411
1412+ PathString external_data_model_path = GetExternalInitializersFolderModelPath (session_options_.config_options );
1413+ if (!external_data_model_path.empty ()) {
1414+ model_location_ = external_data_model_path;
1415+ }
1416+
13911417 // Pass on ownership of the parsed ModelProto to the Model instance (its job here is done by this stage)
13921418 return Model::Load (std::move (this ->model_proto_ ), model_location_, model,
13931419 HasLocalSchema () ? &custom_schema_registries_ : nullptr , *session_logger_,
0 commit comments