26 std::ifstream ifs(fname);
27 if (ifs.is_open() ==
false)
LFATAL(
"Failed to open file " << fname);
29 size_t linenum = 1; std::map<int, std::string> ret;
int id = 0;
30 for (std::string line; std::getline(ifs, line); ++linenum)
32 size_t idx1 = line.find_first_not_of(
" \t");
if (idx1 == line.npos)
continue;
33 size_t idx2 = line.find_last_not_of(
" \t\r\n");
if (idx2 == line.npos)
continue;
34 if (line[idx1] ==
'#')
continue;
36 try {
id = std::stoi(line, &idx1); idx1 = line.find_first_not_of(
"0123456789 \t,:", idx1); }
catch (...) { }
38 std::string classname;
41 LERROR(fname <<
':' << linenum <<
": empty class name -- REPLACING BY 'unspecified'");
42 classname =
"unspecified";
44 else classname = line.substr(idx1, idx2 + 1 - idx1);
50 size_t len = classname.length();
51 if (len > 1 && classname[0] ==
'"' && classname[len-1] ==
'"') classname = classname.substr(1, len-2);
61 LINFO(
"Loaded " << ret.size() <<
" class names from " << fname);
69 auto itr = labels.find(
id);
78 for (
char const c : label) col = c + ((col << 5) - col);
79 col = (col & 0xffffff) | (alpha << 24);
84 void jevois::dnn::topK(
float const * pfProb,
float * pfMaxProb, uint32_t * pMaxClass, uint32_t outputCount,
87 memset(pfMaxProb, 0xfe,
sizeof(
float) * topNum);
88 memset(pMaxClass, 0xff,
sizeof(
float) * topNum);
90 for (uint32_t j = 0; j < topNum; ++j)
92 for (uint32_t i = 0; i < outputCount; ++i)
95 for (k = 0; k < topNum; ++k)
if (i == pMaxClass[k])
break;
96 if (k != topNum)
continue;
98 if (pfProb[i] > pfMaxProb[j]) { pfMaxProb[j] = pfProb[i]; pMaxClass[j] = i; }
106 cv::MatSize
const & ms = m.size;
int const nd = ms.dims();
108 for (
int i = 0; i < nd; ++i) ret +=
std::to_string(ms[i]) + (i < nd-1 ?
"x" :
"");
117 TfLiteIntArray
const & dims = *t->dims;
119 for (
int i = 0; i < dims.size; ++i) ret +=
std::to_string(dims.data[i]) + (i < dims.size-1 ?
"x" :
"");
124 case kTfLiteNoType: ret +=
" NoType";
break;
125 case kTfLiteFloat32: ret +=
" 32F";
break;
126 case kTfLiteInt32: ret +=
" 32S";
break;
127 case kTfLiteUInt8: ret +=
" 8U";
break;
128 case kTfLiteInt64: ret +=
" 64S";
break;
129 case kTfLiteString: ret +=
" String";
break;
130 case kTfLiteBool: ret +=
" 8B";
break;
131 case kTfLiteInt16: ret +=
" 16S";
break;
132 case kTfLiteComplex64: ret +=
" 64C";
break;
133 case kTfLiteInt8: ret +=
" 8I";
break;
134 case kTfLiteFloat16: ret +=
" 16F";
break;
135 case kTfLiteFloat64: ret +=
" 64F";
break;
136 case kTfLiteComplex128: ret +=
" 128C";
break;
137 default: ret +=
" UnknownType";
break;
146 for (uint32_t i = 0; i < attr.dim_num; ++i)
147 ret +=
std::to_string(attr.size[attr.dim_num-1-i]) + (i < attr.dim_num-1 ?
"x" :
"");
150 switch (attr.dtype.vx_type)
152 case VSI_NN_TYPE_UINT8: ret +=
" 8U";
break;
153 case VSI_NN_TYPE_INT8: ret +=
" 8S";
break;
154 case VSI_NN_TYPE_BOOL8: ret +=
" 8B";
break;
155 case VSI_NN_TYPE_UINT16: ret +=
" 16U";
break;
156 case VSI_NN_TYPE_INT16: ret +=
" 16S";
break;
157 case VSI_NN_TYPE_FLOAT16: ret +=
" 16F";
break;
158 case VSI_NN_TYPE_BFLOAT16: ret +=
" 16B";
break;
159 case VSI_NN_TYPE_UINT32: ret +=
" 32U";
break;
160 case VSI_NN_TYPE_INT32: ret +=
" 32S";
break;
161 case VSI_NN_TYPE_FLOAT32: ret +=
" 32F";
break;
162 case VSI_NN_TYPE_UINT64: ret +=
" 64U";
break;
163 case VSI_NN_TYPE_INT64: ret +=
" 64S";
break;
164 case VSI_NN_TYPE_FLOAT64: ret +=
" 64F";
break;
165 default:
throw std::range_error(
"shapestr: Unsupported tensor type " +
std::to_string(attr.dtype.vx_type));
175 std::ostringstream os;
176 std::vector<int64_t> input_node_dims = ti.GetShape();
177 os << input_node_dims.size() <<
"D ";
178 for (int64_t d : input_node_dims) os << d <<
'x';
179 os.seekp(-1, os.cur);
181 switch (ti.GetElementType())
183 case ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED: os <<
" UNDEFINED";
break;
184 case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT: os <<
" 32F";
break;
185 case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT8: os <<
" 8U";
break;
186 case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT8: os <<
" 8S";
break;
187 case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT16: os <<
" 16U";
break;
188 case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT16: os <<
" 16S";
break;
189 case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32: os <<
" 32S";
break;
190 case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64: os <<
" 64S";
break;
191 case ONNX_TENSOR_ELEMENT_DATA_TYPE_STRING: os <<
" STR";
break;
192 case ONNX_TENSOR_ELEMENT_DATA_TYPE_BOOL: os <<
" BOOL";
break;
193 case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16: os <<
" 16F";
break;
194 case ONNX_TENSOR_ELEMENT_DATA_TYPE_DOUBLE: os <<
" 64F";
break;
195 case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT32: os <<
" 32U";
break;
196 case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT64: os <<
" 64U";
break;
197 case ONNX_TENSOR_ELEMENT_DATA_TYPE_COMPLEX64: os <<
" 64CPLX";
break;
198 case ONNX_TENSOR_ELEMENT_DATA_TYPE_COMPLEX128: os <<
" 128CPLX";
break;
199 case ONNX_TENSOR_ELEMENT_DATA_TYPE_BFLOAT16: os <<
" 16B";
break;
200 default:
throw std::range_error(
"shapestr: Unsupported tensor type " +
std::to_string(ti.GetElementType()));
211 case ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED:
return VSI_NN_TYPE_NONE;
212 case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT:
return VSI_NN_TYPE_FLOAT32;
213 case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT8:
return VSI_NN_TYPE_UINT8;
214 case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT8:
return VSI_NN_TYPE_INT8;
215 case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT16:
return VSI_NN_TYPE_UINT16;
216 case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT16:
return VSI_NN_TYPE_INT16;
217 case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32:
return VSI_NN_TYPE_INT32;
218 case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64:
return VSI_NN_TYPE_INT64;
219 case ONNX_TENSOR_ELEMENT_DATA_TYPE_BOOL:
return VSI_NN_TYPE_BOOL8;
220 case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16:
return VSI_NN_TYPE_FLOAT16;
221 case ONNX_TENSOR_ELEMENT_DATA_TYPE_DOUBLE:
return VSI_NN_TYPE_FLOAT64;
222 case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT32:
return VSI_NN_TYPE_UINT32;
223 case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT64:
return VSI_NN_TYPE_UINT64;
224 case ONNX_TENSOR_ELEMENT_DATA_TYPE_BFLOAT16:
return VSI_NN_TYPE_BFLOAT16;
228 default:
throw std::range_error(
"onnx2vsi: Unsupported tensor type " +
std::to_string(t));
235 vsi_nn_tensor_attr_t attr; memset(&attr, 0,
sizeof(attr));
236 attr.dtype.fmt = VSI_NN_DIM_FMT_AUTO;
239 std::vector<int64_t>
const dims = ti.GetShape();
240 size_t const ds = dims.size();
242 for (
size_t i = 0; i < ds; ++i) attr.size[ds - 1 - i] = dims[i];
245 attr.dtype.qnt_type = VSI_NN_QNT_TYPE_NONE;
278 std::vector<size_t> ret;
280 for (std::string
const & t : tok) ret.emplace_back(std::stoi(t));
289 case kTfLiteFloat32:
return CV_32F;
290 case kTfLiteInt32:
return CV_32S;
291 case kTfLiteUInt8:
return CV_8U;
292 case kTfLiteInt16:
return CV_16S;
293 case kTfLiteInt8:
return CV_8S;
294 case kTfLiteFloat16:
return CV_16F;
295 case kTfLiteFloat64:
return CV_64F;
302 default:
throw std::range_error(std::string(
"tf2cv: Unsupported type ") + TfLiteTypeGetName(t));
311 case VSI_NN_TYPE_UINT8:
return CV_8U;
312 case VSI_NN_TYPE_INT8:
return CV_8S;
313 case VSI_NN_TYPE_BOOL8:
return CV_8U;
314 case VSI_NN_TYPE_UINT16:
return CV_16U;
315 case VSI_NN_TYPE_INT16:
return CV_16S;
316 case VSI_NN_TYPE_FLOAT16:
return CV_16F;
319 case VSI_NN_TYPE_INT32:
return CV_32S;
320 case VSI_NN_TYPE_FLOAT32:
return CV_32F;
323 case VSI_NN_TYPE_FLOAT64:
return CV_64F;
324 default:
throw std::range_error(
"vsi2cv: Unsupported tensor type " +
std::to_string(t));
333 case kTfLiteFloat32:
return VSI_NN_TYPE_FLOAT32;
334 case kTfLiteInt32:
return VSI_NN_TYPE_INT32;
335 case kTfLiteUInt8:
return VSI_NN_TYPE_UINT8;
336 case kTfLiteInt16:
return VSI_NN_TYPE_INT16;
337 case kTfLiteInt8:
return VSI_NN_TYPE_INT8;
338 case kTfLiteFloat16:
return VSI_NN_TYPE_FLOAT16;
339 case kTfLiteFloat64:
return VSI_NN_TYPE_FLOAT64;
340 case kTfLiteInt64:
return VSI_NN_TYPE_INT64;
341 case kTfLiteBool:
return VSI_NN_TYPE_BOOL8;
342 case kTfLiteNoType:
return VSI_NN_TYPE_NONE;
346 default:
throw std::range_error(std::string(
"tf2vsi: Unsupported type ") + TfLiteTypeGetName(t));
356 case HAILO_FORMAT_TYPE_AUTO:
return VSI_NN_TYPE_NONE;
break;
357 case HAILO_FORMAT_TYPE_UINT8:
return VSI_NN_TYPE_UINT8;
break;
358 case HAILO_FORMAT_TYPE_UINT16:
return VSI_NN_TYPE_UINT16;
break;
359 case HAILO_FORMAT_TYPE_FLOAT32:
return VSI_NN_TYPE_FLOAT32;
break;
360 default:
throw std::range_error(
"hailo2vsi: Unsupported tensor type " +
std::to_string(t));
368 int tx = std::min(width - 1, std::max(0, r.x));
369 int ty = std::min(height - 1, std::max(0, r.y));
370 int bx = std::min(width - 1, std::max(0, r.x + r.width));
371 int by = std::min(height - 1, std::max(0, r.y + r.height));
372 r.x = tx; r.y = ty; r.width = bx - tx; r.height = by - ty;
378 float tx = std::min(width - 1.0
F, std::max(0.0
F, r.x));
379 float ty = std::min(height - 1.0
F, std::max(0.0
F, r.y));
380 float bx = std::min(width - 1.0
F, std::max(0.0
F, r.x + r.width));
381 float by = std::min(height - 1.0
F, std::max(0.0
F, r.y + r.height));
382 r.x = tx; r.y = ty; r.width = bx - tx; r.height = by - ty;
388 char const *
const specdef =
"[NCHW:|NHWC:|NA:|AUTO:]Type:[NxCxHxW|NxHxWxC|...][:QNT[:fl|:scale:zero]]";
389 std::vector<std::string> spectok =
jevois::split(specs,
",\\s*");
390 std::vector<vsi_nn_tensor_attr_t> ret;
392 for (std::string
const & spec : spectok)
394 vsi_nn_tensor_attr_t attr; memset(&attr, 0,
sizeof(attr));
398 if (tok.size() < 2)
throw std::runtime_error(
"parseTensorSpecs: Malformed tensor spec ["+spec+
"] not "+specdef);
402 if (tok[0] ==
"NCHW") { ++n; attr.dtype.fmt = VSI_NN_DIM_FMT_NCHW; }
403 else if (tok[0] ==
"NHWC") { ++n; attr.dtype.fmt = VSI_NN_DIM_FMT_NHWC; }
404 else if (tok[0] ==
"NA") { ++n; attr.dtype.fmt = VSI_NN_DIM_FMT_NA; }
405 else if (tok[0] ==
"AUTO") { ++n; attr.dtype.fmt = VSI_NN_DIM_FMT_AUTO; }
406 else attr.dtype.fmt = VSI_NN_DIM_FMT_AUTO;
409 if (tok.size() < n+2)
throw std::runtime_error(
"parseTensorSpecs: Malformed tensor spec ["+spec+
"] not "+specdef);
412 if (tok[n] ==
"8U") attr.dtype.vx_type = VSI_NN_TYPE_UINT8;
413 else if (tok[n] ==
"8S") attr.dtype.vx_type = VSI_NN_TYPE_INT8;
414 else if (tok[n] ==
"8B") attr.dtype.vx_type = VSI_NN_TYPE_BOOL8;
415 else if (tok[n] ==
"16U") attr.dtype.vx_type = VSI_NN_TYPE_UINT16;
416 else if (tok[n] ==
"16S") attr.dtype.vx_type = VSI_NN_TYPE_INT16;
417 else if (tok[n] ==
"16F") attr.dtype.vx_type = VSI_NN_TYPE_FLOAT16;
418 else if (tok[n] ==
"16B") attr.dtype.vx_type = VSI_NN_TYPE_BFLOAT16;
419 else if (tok[n] ==
"32U") attr.dtype.vx_type = VSI_NN_TYPE_UINT32;
420 else if (tok[n] ==
"32S") attr.dtype.vx_type = VSI_NN_TYPE_INT32;
421 else if (tok[n] ==
"32F") attr.dtype.vx_type = VSI_NN_TYPE_FLOAT32;
422 else if (tok[n] ==
"64U") attr.dtype.vx_type = VSI_NN_TYPE_UINT64;
423 else if (tok[n] ==
"64S") attr.dtype.vx_type = VSI_NN_TYPE_INT64;
424 else if (tok[n] ==
"64F") attr.dtype.vx_type = VSI_NN_TYPE_FLOAT64;
425 else throw std::range_error(
"parseTensorSpecs: Invalid tensor type [" + tok[n] +
"] in " + spec);
430 attr.dim_num = dims.size();
431 for (
size_t i = 0; i < attr.dim_num; ++i) attr.size[attr.dim_num - 1 - i] = dims[i];
435 if (n == tok.size() || tok[n] ==
"NONE")
437 attr.dtype.qnt_type = VSI_NN_QNT_TYPE_NONE;
439 else if (tok[n] ==
"DFP")
441 attr.dtype.qnt_type = VSI_NN_QNT_TYPE_DFP;
442 if (tok.size() != n+2)
443 throw std::range_error(
"parseTensorSpecs: In "+spec+
", DFP quantization needs :fl (" + specdef +
')');
444 attr.dtype.fl = std::stoi(tok[n+1]);
447 else if (tok[n] ==
"AA" || tok[n] ==
"AS")
449 attr.dtype.qnt_type = VSI_NN_QNT_TYPE_AFFINE_ASYMMETRIC;
450 if (tok.size() != n+3)
451 throw std::range_error(
"parseTensorSpecs: In "+spec+
", AA/AS quantization needs :scale:zero ("+specdef+
')');
452 attr.dtype.scale = std::stof(tok[n+1]);
453 attr.dtype.zero_point = std::stoi(tok[n+2]);
455 else if (tok[n] ==
"APS")
457 attr.dtype.qnt_type = VSI_NN_QNT_TYPE_AFFINE_PERCHANNEL_SYMMETRIC;
458 throw std::range_error(
"parseTensorSpecs: In " + spec +
", AFFINE_PERCHANNEL_SYMMETRIC quant not yet supported");
460 else throw std::range_error(
"parseTensorSpecs: Invalid quantization type in " + spec);
463 ret.emplace_back(attr);
479 size_t const ndim = attr.dim_num;
480 std::vector<int> cvdims(ndim);
481 for (
size_t i = 0; i < ndim; ++i) cvdims[ndim - 1 - i] = attr.size[i];
488 switch (attr.dtype.fmt)
490 case VSI_NN_DIM_FMT_NHWC:
491 if (attr.dim_num < 3)
throw std::range_error(
"attrsize: need at least 3D, got " +
jevois::dnn::attrstr(attr));
492 return cv::Size(attr.size[1], attr.size[2]);
494 case VSI_NN_DIM_FMT_NCHW:
495 if (attr.dim_num < 2)
throw std::range_error(
"attrsize: need at least 2D, got " +
jevois::dnn::attrstr(attr));
496 return cv::Size(attr.size[0], attr.size[1]);
498 case VSI_NN_DIM_FMT_AUTO:
499 if (attr.dim_num < 2)
return cv::Size(attr.size[0], 1);
500 if (attr.dim_num < 3)
return cv::Size(attr.size[0], attr.size[1]);
502 if (attr.size[0] > attr.size[2])
return cv::Size(attr.size[0], attr.size[1]);
503 else return cv::Size(attr.size[1], attr.size[2]);
506 throw std::range_error(
"attrsize: cannot extract width and height, got " +
jevois::dnn::attrstr(attr));
516 switch (attr.dtype.fmt)
518 case VSI_NN_DIM_FMT_NCHW: ret +=
"NCHW:";
break;
519 case VSI_NN_DIM_FMT_NHWC: ret +=
"NHWC:";
break;
524 switch (attr.dtype.vx_type)
526 case VSI_NN_TYPE_UINT8: ret +=
"8U:";
break;
527 case VSI_NN_TYPE_INT8: ret +=
"8S:";
break;
528 case VSI_NN_TYPE_BOOL8: ret +=
"8B:";
break;
529 case VSI_NN_TYPE_UINT16: ret +=
"16U:";
break;
530 case VSI_NN_TYPE_INT16: ret +=
"16S:";
break;
531 case VSI_NN_TYPE_FLOAT16: ret +=
"16F:";
break;
532 case VSI_NN_TYPE_BFLOAT16: ret +=
"16B:";
break;
533 case VSI_NN_TYPE_UINT32: ret +=
"32U:";
break;
534 case VSI_NN_TYPE_INT32: ret +=
"32S:";
break;
535 case VSI_NN_TYPE_FLOAT32: ret +=
"32F:";
break;
536 case VSI_NN_TYPE_UINT64: ret +=
"64U:";
break;
537 case VSI_NN_TYPE_INT64: ret +=
"64S:";
break;
538 case VSI_NN_TYPE_FLOAT64: ret +=
"64F:";
break;
539 default: ret +=
"TYPE_UNKNOWN:";
543 for (uint32_t i = 0; i < attr.dim_num; ++i)
544 ret +=
std::to_string(attr.size[attr.dim_num - 1 - i]) + ((i<attr.dim_num-1) ?
'x' :
':');
547 switch (attr.dtype.qnt_type)
549 case VSI_NN_QNT_TYPE_NONE: ret +=
"NONE";
break;
550 case VSI_NN_QNT_TYPE_DFP: ret +=
"DFP:" +
std::to_string(attr.dtype.fl);
break;
551 case VSI_NN_QNT_TYPE_AFFINE_ASYMMETRIC:
554 case VSI_NN_QNT_TYPE_AFFINE_PERCHANNEL_SYMMETRIC: ret +=
"APS:unsupported";
break;
555 default: ret +=
"QUANT_UNKNOWN";
564 vsi_nn_tensor_attr_t attr; memset(&attr, 0,
sizeof(attr));
565 attr.dtype.fmt = VSI_NN_DIM_FMT_AUTO;
568 switch (t->quantization.type)
570 case kTfLiteNoQuantization:
571 attr.dtype.qnt_type = VSI_NN_QNT_TYPE_NONE;
574 case kTfLiteAffineQuantization:
576 attr.dtype.qnt_type = VSI_NN_QNT_TYPE_AFFINE_ASYMMETRIC;
577 attr.dtype.scale = t->params.scale;
578 attr.dtype.zero_point = t->params.zero_point;
582 default:
LFATAL(
"unsupported quantization " << t->quantization.type);
585 TfLiteIntArray
const & dims = *t->dims;
586 attr.dim_num = dims.size;
587 for (
int i = 0; i < dims.size; ++i) attr.size[dims.size - 1 - i] = dims.data[i];
590 if (attr.dim_num == 4)
592 if (attr.size[0] > attr.size[2]) attr.dtype.fmt = VSI_NN_DIM_FMT_NCHW;
593 else attr.dtype.fmt = VSI_NN_DIM_FMT_NHWC;
603 vsi_nn_tensor_attr_t attr; memset(&attr, 0,
sizeof(attr));
605 attr.dtype.vx_type =
hailo2vsi(vi.format.type);
607 switch (vi.format.order)
609 case HAILO_FORMAT_ORDER_HAILO_NMS:
610 attr.dtype.fmt = VSI_NN_DIM_FMT_AUTO;
612 attr.size[0] = vi.nms_shape.number_of_classes;
613 attr.size[1] = vi.nms_shape.max_bboxes_per_class * 5;
616 case HAILO_FORMAT_ORDER_NHWC:
617 case HAILO_FORMAT_ORDER_FCR:
618 case HAILO_FORMAT_ORDER_F8CR:
619 attr.dtype.fmt = VSI_NN_DIM_FMT_NHWC;
621 attr.size[0] = vi.shape.features;
622 attr.size[1] = vi.shape.width;
623 attr.size[2] = vi.shape.height;
627 case HAILO_FORMAT_ORDER_NHW:
628 attr.dtype.fmt = VSI_NN_DIM_FMT_NHWC;
631 attr.size[1] = vi.shape.width;
632 attr.size[2] = vi.shape.height;
636 case HAILO_FORMAT_ORDER_NC:
637 attr.dtype.fmt = VSI_NN_DIM_FMT_NHWC;
641 attr.size[2] = vi.shape.features;
645 case HAILO_FORMAT_ORDER_NCHW:
646 attr.dtype.fmt = VSI_NN_DIM_FMT_NCHW;
648 attr.size[0] = vi.shape.features;
649 attr.size[1] = vi.shape.width;
650 attr.size[2] = vi.shape.height;
654 default:
throw std::range_error(
"tensorattr: Unsupported Hailo order " +
std::to_string(vi.format.order));
658 attr.dtype.qnt_type = VSI_NN_QNT_TYPE_AFFINE_ASYMMETRIC;
659 attr.dtype.scale = vi.quant_info.qp_scale;
660 attr.dtype.zero_point = int32_t(vi.quant_info.qp_zp);
667 size_t jevois::dnn::softmax(
float const * input,
size_t const n,
size_t const stride,
float const fac,
float * output,
670 if (stride == 0)
LFATAL(
"Cannot work with stride = 0");
673 float largest = -FLT_MAX;
size_t largest_idx = 0;
674 size_t const ns = n * stride;
676 for (
size_t i = 0; i < ns; i += stride)
if (input[i] > largest) { largest = input[i]; largest_idx = i; }
679 for (
size_t i = 0; i < ns; i += stride)
681 float const e = expf(input[i] - largest);
686 for (
size_t i = 0; i < ns; i += stride)
688 float const e = expf(input[i]/fac - largest/fac);
695 if (maxonly) output[largest_idx] /= sum;
696 else for (
size_t i = 0; i < ns; i += stride) output[i] /= sum;
706 if (blob.channels() != 1)
return false;
708 if (uint32_t(blob.size.dims()) != attr.dim_num)
return false;
710 for (
size_t i = 0; i < attr.dim_num; ++i)
711 if (
int(attr.size[attr.dim_num - 1 - i]) != blob.size[i])
return false;
719 if (m.depth() != CV_32F)
LFATAL(
"Tensor to quantize must be 32F");
723 size_t tot = 1;
for (
int d : adims) tot *= d;
725 if (tot != m.total() * m.channels())
730 switch (attr.dtype.qnt_type)
732 case VSI_NN_QNT_TYPE_NONE:
735 m.convertTo(ret, tt);
739 case VSI_NN_QNT_TYPE_DFP:
745 if (attr.dtype.fl > 7)
LFATAL(
"Invalid DFP fl value " << attr.dtype.fl <<
": must be in [0..7]");
747 m.convertTo(ret, tt, 1 << attr.dtype.fl, 0.0);
752 if (attr.dtype.fl > 15)
LFATAL(
"Invalid DFP fl value " << attr.dtype.fl <<
": must be in [0..15]");
754 m.convertTo(ret, tt, 1 << attr.dtype.fl, 0.0);
763 case VSI_NN_QNT_TYPE_AFFINE_ASYMMETRIC:
771 m.convertTo(ret, tt, 1.0 / attr.dtype.scale, attr.dtype.zero_point);
781 case VSI_NN_QNT_TYPE_AFFINE_PERCHANNEL_SYMMETRIC:
782 LFATAL(
"Affine per-channel symmetric not supported yet");
797 switch (attr.dtype.qnt_type)
799 case VSI_NN_QNT_TYPE_NONE:
802 m.convertTo(ret, CV_32F);
806 case VSI_NN_QNT_TYPE_DFP:
809 m.convertTo(ret, CV_32F, 1.0 / (1 << attr.dtype.fl), 0.0);
813 case VSI_NN_QNT_TYPE_AFFINE_ASYMMETRIC:
816 m.convertTo(ret, CV_32F);
817 if (attr.dtype.zero_point) ret -= attr.dtype.zero_point;
818 if (attr.dtype.scale != 1.0F) ret *= attr.dtype.scale;
822 case VSI_NN_QNT_TYPE_AFFINE_PERCHANNEL_SYMMETRIC:
823 LFATAL(
"Affine per-channel symmetric not supported yet");
826 LFATAL(
"Unknown quantization type " <<
int(attr.dtype.qnt_type));
833 cv::MatSize
const & rs = m.size;
834 size_t const ndims = rs.dims();
836 for (
size_t i = 0; i < ndims; ++i)
if (rs[i] == 1) --ret;
else break;