TIM-VX/src/tim/vx/internal/include/utils/vsi_nn_math.h

225 lines
5.9 KiB
C

/****************************************************************************
*
* Copyright (c) 2020 Vivante Corporation
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*****************************************************************************/
#ifndef _VSI_NN_MATH_H
#define _VSI_NN_MATH_H
#include <math.h>
#include <stdlib.h>
#include "vsi_nn_types.h"
#ifdef __cplusplus
extern "C" {
#endif
#define vsi_nn_abs(x) (((x) < 0) ? -(x) : (x))
#define vsi_nn_max(a,b) (((a) > (b)) ? (a) : (b))
#define vsi_nn_min(a,b) (((a) < (b)) ? (a) : (b))
#define vsi_nn_clamp(x, min, max) (((x) < (min)) ? (min) : \
((x) > (max)) ? (max) : (x))
#define vsi_nn_float_compare(a,b,diff) (vsi_nn_abs((a) - (b)) < (diff) ? TRUE : FALSE)
#define vsi_abs(x) vsi_nn_abs(x)
#define vsi_clamp(x, min, max) vsi_nn_clamp(x, min, max)
#define vsi_rtne(x) vsi_rint(x)
#define VSI_NN_INT32_MAX (0x7FFFFFFF)
#define VSI_NN_FLOAT32_INF (0x7F800000)
#define VSI_NN_FLOAT32_NAN (0x7FC00000)
#define VSI_NN_FLOAT64_INF (0x7FF0000000000000)
#define VSI_NN_FLOAT64_NAN (0x7FF8000000000000)
#define DEFINE_ARRAY_TYPE( NAME, TYPE ) \
typedef struct { \
size_t size; \
TYPE *data; \
} vsi_##NAME##_array_t; \
static VSI_INLINE_API vsi_##NAME##_array_t * vsi_##NAME##_array_create( size_t size ) { \
vsi_##NAME##_array_t * array = NULL; \
array = (vsi_##NAME##_array_t *)malloc( sizeof(vsi_##NAME##_array_t) + sizeof(TYPE) * size ); \
if (array == NULL) return NULL; \
array->data = (TYPE *)(((TYPE**)(&(array->data))) + 1); \
array->size = size; \
return array; \
} \
static VSI_INLINE_API void vsi_##NAME##_array_release( vsi_##NAME##_array_t ** array ) \
{ \
if( array && *array ) { \
free( *array ); \
*array = NULL; \
} \
}
DEFINE_ARRAY_TYPE( int, int32_t )
DEFINE_ARRAY_TYPE( float, float )
DEFINE_ARRAY_TYPE( size, vsi_size_t )
#undef DEFINE_ARRAY_TYPE
OVXLIB_API void vsi_nn_Transpose
(
uint8_t * dst,
uint8_t * data,
vsi_size_t * shape,
vsi_size_t dim_num,
vsi_size_t * perm,
vsi_nn_type_e type
);
OVXLIB_API void vsi_nn_Permute
(
uint8_t * dst,
uint8_t * data,
vsi_size_t * shape,
vsi_size_t dim_num,
vsi_size_t * perm,
vsi_nn_type_e type
);
OVXLIB_API void vsi_nn_SqueezeShape
(
vsi_size_t * shape,
vsi_size_t * dim_num
);
OVXLIB_API vsi_size_t vsi_nn_ShapeProduct
(
vsi_size_t * shape,
vsi_size_t dim_num
);
//shape: row first <--> column first
OVXLIB_API void vsi_nn_InvertShape
(
vsi_size_t * in,
vsi_size_t dim_num,
vsi_size_t * out
);
//Permute shape: row first <--> column first
OVXLIB_API void vsi_nn_InvertPermuteShape
(
vsi_size_t * in,
vsi_size_t dim_num,
vsi_size_t * out
);
OVXLIB_API double vsi_nn_Rint
(
double x
);
/**
* Set Seeds for philox_4x32_10 algorithm
* philox_4x32_10 algorithm need 2 uint32_t as seeds.
*
* @param[in] the low uint32_t of the seed.
* @param[in] the high uint32_t of the seed.
*/
void vsi_nn_random_init_for_philox_4x32_10
(
uint32_t low,
uint32_t high
);
/**
* Random Number Generator By philox_4x32_10 algorithm
* Random Number(uint32_t) Generator By philox_4x32_10 algorithm
*
* @param[out] the buffer for RNG output.
* @param[in] the number of generated random numbers.
*/
void vsi_nn_random_generate_by_philox_4x32_10
(
uint32_t *random_buf,
uint32_t len
);
/**
* Uniform Transform
* Transform the random uint32_t to Uniform float in [0, 1).
*
* @param[in] the buffer for random uint32_t.
* @param[out] the buffer for uniform float in [0, 1).
* @param[in] the number of random numbers.
*/
void vsi_nn_random_uniform_transform
(
uint32_t *random_buf,
float *uniform_buf,
uint32_t len
);
static VSI_INLINE_API double copy_sign
(
double number,
double sign
)
{
double value = vsi_nn_abs(number);
return (sign > 0) ? value : (-value);
} /* copy_sign() */
static VSI_INLINE_API float simple_round
(
float x
)
{
return (float) copy_sign(floorf(fabsf(x) + 0.5f), x);
} /* simple_round() */
static VSI_INLINE_API double vsi_rint
(
double x
)
{
#define _EPSILON 1e-8
double decimal;
double inter;
decimal = modf((double)x, &inter);
if( vsi_nn_abs((vsi_nn_abs(decimal) - 0.5f)) < _EPSILON )
{
inter += (int32_t)(inter) % 2;
}
else
{
return simple_round( (float)x );
}
return inter;
} /* vsi_rint() */
/**
* Computes an approximation of the error function.
* This is the same approximation used by Eigen.
*
* @param[in] the value for input float.
*/
float vsi_nn_erf_impl(float x);
#ifdef __cplusplus
}
#endif
#endif