BlobReader.cpp
Go to the documentation of this file.
1 // Modified for internal use of depthai-core library
2 // Luxonis - December 2020
3 
4 // Copyright (C) 2018-2020 Intel Corporation
5 // SPDX-License-Identifier: Apache-2.0
6 //
7 
8 #include "BlobReader.hpp"
9 
10 #include <spdlog/fmt/fmt.h>
11 
12 #include <cassert>
13 #include <memory>
14 #include <sstream>
15 #include <string>
16 #include <vector>
17 
18 #include "BlobFormat.hpp"
19 
20 // TODO(themarpe)
21 // #include <vpu/model/data.hpp>
22 
23 namespace dai {
24 
25 namespace {
26 
27 template <typename T>
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");
31  }
32 
33  auto srcPtr = blob.data() + offset;
34  offset += sizeof(T);
35 
36  return *reinterpret_cast<const T*>(srcPtr);
37 }
38 
39 bool isIOShapeName(std::string name) {
40  return name.find("@shape") != std::string::npos;
41 }
42 
43 } // namespace
44 
45 void BlobReader::parse(const std::vector<std::uint8_t>& blob) {
46  if(blob.empty() || blob.size() < sizeof(ElfN_Ehdr) + sizeof(mv_blob_header)) {
47  throw std::logic_error("BlobReader error: Blob is empty");
48  }
49 
50  pBlob = blob.data();
51 
52  blobHeader = *reinterpret_cast<const mv_blob_header*>(blob.data() + sizeof(ElfN_Ehdr));
53 
54  if(blobHeader.magic_number != BLOB_MAGIC_NUMBER) {
55  throw std::logic_error("BlobReader error: File does not seem to be a supported neural network blob");
56  }
57 
58  if(blob.size() < blobHeader.file_size) {
59  throw std::length_error("BlobReader error: Filesize is less than blob specifies. Likely corrupted");
60  }
61 
62  const auto readIO = [this, &blob](uint32_t& ioSectionOffset, uint32_t idx) {
63  auto ioIdx = readFromBlob<uint32_t>(blob, ioSectionOffset);
64  if(ioIdx != idx) {
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 {})",
68  ioIdx,
69  idx));
70  }
71 
72  auto ioBufferOffset = readFromBlob<int32_t>(blob, ioSectionOffset);
73 
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);
78  }
79 
80  // Truncate zeros
81  ioName = ioName.c_str();
82 
83  auto dataType = static_cast<TensorInfo::DataType>(readFromBlob<int32_t>(blob, ioSectionOffset));
84  auto orderCode = static_cast<TensorInfo::StorageOrder>(readFromBlob<uint32_t>(blob, ioSectionOffset));
85 
86  auto numDims = readFromBlob<uint32_t>(blob, ioSectionOffset);
87 
88  // ignore
89  readFromBlob<int32_t>(blob, ioSectionOffset);
90 
91  auto dimsOffset = blobHeader.const_data_section_offset + readFromBlob<uint32_t>(blob, ioSectionOffset);
92 
93  // Skip strides' location and offset
94  ioSectionOffset += 2 * sizeof(uint32_t);
95 
96  std::vector<unsigned> dims;
97  for(unsigned i = 0; i < numDims; ++i) {
98  dims.push_back(readFromBlob<uint32_t>(blob, dimsOffset));
99  }
100 
101  TensorInfo io;
102  io.numDimensions = numDims;
103  io.dims = dims;
104  io.name = ioName;
105  io.offset = ioBufferOffset;
106  io.order = orderCode;
107  io.dataType = dataType;
108 
109  return io;
110  };
111 
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)) {
116  // Add to inputs
117  networkInputs[processedInput.name] = processedInput;
118  }
119  }
120 
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)) {
125  // Add to inputs
126  networkOutputs[processedOutput.name] = processedOutput;
127  }
128  }
129 }
130 
131 } // namespace dai
dai::TensorInfo::offset
unsigned int offset
Definition: TensorInfo.hpp:44
dai::TensorInfo::dataType
DataType dataType
Definition: TensorInfo.hpp:39
dai::TensorInfo::StorageOrder
StorageOrder
Definition: TensorInfo.hpp:13
dai::TensorInfo::DataType
DataType
Definition: TensorInfo.hpp:30
dai::BlobReader::networkInputs
std::unordered_map< std::string, TensorInfo > networkInputs
Definition: BlobReader.hpp:46
dai::TensorInfo::order
StorageOrder order
Definition: TensorInfo.hpp:38
dai::BlobReader::parse
void parse(const std::vector< std::uint8_t > &blob)
Definition: BlobReader.cpp:45
dai::TensorInfo::dims
std::vector< unsigned > dims
Definition: TensorInfo.hpp:41
dai::TensorInfo::name
std::string name
Definition: TensorInfo.hpp:43
dai::BlobReader::networkOutputs
std::unordered_map< std::string, TensorInfo > networkOutputs
Definition: BlobReader.hpp:47
BlobReader.hpp
dai::TensorInfo::numDimensions
unsigned int numDimensions
Definition: TensorInfo.hpp:40
dai::TensorInfo
TensorInfo structure.
Definition: TensorInfo.hpp:12
BlobFormat.hpp
dai::BlobReader::blobHeader
mv_blob_header blobHeader
Definition: BlobReader.hpp:42
dai::BlobReader::BLOB_MAGIC_NUMBER
constexpr static std::uint32_t BLOB_MAGIC_NUMBER
Definition: BlobReader.hpp:44
dai
Definition: CameraExposureOffset.hpp:6
dai::BlobReader::pBlob
const std::uint8_t * pBlob
Definition: BlobReader.hpp:40


depthai
Author(s): Martin Peterlin
autogenerated on Sat Mar 22 2025 02:58:18