我正在尝试使用CUDA中的Thrust库进行一些科学模拟,但我陷入了以下操作,这基本上是for-each循环:
device_vector<float> In(N);
for-each In(x) in In
Out(x) = some_calculation(In(x-1),In(x),In(x+1));
end
我已经查询了stackoverflow.com并找到了一些类似的问题: Similar questions 1
但似乎只有当some_calculation函数在2个参数之间完成时才使用变换迭代器,因为变换迭代器最多传递两个参数。
然后,问题2: Similar questions 2
讨论结束时没有结论。
我认为这是一个简单的问题,因为它是并行计算的自然要求。任何人都可以告诉我该怎么做?
答案 0 :(得分:3)
花式迭代器是这种操作的关键,并不是那么直观。您可以使用ThisActivityName.this
创建值的元组然后可以迭代,因此对于典型的zip_iterator
类型函数,您可以得到如下内容:
f(x[i-1], x[i], x[i+1])
这里的仿函数一次处理一个元组,其中元组包含来自同一数组或迭代序列中三个不同起始点的三个输入。
编辑:显然将此代码的主机版本转换为使用设备构造对于原始海报证明是具有挑战性的,因此这里是使用#include <iostream>
#include <cmath>
#include <thrust/iterator/zip_iterator.h>
#include <thrust/tuple.h>
#include <thrust/transform.h>
struct divided_diff {
float dx;
divided_diff(float _dx) : dx(_dx) {};
float operator()(const thrust::tuple<float, float, float> &in) const {
float y0 = in.get<0>();
float y1 = in.get<1>();
float y2 = in.get<2>();
return (y0 - 2.f * y1 + y2) / (dx * dx);
}
};
int main() {
const int N = 10;
const float dx = 0.1f;
float x[N], y[N], dydx[N];
for (int i = 0; i < N; ++i) {
x[i] = dx * float(i);
y[i] = std::sin(x[i]);
dydx[i] = 0.f;
}
auto begin = thrust::make_zip_iterator(thrust::make_tuple(&y[0], &y[1], &y[2]));
auto end = thrust::make_zip_iterator(thrust::make_tuple(&y[N-2], &y[N-1], &y[N]));
divided_diff f(dx);
thrust::transform(begin, end, &dydx[1], f);
for (int i = 0; i < N; ++i) {
std::cout << i << " " << dydx[i] << std::endl;
}
return 0;
}
作为基本容器执行设备上所有内容的版本:
thrust::device_vector