NNData.cpp
Go to the documentation of this file.
2 
3 #include <cassert>
4 #include <limits>
5 #include <unordered_map>
6 #include <vector>
7 
10 #include "fp16/fp16.h"
11 
12 namespace dai {
13 
14 NNData::NNData() : Buffer(std::make_shared<RawNNData>()), rawNn(*dynamic_cast<RawNNData*>(raw.get())) {}
15 NNData::NNData(std::shared_ptr<RawNNData> ptr) : Buffer(ptr), rawNn(*ptr.get()) {}
16 
18  switch(type) {
20  return sizeof(uint16_t);
22  return sizeof(float);
24  return sizeof(int8_t);
26  return sizeof(int32_t);
28  return sizeof(uint8_t);
29  default:
30  // invalid type, shouldn't happen
31  assert(0);
32  return 0;
33  }
34 }
35 
36 static std::size_t getTensorDataSize(const TensorInfo& tensor) {
37  return tensor.dims[0] * tensor.strides[0];
38 }
39 
40 std::shared_ptr<RawBuffer> NNData::serialize() const {
41  // get data from u8Data and fp16Data and place properly into the underlying raw buffer
42  rawNn.tensors = {};
43  rawNn.data.clear();
44 
45  // U8 tensors
46  for(const auto& kv : u8Data) {
47  const auto dataType = TensorInfo::DataType::U8F;
48  const auto dataSize = kv.second.size() * sizeofTensorInfoDataType(dataType);
49 
50  // First add any required padding bytes
51  // calculate how many alignment bytes to add for next tensor
52  size_t remainder = (rawNn.data.end() - rawNn.data.begin()) % DATA_ALIGNMENT;
53  if(remainder > 0) {
54  rawNn.data.insert(rawNn.data.end(), DATA_ALIGNMENT - remainder, 0);
55  }
56 
57  // Then get offset to beginning of data
58  size_t offset = rawNn.data.end() - rawNn.data.begin();
59 
60  const auto* data = reinterpret_cast<const std::uint8_t*>(kv.second.data());
61  rawNn.data.insert(rawNn.data.end(), data, data + dataSize);
62 
63  // Add entry in tensors
64  // TODO(themarpe) - refactor with proper way off specifying tensors
66  info.dataType = dataType;
67  info.numDimensions = 1;
68  info.dims.push_back(kv.second.size());
69  info.strides.push_back(sizeofTensorInfoDataType(dataType));
70  info.name = kv.first;
71  info.offset = static_cast<unsigned int>(offset);
72  rawNn.tensors.push_back(info);
73  }
74 
75  // FP16 tensors
76  for(const auto& kv : fp16Data) {
77  const auto dataType = TensorInfo::DataType::FP16;
78  const auto dataSize = kv.second.size() * sizeofTensorInfoDataType(dataType);
79 
80  // First add any required padding bytes
81  // calculate how many alignment bytes to add for next tensor
82  size_t remainder = (rawNn.data.end() - rawNn.data.begin()) % DATA_ALIGNMENT;
83  if(remainder > 0) {
84  rawNn.data.insert(rawNn.data.end(), DATA_ALIGNMENT - remainder, 0);
85  }
86 
87  // Then get offset to beginning of data
88  size_t offset = rawNn.data.end() - rawNn.data.begin();
89 
90  const auto* data = reinterpret_cast<const std::uint8_t*>(kv.second.data());
91  rawNn.data.insert(rawNn.data.end(), data, data + dataSize);
92 
93  // Add entry in tensors
94  // TODO(themarpe) - refactor with proper way off specifying tensors
96  info.dataType = dataType;
97  info.numDimensions = 1;
98  info.dims.push_back(kv.second.size());
99  info.strides.push_back(sizeofTensorInfoDataType(dataType));
100  info.name = kv.first;
101  info.offset = static_cast<unsigned int>(offset);
102  rawNn.tensors.push_back(info);
103  }
104 
105  return raw;
106 }
107 
108 // setters
109 // uint8_t
110 NNData& NNData::setLayer(const std::string& name, std::vector<std::uint8_t> data) {
111  u8Data[name] = std::move(data);
112  return *this;
113 }
114 NNData& NNData::setLayer(const std::string& name, const std::vector<int>& data) {
115  u8Data[name] = std::vector<std::uint8_t>(data.size());
116  for(unsigned i = 0; i < data.size(); i++) {
117  u8Data[name][i] = static_cast<std::uint8_t>(data[i]);
118  }
119  return *this;
120 }
121 
122 // fp16
123 NNData& NNData::setLayer(const std::string& name, std::vector<float> data) {
124  fp16Data[name] = std::vector<std::uint16_t>(data.size());
125  for(unsigned i = 0; i < data.size(); i++) {
126  fp16Data[name][i] = fp16_ieee_from_fp32_value(data[i]);
127  }
128  return *this;
129 }
130 NNData& NNData::setLayer(const std::string& name, std::vector<double> data) {
131  fp16Data[name] = std::vector<std::uint16_t>(data.size());
132  for(unsigned i = 0; i < data.size(); i++) {
133  fp16Data[name][i] = fp16_ieee_from_fp32_value(static_cast<float>(data[i]));
134  }
135  return *this;
136 }
137 
138 // getters
139 std::vector<std::string> NNData::getAllLayerNames() const {
140  std::vector<std::string> names;
141  for(const auto& t : rawNn.tensors) {
142  names.push_back(t.name);
143  }
144  return names;
145 }
146 
147 std::vector<TensorInfo> NNData::getAllLayers() const {
148  return rawNn.tensors;
149 }
150 
151 bool NNData::getLayer(const std::string& name, TensorInfo& tensor) const {
152  for(const auto& t : rawNn.tensors) {
153  if(t.name == name) {
154  tensor = t;
155  return true;
156  }
157  }
158  return false;
159 }
160 
161 bool NNData::hasLayer(const std::string& name) const {
162  for(const auto& tensor : rawNn.tensors) {
163  if(tensor.name == name) return true;
164  }
165  return false;
166 }
167 
168 bool NNData::getLayerDatatype(const std::string& name, TensorInfo::DataType& datatype) const {
169  TensorInfo tensor;
170  if(getLayer(name, tensor)) {
171  datatype = tensor.dataType;
172  return true;
173  }
174  return false;
175 }
176 
177 // uint8
178 std::vector<std::uint8_t> NNData::getLayerUInt8(const std::string& name) const {
179  // std::vector<std::uint8_t> data;
180  // find layer name and its offset
181  TensorInfo tensor;
182  if(getLayer(name, tensor)) {
183  if(tensor.dataType == TensorInfo::DataType::U8F) {
184  // Total data size = last dimension * last stride
185  if(tensor.numDimensions > 0) {
186  size_t size = getTensorDataSize(tensor);
187  auto beg = rawNn.data.begin() + tensor.offset;
188  auto end = beg + size;
189  return {beg, end};
190  }
191  }
192  }
193  return {};
194 }
195 
196 // int32_t
197 std::vector<std::int32_t> NNData::getLayerInt32(const std::string& name) const {
198  // find layer name and its offset
199  TensorInfo tensor;
200  if(getLayer(name, tensor)) {
201  if(tensor.dataType == TensorInfo::DataType::INT) {
202  // Total data size = last dimension * last stride
203  if(tensor.numDimensions > 0) {
204  size_t size = getTensorDataSize(tensor);
205  std::size_t numElements = size / sizeof(std::int32_t); // FP16
206 
207  std::vector<std::int32_t> data;
208  data.reserve(numElements);
209  auto* pInt32Data = reinterpret_cast<std::int32_t*>(&rawNn.data[tensor.offset]);
210  for(std::size_t i = 0; i < numElements; i++) {
211  data.push_back(pInt32Data[i]);
212  }
213  return data;
214  }
215  }
216  }
217  return {};
218 }
219 
220 // fp16
221 std::vector<float> NNData::getLayerFp16(const std::string& name) const {
222  // find layer name and its offset
223  TensorInfo tensor;
224  if(getLayer(name, tensor)) {
225  if(tensor.dataType == TensorInfo::DataType::FP16) {
226  // Total data size = last dimension * last stride
227  if(tensor.numDimensions > 0) {
228  std::size_t size = getTensorDataSize(tensor);
229  std::size_t numElements = size / 2; // FP16
230 
231  std::vector<float> data;
232  data.reserve(numElements);
233  auto* pFp16Data = reinterpret_cast<std::uint16_t*>(&rawNn.data[tensor.offset]);
234  for(std::size_t i = 0; i < numElements; i++) {
235  data.push_back(fp16_ieee_to_fp32_value(pFp16Data[i]));
236  }
237  return data;
238  }
239  }
240  }
241  return {};
242 }
243 
244 // uint8
245 std::vector<std::uint8_t> NNData::getFirstLayerUInt8() const {
246  // find layer name and its offset
247  if(!rawNn.tensors.empty()) {
248  return getLayerUInt8(rawNn.tensors[0].name);
249  }
250 
251  return {};
252 }
253 
254 // fp16
255 std::vector<float> NNData::getFirstLayerFp16() const {
256  // find layer name and its offset
257  if(!rawNn.tensors.empty()) {
258  return getLayerFp16(rawNn.tensors[0].name);
259  }
260  return {};
261 }
262 
263 // int32
264 std::vector<std::int32_t> NNData::getFirstLayerInt32() const {
265  // find layer name and its offset
266  if(!rawNn.tensors.empty()) {
267  return getLayerInt32(rawNn.tensors[0].name);
268  }
269  return {};
270 }
271 
272 // setters
273 NNData& NNData::setTimestamp(std::chrono::time_point<std::chrono::steady_clock, std::chrono::steady_clock::duration> tp) {
274  // Set timestamp from timepoint
275  return static_cast<NNData&>(Buffer::setTimestamp(tp));
276 }
277 NNData& NNData::setTimestampDevice(std::chrono::time_point<std::chrono::steady_clock, std::chrono::steady_clock::duration> tp) {
278  // Set timestamp from timepoint
279  return static_cast<NNData&>(Buffer::setTimestampDevice(tp));
280 }
281 NNData& NNData::setSequenceNum(int64_t sequenceNum) {
282  return static_cast<NNData&>(Buffer::setSequenceNum(sequenceNum));
283 }
284 
285 } // namespace dai
dai::RawNNData::tensors
std::vector< TensorInfo > tensors
Definition: RawNNData.hpp:12
dai::TensorInfo::offset
unsigned int offset
Definition: TensorInfo.hpp:44
dai::NNData::getFirstLayerFp16
std::vector< float > getFirstLayerFp16() const
Definition: NNData.cpp:255
dai::NNData
Definition: NNData.hpp:16
dai::NNData::DATA_ALIGNMENT
static constexpr int DATA_ALIGNMENT
Definition: NNData.hpp:17
dai::TensorInfo::dataType
DataType dataType
Definition: TensorInfo.hpp:39
DAI_SPAN_NAMESPACE_NAME::get
constexpr auto get(span< E, S > s) -> decltype(s[N])
Definition: span.hpp:491
dai::NNData::rawNn
RawNNData & rawNn
Definition: NNData.hpp:19
NNData.hpp
dai::TensorInfo::DataType
DataType
Definition: TensorInfo.hpp:30
dai::NNData::setLayer
NNData & setLayer(const std::string &name, std::vector< std::uint8_t > data)
Definition: NNData.cpp:110
dai::TensorInfo::DataType::FP16
@ FP16
dai::logger::info
void info(const FormatString &fmt, Args &&...args)
Definition: Logging.hpp:78
dai::NNData::NNData
NNData()
Definition: NNData.cpp:14
dai::TensorInfo::DataType::INT
@ INT
dai::TensorInfo::DataType::FP32
@ FP32
dai::TensorInfo::DataType::I8
@ I8
dai::TensorInfo::dims
std::vector< unsigned > dims
Definition: TensorInfo.hpp:41
DAI_SPAN_NAMESPACE_NAME::detail::data
constexpr auto data(C &c) -> decltype(c.data())
Definition: span.hpp:177
dai::Buffer::setTimestamp
Buffer & setTimestamp(std::chrono::time_point< std::chrono::steady_clock, std::chrono::steady_clock::duration > timestamp)
Definition: Buffer.cpp:39
ADatatype.hpp
DAI_SPAN_NAMESPACE_NAME::detail::size
constexpr auto size(const C &c) -> decltype(c.size())
Definition: span.hpp:167
dai::Buffer::setTimestampDevice
Buffer & setTimestampDevice(std::chrono::time_point< std::chrono::steady_clock, std::chrono::steady_clock::duration > timestamp)
Definition: Buffer.cpp:47
dai::NNData::setTimestampDevice
NNData & setTimestampDevice(std::chrono::time_point< std::chrono::steady_clock, std::chrono::steady_clock::duration > timestamp)
Definition: NNData.cpp:277
dai::getTensorDataSize
static std::size_t getTensorDataSize(const TensorInfo &tensor)
Definition: NNData.cpp:36
dai::sizeofTensorInfoDataType
static std::size_t sizeofTensorInfoDataType(TensorInfo::DataType type)
Definition: NNData.cpp:17
dai::NNData::fp16Data
std::unordered_map< std::string, std::vector< std::uint16_t > > fp16Data
Definition: NNData.hpp:25
RawNNData.hpp
dai::NNData::serialize
std::shared_ptr< RawBuffer > serialize() const override
Definition: NNData.cpp:40
dai::NNData::getLayer
bool getLayer(const std::string &name, TensorInfo &tensor) const
Definition: NNData.cpp:151
nanorpc::core::detail::pack::meta::type
type
Definition: pack_meta.h:26
dai::NNData::getLayerDatatype
bool getLayerDatatype(const std::string &name, TensorInfo::DataType &datatype) const
Definition: NNData.cpp:168
dai::TensorInfo::numDimensions
unsigned int numDimensions
Definition: TensorInfo.hpp:40
dai::TensorInfo
TensorInfo structure.
Definition: TensorInfo.hpp:12
dai::Buffer
Base message - buffer of binary data.
Definition: Buffer.hpp:13
dai::NNData::getLayerUInt8
std::vector< std::uint8_t > getLayerUInt8(const std::string &name) const
Definition: NNData.cpp:178
dai::NNData::setSequenceNum
NNData & setSequenceNum(int64_t sequenceNum)
Definition: NNData.cpp:281
dai::RawBuffer::data
std::vector< std::uint8_t > data
Definition: RawBuffer.hpp:14
dai::NNData::setTimestamp
NNData & setTimestamp(std::chrono::time_point< std::chrono::steady_clock, std::chrono::steady_clock::duration > timestamp)
Definition: NNData.cpp:273
dai::NNData::getAllLayerNames
std::vector< std::string > getAllLayerNames() const
Definition: NNData.cpp:139
std
Definition: Node.hpp:366
dai::NNData::u8Data
std::unordered_map< std::string, std::vector< std::uint8_t > > u8Data
Definition: NNData.hpp:23
dai::TensorInfo::strides
std::vector< unsigned > strides
Definition: TensorInfo.hpp:42
dai::NNData::hasLayer
bool hasLayer(const std::string &name) const
Definition: NNData.cpp:161
dai::ADatatype::raw
std::shared_ptr< RawBuffer > raw
Definition: ADatatype.hpp:15
dai::NNData::getAllLayers
std::vector< TensorInfo > getAllLayers() const
Definition: NNData.cpp:147
dai::NNData::getLayerFp16
std::vector< float > getLayerFp16(const std::string &name) const
Definition: NNData.cpp:221
dai
Definition: CameraExposureOffset.hpp:6
dai::RawNNData
RawNNData structure.
Definition: RawNNData.hpp:10
dai::NNData::getLayerInt32
std::vector< std::int32_t > getLayerInt32(const std::string &name) const
Definition: NNData.cpp:197
dai::Buffer::setSequenceNum
Buffer & setSequenceNum(int64_t sequenceNum)
Definition: Buffer.cpp:55
dai::NNData::getFirstLayerInt32
std::vector< std::int32_t > getFirstLayerInt32() const
Definition: NNData.cpp:264
dai::NNData::getFirstLayerUInt8
std::vector< std::uint8_t > getFirstLayerUInt8() const
Definition: NNData.cpp:245
dai::TensorInfo::DataType::U8F
@ U8F


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