2012-03-13 70 views
0

我试图寻找最小元件在一定的CUDA阵列查找cudaMalloc'ed阵列的最小元素位置通过推力:: min_element

float *p; 
...  
thrust::device_ptr<float> pWrapper(p);  
thrust::device_ptr<float> pos = 
       thrust::min_element(pWrapper, pWrapper + MAXX * MAXY, thrust::minimum<float>()); 

p是线性的设备存储器,并且pWrapperthrust::device_ptr

当我使用device_vector,很容易通过

min_element(someDeviceVector) - someDeviceVector.begin() 

相反,当提供给min_element呼叫类型为device_ptr,则min_element的返回类型寻找最小元素的位置是float *p(根据device_vector的定义模板)。从我刚刚提供的代码片断中,我无法确定最小值的位置以及如何从数组中提取它。

我试图从min_element的返回类型中减去ppWrapper的地址,但都没有成功。

+1

不要使用'''推力::这里minimum'''。你需要'''thrust @ less'''(或者什么都不用,'''thrust :: less'''是默认的)。 – 2012-03-13 18:16:10

回答

2

我刚刚发现我只需要在min_element输出结果上使用*运算符。

0

在你的文章中,当你有一个cudaMalloc'ed数组,并且你想通过thrust::min_element找到它的最小元素的位置和值时,你正在考虑一个非常常见的情况。下面,我提供了一个完整的例子,希望对其他用户有用。

基本上,下面的解决方案共享围绕cudaMalloc'ed线性内存环绕thrust::device_ptr的相同想法。但是,该位置可通过thrust::distance找到。

下面是完整的代码:

#include <thrust/device_vector.h> 
#include <thrust/extrema.h> 

/********************/ 
/* CUDA ERROR CHECK */ 
/********************/ 
#define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); } 
inline void gpuAssert(cudaError_t code, char *file, int line, bool abort=true) 
{ 
    if (code != cudaSuccess) 
    { 
     fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line); 
     if (abort) exit(code); 
    } 
} 

/********/ 
/* MAIN */ 
/********/ 
int main() { 

    const int N = 16; 

    srand(time(NULL)); 

    // --- Host side memory allocation and initialization 
    float *h_A = (float*)malloc(N * sizeof(float)); 
    for (int i=0; i<N; i++) h_A[i] = rand(); 

    // --- Device side memory allocation and initialization 
    float *d_A; gpuErrchk(cudaMalloc((void**)&d_A, N * sizeof(float))); 
    gpuErrchk(cudaMemcpy(d_A, h_A, N * sizeof(float), cudaMemcpyHostToDevice)); 

    thrust::device_ptr<float> dp = thrust::device_pointer_cast(d_A); 
    thrust::device_ptr<float> pos = thrust::min_element(dp, dp + N); 

    unsigned int pos_index = thrust::distance(dp, pos); 
    float min_val; 
    gpuErrchk(cudaMemcpy(&min_val, &d_A[pos_index], sizeof(float), cudaMemcpyDeviceToHost)); 

    for (int i=0; i<N; i++) printf("d_A[%i] = %f\n", i, h_A[i]); 
    printf("\n"); 
    printf("Position of the minimum element = %i; Value of the minimum element = %f\n", thrust::distance(dp, pos), min_val); 

    cudaDeviceReset(); 

    return 0; 
}