| 69 | } // namespace |
| 70 | |
| 71 | std::string BatchedMatrixMulKernel::GetKernelBody(TContext* context) const { |
| 72 | std::stringstream ss; |
| 73 | bool trans_a = context->getAttrBool("transposeA"); |
| 74 | bool trans_b = context->getAttrBool("transposeB"); |
| 75 | auto type = Utils::cvt_dtype_specifier(context->getAttrOprand("operand:0").dtype); |
| 76 | if (type == "gi_float16_t") { |
| 77 | ss << gen_fp16_define(); |
| 78 | } |
| 79 | ss << GenCommonRet() << " " << GetKernelSignature(context); |
| 80 | std::string body_temp = R"({ |
| 81 | ${c_type}* a_data = (${c_type}*)inputs[0]->ptr; |
| 82 | ${c_type}* b_data = (${c_type}*)inputs[1]->ptr; |
| 83 | ${c_type}* c_data = (${c_type}*)outputs[0]->ptr; |
| 84 | TINYNN_ASSERT(a_data); |
| 85 | TINYNN_ASSERT(b_data); |
| 86 | TINYNN_ASSERT(c_data); |
| 87 | const Tensor* a_tensor = inputs[0]; |
| 88 | const Tensor* b_tensor = inputs[1]; |
| 89 | const Tensor* c_tensor = outputs[0]; |
| 90 | const Layout a_layout = a_tensor->layout; |
| 91 | const Layout b_layout = b_tensor->layout; |
| 92 | const Layout c_layout = c_tensor->layout; |
| 93 | const int stride_a = a_layout.stride[0]; |
| 94 | const int stride_b = b_layout.stride[0]; |
| 95 | const int stride_c = c_layout.stride[0]; |
| 96 | const int lda = a_layout.stride[1]; |
| 97 | const int ldb = b_layout.stride[1]; |
| 98 | const int ldc = c_layout.stride[1]; |
| 99 | const int b = c_layout.dims[0]; |
| 100 | const int m = c_layout.dims[1]; |
| 101 | const int n = c_layout.dims[2]; |
| 102 | ${k_init} |
| 103 | for(int b_idx = 0; b_idx < b; ++b_idx){ |
| 104 | for (int m_idx = 0; m_idx < m; ++m_idx) { |
| 105 | for (int n_idx = 0; n_idx < n; ++n_idx) { |
| 106 | ${c_type} sum = 0.0; |
| 107 | for (int k_idx = 0; k_idx < k; ++k_idx) { |
| 108 | ${a_init} |
| 109 | ${b_init} |
| 110 | sum += a_val * b_val; |
| 111 | } |
| 112 | c_data[m_idx * ldc + n_idx] = sum; |
| 113 | } |
| 114 | } |
| 115 | a_data += stride_a; |
| 116 | b_data += stride_b; |
| 117 | c_data += stride_c; |
| 118 | } |
| 119 | return TinyNN_SUCCESS; |
| 120 | })"; |
| 121 | |
| 122 | ss << StringTemplate::StringTemplateArgs() |
| 123 | .add("k_init", emit_k(trans_a)) |
| 124 | .add("a_init", emit_a_val(trans_a, type)) |
| 125 | .add("b_init", emit_b_val(trans_b, type)) |
| 126 | .add("c_type", type) |
| 127 | .render(body_temp); |
| 128 | return ss.str(); |
nothing calls this directly
no test coverage detected