如何从内核调用流中的 Thrust 函数?
How to call a Thrust function in a stream from a kernel?
我想通过在设备内核中调用它来使 thrust::scatter
异步(我也可以通过在另一个主机线程中调用它来实现)。 thrust::cuda::par.on(stream)
是不能从设备内核调用的主机函数。以下代码在图灵架构上使用 CUDA 10.1 进行了尝试。
__global__ void async_scatter_kernel(float* first,
float* last,
int* map,
float* output)
{
cudaStream_t stream;
cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
thrust::scatter(thrust::cuda::par.on(stream), first, last, map, output);
cudaDeviceSynchronize();
cudaStreamDestroy(stream);
}
我知道 thrust 在从设备调用时使用动态并行来启动其内核,但是我找不到指定流的方法。
以下代码在 CUDA 10.1.243 上为我编译干净:
$ cat t1518.cu
#include <thrust/scatter.h>
#include <thrust/execution_policy.h>
__global__ void async_scatter_kernel(float* first,
float* last,
int* map,
float* output)
{
cudaStream_t stream;
cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
thrust::scatter(thrust::cuda::par.on(stream), first, last, map, output);
cudaDeviceSynchronize();
cudaStreamDestroy(stream);
}
int main(){
float *first = NULL;
float *last = NULL;
float *output = NULL;
int *map = NULL;
async_scatter_kernel<<<1,1>>>(first, last, map, output);
cudaDeviceSynchronize();
}
$ nvcc -arch=sm_35 -rdc=true t1518.cu -o t1518
$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2019 NVIDIA Corporation
Built on Sun_Jul_28_19:07:16_PDT_2019
Cuda compilation tools, release 10.1, V10.1.243
$
对于使用 CUDA 动态并行的任何代码,-arch=sm_35
(或类似)和 -rdc=true
是必要的(但并非在所有情况下都足够)编译开关。例如,如果省略 -rdc=true
开关,则会出现类似于您所描述的错误:
$ nvcc -arch=sm_35 t1518.cu -o t1518
t1518.cu(11): error: calling a __host__ function("thrust::cuda_cub::par_t::on const") from a __global__ function("async_scatter_kernel") is not allowed
t1518.cu(11): error: identifier "thrust::cuda_cub::par_t::on const" is undefined in device code
2 errors detected in the compilation of "/tmp/tmpxft_00003a80_00000000-8_t1518.cpp1.ii".
$
因此,对于您在此处显示的示例,可以通过更新到最新的 CUDA 版本或通过指定正确的命令行,或同时通过两者来消除编译错误。
我想通过在设备内核中调用它来使 thrust::scatter
异步(我也可以通过在另一个主机线程中调用它来实现)。 thrust::cuda::par.on(stream)
是不能从设备内核调用的主机函数。以下代码在图灵架构上使用 CUDA 10.1 进行了尝试。
__global__ void async_scatter_kernel(float* first,
float* last,
int* map,
float* output)
{
cudaStream_t stream;
cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
thrust::scatter(thrust::cuda::par.on(stream), first, last, map, output);
cudaDeviceSynchronize();
cudaStreamDestroy(stream);
}
我知道 thrust 在从设备调用时使用动态并行来启动其内核,但是我找不到指定流的方法。
以下代码在 CUDA 10.1.243 上为我编译干净:
$ cat t1518.cu
#include <thrust/scatter.h>
#include <thrust/execution_policy.h>
__global__ void async_scatter_kernel(float* first,
float* last,
int* map,
float* output)
{
cudaStream_t stream;
cudaStreamCreateWithFlags(&stream, cudaStreamNonBlocking);
thrust::scatter(thrust::cuda::par.on(stream), first, last, map, output);
cudaDeviceSynchronize();
cudaStreamDestroy(stream);
}
int main(){
float *first = NULL;
float *last = NULL;
float *output = NULL;
int *map = NULL;
async_scatter_kernel<<<1,1>>>(first, last, map, output);
cudaDeviceSynchronize();
}
$ nvcc -arch=sm_35 -rdc=true t1518.cu -o t1518
$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2019 NVIDIA Corporation
Built on Sun_Jul_28_19:07:16_PDT_2019
Cuda compilation tools, release 10.1, V10.1.243
$
对于使用 CUDA 动态并行的任何代码,-arch=sm_35
(或类似)和 -rdc=true
是必要的(但并非在所有情况下都足够)编译开关。例如,如果省略 -rdc=true
开关,则会出现类似于您所描述的错误:
$ nvcc -arch=sm_35 t1518.cu -o t1518
t1518.cu(11): error: calling a __host__ function("thrust::cuda_cub::par_t::on const") from a __global__ function("async_scatter_kernel") is not allowed
t1518.cu(11): error: identifier "thrust::cuda_cub::par_t::on const" is undefined in device code
2 errors detected in the compilation of "/tmp/tmpxft_00003a80_00000000-8_t1518.cpp1.ii".
$
因此,对于您在此处显示的示例,可以通过更新到最新的 CUDA 版本或通过指定正确的命令行,或同时通过两者来消除编译错误。