8#include <cudnn_frontend.h>
28inline const auto check_status = [](
auto status,
const string& what) {
30 "cudnn-frontend {}: {}", what, status.get_message());
40 struct QueriedCapability
44 static int component_of(
const int device_ordinal,
const cudaDeviceAttr attribute)
47 cudaDeviceGetAttribute(&component, attribute, device_ordinal);
53 int device_ordinal = 0;
54 cudaGetDevice(&device_ordinal);
56 const int major = component_of(device_ordinal, cudaDevAttrComputeCapabilityMajor);
57 const int minor = component_of(device_ordinal, cudaDevAttrComputeCapabilityMinor);
59 encoded = major * 100 + minor * 10;
63 static const QueriedCapability capability;
64 return capability.encoded;
74 static const bool verbose =
env_flag_enabled(
"OPENNN_CUDNN_FRONTEND_VERBOSE");
106 static const bool enabled =
env_flag_enabled(
"OPENNN_CONV_ENERGY_AUTOTUNE",
true);
112 static const float tolerance =
113 float(std::clamp(
env_int_or(
"OPENNN_CONV_ENERGY_TOLERANCE", 10), 0LL, 100LL)) / 100.0f;
119 static const int64_t window = std::clamp(
env_int_or(
"OPENNN_CONV_ENERGY_WINDOW_MS", 300), 100LL, 5000LL);
144 static const bool registered = [] {
147 const double total_ms = stats.
total_ms();
149 format(
"total_gpu_ms={:.1f}", total_ms),
159template<
typename TensorMap>
178 float milliseconds = 0;
189template<
typename GraphCache,
typename Body>
192 const lock_guard lock(cache.access_mutex);
193 if (cache.disabled)
return false;
200 catch (
const exception& e)
202 cache.disabled =
true;
205 << e.what() <<
").\n";
213 throw runtime_error(what +
" requires a GPU of compute capability 7.0 or higher.");
216 what +
": no usable cuDNN plan for this shape. The cudnn-frontend message above "
217 "names the cause; under memory pressure it is normally a failed workspace or "
218 "autotune allocation. Reduce the batch size, or cap the convolution workspace "
219 "with device::set_conv_workspace_cap().");
227 if (dtype == DataType_t::BFLOAT16 || dtype == DataType_t::HALF)
return 2;
228 if (dtype == DataType_t::INT8 || dtype == DataType_t::UINT8
229 || dtype == DataType_t::FP8_E4M3 || dtype == DataType_t::FP8_E5M2)
return 1;
243 throw invalid_argument(
"Unsupported data type for a cuDNN graph.");
248 return {h * w * c, 1, w * c, c};
253 auto g = make_shared<graph::Graph>();
254 g->set_io_data_type(
to_dtype(dtype))
255 .set_intermediate_data_type(DataType_t::FLOAT)
256 .set_compute_data_type(DataType_t::FLOAT);
260inline shared_ptr<graph::Tensor_attributes>
262 int64_t n, int64_t c, int64_t h, int64_t w)
264 return graph.tensor(graph::Tensor_attributes()
266 .set_dim({n, c, h, w})
271 int64_t n, int64_t c, int64_t h, int64_t w)
273 tensor->set_output(
true)
274 .set_dim({n, c, h, w})
278using VariantPack = unordered_map<shared_ptr<graph::Tensor_attributes>,
void*>;
280inline vector<int64_t>
bhsd_strides(int64_t h, int64_t s, int64_t d,
bool interleaved)
282 return interleaved ? vector<int64_t>{s * h * d, d, h * d, 1}
283 : vector<int64_t>{h * s * d, s * d, d, 1};
286inline shared_ptr<graph::Tensor_attributes>
288 int64_t b, int64_t h, int64_t s, int64_t d,
bool interleaved)
290 return graph.tensor(graph::Tensor_attributes()
292 .set_dim ({b, h, s, d})
297 int64_t b, int64_t h, int64_t s, int64_t d,
bool interleaved)
299 tensor->set_output(
true)
300 .set_dim ({b, h, s, d})
304inline shared_ptr<graph::Tensor_attributes>
307 return graph.tensor(graph::Tensor_attributes()
309 .set_data_type(DataType_t::FLOAT)
310 .set_dim({1, channels, 1, 1})
316 tensor->set_output(
true)
317 .set_data_type(DataType_t::FLOAT)
318 .set_dim({1, channels, 1, 1})
322template <
typename... Args>
326 return format(fmt, std::forward<Args>(args)...);
329inline shared_ptr<graph::Tensor_attributes>
331 bool pass_by_value =
false, int64_t batch = 1)
333 return graph.tensor(graph::Tensor_attributes()
335 .set_dim ({batch, 1, 1, 1})
336 .set_stride({1, 1, 1, 1})
337 .set_data_type(dtype)
338 .set_is_pass_by_value(pass_by_value));
343 return value <= 0 ? numeric_limits<int64_t>::max() : int64_t(value);
354 static const auto per_kind = []
356 map<string, int64_t> limits;
357 for (
const char* kind : {
"forward",
"wgrad",
"dgrad"})
359 string name =
"OPENNN_AUTOTUNE_CANDIDATES_" + string(kind);
360 for (
char& c : name) c = char(toupper(c));
361 if (
const char* setting = getenv(name.c_str()); setting && *setting)
367 const auto found = per_kind.find(tag);
373 static const vector<HeurMode_t> modes = []
375 const char* setting = getenv(
"OPENNN_CUDNN_HEURISTICS");
376 const string value = setting ? setting :
"A";
377 if (value ==
"B")
return vector<HeurMode_t>{HeurMode_t::B, HeurMode_t::FALLBACK};
378 if (value ==
"AB")
return vector<HeurMode_t>{HeurMode_t::A, HeurMode_t::B, HeurMode_t::FALLBACK};
379 return vector<HeurMode_t>{HeurMode_t::A, HeurMode_t::FALLBACK};
386 static const vector<NumericalNote_t> notes = []
388 vector<NumericalNote_t> selected;
389 const char* setting = getenv(
"OPENNN_CONV_ENGINE_NOTES");
390 const string value = setting ? setting :
"";
391 if (value.find(
"WINOGRAD") != string::npos) selected.push_back(NumericalNote_t::WINOGRAD);
392 if (value.find(
"FFT") != string::npos) selected.push_back(NumericalNote_t::FFT);
400 const int64_t count = graph.get_execution_plan_count();
403 for (int64_t index = 0; index < count && built < limit; ++index)
404 if (graph.build_plan_at_index(index).is_good()) ++built;
411 static const bool enabled =
env_flag_enabled(
"OPENNN_CUDNN_PLAN_CACHE",
true);
420 static const std::filesystem::path directory = []
422 const char* override_path = getenv(
"OPENNN_CUDNN_PLAN_CACHE_DIR");
424 std::filesystem::path root;
426 if (override_path && *override_path)
427 root = std::filesystem::path(override_path);
430 std::error_code error;
431 const std::filesystem::path temporary = std::filesystem::temp_directory_path(error);
432 if (error)
return std::filesystem::path{};
433 root = temporary /
"opennn-cudnn-plans";
454 graph.serialize(structure);
456 catch (
const std::exception&)
458 static std::once_flag reported;
459 std::call_once(reported, []{
460 logging::warning() <<
"cudnn plan cache: this cuDNN build cannot serialise "
461 "execution plans; continuing without the cache.\n"; });
464 structure.erase(
"gid");
467 for (
const char* kind : {
"forward",
"wgrad",
"dgrad"})
469 for (
const HeurMode_t mode :
heuristic_modes()) selection = selection * 31 + size_t(mode) + 1;
470 for (
const NumericalNote_t note :
conv_engine_notes()) selection = selection * 31 + size_t(note) + 7;
486 const size_t key = std::hash<json>{}(structure)
489 ^ (std::hash<size_t>{}(selection) << 3)
500 int64_t& workspace_bytes)
504 std::error_code failed;
506 if (file.empty())
return false;
507 if (!std::filesystem::exists(file, failed) || failed)
return false;
509 std::ifstream stream(file, std::ios::binary);
510 if (!stream)
return false;
512 const vector<uint8_t> blob((std::istreambuf_iterator<char>(stream)),
513 std::istreambuf_iterator<char>());
514 if (blob.empty())
return false;
516 constexpr bool enforce_precompiled =
false;
517 constexpr bool run_warmup =
false;
519 if (graph.deserialize(handle, blob, enforce_precompiled, run_warmup).is_bad())
return false;
521 return graph.get_workspace_size(workspace_bytes).is_good();
528 vector<uint8_t> blob;
536 if (graph.serialize(blob,
false).is_bad() || blob.empty())
return;
538 catch (
const std::exception&)
543 std::error_code failed;
547 static atomic<uint64_t> sequence{0};
550 if (file.empty())
return;
551 const std::filesystem::path pending = file.string()
552 + format(
".{:x}-{}.tmp", std::hash<thread::id>{}(this_thread::get_id()), sequence++);
555 std::ofstream stream(pending, std::ios::binary | std::ios::trunc);
557 stream.write(
reinterpret_cast<const char*
>(blob.data()), std::streamsize(blob.size()));
558 if (!stream) { std::filesystem::remove(pending, failed);
return; }
561 std::filesystem::rename(pending, file, failed);
562 if (failed) std::filesystem::remove(pending, failed);
568 const int64_t count = graph.get_execution_plan_count();
570 for (int64_t index = 0; index < count; ++index)
573 if (graph.get_workspace_size_plan_at_index(index, bytes).is_good())
599 static const int64_t bytes = []
601 const long long megabytes =
env_int_or(
"OPENNN_SDPA_WORKSPACE_MB", -1);
602 return megabytes < 0 ? int64_t(-1) : int64_t(megabytes) * 1024 * 1024;
624 int64_t q_seq, int64_t src_seq, int64_t head_dim)
627 return override_bytes;
629 const int64_t operands = 4 * batch * heads * head_dim * (q_seq + 2 * src_seq);
630 const int64_t statistics = 4 * batch * heads * q_seq;
636 return max(operands + statistics, int64_t(4) * 1024 * 1024);
640 bool allow_autotune =
false, int64_t workspace_cap = 0)
648 check_status(graph.build_operation_graph(handle), tag +
" build_operation_graph");
652 check_status(graph.create_execution_plans({HeurMode_t::A, HeurMode_t::B, HeurMode_t::FALLBACK}),
653 tag +
" create_execution_plans");
655 if (workspace_cap > 0)
656 graph.deselect_workspace_greater_than(workspace_cap);
667 check_status(graph.get_workspace_size(workspace_bytes), tag +
" workspace");
674 graph.deselect_workspace_greater_than(numeric_limits<int64_t>::max());
677 check_status(graph.create_execution_plans({HeurMode_t::A}), tag +
" create_execution_plans");
678 check_status(graph.build_plans(handle, BuildPlanPolicy_t::HEURISTICS_CHOICE), tag +
" build_plans");
679 check_status(graph.get_workspace_size(workspace_bytes), tag +
" workspace");
685inline shared_ptr<graph::Tensor_attributes>
688 return scalar_tensor(graph, name, DataType_t::INT32,
false, batch);
694inline bool finalize(graph::Graph& graph, int64_t& workspace_bytes,
const string& tag,
695 const bool fp32_graph =
false)
707 check_status(graph.build_operation_graph(handle), tag +
" build_operation_graph");
710 const bool convolution_graph = tag ==
"forward" || tag ==
"wgrad" || tag ==
"dgrad";
711 const auto prepare_candidates = [&](
bool restrict_notes)
714 if (conv_workspace_cap > 0)
715 graph.deselect_workspace_greater_than(conv_workspace_cap);
721 graph.deselect_numeric_notes({NumericalNote_t::TENSOR_CORE,
722 NumericalNote_t::DOWN_CONVERT_INPUTS,
723 NumericalNote_t::REDUCED_PRECISION_REDUCTION});
725 graph.deselect_numeric_notes({NumericalNote_t::NONDETERMINISTIC});
730 const auto build_candidates = [&]() ->
bool
732 if (request_autotune)
734 return graph.build_plans(handle, BuildPlanPolicy_t::HEURISTICS_CHOICE).is_good();
738 prepare_candidates(restricted);
739 bool built = build_candidates();
740 if (!built && restricted)
743 prepare_candidates(
false);
744 built = build_candidates();
747 check_status(graph.build_plans(handle, BuildPlanPolicy_t::HEURISTICS_CHOICE), tag +
" build_plans");
749 if (request_autotune && built)
return true;
751 check_status(graph.get_workspace_size(workspace_bytes), tag +
" get_workspace_size");
762 <<
": autotune skipped, keeping the heuristic plan (" << reason <<
").\n";
770 return tag && std::string_view(tag).find(
"ConvolutionOperator") != std::string_view::npos;
779template<
typename TensorMap>
782 const int64_t count = graph.get_execution_plan_count();
783 if (count < 2)
return;
786 cudaStream_t stream =
nullptr;
787 cudnnGetStream(handle, &stream);
788 cudaEvent_t start =
nullptr, stop =
nullptr;
789 if (cudaEventCreate(&start) != cudaSuccess || cudaEventCreate(&stop) != cudaSuccess)
return;
791 struct Reading { int64_t index;
float microseconds;
double millijoules; };
792 vector<Reading> timed;
796 for (int64_t index = 0; index < count; ++index)
798 if (graph.execute_plan_at_index(handle, tensors, workspace, index).is_bad())
continue;
799 float samples[5] = {};
801 for (
float& sample : samples)
803 cudaEventRecord(start, stream);
804 ok = graph.execute_plan_at_index(handle, tensors, workspace, index).is_good();
805 cudaEventRecord(stop, stream);
806 cudaEventSynchronize(stop);
808 float milliseconds = 0.0f;
809 cudaEventElapsedTime(&milliseconds, start, stop);
810 sample = milliseconds * 1000.0f;
813 std::sort(samples, samples + 5);
814 timed.push_back({index, samples[2], 0.0});
818 const auto fastest = std::min_element(timed.begin(), timed.end(),
819 [](
const Reading& a,
const Reading& b) { return a.microseconds < b.microseconds; });
829 vector<Reading*> admissible;
830 for (Reading& reading : timed)
831 if (reading.microseconds <= budget) admissible.push_back(&reading);
834 for (Reading* reading : admissible)
837 /
double(std::max(reading->microseconds, 1.0f))));
838 (void)graph.execute_plan_at_index(handle, tensors, workspace, reading->index);
839 cudaStreamSynchronize(stream);
841 cudaEventRecord(start, stream);
842 for (int64_t run = 0; run < runs; ++run)
843 (
void)graph.execute_plan_at_index(handle, tensors, workspace, reading->index);
844 cudaEventRecord(stop, stream);
845 cudaEventSynchronize(stop);
846 float milliseconds = 0.0f;
847 cudaEventElapsedTime(&milliseconds, start, stop);
850 reading->millijoules = samples >= 5 && watts > 0.0
851 ? watts * double(milliseconds) / double(runs)
855 reading->microseconds = milliseconds * 1000.0f / float(runs);
857 cudaEventDestroy(start);
858 cudaEventDestroy(stop);
861 Reading* baseline =
nullptr;
862 for (Reading* reading : admissible)
863 if (reading->millijoules > 0.0 && (!baseline || reading->microseconds < baseline->microseconds))
865 if (!baseline)
return;
867 Reading* chosen = baseline;
868 for (Reading* reading : admissible)
869 if (reading->millijoules > 0.0 && reading->millijoules < chosen->millijoules * 0.98
875 string chosen_name, fastest_name;
876 (void)graph.get_plan_name_at_index(chosen->index, chosen_name);
877 (void)graph.get_plan_name_at_index(baseline->index, fastest_name);
879 message << (tag ? tag :
"conv") <<
": energy autotune over " << admissible.size() <<
" of "
880 << timed.size() <<
" plans: "
881 << (chosen == baseline ?
"kept the fastest " :
"chose ") << chosen_name
882 <<
" (" << chosen->microseconds <<
" us, " << chosen->millijoules <<
" mJ)";
883 if (chosen != baseline)
884 message <<
" over " << fastest_name <<
" (" << baseline->microseconds <<
" us, "
885 << baseline->millijoules <<
" mJ)";
889 if (chosen != baseline)
891 const auto selected = graph.build_plan_at_index(handle, chosen->index);
896template<
typename TensorMap>
898 TensorMap& tensors, int64_t& workspace_bytes,
899 const char* tag =
nullptr)
901 if (!pending)
return;
909 if (tune_bytes > 0) tune_workspace.resize_bytes(Index(tune_bytes),
Device::CUDA);
917 catch (
const exception& e)
928 workspace_bytes = graph.get_workspace_size();
931template<
typename TensorMap>
933 const TensorMap& tensors, int64_t& workspace_bytes,
934 const char* tag =
nullptr)
936 if (!pending)
return;
939 TensorMap scratch = tensors;
940 vector<Buffer> buffers;
941 buffers.reserve(scratch.size());
945 for (
auto& [tensor, pointer] : scratch)
947 if (tensor->get_is_pass_by_value())
continue;
949 int64_t elements = 1;
950 for (
const int64_t dimension : tensor->get_dim()) elements *= dimension;
955 pointer = buffer.
data();
958 catch (
const exception& e)
964 workspace_bytes = graph.get_workspace_size();
968 autotune_now(pending, graph, scratch, workspace_bytes, tag);
977 explicit operator bool() const noexcept {
return graph !=
nullptr; }
980 void build(shared_ptr<graph::Graph> built,
const string& tag,
const bool fp32_graph =
false)
984 graph = std::move(built);
996 bool allow_autotune =
true, int64_t workspace_cap = 0)
1002 allow_autotune, workspace_cap);
1003 graph = std::move(built);
1007template<
typename TensorMap>
1011 if (scratch_autotune)
Definition device_backend.h:298
DeviceEvent get() const noexcept
Definition device_backend.h:314
void log(const string &title, double total_ms=0.0, string_view category="PROFILE") const
Definition profiler.h:88
void add(const string &key, double ms, double bytes=0.0)
Definition profiler.h:47
double total_ms() const
Definition profiler.h:70
Definition cudnn_frontend_utilities.h:23
shared_ptr< graph::Tensor_attributes > seq_len_scalar(graph::Graph &graph, const char *name, int64_t batch=1)
Definition cudnn_frontend_utilities.h:686
void select_plan_by_energy(graph::Graph &graph, TensorMap &tensors, void *workspace, const char *tag)
Definition cudnn_frontend_utilities.h:780
vector< int64_t > bhsd_strides(int64_t h, int64_t s, int64_t d, bool interleaved)
Definition cudnn_frontend_utilities.h:280
void run_slot(GraphSlot &slot, TensorMap &tensors, const char *what, const string &timing_label, bool scratch_autotune)
Definition cudnn_frontend_utilities.h:1008
bool deterministic_algorithms_enabled()
Definition cudnn_frontend_utilities.h:86
shared_ptr< graph::Graph > new_graph(Type dtype=Type::FP32)
Definition cudnn_frontend_utilities.h:251
int64_t candidate_limit_from(long long value)
Definition cudnn_frontend_utilities.h:341
void set_per_channel_output(shared_ptr< graph::Tensor_attributes > &tensor, int64_t channels)
Definition cudnn_frontend_utilities.h:314
bool conv_energy_verbose()
Definition cudnn_frontend_utilities.h:123
void autotune_with_scratch(bool &pending, graph::Graph &graph, const TensorMap &tensors, int64_t &workspace_bytes, const char *tag=nullptr)
Definition cudnn_frontend_utilities.h:932
shared_ptr< graph::Tensor_attributes > bhsd_tensor(graph::Graph &graph, const char *name, int64_t b, int64_t h, int64_t s, int64_t d, bool interleaved)
Definition cudnn_frontend_utilities.h:287
const auto check_status
Definition cudnn_frontend_utilities.h:28
bool plan_cache_enabled()
Definition cudnn_frontend_utilities.h:409
const std::filesystem::path & plan_cache_directory()
Definition cudnn_frontend_utilities.h:418
int64_t conv_energy_window_ms()
Definition cudnn_frontend_utilities.h:117
int64_t autotune_candidate_limit()
Definition cudnn_frontend_utilities.h:346
bool build_top_candidates(graph::Graph &graph, int64_t limit)
Definition cudnn_frontend_utilities.h:398
int64_t sdpa_workspace_cap_override_bytes()
Definition cudnn_frontend_utilities.h:597
void report_autotune_skipped(const char *tag, const char *reason)
Definition cudnn_frontend_utilities.h:758
bool conv_energy_autotune_enabled()
Definition cudnn_frontend_utilities.h:104
bool finalize(graph::Graph &graph, int64_t &workspace_bytes, const string &tag, const bool fp32_graph=false)
Definition cudnn_frontend_utilities.h:694
bool load_cached_plan(graph::Graph &graph, const cudnnHandle_t handle, int64_t &workspace_bytes)
Definition cudnn_frontend_utilities.h:499
void set_nhwc_output(shared_ptr< graph::Tensor_attributes > &tensor, int64_t n, int64_t c, int64_t h, int64_t w)
Definition cudnn_frontend_utilities.h:270
vector< HeurMode_t > heuristic_modes()
Definition cudnn_frontend_utilities.h:371
bool conv_energy_stage_active()
Definition cudnn_frontend_utilities.h:129
const vector< NumericalNote_t > & conv_engine_notes()
Definition cudnn_frontend_utilities.h:384
int64_t element_bytes(DataType_t dtype)
Definition cudnn_frontend_utilities.h:225
shared_ptr< graph::Tensor_attributes > nhwc_tensor(graph::Graph &graph, const char *name, int64_t n, int64_t c, int64_t h, int64_t w)
Definition cudnn_frontend_utilities.h:261
void autotune_now(bool &pending, graph::Graph &graph, TensorMap &tensors, int64_t &workspace_bytes, const char *tag=nullptr)
Definition cudnn_frontend_utilities.h:897
bool bn_frontend_enabled()
Definition cudnn_frontend_utilities.h:78
shared_ptr< graph::Tensor_attributes > per_channel_tensor(graph::Graph &graph, const char *name, int64_t channels)
Definition cudnn_frontend_utilities.h:305
void store_cached_plan(graph::Graph &graph)
Definition cudnn_frontend_utilities.h:524
string timing_label(format_string< Args... > fmt, Args &&... args)
Definition cudnn_frontend_utilities.h:323
void throw_frontend_unavailable(const string &what)
Definition cudnn_frontend_utilities.h:210
int64_t autotune_workspace_bytes(const graph::Graph &graph)
Definition cudnn_frontend_utilities.h:565
std::filesystem::path plan_cache_file(const graph::Graph &graph)
Definition cudnn_frontend_utilities.h:442
profiler::Stats & graph_timing_stats()
Definition cudnn_frontend_utilities.h:141
void execute_graph(graph::Graph &graph, TensorMap &tensors, void *workspace, const string &what, const string &timing_label)
Definition cudnn_frontend_utilities.h:160
bool run_frontend(GraphCache &cache, const char *label, Body &&body)
Definition cudnn_frontend_utilities.h:190
bool frontend_enabled()
Definition cudnn_frontend_utilities.h:67
vector< int64_t > nhwc_strides(int64_t c, int64_t h, int64_t w)
Definition cudnn_frontend_utilities.h:246
bool frontend_verbose()
Definition cudnn_frontend_utilities.h:72
DataType_t to_dtype(Type t)
Definition cudnn_frontend_utilities.h:233
shared_ptr< graph::Tensor_attributes > scalar_tensor(graph::Graph &graph, const char *name, DataType_t dtype, bool pass_by_value=false, int64_t batch=1)
Definition cudnn_frontend_utilities.h:330
unordered_map< shared_ptr< graph::Tensor_attributes >, void * > VariantPack
Definition cudnn_frontend_utilities.h:278
bool graph_timing_enabled()
Definition cudnn_frontend_utilities.h:135
float conv_energy_tolerance()
Definition cudnn_frontend_utilities.h:110
void set_bhsd_output(shared_ptr< graph::Tensor_attributes > &tensor, int64_t b, int64_t h, int64_t s, int64_t d, bool interleaved)
Definition cudnn_frontend_utilities.h:296
int device_sm_version()
Definition cudnn_frontend_utilities.h:33
bool finalize_attention(graph::Graph &graph, const string &tag, int64_t &workspace_bytes, bool allow_autotune=false, int64_t workspace_cap=0)
Definition cudnn_frontend_utilities.h:639
bool is_convolution_tag(const char *tag)
Definition cudnn_frontend_utilities.h:768
bool sdpa_autotune_enabled()
Definition cudnn_frontend_utilities.h:586
void * shared_workspace(int64_t bytes)
Definition cudnn_frontend_utilities.h:184
constexpr size_t graph_cache_capacity
Definition cudnn_frontend_utilities.h:26
int64_t sdpa_workspace_cap_bytes(int64_t batch, int64_t heads, int64_t q_seq, int64_t src_seq, int64_t head_dim)
Definition cudnn_frontend_utilities.h:623
bool conv_autotune_enabled() noexcept
void synchronize_event(DeviceEvent)
bool energy_meter_available() noexcept
bool allow_tf32() noexcept
DnnHandle get_cudnn_handle()
DeviceStream get_compute_stream()
void record_event(DeviceEvent, DeviceStream)
unsigned long long energy_meter_begin() noexcept
double energy_meter_window_watts(unsigned long long begin, int &samples) noexcept
void reset_last_error() noexcept
int64_t conv_workspace_limit_bytes() noexcept
int lanes_available() noexcept
void synchronize(DeviceStream=nullptr)
Line info()
Definition log.h:77
Line warning()
Definition log.h:76
float maximum(const MatrixR &)
void * ensure_shared_scratch(size_t bytes)
Definition device_backend.h:382
@ CUDA
Definition configuration.h:12
bool env_flag_enabled(const char *) noexcept
Type
Definition configuration.h:13
@ Auto
Definition configuration.h:13
@ FP32
Definition configuration.h:13
@ INT8
Definition configuration.h:13
@ BF16
Definition configuration.h:13
long long env_int_or(const char *, long long default_value) noexcept
#define throw_if(condition,...)
Definition opennn_types.h:243
#define CHECK_CUDA(x)
Definition opennn_types.h:85
#define PROFILE_SCOPE_HOST(name)
Definition profiler.h:289
Definition tensor_types.h:340
void resize_bytes(Index byte_count, Device new_device)
Definition tensor_types.h:410
void * data() const noexcept
Definition tensor_types.h:383
Definition cudnn_frontend_utilities.h:972
bool autotune_pending
Definition cudnn_frontend_utilities.h:975
void build_attention(shared_ptr< graph::Graph > built, const string &tag, bool allow_autotune=true, int64_t workspace_cap=0)
Definition cudnn_frontend_utilities.h:995
void build(shared_ptr< graph::Graph > built, const string &tag, const bool fp32_graph=false)
Definition cudnn_frontend_utilities.h:980
int64_t workspace_bytes
Definition cudnn_frontend_utilities.h:974
shared_ptr< graph::Graph > graph
Definition cudnn_frontend_utilities.h:973
graph::Graph & operator*() const noexcept
Definition cudnn_frontend_utilities.h:978