| 338 | // ---------------------------------------------------------------------------------------- |
| 339 | |
| 340 | void multiply_zero_padded ( |
| 341 | bool add_to, |
| 342 | tensor& dest, |
| 343 | const tensor& src1, |
| 344 | const tensor& src2 |
| 345 | ) |
| 346 | { |
| 347 | auto d = dest.host(); |
| 348 | auto s1 = src1.host(); |
| 349 | auto s2 = src2.host(); |
| 350 | |
| 351 | // Do the simple and fast version if everything has the same dimensions |
| 352 | if (have_same_dimensions(dest, src1) && |
| 353 | have_same_dimensions(dest, src2)) |
| 354 | { |
| 355 | if (add_to) |
| 356 | { |
| 357 | for (size_t i = 0; i < dest.size(); ++i) |
| 358 | d[i] += s1[i] * s2[i]; |
| 359 | } |
| 360 | else |
| 361 | { |
| 362 | for (size_t i = 0; i < dest.size(); ++i) |
| 363 | d[i] = s1[i] * s2[i]; |
| 364 | } |
| 365 | return; |
| 366 | } |
| 367 | |
| 368 | // Otherwise, do the more complex version with bounds checking. |
| 369 | for (long n = 0; n < dest.num_samples(); ++n) |
| 370 | { |
| 371 | for (long k = 0; k < dest.k(); ++k) |
| 372 | { |
| 373 | for (long r = 0; r < dest.nr(); ++r) |
| 374 | { |
| 375 | for (long c = 0; c < dest.nc(); ++c) |
| 376 | { |
| 377 | float v1 = 0; |
| 378 | float v2 = 0; |
| 379 | |
| 380 | // if this index is inside src1 |
| 381 | if (n < src1.num_samples() && |
| 382 | k < src1.k() && |
| 383 | r < src1.nr() && |
| 384 | c < src1.nc() ) |
| 385 | { |
| 386 | const auto s_idx = ((n*src1.k() + k)*src1.nr() + r)*src1.nc() + c; |
| 387 | v1 = s1[s_idx]; |
| 388 | } |
| 389 | |
| 390 | // if this index is inside src2 |
| 391 | if (n < src2.num_samples() && |
| 392 | k < src2.k() && |
| 393 | r < src2.nr() && |
| 394 | c < src2.nc() ) |
| 395 | { |
| 396 | const auto s_idx = ((n*src2.k() + k)*src2.nr() + r)*src2.nc() + c; |
| 397 | v2 = s2[s_idx]; |