Fix memory leaks.

Shutdown CUDA properly when nvtt context is destroyed.
Fixes issue 83.
This commit is contained in:
castano
2009-03-18 05:46:53 +00:00
parent 56543e1a92
commit 8529dcf755
4 changed files with 282 additions and 224 deletions

View File

@ -224,8 +224,13 @@ Compressor::Compressor() : m(*new Compressor::Private())
{ {
// Select fastest CUDA device. // Select fastest CUDA device.
int device = cuda::getFastestDevice(); int device = cuda::getFastestDevice();
cuda::setDevice(device); if (!cuda::setDevice(device))
{
m.cudaEnabled = false;
m.cuda = NULL;
}
else
{
m.cuda = new CudaCompressor(); m.cuda = new CudaCompressor();
if (!m.cuda->isValid()) if (!m.cuda->isValid())
@ -235,10 +240,12 @@ Compressor::Compressor() : m(*new Compressor::Private())
} }
} }
} }
}
Compressor::~Compressor() Compressor::~Compressor()
{ {
delete &m; delete &m;
cuda::exit();
} }
@ -254,8 +261,13 @@ void Compressor::enableCudaAcceleration(bool enable)
{ {
// Select fastest CUDA device. // Select fastest CUDA device.
int device = cuda::getFastestDevice(); int device = cuda::getFastestDevice();
cuda::setDevice(device); if (!cuda::setDevice(device))
{
m.cudaEnabled = false;
m.cuda = NULL;
}
else
{
m.cuda = new CudaCompressor(); m.cuda = new CudaCompressor();
if (!m.cuda->isValid()) if (!m.cuda->isValid())
@ -265,6 +277,7 @@ void Compressor::enableCudaAcceleration(bool enable)
} }
} }
} }
}
/// Check if CUDA acceleration is enabled. /// Check if CUDA acceleration is enabled.
bool Compressor::isCudaAccelerationEnabled() const bool Compressor::isCudaAccelerationEnabled() const

View File

