Skip to content

Commit 27de00a

Browse files
committed
Add support for optimized bin file creation
1 parent c2558f3 commit 27de00a

File tree

4 files changed

+153
-7
lines changed

4 files changed

+153
-7
lines changed

onnxruntime/core/providers/openvino/backend_manager.cc

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,21 @@ Status BackendManager::ExportCompiledBlobAsEPCtxNode(const onnxruntime::GraphVie
215215
// If not embed_mode, dump the blob here and only pass on the path to the blob
216216
std::string model_blob_str;
217217
auto compiled_model = concrete_backend_->GetOVCompiledModel();
218-
if (session_context_.so_context_embed_mode) { // Internal blob
218+
if (session_context_.so_share_ep_contexts){
219+
std::ostringstream model_blob_stream;
220+
compiled_model.export_model(model_blob_stream);
221+
222+
// std::ofstream file(metadata_filename, std::ios::app| std::ios::binary);
223+
// std::cout << " write to metadata bin - " << metadata_filename << std::endl;
224+
auto& bin_file = shared_context_.shared_weights.shared_bin_file.bin_file_;
225+
if (bin_file.is_open()) {
226+
bin_file << model_blob_stream.str();
227+
}
228+
std::cout << "Current offset after "<< subgraph_context_.subgraph_name << " = " << bin_file.tellp() << std::endl;
229+
230+
model_blob_str = shared_context_.shared_weights.shared_bin_file.shared_bin_filename.filename().string();
231+
} else if (session_context_.so_context_embed_mode) {
232+
// Internal blob
219233
std::ostringstream model_blob_stream;
220234
compiled_model.export_model(model_blob_stream);
221235
model_blob_str = std::move(model_blob_stream).str();

onnxruntime/core/providers/openvino/backend_utils.cc

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,30 @@ std::ostream& operator<<(std::ostream& stream, const SharedContext::SharedWeight
6969
return stream;
7070
}
7171

72+
std::ostream& operator<<(std::ostream& stream,
73+
const SharedContext::SharedWeights::SubgraphMetadata::Map& subgraph_metadata) {
74+
try {
75+
stream << subgraph_metadata.size();
76+
77+
// Write each key-value pair
78+
// Put elements in separate lines to facilitate reading
79+
for (const auto& [key, value] : subgraph_metadata) {
80+
stream << std::endl
81+
<< key.name;
82+
stream << std::endl
83+
<< value.epctx_offset;
84+
stream << std::endl
85+
<< value.epctx_length;
86+
}
87+
} catch (const Exception& e) {
88+
ORT_THROW("Error: Failed to write subgraph map data.", e.what());
89+
} catch (...) {
90+
ORT_THROW("Error: Failed to write subgraph map data.");
91+
}
92+
ORT_ENFORCE(stream.good(), "Error: Failed to write subgraph map data.");
93+
return stream;
94+
}
95+
7296
std::istream& operator>>(std::istream& stream, SharedContext::SharedWeights::Metadata::Map& metadata) {
7397
size_t map_size{0};
7498
try {
@@ -117,6 +141,30 @@ std::istream& operator>>(std::istream& stream, SharedContext::SharedWeights::Met
117141

118142
return stream;
119143
}
144+
std::istream& operator>>(std::istream& stream, SharedContext::SharedWeights::SubgraphMetadata::Map& subgraph_metadata) {
145+
size_t map_size{0};
146+
try {
147+
stream >> map_size;
148+
149+
while (!stream.eof()) {
150+
SharedContext::SharedWeights::SubgraphMetadata::Key key;
151+
SharedContext::SharedWeights::SubgraphMetadata::Value value;
152+
stream >> key.name;
153+
stream >> value.epctx_offset;
154+
stream >> value.epctx_length;
155+
156+
subgraph_metadata.emplace(key, value);
157+
}
158+
} catch (const Exception& e) {
159+
ORT_THROW("Error: Failed to read map data.", e.what());
160+
} catch (...) {
161+
ORT_THROW("Error: Failed to read map data.");
162+
}
163+
164+
ORT_ENFORCE(subgraph_metadata.size() == map_size, "Error: Inconsistent map data.");
165+
166+
return stream;
167+
}
120168

121169
namespace backend_utils {
122170

onnxruntime/core/providers/openvino/contexts.h

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,22 @@ class SharedContext : public WeakSingleton<SharedContext> {
2525
public:
2626
SharedContext() : OVCore_(OVCore::Get()) {}
2727
struct SharedWeights {
28+
struct Header {
29+
uint32_t bin_version=1;
30+
uint32_t footer_offset;
31+
Header(uint32_t bin_in, uint32_t footer_in) :
32+
bin_version(bin_in), footer_offset(footer_in){}
33+
};
34+
struct Footer {
35+
uint32_t subgraph_offset;
36+
uint32_t subgraph_length;
37+
uint32_t metadata_offset;
38+
uint32_t metadata_length;
39+
Footer(uint32_t subgraph_offset_in, uint32_t subgraph_length_in,
40+
uint32_t metadata_offset_in, uint32_t metadata_length_in) :
41+
subgraph_offset(subgraph_offset_in), subgraph_length(subgraph_length_in),
42+
metadata_offset(metadata_offset_in), metadata_length(metadata_length_in) {}
43+
};
2844
struct Metadata {
2945
struct Key {
3046
std::string name;
@@ -37,8 +53,8 @@ class SharedContext : public WeakSingleton<SharedContext> {
3753
};
3854
struct Value {
3955
std::string location;
40-
unsigned int data_offset;
41-
unsigned int size;
56+
uint32_t data_offset;
57+
uint32_t size;
4258
std::vector<size_t> dimensions;
4359
std::int32_t element_type;
4460
std::shared_ptr<ov::Tensor> tensor;
@@ -48,6 +64,25 @@ class SharedContext : public WeakSingleton<SharedContext> {
4864
friend std::istream& operator>>(std::istream& right, Metadata::Map& metadata);
4965
};
5066

67+
struct SubgraphMetadata {
68+
struct Key {
69+
std::string name;
70+
bool operator==(const Key&) const = default;
71+
};
72+
struct Hash {
73+
std::size_t operator()(const Key& key) const noexcept {
74+
return std::hash<std::string>()(key.name);
75+
}
76+
};
77+
struct Value {
78+
uint32_t epctx_offset;
79+
uint32_t epctx_length;
80+
};
81+
using Map = std::unordered_map<Key, Value, Hash>;
82+
friend std::ostream& operator<<(std::ostream& right, const SubgraphMetadata::Map& subgraph_metadata);
83+
friend std::istream& operator>>(std::istream& right, SubgraphMetadata::Map& subgraph_metadata);
84+
};
85+
5186
struct WeightsFile {
5287
ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(WeightsFile);
5388
WeightsFile() = delete;
@@ -60,10 +95,38 @@ class SharedContext : public WeakSingleton<SharedContext> {
6095
size_t weights_size_;
6196
};
6297

98+
struct SharedBinFile {
99+
// ORT_DISALLOW_COPY_ASSIGNMENT_AND_MOVE(SharedBinFile);
100+
// SharedBinFile() = delete;
101+
// SharedBinFile(fs::path shared_bin_filename) :
102+
// bin_file_(shared_bin_filename, std::ios::out | std::ios::app| std::ios::binary) {
103+
// if(bin_file_.is_open())
104+
// std::cout << " Bin file opened " << std::endl;
105+
// }
106+
fs::path shared_bin_filename;
107+
std::ofstream bin_file_;
108+
109+
SharedBinFile() = default; // Default constructor
110+
~SharedBinFile() = default; // Prevent closing the file automatically
111+
112+
void openBinFile(fs::path shared_bin_filename) {
113+
if (!bin_file_.is_open()) { // Prevent reopening
114+
bin_file_.open(shared_bin_filename, std::ios::out | std::ios::app | std::ios::binary);
115+
if (!bin_file_) {
116+
throw std::runtime_error("Failed to open log file!");
117+
}
118+
}
119+
}
120+
}shared_bin_file;
121+
63122
fs::path external_weight_filename;
64123
std::unique_ptr<WeightsFile> mapped_weights;
124+
std::unique_ptr<Header> header_;
125+
std::unique_ptr<Footer> footer_;
126+
// std::unique_ptr<SharedBinFile> shared_bin_file;
65127
Metadata::Map metadata;
66-
} shared_weights;
128+
SubgraphMetadata::Map subgraph_metadata;
129+
}shared_weights;
67130
};
68131

69132
using config_t = std::map<std::string, ov::AnyMap>;

onnxruntime/core/providers/openvino/openvino_execution_provider.cc

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,21 +93,30 @@ common::Status OpenVINOExecutionProvider::Compile(
9393
std::vector<NodeComputeInfo>& node_compute_funcs) {
9494
auto& logger = *GetLogger();
9595
Status status = Status::OK();
96-
96+
auto &sb = shared_context_.shared_weights.shared_bin_file;
9797
if (!fused_nodes.empty()) {
9898
// Assume these properties are constant for all the model subgraphs, otherwise move to SubGraphContext
9999
const auto& graph_body_viewer_0 = fused_nodes[0].filtered_graph.get();
100100
session_context_.onnx_model_path_name = graph_body_viewer_0.ModelPath().string();
101101
session_context_.onnx_opset_version =
102102
graph_body_viewer_0.DomainToVersionMap().at(kOnnxDomain);
103+
104+
if (session_context_.so_share_ep_contexts){
105+
if(session_context_.so_context_file_path.empty()) {
106+
sb.shared_bin_filename = session_context_.onnx_model_path_name.parent_path() / "metadata.bin";
107+
} else {
108+
sb.shared_bin_filename = session_context_.so_context_file_path.parent_path() / "metadata.bin";
109+
}
110+
sb.openBinFile(sb.shared_bin_filename);
111+
}
103112
}
104113

114+
105115
// Temporary code to read metadata before it moves to the .bin
106116
auto& metadata = shared_context_->shared_weights.metadata;
107117
if (session_context_.so_share_ep_contexts && metadata.empty()) {
108118
// Metadata is always read from model location, this could be a source or epctx model
109-
fs::path metadata_filename = session_context_.onnx_model_path_name.parent_path() / "metadata.bin";
110-
std::ifstream file(metadata_filename, std::ios::binary);
119+
std::ifstream file(sb.shared_bin_filename, std::ios::binary);
111120
if (file) {
112121
file >> metadata;
113122
}
@@ -120,6 +129,18 @@ common::Status OpenVINOExecutionProvider::Compile(
120129
BackendManager& backend_manager;
121130
};
122131

132+
// onnxruntime::openvino_ep::SharedContext::SharedWeights(shared_bin_filename);
133+
// onnxruntime::openvino_ep::SharedContext::SharedWeights::Header(1,0);
134+
if (!shared_context_.shared_weights.header_) {
135+
shared_context_.shared_weights.header_ = std::make_unique<SharedContext::SharedWeights::Header>(1,2);
136+
}
137+
if(sb.bin_file_.is_open()) {
138+
sb.bin_file_ << shared_context_.shared_weights.header_->bin_version;
139+
sb.bin_file_ << std::endl;
140+
sb.bin_file_ << shared_context_.shared_weights.header_->footer_offset;
141+
}
142+
// ofs.tellp();
143+
std::cout << "Current offset after header = " << sb.bin_file_.tellp() << std::endl;
123144
for (const FusedNodeAndGraph& fused_node_graph : fused_nodes) {
124145
const GraphViewer& graph_body_viewer = fused_node_graph.filtered_graph;
125146
const Node& fused_node = fused_node_graph.fused_node;

0 commit comments

Comments
 (0)