2015-10-15 54 views
1

我可以使用inclusive_scan作爲cpu上的數組,但是可以使用gpu上的數組來做到這一點嗎? (評論是我知道的作品的方式,但我不需要)。或者,還有其他簡單的方法可以對設備內存中的陣列執行全面掃描嗎?將cuda數組傳遞給thrust :: inclusive_scan

代碼:

#include <stdio.h> 
#include <stdlib.h> /* for rand() */ 
#include <unistd.h> /* for getpid() */ 
#include <time.h> /* for time() */ 
#include <math.h> 
#include <assert.h> 
#include <iostream> 
#include <ctime> 
    #include <thrust/scan.h> 
#include <cuda.h> 



#ifdef DOUBLE 
#define REAL double 
#define MAXT 256 
#else 
#define REAL float 
#define MAXT 512 
#endif 

#ifndef MIN 
#define MIN(x,y) ((x < y) ? x : y) 
#endif 

using namespace std; 

bool errorAsk(const char *s="n/a") 
{ 
cudaError_t err=cudaGetLastError(); 
if(err==cudaSuccess) 
    return false; 
printf("CUDA error [%s]: %s\n",s,cudaGetErrorString(err)); 
return true; 
}; 

double *fillArray(double *c_idata,int N,double constant) { 
    int n; 
    for (n = 0; n < N; n++) { 
      c_idata[n] = constant*floor(drand48()*10); 

    } 
return c_idata; 
} 

int main(int argc,char *argv[]) 
{ 
    int N,blocks,threads; 
    N = 100; 
    threads=MAXT; 
    blocks=N/threads+(N%threads==0?0:1); 

    double *c_data,*g_data; 

    c_data = new double[N]; 
    c_data = fillArray(c_data,N,1); 
    cudaMalloc(&g_data,N*sizeof(double)); 

    cudaMemcpy(g_data,c_data,N*sizeof(double),cudaMemcpyHostToDevice); 
    thrust::inclusive_scan(g_data, g_data + N, g_data); // in-place scan 
    cudaMemcpy(c_data,g_data,N*sizeof(double),cudaMemcpyDeviceToHost); 

//  thrust::inclusive_scan(c_data, c_data + N, c_data); // in-place scan 

    for(int i = 0; i < N; i++) { 
      cout<<c_data[i]<<endl; 
    } 
} 

回答

3

如果你讀了thrust quick start guide,你會發現一個建議處理「原始」設備數據:使用thrust::device_ptr

你可能不知道何時會發生什麼「原始「指針被用作Thrust函數的參數。和STL一樣,Thrust也允許這種用法,它將調度算法的主機路徑。如果有問題的指針實際上是指向設備內存的指針,那麼在調用該函數之前,您需要用thrust :: device_ptr來包裝它。

要解決你的代碼,你會想

#include <thrust/device_ptr.h> 

,並與下面兩行替換現有呼叫thrust::inclusive_scan

thrust::device_ptr<double> g_ptr = thrust::device_pointer_cast(g_data); 
thrust::inclusive_scan(g_ptr, g_ptr + N, g_ptr); // in-place scan 

另一種方法是使用推力execution policies並修改您的電話:

thrust::inclusive_scan(thrust::device, g_data, g_data + N, g_data); 

還有其他各種可能性。