10 #include <spdlog/fmt/fmt.h>
28 T readFromBlob(
const std::vector<std::uint8_t>& blob, uint32_t& offset) {
29 if(offset +
sizeof(T) > blob.size()) {
30 throw std::length_error(
"BlobReader error: Filesize is less than blob specifies. Likely corrupted");
33 auto srcPtr = blob.data() + offset;
36 return *
reinterpret_cast<const T*
>(srcPtr);
39 bool isIOShapeName(std::string name) {
40 return name.find(
"@shape") != std::string::npos;
46 if(blob.empty() || blob.size() <
sizeof(ElfN_Ehdr) +
sizeof(mv_blob_header)) {
47 throw std::logic_error(
"BlobReader error: Blob is empty");
52 blobHeader = *
reinterpret_cast<const mv_blob_header*
>(blob.data() +
sizeof(ElfN_Ehdr));
55 throw std::logic_error(
"BlobReader error: File does not seem to be a supported neural network blob");
59 throw std::length_error(
"BlobReader error: Filesize is less than blob specifies. Likely corrupted");
62 const auto readIO = [
this, &blob](uint32_t& ioSectionOffset, uint32_t idx) {
63 auto ioIdx = readFromBlob<uint32_t>(blob, ioSectionOffset);
65 throw std::runtime_error(
66 fmt::format(
"BlobReader failed on I/O processing, its' ioIdx parameter (which is {}) is "
67 "different from its' processing order (which is {})",
72 auto ioBufferOffset = readFromBlob<int32_t>(blob, ioSectionOffset);
74 auto nameLength = readFromBlob<uint32_t>(blob, ioSectionOffset);
75 std::string ioName(nameLength, 0);
76 for(
auto& c : ioName) {
77 c = readFromBlob<char>(blob, ioSectionOffset);
81 ioName = ioName.c_str();
86 auto numDims = readFromBlob<uint32_t>(blob, ioSectionOffset);
89 readFromBlob<int32_t>(blob, ioSectionOffset);
91 auto dimsOffset =
blobHeader.const_data_section_offset + readFromBlob<uint32_t>(blob, ioSectionOffset);
94 ioSectionOffset += 2 *
sizeof(uint32_t);
96 std::vector<unsigned> dims;
97 for(
unsigned i = 0; i < numDims; ++i) {
98 dims.push_back(readFromBlob<uint32_t>(blob, dimsOffset));
105 io.
offset = ioBufferOffset;
106 io.
order = orderCode;
112 auto inputInfoSecOffset =
blobHeader.input_info_section_offset;
113 for(uint32_t i = 0; i <
blobHeader.inputs_count; i++) {
114 const auto processedInput = readIO(inputInfoSecOffset, i);
115 if(!isIOShapeName(processedInput.name)) {
121 auto outputInfoSecOffset =
blobHeader.output_info_section_offset;
122 for(uint32_t i = 0; i <
blobHeader.outputs_count; i++) {
123 const auto processedOutput = readIO(outputInfoSecOffset, i);
124 if(!isIOShapeName(processedOutput.name)) {