目标是使用thrust :: omp
并行化蒙特卡罗过程int main()
{
unsigned Nsimulations = 1000;
// construct some objects here that will be required for Monte Carlo
A a;
B b;
C c;
/*
* use thrust::omp to run the simulation Nsimulation times
* and write a custom reduction function (a sum for objects of type R)
*/
}
// this is the Monte Carlo function - it needs the global variables a, b, c
// passed by reference because they are very large; the return type is R
R monteCarlo(A& a, B& b, C& c)
{
// something supercomplicated here
return r;
}
我需要知道:
答案 0 :(得分:1)
正如我在your previous question中所说,你必须learn more about thrust才能回答这样的问题对你有任何意义。
你可以这样做:
thrust::generate(...);
to generate您的初始随机数。这里矢量的长度是你想要的模拟数量。
然后你可以这样做:
thrust::for_each(...);
传递先前生成的随机数向量作为输入,可能用结果向量压缩。 for_each operation将使用自定义函数来执行monteCarlo
例程,作为对输入向量中每个随机数元素的单独调用。每个输入元素的monteCarlo
例程的输出将进入结果向量中的相应位置。 A,B,C全局变量中的参数/数据可以通过引用作为初始化参数传递给for_each使用的仿函数。
然后你可以这样做:
thrust::reduce(...);
在先前生成的结果向量上,创建最终缩减。
我不会关心你想要做的模拟到OMP线程的映射。 Thrust会处理这个问题,正如#pragma omp parallel for
会在OMP案例中处理它一样。
这是一个完全有效的例子:
$ cat t536.cpp
#include <iostream>
#include <stdlib.h>
#include <thrust/system/omp/execution_policy.h>
#include <thrust/system/omp/vector.h>
#include <thrust/reduce.h>
#include <thrust/for_each.h>
#include <thrust/iterator/zip_iterator.h>
struct A {
unsigned a;
};
struct B {
int b;
};
struct C {
float c;
};
A a;
B b;
C c;
float monteCarlo(int rn){
return ((rn % a.a)+ b.b)/c.c;
}
struct my_functor
{
template <typename Tuple>
void operator()(const Tuple &data) const{
thrust::get<1>(data) = monteCarlo(thrust::get<0>(data));
}
};
int main(int argc, char *argv[]){
a.a = 10;
b.b = 2;
c.c = 4.5f;
unsigned N = 10;
if (argc > 1) N = atoi(argv[1]);
thrust::omp::vector<unsigned> rands(N);
thrust::omp::vector<float> result(N);
thrust::generate(thrust::omp::par, rands.begin(), rands.end(), rand);
thrust::for_each(thrust::omp::par, thrust::make_zip_iterator(thrust::make_tuple(rands.begin(), result.begin())), thrust::make_zip_iterator(thrust::make_tuple(rands.end(), result.end())), my_functor());
float answer = thrust::reduce(thrust::omp::par, result.begin(), result.end());
std::cout << answer << std::endl;
return 0;
}
$ g++ -O2 -I/usr/local/cuda/include -o t536 t536.cpp -fopenmp -lgomp
$ ./t536 10
14.8889
$
(答案应该在1.444 * N的数据类型限制内收敛,因为N变大,对于a,b,c的这些选择)
正如@JaredHoberock在你上一个问题中提到的那样,推力monte carlo example可能会引起人们的兴趣。它演示了操作的“融合”,以便类似的活动可以减少到单个推力调用。上述计划也可能减少到一个推力调用。