| 1164 | } |
| 1165 | |
| 1166 | void ffn_cpu( |
| 1167 | float* xout, float* x, |
| 1168 | float* w1, float* w2, float* w3, |
| 1169 | int hidden_dim, int dim, |
| 1170 | ActivationType act |
| 1171 | ) { |
| 1172 | float* hb = new float[hidden_dim]; |
| 1173 | float* hb2 = new float[hidden_dim]; |
| 1174 | // mix self.w2(F.silu(self.w1(x)) * self.w3(x)) |
| 1175 | // Note this is a feedforward with a GLU, not a simple MLP. |
| 1176 | matmul_unscaled(hb, x, QTensor(Quant::F32, {dim, hidden_dim}, w1, dim*hidden_dim*sizeof(float))); |
| 1177 | matmul_unscaled(hb2, x, QTensor(Quant::F32, {dim, hidden_dim}, w3, dim*hidden_dim*sizeof(float))); |
| 1178 | switch (act) { |
| 1179 | case ActivationType::GELU: { |
| 1180 | for (int i = 0; i < hidden_dim; ++i) { |
| 1181 | hb[i] = gelu(hb[i]) * hb2[i]; |
| 1182 | } |
| 1183 | break; |
| 1184 | } |
| 1185 | case ActivationType::SILU: { |
| 1186 | for (int i = 0; i < hidden_dim; ++i) { |
| 1187 | hb[i] = silu(hb[i]) * hb2[i]; |
| 1188 | } |
| 1189 | break; |
| 1190 | } |
| 1191 | } |
| 1192 | |
| 1193 | matmul_unscaled(xout, hb, QTensor(Quant::F32, {hidden_dim, dim}, w2, hidden_dim*dim*sizeof(float))); |
| 1194 | |
| 1195 | delete[] hb; |
| 1196 | delete[] hb2; |
| 1197 | } |
| 1198 | |
| 1199 | template void Block::_block_cpu<float>(InferenceState&, int, int, int, int) const; |
| 1200 | template void Block::_block_cpu<f16_t>(InferenceState&, int, int, int, int) const; |
nothing calls this directly
no test coverage detected