lambda - CUDA 推力快捷数学函数

标签 lambda cuda placeholder functor thrust

有没有办法将 CUDA 数学函数自动包装在仿函数中,以便人们可以应用 thrust::transform无需手动编写仿函数?类似于(我收集的)功能 std::function提供?
thrust::placeholders似乎不喜欢数学函数。std::function似乎不可用。

示例代码:

#include <thrust/transform.h>
#include <thrust/device_vector.h>
#include <iostream>
#include <functional>
#include <math.h>

struct myfunc{
    __device__ 
    double operator()(double x,double y){
    return hypot(x,y);
    }
};

int main(){

    double x0[10] = {3.,0.,1.,2.,3.,4.,5.,6.,7.,8.};
    double y0[10] = {4.,0.,1.,2.,3.,4.,5.,6.,7.,8.};

    thrust::device_vector<double> x(x0,x0+10);
    thrust::device_vector<double> y(y0,y0+10);
    thrust::device_vector<double> r(10);

    for (int i=0;i<10;i++) std::cout << x0[i] <<" ";    std::cout<<std::endl;
    for (int i=0;i<10;i++) std::cout << y0[i] <<" ";    std::cout<<std::endl;

    // this works:
    thrust::transform(x.begin(),x.end(),y.begin(),r.begin(), myfunc());

    // this doesn't compile:
    using namespace thrust::placeholders;
    thrust::transform(x.begin(),x.end(),y.begin(),r.begin(), hypot(_1,_2));

    // nor does this:
    thrust::transform(x.begin(),x.end(),y.begin(),r.begin(), std::function<double(double,double)>(hypot));


    for (int i=0;i<10;i++) std::cout << r[i] <<" ";    std::cout<<std::endl;
}

最佳答案

将我的评论转换为这个答案:

正如@JaredHoberock 已经说过的,没有自动的方法来实现你想要的。总是有一些语法/打字开销。

减少编写单独仿函数的这种开销的一种方法(就像您对 my_func 所做的那样)是使用 lambda。从 CUDA 7.5 开始,有一个 experimental device lambda feature这允许您执行以下操作:

auto h = []__device__(double x, double y){return hypot(x,y);};
thrust::transform(x.begin(),x.end(),y.begin(),r.begin(), h);

您需要添加以下 nvcc 编译器开关来编译它:
nvcc --expt-extended-lambda ...

另一种方法是使用以下 Wrapper 将函数转换为仿函数:
template<typename Sig, Sig& S>
struct Wrapper;

template<typename R, typename... T, R(&function)(T...)>
struct Wrapper<R(T...), function>
{
    __device__
    R operator() (T&... a)
    {
        return function(a...);
    }
};

然后你会像这样使用它:
 thrust::transform(x.begin(),x.end(),y.begin(),r.begin(), Wrapper<double(double,double), hypot>());

关于lambda - CUDA 推力快捷数学函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32871874/

相关文章:

c# - 编辑器占位符导致构建失败

Java8 Function apply 方法及其实现

java - 如何使用 java 8 将 Stream<Map<K,V>> 收集到 Map<K,List<V>> 中?

cuda内存对齐

debugging - 调试时共享内存问题

forms - 在 Prototype 中使用表单验证的 HTML5 表单占位符回退

c++ - 为什么这个 lambda 可以流式传输?

c++ - `for_each_arg` 的正确用法 - 转发过多?

CUDA:从内核调用 __device__ 函数

Vim Ultisnips - 如何移动到下一个占位符或制表符?