interleave most kernels in 8, last 7 interleave in 2, copy the lat kernels
| 46 | |
| 47 | // interleave most kernels in 8, last 7 interleave in 2, copy the lat kernels |
| 48 | void interleave_kernel(const float* kernel, const float* kernel_interleaved, int kernel_chan, int kernel_size) |
| 49 | { |
| 50 | int i, j, k; |
| 51 | float* cur_kernel[8]; |
| 52 | float* cur_kernel_interleaved; |
| 53 | |
| 54 | // interleave 8 kernel |
| 55 | for(i = 0; i < (kernel_chan & -8); i += 8) |
| 56 | { |
| 57 | for(j = 0; j < 8; j++) |
| 58 | cur_kernel[j] = ( float* )kernel + kernel_size * (i + j); |
| 59 | cur_kernel_interleaved = ( float* )kernel_interleaved + kernel_size * i; |
| 60 | for(k = 0; k < kernel_size; k++) |
| 61 | for(j = 0; j < 8; j++) |
| 62 | cur_kernel_interleaved[8 * k + j] = *(cur_kernel[j] + k); |
| 63 | } |
| 64 | |
| 65 | // interleave 2 kernel |
| 66 | for(; i < (kernel_chan & -2); i += 2) |
| 67 | { |
| 68 | for(j = 0; j < 2; j++) |
| 69 | cur_kernel[j] = ( float* )kernel + kernel_size * (i + j); |
| 70 | cur_kernel_interleaved = ( float* )kernel_interleaved + kernel_size * i; |
| 71 | for(k = 0; k < kernel_size; k++) |
| 72 | for(j = 0; j < 2; j++) |
| 73 | cur_kernel_interleaved[2 * k + j] = *(cur_kernel[j] + k); |
| 74 | } |
| 75 | |
| 76 | // copy last kernel |
| 77 | if(kernel_chan & 0x1) |
| 78 | { |
| 79 | cur_kernel[0] = ( float* )kernel + kernel_size * i; |
| 80 | cur_kernel_interleaved = ( float* )kernel_interleaved + kernel_size * i; |
| 81 | for(k = 0; k < kernel_size; k++) |
| 82 | cur_kernel_interleaved[k] = *(cur_kernel[0] + k); |
| 83 | } |
| 84 | |
| 85 | return; |
| 86 | } |
| 87 | |
| 88 | // start and end channel must be 8 aligned |
| 89 | void sgemv1x8(const float* input, float* weight_interleaved, bool have_biases, const float* biases, const float* output, |