10 #include "etl/concepts.hpp" 26 template <
size_t C1,
size_t C2,
size_t S1,
size_t S2,
size_t P1,
size_t P2,
typename C,
typename M>
28 auto error = errors(i, j);
31 if constexpr (P1 || P2) {
32 if (cpp_unlikely(i < P1 || j < P2 || i >= etl::dim<0>(errors) - P1 || j >= etl::dim<1>(errors) - P2)) {
33 const size_t base_i = i * S1 - P1;
34 const size_t base_j = j * S2 - P2;
36 for (
size_t ii = 0; ii < C1; ++ii) {
37 for (
size_t jj = 0; jj < C2; ++jj) {
38 if (base_i + ii < etl::dim<0>(m) && base_j + jj < etl::dim<1>(m)) {
39 if constexpr (S1 == C1 && S2 == C2) {
40 m(base_i + ii, base_j + jj) = error /
value_t<M>(C1 * C2);
42 m(base_i + ii, base_j + jj) += error /
value_t<M>(C1 * C2);
52 if constexpr (S1 == C1 && S2 == C2) {
53 for (
size_t ii = 0; ii < C1; ++ii) {
54 for (
size_t jj = 0; jj < C2; ++jj) {
55 m(i * S1 - P1 + ii, j * S2 - P2 + jj) = error /
value_t<M>(C1 * C2);
59 for (
size_t ii = 0; ii < C1; ++ii) {
60 for (
size_t jj = 0; jj < C2; ++jj) {
61 m(i * S1 - P1 + ii, j * S2 - P2 + jj) += error /
value_t<M>(C1 * C2);
76 template <
size_t C1,
size_t C2,
size_t S1,
size_t S2,
size_t P1,
size_t P2,
typename C,
typename M>
77 static void pool_block_3d(
const C& errors, M& m,
size_t q,
size_t i,
size_t j) {
78 auto error = errors(q, i, j);
81 if constexpr (P1 || P2) {
82 if (cpp_unlikely(i < P1 || j < P2 || i >= etl::dim<1>(errors) - P1 || j >= etl::dim<2>(errors) - P2)) {
83 const size_t base_i = i * S1 - P1;
84 const size_t base_j = j * S2 - P2;
86 for (
size_t ii = 0; ii < C1; ++ii) {
87 for (
size_t jj = 0; jj < C2; ++jj) {
88 if (base_i + ii < etl::dim<1>(m) && base_j + jj < etl::dim<2>(m)) {
89 if constexpr (S1 == C1 && S2 == C2) {
90 m(q, base_i + ii, base_j + jj) = error /
value_t<M>(C1 * C2);
92 m(q, base_i + ii, base_j + jj) += error /
value_t<M>(C1 * C2);
102 if constexpr (S1 == C1 && S2 == C2) {
103 for (
size_t ii = 0; ii < C1; ++ii) {
104 for (
size_t jj = 0; jj < C2; ++jj) {
105 m(q, i * S1 - P1 + ii, j * S2 - P2 + jj) = error /
value_t<M>(C1 * C2);
109 for (
size_t ii = 0; ii < C1; ++ii) {
110 for (
size_t jj = 0; jj < C2; ++jj) {
111 m(q, i * S1 - P1 + ii, j * S2 - P2 + jj) += error / (C1 * C2);
126 template <
size_t C1,
size_t C2,
size_t S1,
size_t S2,
size_t P1,
size_t P2,
typename C,
typename M>
127 static void pool_block_4d(
const C& errors, M& m,
size_t p,
size_t q,
size_t i,
size_t j) {
128 auto error = errors(p, q, i, j);
131 if constexpr (P1 || P2) {
132 if (cpp_unlikely(i < P1 || j < P2 || i >= etl::dim<2>(errors) - P1 || j >= etl::dim<3>(errors) - P2)) {
133 const size_t base_i = i * S1 - P1;
134 const size_t base_j = j * S2 - P2;
136 for (
size_t ii = 0; ii < C1; ++ii) {
137 for (
size_t jj = 0; jj < C2; ++jj) {
138 if (base_i + ii < etl::dim<2>(m) && base_j + jj < etl::dim<3>(m)) {
139 if constexpr (S1 == C1 && S2 == C2) {
140 m(p, q, base_i + ii, base_j + jj) = error /
value_t<M>(C1 * C2);
142 m(p, q, base_i + ii, base_j + jj) += error /
value_t<M>(C1 * C2);
152 if constexpr (S1 == C1 && S2 == C2) {
153 for (
size_t ii = 0; ii < C1; ++ii) {
154 for (
size_t jj = 0; jj < C2; ++jj) {
155 m(p, q, i * S1 - P1 + ii, j * S2 - P2 + jj) = error /
value_t<M>(C1 * C2);
159 for (
size_t ii = 0; ii < C1; ++ii) {
160 for (
size_t jj = 0; jj < C2; ++jj) {
161 m(p, q, i * S1 - P1 + ii, j * S2 - P2 + jj) += error /
value_t<M>(C1 * C2);
176 template <
typename C,
typename M>
177 static void pool_block_2d(
const C& errors, M& m,
size_t i,
size_t j,
size_t c1,
size_t c2,
size_t s1,
size_t s2,
size_t p1,
size_t p2) {
178 auto error = errors(i, j);
181 if (cpp_unlikely(p1 || p2)) {
182 if (cpp_unlikely(i < p1 || j < p2 || i >= etl::dim<0>(errors) - p1 || j >= etl::dim<1>(errors) - p2)) {
183 const size_t base_i = i * s1 - p1;
184 const size_t base_j = j * s2 - p2;
186 for (
size_t ii = 0; ii < c1; ++ii) {
187 for (
size_t jj = 0; jj < c2; ++jj) {
188 if (base_i + ii < etl::dim<0>(m) && base_j + jj < etl::dim<1>(m)) {
189 if (s1 == c1 && s2 == c2) {
190 m(base_i + ii, base_j + jj) = error /
value_t<M>(c1 * c2);
192 m(base_i + ii, base_j + jj) += error /
value_t<M>(c1 * c2);
202 if (s1 == c1 && s2 == c2) {
203 for (
size_t ii = 0; ii < c1; ++ii) {
204 for (
size_t jj = 0; jj < c2; ++jj) {
205 m(i * s1 - p1 + ii, j * s2 - p2 + jj) = error /
value_t<M>(c1 * c2);
209 for (
size_t ii = 0; ii < c1; ++ii) {
210 for (
size_t jj = 0; jj < c2; ++jj) {
211 m(i * s1 - p1 + ii, j * s2 - p2 + jj) += error /
value_t<M>(c1 * c2);
226 template <
typename C,
typename M>
227 static void pool_block_3d(
const C& errors, M& m,
size_t q,
size_t i,
size_t j,
size_t c1,
size_t c2,
size_t s1,
size_t s2,
size_t p1,
size_t p2) {
228 auto error = errors(q, i, j);
231 if (cpp_unlikely(p1 || p2)) {
232 if (cpp_unlikely(i < p1 || j < p2 || i >= etl::dim<1>(errors) - p1 || j >= etl::dim<2>(errors) - p2)) {
233 const size_t base_i = i * s1 - p1;
234 const size_t base_j = j * s2 - p2;
236 for (
size_t ii = 0; ii < c1; ++ii) {
237 for (
size_t jj = 0; jj < c2; ++jj) {
238 if (base_i + ii < etl::dim<1>(m) && base_j + jj < etl::dim<2>(m)) {
239 if (s1 == c1 && s2 == c2) {
240 m(q, base_i + ii, base_j + jj) = error /
value_t<M>(c1 * c2);
242 m(q, base_i + ii, base_j + jj) += error /
value_t<M>(c1 * c2);
252 if (s1 == c1 && s2 == c2) {
253 for (
size_t ii = 0; ii < c1; ++ii) {
254 for (
size_t jj = 0; jj < c2; ++jj) {
255 m(q, i * s1 - p1 + ii, j * s2 - p2 + jj) = error /
value_t<M>(c1 * c2);
259 for (
size_t ii = 0; ii < c1; ++ii) {
260 for (
size_t jj = 0; jj < c2; ++jj) {
261 m(q, i * s1 - p1 + ii, j * s2 - p2 + jj) += error /
value_t<M>(c1 * c2);
276 template <
typename C,
typename M>
277 static void pool_block_4d(
const C& errors, M& m,
size_t p,
size_t q,
size_t i,
size_t j,
size_t c1,
size_t c2,
size_t s1,
size_t s2,
size_t p1,
size_t p2) {
278 auto error = errors(p, q, i, j);
281 if (cpp_unlikely(p1 || p2)) {
282 if (cpp_unlikely(i < p1 || j < p2 || i >= etl::dim<2>(errors) - p1 || j >= etl::dim<3>(errors) - p2)) {
283 const size_t base_i = i * s1 - p1;
284 const size_t base_j = j * s2 - p2;
286 for (
size_t ii = 0; ii < c1; ++ii) {
287 for (
size_t jj = 0; jj < c2; ++jj) {
288 if (base_i + ii < etl::dim<2>(m) && base_j + jj < etl::dim<3>(m)) {
289 if (s1 == c1 && s2 == c2) {
290 m(p, q, base_i + ii, base_j + jj) = error /
value_t<M>(c1 * c2);
292 m(p, q, base_i + ii, base_j + jj) += error /
value_t<M>(c1 * c2);
302 if (s1 == c1 && s2 == c2) {
303 for (
size_t ii = 0; ii < c1; ++ii) {
304 for (
size_t jj = 0; jj < c2; ++jj) {
305 m(p, q, i * s1 - p1 + ii, j * s2 - p2 + jj) = error /
value_t<M>(c1 * c2);
309 for (
size_t ii = 0; ii < c1; ++ii) {
310 for (
size_t jj = 0; jj < c2; ++jj) {
311 m(p, q, i * s1 - p1 + ii, j * s2 - p2 + jj) += error /
value_t<M>(c1 * c2);
326 template <
size_t C1,
size_t C2,
size_t S1,
size_t S2,
size_t P1,
size_t P2, etl_2d A,
typename B,
typename C,
typename M>
327 static void apply([[maybe_unused]] A&& in, [[maybe_unused]] B&& out, C&& errors, M&& m) {
328 if constexpr (S1 != C1 || S2 != C2) {
332 for (
size_t i = 0; i < etl::dim<0>(out); ++i) {
333 for (
size_t j = 0; j < etl::dim<1>(out); ++j) {
334 pool_block_2d<C1, C2, S1, S2, P1, P2>(errors, m, i, j);
346 template <etl_2d A,
typename B,
typename C,
typename M>
347 static void apply([[maybe_unused]] A&& in, [[maybe_unused]] B&& out, C&& errors, M&& m,
size_t c1,
size_t c2,
size_t s1,
size_t s2,
size_t p1,
size_t p2) {
348 if (s1 != c1 || s2 != c2) {
352 for (
size_t i = 0; i < etl::dim<0>(out); ++i) {
353 for (
size_t j = 0; j < etl::dim<1>(out); ++j) {
368 template <
size_t C1,
size_t C2,
size_t S1,
size_t S2,
size_t P1,
size_t P2, etl_3d A,
typename B,
typename C,
typename M>
369 static void apply([[maybe_unused]] A&& in, [[maybe_unused]] B&& out, C&& errors, M&& m) {
370 if constexpr (S1 != C1 || S2 != C2) {
374 auto batch_fun = [&](
const size_t first,
const size_t last) {
375 for (
size_t q = first; q < last; ++q) {
376 for (
size_t i = 0; i < etl::dim<1>(out); ++i) {
377 for (
size_t j = 0; j < etl::dim<2>(out); ++j) {
378 pool_block_3d<C1, C2, S1, S2, P1, P2>(errors, m, q, i, j);
384 const size_t N = etl::dim<0>(out);
396 template <etl_3d A,
typename B,
typename C,
typename M>
397 static void apply([[maybe_unused]] A&& in, [[maybe_unused]] B&& out, C&& errors, M&& m,
size_t c1,
size_t c2,
size_t s1,
size_t s2,
size_t p1,
size_t p2) {
398 if (s1 != c1 || s2 != c2) {
402 auto batch_fun = [&](
const size_t first,
const size_t last) {
403 for (
size_t q = first; q < last; ++q) {
404 for (
size_t i = 0; i < etl::dim<1>(out); ++i) {
405 for (
size_t j = 0; j < etl::dim<2>(out); ++j) {
406 pool_block_3d(errors, m, q, i, j, c1, c2, s1, s2, p1, p2);
412 const size_t N = etl::dim<0>(out);
426 template <
size_t C1,
size_t C2,
size_t S1,
size_t S2,
size_t P1,
size_t P2, etl_4d A,
typename B,
typename C,
typename M>
427 static void apply([[maybe_unused]] A&& in, [[maybe_unused]] B&& out, C&& errors, M&& m) {
428 if constexpr (S1 != C1 || S2 != C2) {
432 auto batch_fun = [&](
const size_t first,
const size_t last) {
433 for (
size_t p = first; p < last; ++p) {
434 for (
size_t q = 0; q < etl::dim<1>(out); ++q) {
435 for (
size_t i = 0; i < etl::dim<2>(out); ++i) {
436 for (
size_t j = 0; j < etl::dim<3>(out); ++j) {
437 pool_block_4d<C1, C2, S1, S2, P1, P2>(errors, m, p, q, i, j);
444 const size_t N = etl::dim<0>(out);
456 template <etl_4d A,
typename B,
typename C,
typename M>
457 static void apply([[maybe_unused]] A&& in, [[maybe_unused]] B&& out, C&& errors, M&& m,
size_t c1,
size_t c2,
size_t s1,
size_t s2,
size_t p1,
size_t p2) {
458 if (s1 != c1 || s2 != c2) {
462 auto batch_fun = [&](
const size_t first,
const size_t last) {
463 for (
size_t p = first; p < last; ++p) {
464 for (
size_t q = 0; q < etl::dim<1>(out); ++q) {
465 for (
size_t i = 0; i < etl::dim<2>(out); ++i) {
466 for (
size_t j = 0; j < etl::dim<3>(out); ++j) {
467 pool_block_4d(errors, m, p, q, i, j, c1, c2, s1, s2, p1, p2);
474 const size_t N = etl::dim<0>(out);
488 template <
size_t C1,
size_t C2,
size_t S1,
size_t S2,
size_t P1,
size_t P2, etl_5d_and_plus A,
typename B,
typename C,
typename M>
489 static void apply(A&& in, B&& out, C&& errors, M& m) {
490 for (
size_t i = 0; i < etl::dim<0>(in); ++i) {
491 apply<C1, C2, S1, S2, P1, P2>(in(i), out(i), errors(i), m(i));
502 template <etl_5d_and_plus A,
typename B,
typename C,
typename M>
503 static void apply(A&& in, B&& out, C&& errors, M& m,
size_t c1,
size_t c2,
size_t s1,
size_t s2,
size_t p1,
size_t p2) {
504 for (
size_t i = 0; i < etl::dim<0>(in); ++i) {
505 apply(in(i), out(i), errors(i), m(i), c1, c2, s1, s2, p1, p2);
525 template <
size_t C1,
size_t C2,
size_t C3,
typename C,
typename M>
526 static void pool_block_3d(
const C& errors, M& m,
size_t i,
size_t j,
size_t k) {
527 auto error = errors(i, j, k);
529 for (
size_t ii = 0; ii < C1; ++ii) {
530 for (
size_t jj = 0; jj < C2; ++jj) {
531 for (
size_t kk = 0; kk < C3; ++kk) {
532 m(i * C1 + ii, j * C2 + jj, k * C3 + kk) = error /
value_t<M>(C1 * C2 * C3);
549 template <
size_t C1,
size_t C2,
size_t C3,
typename C,
typename M>
550 static void pool_block_4d(
const C& errors, M& m,
size_t n,
size_t i,
size_t j,
size_t k) {
551 auto error = errors(n, i, j, k);
553 for (
size_t ii = 0; ii < C1; ++ii) {
554 for (
size_t jj = 0; jj < C2; ++jj) {
555 for (
size_t kk = 0; kk < C3; ++kk) {
556 m(n, i * C1 + ii, j * C2 + jj, k * C3 + kk) = error /
value_t<M>(C1 * C2 * C3);
573 template <
typename C,
typename M>
574 static void pool_block_3d(
const C& errors, M& m,
size_t i,
size_t j,
size_t k,
size_t c1,
size_t c2,
size_t c3) {
575 auto error = errors(i, j, k);
577 for (
size_t ii = 0; ii < c1; ++ii) {
578 for (
size_t jj = 0; jj < c2; ++jj) {
579 for (
size_t kk = 0; kk < c3; ++kk) {
580 m(i * c1 + ii, j * c2 + jj, k * c3 + kk) = error /
value_t<M>(c1 * c2 * c3);
597 template <
typename C,
typename M>
598 static void pool_block_4d(
const C& errors, M& m,
size_t n,
size_t i,
size_t j,
size_t k,
size_t c1,
size_t c2,
size_t c3) {
599 auto error = errors(n, i, j, k);
601 for (
size_t ii = 0; ii < c1; ++ii) {
602 for (
size_t jj = 0; jj < c2; ++jj) {
603 for (
size_t kk = 0; kk < c3; ++kk) {
604 m(n, i * c1 + ii, j * c2 + jj, k * c3 + kk) = error /
value_t<M>(c1 * c2 * c3);
618 template <
size_t C1,
size_t C2,
size_t C3, etl_3d A,
typename B,
typename C,
typename M>
619 static void apply([[maybe_unused]] A&& in, [[maybe_unused]] B&& out, C&& errors, M&& m) {
620 for (
size_t i = 0; i < etl::dim<0>(out); ++i) {
621 for (
size_t j = 0; j < etl::dim<1>(out); ++j) {
622 for (
size_t k = 0; k < etl::dim<2>(out); ++k) {
623 pool_block_3d<C1, C2, C3>(errors, m, i, j, k);
637 template <etl_3d A,
typename B,
typename C,
typename M>
638 static void apply([[maybe_unused]] A&& in, [[maybe_unused]] B&& out, C&& errors, M&& m,
size_t c1,
size_t c2,
size_t c3) {
639 for (
size_t i = 0; i < etl::dim<0>(out); ++i) {
640 for (
size_t j = 0; j < etl::dim<1>(out); ++j) {
641 for (
size_t k = 0; k < etl::dim<2>(out); ++k) {
664 template <
size_t C1,
size_t C2,
size_t C3, etl_4d A,
typename B,
typename C,
typename M>
665 static void apply([[maybe_unused]] A&& in, [[maybe_unused]] B&& out, C&& errors, M& m) {
666 auto batch_fun_n = [&](
const size_t first,
const size_t last) {
667 for (
size_t n = first; n < last; ++n) {
668 for (
size_t i = 0; i < etl::dim<1>(out); ++i) {
669 for (
size_t j = 0; j < etl::dim<2>(out); ++j) {
670 for (
size_t k = 0; k < etl::dim<3>(out); ++k) {
671 avg_pool_upsample_3d::pool_block_4d<C1, C2, C3>(errors, m, n, i, j, k);
678 const size_t N = etl::dim<0>(out);
691 template <etl_4d A,
typename B,
typename C,
typename M>
692 static void apply([[maybe_unused]] A&& in, [[maybe_unused]] B&& out, C&& errors, M& m,
size_t c1,
size_t c2,
size_t c3) {
693 auto batch_fun_n = [&](
const size_t first,
const size_t last) {
694 for (
size_t n = first; n < last; ++n) {
695 for (
size_t i = 0; i < etl::dim<1>(out); ++i) {
696 for (
size_t j = 0; j < etl::dim<2>(out); ++j) {
697 for (
size_t k = 0; k < etl::dim<3>(out); ++k) {
705 const size_t N = etl::dim<0>(out);
720 template <
size_t C1,
size_t C2,
size_t C3, etl_5d_and_plus A,
typename B,
typename C,
typename M>
721 static void apply(A&& in, B&& out, C&& errors, M& m) {
722 for (
size_t i = 0; i < etl::dim<0>(in); ++i) {
723 apply<C1, C2, C3>(in(i), out(i), errors(i), m(i));
735 template <etl_5d_and_plus A,
typename B,
typename C,
typename M>
736 static void apply(A&& in, B&& out, C&& errors, M& m,
size_t c1,
size_t c2,
size_t c3) {
737 for (
size_t i = 0; i < etl::dim<0>(in); ++i) {
738 apply(in(i), out(i), errors(i), m(i), c1, c2, c3);
static void apply([[maybe_unused]] A &&in, [[maybe_unused]] B &&out, C &&errors, M &&m)
Apply the functor on sub and store the result in m.
Definition: avg_pooling_upsample.hpp:619
static void apply(A &&in, B &&out, C &&errors, M &m, size_t c1, size_t c2, size_t s1, size_t s2, size_t p1, size_t p2)
Apply the functor on sub and store the result in m.
Definition: avg_pooling_upsample.hpp:503
static void apply(A &&in, B &&out, C &&errors, M &m, size_t c1, size_t c2, size_t c3)
Apply the functor on sub and store the result in m.
Definition: avg_pooling_upsample.hpp:736
static void pool_block_3d(const C &errors, M &m, size_t i, size_t j, size_t k)
Pool a 3D block of the sub expression.
Definition: avg_pooling_upsample.hpp:526
void engine_dispatch_1d_serial(Functor &&functor, size_t first, size_t last, size_t threshold, [[maybe_unused]] size_t n_threads=etl::threads)
Dispatch the elements of a range to a functor in a parallel manner, using the global thread engine...
Definition: parallel_support.hpp:734
static void apply([[maybe_unused]] A &&in, [[maybe_unused]] B &&out, C &&errors, M &&m, size_t c1, size_t c2, size_t s1, size_t s2, size_t p1, size_t p2)
Apply the functor on sub and store the result in m.
Definition: avg_pooling_upsample.hpp:347
static void pool_block_4d(const C &errors, M &m, size_t p, size_t q, size_t i, size_t j)
Pool a block of the sub expression.
Definition: avg_pooling_upsample.hpp:127
Functor for the derivative of 3D Avg Pooling.
Definition: avg_pooling_upsample.hpp:513
static void apply(A &&in, B &&out, C &&errors, M &m)
Apply the functor on sub and store the result in m.
Definition: avg_pooling_upsample.hpp:721
Definition: prob_pooling.hpp:10
static void pool_block_4d(const C &errors, M &m, size_t p, size_t q, size_t i, size_t j, size_t c1, size_t c2, size_t s1, size_t s2, size_t p1, size_t p2)
Pool a block of the sub expression.
Definition: avg_pooling_upsample.hpp:277
static void pool_block_3d(const C &errors, M &m, size_t q, size_t i, size_t j)
Pool a block of the sub expression.
Definition: avg_pooling_upsample.hpp:77
static void apply([[maybe_unused]] A &&in, [[maybe_unused]] B &&out, C &&errors, M &m, size_t c1, size_t c2, size_t c3)
Apply the functor on sub and store the result in m.
Definition: avg_pooling_upsample.hpp:692
static void pool_block_4d(const C &errors, M &m, size_t n, size_t i, size_t j, size_t k, size_t c1, size_t c2, size_t c3)
Pool a 4D block of the sub expression.
Definition: avg_pooling_upsample.hpp:598
static void pool_block_2d(const C &errors, M &m, size_t i, size_t j)
Pool a block of the sub expression.
Definition: avg_pooling_upsample.hpp:27
static void pool_block_4d(const C &errors, M &m, size_t n, size_t i, size_t j, size_t k)
Pool a 4D block of the sub expression.
Definition: avg_pooling_upsample.hpp:550
static void pool_block_2d(const C &errors, M &m, size_t i, size_t j, size_t c1, size_t c2, size_t s1, size_t s2, size_t p1, size_t p2)
Pool a block of the sub expression.
Definition: avg_pooling_upsample.hpp:177
static void apply([[maybe_unused]] A &&in, [[maybe_unused]] B &&out, C &&errors, M &m)
Apply the functor on sub and store the result in m.
Definition: avg_pooling_upsample.hpp:665
Functor for the derivative of 2D Max Pooling.
Definition: avg_pooling_upsample.hpp:16
static void pool_block_3d(const C &errors, M &m, size_t q, size_t i, size_t j, size_t c1, size_t c2, size_t s1, size_t s2, size_t p1, size_t p2)
Pool a block of the sub expression.
Definition: avg_pooling_upsample.hpp:227
static void apply([[maybe_unused]] A &&in, [[maybe_unused]] B &&out, C &&errors, M &&m)
Apply the functor on sub and store the result in m.
Definition: avg_pooling_upsample.hpp:327
static void apply(A &&in, B &&out, C &&errors, M &m)
Apply the functor on sub and store the result in m.
Definition: avg_pooling_upsample.hpp:489
typename decay_traits< E >::value_type value_t
Traits to extract the value type out of an ETL type.
Definition: tmp.hpp:81
static void apply([[maybe_unused]] A &&in, [[maybe_unused]] B &&out, C &&errors, M &&m, size_t c1, size_t c2, size_t c3)
Apply the functor on sub and store the result in m.
Definition: avg_pooling_upsample.hpp:638
static void pool_block_3d(const C &errors, M &m, size_t i, size_t j, size_t k, size_t c1, size_t c2, size_t c3)
Pool a 3D block of the sub expression.
Definition: avg_pooling_upsample.hpp:574