CUDNN Frontend API  8.3.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 #include <limits>
32 
33 #include <cudnn.h>
34 #include <cudnn_backend.h>
35 
36 #include "cudnn_frontend_utils.h"
37 
38 namespace cudnn_frontend {
57  public:
59  std::string
60  describe() const override {
61  std::stringstream ss;
62  ss << "CUDNN_BACKEND_POINTWISE_DESCRIPTOR :"
63  << " Mode: " << (mode) << " Math precision " << (math_precision);
64  return ss.str();
65  }
66 
67  int64_t
68  getPortCount() const {
69  switch (mode) {
70  case CUDNN_POINTWISE_ADD:
71  case CUDNN_POINTWISE_MUL:
72 #if (CUDNN_VERSION >= 8300)
73  case CUDNN_POINTWISE_DIV:
74  case CUDNN_POINTWISE_ADD_SQUARE:
75  case CUDNN_POINTWISE_SUB:
76  case CUDNN_POINTWISE_CMP_EQ:
77  case CUDNN_POINTWISE_CMP_NEQ:
78  case CUDNN_POINTWISE_CMP_GT:
79  case CUDNN_POINTWISE_CMP_GE:
80  case CUDNN_POINTWISE_CMP_LT:
81  case CUDNN_POINTWISE_CMP_LE:
82  case CUDNN_POINTWISE_LOGICAL_AND:
83  case CUDNN_POINTWISE_LOGICAL_OR:
84 #endif
85  case CUDNN_POINTWISE_MIN:
86  case CUDNN_POINTWISE_MAX:
87  case CUDNN_POINTWISE_RELU_BWD:
88  case CUDNN_POINTWISE_TANH_BWD:
89  case CUDNN_POINTWISE_SIGMOID_BWD:
90  case CUDNN_POINTWISE_ELU_BWD:
91  case CUDNN_POINTWISE_GELU_BWD:
92  case CUDNN_POINTWISE_SOFTPLUS_BWD:
93  case CUDNN_POINTWISE_SWISH_BWD:
94  return 3;
95  case CUDNN_POINTWISE_SQRT:
96  case CUDNN_POINTWISE_RELU_FWD:
97  case CUDNN_POINTWISE_TANH_FWD:
98  case CUDNN_POINTWISE_SIGMOID_FWD:
99  case CUDNN_POINTWISE_ELU_FWD:
100  case CUDNN_POINTWISE_GELU_FWD:
101  case CUDNN_POINTWISE_SOFTPLUS_FWD:
102  case CUDNN_POINTWISE_SWISH_FWD:
103 #if (CUDNN_VERSION >= 8300)
104  case CUDNN_POINTWISE_EXP:
105  case CUDNN_POINTWISE_LOG:
106  case CUDNN_POINTWISE_NEG:
107  case CUDNN_POINTWISE_MOD:
108  case CUDNN_POINTWISE_POW:
109  case CUDNN_POINTWISE_ABS:
110  case CUDNN_POINTWISE_CEIL:
111  case CUDNN_POINTWISE_FLOOR:
112  case CUDNN_POINTWISE_COS:
113  case CUDNN_POINTWISE_TAN:
114  case CUDNN_POINTWISE_SIN:
115  case CUDNN_POINTWISE_RSQRT:
116  case CUDNN_POINTWISE_LOGICAL_NOT:
117 #endif
118  return 2;
119  }
120  }
121 
122  cudnnPointwiseMode_t
124  return mode;
125  }
126 
127  PointWiseDesc_v8(PointWiseDesc_v8 &&from) = default;
129  operator= (PointWiseDesc_v8 &&from) = default;
130 
131  ~PointWiseDesc_v8() = default;
132 
133  private:
134  PointWiseDesc_v8() = default;
135  PointWiseDesc_v8(PointWiseDesc_v8 const &) = delete;
137  operator=(PointWiseDesc_v8 const &) = delete;
138 
139  cudnnDataType_t math_precision = CUDNN_DATA_FLOAT;
140  cudnnPointwiseMode_t mode = CUDNN_POINTWISE_ADD;
141  cudnnNanPropagation_t nan_propagation = CUDNN_NOT_PROPAGATE_NAN;
142  double upper_clip = std::numeric_limits<double>::max();
143  double lower_clip = 0.0;
144  double lower_clip_slope = 0.0;
145  double elu_alpha = 1.0;
146  double softplus_beta = 1.0;
147  double swish_beta = 1.0;
148 };
149 
154  public:
159  auto
161  setMathPrecision(cudnnDataType_t data_type_) -> PointWiseDescBuilder_v8 & {
162  m_pointWiseDesc.math_precision = data_type_;
163  return *this;
164  }
166  auto
167  setClipping(double l, double u) -> PointWiseDescBuilder_v8 & {
168  m_pointWiseDesc.upper_clip = u;
169  m_pointWiseDesc.lower_clip = l;
170  return *this;
171  }
173  auto
174  setMode(cudnnPointwiseMode_t mode_) -> PointWiseDescBuilder_v8 & {
175  m_pointWiseDesc.mode = mode_;
176  return *this;
177  }
179  auto
180  setMode(cudnnNanPropagation_t nan_mode_) -> PointWiseDescBuilder_v8 & {
181  m_pointWiseDesc.nan_propagation = nan_mode_;
182  return *this;
183  }
186  auto
187  setReluLowerClip(double lower_clip_) -> PointWiseDescBuilder_v8 & {
188  m_pointWiseDesc.lower_clip = lower_clip_;
189  return *this;
190  }
191 
192  auto
193  setReluUpperClip(double upper_clip_) -> PointWiseDescBuilder_v8 & {
194  m_pointWiseDesc.upper_clip = upper_clip_;
195  return *this;
196  }
197 
198  auto
199  setReluLowerClipSlope(double lower_clip_slope_) -> PointWiseDescBuilder_v8 & {
200  m_pointWiseDesc.lower_clip_slope = lower_clip_slope_;
201  return *this;
202  }
203 
204  auto
205  setEluAlpha(double elu_alpha_) -> PointWiseDescBuilder_v8 & {
206  m_pointWiseDesc.elu_alpha = elu_alpha_;
207  return *this;
208  }
209 
210  auto
211  setSoftplusBeta(double softplus_beta_) -> PointWiseDescBuilder_v8 & {
212  m_pointWiseDesc.softplus_beta = softplus_beta_;
213  return *this;
214  }
215 
216  auto
217  setSwishBeta(double swish_beta_) -> PointWiseDescBuilder_v8 & {
218  m_pointWiseDesc.swish_beta = swish_beta_;
219  return *this;
220  }
221 
225  build() {
226  // Create a descriptor. Memory allocation happens here.
227  auto status = m_pointWiseDesc.initialize_managed_backend_pointer(CUDNN_BACKEND_POINTWISE_DESCRIPTOR);
228  if (status != CUDNN_STATUS_SUCCESS) {
230  &m_pointWiseDesc, status, "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: cudnnCreate Failed");
231  return std::move(m_pointWiseDesc);
232  }
233 
234  // Once Created lets set the descriptor parameters.
235  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
236  CUDNN_ATTR_POINTWISE_MODE,
237  CUDNN_TYPE_POINTWISE_MODE,
238  1,
239  &m_pointWiseDesc.mode);
240  if (status != CUDNN_STATUS_SUCCESS) {
242  &m_pointWiseDesc,
243  status,
244  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: CUDNN_TYPE_POINTWISE_MODE SetAttribute Failed");
245  return std::move(m_pointWiseDesc);
246  }
247 
248  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
249  CUDNN_ATTR_POINTWISE_MATH_PREC,
250  CUDNN_TYPE_DATA_TYPE,
251  1,
252  &m_pointWiseDesc.math_precision);
253  if (status != CUDNN_STATUS_SUCCESS) {
255  &m_pointWiseDesc,
256  status,
257  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute CUDNN_ATTR_POINTWISE_MATH_PREC Failed");
258  return std::move(m_pointWiseDesc);
259  }
260 
261  if (m_pointWiseDesc.mode == CUDNN_POINTWISE_RELU_FWD || m_pointWiseDesc.mode == CUDNN_POINTWISE_RELU_BWD) {
262  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
263  CUDNN_ATTR_POINTWISE_NAN_PROPAGATION,
264  CUDNN_TYPE_NAN_PROPOGATION,
265  1,
266  &m_pointWiseDesc.nan_propagation);
267  if (status != CUDNN_STATUS_SUCCESS) {
269  &m_pointWiseDesc,
270  status,
271  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute CUDNN_ATTR_POINTWISE_NAN_PROPAGATION Failed");
272  return std::move(m_pointWiseDesc);
273  }
274 
275  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
276  CUDNN_ATTR_POINTWISE_RELU_LOWER_CLIP,
277  CUDNN_TYPE_DOUBLE,
278  1,
279  &m_pointWiseDesc.lower_clip);
280  if (status != CUDNN_STATUS_SUCCESS) {
282  &m_pointWiseDesc,
283  status,
284  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute CUDNN_ATTR_POINTWISE_RELU_LOWER_CLIP, Failed");
285  return std::move(m_pointWiseDesc);
286  }
287 
288  if (m_pointWiseDesc.math_precision == CUDNN_DATA_FLOAT) {
289  double clamped_upper_clip =
290  std::min<double>(m_pointWiseDesc.upper_clip, std::numeric_limits<float>::max());
291  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
292  CUDNN_ATTR_POINTWISE_RELU_UPPER_CLIP,
293  CUDNN_TYPE_DOUBLE,
294  1,
295  &clamped_upper_clip);
296 
297  } else {
298  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
299  CUDNN_ATTR_POINTWISE_RELU_UPPER_CLIP,
300  CUDNN_TYPE_DOUBLE,
301  1,
302  &m_pointWiseDesc.upper_clip);
303  }
304  if (status != CUDNN_STATUS_SUCCESS) {
306  &m_pointWiseDesc,
307  status,
308  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute CUDNN_ATTR_POINTWISE_RELU_UPPER_CLIP, Failed");
309  return std::move(m_pointWiseDesc);
310  }
311 
312  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
313  CUDNN_ATTR_POINTWISE_RELU_LOWER_CLIP_SLOPE,
314  CUDNN_TYPE_DOUBLE,
315  1,
316  &m_pointWiseDesc.lower_clip_slope);
317  if (status != CUDNN_STATUS_SUCCESS) {
318  set_error_and_throw_exception(&m_pointWiseDesc,
319  status,
320  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute "
321  "CUDNN_ATTR_POINTWISE_RELU_LOWER_CLIP_SLOPE, Failed");
322  return std::move(m_pointWiseDesc);
323  }
324  } else if (m_pointWiseDesc.mode == CUDNN_POINTWISE_ELU_FWD || m_pointWiseDesc.mode == CUDNN_POINTWISE_ELU_BWD) {
325  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
326  CUDNN_ATTR_POINTWISE_ELU_ALPHA,
327  CUDNN_TYPE_DOUBLE,
328  1,
329  &m_pointWiseDesc.elu_alpha);
330  if (status != CUDNN_STATUS_SUCCESS) {
332  &m_pointWiseDesc,
333  status,
334  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute CUDNN_ATTR_POINTWISE_ELU_ALPHA, Failed");
335  return std::move(m_pointWiseDesc);
336  }
337  } else if (m_pointWiseDesc.mode == CUDNN_POINTWISE_SOFTPLUS_FWD ||
338  m_pointWiseDesc.mode == CUDNN_POINTWISE_SOFTPLUS_BWD) {
339  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
340  CUDNN_ATTR_POINTWISE_SOFTPLUS_BETA,
341  CUDNN_TYPE_DOUBLE,
342  1,
343  &m_pointWiseDesc.softplus_beta);
344  if (status != CUDNN_STATUS_SUCCESS) {
346  &m_pointWiseDesc,
347  status,
348  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute CUDNN_ATTR_POINTWISE_SOFTPLUS_BETA, Failed");
349  return std::move(m_pointWiseDesc);
350  }
351  } else if (m_pointWiseDesc.mode == CUDNN_POINTWISE_SWISH_FWD ||
352  m_pointWiseDesc.mode == CUDNN_POINTWISE_SWISH_BWD) {
353  status = cudnnBackendSetAttribute(m_pointWiseDesc.pointer->get_backend_descriptor(),
354  CUDNN_ATTR_POINTWISE_SWISH_BETA,
355  CUDNN_TYPE_DOUBLE,
356  1,
357  &m_pointWiseDesc.swish_beta);
358  if (status != CUDNN_STATUS_SUCCESS) {
360  &m_pointWiseDesc,
361  status,
362  "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: SetAttribute CUDNN_ATTR_POINTWISE_SWISH_BETA, Failed");
363  return std::move(m_pointWiseDesc);
364  }
365  }
366 
367  // Finalizing the descriptor
368  status = cudnnBackendFinalize(m_pointWiseDesc.pointer->get_backend_descriptor());
369  if (status != CUDNN_STATUS_SUCCESS) {
371  &m_pointWiseDesc, status, "CUDNN_BACKEND_POINTWISE_DESCRIPTOR: cudnnFinalize Failed");
372  return std::move(m_pointWiseDesc);
373  }
374 
375  getLogger() << "[cudnn_frontend] " << m_pointWiseDesc << std::endl;
376  return std::move(m_pointWiseDesc);
377  }
378 
379  explicit PointWiseDescBuilder_v8() = default;
380  ~PointWiseDescBuilder_v8() = default;
384  operator=(PointWiseDescBuilder_v8 const &) = delete;
385 
386  private:
388 };
389 }
ConditionalStreamer & getLogger()
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.
auto setMode(cudnnNanPropagation_t nan_mode_) -> PointWiseDescBuilder_v8 &
Set NaN propagation mode.
auto setSwishBeta(double swish_beta_) -> PointWiseDescBuilder_v8 &
cudnnPointwiseMode_t getPointWiseMode() const
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 &
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 &
PointWiseDesc_v8 & operator=(PointWiseDesc_v8 &&from)=default
auto setReluUpperClip(double upper_clip_) -> PointWiseDescBuilder_v8 &
cudnnStatus_t status
Shared pointer of the OpaqueBackendPointer.