mirror of
https://github.com/openmv/openmv.git
synced 2025-11-04 14:49:50 +08:00
504 lines
17 KiB
C
504 lines
17 KiB
C
/**
|
|
******************************************************************************
|
|
* @file ll_aton_lib.h
|
|
* @author SRA Artificial Intelligence & Embedded Architectures
|
|
* @brief Header file of ATON LL low level lib module.
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* Copyright (c) 2024 STMicroelectronics.
|
|
* All rights reserved.
|
|
*
|
|
* This software is licensed under terms that can be found in the LICENSE file
|
|
* in the root directory of this software component.
|
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
|
*
|
|
******************************************************************************
|
|
*/
|
|
|
|
#ifndef __LL_ATON_LIB_H
|
|
#define __LL_ATON_LIB_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C"
|
|
{
|
|
#endif
|
|
|
|
#include "ll_aton.h"
|
|
#include "ll_aton_NN_interface.h"
|
|
#include "ll_aton_caches_interface.h"
|
|
#include "ll_aton_lib_sw_operators.h"
|
|
|
|
#ifndef _LL_LIB_DEBUG
|
|
#define _LL_LIB_DEBUG 1
|
|
#endif
|
|
|
|
#if _LL_LIB_DEBUG
|
|
/**
|
|
* * @brief library error helper types, functions, and macros
|
|
* */
|
|
enum __ll_lib_errors
|
|
{
|
|
_ERR_UNKNOWN = 0,
|
|
_ERR_NINPUTS,
|
|
_ERR_NOUTPUTS,
|
|
_ERR_AXIS,
|
|
_ERR_FRACTIONAL,
|
|
_ERR_DATATYPE,
|
|
_ERR_NBITS,
|
|
_ERR_NBITS_IN,
|
|
_ERR_NBITS_OUT,
|
|
_ERR_SHAPE,
|
|
_ERR_SHAPE_IN,
|
|
_ERR_SHAPE_OUT,
|
|
_ERR_BUFFER,
|
|
_ERR_BUFFER_IN,
|
|
_ERR_BUFFER_OUT,
|
|
_ERR_RANK,
|
|
_ERR_MODE,
|
|
};
|
|
|
|
/* Forward declaration for global function to be used only by `ll_lib` library */
|
|
extern void __ll_lib_error(int err_code, int line, const char *func);
|
|
|
|
#define __LL_LIB_ERROR(_x, _y) \
|
|
{ \
|
|
__ll_lib_error(_x, __LINE__, __FUNCTION__); \
|
|
return _y; \
|
|
}
|
|
#else // !_LL_LIB_DEBUG
|
|
#define __LL_LIB_ERROR(_x, _y) return _y
|
|
#endif // !_LL_LIB_DEBUG
|
|
|
|
#if 0
|
|
/**
|
|
* * @brief tensor data type info structure
|
|
* */
|
|
/* Note: the data type values match ONNX TensorProto.DataType enum */
|
|
typedef enum
|
|
{
|
|
TENSORINFO_DATATYPE_UNDEFINED = 0,
|
|
TENSORINFO_DATATYPE_FLOAT = 1,
|
|
TENSORINFO_DATATYPE_UINT8 = 2,
|
|
TENSORINFO_DATATYPE_INT8 = 3,
|
|
TENSORINFO_DATATYPE_UINT16 = 4,
|
|
TENSORINFO_DATATYPE_INT16 = 5,
|
|
TENSORINFO_DATATYPE_INT32 = 6,
|
|
TENSORINFO_DATATYPE_INT64 = 7,
|
|
TENSORINFO_DATATYPE_STRING = 8,
|
|
TENSORINFO_DATATYPE_BOOL = 9,
|
|
TENSORINFO_DATATYPE_FLOAT16 = 10,
|
|
TENSORINFO_DATATYPE_DOUBLE = 11,
|
|
TENSORINFO_DATATYPE_UINT32 = 12,
|
|
TENSORINFO_DATATYPE_UINT64 = 13,
|
|
TENSORINFO_DATATYPE_COMPLEX64 = 14,
|
|
TENSORINFO_DATATYPE_COMPLEX128 = 15,
|
|
TENSORINFO_DATATYPE_BFLOAT16 = 16,
|
|
TENSORINFO_DATATYPE_QMN = 100, // ATONN specific
|
|
} LL_LIB_TensorInfo_DataType_TypeDef;
|
|
|
|
/**
|
|
* * @brief tensor info structure
|
|
* */
|
|
typedef struct
|
|
{
|
|
ll_aton_pointer addr_base;
|
|
int offset_start;
|
|
int offset_end;
|
|
int batches; // not sure we'll support this!!!
|
|
int nchannels;
|
|
int fwidth;
|
|
int fheight;
|
|
int ndims;
|
|
int nbits;
|
|
int Qm;
|
|
int Qn;
|
|
int Qunsigned;
|
|
int dtype; // it's a LL_LIB_TensorInfo_DataType_TypeDef
|
|
} LL_LIB_TensorInfo_TypeDef;
|
|
|
|
typedef LL_Buffer_InfoTypeDef LL_LIB_TensorInfo_TypeDef;
|
|
|
|
#define _TDIM(x) ((x) != 0 ? (x) : 1)
|
|
#define LL_LIB_TENSOR_ELEMENTS(t) \
|
|
(_TDIM((t)->batches) * _TDIM((t)->fwidth) * _TDIM((t)->fheight) * _TDIM((t)->nchannels))
|
|
#else
|
|
/* ATON canonical positions */
|
|
#define TDIM_NKERNELS 0
|
|
#define TDIM_FHEIGHT 1
|
|
#define TDIM_FWIDTH 2
|
|
#define TDIM_NCHANNELS 3
|
|
|
|
#define _TDIM(x) ((x) != 0 ? (x) : 1)
|
|
|
|
typedef LL_Buffer_InfoTypeDef LL_LIB_TensorInfo_TypeDef;
|
|
|
|
#if 0
|
|
#define LL_LIB_TENSOR_ELEMENTS(t) \
|
|
(_TDIM((t)->shape[TDIM_NKERNELS]) * _TDIM((t)->shape[TDIM_FWIDTH]) * _TDIM((t)->shape[TDIM_FHEIGHT]) * \
|
|
_TDIM((t)->shape[TDIM_NCHANNELS]))
|
|
#else
|
|
int LL_LIB_TENSOR_ELEMENTS(const LL_LIB_TensorInfo_TypeDef *t);
|
|
#endif
|
|
|
|
/* ONNX canonical positions */
|
|
#define TDIM_ONNX_NKERNELS 0
|
|
#define TDIM_ONNX_NCHANNELS 1
|
|
#define TDIM_ONNX_FHEIGHT 2
|
|
#define TDIM_ONNX_FWIDTH 3
|
|
#endif
|
|
|
|
/**
|
|
* * @brief Heap typedefs
|
|
* */
|
|
typedef struct
|
|
{
|
|
/* Generic fields common to all cases */
|
|
LL_Streng_TensorInitTypeDef g_dma_in;
|
|
LL_Streng_TensorInitTypeDef g_dma_out;
|
|
|
|
/* Generic fields common at least for two cases */
|
|
int g_idx;
|
|
int g_size;
|
|
|
|
unsigned char *g_dst_o_src;
|
|
unsigned int g_offset_limit;
|
|
unsigned int g_not_continuous; // 0 or 1 used by batched version of memcpy
|
|
|
|
unsigned int g_num_tensors;
|
|
const void *g_tensors;
|
|
|
|
uint32_t g_wait_mask;
|
|
|
|
/* Special field(s) for single cases */
|
|
union
|
|
{
|
|
/* Concat_Case3 */
|
|
struct
|
|
{
|
|
unsigned int outer_idx;
|
|
unsigned int in_fheight;
|
|
unsigned int nbytes;
|
|
unsigned int out_line_size;
|
|
unsigned char *in_curr;
|
|
} concat_case3;
|
|
/* Pad */
|
|
__ll_pad_sw_params_t pad;
|
|
} special;
|
|
} __ll_lib_params_t;
|
|
|
|
typedef union
|
|
{
|
|
uint32_t _alignment; // align `__ll_lib_params_t` to 4 bytes
|
|
__ll_lib_params_t heap_params;
|
|
} __ll_lib_params_align_t;
|
|
|
|
typedef union
|
|
{
|
|
uint32_t _alignment; // align `LL_Buffer_InfoTypeDef` to 4 bytes
|
|
LL_Buffer_InfoTypeDef buffer_info;
|
|
} __ll_lib_buffer_align_t;
|
|
|
|
/* "Heap" dedicated for the implementation of HW-accelerated operators,
|
|
* based on maximum number of tensors to be supported */
|
|
#define __LL_MAX_TENSORS 24
|
|
|
|
#define __LL_LOWER_HEAP_SIZE ((sizeof(__ll_lib_buffer_align_t) * __LL_MAX_TENSORS) / sizeof(uint32_t)) // in words
|
|
#define __LL_LIB_HEAP_SIZE ((sizeof(__ll_lib_params_align_t) / sizeof(uint32_t)) + __LL_LOWER_HEAP_SIZE) // in words
|
|
|
|
#ifndef offsetof
|
|
#define offsetof(st, m) ((size_t) & (((st *)0)->m))
|
|
#endif
|
|
|
|
#define __LL_DMA_PAD_MAX_DIMS \
|
|
((__LL_LOWER_HEAP_SIZE * sizeof(uint32_t)) / \
|
|
(sizeof(__ll_pad_sw_params_t) - offsetof(__ll_pad_sw_params_t, min_shape)))
|
|
|
|
#define __LL_DMA_MIN_BUFF_LEN 40
|
|
|
|
/**
|
|
* @brief performs a concat operation according to ONNX semantics
|
|
* @param list of input tensor info structures
|
|
* @param number of inputs
|
|
* @param output tensor info structure
|
|
* @param axis for concatenation
|
|
* @retval Error code
|
|
*/
|
|
/** @defgroup LL_ATON_LIB_Concat function
|
|
* * @{
|
|
* */
|
|
int LL_ATON_LIB_Concat(const LL_Buffer_InfoTypeDef *, unsigned int, const LL_Buffer_InfoTypeDef *, unsigned int, int,
|
|
int);
|
|
/**
|
|
* * @}
|
|
* */
|
|
|
|
/**
|
|
* @brief performs a tensor ImageToRow transfer operation using stream engines `dma_in` and `dma_out`
|
|
* @param list of input tensor info structures
|
|
* @param number of inputs
|
|
* @param output tensor info structures
|
|
* @param blocksize_h vertical dimension for the blocksize
|
|
* @param blocksize_w horizontal dimension for the blocksize
|
|
* @param stride_h vertical stride for the sliding window
|
|
* @param stride_w horizontal stride for the sliding window
|
|
*
|
|
* @note Supports only input and output tensors in ATON canonical format
|
|
*
|
|
* @note Bit-sizes are rounded up to multiples of 8-bits
|
|
*
|
|
*/
|
|
/** @defgroup LL_ATON_LIB_DMA_ImageToRow function
|
|
* * @{
|
|
* */
|
|
int LL_ATON_LIB_DMA_ImageToRow(const LL_LIB_TensorInfo_TypeDef *inputs, unsigned int ninputs,
|
|
const LL_LIB_TensorInfo_TypeDef *output, unsigned blocksize_h, unsigned blocksize_w,
|
|
unsigned stride_h, unsigned stride_w, int dma_in, int dma_out);
|
|
/**
|
|
* * @}
|
|
* */
|
|
|
|
/**
|
|
* @brief performs a tensor SpaceToDepth transfer operation using stream engines `dma_in` and `dma_out`
|
|
* @param list of input tensor info structures
|
|
* @param number of inputs
|
|
* @param output tensor info structures
|
|
* @param blocksize_h vertical dimension for the blocksize
|
|
* @param blocksize_w horizontal dimension for the blocksize
|
|
*
|
|
* @note Bit-sizes are rounded up to multiples of 8-bits
|
|
*
|
|
*/
|
|
/** @defgroup LL_ATON_LIB_DMA_SpaceToDepth function
|
|
* * @{
|
|
* */
|
|
int LL_ATON_LIB_DMA_SpaceToDepth(const LL_LIB_TensorInfo_TypeDef *, unsigned int, const LL_LIB_TensorInfo_TypeDef *,
|
|
unsigned, unsigned, int, int);
|
|
|
|
/**
|
|
* * @}
|
|
* */
|
|
|
|
/**
|
|
* @brief performs a tensor RowToImage transfer operation using stream engines `dma_in` and `dma_out`
|
|
* @param list of input tensor info structures
|
|
* @param number of inputs
|
|
* @param output tensor info structures
|
|
* @param blocksize_h vertical dimension for the blocksize
|
|
* @param blocksize_w horizontal dimension for the blocksize
|
|
* @param stride_h vertical stride for the sliding window
|
|
* @param stride_w horizontal stride for the sliding window
|
|
*
|
|
* @note Supports only input and output tensors in ATON canonical format
|
|
*
|
|
* @note Bit-sizes are rounded up to multiples of 8-bits
|
|
*
|
|
*/
|
|
int LL_ATON_LIB_DMA_RowToImage(const LL_LIB_TensorInfo_TypeDef *inputs, unsigned int ninputs,
|
|
const LL_LIB_TensorInfo_TypeDef *output, unsigned blocksize_h, unsigned blocksize_w,
|
|
unsigned stride_h, unsigned stride_w, int dma_in, int dma_out);
|
|
|
|
/**
|
|
* * @}
|
|
* */
|
|
|
|
/**
|
|
* @brief performs a tensor DepthToSpace transfer operation using stream engines `dma_in` and `dma_out`
|
|
* @param list of input tensor info structures
|
|
* @param number of inputs
|
|
* @param output tensor info structures
|
|
* @param blocksize_h vertical dimension for the blocksize
|
|
* @param blocksize_w horizontal dimension for the blocksize
|
|
*
|
|
* @note Supports only input and output tensors in ATON canonical format
|
|
*
|
|
* @note Supports only DCR (depth-column-row) order re-arrangement
|
|
*
|
|
* @note Bit-sizes are rounded up to multiples of 8-bits
|
|
*
|
|
*/
|
|
/** @defgroup LL_ATON_LIB_DMA_DepthToSpace function
|
|
* * @{
|
|
* */
|
|
|
|
int LL_ATON_LIB_DMA_DepthToSpace(const LL_LIB_TensorInfo_TypeDef *, unsigned int, const LL_LIB_TensorInfo_TypeDef *,
|
|
unsigned, unsigned, int, int);
|
|
|
|
/**
|
|
* * @}
|
|
* */
|
|
|
|
/**
|
|
* @brief performs a cast operation to/from Qmn and float
|
|
* @param input tensor info structure
|
|
* @param output tensor info structure
|
|
* @retval Error code
|
|
*/
|
|
/** @defgroup LL_ATON_LIB_Cast function
|
|
* * @{
|
|
* */
|
|
int LL_ATON_LIB_Cast(const LL_LIB_TensorInfo_TypeDef *, const LL_LIB_TensorInfo_TypeDef *, int, int);
|
|
/**
|
|
* * @}
|
|
* */
|
|
|
|
/**
|
|
* @brief performs a Softmax operation on float inputs and output operands according to ONNX semantics
|
|
* @param input tensor info structure
|
|
* @param output tensor info structure
|
|
* @param axis for coalescing of shape into a 2D matrix
|
|
* @retval Error code
|
|
*/
|
|
/** @defgroup LL_ATON_LIB_Softmax function
|
|
* * @{
|
|
* */
|
|
int LL_ATON_LIB_Softmax(const LL_LIB_TensorInfo_TypeDef *, const LL_LIB_TensorInfo_TypeDef *, unsigned int, int);
|
|
/**
|
|
* * @}
|
|
* */
|
|
|
|
/**
|
|
* @brief performs flat copy operation on an input and several outputs using DMA
|
|
* @param input tensor shape structure
|
|
* @param outputs tensor shape structures
|
|
* @param nr_of_outputs number of output tensors
|
|
* @param dma_in DMA number of DMA reading from memory
|
|
* @param dma_in DMA number of DMA writing to memory
|
|
* @retval Error code
|
|
*/
|
|
/** @defgroup LL_ATON_LIB_DMA_Outputs_Flat_Copy function
|
|
* * @{
|
|
* */
|
|
int LL_ATON_LIB_DMA_Outputs_Flat_Copy(const LL_LIB_TensorShape_TypeDef *input,
|
|
const LL_LIB_TensorShape_TypeDef *outputs, unsigned int nr_of_outputs,
|
|
int dma_in, int dma_out);
|
|
/**
|
|
* * @}
|
|
* */
|
|
|
|
/**
|
|
* @brief perform split-like slice operation using DMAs
|
|
* @param input tensor shape structure
|
|
* @param outputs tensor shape structures
|
|
* @param tot_out_size size of output buffer
|
|
* @param width_in_bytes number of bytes per `memcpy`
|
|
* @param fheight DMA `fheight` field
|
|
* @param line_offset DMA `line_offset` field
|
|
* @param n_bits DMA channel size
|
|
* @param dma_in DMA number of DMA reading from memory
|
|
* @param dma_in DMA number of DMA writing to memory
|
|
* @return Error code
|
|
*/
|
|
int LL_ATON_LIB_DMA_Outputs_Slice_SplitLike(const LL_LIB_TensorShape_TypeDef *input,
|
|
const LL_LIB_TensorShape_TypeDef *output, int32_t tot_out_size,
|
|
int32_t width_in_bytes, int32_t fheight, int32_t line_offset,
|
|
int8_t n_bits, int dma_in, int dma_out);
|
|
/**
|
|
* * @}
|
|
* */
|
|
|
|
/**
|
|
* @brief performs channel-split copy operation on an input and several outputs (both in ATON canonical format) using
|
|
* DMA
|
|
* @param input tensor shape structure
|
|
* @param outputs tensor shape structures
|
|
* @param nr_of_outputs number of output tensors
|
|
* @retval Error code
|
|
*/
|
|
/** @defgroup LL_ATON_LIB_DMA_Outputs_Channel_Split_Aton function
|
|
* * @{
|
|
* */
|
|
int LL_ATON_LIB_DMA_Outputs_Channel_Split_Aton(const LL_LIB_TensorShape_TypeDef *, const LL_LIB_TensorShape_TypeDef *,
|
|
unsigned int, unsigned int leading_dims, int dma_in, int dma_out);
|
|
/**
|
|
* * @}
|
|
* */
|
|
|
|
/**
|
|
* @brief performs a channel-split memory copy operation from one input (ATON canonical) to `noutputs`
|
|
* non-ATON-canonical outputs using stream engines `dma_in` and `dma_out`
|
|
* @param src source address
|
|
* @param outputs list of output tensor shape structures
|
|
* @param noutputs number of outputs
|
|
* @retval Error code
|
|
*/
|
|
int LL_ATON_LIB_DMA_Outputs_Channel_Split_Batched(const LL_LIB_TensorShape_TypeDef *input,
|
|
const LL_LIB_TensorShape_TypeDef *outputs,
|
|
unsigned int nr_of_outputs, int dma_in, int dma_out);
|
|
/** @defgroup LL_ATON_LIB_DMA_Outputs_Channel_Split_Batched function
|
|
* * @{
|
|
* */
|
|
|
|
/**
|
|
* @brief performs an optimized `memset` for the `Pad` operator using DMA (aka Framing)
|
|
* @param output destination address of `memset` operation
|
|
* @param constant_value constant value to be set
|
|
* @param out_size number of bytes to output
|
|
* @param common_params parameters needed to setup DMAs and to forward to eventual callback function
|
|
* @retval Error code
|
|
*/
|
|
/** @defgroup LL_ATON_LIB_DMA_Pad_Memset function
|
|
* * @{
|
|
* */
|
|
int LL_ATON_LIB_DMA_Pad_Memset(void *output, int32_t constant_value, size_t out_size,
|
|
__ll_pad_sw_params_t *common_params);
|
|
/**
|
|
* * @}
|
|
* */
|
|
|
|
/**
|
|
* @brief performs HW accelerated filling operation for `Pad` operator (aka Filling)
|
|
* @param init_common_params parameters needed to setup DMAs and to forward to eventual callback function
|
|
* @retval Error code
|
|
*/
|
|
/** @defgroup LL_ATON_LIB_DMA_Pad_Filling function
|
|
* * @{
|
|
* */
|
|
int LL_ATON_LIB_DMA_Pad_Filling(__ll_pad_sw_params_t *init_common_params);
|
|
/**
|
|
* * @}
|
|
* */
|
|
|
|
/**
|
|
* @brief performs a transpose operation on a (4-dimensional) matrix using DMA
|
|
* currently supported permutation(s) is/are: (0, 2, 1, 3)-onnx
|
|
* @param input tensor shape structure
|
|
* @param output tensor shape structure
|
|
* @param target_pos target positions of input tensor
|
|
* @param perm_to_use permutation to apply (when using fallback to pure SW)
|
|
* @retval Error code
|
|
*/
|
|
/** @defgroup LL_ATON_LIB_DMA_Transpose function
|
|
* * @{
|
|
* */
|
|
int LL_ATON_LIB_DMA_Transpose(const LL_LIB_TensorShape_TypeDef *input, const uint32_t *input_axes_offsets,
|
|
const LL_LIB_TensorShape_TypeDef *output, const uint32_t *output_axes_offsets,
|
|
const uint8_t *target_pos, const uint8_t *perm_to_use, int dma_in, int dma_out);
|
|
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
/**
|
|
* @brief performs a ConvInteger operation
|
|
* @param input tensor shape structure
|
|
* @param ninputs number of inputs feat, kern, bias (optional)
|
|
* @param output tensor shape structure
|
|
* @retval Error code
|
|
*/
|
|
/** @defgroup LL_ATON_LIB_DMA_Transpose function
|
|
* * @{
|
|
* */
|
|
|
|
int LL_ATON_LIB_ConvInteger(const LL_LIB_TensorInfo_TypeDef *inputs, unsigned int ninputs,
|
|
const LL_LIB_TensorInfo_TypeDef *output);
|
|
/**
|
|
* @}
|
|
*/
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|