CUDA streams destruction and CudaDeviceReset

北战南征 提交于 2019-11-30 10:36:36

There are two problems here, both related to the destructor of your class and scope.

Firstly, let's start with a version of your main() which will work correctly:

int main( int argc, char** argv) 
{
    {
        CudaStreams streams;
        streams.InitStreams(1);
    }

    cudaDeviceReset();

    return 0;
}

This works correctly because the destructor for streams is called exactly once (when streams falls out of scope), and before cudaDeviceReset is called.

Your original main() (or a compilable version of it, but more about that later...) fails for two reasons. Let's look at it again:

int main( int argc, char** argv) 
{
    CudaStreams streams;
    streams.InitStreams(1);
    streams.~CudaStreams();

    cudaDeviceReset();

    return 0;
}

Here you explicitly call the destructor for streams (which you should almost never do), then cudaDeviceReset, then the destructor is called again at the return statement when streams falls out of scope. The automatic calling the destructor after the context is destroyed is the source of the segfault/exception. The cudaStreamDestroy calls are trying to work on streams without a valid CUDA context. So the solution is not to have any classes which make CUDA API calls fall out of scope (or call their destructors explicitly) when there is no context.

If we made a third version like this:

int main( int argc, char** argv) 
{
    {
        CudaStreams streams;
        streams.InitStreams(1);
        streams.~CudaStreams();
    }

    cudaDeviceReset();

    return 0;
}

You will get a CUDA runtime error. Because the destructor gets call twice. The first time (explicit) it will work. The second (implict, out of scope) will produce a runtime error: you have a valid context, but are now trying to destroy non-existent streams.

As a final comment/question: How hard would it have been to post and actual compilable version of the code you showed in your original question? It literally required 5 extra lines to make it into a proper repro case someone else could actual compile and run. I find it a bit unreasonable to expect others to make a effort to answer what are basically debugging questions if you are not willing to make a similar effort in providing useful code and information which makes everyone's life that much easier. Think about it. [end of rant]

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!