使用 CUDA Thrust 查找最大元素值及其位置

发布于 2024-12-08 20:47:09 字数 344 浏览 0 评论 0原文

如何不仅获取值,还获取最大(最小)元素(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>());

How do I get not only the value but also the position of the maximum (minimum) element (res.val and res.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>());

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

千鲤 2024-12-15 20:47:09

不要使用 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——您将无法安全地取消引用结果。

Don't use thrust::reduce. Use thrust::max_element (thrust::min_element) in thrust/extrema.h:

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;

Be careful when passing an empty range to max_element -- you won't be able to safely dereference the result.

滴情不沾 2024-12-15 20:47:09

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

这个想法是将 device_pointer dev_ptr 包裹在 cudaMalloc 的原始指针周围,转换 min_element 的输出(我正在考虑 device_pointer min_ptr 的最小值而不是最大值(不失一般性),然后找到最小值作为 min_ptr[0]以及 &min_ptr[0] - &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]);

}

Jared Hoberock has already satisfactorily answered this question. I want to provide below a slight change to account for the common case when the array has been allocated by cudaMalloc and not through a device_vector container.

The idea is to wrap a device_pointer dev_ptr around the cudaMalloc'ed raw pointer, casting the output of min_element (I'm considering the minimum instead of the maximum without any loss of generality) to a device_pointer min_ptr and then finding the minimum value as min_ptr[0] and the position by &min_ptr[0] - &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]);

}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文