많은 초기 조건에 대한 초기 값 문제를 해결하기 위해 lorenz_parameters.cu 예제를 boost::odeint에서 수정하려고합니다. 이 프로그램은 segfaults, 나는 내 우연히 포인터를 integrate_adaptive()
의 호출에 전달하여 파생물을 저장하기위한 벡터의 크기를 인쇄하려고 할 때 발생한다고 믿습니다.추력 및 부스트 조합 odeint; 잘못된 포인터 전달 segfault를 일으킬 것으로 생각했습니다
참고로 여기에 documentation for the example 및 code for the same examples이 있습니다 (어떤 이유로 원본 문서의 코드 링크가 작동하지 않음).
아래에는 프로그램의 전체 소스 코드가 첨부되어 있습니다. UNEXPECTED OUTPUT!
으로 표시된 줄이 있는데, 여기에서 파생 벡터의 크기를 인쇄하려고 시도하고 상태 벡터 (512)와 동일한 크기 여야하는 0으로 표시됩니다. LINE I DO NOT UNDERSTAND
이라고 표시된 줄이 있는데, 나는 이것이 내가 잘못 생각하고있는 부분 일 것이라고 생각합니다. 이 줄은 intergrate_adaptive()에 대한 호출의 일부이며이 인수는 parallel_initial_condition_problem
의 operator()
함수에 전달됩니다 (결국/odeint 패키지를 통해 전달되는 것입니다). 그러나 나는 그 예에서와 똑같이하려고 노력하고 있지만, 아직 효과가 없습니다. 어떤 도움이라도 대단히 감사합니다!
#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)
감사합니다. 귀하의 의견에 내가 어떤 버전의 odeint를 설치했는지 확인할 수있었습니다. 1.54 (우분투의 libboost-all-dev 패키지의 현재 기본값)였습니다. 나는 위에서 언급 한 #include뿐만 아니라 최신 버전을 다운로드하여 포함 시켰습니다. 나는'thrust_algebra' 또는'thrust_operations'를 추가했으나 작동시킬 필요가없는 것으로 보입니다. 고맙습니다! – weemattisnot
부스트 1.55를 사용한다면'thrust_algebra'와'thrust_operations'을 추가해야합니다. 컴파일되거나 실행될 수도 있지만 GPU를 사용하지는 않습니다. 자동 대수와 연산을 github 버전 odeint와 다음 부스트 릴리스 (v 1.56)에 추가했습니다. – headmyshoulder