| #include "edge-impulse-sdk/classifier/ei_classifier_config.h" |
| #if EI_CLASSIFIER_TFLITE_LOAD_CMSIS_NN_SOURCES |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| #include "edge-impulse-sdk/CMSIS/NN/Include/arm_nnfunctions.h" |
| #include "edge-impulse-sdk/CMSIS/NN/Include/arm_nnsupportfunctions.h" |
|
|
| |
| |
| |
| |
|
|
| arm_cmsis_nn_status arm_softmax_s16(const int16_t *input, |
| const int32_t num_rows, |
| const int32_t row_size, |
| const int32_t mult, |
| const int32_t shift, |
| const cmsis_nn_softmax_lut_s16 *softmax_params, |
| int16_t *output) |
| { |
| int32_t col = 0; |
| int32_t row_idx; |
|
|
| if (softmax_params->exp_lut == NULL || softmax_params->one_by_one_lut == NULL) |
| { |
| return ARM_CMSIS_NN_ARG_ERROR; |
| } |
|
|
| for (row_idx = 0; row_idx < num_rows; ++row_idx) |
| { |
| |
| int16_t max = *input; |
| for (col = 1; col < row_size; ++col) |
| { |
| max = MAX(max, input[col]); |
| } |
|
|
| int32_t diff = 0; |
| int32_t sum = 0; |
| int16_t *cached_exp_results = output; |
|
|
| for (col = 0; col < row_size; ++col) |
| { |
| diff = input[col] - max; |
| const int32_t scaled_diff = arm_nn_requantize(diff, mult, shift); |
| const int32_t symmetric_scaled_diff = scaled_diff + NN_Q15_MAX; |
| const int16_t saturated_symmetric_scaled_diff = MIN(MAX(symmetric_scaled_diff, NN_Q15_MIN), NN_Q15_MAX); |
|
|
| |
| const int16_t index = (256 + (saturated_symmetric_scaled_diff >> 7)); |
| const int16_t offset = saturated_symmetric_scaled_diff & 0x7f; |
| const int16_t base = softmax_params->exp_lut[index]; |
| const int16_t slope = softmax_params->exp_lut[index + 1] - softmax_params->exp_lut[index]; |
| const int16_t delta = (slope * offset + 64) >> 7; |
| const int16_t result = (base + delta); |
| cached_exp_results[col] = result; |
|
|
| sum += cached_exp_results[col]; |
| } |
|
|
| const int32_t headroom = __CLZ(sum); |
|
|
| |
| const int32_t shifted_sum = (((sum) << (headroom - 1)) + (1 << 13)) >> 14; |
|
|
| |
| |
| |
| const int16_t symmetric_shifted_sum = shifted_sum - 98304; |
|
|
| |
| const int16_t index = (256 + (symmetric_shifted_sum >> 7)); |
| const int16_t offset = symmetric_shifted_sum & 0x7f; |
| const int16_t base = softmax_params->one_by_one_lut[index]; |
| const int16_t slope = softmax_params->one_by_one_lut[index + 1] - softmax_params->one_by_one_lut[index]; |
| const int16_t delta = (slope * offset + 64) >> 7; |
| const int16_t one_by_one_result = (base + delta); |
|
|
| for (col = 0; col < row_size; ++col) |
| { |
| const int16_t right_shift = 30 - headroom; |
| int32_t result = (cached_exp_results[col] * one_by_one_result) >> right_shift; |
| result = (result + 1) >> 1; |
| output[col] = (int16_t)result; |
| } |
|
|
| output += row_size; |
| input += row_size; |
| } |
|
|
| return ARM_CMSIS_NN_SUCCESS; |
| } |
|
|
| |
| |
| |
|
|
| #endif |
|
|