cuda 流:流执行后未调用回调
cuda streams: callback not getting called after stream execution
我在使用 cuda 流回调函数时遇到问题。问题是在内核运行后不执行。我将 cuda 流封装在 C++ class 中,如下所示:
class Stream
{
public:
Stream();
void run(float *input, int points);
~Stream();
static void CUDART_CB callback(cudaStream_t stream,
cudaError_t status,
void * user_data);
private:
void callback_function();
cudaStream_t s;
};
现在,我按照之前的建议设置回调函数如下:
void CUDART_CB StreamWorkflow::callback(cudaStream_t stream,
cudaError_t status,
void * user_data)
{
Stream* thiz = (Stream *)(user_data);
thiz->callback_function();
}
并且构造函数设置流并附加回调
Stream::Stream()
{
checkCudaErrors(cudaStreamCreate(&s));
checkCudaErrors(cudaStreamAddCallback(s, Stream::callback, this, 0));
}
现在 运行 方法在此流上调用 cuda 内核,我知道这执行得很好。它的实现方式如下:
void Stream::run(float *f, int p)
{
dim3 block(16, 16);
dim3 grid((int)ceil(double(p) / 256.0));
my_kernel(f, p, grid, block, s);
checkCudaErrors(cudaDeviceSynchronize());
getLastCudaError("kernel launch failed");
}
我的问题是只有在执行构造函数时才会调用回调。因此,一旦创建对象,callback_function() 就会通过注册的回调 () 执行。内核被主机执行多次,并且在完成时从不执行回调函数。我可以看到内核已成功执行,但回调从未到来。
每次 内核 运行 时,我是否必须注册回调 (因此在执行 运行 函数之前注册此回调)或者我在做什么这里真的有问题吗?
我想您可能对回调的工作原理感到困惑。通常,当您向 CUDA 流发出 CUDA 操作时,该 CUDA 操作将在所有先前向该流发出的 CUDA activity 已完成时执行(并且在向该流发出任何后续 activity 之前)开始)。
回调也不例外。如果您希望在内核执行后执行回调,那么您必须在发布内核后向该流发出该回调。添加回调函数的定义是not:
"any time a kernel completes in this stream, run this callback"
definition of the add callback function 是:
"when the CUDA stream has completed all CUDA activity up to this point, then execute the callback"
或者,直接从文档中引用:
The function to call once preceding stream operations are complete
因此这个构造函数对我来说毫无意义:
Stream::Stream()
{
checkCudaErrors(cudaStreamCreate(&s));
checkCudaErrors(cudaStreamAddCallback(s, Stream::callback, this, 0));
}
这个构造函数说:
"create a CUDA stream"
"when all previously issued activity to this stream is complete, run this callback"
但是当然,您还没有向该流发出任何 activity,因此回调会在流创建后立即运行(且仅一次)。
"so register this callback before executing the run function"
不,如果这是你想要的:
The problem is that it does not execute after the kernel is run
然后将您的添加回调函数移动到在您的内核启动后,我认为您更有可能看到您想要的activity。
我在使用 cuda 流回调函数时遇到问题。问题是在内核运行后不执行。我将 cuda 流封装在 C++ class 中,如下所示:
class Stream
{
public:
Stream();
void run(float *input, int points);
~Stream();
static void CUDART_CB callback(cudaStream_t stream,
cudaError_t status,
void * user_data);
private:
void callback_function();
cudaStream_t s;
};
现在,我按照之前的建议设置回调函数如下:
void CUDART_CB StreamWorkflow::callback(cudaStream_t stream,
cudaError_t status,
void * user_data)
{
Stream* thiz = (Stream *)(user_data);
thiz->callback_function();
}
并且构造函数设置流并附加回调
Stream::Stream()
{
checkCudaErrors(cudaStreamCreate(&s));
checkCudaErrors(cudaStreamAddCallback(s, Stream::callback, this, 0));
}
现在 运行 方法在此流上调用 cuda 内核,我知道这执行得很好。它的实现方式如下:
void Stream::run(float *f, int p)
{
dim3 block(16, 16);
dim3 grid((int)ceil(double(p) / 256.0));
my_kernel(f, p, grid, block, s);
checkCudaErrors(cudaDeviceSynchronize());
getLastCudaError("kernel launch failed");
}
我的问题是只有在执行构造函数时才会调用回调。因此,一旦创建对象,callback_function() 就会通过注册的回调 () 执行。内核被主机执行多次,并且在完成时从不执行回调函数。我可以看到内核已成功执行,但回调从未到来。
每次 内核 运行 时,我是否必须注册回调 (因此在执行 运行 函数之前注册此回调)或者我在做什么这里真的有问题吗?
我想您可能对回调的工作原理感到困惑。通常,当您向 CUDA 流发出 CUDA 操作时,该 CUDA 操作将在所有先前向该流发出的 CUDA activity 已完成时执行(并且在向该流发出任何后续 activity 之前)开始)。
回调也不例外。如果您希望在内核执行后执行回调,那么您必须在发布内核后向该流发出该回调。添加回调函数的定义是not:
"any time a kernel completes in this stream, run this callback"
definition of the add callback function 是:
"when the CUDA stream has completed all CUDA activity up to this point, then execute the callback"
或者,直接从文档中引用:
The function to call once preceding stream operations are complete
因此这个构造函数对我来说毫无意义:
Stream::Stream()
{
checkCudaErrors(cudaStreamCreate(&s));
checkCudaErrors(cudaStreamAddCallback(s, Stream::callback, this, 0));
}
这个构造函数说:
"create a CUDA stream"
"when all previously issued activity to this stream is complete, run this callback"
但是当然,您还没有向该流发出任何 activity,因此回调会在流创建后立即运行(且仅一次)。
"so register this callback before executing the run function"
不,如果这是你想要的:
The problem is that it does not execute after the kernel is run
然后将您的添加回调函数移动到在您的内核启动后,我认为您更有可能看到您想要的activity。