максимальная абсолютная разница с использованием CUDA - PullRequest
0 голосов
/ 23 ноября 2011

У нас есть следующий последовательный код 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

Ответы [ 2 ]

5 голосов
/ 24 ноября 2011

Также возможно реализовать это снижение тяги, используя thrust::transform_reduce. Это решение объединяет всю операцию, как предполагают talonmies:

#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] в этом решении, хотя было бы просто сделать это после сокращения, используя thrust::transform. Не безопасно изменять аргументы transform_reduce в любом функторе.

0 голосов
/ 23 ноября 2011

Эта вторая строка в вашем цикле:

errors=max(errors,fabs(a[i]-b[i]);

известна как сокращение .К счастью, в CUDA SDK есть пример кода сокращения - взгляните на это и используйте его в качестве шаблона для вашего алгоритма.

Возможно, вы захотите разделить его на две отдельные операции (возможно, как два отдельных ядра) -один для параллельной части (вычисление bp[] значений) и второй для сокращения (вычисление errors).

...