CUDNN API  8
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: " << std::to_string(data_type) << " Mode: " << std::to_string(mode)
63  << " Num Dimensions: " << std::to_string(nDims);
64  ss << " PadLower [";
65  std::for_each(std::begin(padLower), std::end(padLower), [&ss, sep](int x) mutable {
66  ss << sep << x;
67  sep = ',';
68  });
69  ss << " ] PadUpper [";
70  std::for_each(std::begin(padUpper), std::end(padUpper), [&ss, sep](int x) mutable {
71  ss << sep << x;
72  sep = ',';
73  });
74  ss << " ] Dilation [";
75  std::for_each(std::begin(dilation), std::end(dilation), [&ss, sep](int x) mutable {
76  ss << sep << x;
77  sep = ',';
78  });
79  ss << " ] Stride [";
80  std::for_each(std::begin(stride), std::end(stride), [&ss, sep](int x) mutable {
81  ss << sep << x;
82  sep = ',';
83  });
84  ss << "]";
85  return ss.str();
86  }
87 
89  : BackendDescriptor(from.get_desc(), from.get_status(), from.get_error()),
90  data_type(from.data_type),
91  mode(from.mode),
92  nDims(from.nDims) {
93  std::copy(std::begin(from.padLower), std::end(from.padLower), padLower);
94  std::copy(std::begin(from.padUpper), std::end(from.padUpper), padUpper);
95  std::copy(std::begin(from.dilation), std::end(from.dilation), dilation);
96  std::copy(std::begin(from.stride), std::end(from.stride), stride);
97  }
98 
99  ~ConvDesc_v8() = default;
100 
101  private:
102  ConvDesc_v8() = default;
103  ConvDesc_v8(ConvDesc_v8 const &) = delete;
104  ConvDesc_v8 &
105  operator=(ConvDesc_v8 const &) = delete;
106 
107  cudnnDataType_t data_type = CUDNN_DATA_FLOAT;
108  cudnnConvolutionMode_t mode = CUDNN_CONVOLUTION;
109  int64_t nDims = -1;
110  int64_t padLower[CUDNN_DIM_MAX + 1] = {0};
111  int64_t padUpper[CUDNN_DIM_MAX + 1] = {0};
112  int64_t dilation[CUDNN_DIM_MAX + 1] = {0};
113  int64_t stride[CUDNN_DIM_MAX + 1] = {-1};
114 };
115 
120  public:
125  auto
127  setDataType(cudnnDataType_t data_type_) -> ConvDescBuilder_v8 & {
128  m_convDesc.data_type = data_type_;
129  return *this;
130  }
132  auto
133  setPrePadding(int64_t ndims, int64_t const *padding) -> ConvDescBuilder_v8 & {
134  std::copy(padding, padding + ndims, m_convDesc.padLower);
135  return *this;
136  }
138  auto
139  setPostPadding(int64_t ndims, int64_t const *padding) -> ConvDescBuilder_v8 & {
140  std::copy(padding, padding + ndims, m_convDesc.padUpper);
141  return *this;
142  }
144  auto
145  setDilation(int64_t ndims, int64_t const *dilation) -> ConvDescBuilder_v8 & {
146  std::copy(dilation, dilation + ndims, m_convDesc.dilation);
147  return *this;
148  }
150  auto
151  setStrides(int64_t ndims, int64_t const *strides) -> ConvDescBuilder_v8 & {
152  std::copy(strides, strides + ndims, m_convDesc.stride);
153  return *this;
154  }
156  auto
157  setNDims(int64_t nDims_) -> ConvDescBuilder_v8 & {
158  m_convDesc.nDims = nDims_;
159  return *this;
160  }
162  auto
163  setMathMode(cudnnConvolutionMode_t mode_) -> ConvDescBuilder_v8 & {
164  m_convDesc.mode = mode_;
165  return *this;
166  }
169  ConvDesc_v8 &&
172  build() {
173  // Sanity check if non-default fields have been set correctly.
174  if (m_convDesc.nDims <= 0) {
176  &m_convDesc,
177  CUDNN_STATUS_BAD_PARAM,
178  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: Check and Set the CUDNN_ATTR_CONVOLUTION_SPATIAL_DIMS field");
179  return std::move(m_convDesc);
180  };
181  if (m_convDesc.stride[0] <= 0) {
183  &m_convDesc,
184  CUDNN_STATUS_BAD_PARAM,
185  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: Check and Set the CUDNN_ATTR_CONVOLUTION_FILTER_STRIDES field");
186  return std::move(m_convDesc);
187  }
188 
189  // Create a descriptor. Memory allocation happens here.
190  auto status = m_convDesc.initialize_managed_backend_pointer(CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR);
191  if (status != CUDNN_STATUS_SUCCESS) {
193  &m_convDesc, status, "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: Bad descriptor created");
194  return std::move(m_convDesc);
195  }
196 
197  if (status != CUDNN_STATUS_SUCCESS) {
199  &m_convDesc, status, "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: cudnnCreate Failed");
200  return std::move(m_convDesc);
201  }
202 
203  // Once Created lets set the descriptor parameters.
204  status = cudnnBackendSetAttribute(m_convDesc.pointer->get_backend_descriptor(),
205  CUDNN_ATTR_CONVOLUTION_COMP_TYPE,
206  CUDNN_TYPE_DATA_TYPE,
207  1,
208  &m_convDesc.data_type);
209  if (status != CUDNN_STATUS_SUCCESS) {
211  &m_convDesc,
212  status,
213  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: SetAttribute CUDNN_ATTR_CONVOLUTION_COMP_TYPE Failed");
214  return std::move(m_convDesc);
215  }
216 
217  status = cudnnBackendSetAttribute(m_convDesc.pointer->get_backend_descriptor(),
218  CUDNN_ATTR_CONVOLUTION_CONV_MODE,
219  CUDNN_TYPE_CONVOLUTION_MODE,
220  1,
221  &m_convDesc.mode);
222  if (status != CUDNN_STATUS_SUCCESS) {
224  &m_convDesc,
225  status,
226  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: SetAttribute CUDNN_ATTR_CONVOLUTION_CONV_MODE Failed");
227  return std::move(m_convDesc);
228  }
229 
230  status = cudnnBackendSetAttribute(m_convDesc.pointer->get_backend_descriptor(),
231  CUDNN_ATTR_CONVOLUTION_SPATIAL_DIMS,
232  CUDNN_TYPE_INT64,
233  1,
234  &m_convDesc.nDims);
235  if (status != CUDNN_STATUS_SUCCESS) {
237  &m_convDesc,
238  status,
239  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: SetAttribute CUDNN_ATTR_CONVOLUTION_SPATIAL_DIMS Failed");
240  return std::move(m_convDesc);
241  }
242 
243  status = cudnnBackendSetAttribute(m_convDesc.pointer->get_backend_descriptor(),
244  CUDNN_ATTR_CONVOLUTION_PRE_PADDINGS,
245  CUDNN_TYPE_INT64,
246  m_convDesc.nDims,
247  m_convDesc.padLower);
248  if (status != CUDNN_STATUS_SUCCESS) {
250  &m_convDesc,
251  status,
252  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: SetAttribute CUDNN_ATTR_CONVOLUTION_PRE_PADDINGS Failed");
253  return std::move(m_convDesc);
254  }
255 
256  status = cudnnBackendSetAttribute(m_convDesc.pointer->get_backend_descriptor(),
257  CUDNN_ATTR_CONVOLUTION_POST_PADDINGS,
258  CUDNN_TYPE_INT64,
259  m_convDesc.nDims,
260  m_convDesc.padUpper);
261  if (status != CUDNN_STATUS_SUCCESS) {
263  &m_convDesc,
264  status,
265  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: SetAttribute CUDNN_ATTR_CONVOLUTION_POST_PADDINGS Failed");
266  return std::move(m_convDesc);
267  }
268 
269  status = cudnnBackendSetAttribute(m_convDesc.pointer->get_backend_descriptor(),
270  CUDNN_ATTR_CONVOLUTION_DILATIONS,
271  CUDNN_TYPE_INT64,
272  m_convDesc.nDims,
273  m_convDesc.dilation);
274  if (status != CUDNN_STATUS_SUCCESS) {
276  &m_convDesc,
277  status,
278  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: SetAttribute CUDNN_ATTR_CONVOLUTION_DILATIONS Failed");
279  return std::move(m_convDesc);
280  }
281 
282  status = cudnnBackendSetAttribute(m_convDesc.pointer->get_backend_descriptor(),
283  CUDNN_ATTR_CONVOLUTION_FILTER_STRIDES,
284  CUDNN_TYPE_INT64,
285  m_convDesc.nDims,
286  m_convDesc.stride);
287  if (status != CUDNN_STATUS_SUCCESS) {
289  &m_convDesc,
290  status,
291  "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: SetAttribute CUDNN_ATTR_CONVOLUTION_FILTER_STRIDES Failed");
292  return std::move(m_convDesc);
293  }
294 
295  // Finalizing the descriptor
296  status = cudnnBackendFinalize(m_convDesc.pointer->get_backend_descriptor());
297  if (status != CUDNN_STATUS_SUCCESS) {
299  &m_convDesc, status, "CUDNN_BACKEND_CONVOLUTION_DESCRIPTOR: cudnnFinalize Failed");
300  return std::move(m_convDesc);
301  }
302 
303  return std::move(m_convDesc);
304  }
305 
306  explicit ConvDescBuilder_v8() = default;
307  ~ConvDescBuilder_v8() = default;
309  ConvDescBuilder_v8(ConvDescBuilder_v8 const &) = delete;
311  operator=(ConvDescBuilder_v8 const &) = delete;
312 
313  private:
315 };
316 }
int64_t padUpper[CUDNN_DIM_MAX+1]
n, g, c, d, h, w
static void set_error_and_throw_exception(BackendDescriptor const *desc, cudnnStatus_t status, const char *message)
ManagedOpaqueDescriptor get_desc() const
Returns a copy of underlying managed descriptor.
int64_t dilation[CUDNN_DIM_MAX+1]
n, g, c, 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.
cudnnStatus_t get_status() const
Current status of the descriptor.
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]
n, g, c, d, h, w
ConvDesc_v8 & operator=(ConvDesc_v8 const &)=delete
auto setStrides(int64_t ndims, int64_t const *strides) -> ConvDescBuilder_v8 &
Set Strides of the convDesc.
const char * get_error() const
Diagonistic error message if any.
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.
cudnnConvolutionMode_t mode
Convolution operation data type.
cudnnStatus_t status
Shared pointer of the OpaqueBackendPointer.