[VitisAI] support memory buffer contains the TensorProto external data (#22042)

### Description
Extend VitisAI EP `tensor_proto_as_raw` API to support memory buffer
containing the TensorProto external data


### Motivation and Context
For reduce peak memory usage, VitisAI EP need support ORT format model
and setting session option
`session.use_ort_model_bytes_for_initializers` for enable directly use
the model bytes for initializers.

Co-authored-by: mingyue <mingyue@xilinx.com>
This commit is contained in:
mingyueliuh 2024-09-12 19:23:09 -04:00 committed by GitHub
parent 5c361106e6
commit 55ab13e7ca
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -9,9 +9,44 @@
#include "core/providers/shared_library/provider_api.h"
namespace vaip {
using namespace onnxruntime;
static gsl::span<const char> process_ext_address(const ONNX_NAMESPACE::TensorProto& tensor) {
auto tensor_proto = const_cast<ONNX_NAMESPACE::TensorProto*>(&tensor);
auto file = std::string();
uintptr_t offset = 0;
size_t size = 0;
if (tensor_proto->data_location() == ONNX_NAMESPACE::TensorProto_DataLocation::TensorProto_DataLocation_EXTERNAL) {
auto external_data = tensor_proto->mutable_external_data();
auto external_data_size = external_data->size();
for (auto i = 0; i < external_data_size; ++i) {
auto& data = external_data->at(i);
char* end = nullptr;
if (*data.mutable_key() == "location") {
file = *data.mutable_value();
} else if (*data.mutable_key() == "offset") {
offset = (uintptr_t)std::strtoull(data.mutable_value()->data(), &end, 10);
} else if (*data.mutable_key() == "length") {
size = (size_t)std::strtoull(data.mutable_value()->data(), &end, 10);
} else if (*data.mutable_key() == "checksum") {
// checksum = (size_t)std::strtoull(data.mutable_value()->data(), &end, 10);
}
}
if (file == "*/_ORT_MEM_ADDR_/*") {
auto addr = reinterpret_cast<const char*>(offset);
return {addr, size};
}
}
return {};
}
gsl::span<const char> tensor_proto_as_raw(const onnxruntime::Graph& graph, const ONNX_NAMESPACE::TensorProto& tensor) {
auto& mut_tensor = const_cast<ONNX_NAMESPACE::TensorProto&>(tensor);
if (!tensor.has_raw_data()) {
auto maybe_external_memory_address = process_ext_address(tensor);
if (!maybe_external_memory_address.empty()) {
return maybe_external_memory_address;
}
std::vector<uint8_t> unpacked_tensor;
auto path = graph.ModelPath();
auto s = onnxruntime::utils::UnpackInitializerData(tensor, path, unpacked_tensor);