Commit 03e487a0 authored by Ferhat Mihoubi's avatar Ferhat Mihoubi
Browse files

Major update of bytecode:

 - Iterative linear solvers using CUDA
 - interpreter.cc decomposed
parent 7a8b4073
noinst_PROGRAMS = bytecode
bytecode_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/../../sources/bytecode -I$(top_srcdir)/../../../preprocessor
bytecode_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/../../sources -I$(top_srcdir)/../../sources/bytecode -I$(top_srcdir)/../../../preprocessor
TOPDIR = $(top_srcdir)/../../sources/bytecode
......@@ -9,8 +9,10 @@ nodist_bytecode_SOURCES = \
$(TOPDIR)/Interpreter.cc \
$(TOPDIR)/Mem_Mngr.cc \
$(TOPDIR)/SparseMatrix.cc \
$(TOPDIR)/Evaluate.cc \
$(TOPDIR)/Interpreter.hh \
$(TOPDIR)/Mem_Mngr.hh \
$(TOPDIR)/SparseMatrix.hh \
$(TOPDIR)/Evaluate.hh \
$(TOPDIR)/ErrorHandling.hh
......@@ -23,24 +23,138 @@
#include <cstring>
#include <iostream>
#include <sstream>
#include <map>
#define BYTE_CODE
#include "CodeInterpreter.hh"
#ifdef DEBUG_EX
# include <math>
# include <math.h>
# include "mex_interface.hh"
#endif
#ifdef OCTAVE_MEX_FILE
# define CHAR_LENGTH 1
#else
# define CHAR_LENGTH 2
#endif
#ifdef _MSC_VER
#include <limits>
#define M_E 2.71828182845904523536
#define M_LOG2E 1.44269504088896340736
#define M_LOG10E 0.434294481903251827651
#define M_LN2 0.693147180559945309417
#define M_LN10 2.30258509299404568402
#define M_PI 3.14159265358979323846
#define M_PI_2 1.57079632679489661923
#define M_PI_4 0.785398163397448309616
#define M_1_PI 0.318309886183790671538
#define M_2_PI 0.636619772367581343076
#define M_1_SQRTPI 0.564189583547756286948
#define M_2_SQRTPI 1.12837916709551257390
#define M_SQRT2 1.41421356237309504880
#define M_SQRT_2 0.707106781186547524401
#define NAN numeric_limits<double>::quiet_NaN()
#define isnan(x) _isnan(x)
#define isinf(x) (!_finite(x))
#define fpu_error(x) (isinf(x) || isnan(x))
class MSVCpp_missings
{
public:
inline double
asinh(double x) const
{
if(x==0.0)
return 0.0;
double ax = abs(x);
return log(x+ax*sqrt(1.+1./(ax*ax)));
}
inline double
acosh(double x) const
{
if(x==0.0)
return 0.0;
double ax = abs(x);
return log(x+ax*sqrt(1.-1./(ax*ax)));
}
inline double
atanh(double x) const
{
return log((1+x)/(1-x))/2;
}
inline double
erf(double x) const
{
const double a1 = -1.26551223, a2 = 1.00002368,
a3 = 0.37409196, a4 = 0.09678418,
a5 = -0.18628806, a6 = 0.27886807,
a7 = -1.13520398, a8 = 1.48851587,
a9 = -0.82215223, a10 = 0.17087277;
double v = 1;
double z = abs(x);
if (z <= 0)
return v;
double t = 1 / (1 + 0.5 * z);
v = t*exp((-z*z) +a1+t*(a2+t*(a3+t*(a4+t*(a5+t*(a6+t*(a7+t*(a8+t*(a9+t*a10)))))))));
if (x < 0)
v = 2 - v;
return 1 - v;
}
inline double
nearbyint(double x) const
{
return floor(x + 0.5);
}
inline double
fmax(double x, double y) const
{
if (x > y)
return x;
else
return y;
}
inline double
fmin(double x, double y) const
{
if (x < y)
return x;
else
return y;
}
};
#endif
//#define DEBUG
using namespace std;
const int NO_ERROR_ON_EXIT = 0;
const int ERROR_ON_EXIT = 1;
typedef vector<pair<Tags, void * > > code_liste_type;
typedef code_liste_type::const_iterator it_code_type;
class GeneralExceptionHandling
{
string ErrorMsg;
public:
#ifdef _MSC_VER_
~GeneralExceptionHandling()
{
FreeLibrary(hinstLib);
};
#endif
GeneralExceptionHandling(string ErrorMsg_arg) : ErrorMsg(ErrorMsg_arg)
{
};
......@@ -121,6 +235,16 @@ public:
};
};
class UserExceptionHandling : public GeneralExceptionHandling
{
double value;
public:
UserExceptionHandling() : GeneralExceptionHandling("Fatal error in bytecode:")
{
completeErrorMsg(" User break\n");
};
};
class FatalExceptionHandling : public GeneralExceptionHandling
{
public:
......@@ -133,16 +257,40 @@ public:
};
};
struct s_plan
{
string var, exo;
int var_num, exo_num;
vector<pair<int, double> > per_value;
};
#ifdef MATLAB_MEX_FILE
extern "C" bool utIsInterruptPending();
#else
#include <octave/oct.h>
#include <octave/unwind-prot.h>
#endif
#ifdef _MSC_VER
class ErrorMsg : public MSVCpp_missings
#else
class ErrorMsg
#endif
{
private:
bool is_load_variable_list;
public:
double *y, *ya;
int y_size;
double *T;
int nb_row_xd, nb_row_x, y_size;
int nb_row_xd, nb_row_x;
int y_kmin, y_kmax, periods;
double *x, *params;
double *u, *y, *ya;
double *u;
double *steady_y, *steady_x;
double *g2, *g1, *r;
double *g2, *g1, *r, *res;
vector<s_plan> splan, spfplan;
vector<mxArray *> jacobian_block, jacobian_other_endo_block, jacobian_exo_block, jacobian_det_exo_block;
map<unsigned int, double> TEF;
map<pair<unsigned int, unsigned int>, double > TEFD;
......@@ -150,11 +298,12 @@ public:
ExpressionType EQN_type;
it_code_type it_code_expr;
unsigned int nb_endo, nb_exo, nb_param;
/*unsigned int*/size_t nb_endo, nb_exo, nb_param;
char *P_endo_names, *P_exo_names, *P_param_names;
unsigned int endo_name_length, exo_name_length, param_name_length;
size_t/*unsigned int*/ endo_name_length, exo_name_length, param_name_length;
unsigned int EQN_equation, EQN_block, EQN_block_number;
unsigned int EQN_dvar1, EQN_dvar2, EQN_dvar3;
vector<pair<string, pair<SymbolType, unsigned int> > > Variable_list;
inline
ErrorMsg()
......@@ -169,6 +318,7 @@ public:
nb_param = mxGetM(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "param_names")));
param_name_length = mxGetN(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "param_names")));
P_param_names = (char *) mxGetPr(mxGetFieldByNumber(M_, 0, mxGetFieldNumber(M_, "param_names")));
is_load_variable_list = false;
}
inline string
......@@ -184,9 +334,9 @@ public:
else
{
if (str[i] == '$')
pos1 = temp.length();
pos1 = int(temp.length());
else
pos2 = temp.length();
pos2 = int(temp.length());
if (pos1 >= 0 && pos2 >= 0)
{
tmp_n.erase(pos1, pos2-pos1+1);
......@@ -199,6 +349,50 @@ public:
return temp;
}
inline void
load_variable_list()
{
ostringstream res;
for (unsigned int variable_num = 0; variable_num < (unsigned int)nb_endo; variable_num++)
{
for (unsigned int i = 0; i < endo_name_length; i++)
if (P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)] != ' ')
res << P_endo_names[CHAR_LENGTH*(variable_num+i*nb_endo)];
Variable_list.push_back(make_pair(res.str(), make_pair(eEndogenous, variable_num)));
}
for (unsigned int variable_num = 0; variable_num < (unsigned int)nb_exo; variable_num++)
{
for (unsigned int i = 0; i < exo_name_length; i++)
if (P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)] != ' ')
res << P_exo_names[CHAR_LENGTH*(variable_num+i*nb_exo)];
Variable_list.push_back(make_pair(res.str(), make_pair(eExogenous, variable_num)));
}
}
inline int
get_ID(const string variable_name, SymbolType *variable_type)
{
if (!is_load_variable_list)
{
load_variable_list();
is_load_variable_list = true;
}
size_t n = Variable_list.size();
int i = 0;
bool notfound = true;
while (notfound && i < n)
{
if (variable_name == Variable_list[i].first)
{
notfound = false;
*variable_type = Variable_list[i].second.first;
return Variable_list[i].second.second;
}
i++;
}
return(-1);
}
inline string
get_variable(const SymbolType variable_type, const unsigned int variable_num) const
{
......@@ -293,7 +487,6 @@ public:
break;
default:
return ("???");
break;
}
else
switch (EQN_type)
......@@ -342,7 +535,6 @@ public:
break;
default:
return ("???");
break;
}
it_code_type it_code_ret;
Error_loc << endl << add_underscore_to_fpe(" " + print_expression(it_code_expr, evaluate, size, block_num, steady_state, Per_u_, it_, it_code_ret, true));
......@@ -378,6 +570,12 @@ public:
while (go_on)
{
#ifdef OCTAVE_MEX_FILE
OCTAVE_QUIT;
#else
if ( utIsInterruptPending() )
throw UserExceptionHandling();
#endif
switch (it_code->first)
{
case FNUMEXPR:
......@@ -441,7 +639,9 @@ public:
case eParameter:
var = ((FLDV_ *) it_code->second)->get_pos();
#ifdef DEBUG
mexPrintf("FLDV_ Param var=%d", var);
mexPrintf("FLDV_ Param var=%d\n", var);
mexPrintf("get_variable(eParameter, var)=%s\n",get_variable(eParameter, var).c_str());
mexEvalString("drawnow;");
#endif
Stack.push(get_variable(eParameter, var));
if (compute)
......@@ -451,7 +651,10 @@ public:
var = ((FLDV_ *) it_code->second)->get_pos();
lag = ((FLDV_ *) it_code->second)->get_lead_lag();
#ifdef DEBUG
mexPrintf("FLDV_ endo var=%d, lag=%d", var, lag);
mexPrintf("FLDV_ endo var=%d, lag=%d\n", var, lag);
mexPrintf("get_variable(eEndogenous, var)=%s, compute=%d\n",get_variable(eEndogenous, var).c_str(), compute);
mexPrintf("it_=%d, lag=%d, y_size=%d, var=%d, y=%x\n", it_, lag, y_size, var, y);
mexEvalString("drawnow;");
#endif
tmp_out.str("");
if (lag > 0)
......@@ -1250,7 +1453,7 @@ public:
Stack.pop();
if (compute)
{
int derivOrder = nearbyint(Stackf.top());
int derivOrder = int(nearbyint(Stackf.top()));
Stackf.pop();
if (fabs(v1f) < NEAR_ZERO && v2f > 0
&& derivOrder > v2f
......@@ -1570,7 +1773,11 @@ public:
}
tmp_out.str("");
tmp_out << function_name << "(";
#ifndef _MSC_VER
string ss[nb_input_arguments];
#else
vector<string> ss(nb_input_arguments);
#endif
for (unsigned int i = 0; i < nb_input_arguments; i++)
{
ss[nb_input_arguments-i-1] = Stack.top();
......@@ -1624,7 +1831,11 @@ public:
tmp_out.str("");
tmp_out << function_name << "(";
tmp_out << arg_func_name.c_str() << ", " << fc->get_row() << ", {";
#ifndef _MSC_VER
string ss[nb_add_input_arguments];
#else
vector<string> ss(nb_input_arguments);
#endif
for (unsigned int i = 0; i < nb_add_input_arguments; i++)
{
ss[nb_add_input_arguments-i-1] = Stack.top();
......@@ -1655,7 +1866,11 @@ public:
}
tmp_out.str("");
tmp_out << function_name << "(";
#ifndef _MSC_VER
string ss[nb_input_arguments];
#else
vector<string> ss(nb_input_arguments);
#endif
for (unsigned int i = 0; i < nb_input_arguments; i++)
{
ss[nb_input_arguments-i-1] = Stack.top();
......@@ -1708,7 +1923,11 @@ public:
tmp_out.str("");
tmp_out << function_name << "(";
tmp_out << arg_func_name.c_str() << ", " << fc->get_row() << ", " << fc->get_col() << ", {";
#ifndef _MSC_VER
string ss[nb_add_input_arguments];
#else
vector<string> ss(nb_input_arguments);
#endif
for (unsigned int i = 0; i < nb_add_input_arguments; i++)
{
ss[nb_add_input_arguments-i-1] = Stack.top();
......@@ -1739,7 +1958,11 @@ public:
}
tmp_out.str("");
tmp_out << function_name << "(";
#ifndef _MSC_VER
string ss[nb_input_arguments];
#else
vector<string> ss(nb_input_arguments);
#endif
for (unsigned int i = 0; i < nb_input_arguments; i++)
{
ss[nb_input_arguments-i-1] = Stack.top();
......@@ -1965,7 +2188,7 @@ public:
it_code++;
}
#ifdef DEBUG
mexPrintf("print_expression end\n"); mexEvalString("drawnow;");
mexPrintf("print_expression end tmp_out.str().c_str()=%s\n", tmp_out.str().c_str()); mexEvalString("drawnow;");
#endif
it_code_ret = it_code;
return (tmp_out.str());
......
This diff is collapsed.
......@@ -27,6 +27,7 @@
#define BYTE_CODE
#include "CodeInterpreter.hh"
#include "SparseMatrix.hh"
#include "Evaluate.hh"
#ifdef LINBCG
# include "linbcg.hh"
#endif
......@@ -40,50 +41,29 @@
using namespace std;
#define pow_ pow
class Interpreter : public SparseMatrix
class Interpreter : public dynSparseMatrix
{
private:
unsigned int EQN_dvar1, EQN_dvar2, EQN_dvar3;
int EQN_lag1, EQN_lag2, EQN_lag3;
mxArray *GlobalTemporaryTerms;
protected:
double pow1(double a, double b);
double divide(double a, double b);
double log1(double a);
double log10_1(double a);
void compute_block_time(int Per_u_, bool evaluate, int block_num, int size, bool steady_state);
void evaluate_a_block(const int size, const int type, string bin_basename, bool steady_state, int block_num,
const bool is_linear = false, const int symbol_table_endo_nbr = 0, const int Block_List_Max_Lag = 0, const int Block_List_Max_Lead = 0, const int u_count_int = 0, int block = -1);
int simulate_a_block(const int size, const int type, string file_name, string bin_basename, bool Gaussian_Elimination, bool steady_state, bool print_it, int block_num,
const bool is_linear = false, const int symbol_table_endo_nbr = 0, const int Block_List_Max_Lag = 0, const int Block_List_Max_Lead = 0, const int u_count_int = 0);
void print_a_block(const int size, const int type, string bin_basename, bool steady_state, int block_num,
const bool is_linear, const int symbol_table_endo_nbr, const int Block_List_Max_Lag,
const int Block_List_Max_Lead, const int u_count_int, int block);
void SingularDisplay(int Per_u_, bool evaluate, int Block_Count, int size, bool steady_state, it_code_type begining);
vector<Block_contain_type> Block_Contain;
code_liste_type code_liste;
it_code_type it_code;
int Block_Count, Per_u_, Per_y_;
int it_, maxit_, size_of_direction;
double solve_tolf;
bool GaussSeidel;
map<pair<pair<int, int>, int>, int> IM_i;
int equation, derivative_equation, derivative_variable;
string filename;
int minimal_solving_periods;
int stack_solve_algo, solve_algo;
bool global_temporary_terms;
bool print, print_error;
void evaluate_a_block();
int simulate_a_block();
void print_a_block();
public:
~Interpreter();
Interpreter(double *params_arg, double *y_arg, double *ya_arg, double *x_arg, double *steady_y_arg, double *steady_x_arg,
double *direction_arg, int y_size_arg, int nb_row_x_arg,
int nb_row_xd_arg, int periods_arg, int y_kmin_arg, int y_kmax_arg, int maxit_arg_, double solve_tolf_arg, int size_o_direction_arg,
double slowc_arg, int y_decal_arg, double markowitz_c_arg, string &filename_arg, int minimal_solving_periods_arg, int stack_solve_algo_arg, int solve_algo_arg,
bool global_temporary_terms_arg, bool print_arg, bool print_error_arg, mxArray *GlobalTemporaryTerms_arg);
bool compute_blocks(string file_name, string bin_basename, bool steady_state, bool evaluate, int block, int &nb_blocks, bool print_it);
double *direction_arg, size_t y_size_arg,
size_t nb_row_x_arg, size_t nb_row_xd_arg, int periods_arg, int y_kmin_arg, int y_kmax_arg,
int maxit_arg_, double solve_tolf_arg, size_t size_of_direction_arg, double slowc_arg, int y_decal_arg, double markowitz_c_arg,
string &filename_arg, int minimal_solving_periods_arg, int stack_solve_algo_arg, int solve_algo_arg,
bool global_temporary_terms_arg, bool print_arg, bool print_error_arg, mxArray *GlobalTemporaryTerms_arg,
bool steady_state_arg, bool print_it_arg
#ifdef CUDA
, const int CUDA_device, cublasHandle_t cublas_handle_arg, cusparseHandle_t cusparse_handle_arg, cusparseMatDescr_t descr_arg
#endif
);
bool compute_blocks(string file_name, string bin_basename, bool evaluate, int block, int &nb_blocks);
inline mxArray *
get_jacob(int block_num)
{
......
This diff is collapsed.
......@@ -19,21 +19,62 @@
#ifndef SPARSEMATRIX_HH_INCLUDED
#define SPARSEMATRIX_HH_INCLUDED
#define PRINTF_ printf
#include <fstream>
#include <stack>
#include <cmath>
#include <map>
#include <ctime>
#include "dynblas.h"
#if !(defined _MSC_VER)
#include "dynumfpack.h"
#endif
#ifdef OCTAVE_MEX_FILE
# define CHAR_LENGTH 1
#else
# define CHAR_LENGTH 2
#ifdef CUDA
#include "cuda.h"
#include "cuda_runtime_api.h"
#include "cublas_v2.h"
#include "cusparse_v2.h"
#endif
#include "Mem_Mngr.hh"
#include "ErrorHandling.hh"
//#include "Interpreter.hh"
#include "Evaluate.hh"
#define cudaChk(x, y) \
{ \
cudaError_t cuda_error = x; \
if (cuda_error != cudaSuccess) \
{ \
ostringstream tmp; \
tmp << y; \
throw FatalExceptionHandling(tmp.str()); \
} \
};
#define cusparseChk(x, y) \
{ \
cusparseStatus_t cusparse_status = x; \
if (cusparse_status != CUSPARSE_STATUS_SUCCESS) \
{ \
ostringstream tmp; \
tmp << y; \
throw FatalExceptionHandling(tmp.str()); \
} \
};
#define cublasChk(x, y) \
{ \
cublasStatus_t cublas_status = x; \
if (cublas_status != CUBLAS_STATUS_SUCCESS) \
{ \
ostringstream tmp; \
tmp << y; \
throw FatalExceptionHandling(tmp.str()); \
} \
};
#define NEW_ALLOC
#define MARKOVITZ
......@@ -53,41 +94,76 @@ const int IFLDZ = 4;
const int IFMUL = 5;
const int IFSTP = 6;
const int IFADD = 7;
const double eps = 1e-10;
const double eps = 1e-15;
const double very_big = 1e24;
const int alt_symbolic_count_max = 1;
const double mem_increasing_factor = 1.1;
class SparseMatrix : public ErrorMsg
class dynSparseMatrix : public Evaluate
{
public:
SparseMatrix();
void Simulate_Newton_Two_Boundaries(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, int periods, bool print_it, bool cvg, int &iter, int minimal_solving_periods, int stack_solve_algo, unsigned int endo_name_length, char *P_endo_names) /*throw(ErrorHandlingException)*/;
bool Simulate_Newton_One_Boundary(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, bool print_it, bool cvg, int &iter, bool steady_state, int stack_solve_algo, int solve_algo);
void Direct_Simulate(int blck, int y_size, int it_, int y_kmin, int y_kmax, int Size, int periods, bool print_it, int iter);
#if (defined _MSC_VER)
typedef int64_t SuiteSparse_long;
#endif
dynSparseMatrix();
dynSparseMatrix(const int y_size_arg, const int y_kmin_arg, const int y_kmax_arg, const bool print_it_arg, const bool steady_state_arg, const int periods_arg, const int minimal_solving_periods_arg
#ifdef CUDA
,const int CUDA_device_arg, cublasHandle_t cublas_handle_arg, cusparseHandle_t cusparse_handle_arg, cusparseMatDescr_t descr_arg
#endif
);
void Simulate_Newton_Two_Boundaries(int blck, int y_size, int y_kmin, int y_kmax, int Size, int periods, bool cvg, int minimal_solving_periods, int stack_solve_algo, unsigned int endo_name_length, char *P_endo_names);
void Simulate_Newton_One_Boundary(bool forward);
void fixe_u(double **u, int u_count_int, int max_lag_plus_max_lead_plus_1);
void Read_SparseMatrix(string file_name, const int Size, int periods, int y_kmin, int y_kmax, bool steady_state, bool two_boundaries, int stack_solve_algo, int solve_algo);
void Read_SparseMatrix(string file_name, const int Size, int periods, int y_kmin, int y_kmax, bool two_boundaries, int stack_solve_algo, int solve_algo);
void Read_file(string file_name, int periods, int u_size1, int y_size, int y_kmin, int y_kmax, int &nb_endo, int &u_count, int &u_count_init, double *u);