Support X-CUBE-AI v4.1.0

This commit is contained in:
Thibaut Vercueil 2019-10-18 13:57:49 +02:00
parent df4a711ded
commit 0f17925f98
19 changed files with 1190 additions and 388 deletions

View File

@ -124,15 +124,25 @@
AI_STRINGIFY_ARG(minor) "." \
AI_STRINGIFY_ARG(micro) \
#define AI_PACK(...) __VA_ARGS__
#define AI_PACK(...) \
__VA_ARGS__
#define AI_PACK_TENSORS_PTR(...) \
AI_PACK(__VA_ARGS__)
#define AI_PACK_INFO(size_) (ai_tensor_info[1]) { { \
.buffer = (ai_buffer[size_])AI_STRUCT_INIT, \
.state = (ai_tensor_state[size_])AI_STRUCT_INIT, \
} }
#define AI_CR "\r\n"
#ifdef HAS_AI_DEBUG
#define AI_DEBUG(expr) expr
#if (defined HAS_AI_DEBUG || defined HAS_DEBUG_LIB)
#define AI_DEBUG(...) __VA_ARGS__
#else
#define AI_DEBUG(expr) AI_WRAP_FUNC(AI_NOP)
#endif /* HAS_AI_DEBUG */
#define AI_DEBUG(...) AI_WRAP_FUNC(AI_NOP)
#endif
#define AI_FLAG_NONE (0x0)
#define AI_FLAG_SET(mask, flag) (mask) |= (flag)

View File

