| 202 | // ---------------------------------------------------------------------------------------- |
| 203 | |
| 204 | void gemm ( |
| 205 | float beta, |
| 206 | tensor& dest, |
| 207 | float alpha, |
| 208 | const tensor& lhs, |
| 209 | bool trans_lhs, |
| 210 | const tensor& rhs, |
| 211 | bool trans_rhs, |
| 212 | operation_mode mode |
| 213 | ) |
| 214 | { |
| 215 | #ifdef DLIB_USE_CUDA |
| 216 | cuda::gemm(beta, dest, alpha, lhs, trans_lhs, rhs, trans_rhs, mode); |
| 217 | #else |
| 218 | if (mode == operation_mode::CHANNEL_WISE) |
| 219 | { |
| 220 | if (beta != 0) |
| 221 | { |
| 222 | if (trans_lhs && trans_rhs) |
| 223 | dest = alpha * trans(mat(lhs)) * trans(mat(rhs)) + beta * mat(dest); |
| 224 | else if (!trans_lhs && trans_rhs) |
| 225 | dest = alpha * mat(lhs) * trans(mat(rhs)) + beta * mat(dest); |
| 226 | else if (trans_lhs && !trans_rhs) |
| 227 | dest = alpha * trans(mat(lhs)) * mat(rhs) + beta * mat(dest); |
| 228 | else |
| 229 | dest = alpha * mat(lhs) * mat(rhs) + beta * mat(dest); |
| 230 | } |
| 231 | else |
| 232 | { |
| 233 | if (trans_lhs && trans_rhs) |
| 234 | dest = alpha * trans(mat(lhs)) * trans(mat(rhs)); |
| 235 | else if (!trans_lhs && trans_rhs) |
| 236 | dest = alpha * mat(lhs) * trans(mat(rhs)); |
| 237 | else if (trans_lhs && !trans_rhs) |
| 238 | dest = alpha * trans(mat(lhs)) * mat(rhs); |
| 239 | else |
| 240 | dest = alpha * mat(lhs) * mat(rhs); |
| 241 | } |
| 242 | } |
| 243 | else if (mode == operation_mode::PLANE_WISE) |
| 244 | { |
| 245 | auto is_matrix = [](const auto& tensor) { |
| 246 | return ((tensor.num_samples() * tensor.k() == 1 && tensor.nr() * tensor.nc() > 1) || |
| 247 | (tensor.num_samples() * tensor.k() > 1 && tensor.nr() * tensor.nc() == 1)); |
| 248 | }; |
| 249 | |
| 250 | long num_samples = std::min({ lhs.num_samples(), rhs.num_samples(), dest.num_samples() }); |
| 251 | long num_channels = std::min({ lhs.k(), rhs.k(), dest.k() }); |
| 252 | const bool lhs_is_matrix = is_matrix(lhs), rhs_is_matrix = is_matrix(rhs), dest_is_matrix = is_matrix(dest); |
| 253 | |
| 254 | if (lhs_is_matrix && rhs_is_matrix && dest_is_matrix) { |
| 255 | num_samples = num_channels = 1; |
| 256 | } |
| 257 | |
| 258 | long lhs_rows = (lhs_is_matrix && lhs.num_samples() > 1) ? lhs.num_samples() : lhs.nr(); |
| 259 | long lhs_cols = (lhs_is_matrix && lhs.k() > 1) ? lhs.k() : lhs.nc(); |
| 260 | long rhs_rows = (rhs_is_matrix && rhs.num_samples() > 1) ? rhs.num_samples() : rhs.nr(); |
| 261 | long rhs_cols = (rhs_is_matrix && rhs.k() > 1) ? rhs.k() : rhs.nc(); |