| #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_convolve_HWC_q7_RGB(const q7_t *Im_in, |
| const uint16_t dim_im_in, |
| const uint16_t ch_im_in, |
| const q7_t *wt, |
| const uint16_t ch_im_out, |
| const uint16_t dim_kernel, |
| const uint16_t padding, |
| const uint16_t stride, |
| const q7_t *bias, |
| const uint16_t bias_shift, |
| const uint16_t out_shift, |
| q7_t *Im_out, |
| const uint16_t dim_im_out, |
| q15_t *bufferA, |
| q7_t *bufferB) |
| { |
| (void)bufferB; |
| #if defined(ARM_MATH_DSP) && !defined(ARM_MATH_MVEI) |
| |
| int16_t i_out_y, i_out_x, i_ker_y, i_ker_x; |
|
|
| |
| |
| |
| |
| q15_t *pBuffer = bufferA; |
| q7_t *pOut = Im_out; |
|
|
| |
| if (ch_im_in != 3) |
| { |
| return ARM_CMSIS_NN_ARG_ERROR; |
| } |
| |
| for (i_out_y = 0; i_out_y < dim_im_out; i_out_y++) |
| { |
| for (i_out_x = 0; i_out_x < dim_im_out; i_out_x++) |
| { |
| for (i_ker_y = i_out_y * stride - padding; i_ker_y < i_out_y * stride - padding + dim_kernel; i_ker_y++) |
| { |
| for (i_ker_x = i_out_x * stride - padding; i_ker_x < i_out_x * stride - padding + dim_kernel; i_ker_x++) |
| { |
| if (i_ker_y < 0 || i_ker_y >= dim_im_in || i_ker_x < 0 || i_ker_x >= dim_im_in) |
| { |
| |
| arm_memset_q7((q7_t *)pBuffer, (q7_t)0, 3 * sizeof(q15_t)); |
| pBuffer += 3; |
| } |
| else |
| { |
| |
| |
| |
| |
|
|
| const q7_t *pPixel = Im_in + (i_ker_y * dim_im_in + i_ker_x) * 3; |
| q31_t buf = arm_nn_read_q7x4(pPixel); |
|
|
| union arm_nnword top; |
| union arm_nnword bottom; |
|
|
| top.word = __SXTB16(buf); |
| bottom.word = __SXTB16(__ROR(buf, 8)); |
|
|
| #ifndef ARM_MATH_BIG_ENDIAN |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| *pBuffer++ = top.half_words[0]; |
| int32_t packed_word = __PKHBT(bottom.word, top.word, 0); |
| arm_memcpy_q7((q7_t *)pBuffer, (q7_t *)&packed_word, 4); |
| #else |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| *pBuffer++ = bottom.half_words[0]; |
| int32_t packed_word = __PKHTB(top.word, bottom.word, 0); |
| arm_memcpy_q7((q7_t *)pBuffer, (q7_t *)&packed_word, 4); |
| #endif |
| pBuffer += 2; |
| } |
| } |
| } |
|
|
| if (pBuffer == bufferA + 2 * 3 * dim_kernel * dim_kernel) |
| { |
| pOut = arm_nn_mat_mult_kernel_q7_q15( |
| wt, bufferA, ch_im_out, 3 * dim_kernel * dim_kernel, bias_shift, out_shift, bias, pOut); |
|
|
| |
| pBuffer = bufferA; |
| } |
| } |
| } |
|
|
| |
| if (pBuffer != bufferA) |
| { |
| const q7_t *pA = wt; |
| int i; |
|
|
| for (i = 0; i < ch_im_out; i++) |
| { |
| q31_t sum = ((q31_t)bias[i] << bias_shift) + NN_ROUND(out_shift); |
| q15_t *pB = bufferA; |
| |
| uint16_t colCnt = 3 * dim_kernel * dim_kernel >> 2; |
|
|
| while (colCnt) |
| { |
|
|
| q31_t inA1, inA2; |
| q31_t inB1, inB2; |
|
|
| pA = read_and_pad(pA, &inA1, &inA2); |
|
|
| inB1 = arm_nn_read_q15x2_ia((const q15_t **)&pB); |
| sum = __SMLAD(inA1, inB1, sum); |
| inB2 = arm_nn_read_q15x2_ia((const q15_t **)&pB); |
| sum = __SMLAD(inA2, inB2, sum); |
|
|
| colCnt--; |
| } |
| colCnt = 3 * dim_kernel * dim_kernel & 0x3; |
| while (colCnt) |
| { |
| q7_t inA1 = *pA++; |
| q15_t inB1 = *pB++; |
| sum += inA1 * inB1; |
| colCnt--; |
| } |
| *pOut++ = (q7_t)__SSAT((sum >> out_shift), 8); |
| } |
| } |
| #else |
| (void)bufferA; |
| |
| int i, j, k, l, m, n; |
| int conv_out; |
| int in_row, in_col; |
|
|
| |
| if (ch_im_in != 3) |
| { |
| return ARM_CMSIS_NN_ARG_ERROR; |
| } |
|
|
| for (i = 0; i < ch_im_out; i++) |
| { |
| for (j = 0; j < dim_im_out; j++) |
| { |
| for (k = 0; k < dim_im_out; k++) |
| { |
| conv_out = (bias[i] << bias_shift) + NN_ROUND(out_shift); |
| for (m = 0; m < dim_kernel; m++) |
| { |
| for (n = 0; n < dim_kernel; n++) |
| { |
| |
| in_row = stride * j + m - padding; |
| in_col = stride * k + n - padding; |
| if (in_row >= 0 && in_col >= 0 && in_row < dim_im_in && in_col < dim_im_in) |
| { |
| for (l = 0; l < ch_im_in; l++) |
| { |
| conv_out += Im_in[(in_row * dim_im_in + in_col) * ch_im_in + l] * |
| wt[i * ch_im_in * dim_kernel * dim_kernel + (m * dim_kernel + n) * ch_im_in + l]; |
| } |
| } |
| } |
| } |
| Im_out[i + (j * dim_im_out + k) * ch_im_out] = (q7_t)__SSAT((conv_out >> out_shift), 8); |
| } |
| } |
| } |
|
|
| #endif |
|
|
| |
| return (ARM_CMSIS_NN_SUCCESS); |
| } |
|
|
| |
| |
| |
|
|
| #endif |
|
|