24 #ifndef ARM_COMPUTE_TEST_VALIDATION_CONVOLUTION_H
25 #define ARM_COMPUTE_TEST_VALIDATION_CONVOLUTION_H
36 namespace convolution_3d
42 return (i >= min && i < max);
50 int i_offset,
int w_offset,
int b_offset,
int o_offset,
51 int xi,
int yi,
int width_in,
int height_in,
int depth_in,
int width_weights,
int height_weights,
int dilation_x = 1,
int dilation_y = 1,
int filter_id = 0)
54 const T *in_ptr = in.
data() + i_offset;
55 const TW *w_ptr = weights.
data() + w_offset;
56 const TB *b_ptr =
bias.data() + b_offset;
57 T *out_ptr = out.
data() + o_offset;
59 const int half_width_weights_start = width_weights / 2;
60 const int half_width_weights_end = ((width_weights % 2) == 0) ? (half_width_weights_start - 1) : half_width_weights_start;
61 const int half_height_weights_start = height_weights / 2;
62 const int half_height_weights_end = ((height_weights % 2) == 0) ? (half_height_weights_start - 1) : half_height_weights_start;
68 for(
int ifm = 0; ifm < depth_in; ++ifm)
71 const int offset_slice_in = xi + yi * width_in + ifm * width_in * height_in;
74 for(
int yk = -half_height_weights_start; yk <= half_height_weights_end; ++yk)
76 for(
int xk = -half_width_weights_start; xk <= half_width_weights_end; ++xk)
81 const int idx = xk + half_width_weights_start;
82 const int idy = yk + half_height_weights_start;
84 const T i_value = in_ptr[offset_slice_in + xk * dilation_x + yk * dilation_y * width_in];
85 const TW w_value = w_ptr[idx + idy * width_weights + ifm * width_weights * height_weights];
87 acc += i_value * w_value;
94 *out_ptr = acc + (*b_ptr);
98 template <
typename T,
typename TW,
typename TB, ARM_COMPUTE_REQUIRES_TA((std::is_same<T, u
int8_t>::value || std::is_same<T,
int8_t>::value) &&(std::is_same<TW, u
int8_t>::value
99 || std::is_same<TW,
int8_t>::value)) >
101 int i_offset,
int w_offset,
int b_offset,
int o_offset,
102 int xi,
int yi,
int width_in,
int height_in,
int depth_in,
int width_weights,
int height_weights,
int dilation_x = 1,
int dilation_y = 1,
int filter_id = 0)
104 const T *in_ptr = in.
data() + i_offset;
105 const TW *w_ptr = weights.
data() + w_offset;
106 const TB *b_ptr =
bias.data() + b_offset;
107 T *out_ptr = out.
data() + o_offset;
113 const int input_offset = -iq_info.
offset;
114 const float input_scale = iq_info.
scale;
115 int weights_offset = -wq_info.
offset;
116 float weights_scale = wq_info.
scale;
129 const int output_offset = oq_info.
offset;
130 const float output_scale = oq_info.
scale;
132 int output_multiplier = 0;
133 int output_shift = 0;
134 const float multiplier = input_scale * weights_scale / output_scale;
137 const int half_width_weights_start = width_weights / 2;
138 const int half_width_weights_end = ((width_weights % 2) == 0) ? (half_width_weights_start - 1) : half_width_weights_start;
139 const int half_height_weights_start = height_weights / 2;
140 const int half_height_weights_end = ((height_weights % 2) == 0) ? (half_height_weights_start - 1) : half_height_weights_start;
146 for(
int ifm = 0; ifm < depth_in; ++ifm)
149 const int offset_slice_in = xi + yi * width_in + ifm * width_in * height_in;
152 for(
int yk = -half_height_weights_start; yk <= half_height_weights_end; ++yk)
154 for(
int xk = -half_width_weights_start; xk <= half_width_weights_end; ++xk)
159 const int idx = xk + half_width_weights_start;
160 const int idy = yk + half_height_weights_start;
162 const int32_t i_value = in_ptr[offset_slice_in + xk * dilation_x + yk * dilation_y * width_in];
163 const int32_t w_value = w_ptr[idx + idy * width_weights + ifm * width_weights * height_weights];
164 acc += (i_value + input_offset) * (w_value + weights_offset);