【问题标题】:How to call a Thrust function in a stream from a kernel?如何从内核调用流中的推力函数?
【发布时间】:2020-01-24 11:56:42
【问题描述】:

我想通过在设备内核中调用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 使用动态并行性来启动其内核,但是我找不到指定流的方法。

【问题讨论】:

  • 即使不指定流而只使用thrust::device执行策略(并为动态并行提供必要的编译环境和运行环境)也会与调用线程异步
  • @RobertCrovella 我还希望我的内核与其他内核同时运行,因为我有/需要多级并发。据我所知,thrust::device 执行策略在空流上运行。我无法分析内核以查看行为,因为视觉分析器不支持 CC 7.0 或更高版本的动态并行性。我认为,要实现与其他内核的并发性,我需要能够在空流以外的流中启动它。
  • 您的代码在 CUDA 10.1.243 上为我编译干净。我的猜测是您的编译命令行(您没有显示)没有正确指定 CUDA 动态并行编译所需的环境。

标签: cuda thrust dynamic-parallelism


【解决方案1】:

以下代码在 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
$

-arch=sm_35(或类似名称)和-rdc=true 对于使用 CUDA 动态并行的任何代码都是必要的(但并非在所有情况下都足够)编译开关。例如,如果您省略 -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 版本或通过指定正确的命令行或两者兼而有之来消除。

【讨论】:

  • 问题确实是-rdc=true。但是,当存在动态并行性时,我无法分析应用程序,无论是使用 Visual Profiler 还是使用 Nsight Systems。我只能看到内存副本。有没有办法通过动态并行跟踪内核?
猜你喜欢
  • 2018-07-22
  • 2011-01-24
  • 1970-01-01
  • 2014-10-19
  • 1970-01-01
  • 2016-04-30
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多