【问题标题】:Finding the maximum element value AND its position using CUDA Thrust使用 CUDA Thrust 查找最大元素值及其位置
【发布时间】:2023-03-26 11:52:01
【问题描述】:

如何不仅获取值,还获取最大(最小)元素(res.valres.pos)的位置?

thrust::host_vector<float> h_vec(100);
thrust::generate(h_vec.begin(), h_vec.end(), rand);
thrust::device_vector<float> d_vec = h_vec;

T res = -1;
res = thrust::reduce(d_vec.begin(), d_vec.end(), res, thrust::maximum<T>());

【问题讨论】:

    标签: cuda thrust


    【解决方案1】:

    Jared Hoberock 已经令人满意地回答了这个问题。当数组由cudaMalloc 分配而不是通过device_vector 容器分配时,我想在下面提供一个细微的更改来解释常见情况。

    这个想法是在cudaMalloc'ed 原始指针周围包裹一个device_pointerdev_ptr,将min_element 的输出(我正在考虑最小值而不是最大值而不失一般性)到device_pointer min_ptr 然后找到最小值为min_ptr[0]&amp;min_ptr[0] - &amp;dev_ptr[0] 的位置。

    #include "cuda_runtime.h"
    #include "device_launch_paraMeters.h"
    
    #include <thrust\device_vector.h>
    #include <thrust/extrema.h>
    
    /***********************/
    /* CUDA ERROR CHECKING */
    /***********************/
    #define gpuErrchk(ans) { gpuAssert((ans), __FILE__, __LINE__); }
    inline void gpuAssert(cudaError_t code, const 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() {
    
        srand(time(NULL));
    
        const int N = 10;
    
        float *h_vec = (float *)malloc(N * sizeof(float));
        for (int i=0; i<N; i++) {
            h_vec[i] = rand() / (float)(RAND_MAX);
            printf("h_vec[%i] = %f\n", i, h_vec[i]);
        }
    
        float *d_vec; gpuErrchk(cudaMalloc((void**)&d_vec, N * sizeof(float)));
        gpuErrchk(cudaMemcpy(d_vec, h_vec, N * sizeof(float), cudaMemcpyHostToDevice));
    
        thrust::device_ptr<float> dev_ptr = thrust::device_pointer_cast(d_vec);
    
        thrust::device_ptr<float> min_ptr = thrust::min_element(dev_ptr, dev_ptr + N);
    
        float min_value = min_ptr[0];
        printf("\nMininum value = %f\n", min_value);
        printf("Position = %i\n", &min_ptr[0] - &dev_ptr[0]);
    
    }
    

    【讨论】:

      【解决方案2】:

      不要使用thrust::reduce。在thrust/extrema.h 中使用thrust::max_element (thrust::min_element):

      thrust::host_vector<float> h_vec(100);
      thrust::generate(h_vec.begin(), h_vec.end(), rand);
      thrust::device_vector<float> d_vec = h_vec;
      
      thrust::device_vector<float>::iterator iter =
        thrust::max_element(d_vec.begin(), d_vec.end());
      
      unsigned int position = iter - d_vec.begin();
      float max_val = *iter;
      
      std::cout << "The maximum value is " << max_val << " at position " << position << std::endl;
      

      将空范围传递给max_element 时要小心——您将无法安全地取消引用结果。

      【讨论】:

      • 如何取消引用主机中的设备迭代器?推力是否具有执行 cudaMemcpy 的隐式取消引用运算符?
      猜你喜欢
      • 2023-04-11
      • 2018-11-22
      • 2020-07-06
      • 1970-01-01
      • 1970-01-01
      • 2019-12-28
      • 1970-01-01
      • 2016-01-18
      相关资源
      最近更新 更多