CUDNN Frontend API  8.3.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 
55  std::string
56  describe() const override {
57  std::stringstream ss;
58  ss << "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR :";
59  ss << " Number of knobs: " << numKnobs;
60  return ss.str();
61  }
62 
64  operator=(EngineConfig_v8 &&from) = default;
65 
66  EngineConfig_v8(EngineConfig_v8 &&from) = default;
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  bool set_knobs_attr = false;
98  std::array<ManagedOpaqueDescriptor, CUDNN_KNOB_TYPE_COUNTS> bChoices = {};
99 };
100 
105  public:
110  auto
113  m_engine_config.engine = engine_.get_desc();
114  m_engine_config.opGraphTag = engine_.getTag();
115  auto &knobs = engine_.getFinalizedKnobs();
116  m_engine_config.numKnobs = knobs.size();
117 
118  m_engine_config.set_knobs_attr = engine_.knobs_set();
119 
120  for (std::uint32_t i = 0; i < knobs.size(); i++) {
121  cudnnStatus_t status;
122  cudnnBackendKnobType_t type = knobs[i].getKnobType();
123  int64_t value = knobs[i].getChoice();
124  status = cudnnBackendSetAttribute(m_engine_config.bChoices[i]->get_backend_descriptor(),
125  CUDNN_ATTR_KNOB_CHOICE_KNOB_TYPE,
126  CUDNN_TYPE_KNOB_TYPE,
127  1,
128  &type);
129  if (status != CUDNN_STATUS_SUCCESS) {
130  set_error_and_throw_exception(&m_engine_config,
131  status,
132  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: "
133  "CUDNN_BACKEND_KNOB_CHOICE_DESCRIPTOR SetAttribute "
134  "CUDNN_ATTR_KNOB_CHOICE_KNOB_TYPE Failed");
135  }
136  status = cudnnBackendSetAttribute(m_engine_config.bChoices[i]->get_backend_descriptor(),
137  CUDNN_ATTR_KNOB_CHOICE_KNOB_VALUE,
138  CUDNN_TYPE_INT64,
139  1,
140  &value);
141  if (status != CUDNN_STATUS_SUCCESS) {
142  set_error_and_throw_exception(&m_engine_config,
143  status,
144  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: "
145  "CUDNN_BACKEND_KNOB_CHOICE_DESCRIPTOR SetAttribute "
146  "CUDNN_ATTR_KNOB_CHOICE_KNOB_VALUE Failed");
147  }
148  status = cudnnBackendFinalize(m_engine_config.bChoices[i]->get_backend_descriptor());
149  if (status != CUDNN_STATUS_SUCCESS) {
151  &m_engine_config,
152  status,
153  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: CUDNN_BACKEND_KNOB_CHOICE_DESCRIPTOR cudnnFinalize Failed");
154  }
155  }
156 
157  return *this;
158  }
161  EngineConfig_v8 &&
164  build() {
165  if (m_engine_config.status != CUDNN_STATUS_SUCCESS) {
166  set_error_and_throw_exception(&m_engine_config,
167  m_engine_config.status,
168  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: is not created properly");
169  return std::move(m_engine_config);
170  }
171  if (m_engine_config.engine == nullptr) {
173  &m_engine_config,
174  CUDNN_STATUS_BAD_PARAM,
175  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: Check and Set the CUDNN_ATTR_ENGINECFG_ENGINE.");
176  return std::move(m_engine_config);
177  }
178  // Create a descriptor. Memory allocation happens here.
179  auto status = m_engine_config.initialize_managed_backend_pointer(CUDNN_BACKEND_ENGINECFG_DESCRIPTOR);
180  if (status != CUDNN_STATUS_SUCCESS) {
182  &m_engine_config, status, "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: cudnnCreate Failed");
183  return std::move(m_engine_config);
184  }
185 
186  status = cudnnBackendSetAttribute(m_engine_config.pointer->get_backend_descriptor(),
187  CUDNN_ATTR_ENGINECFG_ENGINE,
188  CUDNN_TYPE_BACKEND_DESCRIPTOR,
189  1,
190  &(m_engine_config.engine->get_backend_descriptor()));
191  if (status != CUDNN_STATUS_SUCCESS) {
193  &m_engine_config,
194  status,
195  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: SetAttribute CUDNN_ATTR_ENGINECFG_ENGINE Failed");
196  return std::move(m_engine_config);
197  }
198 
199  if (m_engine_config.set_knobs_attr && m_engine_config.numKnobs > 0) {
200  std::array<cudnnBackendDescriptor_t, CUDNN_KNOB_TYPE_COUNTS> bChoices_;
201  for (auto i = 0; i < m_engine_config.numKnobs; i++) {
202  bChoices_[i] = m_engine_config.bChoices[i]->get_backend_descriptor();
203  }
204  status = cudnnBackendSetAttribute(m_engine_config.pointer->get_backend_descriptor(),
205  CUDNN_ATTR_ENGINECFG_KNOB_CHOICES,
206  CUDNN_TYPE_BACKEND_DESCRIPTOR,
207  m_engine_config.numKnobs,
208  bChoices_.data());
209  if (status != CUDNN_STATUS_SUCCESS) {
211  &m_engine_config,
212  status,
213  "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: SetAttribute CUDNN_ATTR_ENGINECFG_KNOB_CHOICES Failed");
214  return std::move(m_engine_config);
215  }
216  }
217 
218  // Finalizing the descriptor
219  status = cudnnBackendFinalize(m_engine_config.pointer->get_backend_descriptor());
220  if (status != CUDNN_STATUS_SUCCESS) {
222  &m_engine_config, status, "CUDNN_BACKEND_ENGINECFG_DESCRIPTOR: cudnnFinalize Failed");
223  return std::move(m_engine_config);
224  }
225  getLogger() << "[cudnn_frontend] " << m_engine_config << std::endl;
226  return std::move(m_engine_config);
227  }
228 
229  explicit EngineConfigBuilder_v8() = default;
230  ~EngineConfigBuilder_v8() = default;
234  operator=(EngineConfigBuilder_v8 const &) = delete;
235 
236  private:
238 };
239 
247 
248 using EngineConfigList = std::vector<ManagedOpaqueDescriptor>;
249 }
ConditionalStreamer & getLogger()
static void set_error_and_throw_exception(BackendDescriptor const *desc, cudnnStatus_t status, const char *message)
EngineConfig_v8 & operator=(EngineConfig_v8 &&from)=default
static ManagedOpaqueDescriptor make_shared_backend_pointer(cudnnBackendDescriptorType_t type)
std::string describe() const override
Return a string describing the backend Descriptor.
auto setEngine(Engine_v8 const &engine_) -> EngineConfigBuilder_v8 &
Set engine for the EngineConfig_v8.
std::shared_ptr< OpaqueBackendPointer > ManagedOpaqueDescriptor
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.