Expression Templates Library (ETL)
max_pooling.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 X, typename Y>
29 void pool_2d(cudnnPoolingMode_t mode, const X& x, Y&& y, 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<X>>;
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 x_tensor = create_tensor_wrapper(x);
37  auto y_tensor = create_tensor_wrapper(y);
38 
39  type alpha[] = {1.0f};
40  type beta[] = {0.0f};
41 
42  // Allocate GPU memory, if necessary
43 
44  x.ensure_gpu_up_to_date();
45  y.ensure_gpu_allocated();
46 
47  // Perform pooling
48 
49  cudnn_check(cudnnPoolingForward(handle.get(), *pooling_desc, alpha, *x_tensor, x.gpu_memory(), beta, *y_tensor, y.gpu_memory()));
50 
51  y.validate_gpu();
52  y.invalidate_cpu();
53 }
54 
62 template <typename X, typename Y>
63 void pool_3d(cudnnPoolingMode_t mode, const X& x, Y&& y, size_t c1, size_t c2, size_t c3, size_t s1, size_t s2, size_t s3, size_t p1, size_t p2, size_t p3) {
64  using type = std::remove_const_t<value_t<X>>;
65 
66  decltype(auto) handle = start_cudnn();
67 
68  auto pooling_desc = create_pooling_desc_wrapper(mode, c1, c2, c3, s1, s2, s3, p1, p2, p3);
69 
70  auto x_tensor = create_tensor_wrapper_5d(x);
71  auto y_tensor = create_tensor_wrapper_5d(y);
72 
73  type alpha[] = {1.0f};
74  type beta[] = {0.0f};
75 
76  // Allocate GPU memory, if necessary
77 
78  x.ensure_gpu_up_to_date();
79  y.ensure_gpu_allocated();
80 
81  // Perform pooling
82 
83  cudnn_check(cudnnPoolingForward(handle.get(), *pooling_desc, alpha, *x_tensor, x.gpu_memory(), beta, *y_tensor, y.gpu_memory()));
84 
85  y.validate_gpu();
86  y.invalidate_cpu();
87 }
88 
92 struct max_pool_2d {
100  template <typename X, typename Y>
101  static void apply(const X& x, Y&& y, size_t c1, size_t c2, size_t s1, size_t s2, size_t p1, size_t p2) {
102  if constexpr (decay_traits<X>::dimensions() < 5) {
103  pool_2d(CUDNN_POOLING_MAX, x, y, c1, c2, s1, s2, p1, p2);
104  } else {
105  // Deep handling
106  for (size_t i = 0; i < etl::dim<0>(x); ++i) {
107  apply(x(i), y(i), c1, c2, s1, s2, p1, p2);
108  }
109  }
110  }
111 };
112 
116 struct avg_pool_2d {
124  template <typename X, typename Y>
125  static void apply(const X& x, Y&& y, size_t c1, size_t c2, size_t s1, size_t s2, size_t p1, size_t p2) {
126  if constexpr (decay_traits<X>::dimensions() < 5) {
127  pool_2d(CUDNN_POOLING_AVERAGE_COUNT_INCLUDE_PADDING, x, y, c1, c2, s1, s2, p1, p2);
128  } else {
129  // Deep handling
130  for (size_t i = 0; i < etl::dim<0>(x); ++i) {
131  apply(x(i), y(i), c1, c2, s1, s2, p1, p2);
132  }
133  }
134  }
135 };
136 
140 struct max_pool_3d {
148  template <typename X, typename Y>
149  static void apply(const X& x, Y&& y, size_t c1, size_t c2, size_t c3, size_t s1, size_t s2, size_t s3, size_t p1, size_t p2, size_t p3) {
150  if constexpr (decay_traits<X>::dimensions() < 5) {
151  pool_3d(CUDNN_POOLING_MAX, x, y, c1, c2, c3, s1, s2, s3, p1, p2, p3);
152  } else {
153  // Deep handling
154  for (size_t i = 0; i < etl::dim<0>(x); ++i) {
155  apply(x(i), y(i), c1, c2, c3, s1, s2, s3, p1, p2, p3);
156  }
157  }
158  }
159 };
160 
164 struct avg_pool_3d {
172  template <typename X, typename Y>
173  static void apply(const X& x, Y&& y, size_t c1, size_t c2, size_t c3, size_t s1, size_t s2, size_t s3, size_t p1, size_t p2, size_t p3) {
174  if constexpr (decay_traits<X>::dimensions() < 5) {
175  pool_3d(CUDNN_POOLING_AVERAGE_COUNT_INCLUDE_PADDING, x, y, c1, c2, c3, s1, s2, s3, p1, p2, p3);
176  } else {
177  // Deep handling
178  for (size_t i = 0; i < etl::dim<0>(x); ++i) {
179  apply(x(i), y(i), c1, c2, c3, s1, s2, s3, p1, p2, p3);
180  }
181  }
182  }
183 };
184 
185 #else
186 
187 //COVERAGE_EXCLUDE_BEGIN
188 
192 struct max_pool_2d {
200  template <typename X, typename Y>
201  static void apply([[maybe_unused]] const X& x,
202  [[maybe_unused]] Y&& y,
203  [[maybe_unused]] size_t c1,
204  [[maybe_unused]] size_t c2,
205  [[maybe_unused]] size_t s1,
206  [[maybe_unused]] size_t s2,
207  [[maybe_unused]] size_t p1,
208  [[maybe_unused]] size_t p2) {
209  cpp_unreachable("Unsupported feature called: cudnn pool");
210  }
211 };
212 
216 struct avg_pool_2d {
224  template <typename X, typename Y>
225  static void apply([[maybe_unused]] const X& x,
226  [[maybe_unused]] Y&& y,
227  [[maybe_unused]] size_t c1,
228  [[maybe_unused]] size_t c2,
229  [[maybe_unused]] size_t s1,
230  [[maybe_unused]] size_t s2,
231  [[maybe_unused]] size_t p1,
232  [[maybe_unused]] size_t p2) {
233  cpp_unreachable("Unsupported feature called: cudnn pool");
234  }
235 };
236 
240 struct max_pool_3d {
248  template <typename X, typename Y>
249  static void apply([[maybe_unused]] const X& x,
250  [[maybe_unused]] Y&& y,
251  [[maybe_unused]] size_t c1,
252  [[maybe_unused]] size_t c2,
253  [[maybe_unused]] size_t c3,
254  [[maybe_unused]] size_t s1,
255  [[maybe_unused]] size_t s2,
256  [[maybe_unused]] size_t s3,
257  [[maybe_unused]] size_t p1,
258  [[maybe_unused]] size_t p2,
259  [[maybe_unused]] size_t p3) {
260  cpp_unreachable("Unsupported feature called: cudnn pool");
261  }
262 };
263 
267 struct avg_pool_3d {
275  template <typename X, typename Y>
276  static void apply([[maybe_unused]] const X& x,
277  [[maybe_unused]] Y&& y,
278  [[maybe_unused]] size_t c1,
279  [[maybe_unused]] size_t c2,
280  [[maybe_unused]] size_t c3,
281  [[maybe_unused]] size_t s1,
282  [[maybe_unused]] size_t s2,
283  [[maybe_unused]] size_t s3,
284  [[maybe_unused]] size_t p1,
285  [[maybe_unused]] size_t p2,
286  [[maybe_unused]] size_t p3) {
287  cpp_unreachable("Unsupported feature called: cudnn pool");
288  }
289 };
290 
291 //COVERAGE_EXCLUDE_END
292 
293 #endif
294 
295 } //end of namespace etl::impl::cudnn
Functor for 2D Max Pooling.
Definition: max_pooling.hpp:267
Definition: bias_add.hpp:24
dyn_pool_2d_expr< detail::build_type< E >, impl::max_pool_2d > max_pool_2d(E &&value, size_t c1, size_t c2)
2D Max Pooling of the given matrix expression
Definition: dyn_pool_2d_expr.hpp:211
static constexpr size_t dimensions()
Return the number of dimensions of the expression.
Definition: traits_base.hpp:31
Functor for 2D Max Pooling.
Definition: max_pooling.hpp:192
Functor for 2D Max Pooling.
Definition: max_pooling.hpp:216
static void apply([[maybe_unused]] const X &x, [[maybe_unused]] Y &&y, [[maybe_unused]] size_t c1, [[maybe_unused]] size_t c2, [[maybe_unused]] size_t c3, [[maybe_unused]] size_t s1, [[maybe_unused]] size_t s2, [[maybe_unused]] size_t s3, [[maybe_unused]] size_t p1, [[maybe_unused]] size_t p2, [[maybe_unused]] size_t p3)
Apply the functor on sub and store the result in m.
Definition: max_pooling.hpp:249
static void apply([[maybe_unused]] const X &x, [[maybe_unused]] Y &&y, [[maybe_unused]] size_t c1, [[maybe_unused]] size_t c2, [[maybe_unused]] size_t c3, [[maybe_unused]] size_t s1, [[maybe_unused]] size_t s2, [[maybe_unused]] size_t s3, [[maybe_unused]] size_t p1, [[maybe_unused]] size_t p2, [[maybe_unused]] size_t p3)
Apply the functor on sub and store the result in m.
Definition: max_pooling.hpp:276
dyn_pool_3d_expr< detail::build_type< E >, impl::avg_pool_3d > avg_pool_3d(E &&value, size_t c1, size_t c2, size_t c3)
3D Average Pooling of the given matrix expression
Definition: dyn_pool_3d_expr.hpp:245
Utility functions for cudnn.
dyn_pool_3d_expr< detail::build_type< E >, impl::max_pool_3d > max_pool_3d(E &&value, size_t c1, size_t c2, size_t c3)
3D Max Pooling of the given matrix expression
Definition: dyn_pool_3d_expr.hpp:216
static void apply([[maybe_unused]] const X &x, [[maybe_unused]] Y &&y, [[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: max_pooling.hpp:201
Functor for 2D Max Pooling.
Definition: max_pooling.hpp:240
static void apply([[maybe_unused]] const X &x, [[maybe_unused]] Y &&y, [[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: max_pooling.hpp:225
dyn_pool_2d_expr< detail::build_type< E >, impl::avg_pool_2d > avg_pool_2d(E &&value, size_t c1, size_t c2)
2D Average Pooling of the given matrix expression
Definition: dyn_pool_2d_expr.hpp:235