【问题标题】:Converting Thrust device iterators to raw pointers将 Thrust 设备迭代器转换为原始指针
【发布时间】:2017-07-27 12:23:57
【问题描述】:

我正在考虑以下简单代码,其中我将 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 架构编译。

代码

#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;
}

【问题讨论】:

  • 这只是一个非常温和的变化,不是吗? stackoverflow.com/q/11113485/681865
  • 在基于推力标签的类型化模型(原始模型)中,任何设备内存都由thrust::device_ptr 表示。这具有指针语义,但不是指针,它有助于强制执行主机/设备指针类型安全。在上面的代码中,迭代器衰减为 device_ptr 而不是指针。您必须强制转换 device_ptr 以获得可以传递给设备代码的原始指针
  • 感谢您,talonmies,您的不懈帮助。我已经解决了这个问题。您要发布答案吗?
  • 如果你愿意,你可以继续写你自己的。我会赞成的。
  • 谢谢。我已经上传了一个包含完整工作代码的答案。

标签: cuda thrust


【解决方案1】:

按照talonmies的cmets,解决办法是通过

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;
}

【讨论】:

    【解决方案2】:

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

    thrust::raw_pointer_cast(d_temp_iterator.data())
    

    【讨论】:

      猜你喜欢
      • 2010-10-19
      • 2023-04-04
      • 2016-10-29
      • 1970-01-01
      • 2016-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多