将Thrust设备迭代器转换为原始指针

时间:2017-07-27 12:23:58

标签: cuda thrust

我正在考虑以下简单代码,我将thrust::host_vector<int>::iterator h_temp_iterator = h_temp.begin();thrust::device_vector<int>::iterator d_temp_iterator = d_temp.begin();转换为原始指针。

为此,我将&(h_temp_iterator[0])&(d_temp_iterator[0])分别传递给函数和内核。前者(CPU案例)编译,后者(GPU案例)不编译。这两种情况原则上应该是对称的,所以我不明白错误信息的原因是:

Error   1   error : no suitable conversion function from "thrust::device_ptr<int>" to "int *" exists    

配置如下:

  1. Windows 7Visual Studio 2010CUDA 7.5,正在为3.5架构进行编译。
  2. Windows 10Visual Studio 2013CUDA 8.0,正在为5.2架构进行编译。
  3. CODE

    #include <thrust\host_vector.h>
    #include <thrust\device_vector.h>
    
    __global__ void testKernel(int *a, const int N)
    {
        int i = threadIdx.x;
    
        if (i >= N) return;
    
        a[i] = 2;
    }
    
    void testFunction(int *a, const int N)
    {
        for (int i = 0; i < N; i++) a[i] = 2;
    }
    
    int main()
    {
        const int N = 10;
    
        thrust::host_vector<int> h_temp(N);
        thrust::device_vector<int> d_temp(N);
    
        thrust::host_vector<int>::iterator h_temp_iterator = h_temp.begin();
        thrust::device_vector<int>::iterator d_temp_iterator = d_temp.begin();
    
        testFunction(&(h_temp_iterator[0]), N);
        testKernel<<<1, N>>>(&(d_temp_iterator[0]), N);
    
        for (int i = 0; i < N; i++) printf("%i %i\n", i, h_temp[i]);
    
        return 0;
    }
    

2 个答案:

答案 0 :(得分:3)

按照talonmies的评论,解决方案是通过

thrust::raw_pointer_cast(&d_temp_iterator[0])

而不是

&d_temp_iterator[0]

在下面,完整工作的代码

#include <thrust\host_vector.h>
#include <thrust\device_vector.h>

__global__ void testKernel(int *a, const int N)
{
    int i = threadIdx.x;

    if (i >= N) return;

    a[i] = 2;

    printf("GPU %i %i\n", i, a[i]);
}

void testFunction(int *a, const int N)
{
    for (int i = 0; i < N; i++) {
        a[i] = 2;
        printf("CPU %i %i\n", i, a[i]);
    }
}

int main()
{
    const int N = 10;

    thrust::host_vector<int> h_temp(N);
    thrust::device_vector<int> d_temp(N);

    thrust::host_vector<int>::iterator h_temp_iterator = h_temp.begin();
    thrust::device_vector<int>::iterator d_temp_iterator = d_temp.begin();

    int *temp = thrust::raw_pointer_cast(&d_temp_iterator[0]);

    testFunction(&(h_temp_iterator[0]), N);
    testKernel<<<1, N>>>(temp, N);

    return 0;
}

答案 1 :(得分:0)

当您使用推力时,另一个更漂亮的解决方案是使用data()获取指针并将其转换为原始指针:

thrust::raw_pointer_cast(d_temp_iterator.data())