Expression Templates Library (ETL)
sigmoid.hpp
Go to the documentation of this file.
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 
13 #pragma once
14 
15 #ifdef ETL_CUDNN_MODE
16 
17 #include "etl/impl/cublas/cuda.hpp"
19 #include "etl/impl/cudnn/cudnn.hpp"
20 
21 #endif
22 
23 namespace etl::impl::cudnn {
24 
25 #ifdef ETL_CUDNN_MODE
26 
33 template <typename I, typename C>
34 void activation(I&& x, C&& y, cudnnActivationMode_t mode) {
35  using type = std::remove_const_t<value_t<I>>;
36 
37  type alpha[] = {1.0f};
38  type beta[] = {0.0f};
39 
40  decltype(auto) handle = start_cudnn();
41 
42  // Prepare the tensors
43  auto x_tensor = create_tensor_flat_wrapper(x);
44  auto y_tensor = create_tensor_flat_wrapper(y);
45 
46  cudnnActivationDescriptor_t func_tensor;
47  cudnn_check(cudnnCreateActivationDescriptor(&func_tensor));
48  cudnn_check(cudnnSetActivationDescriptor(func_tensor, mode, CUDNN_PROPAGATE_NAN, 0.0));
49 
50  // Allocate GPU memory, if necessary
51 
54 
55  // y = activation(x)
56 
57  cudnn_check(cudnnActivationForward(handle.get(), func_tensor, alpha, *x_tensor, x.gpu_memory(), beta, *y_tensor, y.gpu_memory()));
58 
59  y.validate_gpu();
60  y.invalidate_cpu();
61 
62  // Release the resources
63  cudnn_check(cudnnDestroyActivationDescriptor(func_tensor));
64 }
65 
72 template <typename Y, typename DY, typename DX>
73 void backward_activation(Y&& y, DY&& dy, DX&& dx, cudnnActivationMode_t mode) {
74  using type = std::remove_const_t<value_t<Y>>;
75 
76  type alpha[] = {1.0f};
77  type beta[] = {0.0f};
78 
79  decltype(auto) handle = start_cudnn();
80 
81  // Prepare the tensors
82  auto y_tensor = create_tensor_flat_wrapper(y);
83  auto dy_tensor = create_tensor_flat_wrapper(dy);
84  auto dx_tensor = create_tensor_flat_wrapper(dx);
85 
86  cudnnActivationDescriptor_t func_tensor;
87  cudnn_check(cudnnCreateActivationDescriptor(&func_tensor));
88  cudnn_check(cudnnSetActivationDescriptor(func_tensor, mode, CUDNN_PROPAGATE_NAN, 0.0));
89 
90  // Allocate GPU memory, if necessary
91 
92  y.ensure_gpu_up_to_date();
93  dy.ensure_gpu_up_to_date();
94  dx.ensure_gpu_allocated();
95 
96  // y = activation(x)
97 
98  cudnn_check(cudnnActivationBackward(handle.get(), func_tensor, alpha, *y_tensor, y.gpu_memory(), *dy_tensor, dy.gpu_memory(), *y_tensor, y.gpu_memory(),
99  beta, *dx_tensor, dx.gpu_memory()));
100 
101  dx.validate_gpu();
102  dx.invalidate_cpu();
103 
104  // Release the resources
105  cudnn_check(cudnnDestroyActivationDescriptor(func_tensor));
106 }
107 
113 template <typename I, typename C>
114 void sigmoid(I&& x, C&& y) {
115  activation(x, y, CUDNN_ACTIVATION_SIGMOID);
116 }
117 
123 template <typename I, typename C>
124 void relu(I&& x, C&& y) {
125  activation(x, y, CUDNN_ACTIVATION_RELU);
126 }
127 
134 template <typename O, typename E, typename C>
135 void sigmoid_backward(O&& o, E&& e, C&& y) {
136  backward_activation(o, e, y, CUDNN_ACTIVATION_SIGMOID);
137 }
138 
145 template <typename O, typename E, typename C>
146 void relu_backward(O&& o, E&& e, C&& y) {
147  backward_activation(o, e, y, CUDNN_ACTIVATION_RELU);
148 }
149 
156 template <typename I, typename C>
157 void softmax_activation(I&& x, C&& y, cudnnSoftmaxAlgorithm_t mode) {
158  using type = std::remove_const_t<value_t<I>>;
159 
160  type alpha[] = {1.0f};
161  type beta[] = {0.0f};
162 
163  decltype(auto) handle = start_cudnn();
164 
165  // Prepare the tensors
166  auto x_tensor = create_tensor_front_wrapper(x);
167  auto y_tensor = create_tensor_front_wrapper(y);
168 
169  // Allocate GPU memory, if necessary
170 
171  x.ensure_gpu_up_to_date();
172  y.ensure_gpu_allocated();
173 
174  // y = activation(x)
175 
176  cudnn_check(cudnnSoftmaxForward(handle.get(), mode, CUDNN_SOFTMAX_MODE_INSTANCE, alpha, *x_tensor, x.gpu_memory(), beta, *y_tensor, y.gpu_memory()));
177 
178  y.validate_gpu();
179  y.invalidate_cpu();
180 }
181 
187 template <typename I, typename C>
188 void softmax(I&& x, C&& y) {
189  softmax_activation(x, y, CUDNN_SOFTMAX_FAST);
190 }
191 
197 template <typename I, typename C>
198 void stable_softmax(I&& x, C&& y) {
199  softmax_activation(x, y, CUDNN_SOFTMAX_ACCURATE);
200 }
201 
202 #else
203 
204 //COVERAGE_EXCLUDE_BEGIN
205 
211 template <typename I, typename C>
212 void sigmoid([[maybe_unused]] I&& x, [[maybe_unused]] C&& y) {
213  cpp_unreachable("CUDNN not available/enabled");
214 }
215 
221 template <typename I, typename C>
222 void relu([[maybe_unused]] I&& x, [[maybe_unused]] C&& y) {
223  cpp_unreachable("CUDNN not available/enabled");
224 }
225 
232 template <typename O, typename E, typename C>
233 void sigmoid_backward([[maybe_unused]] O&& o, [[maybe_unused]] E&& e, [[maybe_unused]] C&& y) {
234  cpp_unreachable("CUDNN not available/enabled");
235 }
236 
243 template <typename O, typename E, typename C>
244 void relu_backward([[maybe_unused]] O&& o, [[maybe_unused]] E&& e, [[maybe_unused]] C&& y) {
245  cpp_unreachable("CUDNN not available/enabled");
246 }
247 
253 template <typename I, typename C>
254 void softmax([[maybe_unused]] I&& x, [[maybe_unused]] C&& y) {
255  cpp_unreachable("CUDNN not available/enabled");
256 }
257 
263 template <typename I, typename C>
264 void stable_softmax([[maybe_unused]] I&& x, [[maybe_unused]] C&& y) {
265  cpp_unreachable("CUDNN not available/enabled");
266 }
267 
268  //COVERAGE_EXCLUDE_END
269 
270 #endif
271 
272 } //end of namespace etl::impl::cudnn
Definition: bias_add.hpp:24
void ensure_gpu_allocated() const
Ensures that the GPU memory is allocated and that the GPU memory is up to date (to undefined value)...
Definition: sub_view.hpp:717
auto softmax(E &&e)
Return the softmax function of the given ETL expression.
Definition: function_expression_builder.hpp:253
auto relu(const E &value) -> detail::unary_helper< E, relu_unary_op >
Return the relu activation of the given ETL expression.
Definition: function_expression_builder.hpp:207
auto sigmoid(const E &value) -> detail::unary_helper< E, sigmoid_unary_op >
Return the logistic sigmoid of the given ETL expression.
Definition: function_expression_builder.hpp:197
auto relu_backward(O &&output, E &&errors) -> detail::left_binary_helper< O, E, relu_derivative_binary_op >
Return the backward activation of the RELU function.
Definition: ml_expression_builder.hpp:532
auto sigmoid_backward(O &&output, E &&errors) -> detail::left_binary_helper< O, E, sigmoid_derivative_binary_op >
Return the backward activation of the sigmoid function.
Definition: ml_expression_builder.hpp:521
Utility functions for cublas.
void invalidate_cpu() const noexcept
Invalidates the CPU memory.
Definition: sub_view.hpp:688
void ensure_gpu_up_to_date() const
Copy back from the GPU to the expression memory if necessary.
Definition: dyn_matrix_view.hpp:280
auto stable_softmax(E &&e)
Returns the softmax function of the given ETL expression. This version is implemented so that numeric...
Definition: function_expression_builder.hpp:268
void validate_gpu() const noexcept
Validates the GPU memory.
Definition: sub_view.hpp:709
Utility functions for cudnn.
value_type * gpu_memory() const noexcept
Return GPU memory of this expression, if any.
Definition: sub_view.hpp:674