3

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

2 に答える 2

11

最新の編集からの完全な動作例は次のようになります。

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

あなたが間違っていたこと:

  1. Nどこにも定義されていません
  2. への入力イテレータとしてaではなく、生のデバイス ポインタを渡します。device_ptr dexclusive_scan
  3. 適切なイテレータではなくdevice_vector vtoを渡すexclusive_scanv.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ベクトルの最初の要素を指すa を返します。thrust::device_ptr.get()raw デバイス ポインタを返します。したがって

cudaMemcpy(v_, v.data().get(), N*sizeof(int), cudaMemcpyDeviceToHost);

thrust::copy(v, v+N, v_);

この例では、機能的に同等です。

于 2012-09-02T13:18:36.110 に答える
3

cudaMalloc()から取得した生のポインタthrust::device_ptrをusingに変換します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

于 2012-08-30T21:19:43.047 に答える