Skip to content

Commit fc08599

Browse files
committed
Add support for optimized bin file creation
1 parent ea13a05 commit fc08599

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
@@ -214,7 +214,21 @@ Status BackendManager::ExportCompiledBlobAsEPCtxNode(const onnxruntime::GraphVie
214214
// If not embed_mode, dump the blob here and only pass on the path to the blob
215215
std::string model_blob_str;
216216
auto compiled_model = concrete_backend_->GetOVCompiledModel();
217-
if (session_context_.so_context_embed_mode) { // Internal blob
217+
if (session_context_.so_share_ep_contexts){
218+
std::ostringstream model_blob_stream;
219+
compiled_model.export_model(model_blob_stream);
220+
221+
// std::ofstream file(metadata_filename, std::ios::app| std::ios::binary);
222+
// std::cout << " write to metadata bin - " << metadata_filename << std::endl;
223+
auto& bin_file = shared_context_.shared_weights.shared_bin_file.bin_file_;
224+
if (bin_file.is_open()) {
225+
bin_file << model_blob_stream.str();
226+
}
227+
std::cout << "Current offset after "<< subgraph_context_.subgraph_name << " = " << bin_file.tellp() << std::endl;
228+
229+
model_blob_str = shared_context_.shared_weights.shared_bin_file.shared_bin_filename.filename().string();
230+
} else if (session_context_.so_context_embed_mode) {
231+
// Internal blob
218232
std::ostringstream model_blob_stream;
219233
compiled_model.export_model(model_blob_stream);
220234
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
@@ -24,6 +24,22 @@ class SharedContext : public WeakSingleton<SharedContext> {
2424
public:
2525
SharedContext() : OVCore_(OVCore::Get()) {}
2626
struct SharedWeights {
27+
struct Header {
28+
uint32_t bin_version=1;
29+
uint32_t footer_offset;
30+
Header(uint32_t bin_in, uint32_t footer_in) :
31+
bin_version(bin_in), footer_offset(footer_in){}
32+
};
33+
struct Footer {
34+
uint32_t subgraph_offset;
35+
uint32_t subgraph_length;
36+
uint32_t metadata_offset;
37+
uint32_t metadata_length;
38+
Footer(uint32_t subgraph_offset_in, uint32_t subgraph_length_in,
39+
uint32_t metadata_offset_in, uint32_t metadata_length_in) :
40+
subgraph_offset(subgraph_offset_in), subgraph_length(subgraph_length_in),
41+
metadata_offset(metadata_offset_in), metadata_length(metadata_length_in) {}
42+
};
2743
struct Metadata {
2844
struct Key {
2945
std::string name;
@@ -36,8 +52,8 @@ class SharedContext : public WeakSingleton<SharedContext> {
3652
};
3753
struct Value {
3854
std::string location;
39-
unsigned int data_offset;
40-
unsigned int size;
55+
uint32_t data_offset;
56+
uint32_t size;
4157
std::vector<size_t> dimensions;
4258
std::int32_t element_type;
4359
std::shared_ptr<ov::Tensor> tensor;
@@ -47,6 +63,25 @@ class SharedContext : public WeakSingleton<SharedContext> {
4763
friend std::istream& operator>>(std::istream& right, Metadata::Map& metadata);
4864
};
4965

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

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

68131
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
@@ -130,21 +130,30 @@ common::Status OpenVINOExecutionProvider::Compile(
130130
std::vector<NodeComputeInfo>& node_compute_funcs) {
131131
auto& logger = *GetLogger();
132132
Status status = Status::OK();
133-
133+
auto &sb = shared_context_.shared_weights.shared_bin_file;
134134
if (!fused_nodes.empty()) {
135135
// Assume these properties are constant for all the model subgraphs, otherwise move to SubGraphContext
136136
const auto& graph_body_viewer_0 = fused_nodes[0].filtered_graph.get();
137137
session_context_.onnx_model_path_name = graph_body_viewer_0.ModelPath().string();
138138
session_context_.onnx_opset_version =
139139
graph_body_viewer_0.DomainToVersionMap().at(kOnnxDomain);
140+
141+
if (session_context_.so_share_ep_contexts){
142+
if(session_context_.so_context_file_path.empty()) {
143+
sb.shared_bin_filename = session_context_.onnx_model_path_name.parent_path() / "metadata.bin";
144+
} else {
145+
sb.shared_bin_filename = session_context_.so_context_file_path.parent_path() / "metadata.bin";
146+
}
147+
sb.openBinFile(sb.shared_bin_filename);
148+
}
140149
}
141150

151+
142152
// Temporary code to read metadata before it moves to the .bin
143153
auto& metadata = shared_context_->shared_weights.metadata;
144154
if (session_context_.so_share_ep_contexts && metadata.empty()) {
145155
// Metadata is always read from model location, this could be a source or epctx model
146-
fs::path metadata_filename = session_context_.onnx_model_path_name.parent_path() / "metadata.bin";
147-
std::ifstream file(metadata_filename, std::ios::binary);
156+
std::ifstream file(sb.shared_bin_filename, std::ios::binary);
148157
if (file) {
149158
file >> metadata;
150159
}
@@ -157,6 +166,18 @@ common::Status OpenVINOExecutionProvider::Compile(
157166
BackendManager& backend_manager;
158167
};
159168

169+
// onnxruntime::openvino_ep::SharedContext::SharedWeights(shared_bin_filename);
170+
// onnxruntime::openvino_ep::SharedContext::SharedWeights::Header(1,0);
171+
if (!shared_context_.shared_weights.header_) {
172+
shared_context_.shared_weights.header_ = std::make_unique<SharedContext::SharedWeights::Header>(1,2);
173+
}
174+
if(sb.bin_file_.is_open()) {
175+
sb.bin_file_ << shared_context_.shared_weights.header_->bin_version;
176+
sb.bin_file_ << std::endl;
177+
sb.bin_file_ << shared_context_.shared_weights.header_->footer_offset;
178+
}
179+
// ofs.tellp();
180+
std::cout << "Current offset after header = " << sb.bin_file_.tellp() << std::endl;
160181
for (const FusedNodeAndGraph& fused_node_graph : fused_nodes) {
161182
const GraphViewer& graph_body_viewer = fused_node_graph.filtered_graph;
162183
const Node& fused_node = fused_node_graph.fused_node;

0 commit comments

Comments
 (0)