CUDNN Frontend API  8.2.0
cudnn_frontend_PointWiseDesc.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021, NVIDIA CORPORATION. All rights reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  */
22 
23 #pragma once
24 
25 #include <algorithm>
26 #include <array>
27 #include <functional>
28 #include <memory>
29 #include <sstream>
30 #include <utility>
31 
32 #include <cudnn.h>
33 #include <cudnn_backend.h>
34 
35 #include "cudnn_frontend_utils.h"
36 
37 namespace cudnn_frontend {
56  public:
58  std::string
59  describe() const override {
60  std::stringstream ss;
61  ss << "CUDNN_BACKEND_POINTWISE_DESCRIPTOR :"
62  << " Mode: " << (mode) << " Math precision " << (math_precision);
63  return ss.str();
64  }
65 
66  int64_t
67  getPortCount() const {
68  switch (mode) {
69  case CUDNN_POINTWISE_ADD:
70  case CUDNN_POINTWISE_MUL:
71  case CUDNN_POINTWISE_MIN:
72  case CUDNN_POINTWISE_MAX:
73  case CUDNN_POINTWISE_RELU_BWD:
74  case CUDNN_POINTWISE_TANH_BWD:
75  case CUDNN_POINTWISE_SIGMOID_BWD:
76  case CUDNN_POINTWISE_ELU_BWD:
77  case CUDNN_POINTWISE_GELU_BWD:
78  case CUDNN_POINTWISE_SOFTPLUS_BWD:
79  case CUDNN_POINTWISE_SWISH_BWD:
80  return 3;
81  case CUDNN_POINTWISE_SQRT:
82  case CUDNN_POINTWISE_RELU_FWD:
83  case CUDNN_POINTWISE_TANH_FWD:
84  case CUDNN_POINTWISE_SIGMOID_FWD:
85  case CUDNN_POINTWISE_ELU_FWD:
86  case CUDNN_POINTWISE_GELU_FWD:
87  case CUDNN_POINTWISE_SOFTPLUS_FWD:
88  case CUDNN_POINTWISE_SWISH_FWD:
89  return 2;
90  default:
91  return -1;
92  }
93  }
94 
95  cudnnPointwiseMode_t
96  getPointWiseMode() const {
97  return mode;
98  }
99 
101  : BackendDescriptor(from.get_desc(), from.get_status(), from.get_error()),
103  mode(from.mode),
105  upper_clip(from.upper_clip),
106  lower_clip(from.lower_clip),
108  elu_alpha(from.elu_alpha),
110  swish_beta(from.swish_beta) {}
111 
112  ~PointWiseDesc_v8() = default;
113 
114  private:
115  PointWiseDesc_v8() = default;
116  PointWiseDesc_v8(PointWiseDesc_v8 const &) = delete;
118  operator=(PointWiseDesc_v8 const &) = delete;
119 
120  cudnnDataType_t math_precision = CUDNN_DATA_FLOAT;
121  cudnnPointwiseMode_t mode = CUDNN_POINTWISE_ADD;
122  cudnnNanPropagation_t nan_propagation = CUDNN_NOT_PROPAGATE_NAN;
123  double upper_clip = std::numeric_limits<double>::max();
124  double lower_clip = 0.0;
125  double lower_clip_slope = 0.0;
126  double elu_alpha = 1.0;
127  double softplus_beta = 1.0;
128  double swish_beta = 1.0;
129 };
130 
135  public:
140  auto
142  setMathPrecision(cudnnDataType_t data_type_) -> PointWiseDescBuilder_v8 & {
143  m_pointWiseDesc.math_precision = data_type_;
144  return *this;
145  }
147  auto
148  setClipping(double l, double u) -> PointWiseDescBuilder_v8 & {
149  m_pointWiseDesc.upper_clip = u;
150  m_pointWiseDesc.lower_clip = l;
151  return *this;
152  }
154  auto
155  setMode(cudnnPointwiseMode_t mode_) -> PointWiseDescBuilder_v8 & {
156  m_pointWiseDesc.mode = mode_;
157  return *this;
158  }
160  auto
161  setMode(cudnnNanPropagation_t nan_mode_) -> PointWiseDescBuilder_v8 & {
162  m_pointWiseDesc.nan_propagation = nan_mode_;
163  return *this;
164  }
167  auto
168  setReluLowerClip(double lower_clip_) -> PointWiseDescBuilder_v8 & {
169  m_pointWiseDesc.lower_clip = lower_clip_;
170  return *this;
171  }
172 
173  auto
174  setReluUpperClip(double upper_clip_) -> PointWiseDescBuilder_v8 & {
175  m_pointWiseDesc.upper_clip = upper_clip_;
176  return *this;
177  }
178 
179  auto
180  setReluLowerClipSlope(double lower_clip_slope_) -> PointWiseDescBuilder_v8 & {
181  m_pointWiseDesc.lower_clip_slope = lower_clip_slope_;
182  return *this;
183  }
184 
185  auto
186  setEluAlpha(double elu_alpha_) -> PointWiseDescBuilder_v8 & {
187  m_pointWiseDesc.elu_alpha = elu_alpha_;
188  return *this;
189  }
190 
191  auto
192  setSoftplusBeta(double softplus_beta_) -> PointWiseDescBuilder_v8 & {
193  m_pointWiseDesc.softplus_beta = softplus_beta_;
194  return *this;
195  }
196 
197  auto
198  setSwishBeta(double swish_beta_) -> PointWiseDescBuilder_v8 & {
199  m_pointWiseDesc.swish_beta = swish_beta_;
200  return *this;
201  }
202 
206  build() {
207  // Create a descriptor. Memory allocation happens here.
208  auto status = m_pointWiseDesc.initialize_managed_backend_pointer(CUDNN_BACKEND_POINTWISE_DESCRIPTOR);
209  if (status != CUDNN_STATUS_SUCCESS) {
211  &m_pointWiseDesc, status, "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: cudnnCreate Failed");
212  return std::move(m_pointWiseDesc);
213  }
214 
215  // Once Created lets set the descriptor parameters.
216  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
217  CUDNN_ATTR_POINTWISE_MODE,
218  CUDNN_TYPE_POINTWISE_MODE,
219  1,
220  &m_pointWiseDesc.mode);
221  if (status != CUDNN_STATUS_SUCCESS) {
223  &m_pointWiseDesc,
224  status,
225  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: CUDNN_TYPE_POINTWISE_MODE SetAttribute Failed");
226  return std::move(m_pointWiseDesc);
227  }
228 
229  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
230  CUDNN_ATTR_POINTWISE_MATH_PREC,
231  CUDNN_TYPE_DATA_TYPE,
232  1,
233  &m_pointWiseDesc.math_precision);
234  if (status != CUDNN_STATUS_SUCCESS) {
236  &m_pointWiseDesc,
237  status,
238  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute CUDNN_ATTR_POINTWISE_MATH_PREC Failed");
239  return std::move(m_pointWiseDesc);
240  }
241 
242  if (m_pointWiseDesc.mode == CUDNN_POINTWISE_RELU_FWD || m_pointWiseDesc.mode == CUDNN_POINTWISE_RELU_BWD) {
243  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
244  CUDNN_ATTR_POINTWISE_NAN_PROPAGATION,
245  CUDNN_TYPE_NAN_PROPOGATION,
246  1,
247  &m_pointWiseDesc.nan_propagation);
248  if (status != CUDNN_STATUS_SUCCESS) {
250  &m_pointWiseDesc,
251  status,
252  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute CUDNN_ATTR_POINTWISE_NAN_PROPAGATION Failed");
253  return std::move(m_pointWiseDesc);
254  }
255 
256  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
257  CUDNN_ATTR_POINTWISE_RELU_LOWER_CLIP,
258  CUDNN_TYPE_DOUBLE,
259  1,
260  &m_pointWiseDesc.lower_clip);
261  if (status != CUDNN_STATUS_SUCCESS) {
263  &m_pointWiseDesc,
264  status,
265  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute CUDNN_ATTR_POINTWISE_RELU_LOWER_CLIP, Failed");
266  return std::move(m_pointWiseDesc);
267  }
268 
269  if (m_pointWiseDesc.math_precision == CUDNN_DATA_FLOAT) {
270  double clamped_upper_clip =
271  std::min<double>(m_pointWiseDesc.upper_clip, std::numeric_limits<float>::max());
272  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
273  CUDNN_ATTR_POINTWISE_RELU_UPPER_CLIP,
274  CUDNN_TYPE_DOUBLE,
275  1,
276  &clamped_upper_clip);
277 
278  } else {
279  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
280  CUDNN_ATTR_POINTWISE_RELU_UPPER_CLIP,
281  CUDNN_TYPE_DOUBLE,
282  1,
283  &m_pointWiseDesc.upper_clip);
284  }
285  if (status != CUDNN_STATUS_SUCCESS) {
287  &m_pointWiseDesc,
288  status,
289  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute CUDNN_ATTR_POINTWISE_RELU_UPPER_CLIP, Failed");
290  return std::move(m_pointWiseDesc);
291  }
292 
293  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
294  CUDNN_ATTR_POINTWISE_RELU_LOWER_CLIP_SLOPE,
295  CUDNN_TYPE_DOUBLE,
296  1,
297  &m_pointWiseDesc.lower_clip_slope);
298  if (status != CUDNN_STATUS_SUCCESS) {
299  set_error_and_throw_exception(&m_pointWiseDesc,
300  status,
301  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute "
302  "CUDNN_ATTR_POINTWISE_RELU_LOWER_CLIP_SLOPE, Failed");
303  return std::move(m_pointWiseDesc);
304  }
305  } else if (m_pointWiseDesc.mode == CUDNN_POINTWISE_ELU_FWD || m_pointWiseDesc.mode == CUDNN_POINTWISE_ELU_BWD) {
306  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
307  CUDNN_ATTR_POINTWISE_ELU_ALPHA,
308  CUDNN_TYPE_DOUBLE,
309  1,
310  &m_pointWiseDesc.elu_alpha);
311  if (status != CUDNN_STATUS_SUCCESS) {
313  &m_pointWiseDesc,
314  status,
315  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute CUDNN_ATTR_POINTWISE_ELU_ALPHA, Failed");
316  return std::move(m_pointWiseDesc);
317  }
318  } else if (m_pointWiseDesc.mode == CUDNN_POINTWISE_SOFTPLUS_FWD ||
319  m_pointWiseDesc.mode == CUDNN_POINTWISE_SOFTPLUS_BWD) {
320  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
321  CUDNN_ATTR_POINTWISE_SOFTPLUS_BETA,
322  CUDNN_TYPE_DOUBLE,
323  1,
324  &m_pointWiseDesc.softplus_beta);
325  if (status != CUDNN_STATUS_SUCCESS) {
327  &m_pointWiseDesc,
328  status,
329  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute CUDNN_ATTR_POINTWISE_SOFTPLUS_BETA, Failed");
330  return std::move(m_pointWiseDesc);
331  }
332  } else if (m_pointWiseDesc.mode == CUDNN_POINTWISE_SWISH_FWD ||
333  m_pointWiseDesc.mode == CUDNN_POINTWISE_SWISH_BWD) {
334  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
335  CUDNN_ATTR_POINTWISE_SWISH_BETA,
336  CUDNN_TYPE_DOUBLE,
337  1,
338  &m_pointWiseDesc.swish_beta);
339  if (status != CUDNN_STATUS_SUCCESS) {
341  &m_pointWiseDesc,
342  status,
343  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute CUDNN_ATTR_POINTWISE_SWISH_BETA, Failed");
344  return std::move(m_pointWiseDesc);
345  }
346  }
347 
348  // Finalizing the descriptor
349  status = cudnnBackendFinalize(m_pointWiseDesc.pointer->get_backend_descriptor());
350  if (status != CUDNN_STATUS_SUCCESS) {
352  &m_pointWiseDesc, status, "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: cudnnFinalize Failed");
353  return std::move(m_pointWiseDesc);
354  }
355 
356  return std::move(m_pointWiseDesc);
357  }
358 
359  explicit PointWiseDescBuilder_v8() = default;
360  ~PointWiseDescBuilder_v8() = default;
364  operator=(PointWiseDescBuilder_v8 const &) = delete;
365 
366  private:
368 };
369 }
static void set_error_and_throw_exception(BackendDescriptor const *desc, cudnnStatus_t status, const char *message)
auto setClipping(double l, double u) -> PointWiseDescBuilder_v8 &
Set upper and lower limits for the RELU activation.
PointWiseDesc_v8 & operator=(PointWiseDesc_v8 const &)=delete
auto setMode(cudnnNanPropagation_t nan_mode_) -> PointWiseDescBuilder_v8 &
Set NaN propagation mode.
auto setSwishBeta(double swish_beta_) -> PointWiseDescBuilder_v8 &
cudnnPointwiseMode_t getPointWiseMode() const
ManagedOpaqueDescriptor get_desc() const
Returns a copy of underlying managed descriptor.
auto setReluLowerClip(double lower_clip_) -> PointWiseDescBuilder_v8 &
auto setSoftplusBeta(double softplus_beta_) -> PointWiseDescBuilder_v8 &
std::string describe() const override
Return a string describing the backend Descriptor.
auto setReluLowerClipSlope(double lower_clip_slope_) -> PointWiseDescBuilder_v8 &
cudnnStatus_t get_status() const
Current status of the descriptor.
const char * get_error() const
Diagonistic error message if any.
auto setMathPrecision(cudnnDataType_t data_type_) -> PointWiseDescBuilder_v8 &
Set Math Precision Data Type for the Convolution Operation.
auto setMode(cudnnPointwiseMode_t mode_) -> PointWiseDescBuilder_v8 &
Set pointwise mode for the activation.
auto setEluAlpha(double elu_alpha_) -> PointWiseDescBuilder_v8 &
auto setReluUpperClip(double upper_clip_) -> PointWiseDescBuilder_v8 &
cudnnStatus_t status
Shared pointer of the OpaqueBackendPointer.