1

我正在尝试创建一个简单的程序来熟悉 Thrusts 的 GPU 计算能力和 odeint 的 ODE 求解能力。我希望能够在 GPU 上使用 Runge-Kutta 方法解决简单的 ODE(即 dy/dx = 3x^2y),希望以后可以解决更复杂的问题。我可以使用 odeint 相对轻松地做到这一点:

#include <boost/lambda/lambda.hpp>
#include <boost/numeric/odeint.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>

using namespace boost::numeric::odeint;
using namespace std;

typedef std::vector<double> state_type;

void sys( state_type &y, state_type &dydx, double x){
    dydx[0] = 3*x*x*y[0];                           // dydx = 3*x^2*y
}

int main(){
    state_type y(3);
    runge_kutta4< state_type > rk4;
    y[0] = 2;                                       // y0 = 2

    double x = 1;                                   // x0 = 1
    double h = 0.1;                                 // h = 0.1
    for (int i = 0; i < 100; i++,x+=h){
        rk4.do_step(sys,y,x,h);
        cout << "(";
        cout << x+h;
        cout << ",";
        cout << y[0]; 
        cout << ")";
        cout << endl;
    }

}

然而,我在理解推力如何发挥作用时遇到了麻烦。我遇到的大多数在线资源都以洛伦兹参数研究为例,但我觉得这对于我目前的水平来说太高级了。

我了解设备和主​​机向量的概念,但我不明白我的问题将如何适应使用 GPU 来解决。根据我自己的研究,我已经能够使用 CUDA(非推力)求解简单的代数(非微分)方程。然而,事实证明,结合我对 odeint 和推力的知识比我预期的要困难。

特别是,我对以下内容感到困惑:

1) 调整 Runge-Kutta 步进器

2) 适配系统函数本身(本例中为dydx = 3*x*x*y[0])。

3) 在程序中同时包含 odeint 和 Thrust/boost 目录

如果这个问题太基本或要求太多,我深表歉意;我是 StackOverflow 的新手,还没有学会所有的“提问”协议,也没有学会自己尝试解决问题的程度。

4

1 回答 1

1

这个问题有点令人困惑。如果你想使用 GPU,你通常有大型的微分方程系统。只有三个变量通常是不够的。GPU 上的一条指令很慢,但它可以在一条指令中并行执行许多操作。Thrust 旨在处理大型数据结构,例如在 GPU 上具有许多条目的向量。

要简短地回答您的问题,您需要

  1. thrust_algebra和添加thrust_operations到您的 RK 步进器的定义中
  2. 用推力实现系统功能,这是最困难的一步,以及
  3. 添加#include <boost/numeric/odeint.hpp>#include <boost/numeric/odeint/external/thrust.hpp>到您的源文件。当然,您还需要链接 CUDA 库并使用nvcc. odeint 的示例目录中的 makefile 显示了它是如何工作的。
于 2016-04-11T15:49:32.730 回答