I am trying to write some code to ensure all GPU activity (in particular all running threads) are stopped. I need to do this to unload a module with dlclose, so I need to ensure all threads have stopped on both the host and the device.
According to the CUDA documentation, cudaDeviceSynchronize:
Blocks until the device has completed all preceding requested tasks... If the cudaDeviceScheduleBlockingSync flag was set for this device, the host thread will block until the device has finished its work.
However, when I set the blocking sync flag and call cudaDeviceSynchronize, a new host thread is spawned, which is still running after cudaDeviceSynchronize has returned. This is the opposite of what I am trying to achieve.
This behaviour is demonstrated in an example program:
#include <iostream>
void initialiseDevice()
{
cudaError result = cudaSetDeviceFlags(cudaDeviceScheduleBlockingSync);
if (cudaSuccess == result)
std::cout << "Set device flags." << std::endl;
else
std::cout << "Could not set device flags. (" << result << ")"
<< std::endl;
}
void synchroniseDevice()
{
cudaError result = cudaDeviceSynchronize();
if (cudaSuccess == result)
std::cout << "Device synchronise returned success." << std::endl;
else
std::cout << "Device synchronise returned error. (" << result << ")"
<< std::endl;
}
int main()
{
initialiseDevice();
sleep(1);
synchroniseDevice(); // new thread is spawned here
sleep(1); // new thread is still running here!
return 0;
}
If I compile this program with nvcc -g main.cu, and run it in gdb, a call to info threads shows that there are two threads running after cudaDeviceSynchronize has returned.
Output of info threads on the line after cudaDeviceSynchronise when running in gdb:
(gdb) info threads
Id Target Id Frame
2 Thread 0x7ffff5b8b700 (LWP 28458) "a.out" 0x00007ffff75aa023 in select
() at ../sysdeps/unix/syscall-template.S:82
* 1 Thread 0x7ffff7fd4740 (LWP 28255) "a.out" main () at cuda_test.cu:30
Could anyone help me understand why cudaDeviceSynchronize is spawning a new thread, and why the thread is still running after the call returns?
Could anyone point me in the right direction to help me find a method to block until all device and host activity/threads are finished?
info cuda threads(in cuda-gdb). One of those threads you have listed appears to be something spun up by a system call. That can happen. The other thread appears to be the one that would have been blocked by cudaDeviceSynchronize(). - Robert Crovella