@@ -1226,26 +1226,6 @@ Graph::Graph(const Model& owning_model,
1226
1226
ArgNameToTypeMap name_to_type_map;
1227
1227
const auto & model_path = ModelPath ();
1228
1228
1229
- // If the tensor proto data is large enough, externalize it and replace with a tensor_proto
1230
- // with external data reference pointing to an OrtValue, otherwise do nothing.
1231
- auto put_data_maybe_in_memory = [this , &model_path](ONNX_NAMESPACE::TensorProto& tensor_proto) {
1232
- size_t size_in_bytes = 0 ;
1233
- ORT_THROW_IF_ERROR (utils::GetSizeInBytesFromTensorProto<0 >(tensor_proto, &size_in_bytes));
1234
- if (size_in_bytes > utils::kSmallTensorExternalDataThreshold ) {
1235
- OrtValue ort_value;
1236
- ORT_THROW_IF_ERROR (utils::TensorProtoToOrtValue (Env::Default (), model_path, tensor_proto,
1237
- CPUAllocator::DefaultInstance (), ort_value));
1238
- constexpr const bool use_tensor_buffer_true = true ;
1239
- auto tensor_proto_to_add = utils::TensorToTensorProto (ort_value.Get <Tensor>(), tensor_proto.name (),
1240
- use_tensor_buffer_true);
1241
- assert (ort_value.IsAllocated ());
1242
- auto ins_result = ortvalue_initializers_.insert_or_assign (tensor_proto_to_add.name (), std::move (ort_value));
1243
- ORT_ENFORCE (ins_result.second , " Unexpected duplicate insert or assign OrtValue for tensor: " , tensor_proto_to_add.name (),
1244
- " in the initializer list." );
1245
- tensor_proto = std::move (tensor_proto_to_add);
1246
- }
1247
- };
1248
-
1249
1229
// Process 'Constant' nodes
1250
1230
// Put the 'TensorProto' stored in the 'Constant' nodes attribute into the graphs initializer list
1251
1231
for (auto & node : graph_proto_->node ()) {
@@ -1265,8 +1245,6 @@ Graph::Graph(const Model& owning_model,
1265
1245
}
1266
1246
}
1267
1247
1268
- put_data_maybe_in_memory (*tensor);
1269
-
1270
1248
// Ensure initializers are also graph inputs.
1271
1249
if (ir_version_ < 4 ) {
1272
1250
TypeProto t{utils::TypeProtoFromTensorProto (*tensor)};
@@ -1343,22 +1321,7 @@ Graph::Graph(const Model& owning_model,
1343
1321
}
1344
1322
1345
1323
// Copy initial tensors to a map.
1346
- for (int i = 0 , lim = graph_proto_->initializer_size (); i < lim; ++i) {
1347
- auto & tensor = *graph_proto_->mutable_initializer (i);
1348
- // If data is on disk, it will be loaded either by optimizers
1349
- // or during session state finalization.
1350
- // If data is already in memory, do nothing.
1351
- if (!utils::HasExternalData (tensor)) {
1352
- const bool is_sparse = sparse_tensor_names_.count (tensor.name ());
1353
- if (is_sparse) {
1354
- sparse_tensor_names_.erase (tensor.name ());
1355
- }
1356
- put_data_maybe_in_memory (tensor);
1357
- if (is_sparse) {
1358
- sparse_tensor_names_.emplace (tensor.name ());
1359
- }
1360
- }
1361
-
1324
+ for (auto & tensor : graph_proto_->initializer ()) {
1362
1325
auto p = name_to_initial_tensor_.emplace (tensor.name (), &tensor);
1363
1326
if (!p.second ) {
1364
1327
LOGS (logger_, WARNING) << " Duplicate initializer (dense, sparse or ConstantNode): '" << tensor.name ()
@@ -3420,7 +3383,32 @@ Status Graph::Resolve(const ResolveOptions& options) {
3420
3383
3421
3384
ORT_RETURN_IF_ERROR (ForThisAndAllSubgraphs (all_subgraphs, finalize_func));
3422
3385
3423
- return Status::OK ();
3386
+ auto put_weights_maybe_in_memory_func = [&](Graph& graph) -> Status {
3387
+ // if we have any initializers that are not in memory, put them there.
3388
+ const auto & model_path = graph.ModelPath ();
3389
+ auto & graph_proto = *graph.graph_proto_ ;
3390
+ for (int i = 0 , lim = graph_proto.initializer_size (); i < lim; ++i) {
3391
+ auto & tensor_proto = *graph_proto.mutable_initializer (i);
3392
+ if (utils::HasExternalData (tensor_proto)) {
3393
+ continue ; // ignore data on disk, that will be loaded either by EP or at session_state finalize
3394
+ }
3395
+
3396
+ size_t size_in_bytes = 0 ;
3397
+ ORT_RETURN_IF_ERROR (utils::GetSizeInBytesFromTensorProto<0 >(tensor_proto, &size_in_bytes));
3398
+ if (size_in_bytes > utils::kSmallTensorExternalDataThreshold ) {
3399
+ OrtValue ort_value;
3400
+ ORT_RETURN_IF_ERROR (utils::TensorProtoToOrtValue (Env::Default (), model_path, tensor_proto,
3401
+ CPUAllocator::DefaultInstance (), ort_value));
3402
+ constexpr const bool use_tensor_buffer_true = true ;
3403
+ auto tensor_proto_to_add = utils::TensorToTensorProto (ort_value.Get <Tensor>(), tensor_proto.name (),
3404
+ use_tensor_buffer_true);
3405
+ ORT_RETURN_IF_ERROR (graph.ReplaceInitializedTensor (tensor_proto_to_add, ort_value));
3406
+ }
3407
+ }
3408
+ return Status::OK ();
3409
+ };
3410
+
3411
+ return ForThisAndAllSubgraphs (all_subgraphs, put_weights_maybe_in_memory_func);
3424
3412
}
3425
3413
3426
3414
void Graph::SetName (const std::string& name) {
@@ -3659,6 +3647,15 @@ Status Graph::ReplaceInitializedTensorImpl(ONNX_NAMESPACE::TensorProto new_initi
3659
3647
ORT_RETURN_IF_NOT (old_initializer.data_type () == new_initializer.data_type (),
3660
3648
" Replacement tensor's data type does not match." );
3661
3649
3650
+ bool is_sparse = false ;
3651
+ {
3652
+ auto sparse_tensor_it = sparse_tensor_names_.find (initializer_name);
3653
+ if (sparse_tensor_it != sparse_tensor_names_.end ()) {
3654
+ sparse_tensor_names_.erase (sparse_tensor_it);
3655
+ is_sparse = true ;
3656
+ }
3657
+ }
3658
+
3662
3659
auto & mutable_initializers = *(graph_proto_->mutable_initializer ());
3663
3660
// use cheaper pointer comparison to find old entry
3664
3661
auto existing_entry = std::find (mutable_initializers.pointer_begin (), mutable_initializers.pointer_end (),
@@ -3675,6 +3672,9 @@ Status Graph::ReplaceInitializedTensorImpl(ONNX_NAMESPACE::TensorProto new_initi
3675
3672
}
3676
3673
3677
3674
**existing_entry = std::move (new_initializer);
3675
+ if (is_sparse) {
3676
+ sparse_tensor_names_.insert ((**existing_entry).name ());
3677
+ }
3678
3678
3679
3679
return Status::OK ();
3680
3680
}
@@ -3720,7 +3720,7 @@ Status Graph::InjectExternalInitializedTensors(const InlinedHashMap<std::string,
3720
3720
Status Graph::InjectExternalInitializersFromFilesInMemory (
3721
3721
const InlinedHashMap<PathString, std::pair<char *, size_t >>& external_initializer_files) {
3722
3722
for (const auto & [tensor_name, tensor_proto] : name_to_initial_tensor_) {
3723
- if (tensor_proto-> data_location () == TensorProto_DataLocation_EXTERNAL ) {
3723
+ if (utils::HasExternalDataInFile (*tensor_proto) ) {
3724
3724
std::unique_ptr<ExternalDataInfo> external_data_info;
3725
3725
ORT_RETURN_IF_ERROR (ExternalDataInfo::Create (tensor_proto->external_data (), external_data_info));
3726
3726
@@ -3729,25 +3729,27 @@ Status Graph::InjectExternalInitializersFromFilesInMemory(
3729
3729
const size_t external_data_length = external_data_info->GetLength ();
3730
3730
SafeInt<size_t > tensor_byte_size;
3731
3731
ORT_RETURN_IF_ERROR (utils::GetSizeInBytesFromTensorProto<0 >(*tensor_proto, &tensor_byte_size));
3732
+
3732
3733
ORT_RETURN_IF_NOT (external_data_length == 0 || external_data_length == tensor_byte_size,
3733
3734
" TensorProto: " , tensor_name, " external data size mismatch. Computed size: " ,
3734
3735
*&tensor_byte_size, " , external_data.length: " , external_data_length);
3735
3736
3736
3737
SafeInt<FileOffsetType> end_of_read (file_offset);
3737
3738
end_of_read += tensor_byte_size;
3738
3739
3739
- auto external_file_pos = external_initializer_files.find (external_file);
3740
- ORT_RETURN_IF (external_file_pos == external_initializer_files.end (),
3740
+ auto user_provided_entry = external_initializer_files.find (external_file);
3741
+ ORT_RETURN_IF (user_provided_entry == external_initializer_files.end (),
3741
3742
" External file: " , ORT_TSTR_CONVERT_TO_PRINTABLE_STRING (external_file),
3742
3743
" not found from the table user provided." );
3743
- auto external_file_length = external_file_pos->second .second ;
3744
3744
3745
- ORT_RETURN_IF (file_offset < 0 || end_of_read > narrow<FileOffsetType>(external_file_length),
3745
+ auto user_provided_length = user_provided_entry->second .second ;
3746
+
3747
+ ORT_RETURN_IF (file_offset < 0 || end_of_read > narrow<FileOffsetType>(user_provided_length),
3746
3748
" External initializer: " , tensor_name,
3747
3749
" offset: " , file_offset, " size to read: " , external_data_length,
3748
- " given file_length: " , external_file_length , " are out of bounds or can not be read in full." );
3749
- char * external_file_buffer = static_cast <char *>(external_file_pos ->second .first );
3750
- char * tensor_buffer = external_file_buffer + file_offset;
3750
+ " given file_length: " , user_provided_length , " are out of bounds or can not be read in full." );
3751
+ char * user_provided_file_buffer = static_cast <char *>(user_provided_entry ->second .first );
3752
+ char * user_provided_tensor_buffer = user_provided_file_buffer + file_offset;
3751
3753
3752
3754
const auto & old_initializer = *(tensor_proto);
3753
3755
auto & mutable_initializers = *(graph_proto_->mutable_initializer ());
@@ -3762,19 +3764,11 @@ Status Graph::InjectExternalInitializersFromFilesInMemory(
3762
3764
const DataTypeImpl* const type =
3763
3765
DataTypeImpl::TensorTypeFromONNXEnum (old_initializer.data_type ())->GetElementType ();
3764
3766
TensorShape tensor_shape = utils::GetTensorShapeFromTensorProto (old_initializer);
3765
- auto tensor = Tensor (type, tensor_shape, tensor_buffer ,
3767
+ auto tensor = Tensor (type, tensor_shape, user_provided_tensor_buffer ,
3766
3768
OrtMemoryInfo (CPU, OrtAllocatorType::OrtDeviceAllocator));
3767
3769
3768
- constexpr const bool use_tensor_buffer_true = true ;
3769
- auto new_tensor_proto = utils::TensorToTensorProto (tensor, tensor_name, use_tensor_buffer_true);
3770
- // Implied that external data is in memory
3771
- const bool has_external_data_in_memory = utils::HasExternalData (new_tensor_proto);
3772
-
3773
- OrtValue ort_value;
3774
- if (has_external_data_in_memory) {
3775
- Tensor::InitOrtValue (std::move (tensor), ort_value);
3776
- }
3777
- ortvalue_initializers_.insert_or_assign (tensor_name, std::move (ort_value));
3770
+ constexpr const bool use_tensor_buffer_false = false ;
3771
+ auto new_tensor_proto = utils::TensorToTensorProto (tensor, tensor_name, use_tensor_buffer_false);
3778
3772
**existing_entry = std::move (new_tensor_proto);
3779
3773
}
3780
3774
}
0 commit comments