Cuda C ++在设备代码中没有元组吗?

时间:2016-11-22 12:45:30

标签: cuda

__global__ void addKernel(int *c, const int *a, const int *b)
{
    int i = threadIdx.x;
    auto lamb = [](int x) {return x + 1; }; // Works.
    auto t = std::make_tuple(1, 2, 3); // Does not work.
    c[i] = a[i] + b[i];
}

NVCC至少有lambda,但是std::make_tuple无法编译。当前版本的Cuda中不允许使用元组吗?

4 个答案:

答案 0 :(得分:2)

#include <thrust/tuple.h>

__global__ void addKernel(int *c, const int *a, const int *b)
{
    int i = threadIdx.x;
    auto lamb = [](int x) {return x + 1; }; // Works.
    auto t = thrust::make_tuple(1, 2, 3);
    c[i] = a[i] + b[i];
}

我需要从Thrust库中获取它们,而不是让它们工作似乎。以上编译。

答案 1 :(得分:1)

我刚刚尝试过,使用std::( std :: tuple,std :: get等)的元组元编程将在启用C ++ 14和expt-relaxed-constexpr的设备代码中工作(CUDA8 +)编译期间(例如df)-C ++ 14需要CUDA 9,但如果限于此,则基本std :: tuple应该在CUDA 8中工作。推力/元组可以工作,但有一些缺点:限于10个项目,并且缺少一些std :: tuple辅助函数(例如std :: tuple_cat)。由于元组及其相关函数在编译时,因此expt-relaxed-constexpr应该使您的std :: tuple能够“正常工作”。

nvcc -std=c++14 xxxx.cu -o yyyyy --expt-relaxed-constexpr

答案 2 :(得分:1)

由于标准库没有必要的__host____device__批注,因此在设备端对标准c ++库的支持存在问题。

也就是说,clang和nvcc都对某些功能提供了部分支持。通常,如果将__host__ __device__传递给nvcc(或默认使用clang),则仅将其视为--expt-relaxed-constexpr的constexpr函数。 Clang还对标准数学函数提供了更多支持。都不支持依赖C ++运行时的任何内容(内存分配,printf和assert除外),因为设备端不存在。

因此,简而言之-大多数标准C ++库在CUDA中无法在设备端使用,尽管随着标准库中越来越多的功能变为constexpr,事情会慢慢改善。

答案 3 :(得分:1)

实际上,CUDA本身不提供std::tuple的设备侧版本。但是,我在cuda-kat library中有一个完整的元组实现(在撰写本文时仍处于初期开发阶段)。推力的元组类在以下方面受到限制:

  1. 限制为10个元组元素。
  2. 递归地为每个元组元素扩展模板化类型。
  3. 不/部分支持右值(例如get()中的值)

cuda-kat中的元组实现是EASTL元组的改编,而后者又是LLVM项目的libc ++元组的改编。但是,与EASTL不同,它与C ++ 11兼容,因此您不必拥有绝对最新的CUDA版本。可能只需要从库中提取元组类,哦,我认为大约需要4个文件。