| 164 | } // namespace |
| 165 | |
| 166 | std::string PoolingKernel::GetKernelBody(TContext* context) const { |
| 167 | auto format_str = context->getAttrStr("format"); |
| 168 | auto mode_str = context->getAttrStr("mode"); |
| 169 | auto src_dtype = context->getAttrOprand("operand:0").dtype; |
| 170 | auto dst_dtype = context->getAttrOprand("operand:1").dtype; |
| 171 | auto src_specifier = Utils::cvt_dtype_specifier(src_dtype); |
| 172 | auto dst_specifier = Utils::cvt_dtype_specifier(dst_dtype); |
| 173 | auto acc_specifier = get_acc_dtype_specifier(src_dtype, mode_str); |
| 174 | |
| 175 | std::stringstream ss; |
| 176 | const uint32_t window_h = context->getAttrInt("window_h"); |
| 177 | const uint32_t window_w = context->getAttrInt("window_w"); |
| 178 | Pooler pooler(mode_str, window_h * window_w, acc_specifier); |
| 179 | ss << R"( |
| 180 | #include <math.h> |
| 181 | #include <stdbool.h> |
| 182 | )"; |
| 183 | if (src_specifier == "gi_float16_t") |
| 184 | ss << gen_fp16_define(); |
| 185 | ss << pooler.gen_dep(); |
| 186 | ss << GenFormatIter::gen_inline_format_iter_body(format_str); |
| 187 | auto format_iter_symbol = GenFormatIter::gen_inline_format_iter_symbol(format_str); |
| 188 | ss << GenCommonRet() << " " << GetKernelSignature(context) << "{\n"; |
| 189 | |
| 190 | std::string body_temp = R"( |
| 191 | const int oc_ratio = ${oc_ratio}; |
| 192 | const int ic_ratio = ${ic_ratio}; |
| 193 | const int batch_pos = ${batch_pos}; |
| 194 | const int spatial_start = ${spatial_start}; |
| 195 | const int dst_oc_idx = ${dst_oc_idx}; |
| 196 | const int src_ic_idx = ${src_ic_idx}; |
| 197 | |
| 198 | const uint32_t window_h = ${window_h}; |
| 199 | const uint32_t window_w = ${window_w}; |
| 200 | const uint32_t ph = ${pad_h}; |
| 201 | const uint32_t pw = ${pad_w}; |
| 202 | const uint32_t sh = ${stride_h}; |
| 203 | const uint32_t sw = ${stride_w}; |
| 204 | ${src_specifier}* input_data = (${src_specifier}*)inputs[0]->ptr; |
| 205 | TINYNN_ASSERT(input_data); |
| 206 | ${dst_specifier}* output_data = (${dst_specifier}*)outputs[0]->ptr; |
| 207 | TINYNN_ASSERT(output_data); |
| 208 | const Tensor* src_tensor = inputs[0]; |
| 209 | TINYNN_ASSERT(src_tensor); |
| 210 | const Tensor* dst_tensor = outputs[0]; |
| 211 | TINYNN_ASSERT(dst_tensor); |
| 212 | Layout src_layout = inputs[0]->layout; |
| 213 | const Layout dst_layout = dst_tensor->layout; |
| 214 | const uint32_t batch = src_layout.dims[batch_pos]; |
| 215 | const uint32_t ih = src_layout.dims[spatial_start]; |
| 216 | const uint32_t iw = src_layout.dims[spatial_start + 1]; |
| 217 | const uint32_t oc = dst_layout.dims[dst_oc_idx] * oc_ratio; |
| 218 | const uint32_t ic = src_layout.dims[src_ic_idx] * ic_ratio; |
| 219 | const uint32_t oh = dst_layout.dims[spatial_start]; |
| 220 | const uint32_t ow = dst_layout.dims[spatial_start + 1]; |
| 221 | for (uint32_t batch_idx = 0; batch_idx < batch; ++batch_idx) { |
| 222 | for (uint32_t oc_idx = 0; oc_idx < oc; ++oc_idx) { |
| 223 | for (uint32_t oh_idx = 0; oh_idx < oh; ++oh_idx) { |
nothing calls this directly
no test coverage detected