1 #include <ATen/cudnn/Handle.h> 3 #include <ATen/cuda/Exceptions.h> 5 #include <unordered_map> 10 namespace at {
namespace native {
16 Handle(
bool create =
false) : handle(nullptr)
19 AT_CUDNN_CHECK(cudnnCreate(&handle));
30 Handle(
const Handle& rhs) =
delete;
32 Handle(Handle&& rhs) : Handle() { std::swap(handle, rhs.handle); }
34 Handle& operator=(Handle rhs) { std::swap(handle, rhs.handle);
return *
this; }
44 #ifdef NO_CUDNN_DESTROY_HANDLE 74 std::unordered_map<int, std::vector<Handle>> created_handles;
75 std::unordered_map<int, std::vector<cudnnHandle_t>> available_handles;
83 ~PoolWindow(){ release(); }
85 cudnnHandle_t reserve(
int device)
88 if(my_handles.find(device) != my_handles.end())
89 return my_handles[device];
93 std::lock_guard<std::mutex> guard(mutex);
95 if(available_handles[device].size() > 0)
97 my_handles[device] = available_handles[device].back();
98 available_handles[device].pop_back();
104 created_handles[device].emplace_back(
true );
105 my_handles[device] = created_handles[device].back().handle;
108 return my_handles[device];
113 std::unordered_map<int, cudnnHandle_t> my_handles;
128 if(my_handles.size() > 0)
130 std::lock_guard<std::mutex> guard(mutex);
131 for(
auto d_h : my_handles)
132 available_handles[d_h.first].push_back(d_h.second);
139 thread_local PoolWindow myPoolWindow;
143 cudnnHandle_t getCudnnHandle()
146 AT_CUDA_CHECK(cudaGetDevice(&device));
148 return myPoolWindow.reserve(device);
Flush-To-Zero and Denormals-Are-Zero mode.