user1999728
user1999728

Reputation: 903

Matlab fails to free memory stored on GPU allocated in a MEX file

I'm trying to write a MEX which will run some CUDA kernels (I'm not using feval because I need streams). I tried:

mxGPUArray * tmp=mxGPUCopyFromMxArray(prhs[2]);
double * outPtr=(double* ) mxGPUGetData(tmp);
kernel<<<..>>>(outPtr,...);

works perfectly. Unfortunately, it seems Matlab's GPU memory management is lacking... I have to use plhs[0]=mxGPUCreateMxArrayOnGPU(...). Naturally, I can't destroy it in the MEX code. but it seems that after overwriting it, MATLAB doesn't destroy it either - meaning I get a memory leak.

Since I couldn't figure out how to make Matlab clear that memory when it's done, I tried:

double * outPtr=(double* ) mxGetData(prhs[2]);

and calling the kernel with this pointer as input (the kernel writes into that location), I get an error:

kernel<<<...>>>(outPtr,...);
gpuErrchk( cudaPeekAtLastError() );
gpuErrchk( cudaDeviceSynchronize() );

The line points to cudaDeviceSynchronize as the one who generates the error

The input is a gpuArray, and I removed the const from void MexFunction(...), so that I'll be allowed to use the space preallocated to prhs[2], and not have to allocate more memory.
I figured since it's a gpuArray, the pointer will be to GPU memory and I won't have any problems. But apparently, I was wrong...

Any idea how to force Matalb to clean the memory on the GPU when I'm done, or just use the space allocated for prhs[2]? I've tried so many solutions, non of which worked.

I've read about changing values in-place. The problem is, I can't use the memory I preallocated in Matlab - it's on the GPU, but as I've mentioned, I still get errors when I use that pointer, and instead I have to create a new array, which causes the leak...

Upvotes: 0

Views: 1019

Answers (1)

user1999728
user1999728

Reputation: 903

well, I managed to work around this problem by (Accidentally) finding out there's a way to remove to make a const non-const using const_cast

mxGPUArray * tmp = const_cast<mxGPUArray *>(mxGPUCreateFromMxArray(prhs[2]));

Since mxGPUCreateFromMxArray doesn't actually create any more data if the argument is already on the GPU (maybe it copies the information about the array, but the pointer remains the same), it can give you the an object class you need (from mxGPUArray instead of mxArray) without having to copy it.

The problem of being unable to change the data was solved by const_cast

No lhs arguments. I just preallocate the space and overwrite it. the 3rd argument to the MEX is changed appropriately.

I wonder - does anyone see a problem with the code I posted here? (The code I posted there is a simple recreation of the memory leak problem. If this code seems to be correct, then there's either a problem with Matlab, or the right way to do it isn't as simple as it should be...)

Upvotes: 1

Related Questions