CUDNN Frontend API  8.2.0
cudnn_frontend_EngineConfig.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_Engine.h"
36 #include "cudnn_frontend_utils.h"
37 
38 namespace cudnn_frontend {
52  public:
53  friend class EngineConfigBuilder_v8;
54  std::string
55  describe() const override {
56  std::stringstream ss;
57  ss << "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR :";
58  ss << " Number of knobs: " << numKnobs;
59  return ss.str();
60  }
62  : BackendDescriptor(from.get_desc(), from.get_status(), from.get_error()),
63  engine(from.engine),
64  numKnobs(from.numKnobs),
65  opGraphTag(from.opGraphTag) {
66  bChoices = from.bChoices;
67  }
68  ~EngineConfig_v8() = default;
69 
70  std::string const &
71  getTag() const {
72  return opGraphTag;
73  }
74 
75  private:
77  cudnnStatus_t status;
78  for (uint64_t i = 0; i < bChoices.size(); i++) {
79  bChoices[i] = make_shared_backend_pointer(CUDNN_BACKEND_KNOB_CHOICE_DESCRIPTOR);
80  if (bChoices[i]->is_good() == false) {
81  status = bChoices[i]->get_status();
83  this,
84  status,
85  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: CUDNN_BACKEND_KNOB_CHOICE_DESCRIPTOR cudnnCreate Failed");
86  break;
87  }
88  }
89  }
90  EngineConfig_v8(EngineConfig_v8 const &) = delete;
92  operator=(EngineConfig_v8 const &) = delete;
93 
95  int64_t numKnobs = 0;
96  std::string opGraphTag;
97  std::array<ManagedOpaqueDescriptor, CUDNN_KNOB_TYPE_COUNTS> bChoices = {};
98 };
99 
104  public:
109  auto
112  m_engine_config.engine = engine_.get_desc();
113  m_engine_config.opGraphTag = engine_.getTag();
114  auto &knobs = engine_.getFinalizedKnobs();
115  m_engine_config.numKnobs = knobs.size();
116  for (std::uint32_t i = 0; i < knobs.size(); i++) {
117  cudnnStatus_t status;
118  cudnnBackendKnobType_t type = knobs[i].getKnobType();
119  int64_t value = knobs[i].getChoice();
120  status = cudnnBackendSetAttribute(m_engine_config.bChoices[i]->get_backend_descriptor(),
121  CUDNN_ATTR_KNOB_CHOICE_KNOB_TYPE,
122  CUDNN_TYPE_KNOB_TYPE,
123  1,
124  &type);
125  if (status != CUDNN_STATUS_SUCCESS) {
126  set_error_and_throw_exception(&m_engine_config,
127  status,
128  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: "
129  "CUDNN_BACKEND_KNOB_CHOICE_DESCRIPTOR SetAttribute "
130  "CUDNN_ATTR_KNOB_CHOICE_KNOB_TYPE Failed");
131  }
132  status = cudnnBackendSetAttribute(m_engine_config.bChoices[i]->get_backend_descriptor(),
133  CUDNN_ATTR_KNOB_CHOICE_KNOB_VALUE,
134  CUDNN_TYPE_INT64,
135  1,
136  &value);
137  if (status != CUDNN_STATUS_SUCCESS) {
138  set_error_and_throw_exception(&m_engine_config,
139  status,
140  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: "
141  "CUDNN_BACKEND_KNOB_CHOICE_DESCRIPTOR SetAttribute "
142  "CUDNN_ATTR_KNOB_CHOICE_KNOB_VALUE Failed");
143  }
144  status = cudnnBackendFinalize(m_engine_config.bChoices[i]->get_backend_descriptor());
145  if (status != CUDNN_STATUS_SUCCESS) {
147  &m_engine_config,
148  status,
149  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: CUDNN_BACKEND_KNOB_CHOICE_DESCRIPTOR cudnnFinalize Failed");
150  }
151  }
152  return *this;
153  }
156  EngineConfig_v8 &&
159  build() {
160  if (m_engine_config.status != CUDNN_STATUS_SUCCESS) {
161  set_error_and_throw_exception(&m_engine_config,
162  m_engine_config.status,
163  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: is not created properly");
164  return std::move(m_engine_config);
165  }
166  if (m_engine_config.engine == nullptr) {
168  &m_engine_config,
169  CUDNN_STATUS_BAD_PARAM,
170  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: Check and Set the CUDNN_ATTR_ENGINECFG_ENGINE.");
171  return std::move(m_engine_config);
172  }
173  // Create a descriptor. Memory allocation happens here.
174  auto status = m_engine_config.initialize_managed_backend_pointer(CUDNN_BACKEND_ENGINECFG_DESCRIPTOR);
175  if (status != CUDNN_STATUS_SUCCESS) {
177  &m_engine_config, status, "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: cudnnCreate Failed");
178  return std::move(m_engine_config);
179  }
180 
181  status = cudnnBackendSetAttribute(m_engine_config.pointer->get_backend_descriptor(),
182  CUDNN_ATTR_ENGINECFG_ENGINE,
183  CUDNN_TYPE_BACKEND_DESCRIPTOR,
184  1,
185  &(m_engine_config.engine->get_backend_descriptor()));
186  if (status != CUDNN_STATUS_SUCCESS) {
188  &m_engine_config,
189  status,
190  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: SetAttribute CUDNN_ATTR_ENGINECFG_ENGINE Failed");
191  return std::move(m_engine_config);
192  }
193 
194  if (m_engine_config.numKnobs > 0) {
195  std::array<cudnnBackendDescriptor_t, CUDNN_KNOB_TYPE_COUNTS> bChoices_;
196  for (auto i = 0; i < m_engine_config.numKnobs; i++) {
197  bChoices_[i] = m_engine_config.bChoices[i]->get_backend_descriptor();
198  }
199  status = cudnnBackendSetAttribute(m_engine_config.pointer->get_backend_descriptor(),
200  CUDNN_ATTR_ENGINECFG_KNOB_CHOICES,
201  CUDNN_TYPE_BACKEND_DESCRIPTOR,
202  m_engine_config.numKnobs,
203  bChoices_.data());
204  if (status != CUDNN_STATUS_SUCCESS) {
206  &m_engine_config,
207  status,
208  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: SetAttribute CUDNN_ATTR_ENGINECFG_KNOB_CHOICES Failed");
209  return std::move(m_engine_config);
210  }
211  }
212 
213  // Finalizing the descriptor
214  status = cudnnBackendFinalize(m_engine_config.pointer->get_backend_descriptor());
215  if (status != CUDNN_STATUS_SUCCESS) {
217  &m_engine_config, status, "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: cudnnFinalize Failed");
218  return std::move(m_engine_config);
219  }
220  return std::move(m_engine_config);
221  }
222 
223  explicit EngineConfigBuilder_v8() = default;
224  ~EngineConfigBuilder_v8() = default;
228  operator=(EngineConfigBuilder_v8 const &) = delete;
229 
230  private:
232 };
233 
241 
242 using EngineConfigList = std::vector<ManagedOpaqueDescriptor>;
243 }
static void set_error_and_throw_exception(BackendDescriptor const *desc, cudnnStatus_t status, const char *message)
static ManagedOpaqueDescriptor make_shared_backend_pointer(cudnnBackendDescriptorType_t type)
std::string describe() const override
Return a string describing the backend Descriptor.
ManagedOpaqueDescriptor get_desc() const
Returns a copy of underlying managed descriptor.
auto setEngine(Engine_v8 const &engine_) -> EngineConfigBuilder_v8 &
Set engine for the EngineConfig_v8.
cudnnStatus_t get_status() const
Current status of the descriptor.
std::shared_ptr< OpaqueBackendPointer > ManagedOpaqueDescriptor
const char * get_error() const
Diagonistic error message if any.
std::vector< ManagedOpaqueDescriptor > EngineConfigList
std::array< ManagedOpaqueDescriptor, CUDNN_KNOB_TYPE_COUNTS > bChoices
Opaque pointer to the backend knobs.
cudnnStatus_t status
Shared pointer of the OpaqueBackendPointer.
EngineConfig_v8 & operator=(EngineConfig_v8 const &)=delete