| 172 | } |
| 173 | |
| 174 | static void Run(const Tensor& in_x, const Tensor& in_y, bool adj_x, |
| 175 | bool adj_y, bool trans_x, bool trans_y, |
| 176 | const MatMulBCast& bcast, Tensor* out, int start, |
| 177 | int limit) { |
| 178 | const bool should_bcast = bcast.IsBroadcastingRequired(); |
| 179 | const auto& x_batch_indices = bcast.x_batch_indices(); |
| 180 | const auto& y_batch_indices = bcast.y_batch_indices(); |
| 181 | for (int64 i = start; i < limit; ++i) { |
| 182 | const int64 x_batch_index = should_bcast ? x_batch_indices[i] : i; |
| 183 | const int64 y_batch_index = should_bcast ? y_batch_indices[i] : i; |
| 184 | auto x = ConstTensorSliceToEigenMatrix(in_x, x_batch_index); |
| 185 | auto y = ConstTensorSliceToEigenMatrix(in_y, y_batch_index); |
| 186 | auto z = TensorSliceToEigenMatrix(out, i); |
| 187 | if (!adj_x && !trans_x) { |
| 188 | if (!adj_y && !trans_y) { |
| 189 | z.noalias() = x * y; |
| 190 | } else if (adj_y) { |
| 191 | z.noalias() = x * y.adjoint(); |
| 192 | } else { |
| 193 | z.noalias() = x * y.transpose(); |
| 194 | } |
| 195 | } else if (adj_x) { |
| 196 | if (!adj_y && !trans_y) { |
| 197 | z.noalias() = x.adjoint() * y; |
| 198 | } else if (adj_y) { |
| 199 | z.noalias() = x.adjoint() * y.adjoint(); |
| 200 | } else { // trans_y == true |
| 201 | z.noalias() = x.adjoint() * y.transpose(); |
| 202 | } |
| 203 | } else { // trans_x == true |
| 204 | if (!adj_y && !trans_y) { |
| 205 | z.noalias() = x.transpose() * y; |
| 206 | } else if (adj_y) { |
| 207 | z.noalias() = x.transpose() * y.adjoint(); |
| 208 | } else { // trans_y == true |
| 209 | z.noalias() = x.transpose() * y.transpose(); |
| 210 | } |
| 211 | } |
| 212 | } |
| 213 | } |
| 214 | }; |
| 215 | |
| 216 | } // namespace |
nothing calls this directly
no test coverage detected