我想使用Thrust库来计算CUDA中设备数组的前缀和。
我的数组分配了cudaMalloc()
。我的要求如下:
main()
{
Launch kernel 1 on data allocated through cudaMalloc()
// This kernel will poplulate some data d.
Use thrust to calculate prefix sum of d.
Launch kernel 2 on prefix sum.
}
我想在我的内核之间的某处使用Thrust所以我需要方法将指针转换为设备迭代器并返回。下面的代码有什么问题?
int main()
{
int *a;
cudaMalloc((void**)&a,N*sizeof(int));
thrust::device_ptr<int> d=thrust::device_pointer_cast(a);
thrust::device_vector<int> v(N);
thrust::exclusive_scan(a,a+N,v);
return 0;
}
答案 0 :(得分:9)
最新编辑的完整工作示例如下所示:
#include <thrust/device_ptr.h>
#include <thrust/device_vector.h>
#include <thrust/scan.h>
#include <thrust/fill.h>
#include <thrust/copy.h>
#include <cstdio>
int main()
{
const int N = 16;
int * a;
cudaMalloc((void**)&a, N*sizeof(int));
thrust::device_ptr<int> d = thrust::device_pointer_cast(a);
thrust::fill(d, d+N, 2);
thrust::device_vector<int> v(N);
thrust::exclusive_scan(d, d+N, v.begin());
int v_[N];
thrust::copy(v.begin(), v.end(), v_);
for(int i=0; i<N; i++)
printf("%d %d\n", i, v_[i]);
return 0;
}
你错了:
N
未定义任何地方a
而不是device_ptr
d
作为输入迭代器传递给exclusive_scan
device_vector
v
传递给exclusive_scan
而不是相应的迭代器v.begin()
注重细节是完成这项工作所缺乏的。它的工作原理是:
$ nvcc -arch=sm_12 -o thrust_kivekset thrust_kivekset.cu
$ ./thrust_kivekset
0 0
1 2
2 4
3 6
4 8
5 10
6 12
7 14
8 16
9 18
10 20
11 22
12 24
13 26
14 28
15 30
编辑:
thrust::device_vector.data()
将返回thrust::device_ptr
,指向向量的第一个元素。 thrust::device_ptr.get()
将返回原始设备指针。因此
cudaMemcpy(v_, v.data().get(), N*sizeof(int), cudaMemcpyDeviceToHost);
和
thrust::copy(v, v+N, v_);
在这个例子中,在功能上是等效的。
答案 1 :(得分:3)
使用cudaMalloc()
将从thrust::device_ptr
获取的原始指针转换为thrust::device_pointer_cast
。以下是Thrust文档中的一个示例:
#include <thrust/device_ptr.h>
#include <thrust/fill.h>
#include <cuda.h>
int main(void)
{
size_t N = 10;
// obtain raw pointer to device memory
int * raw_ptr;
cudaMalloc((void **) &raw_ptr, N * sizeof(int));
// wrap raw pointer with a device_ptr
thrust::device_ptr<int> dev_ptr = thrust::device_pointer_cast(raw_ptr);
// use device_ptr in Thrust algorithms
thrust::fill(dev_ptr, dev_ptr + N, (int) 0);
// access device memory transparently through device_ptr
dev_ptr[0] = 1;
// free memory
cudaFree(raw_ptr);
return 0;
}
使用thrust::inclusive_scan
或thrust::exclusive_scan
计算前缀总和。
http://code.google.com/p/thrust/wiki/QuickStartGuide#Prefix-Sums