1371 lines
39 KiB
C++
1371 lines
39 KiB
C++
/*
|
|
* vnn_utils.cc
|
|
*
|
|
* This provides helper functions for nbg-benchmark tool and wrappers around OpenVX lib
|
|
* function. The function are mainly used for converting data types and loading
|
|
* network binary graph.
|
|
*
|
|
* Author: Othmane AHL ZOUAOUI <othmane.ahlzouaoui@st.com> for STMicroelectronics.
|
|
*
|
|
* Copyright (c) 2023 STMicroelectronics. All rights reserved.
|
|
*
|
|
* This software component is licensed by ST under BSD 3-Clause license,
|
|
* the "License"; You may not use this file except in compliance with the
|
|
* License. You may obtain a copy of the License at:
|
|
*
|
|
* http://www.opensource.org/licenses/BSD-3-Clause
|
|
*/
|
|
|
|
#include <stdarg.h>
|
|
#include "vnn_utils.h"
|
|
|
|
#ifdef WIN32
|
|
static vx_float32 round(vx_float32 x)
|
|
{
|
|
#if defined(_M_X64)
|
|
return (vx_float32) _copysignf(floorf(fabsf(x) + 0.5f), x);
|
|
#else
|
|
return (vx_float32) _copysign(floorf(fabsf(x) + 0.5f), x);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
vx_uint32 vnn_GetTypeSize(vx_enum format)
|
|
{
|
|
switch(format)
|
|
{
|
|
case VX_TYPE_INT8:
|
|
case VX_TYPE_UINT8:
|
|
case VX_DF_IMAGE_U8:
|
|
return 1;
|
|
case VX_TYPE_INT16:
|
|
case VX_TYPE_UINT16:
|
|
case VX_DF_IMAGE_S16:
|
|
case VX_DF_IMAGE_U16:
|
|
return 2;
|
|
case VX_TYPE_INT32:
|
|
case VX_TYPE_UINT32:
|
|
case VX_DF_IMAGE_S32:
|
|
case VX_DF_IMAGE_U32:
|
|
return 4;
|
|
case VX_TYPE_INT64:
|
|
case VX_TYPE_UINT64:
|
|
return 8;
|
|
case VX_TYPE_FLOAT32:
|
|
case VX_DF_IMAGE_F32:
|
|
return 4;
|
|
case VX_TYPE_FLOAT64:
|
|
return 8;
|
|
case VX_TYPE_ENUM:
|
|
return 4;
|
|
case VX_TYPE_FLOAT16:
|
|
return 2;
|
|
default:
|
|
printf("Not support format:%d,line=%d\n",format,__LINE__);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
vx_int8 vnn_Fp32toInt8(vx_float32 val, vx_int8 fixedPointPos)
|
|
{
|
|
vx_int8 result = 0;
|
|
|
|
if (fixedPointPos > 0)
|
|
{
|
|
vx_int32 data = (vx_int32) round(val * (vx_float32)(1 << fixedPointPos));
|
|
result = (vx_int8)((data > 127) ? 127 : (data < -128) ? -128 : data);
|
|
|
|
}
|
|
else
|
|
{
|
|
vx_int32 data = (vx_int32) round(val * (1.0f / (vx_float32)(1 << -fixedPointPos)));
|
|
result = (vx_int8)((data > 127) ? 127 : (data < -128) ? -128 : data);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
vx_float32 vnn_Int8toFp32(vx_int8 val, vx_int8 fixedPointPos)
|
|
{
|
|
vx_float32 result = 0.0f;
|
|
|
|
if (fixedPointPos > 0)
|
|
{
|
|
result = (vx_float32)val * (1.0f / ((vx_uint32) (1 << fixedPointPos)));
|
|
}
|
|
else
|
|
{
|
|
result = (vx_float32)val * ((vx_float32) (1 << -fixedPointPos));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
vx_uint8 vnn_Fp32toUint8(vx_float32 val, vx_int32 zeroPoint, vx_float32 scale)
|
|
{
|
|
vx_uint8 result = 0;
|
|
vx_int32 data;
|
|
|
|
data = (vx_int32) round((val / scale + (vx_uint8)zeroPoint));
|
|
|
|
if (data > 255)
|
|
data = 255;
|
|
|
|
if (data < 0)
|
|
data = 0;
|
|
|
|
result = (vx_uint8)(data);
|
|
|
|
return result;
|
|
}
|
|
vx_float32 vnn_Uint8toFp32(vx_uint8 val, vx_int32 zeroPoint, vx_float32 scale)
|
|
{
|
|
vx_float32 result = 0.0f;
|
|
|
|
result = (val - (vx_uint8)zeroPoint) * scale;
|
|
return result;
|
|
}
|
|
vx_int8 vnn_Fp32toAsymInt8(vx_float32 val, vx_int32 zeroPoint, vx_float32 scale)
|
|
{
|
|
vx_int8 result = 0;
|
|
vx_int32 data;
|
|
|
|
data = (vx_int32) round((val / scale + (vx_uint8)zeroPoint));
|
|
|
|
if (data > 127)
|
|
data = 127;
|
|
|
|
if (data < -128)
|
|
data = -128;
|
|
|
|
result = (vx_int8)(data);
|
|
|
|
return result;
|
|
}
|
|
vx_float32 vnn_AsymInt8toFp32(vx_int8 val, vx_int32 zeroPoint, vx_float32 scale)
|
|
{
|
|
vx_float32 result = 0.0f;
|
|
|
|
result = (val - (vx_int8)zeroPoint) * scale;
|
|
return result;
|
|
}
|
|
vx_float32 vnn_Int16toFp32(vx_int16 val, vx_int8 fixedPointPos)
|
|
{
|
|
vx_float32 result = 0.0f;
|
|
vx_float32 value = val;
|
|
if (fixedPointPos > 0)
|
|
{
|
|
result = value * (1.0f / ((vx_uint32) (1 << fixedPointPos)));
|
|
}
|
|
else
|
|
{
|
|
result = value * ((vx_float32) (1 << -fixedPointPos));
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
vx_int16 vnn_Fp32toInt16(vx_float32 val, vx_int8 fixedPointPos)
|
|
{
|
|
vx_int16 result = 0;
|
|
|
|
if (fixedPointPos > 0)
|
|
{
|
|
vx_int32 data = (vx_int32) round(val * (vx_float32)(1 << fixedPointPos));
|
|
result = (vx_int16)((data > 32767) ? 32767 : (data < -32768) ? -32768 : data);
|
|
|
|
}
|
|
else
|
|
{
|
|
vx_int32 data = (vx_int32) round(val * (1.0f / (vx_float32)(1 << -fixedPointPos)));
|
|
result = (vx_int16)((data > 32767) ? 32767 : (data < -32768) ? -32768 : data);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
vx_int16 vnn_Fp32toAsymInt16(vx_float32 val, vx_int32 zeroPoint, vx_float32 scale)
|
|
{
|
|
vx_int16 result = 0;
|
|
vx_int32 data;
|
|
|
|
data = (vx_int32) round((val / scale + (vx_int16)zeroPoint));
|
|
|
|
if (data > 32767)
|
|
data = 32767;
|
|
|
|
if (data < -32768)
|
|
data = -32768;
|
|
|
|
result = (vx_int16)(data);
|
|
|
|
return result;
|
|
}
|
|
vx_float32 vnn_AsymInt16toFp32(vx_int16 val, vx_int32 zeroPoint, vx_float32 scale)
|
|
{
|
|
vx_float32 result = 0.0f;
|
|
|
|
result = (val - (vx_int16)zeroPoint) * scale;
|
|
return result;
|
|
}
|
|
|
|
vx_int16 vnn_Fp32toFp16(vx_float32 val)
|
|
{
|
|
#define F16_EXPONENT_BITS 0x1F
|
|
#define F16_EXPONENT_BIAS 15
|
|
|
|
#define F16_EXPONENT_SHIFT 10
|
|
#define F16_MANTISSA_BITS ((1 << F16_EXPONENT_SHIFT) - 1)
|
|
#define F16_MANTISSA_SHIFT (23 - F16_EXPONENT_SHIFT)
|
|
#define F16_MAX_EXPONENT (F16_EXPONENT_BITS << F16_EXPONENT_SHIFT)
|
|
|
|
vx_uint32 f32 = (*(vx_uint32 *) &val);
|
|
vx_int16 f16 = 0;
|
|
/* Decode IEEE 754 little-endian 32-bit floating-point value */
|
|
int sign = (f32 >> 16) & 0x8000;
|
|
/* Map exponent to the range [-127,128] */
|
|
int exponent = ((f32 >> 23) & 0xff) - 127;
|
|
int mantissa = f32 & 0x007fffff;
|
|
if (exponent == 128)
|
|
{ /* Infinity or NaN */
|
|
if (mantissa)
|
|
{
|
|
/* Flush NaN to 0. */
|
|
f16 = (vx_int16)sign;
|
|
}
|
|
else
|
|
{
|
|
/* Clamp to HALF_MAX/HALF_MIN. */
|
|
f16 = (vx_int16)(sign | ((F16_EXPONENT_BITS - 1) << F16_EXPONENT_SHIFT) | F16_MANTISSA_BITS);
|
|
}
|
|
}
|
|
else if (exponent > 15)
|
|
{ /* Overflow - clamp to HALF_MAX/HALF_MIN. */
|
|
f16 = (vx_int16)(sign | ((F16_EXPONENT_BITS - 1) << F16_EXPONENT_SHIFT) | F16_MANTISSA_BITS);
|
|
}
|
|
else if (exponent > -15)
|
|
{ /* Representable value */
|
|
/* RTNE */
|
|
int roundingBit = (mantissa >> (F16_MANTISSA_SHIFT - 1)) & 0x1;
|
|
int stickyBits = mantissa & 0xFFF;
|
|
exponent += F16_EXPONENT_BIAS;
|
|
mantissa >>= F16_MANTISSA_SHIFT;
|
|
if (roundingBit)
|
|
{
|
|
if (stickyBits || (mantissa & 0x1))
|
|
{
|
|
mantissa++;
|
|
if (mantissa > F16_MANTISSA_BITS)
|
|
{
|
|
exponent++;
|
|
if (exponent > 30)
|
|
{
|
|
/* Clamp to HALF_MAX/HALF_MIN. */
|
|
exponent--;
|
|
mantissa--;
|
|
}
|
|
else
|
|
{
|
|
mantissa &= F16_MANTISSA_BITS;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
f16 = (vx_int16)(sign | exponent << F16_EXPONENT_SHIFT | mantissa);
|
|
}
|
|
else
|
|
{
|
|
f16 = (vx_int16)sign;
|
|
}
|
|
return f16;
|
|
}
|
|
|
|
vx_float32 vnn_Fp16toFp32(const vx_uint16 in)
|
|
{
|
|
vx_uint32 t1;
|
|
vx_uint32 t2;
|
|
vx_uint32 t3;
|
|
vx_float32 out;
|
|
|
|
t1 = in & 0x7fff; // Non-sign bits
|
|
t2 = in & 0x8000; // Sign bit
|
|
t3 = in & 0x7c00; // Exponent
|
|
t1 <<= 13; // Align mantissa on MSB
|
|
t2 <<= 16; // Shift sign bit into position
|
|
t1 += 0x38000000; // Adjust bias
|
|
t1 = (t3 == 0 ? 0 : t1); // Denormals-as-zero
|
|
t1 |= t2; // Re-insert sign bit
|
|
*((uint32_t*)&out) = t1;
|
|
return out;
|
|
}
|
|
|
|
vx_uint32 vnn_GetTensorSize(vx_tensor tensor)
|
|
{
|
|
vx_uint32 size[6];
|
|
vx_uint32 num=1,num_of_dim=0;
|
|
vx_uint32 i = 0;
|
|
vxQueryTensor(tensor, VX_TENSOR_NUMBER_OF_DIMS, &num_of_dim, sizeof(num_of_dim));
|
|
vxQueryTensor(tensor, VX_TENSOR_DIMS, size, sizeof(size));
|
|
for(i = 0; i < num_of_dim;i++)
|
|
num = num*size[i];
|
|
return num;
|
|
}
|
|
|
|
vx_uint32 vnn_GetTensorDims(vx_tensor tensor)
|
|
{
|
|
vx_uint32 size[6];
|
|
vx_uint32 num_of_dim=0;
|
|
vxQueryTensor(tensor, VX_TENSOR_NUMBER_OF_DIMS, &num_of_dim, sizeof(num_of_dim));
|
|
return num_of_dim;
|
|
}
|
|
|
|
vx_uint32 vnn_GetTensorBufferSize(vx_tensor tensor)
|
|
{
|
|
vx_uint32 size[6];
|
|
vx_uint32 num=1,num_of_dim=0;
|
|
vx_enum data_format;
|
|
vx_uint32 i = 0;
|
|
vxQueryTensor(tensor, VX_TENSOR_NUMBER_OF_DIMS, &num_of_dim, sizeof(num_of_dim));
|
|
vxQueryTensor(tensor, VX_TENSOR_DIMS, size, sizeof(size));
|
|
vxQueryTensor(tensor, VX_TENSOR_DATA_TYPE, &data_format, sizeof(data_format));
|
|
num = vnn_GetTypeSize(data_format);
|
|
for(i = 0; i < num_of_dim;i++)
|
|
num = num*size[i];
|
|
return num;
|
|
}
|
|
|
|
vx_status vnn_CopyTensorToData(vx_tensor tensor,void **buf)
|
|
{
|
|
vx_uint32 size[MAX_NUM_DIMS];
|
|
vx_size stride[MAX_NUM_DIMS];
|
|
vx_size start[MAX_NUM_DIMS];
|
|
vx_size end[MAX_NUM_DIMS];
|
|
vx_uint32 num_of_dim=0;
|
|
vx_status status = VX_SUCCESS;
|
|
vx_uint32 i = 0;
|
|
vx_enum data_format;
|
|
vx_uint32 data_size = 0;
|
|
vx_context context = vxGetContext((vx_reference)tensor);
|
|
status |= vxQueryTensor(tensor, VX_TENSOR_NUMBER_OF_DIMS, &num_of_dim, sizeof(num_of_dim));
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_DIMS, size, sizeof(size));
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_DATA_TYPE, &data_format, sizeof(data_format));
|
|
|
|
stride[0] = vnn_GetTypeSize(data_format);
|
|
for (i=0; i< num_of_dim; i++)
|
|
{
|
|
start[i] = 0;
|
|
end[i] = (vx_size)size[i];
|
|
if(i>0)
|
|
{
|
|
stride[i] = stride[i - 1] * size[i - 1];
|
|
}
|
|
}
|
|
data_size = vnn_GetTensorBufferSize(tensor);
|
|
if(*buf == NULL)
|
|
*buf = (void*)malloc(data_size);
|
|
status = vxCopyTensorPatch(tensor, num_of_dim,start,end,stride,(void*)*buf, VX_READ_ONLY,0);
|
|
|
|
return status;
|
|
}
|
|
vx_status vnn_CopyTensorToFloat32Data(vx_tensor tensor,vx_float32 **buf)
|
|
{
|
|
vx_uint32 size[6];
|
|
vx_uint32 stride_size[6];
|
|
vx_uint32 num=1,num_of_dim=0;
|
|
vx_tensor_addressing user_addr = NULL;
|
|
vx_status status = VX_SUCCESS;
|
|
vx_uint32 i = 0;
|
|
vx_enum data_format,quant_format;
|
|
vx_uint32 data_size = 0;
|
|
vx_context context = vxGetContext((vx_reference)tensor);
|
|
void *data = NULL;
|
|
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_DATA_TYPE, &data_format, sizeof(data_format));
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_QUANT_FORMAT, &quant_format, sizeof(data_format));
|
|
num = vnn_GetTensorSize(tensor);
|
|
if(*buf == NULL)
|
|
*buf = (vx_float32*)malloc(num * sizeof(vx_float32));
|
|
status |= vnn_CopyTensorToData(tensor,&data);
|
|
|
|
if(quant_format == VX_QUANT_DYNAMIC_FIXED_POINT && data_format == VX_TYPE_INT8)
|
|
{
|
|
vx_int8 fl=0;
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_FIXED_POINT_POSITION, &fl, sizeof(fl));
|
|
if(data_format == VX_TYPE_INT8)
|
|
{
|
|
for(i = 0;i < num; i++)
|
|
(*buf)[i]= vnn_Int8toFp32( ((vx_int8*)data)[i],fl);
|
|
}
|
|
}
|
|
else if(quant_format == VX_QUANT_DYNAMIC_FIXED_POINT && data_format == VX_TYPE_INT16)
|
|
{
|
|
vx_int8 fl=0;
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_FIXED_POINT_POSITION, &fl, sizeof(fl));
|
|
for(i = 0;i < num; i++)
|
|
(*buf)[i]= vnn_Int16toFp32( ((vx_int16*)data)[i],fl);
|
|
}
|
|
else if(quant_format == VX_QUANT_AFFINE_SCALE && data_format == VX_TYPE_UINT8)
|
|
{
|
|
vx_int32 zp=0;
|
|
vx_float32 scale;
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_ZERO_POINT, &zp, sizeof(zp));
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_SCALE, &scale, sizeof(scale));
|
|
for(i = 0;i < num; i++)
|
|
(*buf)[i]= vnn_Uint8toFp32( ((vx_uint8*)data)[i],zp,scale);
|
|
}
|
|
else if(quant_format == VX_QUANT_AFFINE_SCALE && data_format == VX_TYPE_INT8)
|
|
{
|
|
vx_int32 zp=0;
|
|
vx_float32 scale;
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_ZERO_POINT, &zp, sizeof(zp));
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_SCALE, &scale, sizeof(scale));
|
|
for(i = 0;i < num; i++)
|
|
(*buf)[i]= vnn_AsymInt8toFp32( ((vx_int8*)data)[i],zp,scale);
|
|
}
|
|
else if(quant_format == VX_QUANT_AFFINE_SCALE && data_format == VX_TYPE_INT16)
|
|
{
|
|
vx_int32 zp=0;
|
|
vx_float32 scale;
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_ZERO_POINT, &zp, sizeof(zp));
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_SCALE, &scale, sizeof(scale));
|
|
for(i = 0;i < num; i++)
|
|
(*buf)[i]= vnn_AsymInt16toFp32( ((vx_int8*)data)[i],zp,scale);
|
|
}
|
|
else if (quant_format ==VX_QUANT_NONE && data_format == VX_TYPE_UINT8)
|
|
{
|
|
for(i = 0;i < num; i++)
|
|
(*buf)[i] = ((vx_uint8*)data)[i];
|
|
}
|
|
else if(data_format == VX_TYPE_FLOAT16)/*VX_QUANT_NONE*/
|
|
{
|
|
for(i = 0;i < num; i++)
|
|
(*buf)[i]= vnn_Fp16toFp32( ((vx_int16*)data)[i]);
|
|
}
|
|
else if(data_format == VX_TYPE_FLOAT32)/*VX_QUANT_NONE*/
|
|
{
|
|
for(i = 0;i < num; i++)
|
|
(*buf)[i] = ((vx_float32*)data)[i];
|
|
}
|
|
else if(quant_format ==VX_QUANT_NONE && data_format == VX_TYPE_INT32)/*VX_QUANT_NONE*/
|
|
{
|
|
for(i = 0;i < num; i++)
|
|
(*buf)[i] = (vx_float32)(((vx_int32*)data)[i]);
|
|
}
|
|
else if(quant_format ==VX_QUANT_NONE && data_format == VX_TYPE_UINT32)/*VX_QUANT_NONE*/
|
|
{
|
|
for(i = 0;i < num; i++)
|
|
(*buf)[i] = (vx_float32)(((vx_uint32*)data)[i]);
|
|
}
|
|
else
|
|
{
|
|
printf("can't support format!\n");
|
|
status = VX_FAILURE;
|
|
}
|
|
if(data){
|
|
free(data);
|
|
}
|
|
return status;
|
|
}
|
|
|
|
vx_status vnn_CopyDataToTensor(vx_tensor tensor,void *buf)
|
|
{
|
|
vx_uint32 size[MAX_NUM_DIMS];
|
|
vx_size stride[MAX_NUM_DIMS];
|
|
vx_size start[MAX_NUM_DIMS];
|
|
vx_size end[MAX_NUM_DIMS];
|
|
vx_uint32 num_of_dim=0;
|
|
vx_tensor_addressing user_addr = NULL;
|
|
vx_status status = VX_SUCCESS;
|
|
vx_uint32 i = 0;
|
|
vx_enum data_format;
|
|
vx_uint32 data_size = 0;
|
|
vx_context context = vxGetContext((vx_reference)tensor);
|
|
status |= vxQueryTensor(tensor, VX_TENSOR_NUMBER_OF_DIMS, &num_of_dim, sizeof(num_of_dim));
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_DIMS, size, sizeof(size));
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_DATA_TYPE, &data_format, sizeof(data_format));
|
|
|
|
stride[0] = vnn_GetTypeSize(data_format);
|
|
for (i=0; i< num_of_dim; i++)
|
|
{
|
|
start[i] = 0;
|
|
end[i] = (vx_size)size[i];
|
|
if(i>0)
|
|
{
|
|
stride[i] = stride[i - 1] * size[i - 1];
|
|
}
|
|
}
|
|
status = vxCopyTensorPatch(tensor, num_of_dim,start,end,stride,buf, VX_WRITE_ONLY,0);
|
|
|
|
return status;
|
|
}
|
|
vx_status vnn_CopyFloat32DataToTensor(vx_tensor tensor,vx_float32 *buf)
|
|
{
|
|
vx_uint32 size[6];
|
|
vx_uint32 stride_size[6];
|
|
vx_uint32 num=1,num_of_dim=0;
|
|
vx_tensor_addressing user_addr = NULL;
|
|
vx_status status = VX_SUCCESS;
|
|
vx_uint32 i = 0;
|
|
vx_enum data_format,quant_format;
|
|
vx_uint32 data_size = 0;
|
|
vx_context context = vxGetContext((vx_reference)tensor);
|
|
void *data = NULL;
|
|
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_DATA_TYPE, &data_format, sizeof(data_format));
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_QUANT_FORMAT, &quant_format, sizeof(data_format));
|
|
num = vnn_GetTensorSize(tensor);
|
|
data = (void*)malloc(vnn_GetTensorBufferSize(tensor));
|
|
|
|
if(quant_format == VX_QUANT_DYNAMIC_FIXED_POINT && data_format == VX_TYPE_INT8)
|
|
{
|
|
vx_int8 fl=0;
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_FIXED_POINT_POSITION, &fl, sizeof(fl));
|
|
if(data_format == VX_TYPE_INT8)
|
|
{
|
|
for(i = 0;i < num; i++)
|
|
((vx_int8*)data)[i] = vnn_Fp32toInt8(buf[i],fl);
|
|
}
|
|
}
|
|
else if(quant_format == VX_QUANT_DYNAMIC_FIXED_POINT && data_format == VX_TYPE_INT16)
|
|
{
|
|
vx_int8 fl=0;
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_FIXED_POINT_POSITION, &fl, sizeof(fl));
|
|
for(i = 0;i < num; i++)
|
|
((vx_int16*)data)[i] = vnn_Fp32toInt16(buf[i],fl);
|
|
}
|
|
else if(quant_format == VX_QUANT_AFFINE_SCALE && data_format == VX_TYPE_UINT8)
|
|
{
|
|
vx_int32 zp=0;
|
|
vx_float32 scale;
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_ZERO_POINT, &zp, sizeof(zp));
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_SCALE, &scale, sizeof(scale));
|
|
for(i = 0;i < num; i++)
|
|
((vx_uint8*)data)[i] = vnn_Fp32toUint8(buf[i],zp,scale);
|
|
}
|
|
else if(quant_format == VX_QUANT_AFFINE_SCALE && data_format == VX_TYPE_INT8)
|
|
{
|
|
vx_int32 zp=0;
|
|
vx_float32 scale;
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_ZERO_POINT, &zp, sizeof(zp));
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_SCALE, &scale, sizeof(scale));
|
|
for(i = 0;i < num; i++)
|
|
((vx_int8*)data)[i] = vnn_Fp32toAsymInt8(buf[i],zp,scale);
|
|
}
|
|
else if(quant_format == VX_QUANT_AFFINE_SCALE && data_format == VX_TYPE_INT16)
|
|
{
|
|
vx_int32 zp=0;
|
|
vx_float32 scale;
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_ZERO_POINT, &zp, sizeof(zp));
|
|
status |=vxQueryTensor(tensor, VX_TENSOR_SCALE, &scale, sizeof(scale));
|
|
for(i = 0;i < num; i++)
|
|
((vx_int16*)data)[i] = vnn_Fp32toAsymInt16(buf[i],zp,scale);
|
|
}
|
|
else if(quant_format == VX_QUANT_NONE && data_format == VX_TYPE_UINT8)
|
|
{
|
|
for(i = 0;i < num; i++)
|
|
((vx_uint8*)data)[i] = (vx_uint8)buf[i];
|
|
}
|
|
else if(data_format == VX_TYPE_FLOAT16)/*VX_QUANT_NONE*/
|
|
{
|
|
for(i = 0;i < num; i++)
|
|
((vx_int16*)data)[i] = vnn_Fp32toFp16(buf[i]);
|
|
}
|
|
else if(data_format == VX_TYPE_FLOAT32)/*VX_QUANT_NONE*/
|
|
{
|
|
for(i = 0;i < num; i++)
|
|
((vx_float32*)data)[i] = buf[i];
|
|
}
|
|
else if(quant_format == VX_QUANT_NONE && data_format == VX_TYPE_INT32)/*VX_QUANT_NONE*/
|
|
{
|
|
for(i = 0;i < num; i++)
|
|
((vx_int32*)data)[i] = (vx_int32)buf[i];
|
|
}
|
|
else if(quant_format == VX_QUANT_NONE && data_format == VX_TYPE_UINT32)/*VX_QUANT_NONE*/
|
|
{
|
|
for(i = 0;i < num; i++)
|
|
((vx_uint32*)data)[i] = (vx_uint32)buf[i];
|
|
}
|
|
else
|
|
{
|
|
printf("can't support format!\n");
|
|
status = VX_FAILURE;
|
|
}
|
|
status |= vnn_CopyDataToTensor(tensor,data);
|
|
if(data){
|
|
free(data);
|
|
}
|
|
return status;
|
|
}
|
|
|
|
|
|
static file_type get_file_type(const char *file_name)
|
|
{
|
|
const char *ptr;
|
|
char sep = '.';
|
|
uint32_t pos,n;
|
|
char buff[32] = {0};
|
|
|
|
ptr = strrchr(file_name, sep);
|
|
pos = ptr - file_name;
|
|
n = strlen(file_name) - (pos + 1);
|
|
strncpy(buff, file_name+(pos+1), n);
|
|
|
|
if(strcmp(buff, "tensor") == 0
|
|
|| strcmp(buff, "txt") == 0)
|
|
{
|
|
return FILE_TYPE_TEXT;
|
|
}
|
|
else if(strcmp(buff, "bin") == 0
|
|
|| strcmp(buff, "dat") == 0)
|
|
{
|
|
return FILE_TYPE_BIN;
|
|
}
|
|
else
|
|
{
|
|
return FILE_TYPE_NOT_SUPPORT;
|
|
}
|
|
}
|
|
|
|
vx_status vnn_LoadTensorRandom(vx_tensor tensor)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
vx_int32 i=0;
|
|
char dumpInput[128];
|
|
|
|
vx_int32 num = vnn_GetTensorSize(tensor);
|
|
vx_uint8 *buf = (vx_uint8*)malloc(num*sizeof(vx_uint8));
|
|
memset(buf, 0, num * sizeof(vx_uint8));
|
|
|
|
status |= vnn_CopyDataToTensor(tensor,buf);
|
|
_CHECK_STATUS(status, exit);
|
|
//printf("Info: Copied a buffer of a size of %d to tensor.\n", num);
|
|
snprintf(dumpInput, sizeof(dumpInput), "input.dat");
|
|
vnn_SaveTensorToFileAsBinary(tensor, dumpInput);
|
|
status = VX_SUCCESS;
|
|
if(buf)
|
|
free(buf);
|
|
exit:
|
|
return status;
|
|
}
|
|
|
|
vx_status vnn_LoadTensorFromFile(vx_tensor tensor,char *filename)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
vx_int32 i=0;
|
|
file_type ft = get_file_type(filename);
|
|
|
|
if(ft == FILE_TYPE_TEXT) /*tensor*/
|
|
{
|
|
vx_int32 num = vnn_GetTensorSize(tensor);
|
|
vx_float32 *buf = (vx_float32*)malloc(num*sizeof(vx_float32));
|
|
FILE *fp = fopen(filename,"r");
|
|
if(fp)
|
|
{
|
|
for(i = 0;i < num;i++)
|
|
{
|
|
vx_int32 ret = fscanf(fp,"%f",&buf[i]);
|
|
if(ret <=0 )
|
|
{
|
|
printf("There is no enough data!\n");
|
|
status = VX_FAILURE;
|
|
break;
|
|
}
|
|
}
|
|
status |= vnn_CopyFloat32DataToTensor(tensor,buf);
|
|
}
|
|
else
|
|
{
|
|
printf("can't open file %s\n",filename);
|
|
status |= VX_FAILURE;
|
|
}
|
|
|
|
if(buf){
|
|
free(buf);
|
|
}
|
|
if(fp)
|
|
fclose(fp);
|
|
}
|
|
else if(ft == FILE_TYPE_BIN) /*dat or bin*/
|
|
{
|
|
vx_int32 size = vnn_GetTensorBufferSize(tensor);
|
|
void *buf = (void*)malloc(size);
|
|
FILE *fp = fopen(filename,"rb");
|
|
if(fp)
|
|
{
|
|
vx_int32 ret = fread(buf,1,size,fp);
|
|
if(ret < size)
|
|
{
|
|
printf("There is no enough data!\n");
|
|
status = VX_FAILURE;
|
|
}
|
|
vnn_CopyDataToTensor(tensor,buf);
|
|
}
|
|
else
|
|
{
|
|
printf("can't open file %s\n",filename);
|
|
status |= VX_FAILURE;
|
|
}
|
|
if(buf){
|
|
free(buf);
|
|
}
|
|
if(fp)
|
|
fclose(fp);
|
|
}
|
|
else
|
|
{
|
|
printf("not support file type:%s\n",filename);
|
|
status |= VX_FAILURE;
|
|
}
|
|
return status;
|
|
}
|
|
vx_status vnn_SaveTensorToFileAsFloat32(vx_tensor tensor,char *filename)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
vx_float32 *buf = NULL;
|
|
vx_int32 i=0;
|
|
FILE *fp = NULL;
|
|
vx_uint32 size[6];
|
|
vx_uint32 num=0;
|
|
num = vnn_GetTensorSize(tensor);
|
|
fp = fopen(filename,"w");
|
|
if(fp)
|
|
{
|
|
status |= vnn_CopyTensorToFloat32Data(tensor,&buf);
|
|
for(i = 0;i<num;i++)
|
|
fprintf(fp,"%f\n",buf[i]);
|
|
fclose(fp);
|
|
}
|
|
else
|
|
status = VX_FAILURE;
|
|
if(buf){
|
|
free(buf);
|
|
}
|
|
return status;
|
|
}
|
|
vx_status vnn_SaveTensorToFileAsBinary(vx_tensor tensor,char *filename)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
void *buf = NULL;
|
|
vx_int32 i=0;
|
|
FILE *fp = NULL;
|
|
vx_uint32 size[6];
|
|
vx_uint32 num_of_dim=0;
|
|
vx_uint32 buf_size = vnn_GetTensorBufferSize(tensor);
|
|
fp = fopen(filename,"wb");
|
|
if(fp)
|
|
{
|
|
status |= vnn_CopyTensorToData(tensor,&buf);
|
|
fwrite(buf,1,buf_size,fp);
|
|
fclose(fp);
|
|
}
|
|
else
|
|
status = VX_FAILURE;
|
|
|
|
if(buf){
|
|
free(buf);
|
|
}
|
|
return status;
|
|
}
|
|
|
|
|
|
|
|
static vx_status LoadBinaryFromFile(char *filename,void *buf, vx_int32 size)
|
|
{
|
|
FILE *fp = fopen(filename,"rb");
|
|
vx_int32 ret = fread(buf,1,size,fp);
|
|
fclose(fp);
|
|
return ret == size ? VX_SUCCESS : VX_FAILURE;
|
|
}
|
|
static vx_status LoadTextFromFile(char *filename,void *buf, vx_int32 size,vx_enum data_type)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
vx_float32 *temp = (vx_float32*)malloc(size*sizeof(vx_float32));
|
|
FILE *fp = fopen(filename,"r");
|
|
vx_int32 elm_size = vnn_GetTypeSize(data_type);
|
|
vx_int32 count = size/elm_size;
|
|
for(int i=0;i< count;i++)
|
|
fscanf(fp,"%f",&temp[i]);
|
|
fclose(fp);
|
|
switch(data_type)
|
|
{
|
|
case VX_TYPE_INT8:
|
|
for(int i=0;i< count;i++)
|
|
((vx_int8*)buf)[i] = (vx_int8)temp[i];
|
|
break;
|
|
case VX_TYPE_UINT8:
|
|
case VX_DF_IMAGE_U8:
|
|
for(int i=0;i< count;i++)
|
|
((vx_uint8*)buf)[i] = (vx_uint8)temp[i];
|
|
break;
|
|
case VX_TYPE_INT16:
|
|
case VX_DF_IMAGE_S16:
|
|
for(int i=0;i< count;i++)
|
|
((vx_int16*)buf)[i] = (vx_int16)temp[i];
|
|
break;
|
|
case VX_DF_IMAGE_U16:
|
|
case VX_TYPE_UINT16:
|
|
for(int i=0;i< count;i++)
|
|
((vx_uint16*)buf)[i] = (vx_uint16)temp[i];
|
|
break;
|
|
case VX_TYPE_INT32:
|
|
case VX_DF_IMAGE_S32:
|
|
for(int i=0;i< count;i++)
|
|
((vx_int32*)buf)[i] = (vx_int32)temp[i];
|
|
break;
|
|
case VX_TYPE_UINT32:
|
|
case VX_DF_IMAGE_U32:
|
|
for(int i=0;i< count;i++)
|
|
((vx_uint32*)buf)[i] = (vx_uint32)temp[i];
|
|
break;
|
|
case VX_TYPE_FLOAT32:
|
|
case VX_DF_IMAGE_F32:
|
|
for(int i=0;i< count;i++)
|
|
((vx_float32*)buf)[i] = (vx_float32)temp[i];
|
|
break;
|
|
|
|
default:
|
|
printf("Not support format:%d,line=%d\n",data_type,__LINE__);
|
|
status = VX_FAILURE;
|
|
}
|
|
if(temp){
|
|
free(temp);
|
|
}
|
|
return status;
|
|
}
|
|
static vx_status SaveBinaryToFile(char *filename,void *buf, vx_int32 size)
|
|
{
|
|
FILE *fp = fopen(filename,"wb");
|
|
vx_int32 ret = fwrite(buf,1,size,fp);
|
|
fclose(fp);
|
|
return ret == size ? VX_SUCCESS : VX_FAILURE;
|
|
}
|
|
static vx_status SaveTextToFile(char *filename,void *buf, vx_int32 size,vx_enum data_type)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
vx_int32 elm_size = vnn_GetTypeSize(data_type);
|
|
vx_int32 count = size/elm_size;
|
|
vx_float32 *temp = (vx_float32*)malloc(count*sizeof(vx_float32));
|
|
|
|
switch(data_type)
|
|
{
|
|
case VX_TYPE_INT8:
|
|
for(int i=0;i< count;i++)
|
|
temp[i] = (vx_float32)((vx_int8*)buf)[i];
|
|
break;
|
|
case VX_TYPE_UINT8:
|
|
case VX_DF_IMAGE_U8:
|
|
for(int i=0;i< count;i++)
|
|
temp[i] = (vx_float32)((vx_uint8*)buf)[i];
|
|
break;
|
|
case VX_TYPE_INT16:
|
|
case VX_DF_IMAGE_S16:
|
|
for(int i=0;i< count;i++)
|
|
temp[i] = (vx_float32)((vx_int16*)buf)[i];
|
|
break;
|
|
case VX_DF_IMAGE_U16:
|
|
case VX_TYPE_UINT16:
|
|
for(int i=0;i< count;i++)
|
|
temp[i] = (vx_float32)((vx_uint16*)buf)[i];
|
|
break;
|
|
case VX_TYPE_INT32:
|
|
case VX_DF_IMAGE_S32:
|
|
for(int i=0;i< count;i++)
|
|
temp[i] = (vx_float32)((vx_int32*)buf)[i];
|
|
break;
|
|
case VX_TYPE_UINT32:
|
|
case VX_DF_IMAGE_U32:
|
|
for(int i=0;i< count;i++)
|
|
temp[i] = (vx_float32)((vx_uint32*)buf)[i];
|
|
break;
|
|
case VX_TYPE_FLOAT32:
|
|
case VX_DF_IMAGE_F32:
|
|
for(int i=0;i< count;i++)
|
|
temp[i] = ((vx_float32*)buf)[i];
|
|
break;
|
|
default:
|
|
printf("Not support format:%d,line=%d\n",data_type,__LINE__);
|
|
status = VX_FAILURE;
|
|
}
|
|
FILE *fp = fopen(filename,"w");
|
|
for(int i=0;i< count;i++)
|
|
fprintf(fp,"%f\n",temp[i]);
|
|
fclose(fp);
|
|
if(temp){
|
|
free(temp);
|
|
}
|
|
return status;
|
|
}
|
|
|
|
vx_status vnn_LoadImageFromFile(vx_image image,char *filename)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
vx_int32 i=0;
|
|
file_type ft = get_file_type(filename);
|
|
|
|
vx_imagepatch_addressing_t imgInfo = VX_IMAGEPATCH_ADDR_INIT;
|
|
vx_uint32 width,height;
|
|
vx_df_image format;
|
|
vxQueryImage(image, VX_IMAGE_WIDTH, &width, sizeof(vx_uint32));
|
|
vxQueryImage(image, VX_IMAGE_HEIGHT, &height, sizeof(vx_uint32));
|
|
vxQueryImage(image, VX_IMAGE_FORMAT, &format, sizeof(format));
|
|
void* ptr = NULL;
|
|
vx_rectangle_t rect = {0,0,width,height};
|
|
vx_map_id map_id = 0;
|
|
vx_int32 size = width*height*vnn_GetTypeSize(format);
|
|
status |= vxMapImagePatch(image, &rect, 0, &map_id, &imgInfo, (void**)&ptr, VX_WRITE_ONLY, VX_MEMORY_TYPE_HOST, 0);
|
|
if(ft == FILE_TYPE_TEXT)
|
|
LoadTextFromFile(filename,ptr,size,format);
|
|
else if(ft == FILE_TYPE_BIN)
|
|
LoadBinaryFromFile(filename,ptr,size);
|
|
else
|
|
{
|
|
status = VX_FAILURE;
|
|
printf("Not support file type:%d,line=%d\n",filename,__LINE__);
|
|
}
|
|
status |= vxUnmapImagePatch(image, map_id);
|
|
return status;
|
|
}
|
|
vx_status vnn_SaveImageToFile(vx_image image,char *filename)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
vx_int32 i=0;
|
|
file_type ft = get_file_type(filename);
|
|
|
|
vx_imagepatch_addressing_t imgInfo = VX_IMAGEPATCH_ADDR_INIT;
|
|
vx_uint32 width,height;
|
|
vx_df_image format;
|
|
vxQueryImage(image, VX_IMAGE_WIDTH, &width, sizeof(vx_uint32));
|
|
vxQueryImage(image, VX_IMAGE_HEIGHT, &height, sizeof(vx_uint32));
|
|
vxQueryImage(image, VX_IMAGE_FORMAT, &format, sizeof(format));
|
|
void* ptr = NULL;
|
|
vx_rectangle_t rect = {0,0,width,height};
|
|
vx_map_id map_id = 0;
|
|
vx_int32 size = width*height*vnn_GetTypeSize(format);
|
|
status |= vxMapImagePatch(image, &rect, 0, &map_id, &imgInfo, (void**)&ptr, VX_READ_ONLY, VX_MEMORY_TYPE_HOST, 0);
|
|
if(ft == FILE_TYPE_TEXT)
|
|
SaveTextToFile(filename,ptr,size,format);
|
|
else if(ft == FILE_TYPE_BIN)
|
|
SaveBinaryToFile(filename,ptr,size);
|
|
else
|
|
{
|
|
status = VX_FAILURE;
|
|
printf("Not support file type:%d,line=%d\n",filename,__LINE__);
|
|
}
|
|
status |= vxUnmapImagePatch(image, map_id);
|
|
return status;
|
|
}
|
|
vx_status vnn_LoadArrayFromFile(vx_array arr,char *filename)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
vx_int32 i=0;
|
|
file_type ft = get_file_type(filename);
|
|
vx_size itemNumber = 0;
|
|
vx_size itemSize = 0;
|
|
vx_enum itemType;
|
|
vxQueryArray(arr, VX_ARRAY_CAPACITY, &itemNumber, sizeof(itemNumber));
|
|
vxQueryArray(arr, VX_ARRAY_ITEMSIZE, &itemSize, sizeof(itemSize));
|
|
vxQueryArray(arr, VX_ARRAY_ITEMTYPE, &itemType, sizeof(itemType));
|
|
void* ptr = NULL;
|
|
vx_map_id map_id = 0;
|
|
vx_int32 size = itemNumber*itemSize;
|
|
status |= vxMapArrayRange(arr, 0, itemNumber,&map_id, &itemSize, (void**)&ptr, VX_WRITE_ONLY,VX_MEMORY_TYPE_HOST,0);
|
|
if(ft == FILE_TYPE_TEXT)
|
|
LoadTextFromFile(filename,ptr,size,itemType);
|
|
else if(ft == FILE_TYPE_BIN)
|
|
LoadBinaryFromFile(filename,ptr,size);
|
|
else
|
|
{
|
|
status = VX_FAILURE;
|
|
printf("Not support file type:%d,line=%d\n",filename,__LINE__);
|
|
}
|
|
status |= vxUnmapArrayRange(arr, map_id);
|
|
return status;
|
|
}
|
|
vx_status vnn_SaveArrayToFile(vx_array arr,char *filename)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
vx_int32 i=0;
|
|
file_type ft = get_file_type(filename);
|
|
vx_size itemNumber = 0;
|
|
vx_size itemSize = 0;
|
|
vx_enum itemType;
|
|
vxQueryArray(arr, VX_ARRAY_CAPACITY, &itemNumber, sizeof(itemNumber));
|
|
vxQueryArray(arr, VX_ARRAY_ITEMSIZE, &itemSize, sizeof(itemSize));
|
|
vxQueryArray(arr, VX_ARRAY_ITEMTYPE, &itemType, sizeof(itemType));
|
|
void* ptr = NULL;
|
|
vx_map_id map_id = 0;
|
|
vx_int32 size = itemNumber*itemSize;
|
|
status |= vxMapArrayRange(arr, 0, itemNumber,&map_id, &itemSize, (void**)&ptr, VX_READ_ONLY,VX_MEMORY_TYPE_HOST,0);
|
|
if(ft == FILE_TYPE_TEXT)
|
|
SaveTextToFile(filename,ptr,size,itemType);
|
|
else if(ft == FILE_TYPE_BIN)
|
|
SaveBinaryToFile(filename,ptr,size);
|
|
else
|
|
{
|
|
status = VX_FAILURE;
|
|
printf("Not support file type:%d,line=%d\n",filename,__LINE__);
|
|
}
|
|
status |= vxUnmapArrayRange(arr, map_id);
|
|
return status;
|
|
}
|
|
vx_status vnn_LoadScalarFromFile(vx_scalar scalar,char *filename)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
vx_int32 i=0;
|
|
file_type ft = get_file_type(filename);
|
|
vx_enum data_type;
|
|
vx_float32 value;
|
|
vxQueryScalar(scalar, VX_SCALAR_TYPE, &data_type, sizeof(data_type));
|
|
vx_int32 size = vnn_GetTypeSize(data_type);
|
|
if(ft == FILE_TYPE_TEXT)
|
|
LoadTextFromFile(filename,&value,size,data_type);
|
|
else if(ft == FILE_TYPE_BIN)
|
|
LoadBinaryFromFile(filename,&value,size);
|
|
else
|
|
{
|
|
status = VX_FAILURE;
|
|
printf("Not support file type:%d,line=%d\n",filename,__LINE__);
|
|
}
|
|
vxCopyScalar(scalar,&value,VX_WRITE_ONLY,VX_MEMORY_TYPE_HOST);
|
|
return status;
|
|
}
|
|
vx_status vnn_SaveScalarToFile(vx_scalar scalar,char *filename)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
vx_int32 i=0;
|
|
file_type ft = get_file_type(filename);
|
|
vx_enum data_type;
|
|
vx_float32 value;
|
|
vxQueryScalar(scalar, VX_SCALAR_TYPE, &data_type, sizeof(data_type));
|
|
vx_int32 size = vnn_GetTypeSize(data_type);
|
|
vxCopyScalar(scalar,&value,VX_READ_ONLY,VX_MEMORY_TYPE_HOST);
|
|
if(ft == FILE_TYPE_TEXT)
|
|
SaveTextToFile(filename,&value,size,data_type);
|
|
else if(ft == FILE_TYPE_BIN)
|
|
SaveBinaryToFile(filename,&value,size);
|
|
else
|
|
{
|
|
status = VX_FAILURE;
|
|
printf("Not support file type:%d,line=%d\n",filename,__LINE__);
|
|
}
|
|
return status;
|
|
}
|
|
vx_status vnn_LoadDataFromFile(inout_obj* obj,char *filename)
|
|
{
|
|
vx_status status = VX_FAILURE;
|
|
if(obj->data_type == VX_TYPE_TENSOR)
|
|
{
|
|
status = vnn_LoadTensorFromFile(obj->u.tensor,filename);
|
|
_CHECK_STATUS(status, exit);
|
|
}
|
|
else if(obj->data_type == VX_TYPE_IMAGE)
|
|
{
|
|
status = vnn_LoadImageFromFile(obj->u.image,filename);
|
|
_CHECK_STATUS(status, exit);
|
|
}
|
|
else if(obj->data_type == VX_TYPE_ARRAY)
|
|
{
|
|
status = vnn_LoadArrayFromFile(obj->u.array,filename);
|
|
_CHECK_STATUS(status, exit);
|
|
}
|
|
else if(obj->data_type == VX_TYPE_SCALAR)
|
|
{
|
|
status = vnn_LoadScalarFromFile(obj->u.scalar,filename);
|
|
_CHECK_STATUS(status, exit);
|
|
}
|
|
else
|
|
{
|
|
status = VX_FAILURE;
|
|
_CHECK_STATUS(status, exit);
|
|
}
|
|
exit:
|
|
return status;
|
|
}
|
|
vx_status vnn_SaveDataToFile(inout_obj* obj,char *filename)
|
|
{
|
|
vx_status status = VX_FAILURE;
|
|
if(obj->data_type == VX_TYPE_TENSOR)
|
|
{
|
|
file_type ft = get_file_type(filename);
|
|
if(ft == FILE_TYPE_TEXT)
|
|
status = vnn_SaveTensorToFileAsFloat32(obj->u.tensor,filename);
|
|
else if (ft == FILE_TYPE_BIN)
|
|
status = vnn_SaveTensorToFileAsBinary(obj->u.tensor,filename);
|
|
else
|
|
status = VX_FAILURE;
|
|
_CHECK_STATUS(status, exit);
|
|
}
|
|
else if(obj->data_type == VX_TYPE_IMAGE)
|
|
{
|
|
status = vnn_SaveImageToFile(obj->u.image,filename);
|
|
_CHECK_STATUS(status, exit);
|
|
}
|
|
else if(obj->data_type == VX_TYPE_ARRAY)
|
|
{
|
|
status = vnn_SaveArrayToFile(obj->u.array,filename);
|
|
_CHECK_STATUS(status, exit);
|
|
}
|
|
else if(obj->data_type == VX_TYPE_SCALAR)
|
|
{
|
|
status = vnn_SaveScalarToFile(obj->u.scalar,filename);
|
|
_CHECK_STATUS(status, exit);
|
|
}
|
|
else
|
|
{
|
|
status = VX_FAILURE;
|
|
_CHECK_STATUS(status, exit);
|
|
}
|
|
exit:
|
|
return status;
|
|
}
|
|
|
|
vx_bool get_top
|
|
(
|
|
float *pfProb,
|
|
float *pfMaxProb,
|
|
uint32_t *pMaxClass,
|
|
uint32_t outputCount,
|
|
uint32_t topNum
|
|
)
|
|
{
|
|
uint32_t i, j;
|
|
|
|
#define MAX_TOP_NUM 20
|
|
if (topNum > MAX_TOP_NUM) return vx_false_e;
|
|
|
|
memset(pfMaxProb, 0, sizeof(float) * topNum);
|
|
memset(pMaxClass, 0xff, sizeof(float) * topNum);
|
|
|
|
for (j = 0; j < topNum; j++)
|
|
{
|
|
for (i=0; i<outputCount; i++)
|
|
{
|
|
if ((i == *(pMaxClass+0)) || (i == *(pMaxClass+1)) || (i == *(pMaxClass+2)) ||
|
|
(i == *(pMaxClass+3)) || (i == *(pMaxClass+4)))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
if (pfProb[i] > *(pfMaxProb+j))
|
|
{
|
|
*(pfMaxProb+j) = pfProb[i];
|
|
*(pMaxClass+j) = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
return vx_true_e;
|
|
}
|
|
vx_status vnn_ShowTensorTop5(vx_tensor tensor)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
vx_float32 *buf = NULL;
|
|
vx_int32 num = vnn_GetTensorSize(tensor);
|
|
uint32_t MaxClass[5];
|
|
vx_float32 fMaxProb[5];
|
|
vx_int32 i=0;
|
|
status |= vnn_CopyTensorToFloat32Data(tensor,&buf);
|
|
if (!get_top(buf, fMaxProb, MaxClass, num, 5))
|
|
{
|
|
printf("Fail to show result.\n");
|
|
status |= VX_SUCCESS;
|
|
goto final;
|
|
}
|
|
|
|
printf(" --- Top5 ---\n");
|
|
for(i=0; i<5; i++)
|
|
{
|
|
printf("%3d: %8.6f\n", MaxClass[i], fMaxProb[i]);
|
|
}
|
|
final:
|
|
if(buf){
|
|
free(buf);
|
|
}
|
|
return status;
|
|
}
|
|
vx_status vnn_ShowTop5(inout_obj* obj)
|
|
{
|
|
if(obj->data_type == VX_TYPE_TENSOR)
|
|
return vnn_ShowTensorTop5(obj->u.tensor);
|
|
|
|
return VX_SUCCESS;
|
|
}
|
|
vx_status vnn_QueryInputsAndOutputsParam(vx_kernel kernel,inout_param *input,vx_int32 *in_cnt,inout_param *output,vx_int32 *out_cnt)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
int i = 0;
|
|
/* Query number of parameters in kernel. num_params = input_count + output_count */
|
|
vx_uint32 num_params;
|
|
vx_int32 input_count=0,output_count=0;
|
|
vx_enum direction = 0;
|
|
vxQueryKernel(kernel, VX_KERNEL_PARAMETERS, &num_params, sizeof(vx_uint32));
|
|
|
|
for (i = 0; i < num_params; i++)
|
|
{
|
|
inout_param *ptrInOut = NULL;
|
|
vx_parameter param_kernel = NULL;
|
|
vx_meta_format meta;
|
|
vx_size _dim_size[MAX_NUM_DIMS],_dim_count;
|
|
param_kernel = vxGetKernelParameterByIndex(kernel, i);
|
|
vxQueryParameter(param_kernel, VX_PARAMETER_DIRECTION, &direction, sizeof(enum vx_type_e));
|
|
if(direction == VX_INPUT)
|
|
{
|
|
ptrInOut = &input[input_count];
|
|
input_count++;
|
|
}
|
|
else
|
|
{
|
|
ptrInOut = &output[output_count];
|
|
output_count++;
|
|
}
|
|
vxQueryParameter(param_kernel,VX_PARAMETER_META_FORMAT,&meta, sizeof(vx_meta_format));
|
|
vxQueryMetaFormatAttribute(meta, VX_REFERENCE_TYPE, &ptrInOut->data_type, sizeof(ptrInOut->data_type));
|
|
vxQueryParameter(param_kernel,VX_PARAMETER_META_FORMAT, &meta, sizeof(vx_meta_format));
|
|
vxQueryMetaFormatAttribute(meta, VX_TENSOR_NUMBER_OF_DIMS,&_dim_count, sizeof(_dim_count));
|
|
ptrInOut->dim_count = _dim_count;
|
|
vxQueryMetaFormatAttribute(meta, VX_TENSOR_DIMS, &_dim_size, sizeof(_dim_size));
|
|
for(int n = 0;n<ptrInOut->dim_count;n++)
|
|
ptrInOut->dim_size[n] = _dim_size[n];
|
|
vxQueryMetaFormatAttribute(meta, VX_TENSOR_DATA_TYPE, &ptrInOut->data_format, sizeof(ptrInOut->data_format));
|
|
vxQueryMetaFormatAttribute(meta, VX_TENSOR_QUANT_FORMAT, &ptrInOut->quan_format, sizeof(ptrInOut->quan_format));
|
|
switch (ptrInOut->quan_format)
|
|
{
|
|
case VX_QUANT_DYNAMIC_FIXED_POINT:
|
|
vxQueryMetaFormatAttribute(meta,VX_TENSOR_FIXED_POINT_POSITION, &ptrInOut->fixed_pos, sizeof(ptrInOut->fixed_pos));
|
|
break;
|
|
case VX_QUANT_AFFINE_SCALE:
|
|
vxQueryMetaFormatAttribute(meta, VX_TENSOR_ZERO_POINT, &ptrInOut->tf_zerop, sizeof(ptrInOut->tf_zerop));
|
|
vxQueryMetaFormatAttribute(meta, VX_TENSOR_SCALE, &ptrInOut->tf_scale, sizeof(ptrInOut->tf_scale));
|
|
break;
|
|
case VX_QUANT_NONE:
|
|
break;
|
|
case VX_QUANT_AFFINE_SCALE_PER_CHANNEL:
|
|
default:
|
|
status = VX_FAILURE;
|
|
printf("Quant format %u is not supported!", ptrInOut->quan_format);
|
|
_CHECK_STATUS(status, exit);
|
|
break;
|
|
}
|
|
vnn_Log("index:%d,in:%d, data_type:%d\ndim_cnt: %d, dims: %d, %d, %d, %d\nscale: %f, zp: %d, fixPos: %d\nquant_format:%d,data_format: %d\n", i,direction, ptrInOut->data_type,
|
|
ptrInOut->dim_count, ptrInOut->dim_size[0], ptrInOut->dim_size[1],ptrInOut->dim_size[2], ptrInOut->dim_size[3],
|
|
ptrInOut->tf_scale, ptrInOut->tf_zerop, ptrInOut->fixed_pos, ptrInOut->quan_format,
|
|
ptrInOut->data_format);
|
|
}
|
|
*in_cnt = input_count;
|
|
*out_cnt = output_count;
|
|
exit:
|
|
return status;
|
|
|
|
}
|
|
|
|
vx_status vnn_CreateObject(vx_context context, inout_param *param, inout_obj *obj)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
if(param->data_type == VX_TYPE_TENSOR)
|
|
{
|
|
vx_tensor_create_params_t ts_params;
|
|
ts_params.data_format = param->data_format;
|
|
ts_params.num_of_dims = param->dim_count;
|
|
ts_params.sizes = param->dim_size;
|
|
ts_params.quant_format = param->quan_format;
|
|
if(param->quan_format == VX_QUANT_AFFINE_SCALE)
|
|
{
|
|
ts_params.quant_data.affine.scale = param->tf_scale;
|
|
ts_params.quant_data.affine.zeroPoint = param->tf_zerop;
|
|
}
|
|
else if(param->quan_format == VX_QUANT_DYNAMIC_FIXED_POINT)
|
|
{
|
|
ts_params.quant_data.dfp.fixed_point_pos = (vx_int8)param->fixed_pos;
|
|
}
|
|
else
|
|
{
|
|
/*nothing*/
|
|
}
|
|
obj->u.tensor = vxCreateTensor2(context, &ts_params, sizeof(ts_params));
|
|
obj->data_type = param->data_type;
|
|
_CHECK_OBJ(obj->u.tensor,exit);
|
|
}
|
|
else if (param->data_type == VX_TYPE_IMAGE)
|
|
{
|
|
obj->u.image = vxCreateImage(context, param->dim_size[0],param->dim_size[1],param->data_format);
|
|
obj->data_type = VX_TYPE_IMAGE;
|
|
_CHECK_OBJ(obj->u.image,exit);
|
|
}
|
|
else if (param->data_type == VX_TYPE_ARRAY)
|
|
{
|
|
obj->u.array = vxCreateArray(context, param->data_format, param->dim_size[0]);
|
|
obj->data_type = VX_TYPE_ARRAY;
|
|
_CHECK_OBJ(obj->u.array,exit);
|
|
for(int i=0; i < param->dim_size[0];i++)
|
|
{
|
|
vx_float32 zero = 0;
|
|
vxAddArrayItems(obj->u.array,1,&zero,0);
|
|
}
|
|
}
|
|
else if (param->data_type == VX_TYPE_SCALAR)
|
|
{
|
|
vx_float32 num = 0;
|
|
obj->u.scalar = vxCreateScalar(context, param->data_format, &num);
|
|
obj->data_type = VX_TYPE_SCALAR;
|
|
_CHECK_OBJ(obj->u.scalar,exit);
|
|
}
|
|
else
|
|
{
|
|
printf("Not support output data type:%d\n",param->data_type);
|
|
status = VX_FAILURE;
|
|
}
|
|
exit:
|
|
return status;
|
|
}
|
|
vx_status vnn_ReleaseObject(inout_obj *obj)
|
|
{
|
|
vx_status status = VX_SUCCESS;
|
|
if(obj->data_type == VX_TYPE_TENSOR)
|
|
{
|
|
vxReleaseTensor( &obj->u.tensor);
|
|
}
|
|
else if (obj->data_type == VX_TYPE_IMAGE)
|
|
{
|
|
vxReleaseImage( &obj->u.image);
|
|
}
|
|
else if (obj->data_type == VX_TYPE_ARRAY)
|
|
{
|
|
vxReleaseArray( &obj->u.array);
|
|
}
|
|
else if (obj->data_type == VX_TYPE_SCALAR)
|
|
{
|
|
vxReleaseScalar( &obj->u.scalar);
|
|
}
|
|
else
|
|
{
|
|
printf("Not support output data type:%d\n",obj->data_type);
|
|
status = VX_FAILURE;
|
|
}
|
|
return status;
|
|
}
|
|
|
|
void vnn_Log
|
|
(
|
|
const char *fmt,
|
|
...
|
|
)
|
|
{
|
|
char arg_buffer[VSI_NN_MAX_DEBUG_BUFFER_LEN] = {0};
|
|
va_list arg;
|
|
vx_int32 debug = 0;
|
|
|
|
char *debug_s = getenv("VNN_DEBUG");
|
|
if(debug_s)
|
|
{
|
|
debug = atoi(debug_s);
|
|
}
|
|
|
|
if(debug != 1)
|
|
{
|
|
return ;
|
|
}
|
|
va_start(arg, fmt);
|
|
vsnprintf(arg_buffer, VSI_NN_MAX_DEBUG_BUFFER_LEN, fmt, arg);
|
|
va_end(arg);
|
|
fprintf(stderr, "%s\n", arg_buffer);
|
|
}
|