@ -90,20 +90,34 @@ CudaCompressor::CudaCompressor() : m_bitmapTable(NULL), m_bitmapTableCTX(NULL),
#if defined HAVE_CUDA #if defined HAVE_CUDA
// Allocate and upload bitmaps. // Allocate and upload bitmaps.
cudaMalloc((void**) &m_bitmapTable, 992 * sizeof(uint)); cudaMalloc((void**) &m_bitmapTable, 992 * sizeof(uint));
cudaError_t err = cudaGetLastError();
if (err != cudaSuccess) {
fprintf(stderr, "CUDA Error: %s\n", cudaGetErrorString(err));
fflush(stderr);
nvDebugBreak();
}
if (m_bitmapTable != NULL) if (m_bitmapTable != NULL)
{ {
cudaMemcpy(m_bitmapTable, s_bitmapTable, 992 * sizeof(uint), cudaMemcpyHostToDevice); cudaMemcpy(m_bitmapTable, s_bitmapTable, 992 * sizeof(uint), cudaMemcpyHostToDevice);
if (cudaGetLastError() != cudaSuccess) nvDebugBreak();
} }
cudaMalloc((void**) &m_bitmapTableCTX, 704 * sizeof(uint)); cudaMalloc((void**) &m_bitmapTableCTX, 704 * sizeof(uint));
if (cudaGetLastError() != cudaSuccess) nvDebugBreak();
if (m_bitmapTableCTX != NULL) if (m_bitmapTableCTX != NULL)
{ {
cudaMemcpy(m_bitmapTableCTX, s_bitmapTableCTX, 704 * sizeof(uint), cudaMemcpyHostToDevice); cudaMemcpy(m_bitmapTableCTX, s_bitmapTableCTX, 704 * sizeof(uint), cudaMemcpyHostToDevice);
if (cudaGetLastError() != cudaSuccess) nvDebugBreak();
} }
// Allocate scratch buffers. // Allocate scratch buffers.
cudaMalloc((void**) &m_data, MAX_BLOCKS * 64U); cudaMalloc((void**) &m_data, MAX_BLOCKS * 64U);
if (cudaGetLastError() != cudaSuccess) nvDebugBreak();
cudaMalloc((void**) &m_result, MAX_BLOCKS * 8U); cudaMalloc((void**) &m_result, MAX_BLOCKS * 8U);
if (cudaGetLastError() != cudaSuccess) nvDebugBreak();
#endif #endif
} }
@ -114,14 +128,17 @@ CudaCompressor::~CudaCompressor()
cudaFree(m_data); cudaFree(m_data);
cudaFree(m_result); cudaFree(m_result);
cudaFree(m_bitmapTable); cudaFree(m_bitmapTable);
cudaFree(m_bitmapTableCTX);
#endif #endif
} }
bool CudaCompressor::isValid() const bool CudaCompressor::isValid() const
{ {
#if defined HAVE_CUDA #if defined HAVE_CUDA
if (cudaGetLastError() != cudaSuccess) cudaError_t err = cudaGetLastError();
if (err != cudaSuccess)
{ {
nvDebug("*** CUDA Error: %s\n", cudaGetErrorString(err));
return false; return false;
} }
#endif #endif

View File

@ -84,19 +84,26 @@ static bool isCudaDriverAvailable(int version)
if (!nvcuda.isValid()) if (!nvcuda.isValid())
{ {
nvDebug("*** CUDA driver not found.\n");
return false; return false;
} }
if (version >= 2000) if (version >= 2000)
{ {
void * address = nvcuda.bindSymbol("cuStreamCreate"); void * address = nvcuda.bindSymbol("cuStreamCreate");
if (address == NULL) return false; if (address == NULL) {
nvDebug("*** CUDA driver version < 2.0.\n");
return false;
}
} }
if (version >= 2010) if (version >= 2010)
{ {
void * address = nvcuda.bindSymbol("cuModuleLoadDataEx"); void * address = nvcuda.bindSymbol("cuModuleLoadDataEx");
if (address == NULL) return false; if (address == NULL) {
nvDebug("*** CUDA driver version < 2.1.\n");
return false;
}
} }
if (version >= 2020) if (version >= 2020)
@ -104,16 +111,23 @@ static bool isCudaDriverAvailable(int version)
typedef CUresult (CUDAAPI * PFCU_DRIVERGETVERSION)(int * version); typedef CUresult (CUDAAPI * PFCU_DRIVERGETVERSION)(int * version);
PFCU_DRIVERGETVERSION driverGetVersion = (PFCU_DRIVERGETVERSION)nvcuda.bindSymbol("cuDriverGetVersion"); PFCU_DRIVERGETVERSION driverGetVersion = (PFCU_DRIVERGETVERSION)nvcuda.bindSymbol("cuDriverGetVersion");
if (driverGetVersion == NULL) return false; if (driverGetVersion == NULL) {
nvDebug("*** CUDA driver version < 2.2.\n");
return false;
}
int driverVersion; int driverVersion;
if (driverGetVersion(&driverVersion) != CUDA_SUCCESS) return false; CUresult err = driverGetVersion(&driverVersion);
if (err != CUDA_SUCCESS) {
nvDebug("*** Error querying driver version: '%s'.\n", cudaGetErrorString((cudaError_t)err));
return false;
}
return driverVersion >= version; return driverVersion >= version;
} }
#endif // HAVE_CUDA #endif // HAVE_CUDA
return false; return true;
} }
@ -121,10 +135,13 @@ static bool isCudaDriverAvailable(int version)
bool nv::cuda::isHardwarePresent() bool nv::cuda::isHardwarePresent()
{ {
#if defined HAVE_CUDA #if defined HAVE_CUDA
#if NV_OS_WIN32 // Make sure that CUDA driver matches CUDA runtime.
//if (isWindowsVista()) return false; if (!isCudaDriverAvailable(CUDART_VERSION))
//if (isWindowsVista() || !isWow32()) return false; {
#endif nvDebug("CUDA driver not available for CUDA runtime %d\n", CUDART_VERSION);
return false;
}
int count = deviceCount(); int count = deviceCount();
if (count == 1) if (count == 1)
{ {
@ -137,15 +154,9 @@ bool nv::cuda::isHardwarePresent()
{ {
return false; return false;
} }
// Make sure that CUDA driver matches CUDA runtime.
if (!isCudaDriverAvailable(CUDART_VERSION))
{
return false;
} }
// @@ Make sure that warp size == 32 // @@ Make sure that warp size == 32
}
return count > 0; return count > 0;
#else #else
@ -205,8 +216,24 @@ bool nv::cuda::setDevice(int i)
nvCheck(i < deviceCount()); nvCheck(i < deviceCount());
#if defined HAVE_CUDA #if defined HAVE_CUDA
cudaError_t result = cudaSetDevice(i); cudaError_t result = cudaSetDevice(i);
if (result != cudaSuccess) {
nvDebug("*** CUDA Error: %s\n", cudaGetErrorString(result));
}
return result == cudaSuccess; return result == cudaSuccess;
#else #else
return false; return false;
#endif #endif
} }
void nv::cuda::exit()
{
#if defined HAVE_CUDA
cudaError_t result = cudaThreadExit();
if (result != cudaSuccess) {
nvDebug("*** CUDA Error: %s\n", cudaGetErrorString(result));
}
#endif
}

View File

@ -33,6 +33,7 @@ namespace nv
int deviceCount(); int deviceCount();
int getFastestDevice(); int getFastestDevice();
bool setDevice(int i); bool setDevice(int i);
void exit();
}; };
} // nv namespace } // nv namespace