CUDNN Frontend API  8.3.0
cudnn_frontend_ConvDesc.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 {
38 
55  public:
56  friend class ConvDescBuilder_v8;
57  std::string
58  describe() const override {
59  std::stringstream ss;
60  char sep = ' ';
61  ss << "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR :"
62  << " Datatype: " << to_string(compute_precision) << " Mode: " << std::to_string(mode)
63  << " Num Dimensions: " << nDims;
64  ss << " PadLower [";
65  for (auto i = 0; i < nDims; i++) {
66  ss << sep << padLower[i];
67  sep = ',';
68  }
69  ss << " ] PadUpper [";
70  for (auto i = 0; i < nDims; i++) {
71  ss << sep << padUpper[i];
72  sep = ',';
73  }
74  ss << " ] Dilation [";
75  for (auto i = 0; i < nDims; i++) {
76  ss << sep << dilation[i];
77  sep = ',';
78  }
79  ss << " ] Stride [";
80  for (auto i = 0; i < nDims; i++) {
81  ss << sep << stride[i];
82  sep = ',';
83  }
84  ss << "]";
85  return ss.str();
86  }
87 
88  ConvDesc_v8(ConvDesc_v8 &&from) = default;
89  ConvDesc_v8 &
90  operator=(ConvDesc_v8 &&) = default;
91 
92  ~ConvDesc_v8() = default;
93 
94  cudnnDataType_t
96  return compute_precision;
97  }
98 
99  int64_t
101  return nDims;
102  }
103 
104  int64_t const *
105  getPadding() const {
106  return padLower;
107  }
108  int64_t const *
109  getStride() const {
110  return stride;
111  }
112  int64_t const *
113  getDilation() const {
114  return dilation;
115  }
116 
117  cudnnConvolutionMode_t
118  getMathMode() const {
119  return mode;
120  }
121 
122 
123  private:
124  ConvDesc_v8() = default;
125  ConvDesc_v8(ConvDesc_v8 const &) = delete;
126  ConvDesc_v8 &
127  operator=(ConvDesc_v8 const &) = delete;
128 
129  cudnnDataType_t compute_precision = CUDNN_DATA_FLOAT;
130  cudnnConvolutionMode_t mode = CUDNN_CONVOLUTION;
131  int64_t nDims = -1;
132  int64_t padLower[CUDNN_DIM_MAX + 1] = {0};
133  int64_t padUpper[CUDNN_DIM_MAX + 1] = {0};
134  int64_t dilation[CUDNN_DIM_MAX + 1] = {0};
135  int64_t stride[CUDNN_DIM_MAX + 1] = {-1};
136 };
137 
142  public:
147  auto
149  setDataType(cudnnDataType_t data_type_) -> ConvDescBuilder_v8 & {
150  return setComputePrecision(data_type_);
151  }
152  auto
153  setComputePrecision(cudnnDataType_t data_type_) -> ConvDescBuilder_v8 & {
154  m_convDesc.compute_precision = data_type_;
155  return *this;
156  }
158  auto
159  setPrePadding(int64_t ndims, int64_t const *padding) -> ConvDescBuilder_v8 & {
160  std::copy(padding, padding + ndims, m_convDesc.padLower);
161  return *this;
162  }
164  auto
165  setPostPadding(int64_t ndims, int64_t const *padding) -> ConvDescBuilder_v8 & {
166  std::copy(padding, padding + ndims, m_convDesc.padUpper);
167  return *this;
168  }
170  auto
171  setDilation(int64_t ndims, int64_t const *dilation) -> ConvDescBuilder_v8 & {
172  std::copy(dilation, dilation + ndims, m_convDesc.dilation);
173  return *this;
174  }
176  auto
177  setStrides(int64_t ndims, int64_t const *strides) -> ConvDescBuilder_v8 & {
178  std::copy(strides, strides + ndims, m_convDesc.stride);
179  return *this;
180  }
182  auto
183  setNDims(int64_t nDims_) -> ConvDescBuilder_v8 & {
184  m_convDesc.nDims = nDims_;
185  return *this;
186  }
188  auto
189  setMathMode(cudnnConvolutionMode_t mode_) -> ConvDescBuilder_v8 & {
190  m_convDesc.mode = mode_;
191  return *this;
192  }
195  ConvDesc_v8 &&
198  build() {
199  // Sanity check if non-default fields have been set correctly.
200  if (m_convDesc.nDims <= 0) {
202  &m_convDesc,
203  CUDNN_STATUS_BAD_PARAM,
204  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: Check and Set the CUDNN_ATTR_CONVOLUTION_SPATIAL_DIMS field");
205  return std::move(m_convDesc);
206  };
207  if (m_convDesc.stride[0] <= 0) {
209  &m_convDesc,
210  CUDNN_STATUS_BAD_PARAM,
211  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: Check and Set the CUDNN_ATTR_CONVOLUTION_FILTER_STRIDES field");
212  return std::move(m_convDesc);
213  }
214 
215  // Create a descriptor. Memory allocation happens here.
216  auto status = m_convDesc.initialize_managed_backend_pointer(CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR);
217  if (status != CUDNN_STATUS_SUCCESS) {
219  &m_convDesc, status, "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: Bad descriptor created");
220  return std::move(m_convDesc);
221  }
222 
223  if (status != CUDNN_STATUS_SUCCESS) {
225  &m_convDesc, status, "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: cudnnCreate Failed");
226  return std::move(m_convDesc);
227  }
228 
229  // Once Created lets set the descriptor parameters.
230  status = cudnnBackendSetAttribute(m_convDesc.pointer->get_backend_descriptor(),
231  CUDNN_ATTR_CONVOLUTION_COMP_TYPE,
232  CUDNN_TYPE_DATA_TYPE,
233  1,
234  &m_convDesc.compute_precision);
235  if (status != CUDNN_STATUS_SUCCESS) {
237  &m_convDesc,
238  status,
239  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: SetAttribute CUDNN_ATTR_CONVOLUTION_COMP_TYPE Failed");
240  return std::move(m_convDesc);
241  }
242 
243  status = cudnnBackendSetAttribute(m_convDesc.pointer->get_backend_descriptor(),
244  CUDNN_ATTR_CONVOLUTION_CONV_MODE,
245  CUDNN_TYPE_CONVOLUTION_MODE,
246  1,
247  &m_convDesc.mode);
248  if (status != CUDNN_STATUS_SUCCESS) {
250  &m_convDesc,
251  status,
252  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: SetAttribute CUDNN_ATTR_CONVOLUTION_CONV_MODE Failed");
253  return std::move(m_convDesc);
254  }
255 
256  status = cudnnBackendSetAttribute(m_convDesc.pointer->get_backend_descriptor(),
257  CUDNN_ATTR_CONVOLUTION_SPATIAL_DIMS,
258  CUDNN_TYPE_INT64,
259  1,
260  &m_convDesc.nDims);
261  if (status != CUDNN_STATUS_SUCCESS) {
263  &m_convDesc,
264  status,
265  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: SetAttribute CUDNN_ATTR_CONVOLUTION_SPATIAL_DIMS Failed");
266  return std::move(m_convDesc);
267  }
268 
269  status = cudnnBackendSetAttribute(m_convDesc.pointer->get_backend_descriptor(),
270  CUDNN_ATTR_CONVOLUTION_PRE_PADDINGS,
271  CUDNN_TYPE_INT64,
272  m_convDesc.nDims,
273  m_convDesc.padLower);
274  if (status != CUDNN_STATUS_SUCCESS) {
276  &m_convDesc,
277  status,
278  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: SetAttribute CUDNN_ATTR_CONVOLUTION_PRE_PADDINGS Failed");
279  return std::move(m_convDesc);
280  }
281 
282  status = cudnnBackendSetAttribute(m_convDesc.pointer->get_backend_descriptor(),
283  CUDNN_ATTR_CONVOLUTION_POST_PADDINGS,
284  CUDNN_TYPE_INT64,
285  m_convDesc.nDims,
286  m_convDesc.padUpper);
287  if (status != CUDNN_STATUS_SUCCESS) {
289  &m_convDesc,
290  status,
291  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: SetAttribute CUDNN_ATTR_CONVOLUTION_POST_PADDINGS Failed");
292  return std::move(m_convDesc);
293  }
294 
295  status = cudnnBackendSetAttribute(m_convDesc.pointer->get_backend_descriptor(),
296  CUDNN_ATTR_CONVOLUTION_DILATIONS,
297  CUDNN_TYPE_INT64,
298  m_convDesc.nDims,
299  m_convDesc.dilation);
300  if (status != CUDNN_STATUS_SUCCESS) {
302  &m_convDesc,
303  status,
304  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: SetAttribute CUDNN_ATTR_CONVOLUTION_DILATIONS Failed");
305  return std::move(m_convDesc);
306  }
307 
308  status = cudnnBackendSetAttribute(m_convDesc.pointer->get_backend_descriptor(),
309  CUDNN_ATTR_CONVOLUTION_FILTER_STRIDES,
310  CUDNN_TYPE_INT64,
311  m_convDesc.nDims,
312  m_convDesc.stride);
313  if (status != CUDNN_STATUS_SUCCESS) {
315  &m_convDesc,
316  status,
317  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: SetAttribute CUDNN_ATTR_CONVOLUTION_FILTER_STRIDES Failed");
318  return std::move(m_convDesc);
319  }
320 
321  // Finalizing the descriptor
322  status = cudnnBackendFinalize(m_convDesc.pointer->get_backend_descriptor());
323  if (status != CUDNN_STATUS_SUCCESS) {
325  &m_convDesc, status, "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: cudnnFinalize Failed");
326  return std::move(m_convDesc);
327  }
328 
329  getLogger() << "[cudnn_frontend] " << m_convDesc << std::endl;
330  return std::move(m_convDesc);
331  }
332 
333  explicit ConvDescBuilder_v8() = default;
334  ~ConvDescBuilder_v8() = default;
336  ConvDescBuilder_v8(ConvDescBuilder_v8 const &) = delete;
338  operator=(ConvDescBuilder_v8 const &) = delete;
339 
340  private:
342 };
343 }
int64_t padUpper[CUDNN_DIM_MAX+1]
d, h, w
int64_t const * getStride() const
ConditionalStreamer & getLogger()
static void set_error_and_throw_exception(BackendDescriptor const *desc, cudnnStatus_t status, const char *message)
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:25855
int64_t const * getPadding() const
cudnnDataType_t getComputePrecision() const
int64_t dilation[CUDNN_DIM_MAX+1]
d, h, w
int64_t nDims
Convolution vs cross correlation.
auto setNDims(int64_t nDims_) -> ConvDescBuilder_v8 &
Set Num Spatial Dimensions of the convolution Operation.
auto setPrePadding(int64_t ndims, int64_t const *padding) -> ConvDescBuilder_v8 &
Set Padding Lower of the convDesc.
auto setDilation(int64_t ndims, int64_t const *dilation) -> ConvDescBuilder_v8 &
Set Dilation of the convDesc.
auto setMathMode(cudnnConvolutionMode_t mode_) -> ConvDescBuilder_v8 &
Set Convolution Mode of the convolution Operation.
int64_t stride[CUDNN_DIM_MAX+1]
d, h, w
cudnnConvolutionMode_t getMathMode() const
auto setStrides(int64_t ndims, int64_t const *strides) -> ConvDescBuilder_v8 &
Set Strides of the convDesc.
static std::string to_string(cudnnDataType_t type)
auto setPostPadding(int64_t ndims, int64_t const *padding) -> ConvDescBuilder_v8 &
Set Padding Upper of the convDesc.
int64_t padLower[CUDNN_DIM_MAX+1]
number of dimensions
std::string describe() const override
Return a string describing the backend Descriptor.
auto setDataType(cudnnDataType_t data_type_) -> ConvDescBuilder_v8 &
Set Datatype for the Convolution Operation.
int64_t const * getDilation() const
cudnnConvolutionMode_t mode
Convolution operation data type.
ConvDesc_v8 & operator=(ConvDesc_v8 &&)=default
auto setComputePrecision(cudnnDataType_t data_type_) -> ConvDescBuilder_v8 &
cudnnStatus_t status
Shared pointer of the OpaqueBackendPointer.