Expression Templates Library (ETL)
pooling_upsample.hpp
1 //=======================================================================
2 // Copyright (c) 2014-2023 Baptiste Wicht
3 // Distributed under the terms of the MIT License.
4 // (See accompanying file LICENSE or copy at
5 // http://opensource.org/licenses/MIT)
6 //=======================================================================
7 
8 #pragma once
9 
10 #ifdef ETL_CUDNN_MODE
11 
12 #include "etl/impl/cublas/cuda.hpp"
13 #include "etl/impl/cudnn/cudnn.hpp"
14 
15 #endif
16 
17 namespace etl::impl::cudnn {
18 
19 #ifdef ETL_CUDNN_MODE
20 
28 template <typename A, typename B, typename C, typename M>
29 void unpool_2d(cudnnPoolingMode_t mode, 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) {
30  using type = std::remove_const_t<value_t<A>>;
31 
32  decltype(auto) handle = start_cudnn();
33 
34  auto pooling_desc = create_pooling_desc_wrapper(mode, c1, c2, s1, s2, p1, p2);
35 
36  auto in_tensor = create_tensor_wrapper(in);
37  auto out_tensor = create_tensor_wrapper(out);
38  auto errors_tensor = create_tensor_wrapper(errors);
39  auto m_tensor = create_tensor_wrapper(m);
40 
41  type alpha[] = {1.0f};
42  type beta[] = {0.0f};
43 
44  // Allocate GPU memory, if necessary
45 
46  in.ensure_gpu_up_to_date();
47  out.ensure_gpu_allocated();
48  errors.ensure_gpu_up_to_date();
49  m.ensure_gpu_allocated();
50 
51  // Perform pooling
52 
53  cudnn_check(cudnnPoolingBackward(handle.get(), *pooling_desc, alpha, *out_tensor, out.gpu_memory(), *errors_tensor, errors.gpu_memory(), *in_tensor,
54  in.gpu_memory(), beta, *m_tensor, m.gpu_memory()));
55 
56  m.validate_gpu();
57  m.invalidate_cpu();
58 }
59 
67 template <typename A, typename B, typename C, typename M>
68 void unpool_3d(cudnnPoolingMode_t mode, A&& in, B&& out, C&& errors, M& m, size_t c1, size_t c2, size_t c3) {
69  using type = std::remove_const_t<value_t<A>>;
70 
71  decltype(auto) handle = start_cudnn();
72 
73  auto pooling_desc = create_pooling_desc_wrapper(mode, c1, c2, c3, c1, c2, c3, 0, 0, 0);
74 
75  auto in_tensor = create_tensor_wrapper_5d(in);
76  auto out_tensor = create_tensor_wrapper_5d(out);
77  auto errors_tensor = create_tensor_wrapper_5d(errors);
78  auto m_tensor = create_tensor_wrapper_5d(m);
79 
80  type alpha[] = {1.0f};
81  type beta[] = {0.0f};
82 
83  // Allocate GPU memory, if necessary
84 
85  in.ensure_gpu_up_to_date();
86  out.ensure_gpu_allocated();
87  errors.ensure_gpu_up_to_date();
88  m.ensure_gpu_allocated();
89 
90  // Perform pooling
91 
92  cudnn_check(cudnnPoolingBackward(handle.get(), *pooling_desc, alpha, *out_tensor, out.gpu_memory(), *errors_tensor, errors.gpu_memory(), *in_tensor,
93  in.gpu_memory(), beta, *m_tensor, m.gpu_memory()));
94 
95  m.validate_gpu();
96  m.invalidate_cpu();
97 }
98 
102 struct max_pool_upsample_2d {
110  template <typename A, typename B, typename C, typename M>
111  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) {
112  if constexpr (decay_traits<A>::dimensions() < 5) {
113  unpool_2d(CUDNN_POOLING_MAX, in, out, errors, m, c1, c2, s1, s2, p1, p2);
114  } else {
115  // Deep handling
116 
117  for (size_t i = 0; i < etl::dim<0>(in); ++i) {
118  apply(in(i), out(i), errors(i), m(i), c1, c2, s1, s2, p1, p2);
119  }
120  }
121  }
122 };
123 
127 struct max_pool_upsample_3d {
135  template <typename A, typename B, typename C, typename M>
136  static void apply(A&& in, B&& out, C&& errors, M& m, size_t c1, size_t c2, size_t c3) {
137  if constexpr (decay_traits<A>::dimensions() < 5) {
138  unpool_3d(CUDNN_POOLING_MAX, in, out, errors, m, c1, c2, c3);
139  } else {
140  // Deep handling
141 
142  for (size_t i = 0; i < etl::dim<0>(in); ++i) {
143  apply(in(i), out(i), errors(i), m(i), c1, c2, c3);
144  }
145  }
146  }
147 };
148 
152 struct avg_pool_upsample_2d {
160  template <typename A, typename B, typename C, typename M>
161  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) {
162  if constexpr (decay_traits<A>::dimensions() < 5) {
163  unpool_2d(CUDNN_POOLING_AVERAGE_COUNT_INCLUDE_PADDING, in, out, errors, m, c1, c2, s1, s2, p1, p2);
164  } else {
165  // Deep handling
166  for (size_t i = 0; i < etl::dim<0>(in); ++i) {
167  apply(in(i), out(i), errors(i), m(i), c1, c2, p1, p2);
168  }
169  }
170  }
171 };
172 
176 struct avg_pool_upsample_3d {
184  template <typename A, typename B, typename C, typename M>
185  static void apply(A&& in, B&& out, C&& errors, M& m, size_t c1, size_t c2, size_t c3) {
186  if constexpr (decay_traits<A>::dimensions() < 5) {
187  unpool_3d(CUDNN_POOLING_AVERAGE_COUNT_INCLUDE_PADDING, in, out, errors, m, c1, c2, c3);
188  } else {
189  // Deep handling
190  for (size_t i = 0; i < etl::dim<0>(in); ++i) {
191  apply(in(i), out(i), errors(i), m(i), c1, c2, c3);
192  }
193  }
194  }
195 };
196 
197 #else
198 
199 //COVERAGE_EXCLUDE_BEGIN
200 
212  template <typename A, typename B, typename C, typename M>
213  static void apply([[maybe_unused]] A&& in,
214  [[maybe_unused]] B&& out,
215  [[maybe_unused]] C&& errors,
216  [[maybe_unused]] M& m,
217  [[maybe_unused]] size_t c1,
218  [[maybe_unused]] size_t c2,
219  [[maybe_unused]] size_t s1,
220  [[maybe_unused]] size_t s2,
221  [[maybe_unused]] size_t p1,
222  [[maybe_unused]] size_t p2
223  ) {
224  cpp_unreachable("Unsupported feature called: cudnn pool");
225  }
226 };
227 
239  template <typename A, typename B, typename C, typename M>
240  static void apply([[maybe_unused]] A&& in,
241  [[maybe_unused]] B&& out,
242  [[maybe_unused]] C&& errors,
243  [[maybe_unused]] M& m,
244  [[maybe_unused]] size_t c1,
245  [[maybe_unused]] size_t c2,
246  [[maybe_unused]] size_t c3) {
247  cpp_unreachable("Unsupported feature called: cudnn pool");
248  }
249 };
250 
262  template <typename A, typename B, typename C, typename M>
263  static void apply([[maybe_unused]] A&& in,
264  [[maybe_unused]] B&& out,
265  [[maybe_unused]] C&& errors,
266  [[maybe_unused]] M& m,
267  [[maybe_unused]] size_t c1,
268  [[maybe_unused]] size_t c2,
269  [[maybe_unused]] size_t s1,
270  [[maybe_unused]] size_t s2,
271  [[maybe_unused]] size_t p1,
272  [[maybe_unused]] size_t p2
273  ) {
274  cpp_unreachable("Unsupported feature called: cudnn pool");
275  }
276 };
277 
289  template <typename A, typename B, typename C, typename M>
290  static void apply([[maybe_unused]] A&& in,
291  [[maybe_unused]] B&& out,
292  [[maybe_unused]] C&& errors,
293  [[maybe_unused]] M& m,
294  [[maybe_unused]] size_t c1,
295  [[maybe_unused]] size_t c2,
296  [[maybe_unused]] size_t c3) {
297  cpp_unreachable("Unsupported feature called: cudnn pool");
298  }
299 };
300 
301 //COVERAGE_EXCLUDE_END
302 
303 #endif
304 
305 } //end of namespace etl::impl::cudnn
Definition: bias_add.hpp:24
dyn_pool_upsample_3d_expr< detail::build_type< A >, detail::build_type< B >, detail::build_type< C >, true > max_pool_upsample_3d(A &&input, B &&output, C &&errors, size_t c1, size_t c2, size_t c3)
Derivative of the 3D Max Pooling of the given matrix expression and upsampling.
Definition: dyn_pool_upsample_3d_expr.hpp:319
static void apply([[maybe_unused]] A &&in, [[maybe_unused]] B &&out, [[maybe_unused]] C &&errors, [[maybe_unused]] M &m, [[maybe_unused]] size_t c1, [[maybe_unused]] size_t c2, [[maybe_unused]] size_t s1, [[maybe_unused]] size_t s2, [[maybe_unused]] size_t p1, [[maybe_unused]] size_t p2)
Apply the functor on sub and store the result in m.
Definition: pooling_upsample.hpp:263
Functor for 3D Max Pooling Upsample.
Definition: pooling_upsample.hpp:231
static void apply([[maybe_unused]] A &&in, [[maybe_unused]] B &&out, [[maybe_unused]] C &&errors, [[maybe_unused]] M &m, [[maybe_unused]] size_t c1, [[maybe_unused]] size_t c2, [[maybe_unused]] size_t s1, [[maybe_unused]] size_t s2, [[maybe_unused]] size_t p1, [[maybe_unused]] size_t p2)
Apply the functor on sub and store the result in m.
Definition: pooling_upsample.hpp:213
static void apply([[maybe_unused]] A &&in, [[maybe_unused]] B &&out, [[maybe_unused]] C &&errors, [[maybe_unused]] M &m, [[maybe_unused]] size_t c1, [[maybe_unused]] size_t c2, [[maybe_unused]] size_t c3)
Apply the functor on sub and store the result in m.
Definition: pooling_upsample.hpp:290
Functor for 3D Avg Pooling Upsample.
Definition: pooling_upsample.hpp:281
static constexpr size_t dimensions()
Return the number of dimensions of the expression.
Definition: traits_base.hpp:31
Functor for 2D Max Pooling Upsample.
Definition: pooling_upsample.hpp:204
dyn_pool_upsample_3d_expr< detail::build_type< A >, detail::build_type< B >, detail::build_type< C >, false > avg_pool_upsample_3d(A &&input, B &&output, C &&errors, size_t c1, size_t c2, size_t c3)
Derivative of the 3D Average Pooling of the given matrix expression and upsampling.
Definition: dyn_pool_upsample_3d_expr.hpp:334
static void apply([[maybe_unused]] A &&in, [[maybe_unused]] B &&out, [[maybe_unused]] C &&errors, [[maybe_unused]] M &m, [[maybe_unused]] size_t c1, [[maybe_unused]] size_t c2, [[maybe_unused]] size_t c3)
Apply the functor on sub and store the result in m.
Definition: pooling_upsample.hpp:240
Utility functions for cudnn.
dyn_pool_upsample_2d_expr< detail::build_type< A >, detail::build_type< B >, detail::build_type< C >, true > max_pool_upsample_2d(A &&input, B &&output, C &&errors, size_t c1, size_t c2)
Derivative of the 2D Max Pooling of the given matrix expression and upsampling.
Definition: dyn_pool_upsample_2d_expr.hpp:325
Functor for 2D Avg Pooling Upsample.
Definition: pooling_upsample.hpp:254
dyn_pool_upsample_2d_expr< detail::build_type< A >, detail::build_type< B >, detail::build_type< C >, false > avg_pool_upsample_2d(A &&input, B &&output, C &&errors, size_t c1, size_t c2)
Derivative of the 2D Average Pooling of the given matrix expression and upsampling.
Definition: dyn_pool_upsample_2d_expr.hpp:353