结合推力和增强的odeint;错误的指针传递被认为会导致段错误

时间:2014-07-24 15:58:51

标签: segmentation-fault thrust odeint

我正在尝试修改boost::odeint中的lorenz_parameters.cu示例,以解决许多初始条件的初始值问题。程序段错误,我认为这是由于我错误地将指针传递给integrate_adaptive()的调用引起的,因为当我尝试打印出用于存储导数的向量的大小时,它为0。

供参考,以下是documentation for the examplecode for the same examples(由于某种原因,原始文档中代码的链接不起作用)。

我已附上该程序的完整源代码。有一条标记为UNEXPECTED OUTPUT!的行,我尝试打印衍生向量的大小,它出现为0,它应该与状态向量(512)的大小相同。还有一条标记为LINE I DO NOT UNDERSTAND的行,我认为这可能是我做错了。这一行是对intergrate_adaptive()的调用的一部分,我认为这个参数是(最终/通过odeint包)传递给operator()中的parallel_initial_condition_problem函数的内容。但我试图像示例中那样做,但它不起作用。非常感谢任何帮助!

#include <iostream>
#include <vector>
#include <thrust/device_vector.h>
#include <boost/numeric/odeint.hpp>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <typeinfo>

typedef double value_type;

//change this to device_vector< ... > of you want to run on GPU
typedef thrust::host_vector< value_type > state_type;

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

const size_t D = 16; // how many values of each initial condition to try
const size_t N_ICS = D * D; // number of initial conditions
const size_t N_VARS = 2; // number of variables in the system

// time constants
const value_type t_0 = 0.0;
const value_type t_final = 0.1;    
const value_type dt = 0.01;

struct parallel_initial_condition_problem {
  struct functor
  {
    template< class T >
    __host__ __device__
    void operator()( T t ) const
    {
      const value_type k_b = 0.45/6.0;
      const value_type k_f = 1.0;
      const value_type k_d = 1.0;

      // unpack the variables (and the parameters we want to vary, if any)
      value_type f = thrust::get< 0 >( t );
      value_type a = thrust::get< 1 >( t );
      // value_type df = thrust::get< 2 >( t ); // this also causes a segfault
      // value_type da = thrust::get< 3 >( t );
      // calculate the derivative
      thrust::get< 2 >( t ) = -0.01; // minimal value for debugging
      thrust::get< 3 >( t ) = -0.01; 
    }
  };

  parallel_initial_condition_problem( size_t N )
  : m_N( N ) { }

  template< class State , class Deriv >
  void operator()(const State &x , Deriv &dxdt , value_type t ) const
  {
    //// Printing out debugging info (here is the error..but why?)
    cout << "INSIDE operator()" << endl;
    cout << "t: " << t << endl;    
    cout << "size of x: \t" << boost::end(x) - boost::begin(x) << endl;
    cout << "size of dxdt: \t" << boost::end(dxdt) - boost::begin(dxdt) << endl; // UNEXPECTED OUTPUT!!
    cout << endl;

    thrust::for_each(
      thrust::make_zip_iterator( 
        thrust::make_tuple(
               boost::begin( x ) + 0*m_N,
               boost::begin( x ) + 1*m_N ,
               boost::begin( dxdt ) + 0*m_N,
               boost::begin( dxdt ) + 1*m_N
               )
                 ) ,
      thrust::make_zip_iterator( 
        thrust::make_tuple(
               boost::begin( x ) + 1*m_N,
               boost::begin( x ) + 2*m_N ,
               boost::begin( dxdt ) + 3*m_N,
               boost::begin( dxdt ) + 4*m_N
               )
                 ) ,
      functor() );
  }

  size_t m_N;
};

int main(int /* argc */ , char** /* argv */ ) {

  // x stores both (initial) state (x) [0:N_VARS*N_ICS] and dxdt [N_VARS*N_ICS:END]
  state_type x( 2 * N_VARS * N_ICS ); 

  // DUMMY INITIAL CONDITIONS FOR DEBUGGING PURPOSES
  // fill each value with its index
  for(int i=0;i<x.size();i++) {
    x[i] = 0.01+i;
  }

  // system function
  parallel_initial_condition_problem init_con_solver( N_ICS );

  //////////////////////////////// Debugging info: (all seems correct here)
  cout << "POINTERS"  << endl;
  cout << "size of x: " << boost::end(x) - boost::begin(x) << endl;
  cout << "x    :" << &(*x.begin()) << endl;
  cout << "dxdt :" << &(*x.begin()) + N_VARS*N_ICS << endl;
  cout << "end  :" << &(*x.end()) << endl;
  cout << endl;

  /////////////////////////// STATE_T      VALUE_T      DERIV_T      TIME_T
  typedef runge_kutta_dopri5< state_type , value_type , state_type , value_type > stepper_type;
  const value_type abs_err = 1.0e-6;
  const value_type rel_err = 1.0e-6;
  integrate_adaptive( make_controlled( abs_err , rel_err , stepper_type() ),
              init_con_solver ,
              std::make_pair( x.begin() , x.begin() + N_VARS*N_ICS  ), /// LINE I DO NOT UNDERSTAND
              t_0, t_final, dt );

}

运行它的输出是:

$ g++ main.c && ./a.out
POINTERS
size of x: 1024
x    :0x9a2010
dxdt :0x9a3010
end  :0x9a4010

INSIDE operator()
t: 0
size of x:  512
size of dxdt:   0

Segmentation fault (core dumped)

1 个答案:

答案 0 :(得分:1)

我认为有一些包括失踪。试试

#include <boost/numeric/odeint/external/thrust/thrust.hpp>

实际上我想知道,为什么你的代码甚至会编译。如果使用boost(1.55)中的当前odeint版本,还需要指定代数和操作类型:

typedef runge_kutta_dopri5<
    state_type ,
    value_type ,
    state_type ,
    value_type ,
    thrust_algebra ,
    thrust_operations > stepper_type;

这应该会在下一个版本中发生变化。对于oiint的gihub版本,您的代码应该没问题。