Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/138.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用CUDA的最大绝对差_C++_Cuda_Thrust - Fatal编程技术网

C++ 使用CUDA的最大绝对差

C++ 使用CUDA的最大绝对差,c++,cuda,thrust,C++,Cuda,Thrust,我们有下面的串行C代码在 两个向量a[]和b[]: double a[20000],b[20000],r=0.9; for(int i=1;i<=10000;++i) { a[i]=r*a[i]+(1-r)*b[i]]; errors=max(errors,fabs(a[i]-b[i]); b[i]=a[i]; } 请告诉我们如何将此代码移植到CUDA和cublas?循环中的第二行: errors=max(errors,fabs(a[i]-b[i]); 这就是

我们有下面的串行C代码在

两个向量a[]和b[]:

double a[20000],b[20000],r=0.9;

for(int i=1;i<=10000;++i)
{
    a[i]=r*a[i]+(1-r)*b[i]];
    errors=max(errors,fabs(a[i]-b[i]);
    b[i]=a[i];
}

请告诉我们如何将此代码移植到CUDA和cublas?

循环中的第二行:

errors=max(errors,fabs(a[i]-b[i]);
这就是所谓的减量。幸运的是,CUDA SDK中有简化示例代码——请看一下,并将其用作算法的模板


您可能希望将其拆分为两个单独的操作,可能作为两个单独的内核—一个用于并行部分计算bp[]值,另一个用于减少计算错误。

也可以使用推力::转换\u减少来实现推力的减少。此解决方案融合了整个操作,正如Talonmes建议的那样:

#include <thrust/device_vector.h>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/transform_reduce.h>
#include <thrust/functional.h>

// this functor unpacks a tuple and then computes
// a weighted absolute difference of its members
struct weighted_absolute_difference
{
  double r;

  weighted_absolute_difference(const double r)
    : r(r)
  {}

  __host__ __device__
  double operator()(thrust::tuple<double,double> t)
  {
    double a = thrust::get<0>(t);
    double b = thrust::get<1>(t);

    a = r * a + (1.0 - r) * b;

    return fabs(a - b);
  }
};

int main()
{
  using namespace thrust;

  const std::size_t n = 20000;

  const double r = 0.9;

  device_vector<double> a(n), b(n);

  // initialize a & b
  ...

  // do the reduction
  double result =
    transform_reduce(make_zip_iterator(make_tuple(a.begin(), b.begin())),
                     make_zip_iterator(make_tuple(a.end(),   b.end())),
                     weighted_absolute_difference(r),
                     -1.f,
                     maximum<double>());

  // note that this solution does not set
  // a[i] = r * a[i] + (1 - r) * b[i]

  return 0;
}

注意,在这个解决方案中,我们不执行赋值a[i]=r*a[i]+1-r*b[i],尽管在使用推力::变换进行归约之后这样做很简单。在任何一个函子中修改transform\u reduce的参数都是不安全的。

为什么需要使用两个操作来完成?计算和归约可以安全地融合在一起——整个事情都是令人尴尬的并行。@Talonmes:因为OP显然是一个CUDA noob,我觉得使用CUDA SDK中的归约示例对错误进行归约会更容易,然后他们只需要对简单的并行部分进行简单的操作即可减少了。不一定是两个内核,虽然这可能会使调试更容易。很好的解决方案,只需要修复出现两次的a.end,其中第二个应该是b.end,并且要提到的是,结果是transform_reduce的返回值。