2016-04-10 103 views
1

我正在嘗試創建一個簡單的程序,以熟悉T​​hrusts的GPU計算能力和odeint的ODE解決能力。我希望能夠使用GPU上的Runge-Kutta方法來解決簡單的ODE(即dy/dx = 3x^2y),以期在稍後轉向更復雜的問題。我可以用odeint相對容易地做到這一點:如何使用C++中的Thrust和odeint解決簡單的ODE

#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; 
    } 

} 

但是,我很難理解如何發揮主導作用。我所遇到的大多數在線資源都以Lorenz參數研究爲例,但我覺得這是目前的水平。

我瞭解設備和主​​機矢量的概念,但我不明白我的問題將如何適應使用GPU解決。從我自己的研究中,我已經能夠使用CUDA(而非推力)解決簡單的代數(非微分)方程。然而,結合我的知識和推力被證明比我預期的更困難。

特別是,我感到困惑:

1)調整龍格 - 庫塔步進

2)調整系統函數本身(dydx = 3 * X * X * Y [0]在此例)。

3)包含兩種odeint和推力/升壓目錄到程序

我道歉,如果這個問題太基本或要價太高了;我是StackOverflow的新手,還沒有學會所有的「問題提問」協議,也沒有我自己應該嘗試解決這個問題。

回答

1

這個問題有點混亂。如果你想使用GPU,你通常會有大的微分方程組。只有三個變量通常是不夠的。 GPU上的一條指令很慢,但在一條指令期間它可以並行執行許多操作。 Thrust旨在處理大型數據結構,如GPU上具有許多條目的向量。

回答您的問題總之你需要

  1. 添加thrust_algebrathrust_operations給你定義RK步進
  2. 落實與推進系統功能這是最困難的一步,並
  3. #include <boost/numeric/odeint.hpp>#include <boost/numeric/odeint/external/thrust.hpp>添加到您的源文件。當然,您還需要鏈接到CUDA庫並使用nvcc編譯所有內容。在odeint的例子目錄中有makefile顯示這是如何工作的。