| 259 | */ |
| 260 | template <typename T> |
| 261 | SimpleTensor<T> complex_mul_and_reduce(const SimpleTensor<T> &input, const SimpleTensor<T> &weights) |
| 262 | { |
| 263 | const uint32_t W = input.shape().x(); |
| 264 | const uint32_t H = input.shape().y(); |
| 265 | const uint32_t Ci = input.shape().z(); |
| 266 | const uint32_t Co = weights.shape()[3]; |
| 267 | const uint32_t N = input.shape().total_size() / (W * H * Ci); |
| 268 | |
| 269 | TensorShape output_shape = input.shape(); |
| 270 | output_shape.set(2, Co); |
| 271 | SimpleTensor<T> dst(output_shape, input.data_type(), input.num_channels()); |
| 272 | |
| 273 | // dst memory to zero |
| 274 | const auto total_element_count = dst.num_channels() * dst.num_elements(); |
| 275 | std::fill_n(dst.data(), total_element_count, 0); |
| 276 | |
| 277 | for (uint32_t b = 0; b < N; ++b) |
| 278 | { |
| 279 | for (uint32_t co = 0; co < Co; ++co) |
| 280 | { |
| 281 | for (uint32_t ci = 0; ci < Ci; ++ci) |
| 282 | { |
| 283 | for (uint32_t h = 0; h < H; ++h) |
| 284 | { |
| 285 | for (uint32_t w = 0; w < W; ++w) |
| 286 | { |
| 287 | const uint32_t i_index = w + h * W + ci * H * W + b * H * W * Ci; |
| 288 | const uint32_t w_index = w + h * W + ci * H * W + co * H * W * Ci; |
| 289 | const uint32_t o_index = w + h * W + co * H * W + b * H * W * Co; |
| 290 | const Coordinates i_coords = index2coords(input.shape(), i_index); |
| 291 | const Coordinates w_coords = index2coords(weights.shape(), w_index); |
| 292 | const Coordinates o_coords = index2coords(dst.shape(), o_index); |
| 293 | |
| 294 | auto i_ptr = static_cast<const T *>(input(i_coords)); |
| 295 | auto w_ptr = static_cast<const T *>(weights(w_coords)); |
| 296 | auto o_ptr = static_cast<T *>(dst(o_coords)); |
| 297 | |
| 298 | const T Rin = i_ptr[0]; |
| 299 | const T Iin = i_ptr[1]; |
| 300 | const T Rw = w_ptr[0]; |
| 301 | const T Iw = w_ptr[1]; |
| 302 | |
| 303 | o_ptr[0] += Rin * Rw - Iin * Iw; |
| 304 | o_ptr[1] += Rin * Iw + Rw * Iin; |
| 305 | } |
| 306 | } |
| 307 | } |
| 308 | } |
| 309 | } |
| 310 | return dst; |
| 311 | } |
| 312 | } // namespace |
| 313 | |
| 314 | template <typename T> |
no test coverage detected