AIfES 2
2.0.0
|
Math functions for Q7 data type using AVR pgmspace.h library for constant data storage. More...
Go to the source code of this file.
Functions | |
void | aimath_q7_avr_pgm_linear32_1 (const aitensor_t *a, const aitensor_t *b, const aitensor_t *c, aitensor_t *result) |
Performs a matrix multiplication of Q7 matrices a and b and adds a Q31 vector c to each row. More... | |
void | aimath_q7_avr_pgm_linear32_2 (const aitensor_t *a, const aitensor_t *b, const aitensor_t *c, aitensor_t *result) |
Performs a matrix multiplication of Q7 matrices a and b and adds a Q31 vector c to each row. More... | |
void | aimath_q7_avr_pgm_linear32_bt_1 (const aitensor_t *a, const aitensor_t *b, const aitensor_t *c, aitensor_t *result) |
Performs a matrix multiplication of Q7 matrices a and b (transposed) and adds a Q31 vector c to each row. More... | |
void | aimath_q7_avr_pgm_linear32_bt_2 (const aitensor_t *a, const aitensor_t *b, const aitensor_t *c, aitensor_t *result) |
Performs a matrix multiplication of Q7 matrices a and b and adds a Q31 vector c to each row. More... | |
void | aimath_q7_avr_pgm_relu (const aitensor_t *x, aitensor_t *result) |
Calculates the rectifier (ReLU) value of each element in a Q7 tensor. More... | |
void | aimath_q7_avr_pgm_leaky_relu (const aitensor_t *x, const void *alpha, aitensor_t *result) |
Calculates the leaky rectifier (leaky ReLU) value of each element in a Q7 tensor. More... | |
void | aimath_q7_avr_pgm_elu (const aitensor_t *x, const void *alpha, aitensor_t *result) |
Calculates the exponential rectifier (ELU) value of each element in a Q7 tensor. More... | |
void | aimath_q7_avr_pgm_sigmoid (const aitensor_t *x, aitensor_t *result) |
Calculates the sigmoid of each element in a Q7 tensor. More... | |
void | aimath_q7_avr_pgm_tanh (const aitensor_t *x, aitensor_t *result) |
Calculates the tanh of each element in a Q7 tensor. More... | |
void | aimath_q7_avr_pgm_softsign (const aitensor_t *x, aitensor_t *result) |
Calculates the softsign value of each element in a Q7 tensor. More... | |
void | aimath_q7_avr_pgm_softmax (const aitensor_t *x, aitensor_t *result) |
Calculates the softmax value of each batch element (row) of a Q7 tensor. More... | |
Math functions for Q7 data type using AVR pgmspace.h library for constant data storage.
These functions modify the default implementation of the Q7 math functions to work with parameters, stored in the program memory of AVR controllers.
The library avr/pgmspace.h is required.
void aimath_q7_avr_pgm_elu | ( | const aitensor_t * | x, |
const void * | alpha, | ||
aitensor_t * | result | ||
) |
Calculates the exponential rectifier (ELU) value of each element in a Q7 tensor.
The quantization parameters x must be defined constant in PROGMEM.
This function wraps the function aimath_f32_default_elu() internally.
\[ result_{i} = \begin{cases} \alpha \cdot (e^{x_i} - 1) & \text{if } x_i < 0 \\ x_i & \text{if } x_i \geq 0 \end{cases} \]
The ELU is calculated with a piecewise linear approximation to avoid using exponential functions.
\[ result_{i} = \begin{cases} x_i & \text{if } 0 \leq x_i\\ \alpha \cdot 0.625 \cdot x_i & \text{if } -1 \leq x < 0\\ \alpha \cdot (0.25 \cdot x_i - 0.375) & \text{if } -2 \leq x < -1\\ \alpha \cdot (0.09375 \cdot x_i - 0.6875) & \text{if } -3 \leq x < -2\\ \alpha \cdot (0.03125 \cdot x_i - 0.875) & \text{if } -4 \leq x < -3\\ - \alpha & \text{if } x < -4 \end{cases} \]
The quantization parameters of the result tensor are set to {shift = x.shift, zero_point = x.zero_point} by the function because the output values are in the interval (max(-alpha, min(x)), max(x)].
Example:
*x | Q7 tensor to calculate the ELU from (N-D tensor) (quantization parameters const in PROGMEM) |
*alpha | Scalar \( \alpha \) (type aiscalar_q7_t) |
*result | Resulting Q7 tensor (N-D tensor) |
void aimath_q7_avr_pgm_leaky_relu | ( | const aitensor_t * | x, |
const void * | alpha, | ||
aitensor_t * | result | ||
) |
Calculates the leaky rectifier (leaky ReLU) value of each element in a Q7 tensor.
The quantization parameters x must be defined constant in PROGMEM.
This function wraps the function aimath_f32_default_leaky_relu() internally.
\[ result_{i} = \begin{cases} \alpha \cdot x_i & \text{if } x_i < 0 \\ x_i & \text{if } x_i \geq 0 \end{cases} \]
The quantization parameters of the result tensor are set to {shift = x.shift, zero_point = x.zero_point} by the function because the output values are in the interval (alpha * min(x), max(x)].
Example:
*x | Q7 tensor to calculate the leaky ReLU from (N-D tensor) (quantization parameters const in PROGMEM) |
*alpha | Scalar \( \alpha \) (type aiscalar_q7_t) for the leakage |
*result | Resulting Q7 tensor (N-D tensor) |
void aimath_q7_avr_pgm_linear32_1 | ( | const aitensor_t * | a, |
const aitensor_t * | b, | ||
const aitensor_t * | c, | ||
aitensor_t * | result | ||
) |
Performs a matrix multiplication of Q7 matrices a and b and adds a Q31 vector c to each row.
The data of b and c and the quantization parameters of a, b, c and result must be defined constant in PROGMEM.
Same functionality as aimath_f32_default_linear32().
The addition of the horizontal vector c is performed via broadcast, i.e. element wise in each column Mathematically this broadcast is equal to multiplying c with an vertical vector (with the same number of elements as c) and adding the result to a * b.
** The quantization parameters of the vector c have to be {zero_point = 0, shift = a.shift + b.shift}! **
\[ result = a \cdot b + \left( \begin{array}{c} 1 \\ 1 \\ \vdots \\ 1 \\ \end{array}\right) \cdot c \]
Example:
*a | Q7 matrix a (2D tensor of shape [N x K]) (quantization parameters const in PROGMEM) |
*b | Q7 matrix b (2D tensor of shape [K x M]) (data and quantization parameters const in PROGMEM) |
*c | Q31 vector c (2D tensor of shape [1 x M]) (data and quantization parameters const in PROGMEM) |
*result | Resulting Q7 matrix (2D tensor of shape [N x M]) (quantization parameters const in PROGMEM) |
void aimath_q7_avr_pgm_linear32_2 | ( | const aitensor_t * | a, |
const aitensor_t * | b, | ||
const aitensor_t * | c, | ||
aitensor_t * | result | ||
) |
Performs a matrix multiplication of Q7 matrices a and b and adds a Q31 vector c to each row.
The data of b and c and the quantization parameters of b, c and result (not of a!) must be defined constant in PROGMEM.
Same functionality as aimath_f32_default_linear32().
The addition of the horizontal vector c is performed via broadcast, i.e. element wise in each column Mathematically this broadcast is equal to multiplying c with an vertical vector (with the same number of elements as c) and adding the result to a * b.
** The quantization parameters of the vector c have to be {zero_point = 0, shift = a.shift + b.shift}! **
\[ result = a \cdot b + \left( \begin{array}{c} 1 \\ 1 \\ \vdots \\ 1 \\ \end{array}\right) \cdot c \]
Example:
*a | Q7 matrix a (2D tensor of shape [N x K]) |
*b | Q7 matrix b (2D tensor of shape [K x M]) (data and quantization parameters const in PROGMEM) |
*c | Q31 vector c (2D tensor of shape [1 x M]) (data and quantization parameters const in PROGMEM) |
*result | Resulting Q7 matrix (2D tensor of shape [N x M]) (quantization parameters const in PROGMEM) |
void aimath_q7_avr_pgm_linear32_bt_1 | ( | const aitensor_t * | a, |
const aitensor_t * | b, | ||
const aitensor_t * | c, | ||
aitensor_t * | result | ||
) |
Performs a matrix multiplication of Q7 matrices a and b (transposed) and adds a Q31 vector c to each row.
The data of b and c and the quantization parameters of a, b, c and result must be defined constant in PROGMEM.
The b matrix has to be transposed.
Same functionality as aimath_f32_default_linear32_bt().
The addition of the horizontal vector c is performed via broadcast, i.e. element wise in each column Mathematically this broadcast is equal to multiplying c with an vertical vector (with the same number of elements as c) and adding the result to \( a * b^T \).
The quantization parameters of the vector c have to be {zero_point = 0, shift = a.shift + b.shift}!
\[ result = a \cdot b^T + \left( \begin{array}{c} 1 \\ 1 \\ \vdots \\ 1 \\ \end{array}\right) \cdot c \]
Example:
*a | Q7 matrix a (2D tensor of shape [N x K]) (quantization parameters const in PROGMEM) |
*b | Q7 matrix b (2D tensor of shape [M x K]) (data and quantization parameters const in PROGMEM) |
*c | Q31 vector c (2D tensor of shape [1 x M]) (data and quantization parameters const in PROGMEM) |
*result | Resulting Q7 matrix (2D tensor of shape [N x M]) (quantization parameters const in PROGMEM) |
void aimath_q7_avr_pgm_linear32_bt_2 | ( | const aitensor_t * | a, |
const aitensor_t * | b, | ||
const aitensor_t * | c, | ||
aitensor_t * | result | ||
) |
Performs a matrix multiplication of Q7 matrices a and b and adds a Q31 vector c to each row.
The data of b and c and the quantization parameters of b, c and result (not of a!) must be defined constant in PROGMEM.
The b matrix has to be transposed.
Same functionality as aimath_f32_default_linear32().
The addition of the horizontal vector c is performed via broadcast, i.e. element wise in each column Mathematically this broadcast is equal to multiplying c with an vertical vector (with the same number of elements as c) and adding the result to \( a * b^T \).
** The quantization parameters of the vector c have to be {zero_point = 0, shift = a.shift + b.shift}! **
\[ result = a \cdot b^T + \left( \begin{array}{c} 1 \\ 1 \\ \vdots \\ 1 \\ \end{array}\right) \cdot c \]
Example:
*a | Q7 matrix a (2D tensor of shape [N x K]) |
*b | Q7 matrix b (2D tensor of shape [M x K]) (data and quantization parameters const in PROGMEM) |
*c | Q31 vector c (2D tensor of shape [1 x M]) (data and quantization parameters const in PROGMEM) |
*result | Resulting Q7 matrix (2D tensor of shape [N x M]) (quantization parameters const in PROGMEM) |
void aimath_q7_avr_pgm_relu | ( | const aitensor_t * | x, |
aitensor_t * | result | ||
) |
Calculates the rectifier (ReLU) value of each element in a Q7 tensor.
The quantization parameters x must be defined constant in PROGMEM.
This function wraps the function aimath_f32_default_relu() internally.
\[ result_{i} = max(0, x_{i}) \]
The quantization parameters of the result tensor are set to {shift = x.shift, zero_point = x.zero_point} by the function because the output values are in the interval [0, max(x)].
Example:
*x | Q7 tensor to calculate the ReLU from (N-D tensor) (quantization parameters const in PROGMEM) |
*result | Resulting Q7 tensor (N-D tensor) |
void aimath_q7_avr_pgm_sigmoid | ( | const aitensor_t * | x, |
aitensor_t * | result | ||
) |
Calculates the sigmoid of each element in a Q7 tensor.
The quantization parameters x must be defined constant in PROGMEM.
This function wraps the function aimath_f32_default_sigmoid() internally.
\[ result_{i} = \sigma(x_{i}) = \frac{1}{1 + e^{-x_{i}}} \]
The sigmoid is calculated with a piecewise linear approximation (PLAN) to avoid using exponential functions.
\[ result_{i} = \sigma_{PLAN}(x_i) = \begin{cases} 1 & \text{if } 5 \leq x_i\\ 0.03125 \cdot |x_i| + 0.84375 & \text{if } 2.375 \leq x_i < 5\\ 0.0125 \cdot |x_i| + 0.625 & \text{if } 1 \leq x_i < 2.375\\ 0.25 \cdot |x_i| + 0.5 & \text{if } 0 \leq x_i < 1\\ 1 - \sigma_{PLAN}(- x_i) & \text{if } x_i < 0\\ \end{cases} \]
The quantization parameters of the result tensor are set to {shift = 8, zero_point = -2^7} by the function because the output values are in the interval (0, 1).
Example:
*x | Q7 tensor to calculate the sigmoid from (N-D tensor) (quantization parameters const in PROGMEM) |
*result | Resulting Q7 tensor (N-D tensor) |
void aimath_q7_avr_pgm_softmax | ( | const aitensor_t * | x, |
aitensor_t * | result | ||
) |
Calculates the softmax value of each batch element (row) of a Q7 tensor.
The quantization parameters x must be defined constant in PROGMEM.
This function wraps the function aimath_f32_default_softmax() internally.
\[ result_{i} = \frac{e^{x_i}}{\sum_{j=1}^{K} e^{x_j}} \]
The quantization parameters of the result tensor are set to {shift = 8, zero_point = -128} by the function because the output values are in the interval (0, 1).
Example:
*x | Q7 tensor to calculate the softmax from (N-D tensor) (quantization parameters const in PROGMEM) |
*result | Resulting Q7 tensor (N-D tensor) |
void aimath_q7_avr_pgm_softsign | ( | const aitensor_t * | x, |
aitensor_t * | result | ||
) |
Calculates the softsign value of each element in a Q7 tensor.
The quantization parameters x must be defined constant in PROGMEM.
This function wraps the function aimath_f32_default_softsign() internally.
\[ result_{i} = \frac {x_i} {1 + |x_i|} \]
The quantization parameters of the result tensor are set to {shift = 7, zero_point = 0} by the function because the output values are in the interval (-1, 1).
Example:
*x | Q7 tensor to calculate the softsign from (N-D tensor) (quantization parameters const in PROGMEM) |
*result | Resulting Q7 tensor (N-D tensor) |
void aimath_q7_avr_pgm_tanh | ( | const aitensor_t * | x, |
aitensor_t * | result | ||
) |
Calculates the tanh of each element in a Q7 tensor.
The quantization parameters x must be defined constant in PROGMEM.
This function wraps the function aimath_f32_default_tanh() internally.
\[ result_{i} = \tanh(x_{i}) = \frac{e^{x_i} - e^{-x_i}}{e^{x_i} + e^{-x_i}} \]
The tanh is calculated with a piecewise linear approximation (PLA) to avoid using exponential functions.
\[ result_{i} = \tanh_{PLA}(x_i) = 2 \cdot \sigma(2x_i) - 1 = \begin{cases} 1 & \text{if } 5 \leq x_i\\ 0.0625 \cdot |x_i| + 0.6875 & \text{if } 2.375 \leq x_i < 5\\ 0.25 \cdot |x_i| + 0.25 & \text{if } 1 \leq x_i < 2.375\\ 0.5 \cdot |x_i| & \text{if } 0 \leq x_i < 1\\ - \tanh_{PLA}(- x_i) & \text{if } x_i < 0\\ \end{cases} \]
The quantization parameters of the result tensor are set to {shift = 7, zero_point = 0} by the function because the output values are in the interval (-1, 1).
Example:
*x | Q7 tensor to calculate the tanh from (N-D tensor) (quantization parameters const in PROGMEM) |
*result | Resulting Q7 tensor (N-D tensor) |