Files
kunlun/dtest/bee_ai_test/matrix_function.h
2024-09-28 14:24:04 +08:00

474 lines
22 KiB
C
Executable File

/****************************************************************************
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
be copied by any method or incorporated into another program without
the express written consent of Aerospace C.Power. This Information or any portion
thereof remains the property of Aerospace C.Power. The Information contained herein
is believed to be accurate and Aerospace C.Power assumes no responsibility or
liability for its use in any way and conveys no license or title under
any patent or copyright and makes no representation or warranty that this
Information is free from patent or copyright infringement.
****************************************************************************/
#ifndef MATRIX_FUNCTION_H
#define MATRIX_FUNCTION_H
/* os shim includes */
#include "os_types.h"
#ifdef __cplusplus
extern "C" {
#endif
/** \defgroup matrix function API
* @brief matrix function APIs
* Matrix functions, including matrix multiplying, transposing
*
* Any matrix M(whose size is h*w) of type uint8 or int8 should be arranged in this form below so that the distance between M[i, j] and M[i + 1, j] is ceil(w / 8) * 8 bytes, as an example, we set M's size is 28 * 28
* M[0, 0], M[0, 1], M[0, 2], ..., M[0, 27], 0, 0, 0, 0,
* M[1, 0], M[1, 1], M[1, 2], ..., M[1, 27], 0, 0, 0, 0,
* ...
* M[27,0], M[27,1], M[27,2], ..., M[27,27], 0, 0, 0, 0
*
* Any matrix M(whose size is h*w) of type uint16 or int16 should be arranged in this form below so that the distance between M[i, j] and M[i + 1, j] is ceil(w / 4) * 8 bytes, as an example, we set M's size is 14 * 14
* M[0, 0], M[0, 1], M[0, 2], ..., M[0, 13], 0, 0,
* M[1, 0], M[1, 1], M[1, 2], ..., M[1, 13], 0, 0,
* ...
* M[13,0], M[13,1], M[13,2], ..., M[13,13], 0, 0
*
* Any matrix M(whose size is h*w) of type float, uint32 or int32 should be arranged in this form below so that the distance between M[i, j] and M[i + 1, j] is ceil(w / 2) * 8 bytes, as an example, we set M's size is 7 * 7
* M[0, 0], M[0, 1], M[0, 2], ..., M[0, 6], 0,
* M[1, 0], M[1, 1], M[1, 2], ..., M[1, 6], 0,
* ...
* M[6 ,0], M[6 ,1], M[6 ,2], ..., M[6 ,6], 0
*
* Any matrix M(whose size is h*w) of type uint64 or int64 should be arranged consecutively
*
*/
/** @addtogroup matrix_function_APIs
* @{
*/
/* @brief matrix_transpose_int8() - matrix transpose operation
* @param in: where the input, a matrix, is put
* @param out: where the output, a matrix, will be put
* @param height: height of input matrix, i.e. it's width of output matrix
* @param width_: width of input matrix, i.e. it's height of output matrix
* @return 0 -- succeed
* @return 1 -- height is 0
* @return 2 -- width_ is 0
*/
uint8_t matrix_transpose_int8(int8_t *in, int8_t *out, uint32_t height, uint32_t width_);
/* @brief matrix_transpose_uint8() - matrix transpose operation
* @param in: where the input, a matrix, is put
* @param out: where the output, a matrix, will be put
* @param height: height of input matrix, i.e. it's width of output matrix
* @param width_: width of input matrix, i.e. it's height of output matrix
* @return 0 -- succeed
* @return 1 -- height is 0
* @return 2 -- width_ is 0
*/
uint8_t matrix_transpose_uint8(uint8_t *in, uint8_t *out, uint32_t height, uint32_t width_);
/* @brief matrix_transpose_int16() - matrix transpose operation
* @param in: where the input, a matrix, is put
* @param out: where the output, a matrix, will be put
* @param height: height of input matrix, i.e. it's width of output matrix
* @param width_: width of input matrix, i.e. it's height of output matrix
* @return 0 -- succeed
* @return 1 -- height is 0
* @return 2 -- width_ is 0
*/
uint8_t matrix_transpose_int16(int16_t *in, int16_t *out, uint32_t height, uint32_t width_);
/* @brief matrix_transpose_uint16() - matrix transpose operation
* @param in: where the input, a matrix, is put
* @param out: where the output, a matrix, will be put
* @param height: height of input matrix, i.e. it's width of output matrix
* @param width_: width of input matrix, i.e. it's height of output matrix
* @return 0 -- succeed
* @return 1 -- height is 0
* @return 2 -- width_ is 0
*/
uint8_t matrix_transpose_uint16(uint16_t *in, uint16_t *out, uint32_t height, uint32_t width_);
/* @brief matrix_transpose_int32() - matrix transpose operation
* @param in: where the input, a matrix, is put
* @param out: where the output, a matrix, will be put
* @param height: height of input matrix, i.e. it's width of output matrix
* @param width_: width of input matrix, i.e. it's height of output matrix
* @return 0 -- succeed
* @return 1 -- height is 0
* @return 2 -- width_ is 0
*/
uint8_t matrix_transpose_int32(int32_t *in, int32_t *out, uint32_t height, uint32_t width_);
/* @brief matrix_transpose_uint32() - matrix transpose operation
* @param in: where the input, a matrix, is put
* @param out: where the output, a matrix, will be put
* @param height: height of input matrix, i.e. it's width of output matrix
* @param width_: width of input matrix, i.e. it's height of output matrix
* @return 0 -- succeed
* @return 1 -- height is 0
* @return 2 -- width_ is 0
*/
uint8_t matrix_transpose_uint32(uint32_t *in, uint32_t *out, uint32_t height, uint32_t width_);
/* @brief matrix_multi_int8_to_int32() - matrix multiplying operation, i.e.
output[i, j] = sum(a[i, k] * b[k, j]), where sum is on k
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param w_a_h_b: width of matrix a, i.e. this number must be the height of matrix b
* @param w_b: width of matrix b
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- w_a_h_b is 0
* @return 3 -- w_b is 0
*/
uint8_t matrix_multi_int8_to_int32(int8_t *a, int8_t *b, int32_t *output, uint32_t h_a, uint32_t w_a_h_b, uint32_t w_b);
/* @brief matrix_multi_uint8_to_uint32() - matrix multiplying operation, i.e.
output[i, j] = sum(a[i, k] * b[k, j]), where sum is on k
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param w_a_h_b: width of matrix a, i.e. this number must be the height of matrix b
* @param w_b: width of matrix b
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- w_a_h_b is 0
* @return 3 -- w_b is 0
*/
uint8_t matrix_multi_uint8_to_uint32(uint8_t *a, uint8_t *b, uint32_t *output, uint32_t h_a, uint32_t w_a_h_b, uint32_t w_b);
/* @brief matrix_multi_int8_to_int8() - matrix multiplying operation, i.e.
output[i, j] = sum(a[i, k] * b[k, j]) >> right_shift_num, where sum is on k
where the right_shift_num could be used for avoiding saturation
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param w_a_h_b: width of matrix a, i.e. this number must be the height of matrix b
* @param w_b: width of matrix b
* @param right_shift_num: the right shift number shown in the formula above
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- w_a_h_b is 0
* @return 3 -- w_b is 0
*/
uint8_t matrix_multi_int8_to_int8(int8_t *a, int8_t *b, int8_t *output, uint32_t h_a, uint32_t w_a_h_b, uint32_t w_b, uint8_t right_shift_num);
/* @brief matrix_multi_uint8_to_uint8() - matrix multiplying operation, i.e.
output[i, j] = sum(a[i, k] * b[k, j]) >> right_shift_num, where sum is on k
where the right_shift_num could be used for avoiding saturation
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param w_a_h_b: width of matrix a, i.e. this number must be the height of matrix b
* @param w_b: width of matrix b
* @param right_shift_num: the right shift number shown in the formula above
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- w_a_h_b is 0
* @return 3 -- w_b is 0
*/
uint8_t matrix_multi_uint8_to_uint8(uint8_t *a, uint8_t *b, uint8_t *output, uint32_t h_a, uint32_t w_a_h_b, uint32_t w_b, uint8_t right_shift_num);
/* @brief matrix_multi_int16_to_int64() - matrix multiplying operation, i.e.
output[i, j] = sum(a[i, k] * b[k, j]), where sum is on k
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param w_a_h_b: width of matrix a, i.e. this number must be the height of matrix b
* @param w_b: width of matrix b
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- w_a_h_b is 0
* @return 3 -- w_b is 0
*/
uint8_t matrix_multi_int16_to_int64(int16_t *a, int16_t *b, int64_t *output, uint32_t h_a, uint32_t w_a_h_b, uint32_t w_b);
/* @brief matrix_multi_uint16_to_uint64() - matrix multiplying operation, i.e.
output[i, j] = sum(a[i, k] * b[k, j]), where sum is on k
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param w_a_h_b: width of matrix a, i.e. this number must be the height of matrix b
* @param w_b: width of matrix b
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- w_a_h_b is 0
* @return 3 -- w_b is 0
*/
uint8_t matrix_multi_uint16_to_uint64(uint16_t *a, uint16_t *b, uint64_t *output, uint32_t h_a, uint32_t w_a_h_b, uint32_t w_b);
/* @brief matrix_multi_int16_to_int16() - matrix multiplying operation, i.e.
output[i, j] = sum(a[i, k] * b[k, j]) >> right_shift_num, where sum is on k
where the right_shift_num could be used for avoiding saturation
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param w_a_h_b: width of matrix a, i.e. this number must be the height of matrix b
* @param w_b: width of matrix b
* @param right_shift_num: the right shift number shown in the formula above
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- w_a_h_b is 0
* @return 3 -- w_b is 0
*/
uint8_t matrix_multi_int16_to_int16(int16_t *a, int16_t *b, int16_t *output, uint32_t h_a, uint32_t w_a_h_b, uint32_t w_b, uint8_t right_shift_num);
/* @brief matrix_multi_uint16_to_uint16() - matrix multiplying operation, i.e.
output[i, j] = sum(a[i, k] * b[k, j]) >> right_shift_num, where sum is on k
where the right_shift_num could be used for avoiding saturation
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param w_a_h_b: width of matrix a, i.e. this number must be the height of matrix b
* @param w_b: width of matrix b
* @param right_shift_num: the right shift number shown in the formula above
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- w_a_h_b is 0
* @return 3 -- w_b is 0
*/
uint8_t matrix_multi_uint16_to_uint16(uint16_t *a, uint16_t *b, uint16_t *output, uint32_t h_a, uint32_t w_a_h_b, uint32_t w_b, uint8_t right_shift_num);
/* @brief matrix_multi_float() - matrix multiplying operation, i.e.
output[i, j] = sum(a[i, k] * b[k, j]), where sum is on k
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param w_a_h_b: width of matrix a, i.e. this number must be the height of matrix b
* @param w_b: width of matrix b
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- w_a_h_b is 0
* @return 3 -- w_b is 0
*/
uint8_t matrix_multi_float(float *a, float *b, float *output, uint32_t h_a, uint32_t w_a_h_b, uint32_t w_b);
/* @brief matrix_multi_int32_to_int32() - matrix multiplying operation, i.e.
output[i, j] = sum(a[i, k] * b[k, j]), where sum is on k
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param w_a_h_b: width of matrix a, i.e. this number must be the height of matrix b
* @param w_b: width of matrix b
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- w_a_h_b is 0
* @return 3 -- w_b is 0
*/
uint8_t matrix_multi_int32_to_int32(int32_t *a, int32_t *b, int32_t *output, uint32_t h_a, uint32_t w_a_h_b, uint32_t w_b);
/* @brief matrix_multi_uint32_to_uint32() - matrix multiplying operation, i.e.
output[i, j] = sum(a[i, k] * b[k, j]), where sum is on k
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param w_a_h_b: width of matrix a, i.e. this number must be the height of matrix b
* @param w_b: width of matrix b
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- w_a_h_b is 0
* @return 3 -- w_b is 0
*/
uint8_t matrix_multi_uint32_to_uint32(uint32_t *a, uint32_t *b, uint32_t *output, uint32_t h_a, uint32_t w_a_h_b, uint32_t w_b);
/* @brief matrix_transpose_multi_int8_to_int32() - calculating a*transpose(b), i.e.
output[i, j] = sum(a[i, k] * b[j, k]), where sum is on k
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param h_b: height of matrix b
* @param width: width of matrix a & b
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- h_b is 0
* @return 3 -- width is 0
*/
uint8_t matrix_transpose_multi_int8_to_int32(int8_t *a, int8_t *b, int32_t *out, uint32_t h_a, uint32_t h_b, uint32_t width);
/* @brief matrix_transpose_multi_uint8_to_uint32() - calculating a*transpose(b), i.e.
output[i, j] = sum(a[i, k] * b[j, k]), where sum is on k
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param h_b: height of matrix b
* @param width: width of matrix a & b
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- h_b is 0
* @return 3 -- width is 0
*/
uint8_t matrix_transpose_multi_uint8_to_uint32(uint8_t *a, uint8_t *b, uint32_t *out, uint32_t h_a, uint32_t h_b, uint32_t width);
/* @brief matrix_transpose_multi_int8_to_int8() - calculating a*transpose(b), i.e.
output[i, j] = sum(a[i, k] * b[j, k]) >> right_shift, where sum is on k
where the right_shift could be used for avoiding saturation
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param h_b: height of matrix b
* @param width: width of matrix a & b
* @param right_shift: the right shift number shown in the formula above
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- h_b is 0
* @return 3 -- width is 0
*/
uint8_t matrix_transpose_multi_int8_to_int8(int8_t *a, int8_t *b, int8_t *out, uint32_t h_a, uint32_t h_b, uint32_t width, uint8_t right_shift);
/* @brief matrix_transpose_multi_uint8_to_uint8() - calculating a*transpose(b), i.e.
output[i, j] = sum(a[i, k] * b[j, k]) >> right_shift, where sum is on k
where the right_shift could be used for avoiding saturation
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param h_b: height of matrix b
* @param width: width of matrix a & b
* @param right_shift: the right shift number shown in the formula above
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- h_b is 0
* @return 3 -- width is 0
*/
uint8_t matrix_transpose_multi_uint8_to_uint8(uint8_t *a, uint8_t *b, uint8_t *out, uint32_t h_a, uint32_t h_b, uint32_t width, uint8_t right_shift);
/* @brief matrix_transpose_multi_int16_to_int64() - calculating a*transpose(b), i.e.
output[i, j] = sum(a[i, k] * b[j, k]), where sum is on k
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param h_b: height of matrix b
* @param width: width of matrix a & b
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- h_b is 0
* @return 3 -- width is 0
*/
uint8_t matrix_transpose_multi_int16_to_int64(int16_t *a, int16_t *b, int64_t *out, uint32_t h_a, uint32_t h_b, uint32_t width);
/* @brief matrix_transpose_multi_uint16_to_uint64() - calculating a*transpose(b), i.e.
output[i, j] = sum(a[i, k] * b[j, k]), where sum is on k
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param h_b: height of matrix b
* @param width: width of matrix a & b
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- h_b is 0
* @return 3 -- width is 0
*/
uint8_t matrix_transpose_multi_uint16_to_uint64(uint16_t *a, uint16_t *b, uint64_t *out, uint32_t h_a, uint32_t h_b, uint32_t width);
/* @brief matrix_transpose_multi_int16_to_int16() - calculating a*transpose(b), i.e.
output[i, j] = sum(a[i, k] * b[j, k]) >> right_shift, where sum is on k
where the right_shift could be used for avoiding saturation
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param h_b: height of matrix b
* @param width: width of matrix a & b
* @param right_shift: the right shift number shown in the formula above
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- h_b is 0
* @return 3 -- width is 0
*/
uint8_t matrix_transpose_multi_int16_to_int16(int16_t *a, int16_t *b, int16_t *out, uint32_t h_a, uint32_t h_b, uint32_t width, uint8_t right_shift);
/* @brief matrix_transpose_multi_uint16_to_uint16() - calculating a*transpose(b), i.e.
output[i, j] = sum(a[i, k] * b[j, k]) >> right_shift, where sum is on k
where the right_shift could be used for avoiding saturation
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param h_b: height of matrix b
* @param width: width of matrix a & b
* @param right_shift: the right shift number shown in the formula above
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- h_b is 0
* @return 3 -- width is 0
*/
uint8_t matrix_transpose_multi_uint16_to_uint16(uint16_t *a, uint16_t *b, uint16_t *out, uint32_t h_a, uint32_t h_b, uint32_t width, uint8_t right_shift);
/* @brief matrix_transpose_multi_float() - calculating a*transpose(b), i.e.
output[i, j] = sum(a[i, k] * b[j, k]), where sum is on k
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param h_b: height of matrix b
* @param width: width of matrix a & b
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- h_b is 0
* @return 3 -- width is 0
*/
uint8_t matrix_transpose_multi_float(float *a, float *b, float *out, uint32_t h_a, uint32_t h_b, uint32_t width);
/* @brief matrix_transpose_multi_int32_to_int32() - calculating a*transpose(b), i.e.
output[i, j] = sum(a[i, k] * b[j, k]), where sum is on k
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param h_b: height of matrix b
* @param width: width of matrix a & b
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- h_b is 0
* @return 3 -- width is 0
*/
uint8_t matrix_transpose_multi_int32_to_int32(int32_t *a, int32_t *b, int32_t *out, uint32_t h_a, uint32_t h_b, uint32_t width);
/* @brief matrix_transpose_multi_uint32_to_uint32() - calculating a*transpose(b), i.e.
output[i, j] = sum(a[i, k] * b[j, k]), where sum is on k
* @param a: pointer to input matrix shown in the formula above
* @param b: pointer to input matrix shown in the formula above
* @param output: where the output, a matrix, will be put
* @param h_a: height of matrix a
* @param h_b: height of matrix b
* @param width: width of matrix a & b
* @return 0 -- succeed
* @return 1 -- h_a is 0
* @return 2 -- h_b is 0
* @return 3 -- width is 0
*/
uint8_t matrix_transpose_multi_uint32_to_uint32(uint32_t *a, uint32_t *b, uint32_t *out, uint32_t h_a, uint32_t h_b, uint32_t width);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif