From 3783f05c710cb0c19ecacf82dc27fae1d1bd7f7f Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Tue, 21 Apr 2015 16:49:37 +0200 Subject: [PATCH 01/15] preprocessor: remove commented code --- DynamicModel.cc | 92 ------------------------------------------------- 1 file changed, 92 deletions(-) diff --git a/DynamicModel.cc b/DynamicModel.cc index 1de6bc8c..f4957557 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -261,8 +261,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const { int lag = it->first.first; unsigned int var = it->first.second.first; - //int eqr = getBlockInitialEquationID(block, eq); - //int varr = getBlockInitialVariableID(block, var); if (var != prev_var || lag != prev_lag) { prev_var = var; @@ -280,8 +278,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const { int lag = it->first.first; unsigned int var = it->first.second.first; - //int eqr = getBlockInitialEquationID(block, eq); - //int varr = getBlockInitialVariableID(block, var); if (var != prev_var || lag != prev_lag) { prev_var = var; @@ -299,8 +295,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const { int lag = it->first.first; unsigned int var = it->first.second.first; - //int eqr = getBlockInitialEquationID(block, eq); - //int varr = getBlockInitialVariableID(block, var); if (var != prev_var || lag != prev_lag) { prev_var = var; @@ -318,8 +312,6 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const { int lag = it->first.first; unsigned int var = it->first.second.first; - //int eqr = getBlockInitialEquationID(block, eq); - //int varr = getBlockInitialVariableID(block, var); if (var != prev_var || lag != prev_lag) { prev_var = var; @@ -2801,89 +2793,6 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de typedef pair > index_KF; vector v_index_KF; - - /* DO 170, J = 1, N - TEMP1 = ALPHA*A( J, J ) - DO 110, I = 1, M - C( I, J ) = TEMP1*B( I, J ) - 11 110 CONTINUE - DO 140, K = 1, J - 1 - TEMP1 = ALPHA*A( K, J ) - DO 130, I = 1, M - C( I, J ) = C( I, J ) + TEMP1*B( I, K ) - 13 130 CONTINUE - 14 140 CONTINUE - DO 160, K = J + 1, N - TEMP1 = ALPHA*A( J, K ) - DO 150, I = 1, M - C( I, J ) = C( I, J ) + TEMP1*B( I, K ) - 15 150 CONTINUE - 16 160 CONTINUE - 17 170 CONTINUE - for(int j = 0; j < n; j++) - { - double temp1 = P_t_t1[j + j * n]; - for (int i = 0; i < n; i++) - tmp[i + j * n] = tmp1 * T[i + j * n]; - for (int k = 0; k < j - 1; k++) - { - temp1 = P_t_t1[k + j * n]; - for (int i = 0; i < n; i++) - tmp[i + j * n] += temp1 * T[i + k * n]; - } - for (int k = j + 1; k < n; k++) - { - temp1 = P_t_t1[j + k * n]; - for (int i = 0; i < n; i++) - tmp[i + j * n] += temp1 * T[i + k * n]; - } - } - - for(int j = n_obs; j < n; j++) - { - int j1 = j - n_obs; - double temp1 = P_t_t1[j1 + j1 * n_state]; - for (int i = 0; i < n; i++) - tmp[i + j1 * n] = tmp1 * T[i + j * n]; - for (int k = n_obs; k < j - 1; k++) - { - int k1 = k - n_obs; - temp1 = P_t_t1[k1 + j1 * n_state]; - for (int i = 0; i < n; i++) - tmp[i + j1 * n] += temp1 * T[i + k * n]; - } - for (int k = max(j + 1, n_obs); k < n; k++) - { - int k1 = k - n_obs; - temp1 = P_t_t1[j1 + k1 * n_state]; - for (int i = 0; i < n; i++) - tmp[i + j1 * n] += temp1 * T[i + k * n]; - } - } - - for(int j = n_obs; j < n; j++) - { - int j1 = j - n_obs; - double temp1 = P_t_t1[j1 + j1 * n_state]; - for (int i = 0; i < n; i++) - tmp[i + j1 * n] = tmp1 * T[i + j * n]; - for (int k = n_obs; k < j - 1; k++) - { - int k1 = k - n_obs; - temp1 = P_t_t1[k1 + j1 * n_state]; - for (int i = 0; i < n; i++) - if ((i < n_obs) || (i >= nb_diag + n_obs) || (j1 >= nb_diag)) - tmp[i + j1 * n] += temp1 * T[i + k * n]; - } - for (int k = max(j + 1, n_obs); k < n; k++) - { - int k1 = k - n_obs; - temp1 = P_t_t1[j1 + k1 * n_state]; - for (int i = 0; i < n; i++) - if ((i < n_obs) || (i >= nb_diag + n_obs) || (j1 >= nb_diag)) - tmp[i + j1 * n] += temp1 * T[i + k * n]; - } - }*/ for (int i = 0; i < n; i++) //int i = 0; for (int j = n_obs; j < n; j++) @@ -2902,7 +2811,6 @@ DynamicModel::writeOutput(ostream &output, const string &basename, bool block_de for (vector::iterator it = v_index_KF.begin(); it != v_index_KF.end(); it++) KF_index_file.write(reinterpret_cast(&(*it)), sizeof(index_KF)); - //typedef pair, pair > index_KF_2; vector v_index_KF_2; int n_n_obs = n * n_obs; for (int i = 0; i < n; i++) From d13520019d2757240e06aeaec3f795372c190ea1 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 27 Apr 2015 11:50:25 +0200 Subject: [PATCH 02/15] preprocessor: add dirname option to estimation. closes #910 --- DynareBison.yy | 4 +++- DynareFlex.ll | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/DynareBison.yy b/DynareBison.yy index 6c76d416..b7288da9 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -92,7 +92,7 @@ class ParsingDriver; %token CONSIDER_ALL_ENDOGENOUS CONSIDER_ONLY_OBSERVED %token DATAFILE FILE SERIES DOUBLING DR_CYCLE_REDUCTION_TOL DR_LOGARITHMIC_REDUCTION_TOL DR_LOGARITHMIC_REDUCTION_MAXITER DR_ALGO DROP DSAMPLE DYNASAVE DYNATYPE CALIBRATION DIFFERENTIATE_FORWARD_VARS %token END ENDVAL EQUAL ESTIMATION ESTIMATED_PARAMS ESTIMATED_PARAMS_BOUNDS ESTIMATED_PARAMS_INIT EXTENDED_PATH ENDOGENOUS_PRIOR -%token FILENAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME +%token FILENAME DIRNAME FILTER_STEP_AHEAD FILTERED_VARS FIRST_OBS LAST_OBS SET_TIME %token FLOAT_NUMBER DATES %token DEFAULT FIXED_POINT OPT_ALGO %token FORECAST K_ORDER_SOLVER INSTRUMENTS SHIFT MEAN STDEV VARIANCE MODE INTERVAL SHAPE DOMAINN @@ -1712,6 +1712,7 @@ estimation_options : o_datafile | o_filter_algorithm | o_proposal_approximation | o_distribution_approximation + | o_dirname ; list_optim_option : QUOTED_STRING COMMA QUOTED_STRING @@ -2546,6 +2547,7 @@ o_qz_zero_threshold : QZ_ZERO_THRESHOLD EQUAL non_negative_number { driver.optio o_file : FILE EQUAL filename { driver.option_str("file", $3); }; o_series : SERIES EQUAL symbol { driver.option_str("series", $3); }; o_datafile : DATAFILE EQUAL filename { driver.option_str("datafile", $3); }; +o_dirname : DIRNAME EQUAL filename { driver.option_str("dirname", $3); }; o_nobs : NOBS EQUAL vec_int { driver.option_vec_int("nobs", $3); } | NOBS EQUAL vec_int_number diff --git a/DynareFlex.ll b/DynareFlex.ll index 0e7a31c1..4428dd37 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -236,6 +236,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 dates {dates_parens_nb=0; BEGIN DATES_STATEMENT; yylval->string_val = new string("dates");} file {return token::FILE;} datafile {return token::DATAFILE;} +dirname {return token::DIRNAME;} nobs {return token::NOBS;} last_obs {return token::LAST_OBS;} first_obs {return token::FIRST_OBS;} From e8809480e2e6ad12cf28a0673c647fbd3313d072 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Thu, 30 Apr 2015 12:35:33 +0200 Subject: [PATCH 03/15] preprocessor: add dynare_version field to oo_, M_, and options_, #546 --- ModFile.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ModFile.cc b/ModFile.cc index 847fc7e3..6d9eca0e 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -574,6 +574,9 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo << "global M_ oo_ options_ ys0_ ex0_ estimation_info" << endl << "options_ = [];" << endl << "M_.fname = '" << basename << "';" << endl + << "M_.dynare_version = '" << PACKAGE_VERSION << "';" << endl + << "oo_.dynare_version = '" << PACKAGE_VERSION << "';" << endl + << "options_.dynare_version = '" << PACKAGE_VERSION << "';" << endl << "%" << endl << "% Some global variables initialization" << endl << "%" << endl; From 5b42483e81cd6a217f25a45b2d39d68462546f37 Mon Sep 17 00:00:00 2001 From: Michel Juillard Date: Sun, 10 May 2015 18:16:11 +0200 Subject: [PATCH 04/15] adding feature to recompile MEX files only if the model has changed (not activated yet) detail of compilation code moved from preprocessor (ModFile.cc) to ./matlab/utilities/general/dyn_mex.m --- DynamicModel.cc | 94 ++++++++++++++++++++++++ DynamicModel.hh | 3 + ModFile.cc | 189 +++++++++++++++++++++--------------------------- ModFile.hh | 9 +++ 4 files changed, 187 insertions(+), 108 deletions(-) diff --git a/DynamicModel.cc b/DynamicModel.cc index f4957557..74d7a2c6 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -4221,5 +4221,99 @@ DynamicModel::dynamicOnlyEquationsNbr() const return eqs.size(); } +#ifndef PRIVATE_BUFFER_SIZE +#define PRIVATE_BUFFER_SIZE 1024 +#endif +bool +DynamicModel::isChecksumMatching(const string &basename) const +{ + boost::crc_32_type result; + std::stringstream buffer; + + // Write equation tags + for (size_t i = 0; i < equation_tags.size(); i++) + buffer << " " << equation_tags[i].first + 1 + << equation_tags[i].second.first + << equation_tags[i].second.second; + + ExprNodeOutputType buffer_type = oCDynamicModel; + + for (int eq = 0; eq < (int) equations.size(); eq++) + { + BinaryOpNode *eq_node = equations[eq]; + expr_t lhs = eq_node->get_arg1(); + expr_t rhs = eq_node->get_arg2(); + + // Test if the right hand side of the equation is empty. + double vrhs = 1.0; + try + { + vrhs = rhs->eval(eval_context_t()); + } + catch (ExprNode::EvalException &e) + { + } + + if (vrhs != 0) // The right hand side of the equation is not empty ==> residual=lhs-rhs; + { + buffer << "lhs ="; + lhs->writeOutput(buffer, buffer_type, temporary_terms); + buffer << ";" << endl; + + buffer << "rhs ="; + rhs->writeOutput(buffer, buffer_type, temporary_terms); + buffer << ";" << endl; + + buffer << "residual" << LEFT_ARRAY_SUBSCRIPT(buffer_type) + << eq + ARRAY_SUBSCRIPT_OFFSET(buffer_type) + << RIGHT_ARRAY_SUBSCRIPT(buffer_type) + << "= lhs-rhs;" << endl; + } + else // The right hand side of the equation is empty ==> residual=lhs; + { + buffer << "residual" << LEFT_ARRAY_SUBSCRIPT(buffer_type) + << eq + ARRAY_SUBSCRIPT_OFFSET(buffer_type) + << RIGHT_ARRAY_SUBSCRIPT(buffer_type) + << " = "; + lhs->writeOutput(buffer, buffer_type, temporary_terms); + buffer << ";" << endl; + } + } + + char private_buffer[PRIVATE_BUFFER_SIZE]; + while(buffer) + { + buffer.get(private_buffer,PRIVATE_BUFFER_SIZE); + result.process_bytes(private_buffer,strlen(private_buffer)); + } + + fstream checksum_file; + + string filename = basename + "/checksum"; + + // checksum_file.open(filename.c_str(), ios::in | ios::out | ios::binary); + checksum_file.open(filename.c_str(), ios::in | ios::binary); + unsigned int old_checksum = 0; + if (checksum_file.is_open()) + { + checksum_file >> old_checksum; + std::cout << "old_checksum " << old_checksum << endl; + } + if ((!checksum_file.is_open()) || (old_checksum != result.checksum())) + { + checksum_file.close(); + checksum_file.open(filename.c_str(), ios::out | ios::binary); + if (!checksum_file.is_open()) + { + cerr << "ERROR: Can't open file " << filename << endl; + exit(EXIT_FAILURE); + } + checksum_file << result.checksum(); + checksum_file.close(); + return false; + } + + return true; +} diff --git a/DynamicModel.hh b/DynamicModel.hh index 8efbc5d3..d96a7d50 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -24,6 +24,7 @@ using namespace std; #define ZERO_BAND 1e-8 #include +#include #include "StaticModel.hh" @@ -479,6 +480,8 @@ public: void writeSecondDerivativesC_csr(const string &basename, bool cuda) const; //! Writes C file containing third order derivatives of model evaluated at steady state (compressed sparse column) void writeThirdDerivativesC_csr(const string &basename, bool cuda) const; + + bool isChecksumMatching(const string &basename) const; }; //! Classes to re-order derivatives for various sparse storage formats diff --git a/ModFile.cc b/ModFile.cc index 6d9eca0e..9f8f73f5 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -469,55 +469,55 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output) // Compute static model and its derivatives dynamic_model.toStatic(static_model); if (!no_static) - { - if (mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present || mod_file_struct.osr_present - || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present - || mod_file_struct.calib_smoother_present) - static_model.set_cutoff_to_zero(); + { + if (mod_file_struct.stoch_simul_present + || mod_file_struct.estimation_present || mod_file_struct.osr_present + || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present + || mod_file_struct.calib_smoother_present) + static_model.set_cutoff_to_zero(); - const bool static_hessian = mod_file_struct.identification_present - || mod_file_struct.estimation_analytic_derivation; - const bool paramsDerivatives = mod_file_struct.identification_present - || mod_file_struct.estimation_analytic_derivation; - static_model.computingPass(global_eval_context, no_tmp_terms, static_hessian, - false, paramsDerivatives, block, byte_code); - } + const bool static_hessian = mod_file_struct.identification_present + || mod_file_struct.estimation_analytic_derivation; + const bool paramsDerivatives = mod_file_struct.identification_present + || mod_file_struct.estimation_analytic_derivation; + static_model.computingPass(global_eval_context, no_tmp_terms, static_hessian, + false, paramsDerivatives, block, byte_code); + } // Set things to compute for dynamic model if (mod_file_struct.perfect_foresight_solver_present || mod_file_struct.check_present - || mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present || mod_file_struct.osr_present - || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present - || mod_file_struct.calib_smoother_present) - { - if (mod_file_struct.perfect_foresight_solver_present) - dynamic_model.computingPass(true, false, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code); - else - { - if (mod_file_struct.stoch_simul_present - || mod_file_struct.estimation_present || mod_file_struct.osr_present - || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present - || mod_file_struct.calib_smoother_present) - dynamic_model.set_cutoff_to_zero(); - if (mod_file_struct.order_option < 1 || mod_file_struct.order_option > 3) - { - cerr << "ERROR: Incorrect order option..." << endl; - exit(EXIT_FAILURE); - } - bool hessian = mod_file_struct.order_option >= 2 - || mod_file_struct.identification_present - || mod_file_struct.estimation_analytic_derivation - || output == second - || output == third; - bool thirdDerivatives = mod_file_struct.order_option == 3 - || mod_file_struct.estimation_analytic_derivation - || output == third; - bool paramsDerivatives = mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation; - dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivatives, global_eval_context, no_tmp_terms, block, use_dll, byte_code); - } - } - else // No computing task requested, compute derivatives up to 2nd order by default - dynamic_model.computingPass(true, true, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code); + || mod_file_struct.stoch_simul_present + || mod_file_struct.estimation_present || mod_file_struct.osr_present + || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present + || mod_file_struct.calib_smoother_present) + { + if (mod_file_struct.perfect_foresight_solver_present) + dynamic_model.computingPass(true, false, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code); + else + { + if (mod_file_struct.stoch_simul_present + || mod_file_struct.estimation_present || mod_file_struct.osr_present + || mod_file_struct.ramsey_model_present || mod_file_struct.identification_present + || mod_file_struct.calib_smoother_present) + dynamic_model.set_cutoff_to_zero(); + if (mod_file_struct.order_option < 1 || mod_file_struct.order_option > 3) + { + cerr << "ERROR: Incorrect order option..." << endl; + exit(EXIT_FAILURE); + } + bool hessian = mod_file_struct.order_option >= 2 + || mod_file_struct.identification_present + || mod_file_struct.estimation_analytic_derivation + || output == second + || output == third; + bool thirdDerivatives = mod_file_struct.order_option == 3 + || mod_file_struct.estimation_analytic_derivation + || output == third; + bool paramsDerivatives = mod_file_struct.identification_present || mod_file_struct.estimation_analytic_derivation; + dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivatives, global_eval_context, no_tmp_terms, block, use_dll, byte_code); + } + } + else // No computing task requested, compute derivatives up to 2nd order by default + dynamic_model.computingPass(true, true, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code); } for (vector::iterator it = statements.begin(); @@ -649,18 +649,23 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo << " error('DYNARE: Can''t find bytecode DLL. Please compile it or remove the ''bytecode'' option.')" << endl << "end" << endl; - // Erase possible remnants of previous runs - unlink((basename + "_dynamic.m").c_str()); - unlink((basename + "_dynamic.cod").c_str()); - unlink((basename + "_dynamic.bin").c_str()); + bool hasModelChanged = !dynamic_model.isChecksumMatching(basename); + + if (hasModelChanged) + { + // Erase possible remnants of previous runs + unlink((basename + "_dynamic.m").c_str()); + unlink((basename + "_dynamic.cod").c_str()); + unlink((basename + "_dynamic.bin").c_str()); - unlink((basename + "_static.m").c_str()); - unlink((basename + "_static.cod").c_str()); - unlink((basename + "_static.bin").c_str()); - - unlink((basename + "_steadystate2.m").c_str()); - unlink((basename + "_set_auxiliary_variables.m").c_str()); + unlink((basename + "_static.m").c_str()); + unlink((basename + "_static.cod").c_str()); + unlink((basename + "_static.bin").c_str()); + unlink((basename + "_steadystate2.m").c_str()); + unlink((basename + "_set_auxiliary_variables.m").c_str()); + } + if (!use_dll) { mOutputFile << "erase_compiled_function('" + basename + "_static');" << endl; @@ -697,53 +702,19 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo // Compile the dynamic MEX file for use_dll option if (use_dll) { - mOutputFile << "if ~exist('OCTAVE_VERSION')" << endl; - // Some mex commands are enclosed in an eval(), because otherwise it will make Octave fail #if defined(_WIN32) || defined(__CYGWIN32__) if (msvc) // MATLAB/Windows + Microsoft Visual C++ - mOutputFile << " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Dynamic\" " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Static\" " << basename << "_static.c "<< basename << "_static_mex.c')" << endl; + mOutputFile << "dyn_mex('msvc', '" << basename << ", 1)" << endl; else if (cygwin) // MATLAB/Windows + Cygwin g++ - mOutputFile << " eval('mex -O PRELINK_CMDS1=\"echo EXPORTS > mex.def & echo mexFunction >> mex.def & echo Dynamic >> mex.def\" " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O PRELINK_CMDS1=\"echo EXPORTS > mex.def & echo mexFunction >> mex.def & echo Static >> mex.def\" " << basename << "_static.c "<< basename << "_static_mex.c')" << endl; + mOutputFile << "dyn_mex('cygwin', '" << basename << "', 1)" << endl; else mOutputFile << " error('When using the USE_DLL option, you must give either ''cygwin'' or ''msvc'' option to the ''dynare'' command')" << endl; #else -# ifdef __linux__ - // MATLAB/Linux - mOutputFile << " if matlab_ver_less_than('8.3')" << endl - << " eval('mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' " << basename << "_static.c "<< basename << "_static_mex.c')" << endl - << " else" << endl - << " eval('mex -O LINKEXPORT='''' " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LINKEXPORT='''' " << basename << "_static.c "<< basename << "_static_mex.c')" << endl - << " end" << endl; -# else // MacOS - // MATLAB/MacOS - mOutputFile << " if matlab_ver_less_than('8.3')" << endl - << " if matlab_ver_less_than('8.1')" << endl - << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " - << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " - << basename << "_static.c " << basename << "_static_mex.c')" << endl - << " else" << endl - << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$MW_SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " - << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$MW_SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " - << basename << "_static.c " << basename << "_static_mex.c')" << endl - << " end" << endl - << " else" << endl - << " eval('mex -O LINKEXPORT='''' " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl - << " eval('mex -O LINKEXPORT='''' " << basename << "_static.c "<< basename << "_static_mex.c')" << endl - << " end" << endl; -# endif + // other configurations + mOutputFile << "dyn_mex('', '" << basename << "', 1)" << endl; #endif - mOutputFile << "else" << endl // Octave - << " mex " << basename << "_dynamic.c " << basename << "_dynamic_mex.c" << endl - << " mex " << basename << "_static.c " << basename << "_static_mex.c" << endl - << "end" << endl; } // Add path for block option with M-files @@ -824,22 +795,24 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo mOutputFile.close(); - // Create static and dynamic files - if (dynamic_model.equation_number() > 0) + if (hasModelChanged) { - if (!no_static) - { - static_model.writeStaticFile(basename, block, byte_code, use_dll); - static_model.writeParamsDerivativesFile(basename); - } + // Create static and dynamic files + if (dynamic_model.equation_number() > 0) + { + if (!no_static) + { + static_model.writeStaticFile(basename, block, byte_code, use_dll); + static_model.writeParamsDerivativesFile(basename); + } - dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option); - dynamic_model.writeParamsDerivativesFile(basename); + dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option); + dynamic_model.writeParamsDerivativesFile(basename); + } + + // Create steady state file + steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present); } - - // Create steady state file - steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present); - + cout << "done" << endl; } - diff --git a/ModFile.hh b/ModFile.hh index 722ea534..0a384931 100644 --- a/ModFile.hh +++ b/ModFile.hh @@ -24,6 +24,8 @@ using namespace std; #include #include +#include +#include #include "SymbolTable.hh" #include "NumericalConstants.hh" @@ -37,6 +39,11 @@ using namespace std; #include "WarningConsolidation.hh" #include "ExtendedPreprocessorTypes.hh" +// for checksum computation +#ifndef PRIVATE_BUFFER_SIZE +#define PRIVATE_BUFFER_SIZE 1024 +#endif + //! The abstract representation of a "mod" file class ModFile { @@ -153,6 +160,8 @@ public: //! Writes Cpp output files only => No further Matlab processing void writeCCOutputFiles(const string &basename) const; void writeModelCC(const string &basename) const; + + void computeChecksum(); }; #endif // ! MOD_FILE_HH From f020a2cb52feee735be21d06aae7e3a492d6ee27 Mon Sep 17 00:00:00 2001 From: Michel Juillard Date: Sun, 10 May 2015 20:29:03 +0200 Subject: [PATCH 05/15] adding dynare command line option 'fast' in order not to recompile MEX files if the lists of variables and the equations haven't changed between two runs of the same model file. --- DynareMain.cc | 9 ++++++--- DynareMain2.cc | 9 +++++---- ModFile.cc | 16 ++++++++++------ ModFile.hh | 3 ++- 4 files changed, 23 insertions(+), 14 deletions(-) diff --git a/DynareMain.cc b/DynareMain.cc index 19d773b8..9320a4af 100644 --- a/DynareMain.cc +++ b/DynareMain.cc @@ -38,7 +38,7 @@ void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear_global, bool no_tmp_terms, bool no_log, bool no_warn, bool warn_uninit, bool console, bool nograph, bool nointeractive, bool parallel, const string ¶llel_config_file, const string &cluster_name, bool parallel_slave_open_mode, - bool parallel_test, bool nostrict, FileOutputType output_mode, LanguageOutputType lang + bool parallel_test, bool nostrict, bool check_model_changes, FileOutputType output_mode, LanguageOutputType lang #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -49,7 +49,7 @@ usage() { cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [onlyclearglobals] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [nolog] [warn_uninit]" << " [console] [nograph] [nointeractive] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test] " - << " [-D[=]] [nostrict] [output=dynamic|first|second|third] [language=C|C++]" + << " [-D[=]] [nostrict] [fast] [output=dynamic|first|second|third] [language=C|C++]" #if defined(_WIN32) || defined(__CYGWIN32__) << " [cygwin] [msvc]" #endif @@ -97,6 +97,7 @@ main(int argc, char **argv) bool parallel_slave_open_mode = false; bool parallel_test = false; bool nostrict = false; + bool check_model_changes = false; map defines; FileOutputType output_mode = none; LanguageOutputType language = matlab; @@ -165,6 +166,8 @@ main(int argc, char **argv) parallel_test = true; else if (!strcmp(argv[arg], "nostrict")) nostrict = true; + else if (!strcmp(argv[arg], "fast")) + check_model_changes = true; else if (strlen(argv[arg]) >= 8 && !strncmp(argv[arg], "parallel", 8)) { parallel = true; @@ -285,7 +288,7 @@ main(int argc, char **argv) // Do the rest main2(macro_output, basename, debug, clear_all, clear_global, no_tmp_terms, no_log, no_warn, warn_uninit, console, nograph, nointeractive, - parallel, parallel_config_file, cluster_name, parallel_slave_open_mode, parallel_test, nostrict, output_mode, language + parallel, parallel_config_file, cluster_name, parallel_slave_open_mode, parallel_test, nostrict, check_model_changes, output_mode, language #if defined(_WIN32) || defined(__CYGWIN32__) , cygwin, msvc #endif diff --git a/DynareMain2.cc b/DynareMain2.cc index 376dd20a..fe1c6942 100644 --- a/DynareMain2.cc +++ b/DynareMain2.cc @@ -27,7 +27,7 @@ void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear_global, bool no_tmp_terms, bool no_log, bool no_warn, bool warn_uninit, bool console, bool nograph, bool nointeractive, bool parallel, const string ¶llel_config_file, const string &cluster_name, bool parallel_slave_open_mode, - bool parallel_test, bool nostrict, FileOutputType output_mode, LanguageOutputType language + bool parallel_test, bool nostrict, bool check_model_changes, FileOutputType output_mode, LanguageOutputType language #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -60,11 +60,12 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear if (output_mode != none) mod_file->writeExternalFiles(basename, output_mode, language); else - mod_file->writeOutputFiles(basename, clear_all, clear_global, no_log, no_warn, console, nograph, nointeractive, config_file + mod_file->writeOutputFiles(basename, clear_all, clear_global, no_log, no_warn, console, nograph, + nointeractive, config_file, check_model_changes #if defined(_WIN32) || defined(__CYGWIN32__) - , cygwin, msvc + , cygwin, msvc #endif - ); + ); delete mod_file; diff --git a/ModFile.cc b/ModFile.cc index 9f8f73f5..c6b7ca83 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -526,7 +526,8 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output) } void -ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn, bool console, bool nograph, bool nointeractive, const ConfigFile &config_file +ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn, bool console, bool nograph, + bool nointeractive, const ConfigFile &config_file, bool check_model_changes #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif @@ -650,7 +651,9 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo << "end" << endl; bool hasModelChanged = !dynamic_model.isChecksumMatching(basename); - + if (!check_model_changes) + hasModelChanged = true; + if (hasModelChanged) { // Erase possible remnants of previous runs @@ -700,20 +703,21 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo #endif // Compile the dynamic MEX file for use_dll option + // When check_model_changes is true, don't force compile if MEX is fresher than source if (use_dll) { #if defined(_WIN32) || defined(__CYGWIN32__) if (msvc) // MATLAB/Windows + Microsoft Visual C++ - mOutputFile << "dyn_mex('msvc', '" << basename << ", 1)" << endl; + mOutputFile << "dyn_mex('msvc', '" << basename << "', " << !check_model_changes << ")" << endl; else if (cygwin) // MATLAB/Windows + Cygwin g++ - mOutputFile << "dyn_mex('cygwin', '" << basename << "', 1)" << endl; + mOutputFile << "dyn_mex('cygwin', '" << basename << "', " << !check_model_changes << ")" << endl; else mOutputFile << " error('When using the USE_DLL option, you must give either ''cygwin'' or ''msvc'' option to the ''dynare'' command')" << endl; #else - // other configurations - mOutputFile << "dyn_mex('', '" << basename << "', 1)" << endl; + // other configurations + mOutputFile << "dyn_mex('', '" << basename << "', " << !check_model_changes << ")" << endl; #endif } diff --git a/ModFile.hh b/ModFile.hh index 0a384931..bf363668 100644 --- a/ModFile.hh +++ b/ModFile.hh @@ -145,7 +145,8 @@ public: \param cygwin Should the MEX command of use_dll be adapted for Cygwin? \param msvc Should the MEX command of use_dll be adapted for MSVC? */ - void writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn, bool console, bool nograph, bool nointeractive, const ConfigFile &config_file + void writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn, + bool console, bool nograph, bool nointeractive, const ConfigFile &config_file, bool check_model_changes #if defined(_WIN32) || defined(__CYGWIN32__) , bool cygwin, bool msvc #endif From a757579213d530d8ca4fa177bfd2154b1b77c33a Mon Sep 17 00:00:00 2001 From: Michel Juillard Date: Mon, 11 May 2015 08:52:50 +0200 Subject: [PATCH 06/15] fixing logic in creation of checksum file. Improving documentation. --- DynamicModel.cc | 31 ++++++++++++++++++++++--------- ModFile.cc | 2 +- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/DynamicModel.cc b/DynamicModel.cc index 74d7a2c6..b7eb27d8 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -4289,21 +4289,34 @@ DynamicModel::isChecksumMatching(const string &basename) const result.process_bytes(private_buffer,strlen(private_buffer)); } + // check whether basename directory exist. If not, create it. + // If it does, read old checksum if it exist fstream checksum_file; - string filename = basename + "/checksum"; - - // checksum_file.open(filename.c_str(), ios::in | ios::out | ios::binary); - checksum_file.open(filename.c_str(), ios::in | ios::binary); unsigned int old_checksum = 0; - if (checksum_file.is_open()) + struct stat sd; + if (stat(basename.c_str(), &sd) != 0) { - checksum_file >> old_checksum; - std::cout << "old_checksum " << old_checksum << endl; - } - if ((!checksum_file.is_open()) || (old_checksum != result.checksum())) + const int dir_err = mkdir(basename.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + if (dir_err == -1) { + cerr << "ERROR: can't create directory " << basename << endl; + exit(EXIT_FAILURE); + } + } + else + { + // read old checksum if it exists + checksum_file.open(filename.c_str(), ios::in | ios::binary); + if (checksum_file.is_open()) + { + checksum_file >> old_checksum; checksum_file.close(); + } + } + // write new checksum file if none or different from old checksum + if (old_checksum != result.checksum()) + { checksum_file.open(filename.c_str(), ios::out | ios::binary); if (!checksum_file.is_open()) { diff --git a/ModFile.cc b/ModFile.cc index c6b7ca83..0a7860c4 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -596,7 +596,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo if (nointeractive) mOutputFile << "options_.nointeractive = 1;" << endl; - cout << "Processing outputs ..."; + cout << "Processing outputs ..." << endl; symbol_table.writeOutput(mOutputFile); From dbf2e0e37956e32f8f72148b446034c522126ff6 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Mon, 11 May 2015 16:39:06 +0200 Subject: [PATCH 07/15] preprocessor: organize external function code --- ExprNode.cc | 633 ++++++++++++++++++++++++++-------------------------- 1 file changed, 316 insertions(+), 317 deletions(-) diff --git a/ExprNode.cc b/ExprNode.cc index d61ebb56..3805c1a6 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -4297,15 +4297,6 @@ AbstractExternalFunctionNode::AbstractExternalFunctionNode(DataTree &datatree_ar { } -ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg, - int symb_id_arg, - const vector &arguments_arg) : - AbstractExternalFunctionNode(datatree_arg, symb_id_arg, arguments_arg) -{ - // Add myself to the external function map - datatree.external_function_node_map[make_pair(arguments, symb_id)] = this; -} - void AbstractExternalFunctionNode::prepareForDerivation() { @@ -4336,20 +4327,6 @@ AbstractExternalFunctionNode::computeDerivative(int deriv_id) return composeDerivatives(dargs); } -expr_t -ExternalFunctionNode::composeDerivatives(const vector &dargs) -{ - vector dNodes; - for (int i = 0; i < (int) dargs.size(); i++) - dNodes.push_back(datatree.AddTimes(dargs.at(i), - datatree.AddFirstDerivExternalFunction(symb_id, arguments, i+1))); - - expr_t theDeriv = datatree.Zero; - for (vector::const_iterator it = dNodes.begin(); it != dNodes.end(); it++) - theDeriv = datatree.AddPlus(theDeriv, *it); - return theDeriv; -} - expr_t AbstractExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map &recursive_variables) { @@ -4361,76 +4338,6 @@ AbstractExternalFunctionNode::getChainRuleDerivative(int deriv_id, const map &reference_count, - temporary_terms_t &temporary_terms, - bool is_matlab) const -{ - temporary_terms.insert(const_cast(this)); -} - -void -AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - { - if (it != arguments.begin()) - output << ","; - - (*it)->writeOutput(output, output_type, temporary_terms, tef_terms); - } -} - -void -AbstractExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms, const string &ending) const -{ - output << "mxArray *prhs"<< ending << "[nrhs"<< ending << "];" << endl; - int i = 0; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - { - output << "prhs" << ending << "[" << i++ << "] = mxCreateDoubleScalar("; // All external_function arguments are scalars - (*it)->writeOutput(output, output_type, temporary_terms, tef_terms); - output << ");" << endl; - } -} - -void -ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - if (output_type == oMatlabOutsideModel || output_type == oSteadyStateFile - || output_type == oCSteadyStateFile || IS_LATEX(output_type)) - { - string name = IS_LATEX(output_type) ? datatree.symbol_table.getTeXName(symb_id) - : datatree.symbol_table.getName(symb_id); - output << name << "("; - writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms); - output << ")"; - return; - } - - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (output_type == oMatlabDynamicModelSparse) - output << "T" << idx << "(it_)"; - else - output << "T" << idx; - return; - } - - if (IS_C(output_type)) - output << "*"; - output << "TEF_" << getIndxInTefTerms(symb_id, tef_terms); -} - unsigned int AbstractExternalFunctionNode::compileExternalFunctionArguments(ostream &CompileCode, unsigned int &instruction_number, bool lhs_rhs, const temporary_terms_t &temporary_terms, @@ -4444,184 +4351,6 @@ AbstractExternalFunctionNode::compileExternalFunctionArguments(ostream &CompileC return (arguments.size()); } -void -ExternalFunctionNode::compile(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); - if (it != temporary_terms.end()) - { - if (dynamic) - { - map_idx_t::const_iterator ii = map_idx.find(idx); - FLDT_ fldt(ii->second); - fldt.write(CompileCode, instruction_number); - } - else - { - map_idx_t::const_iterator ii = map_idx.find(idx); - FLDST_ fldst(ii->second); - fldst.write(CompileCode, instruction_number); - } - return; - } - - if (!lhs_rhs) - { - FLDTEF_ fldtef(getIndxInTefTerms(symb_id, tef_terms)); - fldtef.write(CompileCode, instruction_number); - } - else - { - FSTPTEF_ fstptef(getIndxInTefTerms(symb_id, tef_terms)); - fstptef.write(CompileCode, instruction_number); - } -} - -void -ExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, - const temporary_terms_t &temporary_terms, - deriv_node_temp_terms_t &tef_terms) const -{ - int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); - assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms); - - if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) - { - tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size(); - int indx = getIndxInTefTerms(symb_id, tef_terms); - int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); - assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); - - if (IS_C(output_type)) - { - stringstream ending; - ending << "_tef_" << getIndxInTefTerms(symb_id, tef_terms); - if (symb_id == first_deriv_symb_id - && symb_id == second_deriv_symb_id) - output << "int nlhs" << ending.str() << " = 3;" << endl - << "double *TEF_" << indx << ", " - << "*TEFD_" << indx << ", " - << "*TEFDD_" << indx << ";" << endl; - else if (symb_id == first_deriv_symb_id) - output << "int nlhs" << ending.str() << " = 2;" << endl - << "double *TEF_" << indx << ", " - << "*TEFD_" << indx << "; " << endl; - else - output << "int nlhs" << ending.str() << " = 1;" << endl - << "double *TEF_" << indx << ";" << endl; - - output << "mxArray *plhs" << ending.str()<< "[nlhs"<< ending.str() << "];" << endl; - output << "int nrhs" << ending.str()<< " = " << arguments.size() << ";" << endl; - writePrhs(output, output_type, temporary_terms, tef_terms, ending.str()); - - output << "mexCallMATLAB(" - << "nlhs" << ending.str() << ", " - << "plhs" << ending.str() << ", " - << "nrhs" << ending.str() << ", " - << "prhs" << ending.str() << ", \"" - << datatree.symbol_table.getName(symb_id) << "\");" << endl; - - if (symb_id == first_deriv_symb_id - && symb_id == second_deriv_symb_id) - output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl - << "TEFD_" << indx << " = mxGetPr(plhs" << ending.str() << "[1]);" << endl - << "TEFDD_" << indx << " = mxGetPr(plhs" << ending.str() << "[2]);" << endl - << "int TEFDD_" << indx << "_nrows = (int)mxGetM(plhs" << ending.str()<< "[2]);" << endl; - else if (symb_id == first_deriv_symb_id) - output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl - << "TEFD_" << indx << " = mxGetPr(plhs" << ending.str() << "[1]);" << endl; - else - output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl; - } - else - { - if (symb_id == first_deriv_symb_id - && symb_id == second_deriv_symb_id) - output << "[TEF_" << indx << " TEFD_"<< indx << " TEFDD_"<< indx << "] = "; - else if (symb_id == first_deriv_symb_id) - output << "[TEF_" << indx << " TEFD_"<< indx << "] = "; - else - output << "TEF_" << indx << " = "; - - output << datatree.symbol_table.getName(symb_id) << "("; - writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms); - output << ");" << endl; - } - } -} - -void -ExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, - bool lhs_rhs, const temporary_terms_t &temporary_terms, - const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, - deriv_node_temp_terms_t &tef_terms) const -{ - int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); - assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); - - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - (*it)->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, - map_idx, dynamic, steady_dynamic, tef_terms); - - if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) - { - tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size(); - int indx = getIndxInTefTerms(symb_id, tef_terms); - int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); - assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); - - unsigned int nb_output_arguments = 0; - if (symb_id == first_deriv_symb_id - && symb_id == second_deriv_symb_id) - nb_output_arguments = 3; - else if (symb_id == first_deriv_symb_id) - nb_output_arguments = 2; - else - nb_output_arguments = 1; - unsigned int nb_input_arguments = compileExternalFunctionArguments(CompileCode, instruction_number, lhs_rhs, temporary_terms, - map_idx, dynamic, steady_dynamic, tef_terms); - - FCALL_ fcall(nb_output_arguments, nb_input_arguments, datatree.symbol_table.getName(symb_id), indx); - switch (nb_output_arguments) - { - case 1: - fcall.set_function_type(ExternalFunctionWithoutDerivative); - break; - case 2: - fcall.set_function_type(ExternalFunctionWithFirstDerivative); - break; - case 3: - fcall.set_function_type(ExternalFunctionWithFirstandSecondDerivative); - break; - } - fcall.write(CompileCode, instruction_number); - FSTPTEF_ fstptef(indx); - fstptef.write(CompileCode, instruction_number); - } -} - -void -ExternalFunctionNode::computeTemporaryTerms(map &reference_count, - temporary_terms_t &temporary_terms, - map > &first_occurence, - int Curr_block, - vector< vector > &v_temporary_terms, - int equation) const -{ - expr_t this2 = const_cast(this); - temporary_terms.insert(this2); - first_occurence[this2] = make_pair(Curr_block, equation); - v_temporary_terms[Curr_block][equation].insert(this2); -} - void AbstractExternalFunctionNode::collectDynamicVariables(SymbolType type_arg, set > &result) const { @@ -4650,45 +4379,6 @@ AbstractExternalFunctionNode::eval(const eval_context_t &eval_context) const thr throw EvalExternalFunctionException(); } -pair -AbstractExternalFunctionNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const -{ - vector > V_arguments; - vector V_expr_t; - bool present = false; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - { - V_arguments.push_back((*it)->normalizeEquation(var_endo, List_of_Op_RHS)); - present = present || V_arguments[V_arguments.size()-1].first; - V_expr_t.push_back(V_arguments[V_arguments.size()-1].second); - } - if (!present) - return (make_pair(0, datatree.AddExternalFunction(symb_id, V_expr_t))); - else - return (make_pair(1, (expr_t) NULL)); -} - -expr_t -ExternalFunctionNode::toStatic(DataTree &static_datatree) const -{ - vector static_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - static_arguments.push_back((*it)->toStatic(static_datatree)); - return static_datatree.AddExternalFunction(symb_id, static_arguments); -} - -expr_t -ExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const -{ - vector dynamic_arguments; - for (vector::const_iterator it = arguments.begin(); - it != arguments.end(); it++) - dynamic_arguments.push_back((*it)->cloneDynamic(dynamic_datatree)); - return dynamic_datatree.AddExternalFunction(symb_id, dynamic_arguments); -} - int AbstractExternalFunctionNode::maxEndoLead() const { @@ -4811,12 +4501,6 @@ AbstractExternalFunctionNode::differentiateForwardVars(const vector &sub return buildSimilarExternalFunctionNode(arguments_subst, datatree); } -expr_t -ExternalFunctionNode::buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const -{ - return alt_datatree.AddExternalFunction(symb_id, alt_args); -} - bool AbstractExternalFunctionNode::alreadyWrittenAsTefTerm(int the_symb_id, deriv_node_temp_terms_t &tef_terms) const { @@ -4889,10 +4573,325 @@ AbstractExternalFunctionNode::isInStaticForm() const for (vector::const_iterator it = arguments.begin(); it != arguments.end(); ++it) if (!(*it)->isInStaticForm()) return false; - return true; } +pair +AbstractExternalFunctionNode::normalizeEquation(int var_endo, vector > > &List_of_Op_RHS) const +{ + vector > V_arguments; + vector V_expr_t; + bool present = false; + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + { + V_arguments.push_back((*it)->normalizeEquation(var_endo, List_of_Op_RHS)); + present = present || V_arguments[V_arguments.size()-1].first; + V_expr_t.push_back(V_arguments[V_arguments.size()-1].second); + } + if (!present) + return (make_pair(0, datatree.AddExternalFunction(symb_id, V_expr_t))); + else + return (make_pair(1, (expr_t) NULL)); +} + +void +AbstractExternalFunctionNode::writeExternalFunctionArguments(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms) const +{ + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + { + if (it != arguments.begin()) + output << ","; + + (*it)->writeOutput(output, output_type, temporary_terms, tef_terms); + } +} + +void +AbstractExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms, const string &ending) const +{ + output << "mxArray *prhs"<< ending << "[nrhs"<< ending << "];" << endl; + int i = 0; + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + { + output << "prhs" << ending << "[" << i++ << "] = mxCreateDoubleScalar("; // All external_function arguments are scalars + (*it)->writeOutput(output, output_type, temporary_terms, tef_terms); + output << ");" << endl; + } +} + +ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg, + int symb_id_arg, + const vector &arguments_arg) : + AbstractExternalFunctionNode(datatree_arg, symb_id_arg, arguments_arg) +{ + // Add myself to the external function map + datatree.external_function_node_map[make_pair(arguments, symb_id)] = this; +} + +expr_t +ExternalFunctionNode::composeDerivatives(const vector &dargs) +{ + vector dNodes; + for (int i = 0; i < (int) dargs.size(); i++) + dNodes.push_back(datatree.AddTimes(dargs.at(i), + datatree.AddFirstDerivExternalFunction(symb_id, arguments, i+1))); + + expr_t theDeriv = datatree.Zero; + for (vector::const_iterator it = dNodes.begin(); it != dNodes.end(); it++) + theDeriv = datatree.AddPlus(theDeriv, *it); + return theDeriv; +} + +void +ExternalFunctionNode::computeTemporaryTerms(map &reference_count, + temporary_terms_t &temporary_terms, + bool is_matlab) const +{ + temporary_terms.insert(const_cast(this)); +} + +void +ExternalFunctionNode::computeTemporaryTerms(map &reference_count, + temporary_terms_t &temporary_terms, + map > &first_occurence, + int Curr_block, + vector< vector > &v_temporary_terms, + int equation) const +{ + expr_t this2 = const_cast(this); + temporary_terms.insert(this2); + first_occurence[this2] = make_pair(Curr_block, equation); + v_temporary_terms[Curr_block][equation].insert(this2); +} + +void +ExternalFunctionNode::compile(ostream &CompileCode, unsigned int &instruction_number, + bool lhs_rhs, const temporary_terms_t &temporary_terms, + const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, + deriv_node_temp_terms_t &tef_terms) const +{ + temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + { + if (dynamic) + { + map_idx_t::const_iterator ii = map_idx.find(idx); + FLDT_ fldt(ii->second); + fldt.write(CompileCode, instruction_number); + } + else + { + map_idx_t::const_iterator ii = map_idx.find(idx); + FLDST_ fldst(ii->second); + fldst.write(CompileCode, instruction_number); + } + return; + } + + if (!lhs_rhs) + { + FLDTEF_ fldtef(getIndxInTefTerms(symb_id, tef_terms)); + fldtef.write(CompileCode, instruction_number); + } + else + { + FSTPTEF_ fstptef(getIndxInTefTerms(symb_id, tef_terms)); + fstptef.write(CompileCode, instruction_number); + } +} + +void +ExternalFunctionNode::compileExternalFunctionOutput(ostream &CompileCode, unsigned int &instruction_number, + bool lhs_rhs, const temporary_terms_t &temporary_terms, + const map_idx_t &map_idx, bool dynamic, bool steady_dynamic, + deriv_node_temp_terms_t &tef_terms) const +{ + int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); + assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); + + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + (*it)->compileExternalFunctionOutput(CompileCode, instruction_number, lhs_rhs, temporary_terms, + map_idx, dynamic, steady_dynamic, tef_terms); + + if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) + { + tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size(); + int indx = getIndxInTefTerms(symb_id, tef_terms); + int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); + assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); + + unsigned int nb_output_arguments = 0; + if (symb_id == first_deriv_symb_id + && symb_id == second_deriv_symb_id) + nb_output_arguments = 3; + else if (symb_id == first_deriv_symb_id) + nb_output_arguments = 2; + else + nb_output_arguments = 1; + unsigned int nb_input_arguments = compileExternalFunctionArguments(CompileCode, instruction_number, lhs_rhs, temporary_terms, + map_idx, dynamic, steady_dynamic, tef_terms); + + FCALL_ fcall(nb_output_arguments, nb_input_arguments, datatree.symbol_table.getName(symb_id), indx); + switch (nb_output_arguments) + { + case 1: + fcall.set_function_type(ExternalFunctionWithoutDerivative); + break; + case 2: + fcall.set_function_type(ExternalFunctionWithFirstDerivative); + break; + case 3: + fcall.set_function_type(ExternalFunctionWithFirstandSecondDerivative); + break; + } + fcall.write(CompileCode, instruction_number); + FSTPTEF_ fstptef(indx); + fstptef.write(CompileCode, instruction_number); + } +} + +void +ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms) const +{ + if (output_type == oMatlabOutsideModel || output_type == oSteadyStateFile + || output_type == oCSteadyStateFile || IS_LATEX(output_type)) + { + string name = IS_LATEX(output_type) ? datatree.symbol_table.getTeXName(symb_id) + : datatree.symbol_table.getName(symb_id); + output << name << "("; + writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms); + output << ")"; + return; + } + + temporary_terms_t::const_iterator it = temporary_terms.find(const_cast(this)); + if (it != temporary_terms.end()) + { + if (output_type == oMatlabDynamicModelSparse) + output << "T" << idx << "(it_)"; + else + output << "T" << idx; + return; + } + + if (IS_C(output_type)) + output << "*"; + output << "TEF_" << getIndxInTefTerms(symb_id, tef_terms); +} + +void +ExternalFunctionNode::writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, + const temporary_terms_t &temporary_terms, + deriv_node_temp_terms_t &tef_terms) const +{ + int first_deriv_symb_id = datatree.external_functions_table.getFirstDerivSymbID(symb_id); + assert(first_deriv_symb_id != eExtFunSetButNoNameProvided); + + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + (*it)->writeExternalFunctionOutput(output, output_type, temporary_terms, tef_terms); + + if (!alreadyWrittenAsTefTerm(symb_id, tef_terms)) + { + tef_terms[make_pair(symb_id, arguments)] = (int) tef_terms.size(); + int indx = getIndxInTefTerms(symb_id, tef_terms); + int second_deriv_symb_id = datatree.external_functions_table.getSecondDerivSymbID(symb_id); + assert(second_deriv_symb_id != eExtFunSetButNoNameProvided); + + if (IS_C(output_type)) + { + stringstream ending; + ending << "_tef_" << getIndxInTefTerms(symb_id, tef_terms); + if (symb_id == first_deriv_symb_id + && symb_id == second_deriv_symb_id) + output << "int nlhs" << ending.str() << " = 3;" << endl + << "double *TEF_" << indx << ", " + << "*TEFD_" << indx << ", " + << "*TEFDD_" << indx << ";" << endl; + else if (symb_id == first_deriv_symb_id) + output << "int nlhs" << ending.str() << " = 2;" << endl + << "double *TEF_" << indx << ", " + << "*TEFD_" << indx << "; " << endl; + else + output << "int nlhs" << ending.str() << " = 1;" << endl + << "double *TEF_" << indx << ";" << endl; + + output << "mxArray *plhs" << ending.str()<< "[nlhs"<< ending.str() << "];" << endl; + output << "int nrhs" << ending.str()<< " = " << arguments.size() << ";" << endl; + writePrhs(output, output_type, temporary_terms, tef_terms, ending.str()); + + output << "mexCallMATLAB(" + << "nlhs" << ending.str() << ", " + << "plhs" << ending.str() << ", " + << "nrhs" << ending.str() << ", " + << "prhs" << ending.str() << ", \"" + << datatree.symbol_table.getName(symb_id) << "\");" << endl; + + if (symb_id == first_deriv_symb_id + && symb_id == second_deriv_symb_id) + output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl + << "TEFD_" << indx << " = mxGetPr(plhs" << ending.str() << "[1]);" << endl + << "TEFDD_" << indx << " = mxGetPr(plhs" << ending.str() << "[2]);" << endl + << "int TEFDD_" << indx << "_nrows = (int)mxGetM(plhs" << ending.str()<< "[2]);" << endl; + else if (symb_id == first_deriv_symb_id) + output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl + << "TEFD_" << indx << " = mxGetPr(plhs" << ending.str() << "[1]);" << endl; + else + output << "TEF_" << indx << " = mxGetPr(plhs" << ending.str() << "[0]);" << endl; + } + else + { + if (symb_id == first_deriv_symb_id + && symb_id == second_deriv_symb_id) + output << "[TEF_" << indx << " TEFD_"<< indx << " TEFDD_"<< indx << "] = "; + else if (symb_id == first_deriv_symb_id) + output << "[TEF_" << indx << " TEFD_"<< indx << "] = "; + else + output << "TEF_" << indx << " = "; + + output << datatree.symbol_table.getName(symb_id) << "("; + writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms); + output << ");" << endl; + } + } +} + +expr_t +ExternalFunctionNode::toStatic(DataTree &static_datatree) const +{ + vector static_arguments; + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + static_arguments.push_back((*it)->toStatic(static_datatree)); + return static_datatree.AddExternalFunction(symb_id, static_arguments); +} + +expr_t +ExternalFunctionNode::cloneDynamic(DataTree &dynamic_datatree) const +{ + vector dynamic_arguments; + for (vector::const_iterator it = arguments.begin(); + it != arguments.end(); it++) + dynamic_arguments.push_back((*it)->cloneDynamic(dynamic_datatree)); + return dynamic_datatree.AddExternalFunction(symb_id, dynamic_arguments); +} + +expr_t +ExternalFunctionNode::buildSimilarExternalFunctionNode(vector &alt_args, DataTree &alt_datatree) const +{ + return alt_datatree.AddExternalFunction(symb_id, alt_args); +} + FirstDerivExternalFunctionNode::FirstDerivExternalFunctionNode(DataTree &datatree_arg, int top_level_symb_id_arg, const vector &arguments_arg, From ec826635800ab04157cb80a7b21a66507de08541 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Tue, 12 May 2015 16:36:03 +0200 Subject: [PATCH 08/15] =?UTF-8?q?preprocessor:=20external=20functions=20bu?= =?UTF-8?q?g=20fix:=20fixes=20the=20case=20where=20an=20external=20functio?= =?UTF-8?q?n=20is=20contained=20in=20a=20local=20variable=20that=E2=80=99s?= =?UTF-8?q?=20used=20in=20an=20equation=20with=20leads/lags=20that=20requi?= =?UTF-8?q?re=20auxiliary=20equations.=20Closes=20#916?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ExprNode.cc | 39 +++++++++++++++++++++++++++++++++++++++ ExprNode.hh | 11 ++++++++++- StaticModel.cc | 11 +++++++++-- 3 files changed, 58 insertions(+), 3 deletions(-) diff --git a/ExprNode.cc b/ExprNode.cc index 3805c1a6..8798d796 100644 --- a/ExprNode.cc +++ b/ExprNode.cc @@ -308,6 +308,12 @@ NumConstNode::writeOutput(ostream &output, ExprNodeOutputType output_type, output << datatree.num_constants.get(id); } +bool +NumConstNode::containsExternalFunction() const +{ + return false; +} + double NumConstNode::eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException) { @@ -571,6 +577,12 @@ VariableNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, t datatree.local_variables_table[symb_id]->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block); } +bool +VariableNode::containsExternalFunction() const +{ + return false; +} + void VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -1714,6 +1726,12 @@ UnaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, te arg->collectTemporary_terms(temporary_terms, temporary_terms_inuse, Curr_Block); } +bool +UnaryOpNode::containsExternalFunction() const +{ + return arg->containsExternalFunction(); +} + void UnaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -2885,6 +2903,13 @@ BinaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, t } } +bool +BinaryOpNode::containsExternalFunction() const +{ + return arg1->containsExternalFunction() + || arg2->containsExternalFunction(); +} + void BinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -3963,6 +3988,14 @@ TrinaryOpNode::collectTemporary_terms(const temporary_terms_t &temporary_terms, } } +bool +TrinaryOpNode::containsExternalFunction() const +{ + return arg1->containsExternalFunction() + || arg2->containsExternalFunction() + || arg3->containsExternalFunction(); +} + void TrinaryOpNode::writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, @@ -4626,6 +4659,12 @@ AbstractExternalFunctionNode::writePrhs(ostream &output, ExprNodeOutputType outp } } +bool +AbstractExternalFunctionNode::containsExternalFunction() const +{ + return true; +} + ExternalFunctionNode::ExternalFunctionNode(DataTree &datatree_arg, int symb_id_arg, const vector &arguments_arg) : diff --git a/ExprNode.hh b/ExprNode.hh index b008333c..0500ff6d 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007-2014 Dynare Team + * Copyright (C) 2007-2015 Dynare Team * * This file is part of Dynare. * @@ -187,6 +187,9 @@ public: */ virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0; + //! returns true if the expr node contains an external function + virtual bool containsExternalFunction() const = 0; + //! Writes output of node (with no temporary terms and with "outside model" output type) void writeOutput(ostream &output) const; @@ -441,6 +444,7 @@ public: }; virtual void prepareForDerivation(); virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual bool containsExternalFunction() const; virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; virtual void collectTemporary_terms(const temporary_terms_t &temporary_terms, temporary_terms_inuse_t &temporary_terms_inuse, int Curr_Block) const; virtual double eval(const eval_context_t &eval_context) const throw (EvalException, EvalExternalFunctionException); @@ -486,6 +490,7 @@ public: VariableNode(DataTree &datatree_arg, int symb_id_arg, int lag_arg); virtual void prepareForDerivation(); virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual bool containsExternalFunction() const; virtual void collectDynamicVariables(SymbolType type_arg, set > &result) const; virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, @@ -552,6 +557,7 @@ public: virtual void prepareForDerivation(); virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const; virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual bool containsExternalFunction() const; virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; @@ -630,6 +636,7 @@ public: virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const; virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const; virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual bool containsExternalFunction() const; virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; @@ -724,6 +731,7 @@ public: virtual int precedence(ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const; virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const; virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; + virtual bool containsExternalFunction() const; virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const; @@ -795,6 +803,7 @@ public: virtual void prepareForDerivation(); virtual void computeTemporaryTerms(map &reference_count, temporary_terms_t &temporary_terms, bool is_matlab) const = 0; virtual void writeOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0; + virtual bool containsExternalFunction() const; virtual void writeExternalFunctionOutput(ostream &output, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms, deriv_node_temp_terms_t &tef_terms) const = 0; diff --git a/StaticModel.cc b/StaticModel.cc index 09fb9261..045e6336 100644 --- a/StaticModel.cc +++ b/StaticModel.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 Dynare Team + * Copyright (C) 2003-2015 Dynare Team * * This file is part of Dynare. * @@ -1927,9 +1927,16 @@ void StaticModel::writeAuxVarRecursiveDefinitions(const string &basename) const << "% from model file (.mod)" << endl << endl; + deriv_node_temp_terms_t tef_terms; + temporary_terms_t temporary_terms; + for (int i = 0; i < (int) aux_equations.size(); i++) + if (dynamic_cast(aux_equations[i])->containsExternalFunction()) + dynamic_cast(aux_equations[i])->writeExternalFunctionOutput(output, oMatlabStaticModel, + temporary_terms, tef_terms); + for (int i = 0; i < (int) aux_equations.size(); i++) { - dynamic_cast(aux_equations[i])->writeOutput(output, oMatlabStaticModel); + dynamic_cast(aux_equations[i])->writeOutput(output, oMatlabStaticModel, temporary_terms, tef_terms); output << ";" << endl; } } From 46ac39092d90fd82c1f7e1c12618019f4e8e9e6d Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Wed, 13 May 2015 15:12:21 +0200 Subject: [PATCH 09/15] preprocessor: add dr_display_tol to stoch_simul. #924 --- DynareBison.yy | 4 +++- DynareFlex.ll | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/DynareBison.yy b/DynareBison.yy index b7288da9..58f13f4b 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -84,7 +84,7 @@ class ParsingDriver; %token AIM_SOLVER ANALYTIC_DERIVATION AR AUTOCORR %token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION -%token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION +%token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION DR_DISPLAY_TOL %token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA %token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN %token BVAR_REPLIC BYTECODE ALL_VALUES_REQUIRED @@ -1094,6 +1094,7 @@ stoch_simul_primary_options : o_dr_algo | o_dr_logarithmic_reduction_tol | o_dr_logarithmic_reduction_maxiter | o_irf_plot_threshold + | o_dr_display_tol ; stoch_simul_options : stoch_simul_primary_options @@ -2966,6 +2967,7 @@ o_mcmc_jumping_covariance : MCMC_JUMPING_COVARIANCE EQUAL HESSIAN { driver.option_str("MCMC_jumping_covariance", $3); } ; o_irf_plot_threshold : IRF_PLOT_THRESHOLD EQUAL non_negative_number { driver.option_num("impulse_responses.plot_threshold", $3); }; +o_dr_display_tol : DR_DISPLAY_TOL EQUAL non_negative_number { driver.option_num("dr_display_tol", $3); }; o_consider_all_endogenous : CONSIDER_ALL_ENDOGENOUS { driver.option_str("endo_vars_for_moment_computations_in_estimation", "all_endogenous_variables"); }; o_consider_only_observed : CONSIDER_ONLY_OBSERVED { driver.option_str("endo_vars_for_moment_computations_in_estimation", "only_observed_variables"); }; o_no_homotopy : NO_HOMOTOPY { driver.option_num("no_homotopy", "1"); }; diff --git a/DynareFlex.ll b/DynareFlex.ll index 4428dd37..7201350b 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -567,6 +567,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 period {return token::PERIOD;} outfile {return token::OUTFILE;} outvars {return token::OUTVARS;} +dr_display_tol {return token::DR_DISPLAY_TOL;} [\$][^$]*[\$] { strtok(yytext+1, "$"); From 8f458eb961ecad2e2535c9ebcd5ff57e4900dfc0 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Wed, 13 May 2015 15:14:34 +0200 Subject: [PATCH 10/15] preprocessor: add huge_number to estimation and osr. #924 --- DynareBison.yy | 5 ++++- DynareFlex.ll | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/DynareBison.yy b/DynareBison.yy index 58f13f4b..740c6578 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -84,7 +84,7 @@ class ParsingDriver; %token AIM_SOLVER ANALYTIC_DERIVATION AR AUTOCORR %token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION -%token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION DR_DISPLAY_TOL +%token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION DR_DISPLAY_TOL HUGE_NUMBER %token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA %token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN %token BVAR_REPLIC BYTECODE ALL_VALUES_REQUIRED @@ -1714,6 +1714,7 @@ estimation_options : o_datafile | o_proposal_approximation | o_distribution_approximation | o_dirname + | o_huge_number ; list_optim_option : QUOTED_STRING COMMA QUOTED_STRING @@ -1770,6 +1771,7 @@ osr_options : stoch_simul_primary_options | o_osr_tolf | o_opt_algo | o_optim + | o_huge_number ; osr : OSR ';' @@ -2549,6 +2551,7 @@ o_file : FILE EQUAL filename { driver.option_str("file", $3); }; o_series : SERIES EQUAL symbol { driver.option_str("series", $3); }; o_datafile : DATAFILE EQUAL filename { driver.option_str("datafile", $3); }; o_dirname : DIRNAME EQUAL filename { driver.option_str("dirname", $3); }; +o_huge_number : HUGE_NUMBER EQUAL non_negative_number { driver.option_num("huge_number", $3); }; o_nobs : NOBS EQUAL vec_int { driver.option_vec_int("nobs", $3); } | NOBS EQUAL vec_int_number diff --git a/DynareFlex.ll b/DynareFlex.ll index 7201350b..91de01a2 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -567,6 +567,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 period {return token::PERIOD;} outfile {return token::OUTFILE;} outvars {return token::OUTVARS;} +huge_number {return token::HUGE_NUMBER;} dr_display_tol {return token::DR_DISPLAY_TOL;} [\$][^$]*[\$] { From 23545052a8a10393e2b988a7af175b7da889d97c Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Wed, 13 May 2015 15:32:24 +0200 Subject: [PATCH 11/15] preprocessor: add use_tarb option to estimation. #940 --- DynareBison.yy | 5 +++-- DynareFlex.ll | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/DynareBison.yy b/DynareBison.yy index 740c6578..7af46067 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -83,7 +83,7 @@ class ParsingDriver; } %token AIM_SOLVER ANALYTIC_DERIVATION AR AUTOCORR -%token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION +%token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION USE_TARB %token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION DR_DISPLAY_TOL HUGE_NUMBER %token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA %token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN @@ -1715,6 +1715,7 @@ estimation_options : o_datafile | o_distribution_approximation | o_dirname | o_huge_number + | o_use_tarb ; list_optim_option : QUOTED_STRING COMMA QUOTED_STRING @@ -2872,7 +2873,7 @@ o_equations : EQUATIONS EQUAL vec_int | EQUATIONS EQUAL vec_int_number { driver.option_vec_int("ms.equations",$3); } ; - +o_use_tarb : USE_TARB { driver.option_num("TaRB.use_TaRB", "1"); }; o_instruments : INSTRUMENTS EQUAL '(' symbol_list ')' {driver.option_symbol_list("instruments"); }; o_ext_func_name : EXT_FUNC_NAME EQUAL filename { driver.external_function_option("name", $3); }; diff --git a/DynareFlex.ll b/DynareFlex.ll index 91de01a2..992cdb03 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -569,6 +569,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 outvars {return token::OUTVARS;} huge_number {return token::HUGE_NUMBER;} dr_display_tol {return token::DR_DISPLAY_TOL;} +use_tarb {return token::USE_TARB;} [\$][^$]*[\$] { strtok(yytext+1, "$"); From e00b7b62f6e003493426016d54334806bfebfdc5 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Wed, 13 May 2015 15:46:52 +0200 Subject: [PATCH 12/15] preprocessor: add tarb_mode_compute option to estimation. #940 --- DynareBison.yy | 4 +++- DynareFlex.ll | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/DynareBison.yy b/DynareBison.yy index 7af46067..47d241e6 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -82,7 +82,7 @@ class ParsingDriver; #define yylex driver.lexer->lex } -%token AIM_SOLVER ANALYTIC_DERIVATION AR AUTOCORR +%token AIM_SOLVER ANALYTIC_DERIVATION AR AUTOCORR TARB_MODE_COMPUTE %token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION USE_TARB %token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION DR_DISPLAY_TOL HUGE_NUMBER %token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA @@ -1716,6 +1716,7 @@ estimation_options : o_datafile | o_dirname | o_huge_number | o_use_tarb + | o_tarb_mode_compute ; list_optim_option : QUOTED_STRING COMMA QUOTED_STRING @@ -2874,6 +2875,7 @@ o_equations : EQUATIONS EQUAL vec_int { driver.option_vec_int("ms.equations",$3); } ; o_use_tarb : USE_TARB { driver.option_num("TaRB.use_TaRB", "1"); }; +o_tarb_mode_compute : TARB_MODE_COMPUTE EQUAL INT_NUMBER { driver.option_num("TaRB.mode_compute", $3); }; o_instruments : INSTRUMENTS EQUAL '(' symbol_list ')' {driver.option_symbol_list("instruments"); }; o_ext_func_name : EXT_FUNC_NAME EQUAL filename { driver.external_function_option("name", $3); }; diff --git a/DynareFlex.ll b/DynareFlex.ll index 992cdb03..05867db7 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -570,6 +570,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 huge_number {return token::HUGE_NUMBER;} dr_display_tol {return token::DR_DISPLAY_TOL;} use_tarb {return token::USE_TARB;} +tarb_mode_compute {return token::TARB_MODE_COMPUTE;} [\$][^$]*[\$] { strtok(yytext+1, "$"); From 6f4a19bb26771d3124291586adc28f28be6b8b86 Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Wed, 13 May 2015 15:49:41 +0200 Subject: [PATCH 13/15] preprocessor: add tarb_new_block_probability option to estimation. #940 --- DynareBison.yy | 4 +++- DynareFlex.ll | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/DynareBison.yy b/DynareBison.yy index 47d241e6..5585267e 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -83,7 +83,7 @@ class ParsingDriver; } %token AIM_SOLVER ANALYTIC_DERIVATION AR AUTOCORR TARB_MODE_COMPUTE -%token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION USE_TARB +%token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION USE_TARB TARB_NEW_BLOCK_PROBABILITY %token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION DR_DISPLAY_TOL HUGE_NUMBER %token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA %token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN @@ -1717,6 +1717,7 @@ estimation_options : o_datafile | o_huge_number | o_use_tarb | o_tarb_mode_compute + | o_tarb_new_block_probability ; list_optim_option : QUOTED_STRING COMMA QUOTED_STRING @@ -2876,6 +2877,7 @@ o_equations : EQUATIONS EQUAL vec_int ; o_use_tarb : USE_TARB { driver.option_num("TaRB.use_TaRB", "1"); }; o_tarb_mode_compute : TARB_MODE_COMPUTE EQUAL INT_NUMBER { driver.option_num("TaRB.mode_compute", $3); }; +o_tarb_new_block_probability : TARB_NEW_BLOCK_PROBABILITY EQUAL non_negative_number {driver.option_num("TaRB.new_block_probability",$3); }; o_instruments : INSTRUMENTS EQUAL '(' symbol_list ')' {driver.option_symbol_list("instruments"); }; o_ext_func_name : EXT_FUNC_NAME EQUAL filename { driver.external_function_option("name", $3); }; diff --git a/DynareFlex.ll b/DynareFlex.ll index 05867db7..f6c67669 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -571,6 +571,8 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 dr_display_tol {return token::DR_DISPLAY_TOL;} use_tarb {return token::USE_TARB;} tarb_mode_compute {return token::TARB_MODE_COMPUTE;} +tarb_new_block_probability {return token::TARB_NEW_BLOCK_PROBABILITY;} + [\$][^$]*[\$] { strtok(yytext+1, "$"); From 691af085cd12cb7baa78f38a0387d00a643d3ddf Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Wed, 13 May 2015 16:09:50 +0200 Subject: [PATCH 14/15] preprocessor: add tarb_optim option to estimation. #940 --- DynareBison.yy | 14 +++++++++++++- DynareFlex.ll | 2 +- ParsingDriver.cc | 28 ++++++++++++++++++++++++++++ ParsingDriver.hh | 5 +++++ 4 files changed, 47 insertions(+), 2 deletions(-) diff --git a/DynareBison.yy b/DynareBison.yy index 5585267e..bd9300e1 100644 --- a/DynareBison.yy +++ b/DynareBison.yy @@ -85,7 +85,7 @@ class ParsingDriver; %token AIM_SOLVER ANALYTIC_DERIVATION AR AUTOCORR TARB_MODE_COMPUTE %token BAYESIAN_IRF BETA_PDF BLOCK USE_CALIBRATION USE_TARB TARB_NEW_BLOCK_PROBABILITY %token BVAR_DENSITY BVAR_FORECAST NODECOMPOSITION DR_DISPLAY_TOL HUGE_NUMBER -%token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA +%token BVAR_PRIOR_DECAY BVAR_PRIOR_FLAT BVAR_PRIOR_LAMBDA TARB_OPTIM %token BVAR_PRIOR_MU BVAR_PRIOR_OMEGA BVAR_PRIOR_TAU BVAR_PRIOR_TRAIN %token BVAR_REPLIC BYTECODE ALL_VALUES_REQUIRED %token CALIB_SMOOTHER CHANGE_TYPE CHECK CONDITIONAL_FORECAST CONDITIONAL_FORECAST_PATHS CONF_SIG CONSTANT CONTROLLED_VAREXO CORR COVAR CUTOFF CYCLE_REDUCTION LOGARITHMIC_REDUCTION @@ -1718,6 +1718,7 @@ estimation_options : o_datafile | o_use_tarb | o_tarb_mode_compute | o_tarb_new_block_probability + | o_tarb_optim ; list_optim_option : QUOTED_STRING COMMA QUOTED_STRING @@ -1730,6 +1731,16 @@ optim_options : list_optim_option | optim_options COMMA list_optim_option; ; +list_tarb_optim_option : QUOTED_STRING COMMA QUOTED_STRING + { driver.tarb_optim_options_string($1, $3); } + | QUOTED_STRING COMMA signed_number + { driver.tarb_optim_options_num($1, $3); } + ; + +tarb_optim_options : list_tarb_optim_option + | tarb_optim_options COMMA list_tarb_optim_option; + ; + varobs : VAROBS { driver.check_varobs(); } varobs_list ';'; varobs_list : varobs_list symbol @@ -2621,6 +2632,7 @@ o_posterior_max_subsample_draws : POSTERIOR_MAX_SUBSAMPLE_DRAWS EQUAL INT_NUMBER o_mh_drop : MH_DROP EQUAL non_negative_number { driver.option_num("mh_drop", $3); }; o_mh_jscale : MH_JSCALE EQUAL non_negative_number { driver.option_num("mh_jscale", $3); }; o_optim : OPTIM EQUAL '(' optim_options ')'; +o_tarb_optim : TARB_OPTIM EQUAL '(' tarb_optim_options ')'; o_mh_init_scale : MH_INIT_SCALE EQUAL non_negative_number { driver.option_num("mh_init_scale", $3); }; o_mode_file : MODE_FILE EQUAL filename { driver.option_str("mode_file", $3); }; o_mode_compute : MODE_COMPUTE EQUAL INT_NUMBER { driver.option_num("mode_compute", $3); }; diff --git a/DynareFlex.ll b/DynareFlex.ll index f6c67669..5466487d 100644 --- a/DynareFlex.ll +++ b/DynareFlex.ll @@ -572,7 +572,7 @@ DATE -?[0-9]+([YyAa]|[Mm]([1-9]|1[0-2])|[Qq][1-4]|[Ww]([1-9]{1}|[1-4][0-9]|5[0-2 use_tarb {return token::USE_TARB;} tarb_mode_compute {return token::TARB_MODE_COMPUTE;} tarb_new_block_probability {return token::TARB_NEW_BLOCK_PROBABILITY;} - +tarb_optim {return token::TARB_OPTIM;} [\$][^$]*[\$] { strtok(yytext+1, "$"); diff --git a/ParsingDriver.cc b/ParsingDriver.cc index 67c4be45..ba541ec8 100644 --- a/ParsingDriver.cc +++ b/ParsingDriver.cc @@ -1630,6 +1630,34 @@ ParsingDriver::optim_options_num(string *name, string *value) delete value; } +void +ParsingDriver::tarb_optim_options_helper(const string &name) +{ + if (options_list.string_options.find("TaRB.optim_opt") == options_list.string_options.end()) + options_list.string_options["TaRB.optim_opt"] = ""; + else + options_list.string_options["TaRB.optim_opt"] += ","; + options_list.string_options["TaRB.optim_opt"] += "''" + name + "'',"; +} + +void +ParsingDriver::tarb_optim_options_string(string *name, string *value) +{ + tarb_optim_options_helper(*name); + options_list.string_options["TaRB.optim_opt"] += "''" + *value + "''"; + delete name; + delete value; +} + +void +ParsingDriver::tarb_optim_options_num(string *name, string *value) +{ + tarb_optim_options_helper(*name); + options_list.string_options["TaRB.optim_opt"] += *value; + delete name; + delete value; +} + void ParsingDriver::check_varobs() { diff --git a/ParsingDriver.hh b/ParsingDriver.hh index d4ebc05d..dd93276c 100644 --- a/ParsingDriver.hh +++ b/ParsingDriver.hh @@ -98,6 +98,7 @@ private: //! Creates option "optim_opt" in OptionsList if it doesn't exist, else add a comma, and adds the option name void optim_options_helper(const string &name); + void tarb_optim_options_helper(const string &name); //! Stores temporary symbol table SymbolList symbol_list; @@ -443,6 +444,10 @@ public: void optim_options_string(string *name, string *value); //! Adds an optimization option (numeric value) void optim_options_num(string *name, string *value); + //! Adds a TaRB optimization option (string value) + void tarb_optim_options_string(string *name, string *value); + //! Adds a TaRB optimization option (numeric value) + void tarb_optim_options_num(string *name, string *value); //! Check that no observed variable has yet be defined void check_varobs(); //! Add a new observed variable From 39978f905f7a6084e123ac92a3be2748b11699d1 Mon Sep 17 00:00:00 2001 From: Michel Juillard Date: Wed, 13 May 2015 17:11:39 +0200 Subject: [PATCH 15/15] changing code for making directory baseline in order to comply with mingw --- DynamicModel.cc | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/DynamicModel.cc b/DynamicModel.cc index b7eb27d8..339cbe97 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -4289,24 +4289,29 @@ DynamicModel::isChecksumMatching(const string &basename) const result.process_bytes(private_buffer,strlen(private_buffer)); } + bool basename_dir_exists = false; +#ifdef _WIN32 + int r = mkdir(basename.c_str()); +#else + int r = mkdir(basename.c_str(), 0777); +#endif + if (r < 0) + if (errno != EEXIST) + { + perror("ERROR"); + exit(EXIT_FAILURE); + } + else + basename_dir_exists = true; + // check whether basename directory exist. If not, create it. // If it does, read old checksum if it exist fstream checksum_file; string filename = basename + "/checksum"; unsigned int old_checksum = 0; - struct stat sd; - if (stat(basename.c_str(), &sd) != 0) + // read old checksum if it exists + if (basename_dir_exists) { - const int dir_err = mkdir(basename.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); - if (dir_err == -1) - { - cerr << "ERROR: can't create directory " << basename << endl; - exit(EXIT_FAILURE); - } - } - else - { - // read old checksum if it exists checksum_file.open(filename.c_str(), ios::in | ios::binary); if (checksum_file.is_open()) {