| 90 | } |
| 91 | |
| 92 | std::string ReduceKernel::GetKernelBody(TContext* context) const { |
| 93 | auto mode = context->getAttrStr("mode"); |
| 94 | size_t axis = context->getAttrInt("axis"); |
| 95 | auto input = context->getAttrOprand("operand:0"); |
| 96 | std::stringstream writer; |
| 97 | auto dtype = context->getAttrOprand("operand:0").dtype; |
| 98 | auto specifier = Utils::cvt_dtype_specifier(dtype); |
| 99 | writer << gen_helper(mode, dtype); |
| 100 | writer << GenCommonRet() << " "; |
| 101 | writer << GetKernelSignature(context) << "{\n"; |
| 102 | writer << "const size_t axis = " << axis << ";\n"; |
| 103 | writer << StringTemplate::StringTemplateArgs() |
| 104 | .add("specifier", specifier) |
| 105 | .add("gen_init", gen_init(mode, dtype)) |
| 106 | .add("gen_apply", |
| 107 | gen_apply(mode, "acc", "input_data[i * B * C + j * C + k]")) |
| 108 | .add("gen_write", gen_write(mode, "acc", "B")) |
| 109 | .render(R"( |
| 110 | ${specifier}* input_data = (${specifier}*)inputs[0]->ptr; |
| 111 | ${specifier}* output_data = (${specifier}*)outputs[0]->ptr; |
| 112 | |
| 113 | Layout in_layout = inputs[0]->layout; |
| 114 | int A = 1, B, C = 1; |
| 115 | for (int i = 0; i < axis; ++ i) |
| 116 | A *= in_layout.dims[i]; |
| 117 | B = in_layout.dims[axis]; |
| 118 | for (int i = axis + 1; i < in_layout.nr_dim; ++ i) |
| 119 | C *= in_layout.dims[i]; |
| 120 | |
| 121 | for (int i = 0; i < A; ++ i) { |
| 122 | for (int k = 0; k < C; ++ k) { |
| 123 | ${specifier} acc = ${gen_init}; |
| 124 | for (int j = 0; j < B; ++ j) { |
| 125 | acc = ${gen_apply}; |
| 126 | } |
| 127 | |
| 128 | output_data[i * C + k] = ${gen_write}; |
| 129 | } |
| 130 | } |
| 131 | return TinyNN_SUCCESS; |
| 132 | })"); |
| 133 | return writer.str(); |
| 134 | } |
| 135 | |
| 136 | // vim: syntax=cpp.doxygen |
nothing calls this directly
no test coverage detected