Cuda 将推力设备迭代器转换为原始指针
我正在考虑下面的简单代码,其中我正在转换Cuda 将推力设备迭代器转换为原始指针,cuda,thrust,Cuda,Thrust,我正在考虑下面的简单代码,其中我正在转换推力::主机向量::迭代器h_temp_迭代器=h_temp.begin()和推力::设备向量::迭代器d_temp_迭代器=d_temp.begin()到原始指针 为此,我分别将&(h_temp_迭代器[0])和&(d_temp_迭代器[0])传递给函数和内核。前者(CPU情况)编译,后者(GPU情况)不编译。这两种情况原则上应该是对称的,因此我不理解错误消息的原因,即: Error 1 error : no suitable conversio
推力::主机向量::迭代器h_temp_迭代器=h_temp.begin()代码>和推力::设备向量::迭代器d_temp_迭代器=d_temp.begin()代码>到原始指针
为此,我分别将&(h_temp_迭代器[0])
和&(d_temp_迭代器[0])
传递给函数和内核。前者(CPU情况)编译,后者(GPU情况)不编译。这两种情况原则上应该是对称的,因此我不理解错误消息的原因,即:
Error 1 error : no suitable conversion function from "thrust::device_ptr<int>" to "int *" exists
根据Talonmes的评论,解决方案是通过
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;
}
#包括
#包括
__全局无效测试内核(int*a,const int N)
{
int i=threadIdx.x;
如果(i>=N)返回;
a[i]=2;
printf(“GPU%i%i\n”,i,a[i]);
}
void testFunction(int*a,const int N)
{
对于(int i=0;i
根据技术人员的意见,解决方案是通过
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;
}
#包括
#包括
__全局无效测试内核(int*a,const int N)
{
int i=threadIdx.x;
如果(i>=N)返回;
a[i]=2;
printf(“GPU%i%i\n”,i,a[i]);
}
void testFunction(int*a,const int N)
{
对于(int i=0;i
当您使用推力时,另一个更漂亮的解决方案是使用数据()获取指针并将其转换为原始指针:
thrust::raw_pointer_cast(d_temp_iterator.data())
当您使用推力时,另一个更好的解决方案是使用data()
获取指针并将其转换为原始指针:
thrust::raw_pointer_cast(d_temp_iterator.data())
这只是一个非常温和的变化,不是吗?在基于推力标签的类型化模型(原始模型)中,任何设备内存都由推力::设备ptr
表示。它具有指针语义,但不是指针,这有助于加强主机/设备指针类型的安全性。在上面的代码中,迭代器衰减为设备\u ptr
而不是指针。你必须施放设备\u ptr
才能获得一个原始指针,你可以传递给设备代码谢谢你,Talonmes,感谢你不懈的帮助。我已经解决了这个问题。你想发布一个答案吗?如果你愿意,你可以自己写。我会投票的,谢谢。我上传了一个完整代码的答案。这只是一个非常温和的变化,不是吗?在基于推力标签的类型化模型(原始模型)中,任何设备内存都由推力::设备ptr
表示。它具有指针语义,但不是指针,这有助于加强主机/设备指针类型的安全性。在上面的代码中,迭代器衰减为设备\u ptr
而不是指针。你必须施放设备\u ptr
才能获得一个原始指针,你可以传递给设备代码谢谢你,Talonmes,感谢你不懈的帮助。我已经解决了这个问题。你想发布一个答案吗?如果你愿意,你可以自己写。我会投票的,谢谢。我已经上传了一个完整的工作代码的答案。