@ -26,6 +26,7 @@
#include "ai_platform.h"
#include "ai_platform_interface.h"
/*!
* @defgroup datatypes_internal Internal Datatypes
* @brief Data structures used internally to implement neural networks
@ -73,65 +74,117 @@
9,8,7,6,5,4,3,2,1,0
#define AI_PTR_ALIGN(ptr, alignment) \
( (((ai_uptr)(ptr))+((alignment)-1))&(~((alignment)-1)) )
( (((ai_uptr)(ptr))+((ai_uptr)(alignment)-1))&(~((ai_uptr)(alignment)-1)) )
#define AI_DIMENSION(item_, pos_) \
((item_).dimension[(pos_)])
/*! AI_STORAGE_KLASS SECTION ************************************/
#define AI_STORAGE_KLASS_TYPE(s_) \
( (s_)->type )
/******************************************************************************/
#define AI_BITS_TO_BYTES(bits_) \
(((bits_)+0x7) >> 3)
#define AI_STORAGE_KLASS_SIZE(s_) \
( (s_)->size )
#define AI_BYTES_TO_BITS(bytes_) \
((bytes_) << 3)
#define AI_STORAGE_KLASS_DATA(s_, type_) \
( (type_*)((s_)->data) )
/******************************************************************************/
#define AI_STORAGE_KLASS_COPY(dst_, dst_type_, src_, src_type_) \
{ \
AI_ASSERT(AI_STORAGE_KLASS_SIZE(src_)>=AI_STORAGE_KLASS_SIZE(dst_)) \
AI_STORAGE_KLASS_SIZE(dst_) = AI_STORAGE_KLASS_SIZE(src_); \
for (ai_size i=0; i<AI_STORAGE_KLASS_SIZE(dst_); i++ ) { \
AI_STORAGE_KLASS_DATA(dst_, dst_type_)[i] = \
AI_STORAGE_KLASS_DATA(src_, src_type_)[i]; \
} \
}
#define AI_STORAGE_KLASS_DUMP(s_, pfx_, post_, fmt_, type_) \
{ \
AI_ASSERT(s_) \
printf(pfx_, AI_STORAGE_KLASS_SIZE(s_)); \
for ( ai_u32 i=0; i<AI_STORAGE_KLASS_SIZE(s_); i++ ) { \
if ( (i % 8)==0 ) printf("\n "); \
printf(fmt_, AI_STORAGE_KLASS_DATA(s_, type_)[i]); \
} \
printf(post_); \
}
/*! AI_SHAPES SECTION ************************************/
#define AI_SHAPE_2D_H(shape_) \
AI_DIMENSION((shape_), AI_SHAPE_2D_HEIGHT)
AI_SHAPE_ELEM(shape_, AI_SHAPE_2D_HEIGHT)
#define AI_SHAPE_2D_W(shape_) \
AI_DIMENSION((shape_), AI_SHAPE_2D_WIDTH)
AI_SHAPE_ELEM(shape_, AI_SHAPE_2D_WIDTH)
#define AI_SHAPE_ND_SIZE(shape_) \
((shape_).size)
#define AI_SHAPE_ELEM(shape_, pos_) \
AI_STORAGE_KLASS_DATA(shape_, ai_shape_dimension)[pos_]
#define AI_SHAPE_ND_ELEM(shape_, pos_) \
AI_DIMENSION(shape_, pos_)
#define AI_SHAPE_SIZE(shape_) \
AI_STORAGE_KLASS_SIZE(shape_)
/******************************************************************************/
#define AI_STRIDE_2D_H(stride_) \
AI_DIMENSION((stride_), AI_SHAPE_2D_HEIGHT)
#define AI_SHAPE_CLONE(dst_, src_) \
AI_STORAGE_KLASS_COPY(dst_, ai_shape_dimension, src_, ai_shape_dimension)
#define AI_STRIDE_2D_W(stride_) \
AI_DIMENSION((stride_), AI_SHAPE_2D_WIDTH)
#define AI_STRIDE_ND_SIZE(stride_) \
((stride_).size)
#define AI_STRIDE_ND_ELEM(stride_, pos_) \
AI_DIMENSION(stride_, pos_)
/******************************************************************************/
//#define AI_SHAPE_BATCH(shape) AI_DIMENSION((shape), AI_SHAPE_BATCH_CHANNEL)
#define AI_SHAPE_H(shape) AI_DIMENSION((shape), AI_SHAPE_HEIGHT)
#define AI_SHAPE_W(shape) AI_DIMENSION((shape), AI_SHAPE_WIDTH)
#define AI_SHAPE_CH(shape) AI_DIMENSION((shape), AI_SHAPE_CHANNEL)
#define AI_SHAPE_IN_CH(shape) AI_DIMENSION((shape), AI_SHAPE_IN_CHANNEL)
//#define AI_SHAPE_BATCH(shape_) AI_SHAPE_ELEM((shape_), AI_SHAPE_BATCH_CHANNEL)
#define AI_SHAPE_H(shape_) AI_SHAPE_ELEM((shape_), AI_SHAPE_HEIGHT)
#define AI_SHAPE_W(shape_) AI_SHAPE_ELEM((shape_), AI_SHAPE_WIDTH)
#define AI_SHAPE_CH(shape_) AI_SHAPE_ELEM((shape_), AI_SHAPE_CHANNEL)
#define AI_SHAPE_IN_CH(shape_) AI_SHAPE_ELEM((shape_), AI_SHAPE_IN_CHANNEL)
#define AI_CONV_SHAPE_H AI_SHAPE_W
#define AI_CONV_SHAPE_W AI_SHAPE_CH
#define AI_CONV_SHAPE_CH AI_SHAPE_H
#define AI_CONV_SHAPE_IN_CH AI_SHAPE_IN_CH
//#define AI_STRIDE_BATCH(stride) AI_DIMENSION((stride), AI_SHAPE_BATCH_CHANNEL)
#define AI_STRIDE_H(stride) AI_DIMENSION((stride), AI_SHAPE_HEIGHT)
#define AI_STRIDE_W(stride) AI_DIMENSION((stride), AI_SHAPE_WIDTH)
#define AI_STRIDE_CH(stride) AI_DIMENSION((stride), AI_SHAPE_CHANNEL)
#define AI_STRIDE_IN_CH(stride) AI_DIMENSION((stride), AI_SHAPE_IN_CHANNEL)
/*! AI_STRIDES SECTION ***********************************/
#define AI_STRIDE_2D_H(stride_) \
AI_STRIDE_ELEM((stride_), AI_SHAPE_2D_HEIGHT)
#define AI_STRIDE_2D_W(stride_) \
AI_STRIDE_ELEM((stride_), AI_SHAPE_2D_WIDTH)
#define AI_STRIDE_ELEM(stride_, pos_) \
AI_STORAGE_KLASS_DATA(stride_, ai_stride_dimension)[pos_]
#define AI_STRIDE_SIZE(stride_) \
AI_STORAGE_KLASS_SIZE(stride_)
#define AI_STRIDE_CLONE(dst_, src_) \
AI_STORAGE_KLASS_COPY(dst_, ai_stride_dimension, src_, ai_stride_dimension)
//#define AI_STRIDE_BATCH(stride) AI_STRIDE_ELEM((stride), AI_SHAPE_BATCH_CHANNEL)
#define AI_STRIDE_H(stride) AI_STRIDE_ELEM((stride), AI_SHAPE_HEIGHT)
#define AI_STRIDE_W(stride) AI_STRIDE_ELEM((stride), AI_SHAPE_WIDTH)
#define AI_STRIDE_CH(stride) AI_STRIDE_ELEM((stride), AI_SHAPE_CHANNEL)
#define AI_STRIDE_IN_CH(stride) AI_STRIDE_ELEM((stride), AI_SHAPE_IN_CHANNEL)
/*! AI_TENSORS SECTION ***********************************/
#define AI_TENSOR_KLASS(tensor_) \
( (tensor_) ? (tensor_)->klass : NULL )
#define AI_TENSOR_SHAPE(tensor_) \
( &((tensor_)->shape) )
#define AI_TENSOR_STRIDE(tensor_) \
( &((tensor_)->stride) )
#define AI_TENSOR_INFO(tensor_) \
( &((tensor_)->info) )
#define AI_TENSOR_DATA(tensor_) \
( (tensor_) ? (tensor_)->data : NULL )
#define AI_TENSOR_ID(tensor_) \
( (tensor_) ? AI_TENSOR_INFO(tensor_)->id : 0 )
#define AI_TENSOR_FLAGS(tensor_) \
( (tensor_) ? AI_TENSOR_INFO(tensor_)->flags : 0 )
#define AI_TENSOR_DATA_SIZE(tensor_) \
( (tensor_) ? AI_TENSOR_INFO(tensor_)->data_size : 0 )
/*! AI_OFFSETS SECTION ***********************************/
//#define AI_OFFSET_BATCH(b, stride) ((ai_ptr_offset)(b) * AI_STRIDE_BATCH(stride))
#define AI_OFFSET_H(y, stride) ((ai_ptr_offset)(y) * AI_STRIDE_H(stride))
#define AI_OFFSET_W(x, stride) ((ai_ptr_offset)(x) * AI_STRIDE_W(stride))
@ -150,14 +203,27 @@
/** Tensors datatypes defines handlers ****************************************/
#define AI_TENSOR_SIZE(tensor_) \
( AI_SHAPE_H((tensor_)->shape) * AI_SHAPE_W((tensor_)->shape) * \
AI_SHAPE_CH((tensor_)->shape) * AI_SHAPE_IN_CH((tensor_)->shape) )
( AI_SHAPE_H(AI_TENSOR_SHAPE(tensor_)) * AI_SHAPE_W(AI_TENSOR_SHAPE(tensor_)) * \
AI_SHAPE_CH(AI_TENSOR_SHAPE(tensor_)) * AI_SHAPE_IN_CH(AI_TENSOR_SHAPE(tensor_)) )
#define AI_TENSOR_BYTE_SIZE(tensor_) \
( AI_SHAPE_H((tensor_)->shape) * AI_STRIDE_H((tensor_)->stride) )
( AI_SHAPE_H(AI_TENSOR_SHAPE(tensor_)) * AI_STRIDE_H(AI_TENSOR_STRIDE(tensor_)) )
/******************************************************************************/
/** Integer tensor info extraction ********************************************/
#define AI_INTQ_INFO_LIST_SCALE_ARRAY(list_, type_) \
( ((list_) && (list_)->info) \
? ((type_*)((list_)->info->scale)) : NULL )
#define AI_INTQ_INFO_LIST_ZEROPOINT_ARRAY(list_, type_) \
( ((list_) && (list_)->info) \
? ((type_*)((list_)->info->zeropoint)) : NULL )
#define AI_KLASS_GET_INTQ_INFO_LIST(tensor_) \
((ai_intq_info_list*)((tensor_)->klass))
AI_API_DECLARE_BEGIN
/*!
@ -207,10 +273,15 @@ typedef ai_bool (*func_copy_tensor)(ai_tensor* dst, const ai_tensor* src);
* @return true if shape0 and shape1 have same dimensions. false otherwise
*/
AI_DECLARE_STATIC
ai_bool ai_shape_is_same(const ai_shape* shape0, const ai_shape* shape1) {
ai_bool ai_shape_is_same(
const ai_shape* shape0, const ai_shape* shape1)
{
AI_ASSERT(shape0 && shape1)
for (ai_size i = 0; i < AI_SHAPE_MAX_DIMENSION; ++i) {
if ( shape0->dimension[i]!=shape1->dimension[i] )
AI_ASSERT(AI_SHAPE_SIZE(shape0)==AI_SHAPE_SIZE(shape1))
ai_size dim = AI_SHAPE_SIZE(shape0);
while ( dim>0 ) {
dim--;
if ( AI_SHAPE_ELEM(shape0, dim)!=AI_SHAPE_ELEM(shape1, dim) )
return false;
}
return true;
@ -225,10 +296,15 @@ ai_bool ai_shape_is_same(const ai_shape* shape0, const ai_shape* shape1) {
* smallers or equal of the shape1 ones). false otherwise
*/
AI_DECLARE_STATIC
ai_bool ai_shape_is_subshape(const ai_shape* shape0, const ai_shape* shape1) {
ai_bool ai_shape_is_subshape(
const ai_shape* shape0, const ai_shape* shape1)
{
AI_ASSERT(shape0 && shape1)
for (ai_size i = 0; i < AI_SHAPE_MAX_DIMENSION; ++i) {
if ( shape0->dimension[i]>shape1->dimension[i] )
AI_ASSERT(AI_SHAPE_SIZE(shape0)==AI_SHAPE_SIZE(shape1))
ai_size dim = AI_SHAPE_SIZE(shape0);
while ( dim ) {
dim--;
if ( AI_SHAPE_ELEM(shape0, dim)>AI_SHAPE_ELEM(shape1, dim) )
return false;
}
return true;
@ -240,13 +316,16 @@ ai_bool ai_shape_is_subshape(const ai_shape* shape0, const ai_shape* shape1) {
* @param shape the tensor shape
*/
AI_DECLARE_STATIC
ai_size ai_shape_get_size(const ai_shape* shape) {
ai_size ai_shape_get_size(const ai_shape* shape)
{
AI_ASSERT(shape)
AI_ASSERT(AI_SHAPE_SIZE(shape)==AI_SHAPE_MAX_DIMENSION)
ai_size dim = AI_SHAPE_SIZE(shape);
ai_size size = 1;
for (ai_size i = 0; i < AI_SHAPE_MAX_DIMENSION; ++i) {
size *= shape->dimension[i];
while ( dim>0 ) {
dim--;
size *= AI_SHAPE_ELEM(shape, dim);
}
return size;
}
@ -256,11 +335,10 @@ ai_size ai_shape_get_size(const ai_shape* shape) {
* @param shape the tensor shape
*/
AI_DECLARE_STATIC
ai_size ai_shape_get_npixels(const ai_shape* shape) {
ai_size ai_shape_get_npixels(const ai_shape* shape)
{
AI_ASSERT(shape)
const ai_size npixels =
shape->dimension[AI_SHAPE_WIDTH] * shape->dimension[AI_SHAPE_HEIGHT];
const ai_size npixels = AI_SHAPE_W(shape) * AI_SHAPE_H(shape);
return npixels;
}

View File

@ -11,9 +11,14 @@
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdarg.h>
#ifdef __cplusplus
extern "C" {
#else
#include <stdbool.h>
#endif
/*!
* @defgroup log Core logger class definition and implementation
* @brief Data structures and defines used to implementlogger module
@ -44,6 +49,7 @@
#define LOG_DEBUG (0x5)
#define LOG_TRACE (0x6)
/*!
* @typedef log_LockFn
* @ingroup ai_log
@ -127,4 +133,8 @@ void ai_log_set_fp(FILE *fp);
void ai_log_log(const uint8_t level, const char *file,
const int line, const char *fmt, ...);
#ifdef __cplusplus
}
#endif
#endif /*AI_LOG_H_*/

View File

@ -26,7 +26,7 @@
#define STM32_DOT_INLINE_OPTIM
#define AI_FLOAT_EPSILON_2 (6.19209290e-5F) /* Used for small calculation
#define AI_FLOAT_TOLERANCE (6.19209290e-5F) /* Used for small calculation
noise issues */
#define AI_FLOAT_EPSILON (1.19209290e-7F)
#define AI_I8_EPSILON (0.00787401F) /* 1/(2^7 - 1) */
@ -36,10 +36,17 @@
#define AI_MIN(x,y) ( ((x)<(y)) ? (x) : (y) )
#define AI_MAX(x,y) ( ((x)>(y)) ? (x) : (y) )
#define AI_SIGN(x) (((x)>0) ? 1 : -1)
#define AI_CLAMP(x, min, max) AI_MIN(AI_MAX(x,min), max)
#define AI_ROUND(x) round(x)
#define AI_ABS(x) fabsf(x)
#define AI_ABS_DIFF(x, y) ( ((x)>(y)) ? ((x)-(y)) : ((y)-(x)) )
#define AI_NEG(x) ( -1 * (x) )
#define AI_RECIPROCAL(x) ( 1.0f / (x) )
#define AI_CEIL(x) ceilf(x)
#define AI_FLOOR(x) floorf(x)
#define AI_FLOOR_DIV(x, y) AI_FLOOR((x)/(y)) /* floor division: x // y */
#define AI_FLOOR_MOD(x, y) fmodf(x, y)
#define AI_ROUND(x) roundf(x)
#if defined(STM32_DOT_INLINE_OPTIM)
@ -94,13 +101,25 @@ void __ai_math_dot_array(
ai_math_dot_array(dst, src0, src1, size)
#endif
#define AI_MATH_SQRT(x) ai_math_sqrt(x)
#define AI_MATH_ACOS(x) acosf(x)
#define AI_MATH_ACOSH(x) acoshf(x)
#define AI_MATH_ASIN(x) asinf(x)
#define AI_MATH_ASINH(x) asinhf(x)
#define AI_MATH_ATAN(x) atanf(x)
#define AI_MATH_ATANH(x) atanhf(x)
#define AI_MATH_COS(x) cosf(x)
#define AI_MATH_COSH(x) coshf(x)
#define AI_MATH_ERF(x) erff(x)
#define AI_MATH_EXP(x) expf(x)
#define AI_MATH_POW(x, e) powf((x), (e))
#define AI_MATH_TANH(x) tanhf(x)
#define AI_MATH_SIGN(x) (((x)>0) ? 1 : -1)
#define AI_MATH_LOG(x) logf(x)
#define AI_MATH_POW(x, e) powf((x), (e))
#define AI_MATH_RSQRT(x) (1.0f / AI_MATH_SQRT(x))
#define AI_MATH_SIN(x) sinf(x)
#define AI_MATH_SINH(x) sinhf(x)
#define AI_MATH_SQRT(x) ai_math_sqrt(x)
#define AI_MATH_TAN(x) tanf(x)
#define AI_MATH_TANH(x) tanhf(x)
#define AI_MATH_RELU_TEST(x, thr, min, max) \
( ((x)<(thr)) ? (min) : (max) )
@ -132,11 +151,14 @@ void __ai_math_dot_array(
#define AI_MATH_SELU(x, alpha, scale) \
((scale)*AI_MATH_ELU(x, alpha))
#define AI_MATH_SCALED_TANH(x, alpha, beta) \
((alpha)*AI_MATH_TANH((beta)*(x)))
#define AI_MATH_SIGMOID(x) \
(1.0f / (1.0f + AI_MATH_EXP(-(x))))
#define AI_MATH_HARD_SIGMOID(x) \
(AI_MAX(0.0f, AI_MIN(1.0f, (x) * 0.2f + 0.5f)))
#define AI_MATH_HARD_SIGMOID(x, alpha, beta) \
(AI_MAX(0.0f, AI_MIN(1.0f, (x) * (alpha) + (beta))))
#define AI_MATH_SOFT_PLUS(x) \
AI_MATH_LOG(AI_MATH_EXP(x)+1.0f)
@ -266,6 +288,8 @@ AI_INTERFACE_ENTRY
ai_float ai_fast_prelu(const ai_float x, const ai_float slope);
AI_INTERFACE_ENTRY ai_float ai_div(const ai_float a, const ai_float b);
AI_INTERFACE_ENTRY ai_float ai_floor_div(const ai_float a, const ai_float b);
AI_INTERFACE_ENTRY ai_float ai_floor_mod(const ai_float a, const ai_float b);
AI_INTERFACE_ENTRY ai_float ai_max(const ai_float a, const ai_float b);
AI_INTERFACE_ENTRY ai_float ai_min(const ai_float a, const ai_float b);
AI_INTERFACE_ENTRY ai_float ai_mul(const ai_float a, const ai_float b);

View File

@ -22,7 +22,6 @@
#define __AI_PLATFORM_H__
#pragma once
#include <stdbool.h>
#include <stdint.h>
#define AI_PLATFORM_API_MAJOR 1
@ -34,6 +33,7 @@
#define AI_API_DECLARE_BEGIN extern "C" {
#define AI_API_DECLARE_END }
#else
#include <stdbool.h>
#define AI_API_DECLARE_BEGIN /* AI_API_DECLARE_BEGIN */
#define AI_API_DECLARE_END /* AI_API_DECLARE_END */
#endif
@ -63,28 +63,28 @@
#define AI_ALIGNED(x) __attribute__((aligned(x)))
#else
/* Dynamic libraries are not supported by the compiler */
#define AI_API_ENTRY /* AI_API_ENTRY */
#define AI_ALIGNED(x) /* AI_ALIGNED(x) */
#define AI_API_ENTRY /* AI_API_ENTRY */
#define AI_ALIGNED(x) /* AI_ALIGNED(x) */
#endif
#define AI_HANDLE_PTR(ptr_) ((ai_handle)(ptr_))
#define AI_HANDLE_NULL AI_HANDLE_PTR(0)
#define AI_HANDLE_PTR(ptr_) ((ai_handle)(ptr_))
#define AI_HANDLE_NULL AI_HANDLE_PTR(0)
#define AI_HANDLE_FUNC_PTR(func) ((ai_handle_func)(func))
#define AI_HANDLE_FUNC_PTR(func) ((ai_handle_func)(func))
#define AI_UNUSED(x) (void)(x);
#define AI_UNUSED(x) (void)(x);
#define AI_DEPRECATED /* AI_DEPRECATED */
#define AI_DEPRECATED /* AI_DEPRECATED */
#define AI_LEGACY /* AI_LEGACY */
#define AI_LEGACY /* AI_LEGACY */
#ifndef __GNUC__
#define AI_STRUCT_INIT {0}
#define AI_STRUCT_INIT {0}
#else
#define AI_STRUCT_INIT {}
#define AI_STRUCT_INIT {}
#endif
#define AI_ERROR_FMT AIU32_FMT
#define AI_ERROR_FMT AIU32_FMT
#define AI_IS_UNSIGNED(type) \
((((type)0) - 1) > 0)
@ -97,6 +97,18 @@
.params = params_, \
.activations = activations_ }
/*! ai_intq_info struct handlers **********************************************/
#define AI_INTQ_INFO_LIST_FLAGS(list_) \
( (list_) ? (list_)->flags : 0 )
#define AI_INTQ_INFO_LIST_SCALE(list_, type_, pos_) \
( ((list_) && (list_)->info && ((pos_)<(list_)->size)) \
? ((type_*)((list_)->info->scale))[(pos_)] : 0 )
#define AI_INTQ_INFO_LIST_ZEROPOINT(list_, type_, pos_) \
( ((list_) && (list_)->info && ((pos_)<(list_)->size)) \
? ((type_*)((list_)->info->zeropoint))[(pos_)] : 0 )
/*! ai_buffer format handlers *************************************************/
/*!
@ -107,6 +119,13 @@
*/
typedef int32_t ai_buffer_format;
/*! ai_buffer_meta flags ******************************************************/
#define AI_BUFFER_META_HAS_INTQ_INFO (0x1U << 0)
#define AI_BUFFER_META_FLAG_SCALE_FLOAT (0x1U << 0)
#define AI_BUFFER_META_FLAG_ZEROPOINT_U8 (0x1U << 1)
#define AI_BUFFER_META_FLAG_ZEROPOINT_S8 (0x1U << 2)
/*! ai_buffer format variable flags *******************************************/
#define AI_BUFFER_FMT_TYPE_NONE (0x0)
#define AI_BUFFER_FMT_TYPE_FLOAT (0x1)
#define AI_BUFFER_FMT_TYPE_Q (0x2)
@ -175,6 +194,30 @@ typedef int32_t ai_buffer_format;
#define AI_BUFFER_DATA(buf_, type_) \
((type_*)((buf_)->data))
#define AI_BUFFER_META_INFO(buf_) \
((buf_)->meta_info)
#define AI_BUFFER_META_INFO_INTQ(meta_) \
((meta_) && ((meta_)->flags & AI_BUFFER_META_HAS_INTQ_INFO)) \
? ((meta_)->intq_info) : NULL
#define AI_BUFFER_META_INFO_INTQ_GET_SCALE(meta_, pos_) \
( (AI_BUFFER_META_INFO_INTQ(meta_)) \
? AI_INTQ_INFO_LIST_SCALE(AI_BUFFER_META_INFO_INTQ(meta_), ai_float, pos_) \
: 0 )
#define AI_BUFFER_META_INFO_INTQ_GET_ZEROPOINT(meta_, pos_) \
( (AI_BUFFER_META_INFO_INTQ(meta_)) \
? ((AI_INTQ_INFO_LIST_FLAGS(AI_BUFFER_META_INFO_INTQ(meta_))&AI_BUFFER_META_FLAG_ZEROPOINT_U8) \
? AI_INTQ_INFO_LIST_ZEROPOINT(AI_BUFFER_META_INFO_INTQ(meta_), ai_u8, pos_) \
: AI_INTQ_INFO_LIST_ZEROPOINT(AI_BUFFER_META_INFO_INTQ(meta_), ai_i8, pos_) ) \
: 0 )
#define AI_BUFFER_META_INFO_INIT(flags_, intq_info_) { \
.flags = (flags_), \
.intq_info = AI_PACK(intq_info_) \
}
#define AI_BUFFER_SIZE(buf_) \
(((buf_)->width) * ((buf_)->height) * ((buf_)->channels))
@ -188,7 +231,8 @@ typedef int32_t ai_buffer_format;
.height = (h_), \
.width = (w_), \
.channels = (ch_), \
.data = (ai_handle)(data_) \
.data = (ai_handle)(data_), \
.meta_info = NULL \
}
#define AI_BUFFER_OBJ_INIT_STATIC(type_, format_, h_, w_, ch_, n_batches_, ...) \
@ -197,7 +241,8 @@ typedef int32_t ai_buffer_format;
.height = (h_), \
.width = (w_), \
.channels = (ch_), \
.data = (ai_handle)((type_[(h_)*(w_)*(ch_)*(n_batches_)]){__VA_ARGS__}) \
.data = (ai_handle)((type_[(h_)*(w_)*(ch_)*(n_batches_)]){__VA_ARGS__}), \
.meta_info = NULL \
}
/*!
@ -269,6 +314,7 @@ typedef int64_t ai_i64;
typedef uint32_t ai_signature;
/******************************************************************************/
/*!
* @struct ai_error
* @ingroup ai_platform
@ -279,6 +325,43 @@ typedef struct ai_error_ {
ai_u32 code : 24; /*!< Error code represented by @ref ai_error_code */
} ai_error;
/******************************************************************************/
/*!
* @struct ai_intq_info
* @ingroup ai_platform
* @brief an element of the ai_intq_info_list entry. It reports an array for the
* scale and zeropoint values for each buffer. Optional flags are also present
*/
typedef struct ai_intq_info_ {
ai_float* scale;
ai_handle zeropoint;
} ai_intq_info;
/*!
* @struct ai_intq_info_list
* @ingroup ai_platform
* @brief list reporting meta info for quantized networks integer support
* when size > 1 it means a per channel out quantization
*/
typedef struct ai_intq_info_list_ {
ai_u16 flags; /*!< optional flags to store intq info attributes */
ai_u16 size; /*!< number of elements in the the intq_info list */
ai_intq_info* info; /*!< pointer to an array of metainfo associated to the intq_info list */
} ai_intq_info_list;
/******************************************************************************/
/*!
* @struct ai_buffer_meta_info
* @ingroup ai_platform
* @brief Optional meta attributes associated with the I/O buffer.
* This datastruct is used also for network querying, where the data field may
* may be NULL.
*/
typedef struct ai_buffer_meta_info_ {
ai_u32 flags; /*!< meta info flags */
ai_intq_info_list* intq_info; /*!< meta info related to integer format */
} ai_buffer_meta_info;
/*!
* @struct ai_buffer
* @ingroup ai_platform
@ -293,6 +376,7 @@ typedef struct ai_buffer_ {
ai_u16 width; /*!< buffer width dimension */
ai_u32 channels; /*!< buffer number of channels */
ai_handle data; /*!< pointer to buffer data */
ai_buffer_meta_info* meta_info; /*!< pointer to buffer metadata info */
} ai_buffer;
/* enums section */

View File

@ -41,46 +41,153 @@
ai_platform_network_set_error((net_), AI_CONCAT(AI_ERROR_,type_), \
AI_CONCAT(AI_ERROR_CODE_,code_))
/******************************************************************************/
/*! AI_PTR HANDLERS SECTION ************************************/
#define AI_PTR(ptr_) ((ai_ptr)(ptr_))
#define AI_PTR_CONST(ptr_) ((ai_ptr_const)(ptr_))
/******************************************************************************/
#define AI_SHAPE_2D_INIT(h, w) \
{ .dimension={ (w), (h) } }
/*! STATIC ARRAYS ALLOCATOR SECTION ************************************/
#define AI_PACK_STORAGE_ARRAY(type_, dim_, ...) \
(type_[dim_]) { AI_PACK(__VA_ARGS__) }
#define AI_SHAPE_ND_INIT(size_, ...) \
{ .size = (ai_size)(size_), \
.dimension = (ai_shape_dimension[]){ __VA_ARGS__ } }
/*! AI_STORAGE_KLASS SECTION ************************************/
#define AI_STORAGE_KLASS_PACK(type_, dim_, ...) \
AI_PACK_STORAGE_ARRAY(type_, dim_, __VA_ARGS__)
#define AI_STORAGE_KLASS_INIT(type_, size_, data_) \
{ \
.type = (type_), \
.size = (size_), \
.data = (ai_handle)(data_), \
}
/*!
* @enum ai_storage_klass_type
* @ingroup ai_platform_interface
* @brief @ref ai_storage_class types enum
*/
typedef enum {
AI_STORAGE_KLASS_SHAPE = 0x0,
AI_STORAGE_KLASS_STRIDE,
AI_STORAGE_KLASS_FLOAT,
AI_STORAGE_KLASS_U8,
AI_STORAGE_KLASS_I8,
AI_STORAGE_KLASS_U16,
AI_STORAGE_KLASS_I16,
AI_STORAGE_KLASS_U32,
AI_STORAGE_KLASS_I32,
AI_STORAGE_KLASS_U64,
AI_STORAGE_KLASS_I64,
} ai_storage_klass_type;
/*!
* @struct ai_storage_klass
* @ingroup ai_platform_interface
* @brief Generic "Template" klass for generic storage arrays containers
* from this klass several typed containers are derived (see e.g. @ref ai_shape)
*/
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_storage_klass_s {
ai_u32 type : 8;
ai_u32 size : 24;
ai_handle data;
} ai_storage_klass;
AI_PACKED_STRUCT_END
/*! AI_SHAPES SECTION ************************************/
#define AI_SHAPE_2D_INIT(w_, h_) \
{ .data = { (w_), (h_) } }
#define AI_SHAPE_INIT(dim_, ...) \
AI_STORAGE_KLASS_INIT( \
AI_STORAGE_KLASS_SHAPE, \
dim_, \
AI_STORAGE_KLASS_PACK(ai_shape_dimension, dim_, ## __VA_ARGS__))
#define AI_SHAPE_INIT_FROM_BUFFER(dim_, buffer_) \
AI_STORAGE_KLASS_INIT( \
AI_STORAGE_KLASS_SHAPE, \
dim_, \
buffer_)
/*!
* @enum ai_shape_type
* @ingroup ai_platform_interface
* @brief Codes for the 4D tensor dimensions
*/
typedef enum {
AI_SHAPE_MAX_DIMENSION = 0x4,
AI_SHAPE_HEIGHT = 0x3,
AI_SHAPE_WIDTH = 0x2,
AI_SHAPE_CHANNEL = 0x1,
AI_SHAPE_IN_CHANNEL = 0x0,
// AI_SHAPE_BATCH_CHANNEL = 0x4,
} ai_shape_type;
/*!
* @struct ai_shape
* @ingroup ai_platform_interface
* @brief Dimensions for generic 4D tensors
*/
#if 1
#if 0
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_shape_s {
ai_u32 type : 8;
ai_u32 size : 24;
ai_shape_dimension data[AI_SHAPE_MAX_DIMENSION]; /*!< 4D tensor shape */
} ai_shape;
AI_PACKED_STRUCT_END
#else
typedef ai_storage_klass ai_shape;
#endif
#else
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_shape_s {
ai_shape_dimension* dimension; /*!< ND tensor shape */
} ai_shape;
AI_PACKED_STRUCT_END
#endif
/*! AI_STRIDES HANDLERS SECTION ************************************/
#define AI_STRIDE_INIT(dim_, ...) \
AI_STORAGE_KLASS_INIT( \
AI_STORAGE_KLASS_STRIDE, \
dim_, \
AI_STORAGE_KLASS_PACK(ai_stride_dimension, dim_, ## __VA_ARGS__))
#define AI_STRIDE_INIT_FROM_BUFFER(dim_, buffer_) \
AI_STORAGE_KLASS_INIT( \
AI_STORAGE_KLASS_STRIDE, \
dim_, \
buffer_)
#define AI_SHAPE_INIT(h, w, ch, in_ch) {.dimension={ (in_ch), (ch), (w), (h) }}
/*!
* @struct ai_stride
* @ingroup ai_platform_interface
* @brief Stride dimensions for generic 4D tensors (in number of elements)
*/
typedef ai_storage_klass ai_stride;
/******************************************************************************/
#define AI_STRIDE_2D_INIT(h, w) \
{ .dimension={ (w), (h) } }
/*! BASIC_TYPES HANDLERS SECTION ************************************/
#define AI_SIZE(value_) \
((ai_size)(value_))
#define AI_STRIDE_ND_INIT(size_, ...) \
{ .size = (ai_size)(size_), \
.dimension = (ai_stride_dimension[]){ __VA_ARGS__ } }
/*! AI_KLASS_OBJ HANDLERS SECTION ************************************/
#define AI_KLASS_OBJ(obj_) \
((ai_klass_obj)(obj_))
#define AI_STRIDE_INIT(h, w, ch, in_ch) \
{ .dimension={ (in_ch), (ch), (w), (h) } }
/******************************************************************************/
#define AI_KLASS_OBJ(obj) \
((ai_klass_obj)(obj))
/*! generic handlers section **************************************************/
/*! GENERIC HANDLERS SECTION ************************************/
#define AI_OBJ_DATA(obj_, type_) \
((type_)(obj_)->data)
/*! ai_buffer handlers section ************************************************/
/*! AI_BUFFER HANDLERS SECTION ************************************/
#define AI_BUFFER_OBJ(ptr) \
((ai_buffer*)(ptr))
/*! ai_array handlers section *************************************************/
/*! AI_ARRAY HANDLERS SECTION ************************************/
#define AI_ARRAY_OBJ(ptr) \
((ai_array*)(ptr))
@ -91,12 +198,12 @@
(AI_ARRAY_OBJ(array_)->size)
#define AI_ARRAY_OBJ_BYTE_SIZE(array_) \
AI_ARRAY_GET_BYTE_SIZE(AI_ARRAY_OBJ(array_)->format, \
AI_ARRAY_OBJ(array_)->size)
AI_SIZE(AI_ARRAY_GET_BYTE_SIZE(AI_ARRAY_OBJ_FMT(array_), \
AI_ARRAY_OBJ_SIZE(array_)))
#define AI_ARRAY_OBJ_DATA_SIZE(array_) \
AI_ARRAY_GET_DATA_BYTE_SIZE(AI_ARRAY_OBJ(array_)->format, \
AI_ARRAY_OBJ(array_)->size)
AI_ARRAY_GET_DATA_BYTE_SIZE(AI_ARRAY_OBJ_FMT(array_), \
AI_ARRAY_OBJ_SIZE(array_))
#define AI_ARRAY_OBJ_DATA(array_, type_) \
((type_*)(AI_ARRAY_OBJ(array_)->data))
@ -104,7 +211,6 @@
#define AI_ARRAY_OBJ_DATA_START(array_, type_) \
((type_*)(AI_ARRAY_OBJ(array_)->data_start))
#define AI_ARRAY_OBJ_ELEM(array_, type_, pos_) \
AI_ARRAY_OBJ_DATA(array_, type_)[(pos_)]
@ -112,39 +218,65 @@
.format = AI_FMT_OBJ(format_), \
.size = (ai_array_size)(size_), \
.data = (ai_ptr)((type_[]){ __VA_ARGS__ }), \
.data_start = (ai_ptr)((type_[]){ __VA_ARGS__ }), \
.data_start = AI_PTR(0), \
}
#define AI_ARRAY_OBJ_DECLARE_STATIC(name_, type_, format_, attr_, size_, ...) \
AI_ALIGNED(4) \
attr_ ai_array name_ = AI_ARRAY_OBJ_INIT_STATIC(type_, format_, size_, __VA_ARGS__);
#define AI_ARRAY_OBJ_INIT(format_, data_, data_start_, size_) { \
.format = AI_FMT_OBJ(format_), \
.size = (ai_array_size)(size_), \
.data = AI_PTR(data_), \
.data_start = AI_PTR(data_start_) }
#define AI_ARRAY_OBJ_DECLARE_STATIC(name_, type_, format_, attr_, size_, ...) \
AI_ALIGNED(4) \
attr_ ai_array name_ = AI_ARRAY_OBJ_INIT_STATIC(type_, format_, size_, __VA_ARGS__);
#define AI_ARRAY_OBJ_DECLARE(name_, format_, data_, data_start_, size_, attr_) \
AI_ALIGNED(4) \
attr_ ai_array name_ = AI_ARRAY_OBJ_INIT(format_, data_, data_start_, size_);
/******************************************************************************/
#define AI_TENSOR_OBJ(ptr) \
((struct ai_tensor_*)(ptr))
/********************************* ai_array macros ***************************/
#define AI_PACK_ARRAYS(...) \
(ai_array[]) { AI_PACK(__VA_ARGS__) }
#define AI_TENSOR_OBJ_INIT(shape_, stride_, data_array_ptr_) { \
.data = AI_ARRAY_OBJ(data_array_ptr_), \
.shape = shape_, \
.stride = stride_, \
#define AI_ARRAY_LIST_OBJ_INIT(arrays_ptr_) \
((ai_array*)(arrays_ptr_))
#define AI_ARRAY_LIST_FLAGS(list_) \
( (list_) ? (list_)->flags : 0x0 )
#define AI_ARRAY_LIST_SIZE(list_) \
( (list_) ? (list_)->size : 0 )
#define AI_ARRAY_LIST_DATA(list_, pos_) \
( (list_) ? &((list_)->data[pos_]) : NULL )
/********************************* ai_tensor macros **************************/
#define AI_TENSOR_OBJ(obj_) \
((ai_tensor*)(obj_))
#define AI_TENSOR_INFO_OBJ_INIT(id_, flags_, data_size_) { \
.id = (id_), \
.flags = (flags_), \
.data_size = (data_size_) \
}
#define AI_TENSOR_OBJ_DECLARE(name_, shape_, stride_, \
data_array_ptr_, attr_) \
#define AI_TENSOR_OBJ_INIT(id_, flags_, shape_, stride_, arrays_size_, arrays_ptr_, klass_obj_) { \
.klass = (ai_klass_obj)(klass_obj_), \
.info = AI_TENSOR_INFO_OBJ_INIT(id_, flags_, arrays_size_), \
.shape = shape_, \
.stride = stride_, \
.data = AI_ARRAY_LIST_OBJ_INIT(AI_PACK(arrays_ptr_)), \
}
#define AI_TENSOR_OBJ_DECLARE(name_, attr_, id_, flags_, shape_, stride_, \
arrays_size_, arrays_ptr_, klass_obj_) \
AI_ALIGNED(4) \
attr_ ai_tensor name_ = AI_TENSOR_OBJ_INIT(AI_PACK(shape_), AI_PACK(stride_), \
data_array_ptr_);
attr_ ai_tensor name_ = AI_TENSOR_OBJ_INIT(id_, flags_, AI_PACK(shape_), AI_PACK(stride_), \
arrays_size_, AI_PACK(arrays_ptr_), AI_PACK(klass_obj_));
/********************************* TENSOR STATE MACROS ***********************/
#define AI_TENSOR_STATE_OBJ_INIT(end_ptr_ , curr_ptr_, stride_, size_) \
@ -152,12 +284,14 @@
/********************************* TENSOR LIST MACROS ************************/
#define AI_TENSOR_LIST_EMPTY \
{ .tensor = (ai_tensor*[]) { NULL }, .info = NULL, \
.size = 0, .flags = AI_FLAG_NONE }
{ .size = 0, .flags = AI_FLAG_NONE, \
.tensor = (ai_tensor*[]) { NULL }, .info = NULL \
}
#define AI_TENSOR_LIST_ENTRY(...) \
{ .tensor = (ai_tensor*[]) { __VA_ARGS__ }, .info = NULL, \
.size = AI_NUMARGS(__VA_ARGS__), .flags = AI_FLAG_NONE }
{ .size = AI_NUMARGS(__VA_ARGS__), .flags = AI_FLAG_NONE, \
.tensor = (ai_tensor*[]) { __VA_ARGS__ }, .info = NULL \
}
#define AI_TENSOR_LIST_OBJ_DECLARE(name_, attr_, ...) \
AI_ALIGNED(4) \
@ -165,24 +299,25 @@
/********************************* TENSOR LIST I/O MACROS ********************/
#define AI_TENSOR_LIST_IO_ENTRY(flags_, size_, ...) \
{ .tensor = (ai_tensor*[]) { __VA_ARGS__ }, \
.info = (ai_tensor_info[1]) { { \
{ .size = (size_), .flags = (flags_), \
.tensor = (ai_tensor*[]) { __VA_ARGS__ }, \
.info = (ai_tensor_list_info[1]) { { \
.buffer = (ai_buffer[size_])AI_STRUCT_INIT, \
.state = (ai_tensor_state[size_])AI_STRUCT_INIT \
} }, \
.size = (size_), \
.flags = (flags_) }
.state = (ai_tensor_state[size_])AI_STRUCT_INIT, \
.meta = (ai_buffer_meta_info[size_])AI_STRUCT_INIT \
} } \
}
/********************************* TENSOR CHAIN MACROS ***********************/
#define AI_TENSOR_CHAIN_OBJ_INIT(flags_, in_, out_, weights_, scratch_) \
{ .chain = (ai_tensor_list[]){ in_, out_, weights_, scratch_ }, \
.size = 4, .flags = (flags_) }
#define AI_TENSOR_CHAIN_OBJ_INIT(flags_, size_, ...) \
{ .size = (size_), .flags = (flags_), \
.chain = (ai_tensor_list[]){ __VA_ARGS__ } }
#define AI_TENSOR_CHAIN_OBJ_DECLARE(name_, attr_, in_, out_, weights_, scratch_) \
#define AI_TENSOR_CHAIN_OBJ_DECLARE(name_, attr_, size_, ...) \
AI_ALIGNED(4) \
attr_ ai_tensor_chain name_ = \
AI_TENSOR_CHAIN_OBJ_INIT(AI_FLAG_NONE, AI_PACK(in_), AI_PACK(out_), \
AI_PACK(weights_), AI_PACK(scratch_));
AI_TENSOR_CHAIN_OBJ_INIT(AI_FLAG_NONE, size_, __VA_ARGS__);
/********************************* TENSOR CHAIN I/O MACROS *******************/
#define AI_TENSOR_CHAIN_IO_OBJ_INIT(flags_, in_tensor_list_, out_tensor_list_) \
@ -196,15 +331,17 @@
AI_TENSOR_CHAIN_IO_OBJ_INIT(flags_, in_tensor_list_, out_tensor_list_);
/******************************* NETWORK SECTION ****************************/
#define AI_NETWORK_OBJ(ptr) ((ai_network*)(ptr))
#define AI_NETWORK_OBJ(obj_) \
((ai_network*)(obj_))
#define AI_NETWORK_OBJ_INIT( \
weights_buffer_, activations_buffer_, \
in_tensor_list_ptr_, out_tensor_list_ptr_, \
in_node_ptr_, signature_) { \
in_node_ptr_, signature_, klass_obj_) { \
.magic = 0x0, \
.signature = signature_, \
.klass = AI_KLASS_OBJ(klass_obj_), \
.flags = AI_FLAG_NONE, \
.error = AI_ERROR_INIT(NONE, NONE), \
.n_batches = 0, \
@ -216,23 +353,23 @@
AI_PACK(out_tensor_list_ptr_)), \
.input_node = AI_NODE_OBJ(in_node_ptr_), \
.current_node = AI_NODE_OBJ(NULL), \
.klass = AI_KLASS_OBJ(NULL) }
}
#define AI_NETWORK_OBJ_DECLARE( \
var_name_, \
name_, attr_, \
weights_buffer_, activations_buffer_, \
in_tensor_list_ptr_, out_tensor_list_ptr_, \
in_node_ptr_, signature_) \
in_node_ptr_, signature_, klass_obj_) \
AI_ALIGNED(4) \
AI_STATIC ai_network var_name_ = AI_NETWORK_OBJ_INIT( \
attr_ ai_network name_ = AI_NETWORK_OBJ_INIT( \
AI_PACK(weights_buffer_), \
AI_PACK(activations_buffer_), \
AI_PACK(in_tensor_list_ptr_), \
AI_PACK(out_tensor_list_ptr_), \
(in_node_ptr_), (signature_));
(in_node_ptr_), (signature_), (klass_obj_));
#define AI_NETWORK_ACQUIRE_CTX(handle) \
AI_NETWORK_OBJ(ai_platform_context_acquire(handle))
#define AI_NETWORK_ACQUIRE_CTX(handle_) \
AI_NETWORK_OBJ(ai_platform_context_acquire(handle_))
/******************************************************************************/
@ -317,82 +454,10 @@ typedef enum {
*/
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_shape_2d_s {
ai_shape_dimension dimension[AI_SHAPE_2D_MAX_DIMENSION]; /*!< 2D tensor dimensions */
ai_shape_dimension data[AI_SHAPE_2D_MAX_DIMENSION]; /*!< 2D tensor dimensions */
} ai_shape_2d;
AI_PACKED_STRUCT_END
/*!
* @struct ai_stride_2d
* @ingroup ai_platform_interface
* @brief Stride dimensions for generic 2D tensors (in number of elements)
*/
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_stride_2d_s {
ai_stride_dimension dimension[AI_SHAPE_2D_MAX_DIMENSION]; /*!< 2D tensor stride */
} ai_stride_2d;
AI_PACKED_STRUCT_END
/*!
* @struct ai_shape_nd
* @ingroup ai_platform_interface
* @brief Dimensions for generic N-dimensional tensors
*/
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_shape_nd_s {
ai_size size; /*!< number of elements in the n-dimensional shape
(NOT number of bytes!). */
ai_shape_dimension* dimension;
} ai_shape_nd;
AI_PACKED_STRUCT_END
/*!
* @struct ai_stride_nd
* @ingroup ai_platform_interface
* @brief Stride dimensions for generic N-dimensional tensors
*/
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_stride_nd_s {
ai_size size; /*!< number of elements in the n-dimensional stride
(NOT number of bytes!). */
ai_stride_dimension* dimension;
} ai_stride_nd;
AI_PACKED_STRUCT_END
/*!
* @enum ai_shape_type
* @ingroup ai_platform_interface
* @brief Codes for the 4D tensor dimensions
*/
typedef enum {
AI_SHAPE_MAX_DIMENSION = 0x4,
AI_SHAPE_HEIGHT = 0x3,
AI_SHAPE_WIDTH = 0x2,
AI_SHAPE_CHANNEL = 0x1,
AI_SHAPE_IN_CHANNEL = 0x0,
// AI_SHAPE_BATCH_CHANNEL = 0x5,
} ai_shape_type;
/*!
* @struct ai_shape
* @ingroup ai_platform_interface
* @brief Dimensions for generic 4D tensors
*/
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_shape_s {
ai_shape_dimension dimension[AI_SHAPE_MAX_DIMENSION]; /*!< 4D tensor dimensions */
} ai_shape;
AI_PACKED_STRUCT_END
/*!
* @struct ai_stride
* @ingroup ai_platform_interface
* @brief Stride dimensions for generic 4D tensors (in number of elements)
*/
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_stride_s {
ai_stride_dimension dimension[AI_SHAPE_MAX_DIMENSION]; /*!< 4D tensor stride */
} ai_stride;
AI_PACKED_STRUCT_END
/*!
* @struct ai_array
@ -402,8 +467,10 @@ AI_PACKED_STRUCT_END
*/
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_array_s {
// ai_u16 flags; /*!< optional flags to store array list attributes */
// ai_u16 id; /*!< ID of the array object */
ai_array_format format; /*!< array format (see @ref ai_array_format) */
ai_array_size size; /*!< number of elements in the array (NOT number
ai_array_size size; /*!< number of elements in the array (NOT number
of bytes!). The size of the array could be
determine using @ref AI_ARRAY_GET_BYTE_SIZE
macro */
@ -412,6 +479,21 @@ typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_array_s {
} ai_array;
AI_PACKED_STRUCT_END
/*!
* @struct ai_tensor_info
* @ingroup ai_platform_interface
* @brief ai_tensor_info info structure for storing size of the array list,
* tensor dimensionality, etc.
*
*/
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_tensor_info_s {
ai_u16 id;
ai_u8 flags;
ai_u8 data_size;
} ai_tensor_info;
AI_PACKED_STRUCT_END
/*!
* @struct ai_tensor
* @ingroup ai_platform_interface
@ -423,9 +505,11 @@ AI_PACKED_STRUCT_END
*/
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_tensor_s {
ai_array* data; /*!< flattened array pointer to tensor data */
ai_klass_obj klass; /*!< opaque pointer to klass context */
ai_tensor_info info; /*!< tensor info metadata see @ref ai_tensor_info)*/
ai_shape shape; /*!< tensor shape see @ref ai_shape */
ai_stride stride; /*!< tensor stride see @ref ai_stride */
ai_array* data; /*!< flattened array pointer to tensor data */
} ai_tensor;
AI_PACKED_STRUCT_END
@ -444,19 +528,59 @@ typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_tensor_state_s {
AI_PACKED_STRUCT_END
/*!
* @struct ai_tensor_info
* @struct ai_tensor_list_info
* @ingroup ai_platform_interface
* @brief info metadata for tensor management (used for I/O network tensors)
* @brief info metadata for tensor list management (used for I/O network tensors)
*/
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_tensor_info_s {
// union {
ai_tensor_state* state;
ai_buffer* buffer;
// };
} ai_tensor_info;
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_tensor_list_info_s {
ai_tensor_state* state; /*!< I/O buffer internal pointers state */
ai_buffer* buffer; /*!< I/O buffer pointer */
ai_buffer_meta_info* meta; /*!< I/O buffer meta informations */
} ai_tensor_list_info;
AI_PACKED_STRUCT_END
/********************************* INTEGER QUANTIZATION DATATYPES ************/
#define AI_INTQ_INFO_OBJ_INIT(flags_, scale_ , zeropoint_) { \
.scale = (scale_), \
.zeropoint = (ai_handle)(zeropoint_), \
.flags = (flags_), \
}
#define AI_PACK_INTQ_INFO_LIST(...) \
(ai_intq_info_list[]) { AI_PACK(__VA_ARGS__) }
#define AI_PACK_INTQ_INFO(scale_, zp_) \
(ai_intq_info[1]) { { .scale = AI_PACK(scale_), \
.zeropoint = AI_PACK(zp_) } }
#define AI_PACK_INTQ_SCALE(...) \
(ai_float[]) { AI_PACK(__VA_ARGS__) }
#define AI_PACK_INTQ_ZP(...) \
(ai_i8[]) { AI_PACK(__VA_ARGS__) }
#define AI_PACK_UINTQ_ZP(...) \
(ai_u8[]) { AI_PACK(__VA_ARGS__) }
#define AI_INTQ_INFO_LIST_OBJ_EMPTY { 0 }
#define AI_INTQ_INFO_LIST_OBJ_INIT(flags_, size_, info_) \
{ \
.flags = (flags_), \
.size = (size_), \
.info = (info_), \
}
#define AI_INTQ_INFO_LIST_OBJ_DECLARE(name_, attr_, ...) \
AI_ALIGNED(4) \
attr_ ai_intq_info_list name_ = \
AI_INTQ_INFO_LIST_OBJ_INIT(AI_FLAG_NONE, __VA_ARGS__);
/********************************* TENSOR CHAINS DATATYPES *******************/
/*!
* @enum ai_tensor_chain_type
@ -478,10 +602,10 @@ typedef enum {
*/
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_tensor_list_s {
ai_tensor** tensor; /*!< array of linked tensor pointer */
ai_tensor_info* info; /*!< pointer to an array of metainfo associated to the tensors */
ai_u16 size; /*!< number of elements in the the tensor list */
ai_u16 flags; /*!< optional flags to store tensor list attributes */
ai_tensor** tensor; /*!< array of linked tensor pointer */
ai_tensor_list_info* info; /*!< pointer to an array of metainfo associated to the tensors */
} ai_tensor_list;
AI_PACKED_STRUCT_END
@ -493,9 +617,9 @@ AI_PACKED_STRUCT_END
*/
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_tensor_chain_s {
ai_tensor_list* chain; /*!< pointer to a 4 sized array see @ref ai_tensor_chain_type */
ai_u16 size;
ai_u16 flags;
ai_tensor_list* chain; /*!< pointer to a 4 sized array see @ref ai_tensor_chain_type */
} ai_tensor_chain;
AI_PACKED_STRUCT_END
@ -510,6 +634,7 @@ struct ai_node_s;
AI_PACKED_STRUCT_START
typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_network_s {
AI_CONTEXT_FIELDS
ai_klass_obj klass; /*!< opaque handler to specific network implementations */
ai_flags flags; /*!< bitflags mask to track some network state info */
ai_error error; /*!< track 1st error code in the network */
@ -522,8 +647,6 @@ typedef AI_ALIGNED_TYPE(struct, 4) AI_PACKED ai_network_s {
struct ai_node_s* input_node; /*!< first node to execute */
struct ai_node_s* current_node; /*!< current node to execute */
ai_klass_obj klass; /*!< opaque handler to specific network implementations */
} ai_network;
AI_PACKED_STRUCT_END

View File

@ -25,7 +25,6 @@
#include "ai_platform.h"
#include "ai_platform_interface.h"
#include "ai_datatypes_internal.h"
#include "core_datatypes.h"
#include "core_log.h"
@ -53,7 +52,7 @@
#define ASSERT_TENSOR_SANITY(t_) \
AI_ASSERT((t_) && (t_)->data) \
AI_ASSERT(ai_shape_get_size(&(t_)->shape)>0) \
AI_ASSERT(CORE_TENSOR_GET_SHAPE_SIZE(t_)>0) \
ASSERT_ARRAY_SANITY((t_)->data)
#define ASSERT_TENSOR_LIST_SANITY(tlist_) \
@ -99,7 +98,7 @@
#define AI_NODE_FORWARD_FUNC(func_) \
((node_forward_func)(func_))
#define AI_NODE_IS_FIRST(node) \
(AI_NODE_OBJ(node)==AI_NODE_OBJ(AI_NODE_OBJ(node)->network->input_node))
@ -110,19 +109,19 @@
#define AI_NODE_COMMON_FIELDS_DECLARE \
ai_node_type type; /*!< node type id (see @ref ai_node_type) */ \
ai_id_obj id; /*!< node object instance id (see @ref ai_id_obj) */ \
ai_klass_obj klass; /*!< opaque handler to specific layer implementations */ \
struct ai_network_s* network; /*!< handle to global network context */ \
struct ai_node_s* next; /*!< the next node object in the sequence */ \
node_forward_func forward; /*!< forward function for the node */ \
ai_klass_obj klass; /*!< opaque handler to specific layer implementations */ \
AI_CONST ai_tensor_chain* tensors; /*!< pointer to node tensor chain */
#define AI_NODE_COMMON_INIT(type_, id_, forward_, next_, network_, klass_) \
#define AI_NODE_COMMON_INIT(type_, id_, forward_, next_, network_, klass_obj_) \
.type = AI_NODE_TYPE(type_), \
.id = AI_ID_OBJ(id_), \
.klass = AI_KLASS_OBJ(klass_obj_), \
.network = AI_NETWORK_OBJ(network_), \
.next = AI_NODE_OBJ(next_), \
.forward = AI_NODE_FORWARD_FUNC(forward_), \
.klass = AI_KLASS_OBJ(klass_), \
.tensors = NULL
#define AI_FOR_EACH_NODE_DO(node_, nodes_) \
@ -132,50 +131,56 @@
/** TENSOR CHAINS LOOP MACROS & GETTERS *************************************/
#define AI_FOR_EACH_TENSOR_CHAIN_DO(tlist_ptr_, chain_) \
ai_tensor_list* tlist_ptr_=(chain_)->chain; \
for ( ; tlist_ptr_<(((chain_)->chain)+GET_TENSOR_CHAIN_SIZE(chain_)); tlist_ptr_++ )
ai_tensor_list* tlist_ptr_ = (chain_)->chain; \
for ( ; tlist_ptr_<(((chain_)->chain)+((chain_)->size)); tlist_ptr_++ )
#define AI_FOR_EACH_TENSOR_LIST_DO(idx_, t_ptr_, tlist_ptr_) \
ai_tensor* t_ptr_ = GET_TENSOR_LIST_ITEM(tlist_ptr_, 0); \
for ( ai_size idx_ = 0; \
idx_ < GET_TENSOR_LIST_SIZE(tlist_ptr_); \
++idx_, t_ptr_ = GET_TENSOR_LIST_ITEM(tlist_ptr_, idx_) )
ai_tensor* t_ptr_ = (GET_TENSOR_LIST_SIZE(tlist_ptr_)>0) \
? GET_TENSOR_LIST_ITEM(tlist_ptr_, 0) : NULL; \
for ( ai_size idx_ = 0; \
idx_ < GET_TENSOR_LIST_SIZE(tlist_ptr_) && \
(t_ptr_ = GET_TENSOR_LIST_ITEM(tlist_ptr_, idx_)) != 0; ++idx_)
#define GET_TENSOR_LIST_INFO(list_) \
( (list_)->info )
( (list_)->info )
#define GET_TENSOR_LIST_META(list_, pos_) \
( &(GET_TENSOR_LIST_INFO(list_)->meta[pos_]) )
#define GET_TENSOR_LIST_STATE(list_, pos_) \
( &(GET_TENSOR_LIST_INFO(list_)->state[pos_]) )
( &(GET_TENSOR_LIST_INFO(list_)->state[pos_]) )
#define GET_TENSOR_LIST_BUFFER(list_, pos_) \
( &(GET_TENSOR_LIST_INFO(list_)->buffer[pos_]) )
( &(GET_TENSOR_LIST_INFO(list_)->buffer[pos_]) )
#define GET_TENSOR_LIST_ITEM(list_, pos_) \
( (list_)->tensor[(pos_)] )
( (NULL!=(list_)->tensor) \
? (list_)->tensor[(pos_)] : NULL )
#define GET_TENSOR_LIST_ITEMS(list_) \
( (list_)->tensor )
( (list_)->tensor )
#define GET_TENSOR_LIST_SIZE(list_) \
( (list_)->size )
( (NULL!=(list_)) ? (list_)->size : 0 )
#define GET_TENSOR_CHAIN_SIZE(chain_) \
( (chain_)->size )
( (NULL!=(chain_)) ? (chain_)->size : 0 )
#define GET_TENSOR_LIST(chain_, type_) \
( &(chain_)->chain[AI_CONCAT(AI_TENSOR_CHAIN_, type_)] )
( (AI_CONCAT(AI_TENSOR_CHAIN_, type_)<(chain_)->size) \
? &(chain_)->chain[AI_CONCAT(AI_TENSOR_CHAIN_, type_)] : NULL )
#define GET_TENSOR_LIST_IN(chain_) \
( GET_TENSOR_LIST(chain_, INPUT) )
( GET_TENSOR_LIST(chain_, INPUT) )
#define GET_TENSOR_LIST_OUT(chain_) \
( GET_TENSOR_LIST(chain_, OUTPUT) )
( GET_TENSOR_LIST(chain_, OUTPUT) )
#define GET_TENSOR_LIST_WEIGTHS(chain_) \
( GET_TENSOR_LIST(chain_, WEIGHTS) )
#define GET_TENSOR_LIST_SCRATCH(chain_) \
( GET_TENSOR_LIST(chain_, SCRATCH) )
( GET_TENSOR_LIST(chain_, SCRATCH) )
#define GET_TENSOR_IN(chain_, pos_) \
( GET_TENSOR_LIST_ITEM(GET_TENSOR_LIST_IN(chain_), (pos_)) )
@ -183,6 +188,12 @@
#define GET_TENSOR_OUT(chain_, pos_) \
( GET_TENSOR_LIST_ITEM(GET_TENSOR_LIST_OUT(chain_), (pos_)) )
#define SET_TENSOR_IN(chain_, pos_) \
( GET_TENSOR_LIST_IN(chain_)->tensor[(pos_)] )
#define SET_TENSOR_OUT(chain_, pos_) \
( GET_TENSOR_LIST_OUT(chain_)->tensor[(pos_)] )
#define GET_TENSOR_WEIGHTS(chain_, pos_) \
( GET_TENSOR_LIST_ITEM(GET_TENSOR_LIST_WEIGTHS(chain_), (pos_)) )

View File

@ -66,33 +66,7 @@ void node_convert(ai_node *pNode);
* @return a condverted stride datastruct
*/
AI_INTERNAL_API
ai_stride core_shape_to_stride(const ai_shape* in);
void core_shape_to_stride(ai_stride* out, const ai_shape* in);
/*!
* @brief Convert a shape 2D struct into a stride struct
* @ingroup core_convert
* @param[in] in a pointer to a shape to convert
* @return a condverted stride datastruct
*/
AI_INTERNAL_API
ai_stride core_shape_2d_to_stride(const ai_shape_2d* in);
/*!
* @brief Convert a shape struct into a ND stride struct (multi dimensional)
* @ingroup core_convert
* @param[in] in a pointer to a shape to convert
* @return a condverted ND stride datastruct
*/
AI_INTERNAL_API
ai_stride_nd core_shape_to_stride_nd(const ai_shape* in);
/*!
* @brief Convert a shape 2D struct into a ND stride struct (multi dimensional)
* @ingroup core_convert
* @param[in] in a pointer to a shape 2D to convert
* @return a condverted ND stride datastruct
*/
AI_INTERNAL_API
ai_stride_nd core_shape_2d_to_stride_nd(const ai_shape_2d* in);
#endif /*__CORE_CONVERT_H_*/

View File

@ -33,7 +33,7 @@
* @brief platform runtime core library version
*/
#define AI_PLATFORM_RUNTIME_MAJOR 4
#define AI_PLATFORM_RUNTIME_MINOR 0
#define AI_PLATFORM_RUNTIME_MINOR 1
#define AI_PLATFORM_RUNTIME_MICRO 0
#define AI_MAGIC_CONTEXT_TOKEN (0xA1C00100) /*!< AI Cool! Magic Token */

View File

@ -29,7 +29,6 @@
#endif
#include "ai_platform.h"
#include "ai_common_config.h"
#include "ai_datatypes_internal.h"
#include "core_common.h"
#include "core_convert.h"
@ -40,19 +39,6 @@
#define AI_OPTIM_FUNC_MP_ARRAY_F32 (0)
/* Basic sanity checks for generic layer datastructs */
#define ASSERT_LAYER_SANITY(l) \
do { \
AI_ASSERT((l)->tensors && (l)->tensors->chain) \
ASSERT_TENSOR_DATA_SANITY(GET_TENSOR_IN((l)->tensors, 0)) \
ASSERT_TENSOR_DATA_SANITY(GET_TENSOR_OUT((l)->tensors, 0)) \
AI_ASSERT(ai_shape_get_size(&GET_TENSOR_IN((l)->tensors, 0)->shape) <= \
GET_TENSOR_IN((l)->tensors, 0)->data->size) \
AI_ASSERT(ai_shape_get_size(&GET_TENSOR_OUT((l)->tensors, 0)->shape) <= \
GET_TENSOR_OUT((l)->tensors, 0)->data->size) \
} while (0);
#define AI_LAYER_OBJ(obj_) \
((ai_layer*)(obj_))

View File

@ -31,7 +31,7 @@
func_nl nl_func; /*!< function pointer to non linear transform */ \
ai_shape_2d filter_stride; /*!< filter stride, how much the filter moves */ \
ai_shape_2d dilation; /*!< dilation value along axis of the filter */ \
ai_shape_nd filter_pad; /*!< filter pad 4d */
ai_shape filter_pad; /*!< filter pad 4d */
/*!
* @defgroup layers_conv2d Convolutive Layers Definitions
@ -87,7 +87,7 @@ typedef AI_ALIGNED_TYPE(struct, 4) ai_layer_conv2d_nl_pool_ {
ai_shape_2d pool_size; /*!< pooling size */
ai_shape_2d pool_stride; /*!< pooling stride */
ai_shape_nd pool_pad; /*!< pooling pad */
ai_shape pool_pad; /*!< pooling pad */
func_pool pool_func; /*!< function pointer to pooling transform */
} ai_layer_conv2d_nl_pool;
@ -165,6 +165,32 @@ void forward_conv2d_fixed(ai_layer *pLayer);
AI_INTERNAL_API
void forward_conv2d_nl_pool_fixed(ai_layer *pLayer);
/*!
* @brief Computes the activations of a integer quantized 2D convolutional layer.
* @ingroup layers_conv2d
* @param layer the convolutional (conv) layer
*/
AI_INTERNAL_API
void forward_conv2d_integer(ai_layer *pLayer);
/*!
* @brief Computes the activations of a integer @ref ai_layer_conv2d_nl_pool layer.
* The @ref ai_layer_conv2d_nl_pool is a fused conv2D + optional nonlinear
* layer + optional pooling / nonlinearity (average, max)
* @ingroup layers_conv2d
* @param layer see @ai_layer_conv2d_nl_pool
*/
AI_INTERNAL_API
void forward_conv2d_nl_pool_integer(ai_layer *pLayer);
/*!
* @brief Computes the activations of a integer dense (fully connected) layer.
* @ingroup layers_dense
* @param layer the dense layer
*/
AI_INTERNAL_API
void forward_dense_integer(ai_layer *pLayer);
AI_API_DECLARE_END
#endif /*__LAYERS_CONV2D_H_*/

View File

@ -30,14 +30,6 @@
*
*/
#define AI_ASSERT_SHAPE_MATCH(x,y) \
do{\
AI_ASSERT(AI_SHAPE_H(y) == 1 || AI_SHAPE_H(x)==1 || AI_SHAPE_H(y)==AI_SHAPE_H(x))\
AI_ASSERT(AI_SHAPE_W(y) == 1 || AI_SHAPE_W(x)==1 || AI_SHAPE_W(y)==AI_SHAPE_W(x))\
AI_ASSERT(AI_SHAPE_CH(y) == 1 || AI_SHAPE_CH(x)==1|| AI_SHAPE_CH(y)==AI_SHAPE_CH(x))\
AI_ASSERT(AI_SHAPE_IN_CH(y) == 1 || AI_SHAPE_IN_CH(x)==1|| AI_SHAPE_IN_CH(y)==AI_SHAPE_IN_CH(x))\
}while(0)
AI_API_DECLARE_BEGIN
/*!
@ -96,18 +88,6 @@ typedef AI_ALIGNED_TYPE(struct, 4) ai_layer_slice_ {
AI_CONST ai_array* ends; /*!< Ending indices (exclusive) of corrisponding axis in axes*/
} ai_layer_slice;
/*!
* @struct ai_layer_transpose
* @ingroup layers_generic
* @brief Transpose layer definition
*
* This layer defines the params of a transpose layer. It is intended to be used
* by his associated forward function @ref forward_transpose
*/
typedef AI_ALIGNED_TYPE(struct, 4) ai_layer_transpose_ {
AI_LAYER_COMMON_FIELDS_DECLARE
ai_array* perm; /*!< Axes permutation order */
} ai_layer_transpose;
/*!
* @struct ai_layer_tile
@ -164,7 +144,7 @@ typedef AI_ALIGNED_TYPE(struct, 4) ai_layer_instanceNormaization_{
typedef AI_ALIGNED_TYPE(struct, 4) ai_layer_pad_{
AI_LAYER_COMMON_FIELDS_DECLARE
ai_pad_mode mode; /*!< pad mode */
ai_shape_nd pads; /*!< Number of padding to add or remove at the beginning and end of each axis */
ai_shape pads; /*!< Number of padding to add or remove at the beginning and end of each axis */
ai_float value; /*!< Indicates the value to be filled */
} ai_layer_pad;
/*!
@ -187,17 +167,17 @@ typedef AI_ALIGNED_TYPE(struct, 4) ai_layer_add_ {
} ai_layer_add;
/*!
* @struct ai_layer_permute
* @struct ai_layer_transpose
* @ingroup layers_generic
* @brief Permute layer datastruct declaration. This defines the params of a
* permute layer. It is intended to be used by his associated forward function
* @ref forward_permute
* @brief Transpose layer datastruct declaration. This defines the params of a
* transpose layer. It is intended to be used by his associated forward function
* @ref forward_transpose
*/
typedef AI_ALIGNED_TYPE(struct, 4) ai_layer_permute_ {
typedef AI_ALIGNED_TYPE(struct, 4) ai_layer_transpose_ {
AI_LAYER_COMMON_FIELDS_DECLARE
ai_shape out_mapping; /*!< permute output mapping order, i.e. it is a
ai_shape out_mapping; /*!< transpose output mapping order. I.e. tt is a
permutation of the input tensor shape */
} ai_layer_permute;
} ai_layer_transpose;
#define AI_TIME_DISTRIBUTED_AXIS (AI_SHAPE_HEIGHT)
@ -286,13 +266,13 @@ AI_INTERNAL_API
void forward_add(ai_layer* layer);
/*!
* @brief Permute a tensor along a pivot and save permuted values into an output
* @brief Transpose a tensor along a pivot and save transposed values into an output
* tensor
* @ingroup layers_generic
* @param layer the permute layer
* @param layer the transpose layer
*/
AI_INTERNAL_API
void forward_permute(ai_layer* layer);
void forward_transpose(ai_layer* layer);
/*!
* @brief TimeDistrubuted forward layer function. This forward function
@ -320,14 +300,6 @@ void forward_concat(ai_layer* layer);
AI_INTERNAL_API
void forward_slice(ai_layer* layer);
/*!
* @brief Transpose an input tensor
* @ingroup layers_generic
* @param layer the transposed layer
*/
AI_INTERNAL_API
void forward_transpose(ai_layer* layer);
/*!
* @brief Tile an input tensors
* @ingroup layers_generic
@ -368,14 +340,6 @@ void forward_upsample(ai_layer* layer);
AI_INTERNAL_API
void forward_instanceNormalization(ai_layer* layer);
/*!
* @brief Hardmax on an input tensors
* @ingroup layers_generic
* @param layer the hardmax layer
*/
AI_INTERNAL_API
void forward_hardmax(ai_layer* layer);
/*!
* @brief Apply an elementwise transformation to the input tensors
* @ingroup layers_generic
@ -392,6 +356,16 @@ void forward_eltwise(ai_layer* layer);
AI_INTERNAL_API
void forward_reduce(ai_layer* layer);
/*!
* @brief Apply an elementwise addition to the input tensors
* @ingroup layers_generic
* @param layer the elementwise layer
*/
AI_INTERNAL_API
void forward_add_integer(ai_layer* layer);
AI_API_DECLARE_END
#endif /*__LAYERS_GENERIC_H_*/

View File

@ -51,8 +51,8 @@ LAYER_ENTRY(NL, 10009, ai_layer_nl, NULL)
LAYER_ENTRY(NORM, 10010, ai_layer_norm, forward_norm)
/*!< Merged Conv2d / Pool layer */
LAYER_ENTRY(OPTIMIZED_CONV2D, 10011, ai_layer_conv2d_nl_pool, forward_conv2d_nl_pool)
/*!< Permute Tensor layer */
LAYER_ENTRY(PERMUTE, 10012, ai_layer_permute, forward_permute)
/*!< Transpose Tensor layer */
LAYER_ENTRY(TRANSPOSE, 10012, ai_layer_transpose, forward_transpose)
/*!< Pooling layer */
LAYER_ENTRY(POOL, 10013, ai_layer_pool, forward_pool)
/*!< Softmax layer */

View File

@ -51,7 +51,7 @@ typedef AI_ALIGNED_TYPE(struct, 4) ai_layer_nl_ {
* this function pointer abstracts a generic non linear layer.
* see @ref nl_func_tanh_array_f32 and similar as examples.
*/
typedef void (*func_nl)(ai_handle out, const ai_handle in,
typedef void (*func_nl)(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
@ -63,7 +63,7 @@ typedef void (*func_nl)(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_sm_channel_f32(ai_handle out, const ai_handle in,
void nl_func_sm_channel_f32(ai_array *out, const ai_array *in,
const ai_size channel_size, const ai_handle params);
/*!
@ -77,7 +77,7 @@ void nl_func_sm_channel_f32(ai_handle out, const ai_handle in,
* @param out_channel_step number of elements to move to next output element
*/
AI_INTERNAL_API
void nl_func_sm_array_f32(ai_handle out, const ai_handle in,
void nl_func_sm_array_f32(ai_array *out, ai_array *in,
const ai_size in_size,
const ai_size channel_size,
const ai_size in_channel_step,
@ -92,7 +92,7 @@ void nl_func_sm_array_f32(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_tanh_array_f32(ai_handle out, const ai_handle in,
void nl_func_tanh_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
@ -104,7 +104,7 @@ void nl_func_tanh_array_f32(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_tanh_array_fixed(ai_handle out, const ai_handle in,
void nl_func_tanh_array_fixed(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
@ -117,7 +117,7 @@ void nl_func_tanh_array_fixed(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_sigmoid_array_f32(ai_handle out, const ai_handle in,
void nl_func_sigmoid_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
@ -129,7 +129,7 @@ void nl_func_sigmoid_array_f32(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_sigmoid_array_fixed(ai_handle out, const ai_handle in,
void nl_func_sigmoid_array_fixed(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
@ -142,9 +142,225 @@ void nl_func_sigmoid_array_fixed(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_hard_sigmoid_array_f32(ai_handle out, const ai_handle in,
void nl_func_hard_sigmoid_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the absolute value function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_abs_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the cosine function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_cos_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the inverse cosine function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_acos_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the hyperbolic cosine function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_cosh_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the inverse hyperbolic cosine function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_acosh_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the sine function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_sin_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the inverse sine function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_asin_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the hyperbolic sine function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_sinh_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the inverse hyperbolic sine function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_asinh_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the tangent function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_tan_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the inverse tangent function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_atan_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the inverse hyperbolic tangent function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_atanh_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the error function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_erf_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the natural logarithm function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_log_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the reciprocal square root function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_rsqrt_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the floor function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_floor_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the ceil function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_ceil_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the rounding function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_round_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the exponential function on a float data array
* @ingroup layers_nl
@ -154,9 +370,33 @@ void nl_func_hard_sigmoid_array_f32(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_exp_array_f32(ai_handle out, const ai_handle in,
void nl_func_exp_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the sign negation function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_neg_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the reciprocal function on a float data array
* @ingroup layers_nl
* @param in opaque handler to float, size should be 1
* @param out opaque handler to float output elem
* @param size number of elements in the input buffer
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_reciprocal_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the square root function on a float data array
* @ingroup layers_nl
@ -166,7 +406,7 @@ void nl_func_exp_array_f32(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_sqrt_array_f32(ai_handle out, const ai_handle in,
void nl_func_sqrt_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
@ -177,7 +417,7 @@ void nl_func_sqrt_array_f32(ai_handle out, const ai_handle in,
* @param size number of elements in the input buffer
*/
AI_INTERNAL_API
void nl_func_soft_plus_array_f32(ai_handle out, const ai_handle in,
void nl_func_soft_plus_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
@ -189,7 +429,7 @@ void nl_func_soft_plus_array_f32(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_soft_sign_array_f32(ai_handle out, const ai_handle in,
void nl_func_soft_sign_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
@ -200,7 +440,7 @@ void nl_func_soft_sign_array_f32(ai_handle out, const ai_handle in,
* @param size number of elements in the input buffer
*/
AI_INTERNAL_API
void nl_func_sign_array_f32(ai_handle out, const ai_handle in,
void nl_func_sign_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
@ -212,7 +452,7 @@ void nl_func_sign_array_f32(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_clip_array_f32(ai_handle out, const ai_handle in,
void nl_func_clip_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
@ -223,7 +463,7 @@ void nl_func_clip_array_f32(ai_handle out, const ai_handle in,
* @param axis direction of the max index to be searched
*/
AI_INTERNAL_API
void nl_func_hardmax_array_f32(ai_handle out, const ai_handle in,
void nl_func_hardmax_array_f32(ai_array *out, const ai_array *in,
const ai_shape *shape, const ai_handle params);
/*!
@ -235,7 +475,7 @@ void nl_func_hardmax_array_f32(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_relu_generic_array_f32(ai_handle out, const ai_handle in,
void nl_func_relu_generic_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
@ -247,7 +487,7 @@ void nl_func_relu_generic_array_f32(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_relu_thresholded_array_f32(ai_handle out, const ai_handle in,
void nl_func_relu_thresholded_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
@ -259,7 +499,7 @@ void nl_func_relu_thresholded_array_f32(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_relu_array_f32(ai_handle out, const ai_handle in,
void nl_func_relu_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
@ -271,9 +511,19 @@ void nl_func_relu_array_f32(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_relu_array_fixed(ai_handle out, const ai_handle in,
void nl_func_relu_array_fixed(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the activation function on an integer-quantized data array
* @ingroup layers_nl
* @param in opaque handler to input elements to process
* @param out opaque handler to output elements
* @param size total size (number of elements) to process on the input
* @param params opaque handler to generated and used LUT
*/
void nl_func_array_integer(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
* @brief Computes the elu function on a float data array
@ -284,7 +534,7 @@ void nl_func_relu_array_fixed(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_elu_array_f32(ai_handle out, const ai_handle in,
void nl_func_elu_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
@ -296,7 +546,7 @@ void nl_func_elu_array_f32(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_relu_max_array_fixed(ai_handle out, const ai_handle in,
void nl_func_relu_max_array_fixed(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
@ -308,7 +558,7 @@ void nl_func_relu_max_array_fixed(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_selu_array_f32(ai_handle out, const ai_handle in,
void nl_func_selu_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
/*!
@ -321,7 +571,7 @@ void nl_func_selu_array_f32(ai_handle out, const ai_handle in,
* @param params opaque handler to optional nl parameters
*/
AI_INTERNAL_API
void nl_func_prelu_array_f32(ai_handle out, const ai_handle in,
void nl_func_prelu_array_f32(ai_array *out, const ai_array *in,
const ai_size size, const ai_handle params);
@ -345,6 +595,15 @@ void forward_relu(ai_layer* layer);
AI_INTERNAL_API
void forward_relu_fixed(ai_layer *pLayer);
#if 0
/*!
* @brief Computes the activations of a integer-quantized ReLU nonlinear layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_relu_integer(ai_layer *pLayer);
#endif
/*!
* @brief Computes the activations of a ReLU6 nonlinear layer.
@ -419,7 +678,6 @@ void forward_sigmoid(ai_layer* layer);
AI_INTERNAL_API
void forward_sigmoid_fixed(ai_layer *pLayer);
/*!
* @brief Computes the activations of a hard sigmoid nonlinear layer.
* @ingroup layers_nl
@ -460,6 +718,86 @@ void forward_soft_plus(ai_layer* layer);
AI_INTERNAL_API
void forward_soft_sign(ai_layer* layer);
/*!
* @brief Computes the activations of a cosine (cos) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_cos(ai_layer* layer);
/*!
* @brief Computes the activations of a inverse cosine (acos) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_acos(ai_layer* layer);
/*!
* @brief Computes the activations of a hyperbolic cosine (cosh) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_cosh(ai_layer* layer);
/*!
* @brief Computes the activations of a inverse hyperbolic cosine (acosh) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_acosh(ai_layer* layer);
/*!
* @brief Computes the activations of a sine (sin) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_sin(ai_layer* layer);
/*!
* @brief Computes the activations of a inverse sine (asin) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_asin(ai_layer* layer);
/*!
* @brief Computes the activations of a hyperbolic sine (sinh) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_sinh(ai_layer* layer);
/*!
* @brief Computes the activations of a inverse hyperbolic sine (asinh) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_asinh(ai_layer* layer);
/*!
* @brief Computes the activations of a tangent (tan) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_tan(ai_layer* layer);
/*!
* @brief Computes the activations of a inverse tangent (atan) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_atan(ai_layer* layer);
/*!
* @brief Computes the activations of a hyperbolic tangent (tanh) layer.
* @ingroup layers_nl
@ -468,6 +806,14 @@ void forward_soft_sign(ai_layer* layer);
AI_INTERNAL_API
void forward_tanh(ai_layer* layer);
/*!
* @brief Computes the activations of a inverse hyperbolic tangent (atanh) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_atanh(ai_layer* layer);
/*!
* @brief Computes the activations of a fixed point tanh nonlinear layer.
* @ingroup layers_nl
@ -476,6 +822,85 @@ void forward_tanh(ai_layer* layer);
AI_INTERNAL_API
void forward_tanh_fixed(ai_layer *pLayer);
/*!
* @brief Computes the activations of a error function (erf) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_erf(ai_layer* layer);
/*!
* @brief Computes the activations of a natural logarithm (log) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_log(ai_layer* layer);
/*!
* @brief Computes the activations of a reciprocal square root (rsqrt) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_rsqrt(ai_layer* layer);
/*!
* @brief Computes the activations of an absolute value (abs) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_abs(ai_layer* layer);
/*!
* @brief Computes the activations of a ceil layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_ceil(ai_layer* layer);
/*!
* @brief Computes the activations of a floor layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_floor(ai_layer* layer);
/*!
* @brief Computes the activations of a rounding layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_round(ai_layer* layer);
/*!
* @brief Computes the activations of a sign negation (neg) layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_neg(ai_layer* layer);
/*!
* @brief Computes the activations of a reciprocal layer.
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_reciprocal(ai_layer* layer);
/*!
* @brief Hardmax on an input tensors
* @ingroup layers_generic
* @param layer the hardmax layer
*/
AI_INTERNAL_API
void forward_hardmax(ai_layer* layer);
/*!
* @brief Computes the activations of a softmax nonlinear layer.
@ -485,6 +910,15 @@ void forward_tanh_fixed(ai_layer *pLayer);
AI_INTERNAL_API
void forward_sm(ai_layer* layer);
/*!
* @brief Computes the activations of an integer quantized nonlinear layer.
* Non linear operation is function of used LUT defined through
* (pLayer->nl_params->data)
* @ingroup layers_nl
* @param layer the nonlinear (nl) layer
*/
AI_INTERNAL_API
void forward_nl_integer(ai_layer *pLayer);
AI_API_DECLARE_END

View File

@ -43,7 +43,7 @@ typedef AI_ALIGNED_TYPE(struct, 4) ai_layer_pool_ {
AI_LAYER_COMMON_FIELDS_DECLARE
ai_shape_2d pool_size; /*!< pooling size */
ai_shape_2d pool_stride; /*!< pooling stride */
ai_shape_nd pool_pad; /*!< pooling pad, y,x border sizes */
ai_shape pool_pad; /*!< pooling pad, y,x border sizes */
ai_u8 count_include_pad; /*!< include pad flag */
} ai_layer_pool;
@ -119,6 +119,33 @@ void pool_func_mp_array_fixed(ai_handle in,
const ai_u16 dim_im_out_x, const ai_u16 dim_im_out_y,
ai_handle out);
/*!
* @brief Max Pooling on a 8-bits integer quantized data array
* @ingroup layers_pool
* @param in opaque handler to input data to process
* @param dim_im_in_x input feature map width
* @param dim_im_in_y input feature map height
* @param ch_im_in number of input channels
* @param dim_kernel_x kernel width
* @param dim_kernel_y kernel height
* @param padding_x right padding value
* @param padding_y top padding value
* @param stride_x stride value on x dimension
* @param stride_y stride value on y dimension
* @param dim_im_out_x output feature map width
* @param dim_im_out_y output feature map height
* @param out opaque handler to output data
*/
AI_INTERNAL_API
void pool_func_mp_array_integer(ai_handle in,
const ai_u16 dim_im_in_x, const ai_u16 dim_im_in_y,
const ai_u16 ch_im_in,
const ai_u16 dim_kernel_x, const ai_u16 dim_kernel_y,
const ai_u16 padding_x, const ai_u16 padding_y,
const ai_u16 stride_x, const ai_u16 stride_y,
const ai_u16 dim_im_out_x, const ai_u16 dim_im_out_y,
ai_handle out);
/*!
* @brief Average Pooling on a float data array
* @ingroup layers_pool
@ -146,7 +173,6 @@ void pool_func_ap_array_f32(ai_handle in,
const ai_u16 dim_im_out_x, const ai_u16 dim_im_out_y,
ai_handle out);
/*!
* @brief Average Pooling on a 8/16 bits fixed point data array
* @ingroup layers_pool
@ -174,7 +200,34 @@ void pool_func_ap_array_fixed(ai_handle in,
const ai_u16 dim_im_out_x, const ai_u16 dim_im_out_y,
ai_handle out);
/*!
* @brief Average Pooling on a 8-bits integer quantized data array
* @ingroup layers_pool
* @param in opaque handler to input data to process
* @param dim_im_in_x input feature map width
* @param dim_im_in_y input feature map height
* @param ch_im_in number of input channels
* @param dim_kernel_x kernel width
* @param dim_kernel_y kernel height
* @param padding_x right padding value
* @param padding_y top padding value
* @param stride_x stride value on x dimension
* @param stride_y stride value on y dimension
* @param dim_im_out_x output feature map width
* @param dim_im_out_y output feature map height
* @param out opaque handler to scratch memory
*/
AI_INTERNAL_API
void pool_func_ap_array_integer(ai_handle in,
const ai_u16 dim_im_in_x, const ai_u16 dim_im_in_y,
const ai_u16 ch_im_in,
const ai_u16 dim_kernel_x, const ai_u16 dim_kernel_y,
const ai_u16 padding_x, const ai_u16 padding_y,
const ai_u16 stride_x, const ai_u16 stride_y,
const ai_u16 dim_im_out_x, const ai_u16 dim_im_out_y,
ai_handle out);
/******************************************************************************/
/* Forward Functions Section */
/******************************************************************************/
@ -195,6 +248,13 @@ void forward_mp(ai_layer* layer);
AI_INTERNAL_API
void forward_mp_fixed(ai_layer *pLayer);
/*!
* @brief Computes the activations of an integer-quantized max pooling layer.
* @ingroup layers_pool
* @param layer the pooling (pool) layer
*/
AI_INTERNAL_API
void forward_mp_integer(ai_layer *pLayer);
/*!
* @brief Computes the activations of an average pooling layer.
@ -212,6 +272,14 @@ void forward_ap(ai_layer* layer);
AI_INTERNAL_API
void forward_ap_fixed(ai_layer *pLayer);
/*!
* @brief Computes the activations of an integer-quantized average pooling layer.
* @ingroup layers_pool
* @param layer the pooling (pool) layer
*/
AI_INTERNAL_API
void forward_ap_integer(ai_layer *pLayer);
AI_API_DECLARE_END
#endif /*__LAYERS_POOL_H_*/

Binary file not shown.

View File

@ -14,7 +14,7 @@ Starting from a trained network model, such as a *.h5 saved model* from Keras, C
> Note: It is recommended to use Linux to build the firmware. Even if it is still possible to do it with Windows, you may run into some issues, for example because of symbolic links in the project. If you're on Windows, you can use [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/install-win10), it will provide a full Linux environnement and the compilation will be painless.
- stm32ai command line to generate the optimized code. [Download from ST website]( https://www.st.com/en/embedded-software/x-cube-ai.html)
- stm32ai command line to generate the optimized code. **Version 4.1.0** [Download from ST website]( https://www.st.com/en/embedded-software/x-cube-ai.html)
If you have the extension already enabled in Cube.MX, just add
`<home>/STM32Cube/Repository/Packs/STMicroelectronics/X-CUBE-AI/<version>/Utilities/<operating-system>/`

View File

@ -25,4 +25,4 @@ FIRM_OBJ += $(addprefix $(BUILD)/stm32cubeai/,\
py_st_nn.o \
)
FIRM_OBJ += -l:NetworkRuntime400_CM7_GCC.a -Lstm32cubeai/AI/Lib -lc -lm
FIRM_OBJ += -l:NetworkRuntime410_CM7_GCC.a -Lstm32cubeai/AI/Lib -lc -lm