Thrust:尽管__CUDA_ARCH__仍然执行主机代码的原因

时间:2016-10-06 22:36:31

标签: cuda thrust

我尝试在代码中定义两个分支:一个用于CUDA执行,另一个用于 - 没有它(考虑到未来的OMP)。但是当我使用宏__CUDA_ARCH__时,它看起来好像总是执行主机代码。但我认为Thrust默认使用CUDA(和设备代码分支)。我的代码出了什么问题? 这是:

#include <thrust/transform.h>                                 
#include <thrust/functional.h>                                
#include <thrust/iterator/counting_iterator.h>                
#include <stdio.h>                                            

struct my_op                                                  
{                                                             
    my_op(int init_const) : constanta(init_const) {}      
    __host__ __device__ int operator()(const int &x) const
    {                                                     
        #if defined(__CUDA_ARCH__)                    
            return 2 * x * constanta;    // never executed - why?
        #else                                     
            return x * constanta;        // always executed                 
        #endif                       
    }                                                     

private:                                                      
    int constanta;                                        
};                                                            

int main()                                                    
{                                                             
 int data[7] = { 0, 0, 0, 0, 0, 0, 0 };                        
 thrust::counting_iterator<int> first(10);                     
 thrust::counting_iterator<int> last = first + 7;              

 int init_value = 1;                                           
 my_op op(init_value);                                         

 thrust::transform(first, last, data, op);                     
 for each (int el in data)                                     
    std::cout << el << " ";                               

 std::cout << std::endl;                                       
}                  

我希望“变换”将矢量定义为乘以2 * constanta,但我看到使用了主机代码 - 输出为“10 11 12 13 14 15 16”,而不是“20 22 24 26 28 30 32” (如预期的那样)。

为什么?

1 个答案:

答案 0 :(得分:2)

Thrust正在选择主机路径,因为提供给推力转换操作的一个数据项位于主机内存中:

 thrust::transform(first, last, data, op); 
                                ^^^^

如果您希望推力算法在设备上运行,一般来说,传递给/从的所有容器数据也必须驻留在设备存储器中。

以下是对代码的修改,如果我们将data替换为设备驻留容器,则表明推力将遵循设备路径:

$ cat t13.cu
#include <thrust/transform.h>
#include <thrust/functional.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/device_vector.h>
#include <stdio.h>

struct my_op
{
    my_op(int init_const) : constanta(init_const) {}
    __host__ __device__ int operator()(const int &x) const
    {
        #if defined(__CUDA_ARCH__)
            return 2 * x * constanta;    // never executed - why?
        #else
            return x * constanta;        // always executed
        #endif
    }

private:
    int constanta;
};

int main()
{
// int data[7] = { 0, 0, 0, 0, 0, 0, 0 };
 thrust::counting_iterator<int> first(10);
 thrust::counting_iterator<int> last = first + 7;
 thrust::device_vector<int> d_data(7);

 int init_value = 1;
 my_op op(init_value);

 thrust::transform(first, last, d_data.begin(), op);
 for (int el = 0; el < 7; el++) {
    int dat = d_data[el];
    std::cout << dat  << " ";    }

 std::cout << std::endl;
}
$ nvcc -arch=sm_61 -o t13 t13.cu
$ ./t13
20 22 24 26 28 30 32
$

您可能需要阅读thrust quick start guide以了解推力算法调度。