12 #include <fmt/format.h>
65 fmt::format(
"Failed to create numpy header info at {}",
70 if (compare_result != 0) {
71 throw armnn::Exception(fmt::format(
"Numpy does not contain magic string. Can not parse invalid numpy {}",
83 if (*(
reinterpret_cast<char *
>(&i)) == 1)
100 if (*(
reinterpret_cast<char *
>(&i)) == 1)
126 std::string substringStart,
127 std::string substringEnd,
128 bool removeStartChar = 0,
129 bool includeEndChar = 0)
131 size_t startPos = fullString.find(substringStart);
132 size_t endPos = fullString.find(substringEnd, startPos);
133 if (startPos == std::string::npos || endPos == std::string::npos)
142 startPos+= removeStartChar;
143 endPos += includeEndChar;
144 return fullString.substr(startPos, endPos - startPos);
149 std::istringstream shapeStringStream(shapeString);
151 while(getline(shapeStringStream, token,
','))
153 header.
m_Shape.push_back(
static_cast<uint32_t
>(std::stoi(token)));
160 ifStream.read(stringBuffer,
static_cast<std::streamsize
>(headerInfo.
m_HeaderLen));
174 std::string::iterator whitespaceSubstringStart = std::remove(header.
m_HeaderString.begin(),
196 fortranOrderString =
getSubstring(fortranOrderString,
":",
"e", 1, 1);
197 header.
m_FortranOrder = fortranOrderString.find(
"True") != std::string::npos ? true :
false;
205 shapeString =
getSubstring(shapeString,
"(",
")", 1, 0);
210 inline void ReadData(std::ifstream& ifStream, T* tensor,
const unsigned int& numElements)
212 const std::streamsize bytes =
static_cast<std::streamsize
>(
sizeof(T)) *
213 static_cast<std::streamsize
>(numElements);
214 ifStream.read(
reinterpret_cast<char *
>(tensor), bytes);
220 if(descr.find(
"f4") != std::string::npos || descr.find(
"f8") != std::string::npos)
224 else if (descr.find(
"f2") != std::string::npos)
228 else if (descr.find(
"i8") != std::string::npos)
232 else if (descr.find(
"i4") != std::string::npos)
236 else if (descr.find(
"i2") != std::string::npos)
240 else if (descr.find(
"i1") != std::string::npos)
244 else if (descr.find(
"u1") != std::string::npos)
260 return "f" + std::to_string(
sizeof(
float));
275 throw armnn::Exception(fmt::format(
"ArmNN to Numpy data type:{} not supported. {}",
280 template <
typename T>
283 if(descr.find(
"f4") != std::string::npos || descr.find(
"f8") != std::string::npos)
285 return std::is_same<T, float>::value;
287 else if (descr.find(
"i8") != std::string::npos)
289 return std::is_same<T, int64_t>::value;
291 else if (descr.find(
"i4") != std::string::npos)
293 return std::is_same<T, int32_t>::value;
295 else if (descr.find(
"i2") != std::string::npos)
297 return std::is_same<T, int16_t>::value;
299 else if (descr.find(
"i1") != std::string::npos)
301 return std::is_same<T, int8_t>::value;
303 else if (descr.find(
"u1") != std::string::npos)
305 return std::is_same<T, uint8_t>::value;
316 unsigned int numEls = 1;
329 const T*
const array,
330 const unsigned int numElements,
334 std::ofstream out(outputTensorFileName, std::ofstream::binary);
339 std::string shapeStr =
"(";
342 shapeStr = shapeStr + std::to_string(shape[i]) +
", ";
344 shapeStr = shapeStr + std::to_string(shape[shape.
GetNumDimensions()-1]) +
")";
347 std::string endianChar = (*(
reinterpret_cast<char *
>(&i))) ?
"<" :
">";
349 std::string fortranOrder =
"False";
350 std::string headerStr =
"{'descr': '" + endianChar + dataTypeStr +
351 "', 'fortran_order': " + fortranOrder +
352 ", 'shape': " + shapeStr +
", }";
363 uint8_t major_version = 1;
366 if (length >= 255 * 255)
373 size_t padding_length = 16 - length % 16;
374 std::string padding(padding_length,
' ');
378 out.put(
static_cast<char>(major_version));
382 if (major_version == 1)
384 auto header_len =
static_cast<uint16_t
>(headerStr.length() + padding.length() + 1);
386 std::array<uint8_t, 2> header_len_16{
static_cast<uint8_t
>((header_len >> 0) & 0xff),
387 static_cast<uint8_t
>((header_len >> 8) & 0xff)};
388 out.write(
reinterpret_cast<char *
>(header_len_16.data()), 2);
392 auto header_len =
static_cast<uint32_t
>(headerStr.length() + padding.length() + 1);
394 std::array<uint8_t, 4> header_len_32{
395 static_cast<uint8_t
>((header_len >> 0) & 0xff),
static_cast<uint8_t
>((header_len >> 8) & 0xff),
396 static_cast<uint8_t
>((header_len >> 16) & 0xff),
static_cast<uint8_t
>((header_len >> 24) & 0xff)};
397 out.write(
reinterpret_cast<char *
>(header_len_32.data()), 4);
400 out << headerStr << padding <<
'\n';
404 out.write(
reinterpret_cast<const char *
>(array),
sizeof(T) * numElements);
Base class for all ArmNN exceptions so that users can filter to just those.
unsigned int GetNumDimensions() const
Function that returns the tensor rank.
void CreateHeader(std::ifstream &ifStream, HeaderInfo &headerInfo, Header &header)
void WriteToNumpyFile(const std::string &outputTensorFileName, const T *const array, const unsigned int numElements, armnn::DataType dataType, const armnn::TensorShape &shape)
void CreateHeaderInfo(std::ifstream &ifStream, HeaderInfo &headerInfo)
std::string getNumpyDescr(armnn::DataType dType)
void ReadData(std::ifstream &ifStream, T *tensor, const unsigned int &numElements)
unsigned int getNumElements(Header &header)
void parseShape(Header &header, std::string &shapeString)
armnn::DataType getArmNNDataType(std::string &descr)
std::string getSubstring(std::string fullString, std::string substringStart, std::string substringEnd, bool removeStartChar=0, bool includeEndChar=0)
Primarily used to isolate values from header dictionary.
bool compareCTypes(std::string &descr)