如何解决为什么多次调用curand时我的代码会失败?
当我将numPaths增加到1000000时,除非除非同时减少numSteps,否则下面的蒙特卡洛代码将失败(“进程退出,代码为-2147483645,价格函数的输出未打印)。”如果删除所有对curand的引用并使用固定数字,则代码始终有效,因此我认为问题与生成太多随机数有关。我尝试用每个线程(而不是新的子序列)的新种子调用curand_init,但是它不能解决问题。
此外,在使用“推力”而不是“ curand”生成随机数时,我也遇到了相同的问题。
有人可以帮忙吗?
#include <math.h>
#include <curand_kernel.h>
#include "cuda_runtime.h"
#include <thrust/device_vector.h>
#include <thrust/reduce.h>
#include <thrust/transform_reduce.h>
#include <thrust/transform.h>
#include <thrust/functional.h>
#include <thrust/iterator/transform_iterator.h>
#include <thrust/iterator/counting_iterator.h>
#include <thrust/iterator/zip_iterator.h>
#include <device_launch_parameters.h>
#include <thrust/execution_policy.h>
using State3D = thrust::tuple<double,double,double>;
template<typename State>
struct AbstractModel : public thrust::binary_function<State,int,State>
{
private:
double seed = 0;
int numSteps;
public:
double dt,sqdt;
AbstractModel(double T,int numSteps)
: numSteps(numSteps),dt(T / numSteps),sqdt(sqrt(T / numSteps)) {}
__device__ virtual void nextStep(State& state,curandState &rand_state) const = 0;
__device__ State operator() (const State &state,const int &i) const
{
curandState rand_state;
curand_init(seed,i,&rand_state);
State currentState = state;
for (unsigned i = 0; i < numSteps; i++)
nextStep(currentState,rand_state);
return currentState;
}
};
struct Model : public AbstractModel<State3D>
{
double lambda,m,w,theta,eta;
Model(double T,int numSteps,double lambda,double m,double w,double theta,double eta)
: AbstractModel(T,numSteps),lambda(lambda),m(m),w(w),theta(theta),eta(eta) {}
__device__ void nextStep(State3D &state,curandState &rand_state) const
{
double level = fmax(state.get<2>(),0.0),sqlevel = sqrt(level),vol = lambda * sqlevel;
state.get<0>() += vol * sqdt * curand_normal_double(&rand_state);
state.get<1>() += vol * vol * dt;
state.get<2>() += theta * (1.0 - level) * dt + eta * sqlevel * sqdt * curand_normal_double(&rand_state);
}
};
struct ModelInitializer : public thrust::unary_function<int,State3D>
{
__device__ State3D operator() (const int idx) const
{
return thrust::make_tuple<double,double>(0.0,0.0,0.0);
}
};
struct ModelPayoffTest : public thrust::unary_function<thrust::tuple<double,double>,double>
{
double operator()(const thrust::tuple<double,double> &state) const
{
return state.get<2>();
}
};
template<typename Model,typename Payoff>
double price(unsigned numPaths,Model &model,Payoff &payoff)
{
thrust::device_vector<State3D> markov_states(numPaths);
//initialize paths with start value
thrust::transform(thrust::make_counting_iterator(0),thrust::make_counting_iterator(0) + numPaths,markov_states.begin(),ModelInitializer()/*model*/);
//diffuse paths
thrust::transform(markov_states.begin(),markov_states.end(),thrust::make_counting_iterator(0)/*rand_states.begin()*/,model);
return thrust::transform_reduce(markov_states.begin(),payoff,thrust::plus<double>()) / numPaths;
}
int main()
{
double lambda = 0.05,m = 20,w = 0.5,theta = 0.05,eta = 0.1;
double T = 10;
int numSteps = 10 * 365;
Model cheyette(T,numSteps,lambda,eta);
ModelPayoffTest payoff;
int numPaths = 100000;
std::cout << price<Model,ModelPayoffTest>(numPaths,cheyette,payoff) << "\n";
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。