| 24 | } |
| 25 | |
| 26 | static int ref_conv_fp16(const __fp16* input, __fp16* output, const __fp16* kernel, const __fp16* bias, op_data* param) |
| 27 | { |
| 28 | int batch = param->batch; |
| 29 | int group = param->group; |
| 30 | int input_c = param->in_shape[0] / group; |
| 31 | int input_h = param->in_shape[1]; |
| 32 | int input_w = param->in_shape[2]; |
| 33 | int output_c = param->out_shape[0] / group; |
| 34 | int output_h = param->out_shape[1]; |
| 35 | int output_w = param->out_shape[2]; |
| 36 | |
| 37 | int kernel_size = input_c * param->kernels[0] * param->kernels[1]; |
| 38 | int n, g, c, h, w, kc, kh, kw; |
| 39 | int input_offset = 0; |
| 40 | int kernel_offset = 0; |
| 41 | int output_offset = 0; |
| 42 | for(n = 0; n < batch; ++n) |
| 43 | { |
| 44 | for(g = 0; g < group; ++g) |
| 45 | { |
| 46 | for(c = 0; c < output_c; ++c) |
| 47 | { |
| 48 | for(h = 0; h < output_h; ++h) |
| 49 | { |
| 50 | for(w = 0; w < output_w; ++w) |
| 51 | { |
| 52 | const int h_start = (h * param->strides[0]) - param->pads[0]; |
| 53 | const int w_start = (w * param->strides[1]) - param->pads[1]; |
| 54 | #if !defined(__ARM_ARCH) || __ARM_ARCH < 8 |
| 55 | float total = bias ? fp16_to_fp32(bias[output_c * g + c]) : 0; |
| 56 | #else |
| 57 | __fp16 total = bias ? bias[output_c * g + c] : 0; |
| 58 | #endif |
| 59 | if(param->layout == 0) |
| 60 | { |
| 61 | output_offset = n * group * output_c * output_h * output_w + |
| 62 | g * output_c * output_h * output_w + c * output_h * output_w + |
| 63 | h * output_w + w; |
| 64 | } |
| 65 | else |
| 66 | { |
| 67 | output_offset = n * group * output_c * output_h * output_w + |
| 68 | h * output_w * group * output_c + w * group * output_c + output_c * g + c; |
| 69 | } |
| 70 | for(kc = 0; kc < input_c; ++kc) |
| 71 | { |
| 72 | for(kh = 0; kh < param->kernels[0]; ++kh) |
| 73 | { |
| 74 | for(kw = 0; kw < param->kernels[1]; ++kw) |
| 75 | { |
| 76 | const int cur_y = h_start + param->dilations[0] * kh; |
| 77 | const int cur_x = w_start + param->dilations[1] * kw; |
| 78 | // If the location is outside the bounds of the input image, |
| 79 | // use zero as a default value. |
| 80 | if((cur_x >= 0) && (cur_x < input_w) && (cur_y >= 0) && (cur_y < input_h)) |
| 81 | { |
| 82 | if(param->layout == 0) |
| 83 | { |
nothing calls this directly
no test coverage detected