AIfES 2
2.0.0
|
Math functions for Q7 data type, default implementation. More...
Go to the source code of this file.
Functions | |
void | aimath_q7_default_linear32 (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_default_linear32_bt (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_default_mat_mul (const aitensor_t *a, const aitensor_t *b, aitensor_t *result) |
Performs a matrix multiplication of Q7 matrices a and b. More... | |
void | aimath_q7_default_multiply (const aitensor_t *a, const aitensor_t *b, aitensor_t *result) |
Performs an element wise multiplication of Q7 tensors a and b (Hadamard product) More... | |
void | aimath_q7_default_scalar_mul (const void *scalar, const aitensor_t *a, aitensor_t *result) |
Performs a scalar multiplication (scaling) of Q7 tensor a and a scalar. More... | |
void | aimath_q7_default_tensor_add_different_shift (const aitensor_t *a, const aitensor_t *b, aitensor_t *result) |
Performs an element wise addition of Q7 tensors a and b with different shifts. More... | |
void | aimath_q7_default_tensor_add_same_shift (const aitensor_t *a, const aitensor_t *b, aitensor_t *result) |
Performs an element wise addition of Q7 tensors a and b with same shifts. More... | |
void | aimath_q7_default_tensor_sub_different_shift (const aitensor_t *a, const aitensor_t *b, aitensor_t *result) |
Performs an element wise addition of Q7 tensors a and b with different shifts. More... | |
void | aimath_q7_default_tensor_sub_same_shift (const aitensor_t *a, const aitensor_t *b, aitensor_t *result) |
Performs an element wise subtraction of Q7 tensors a and b with same shifts. More... | |
void | aimath_q7_default_copy_tensor (const aitensor_t *from, aitensor_t *to) |
Performs an element wise copy of Q7 tensors. More... | |
void | aimath_q7_default_transpose_vector (aitensor_t *vector) |
Transposes a Q7 vector. More... | |
void | aimath_q7_default_transpose_matrix (aitensor_t *x) |
Transpose a Q7 tensor. More... | |
void | aimath_q7_default_sigmoid (const aitensor_t *x, aitensor_t *result) |
Calculates the sigmoid of each element in a Q7 tensor. More... | |
void | aimath_q7_default_relu (const aitensor_t *x, aitensor_t *result) |
Calculates the rectifier (ReLU) value of each element in a Q7 tensor. More... | |
void | aimath_q7_default_d_relu (const aitensor_t *x, aitensor_t *result) |
Calculates the rectifier (ReLU) derivative of each element in a Q7 tensor. More... | |
void | aimath_q7_default_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_default_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_default_tanh (const aitensor_t *x, aitensor_t *result) |
Calculates the tanh of each element in a Q7 tensor. More... | |
void | aimath_q7_default_softsign (const aitensor_t *x, aitensor_t *result) |
Calculates the softsign value of each element in a Q7 tensor. More... | |
void | aimath_q7_default_softmax (const aitensor_t *x, aitensor_t *result) |
Calculates the softmax value of each batch element (row) of a Q7 tensor. More... | |
void | aimath_q7_default_zero_tensor (aitensor_t *tensor) |
Fills a Q7 tensor with zeros. More... | |
void | aimath_q7_default_init_zeros (aitensor_t *tensor) |
Fills a Q7 tensor with zeros. More... | |
Math functions for Q7 data type, default implementation.
These functions can be used when no hardware specific implementation is available.
void aimath_q7_default_copy_tensor | ( | const aitensor_t * | from, |
aitensor_t * | to | ||
) |
Performs an element wise copy of Q7 tensors.
\[ to \leftarrow from \]
Dimension, shape and quantization parameters of from and to tensors have to be the same.
Example:
*from | Q7 tensor to copy from (N-D tensor) |
*to | Q7 tensor to copy to (N-D tensor) |
void aimath_q7_default_d_relu | ( | const aitensor_t * | x, |
aitensor_t * | result | ||
) |
Calculates the rectifier (ReLU) derivative of each element in a Q7 tensor.
\[ result_{ij} = \begin{cases} 0 & \text{if } x_i < 0\\ 1 & \text{if } x_i \geq 0 \end{cases} \]
The quantization parameters of the result tensor are set to {shift = 0, zero_point = 0} by the function because the output values are either 0 or 1.
Example:
*x | Q7 tensor to calculate the ReLU derivative from (N-D tensor) |
*result | Resulting Q7 tensor (N-D tensor) |
void aimath_q7_default_elu | ( | const aitensor_t * | x, |
const void * | alpha, | ||
aitensor_t * | result | ||
) |
Calculates the exponential rectifier (ELU) value of each element in a Q7 tensor.
\[ 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) |
*alpha | Scalar \( \alpha \) (type aiscalar_q7_t) |
*result | Resulting Q7 tensor (N-D tensor) |
void aimath_q7_default_init_zeros | ( | aitensor_t * | tensor | ) |
Fills a Q7 tensor with zeros.
\[ tensor_{i} = 0 \]
The function sets all tensor elements, the shift and the zero_point to 0.
Example:
*tensor | Q7 tensor to set to zero (N-D tensor) |
void aimath_q7_default_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.
\[ 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) |
*alpha | Scalar \( \alpha \) (type aiscalar_q7_t) for the leakage |
*result | Resulting Q7 tensor (N-D tensor) |
void aimath_q7_default_linear32 | ( | 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 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 \cdot 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 = \left( \begin{array}{rrr} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{array}\right) \]
\[ b = \left( \begin{array}{rr} 1 & 0 \\ 0 & 1 \\ 0 & 0 \end{array}\right) \]
\[ c = \left( \begin{array}{rr} 2 & 5 \end{array}\right) \]
\[ result = a \cdot b + \left( \begin{array}{r} 1 \\ 1 \\ 1 \\ \end{array}\right) \cdot c \]
\[ = \left( \begin{array}{rr} 1 & 2 \\ 4 & 5 \\ 7 & 8 \end{array}\right) + \left( \begin{array}{rr} 2 & 5 \\ 2 & 5 \\ 2 & 5 \end{array}\right) \]
\[ = \left( \begin{array}{rr} 3 & 7 \\ 6 & 10 \\ 9 & 13 \end{array}\right) \]
Example:
*a | Q7 matrix a (2D tensor of shape [N x K]) |
*b | Q7 matrix b (2D tensor of shape [K x M]) |
*c | Q31 vector c (2D tensor of shape [1 x M] or 1D tensor of shape [M]) |
*result | Resulting Q7 matrix (2D tensor of shape [N x M]) |
void aimath_q7_default_linear32_bt | ( | 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.
Same operation as aimath_q7_default_linear32() but with a transposed b matrix.
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 \cdot 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 = \left( \begin{array}{rrr} 1 & 2 & 3 \\ 4 & 5 & 6 \\ 7 & 8 & 9 \end{array}\right) \]
\[ b = \left( \begin{array}{rr} 1 & 0 & 0 \\ 0 & 1 & 0 \end{array}\right) \]
\[ c = \left( \begin{array}{rr} 2 & 5 \end{array}\right) \]
\[ result = a \cdot b^T + \left( \begin{array}{r} 1 \\ 1 \\ 1 \\ \end{array}\right) \cdot c \]
\[ = \left( \begin{array}{rr} 1 & 2 \\ 4 & 5 \\ 7 & 8 \end{array}\right) + \left( \begin{array}{rr} 2 & 5 \\ 2 & 5 \\ 2 & 5 \end{array}\right) \]
\[ = \left( \begin{array}{rr} 3 & 7 \\ 6 & 10 \\ 9 & 13 \end{array}\right) \]
Example:
*a | Q7 matrix a (2D tensor of shape [N x K]) |
*b | Q7 matrix b (2D tensor of shape [M x K]) |
*c | Q31 vector c (2D tensor of shape [1 x M] or 1D tensor of shape [M]) |
*result | Resulting Q7 matrix (2D tensor of shape [N x M]) |
void aimath_q7_default_mat_mul | ( | const aitensor_t * | a, |
const aitensor_t * | b, | ||
aitensor_t * | result | ||
) |
Performs a matrix multiplication of Q7 matrices a and b.
\[ result = a \cdot b \]
Example:
*a | Q7 matrix a (2D tensor of shape [N x K]) |
*b | Q7 matrix b (2D tensor of shape [K x M]) |
*result | Resulting Q7 matrix of the multiplication (2D tensor of shape [N x M]) |
void aimath_q7_default_multiply | ( | const aitensor_t * | a, |
const aitensor_t * | b, | ||
aitensor_t * | result | ||
) |
Performs an element wise multiplication of Q7 tensors a and b (Hadamard product)
\[ result = a \circ b \]
Example:
*a | Q7 tensor a (N-D tensor) |
*b | Q7 tensor b (N-D tensor) |
*result | Resulting Q7 tensor of the element wise multiplication (N-D tensor) |
void aimath_q7_default_relu | ( | const aitensor_t * | x, |
aitensor_t * | result | ||
) |
Calculates the rectifier (ReLU) value of each element in a Q7 tensor.
\[ 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) |
*result | Resulting Q7 tensor (N-D tensor) |
void aimath_q7_default_scalar_mul | ( | const void * | scalar, |
const aitensor_t * | a, | ||
aitensor_t * | result | ||
) |
Performs a scalar multiplication (scaling) of Q7 tensor a and a scalar.
\[ result = scalar \cdot a \]
Example:
*scalar | Scalar (type aiscalar_q7_t) |
*a | Q7 tensor a (N-D tensor) |
*result | Resulting Q7 tensor of the scalar multiplication (N-D tensor) |
void aimath_q7_default_sigmoid | ( | const aitensor_t * | x, |
aitensor_t * | result | ||
) |
Calculates the sigmoid of each element in a Q7 tensor.
\[ 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) |
*result | Resulting Q7 tensor (N-D tensor) |
void aimath_q7_default_softmax | ( | const aitensor_t * | x, |
aitensor_t * | result | ||
) |
Calculates the softmax value of each batch element (row) of a Q7 tensor.
\[ 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) |
*result | Resulting Q7 tensor (N-D tensor) |
void aimath_q7_default_softsign | ( | const aitensor_t * | x, |
aitensor_t * | result | ||
) |
Calculates the softsign value of each element in a Q7 tensor.
\[ 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) |
*result | Resulting Q7 tensor (N-D tensor) |
void aimath_q7_default_tanh | ( | const aitensor_t * | x, |
aitensor_t * | result | ||
) |
Calculates the tanh of each element in a Q7 tensor.
\[ 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) |
*result | Resulting Q7 tensor (N-D tensor) |
void aimath_q7_default_tensor_add_different_shift | ( | const aitensor_t * | a, |
const aitensor_t * | b, | ||
aitensor_t * | result | ||
) |
Performs an element wise addition of Q7 tensors a and b with different shifts.
\[ result = a + b \]
The tensors a, b and result can have different shifts. The function will rescale the tensors internally to perform the addition. If a, b and result have the same shift, use aimath_q7_default_tensor_add_same_shift() instead because it is more efficient.
Example:
*a | Q7 tensor a (N-D tensor) |
*b | Q7 tensor b (N-D tensor) |
*result | Resulting Q7 tensor of the element wise addition (N-D tensor) |
void aimath_q7_default_tensor_add_same_shift | ( | const aitensor_t * | a, |
const aitensor_t * | b, | ||
aitensor_t * | result | ||
) |
Performs an element wise addition of Q7 tensors a and b with same shifts.
\[ result = a + b \]
The tensors a, b and result must have the same shift. If a, b and result have the different shifts, use aimath_q7_default_tensor_add_different_shift() instead.
Example:
*a | Q7 tensor a (N-D tensor) |
*b | Q7 tensor b (N-D tensor) |
*result | Resulting Q7 tensor of the element wise addition (N-D tensor) |
void aimath_q7_default_tensor_sub_different_shift | ( | const aitensor_t * | a, |
const aitensor_t * | b, | ||
aitensor_t * | result | ||
) |
Performs an element wise addition of Q7 tensors a and b with different shifts.
\[ result = a - b \]
The tensors a, b and result can have different shifts. The function will rescale the tensors internally to perform the subtraction. If a, b and result have the same shift, use aimath_q7_default_tensor_sub_same_shift() instead because it is more efficient.
Example:
*a | Q7 tensor a (N-D tensor) |
*b | Q7 tensor b (N-D tensor) |
*result | Resulting Q7 tensor of the element wise subtraction (N-D tensor) |
void aimath_q7_default_tensor_sub_same_shift | ( | const aitensor_t * | a, |
const aitensor_t * | b, | ||
aitensor_t * | result | ||
) |
Performs an element wise subtraction of Q7 tensors a and b with same shifts.
\[ result = a - b \]
The tensors a, b and result must have the same shift. If a, b and result have the different shifts, use aimath_q7_default_tensor_sub_different_shift() instead.
Example:
*a | Q7 tensor a (N-D tensor) |
*b | Q7 tensor b (N-D tensor) |
*result | Resulting Q7 tensor of the element wise subtraction (N-D tensor) |
void aimath_q7_default_transpose_matrix | ( | aitensor_t * | x | ) |
Transpose a Q7 tensor.
\[ x \leftarrow x^T \]
Example:
*x | Q7 tensor to be transposed (2D tensor) |
void aimath_q7_default_transpose_vector | ( | aitensor_t * | vector | ) |
Transposes a Q7 vector.
The given tensor must be a vector (2D tensor of shape [1 x N] or [N x 1]).
\[ vector \leftarrow vector^T \]
Example:
*vector | Q7 vector (2D tensor of shape [1 x N] or [N x 1]) |
void aimath_q7_default_zero_tensor | ( | aitensor_t * | tensor | ) |
Fills a Q7 tensor with zeros.
\[ tensor_{i} = 0 \]
The function sets all tensor elements to the zero_point given in the tensor parameters.
Example:
*tensor | Q7 tensor to set to zero (N-D tensor) |