19 # include <cuda_runtime.h>
23 #include <boost/fiber/condition_variable.hpp>
24 #include <boost/fiber/mutex.hpp>
33 using namespace std::chrono_literals;
35 const std::string DEVARREXC =
"CUDADeviceArrayException";
37 const char* errname = cudaGetErrorName( err );
38 const char* errstr = cudaGetErrorString( err );
40 std::format(
"Encountered CUDA error {} [{}]: {} on {}:{}", errname,
int( err ), errstr, file,
line );
44 boost::fibers::mutex gpu_mem_mtx;
45 boost::fibers::condition_variable gpu_mem_cv;
49 void* devPtr =
nullptr;
50 cudaError_t err = cudaSuccess;
53 err = cudaMallocAsync( &devPtr,
size,
stream );
54 if ( err == cudaSuccess ) {
break; }
55 if ( err == cudaErrorMemoryAllocation ) {
58 gpu_mem_cv.wait( lck );
62 }
while ( err == cudaErrorMemoryAllocation );
64 stream.parent()->restoreAfterSuspend().orThrow(
"Error restoring", DEVARREXC );
69 void* devPtr =
nullptr;
70 cudaError_t err = cudaSuccess;
73 err = cudaMalloc( &devPtr,
size );
74 if ( err == cudaSuccess ) {
break; }
75 if ( err == cudaErrorMemoryAllocation ) {
79 if ( parent !=
nullptr ) {
81 gpu_mem_cv.wait( lck );
89 }
while ( err == cudaErrorMemoryAllocation );
94 cudaError_t err = cudaFreeAsync( ptr,
stream );
95 if ( err != cudaSuccess ) {
98 gpu_mem_cv.notify_all();
102 cudaError_t err = cudaFree( ptr );
103 if ( err != cudaSuccess ) {
106 gpu_mem_cv.notify_all();
110 cudaError_t err = cudaMemcpyAsync( devPtr, hstPtr,
size, cudaMemcpyHostToDevice,
stream );
111 if ( err != cudaSuccess ) {
115 stream.await().orThrow(
"Await error", DEVARREXC );
119 cudaError_t err = cudaMemcpy( devPtr, hstPtr,
size, cudaMemcpyHostToDevice );
120 if ( err != cudaSuccess ) {
126 cudaError_t err = cudaMemcpyAsync( hstPtr, devPtr,
size, cudaMemcpyDeviceToHost,
stream );
127 if ( err != cudaSuccess ) {
131 stream.await().orThrow(
"Await error", DEVARREXC );
135 cudaError_t err = cudaMemcpy( hstPtr, devPtr,
size, cudaMemcpyDeviceToHost );
136 if ( err != cudaSuccess ) {
142 cudaError_t err = cudaMemcpyAsync( destDevPtr, srcDevPtr,
size, cudaMemcpyDeviceToDevice,
stream );
143 if ( err != cudaSuccess ) {
149 cudaError_t err = cudaMemcpy( destDevPtr, srcDevPtr,
size, cudaMemcpyDeviceToDevice );
150 if ( err != cudaSuccess ) {