通过thrust :: min_element找到cudaMalloc数组的最小元素位置

时间:2012-03-13 17:20:37

标签: cuda thrust

我试图找到某个CUDA数组中的最小元素

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的地址的返回类型中减去,但都没有效果。

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

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

基本上,下面的解决方案在thrust::device_ptr'线性内存周围包含cudaMalloc的想法相同。但是,该位置由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;
}