From f13b95cb873c547438319111de008928634ea1ee Mon Sep 17 00:00:00 2001 From: ferhat <ferhat@ac1d8469-bf42-47a9-8791-bf33cf982152> Date: Fri, 22 Jan 2010 10:03:29 +0000 Subject: [PATCH] "bytecode" option can be used without "block" option git-svn-id: https://www.dynare.org/svn/dynare/trunk@3373 ac1d8469-bf42-47a9-8791-bf33cf982152 --- CodeInterpreter.hh | 25 ++++++- ComputingTasks.cc | 2 +- DynamicModel.cc | 158 +++++++++++++++++++++++++++++++++++++++++---- DynamicModel.hh | 16 ++++- ExprNode.hh | 1 + ModFile.cc | 19 +++--- ModelTree.cc | 109 +++++++++++++++++++++++++++++++ ModelTree.hh | 7 ++ StaticModel.cc | 149 +++++++++++++++++++++++++++++++++++++++--- StaticModel.hh | 19 ++++-- 10 files changed, 467 insertions(+), 38 deletions(-) diff --git a/CodeInterpreter.hh b/CodeInterpreter.hh index 90774f6a..e8666581 100644 --- a/CodeInterpreter.hh +++ b/CodeInterpreter.hh @@ -82,6 +82,7 @@ enum Tags FSTPR, //!< Loads a residual from the stack - 12 FSTPG, //!< Loads a derivative from the stack - 13 + FSTPG2, //!< Loads a derivative matrix from the stack - 13 FUNARY, //!< A Unary operator - 14 FBINARY, //!< A binary operator - 15 @@ -533,6 +534,28 @@ public: }; }; +class FSTPG2_ : public TagWithTwoArguments<unsigned int, unsigned int> +{ +public: + inline FSTPG2_() : TagWithTwoArguments<unsigned int, unsigned int>::TagWithTwoArguments(FSTPG2, 0, 0) + { + }; + inline FSTPG2_(const unsigned int pos_arg1, const unsigned int pos_arg2) : TagWithTwoArguments<unsigned int, unsigned int>::TagWithTwoArguments(FSTPG2, pos_arg1, pos_arg2) + { + }; + inline unsigned int + get_row() + { + return arg1; + }; + inline unsigned int + get_col() + { + return arg2; + }; +}; + + class FUNARY_ : public TagWithOneArgument<uint8_t> { public: @@ -728,7 +751,7 @@ public: op_code = FBEGINBLOCK; size = 0; type = UNKNOWN; /*variable = NULL; equation = NULL;*/ is_linear = false; endo_nbr = 0; Max_Lag = 0; Max_Lead = 0; u_count_int = 0; }; - inline FBEGINBLOCK_(unsigned int &size_arg, BlockSimulationType &type_arg, int unsigned first_element, int unsigned &block_size, + inline FBEGINBLOCK_(unsigned int size_arg, BlockSimulationType type_arg, int unsigned first_element, int unsigned block_size, const vector<int> &variable_arg, const vector<int> &equation_arg, bool is_linear_arg, int endo_nbr_arg, int Max_Lag_arg, int Max_Lead_arg, int &u_count_int_arg) { diff --git a/ComputingTasks.cc b/ComputingTasks.cc index 20118f1e..ff26e0bf 100644 --- a/ComputingTasks.cc +++ b/ComputingTasks.cc @@ -878,7 +878,7 @@ PlannerObjectiveStatement::checkPass(ModFileStructure &mod_file_struct) void PlannerObjectiveStatement::computingPass() { - model_tree->computingPass(eval_context_type(), false, true, false); + model_tree->computingPass(eval_context_type(), false, true, false, false); } void diff --git a/DynamicModel.cc b/DynamicModel.cc index 9e39502b..21058288 100644 --- a/DynamicModel.cc +++ b/DynamicModel.cc @@ -81,6 +81,18 @@ DynamicModel::compileChainRuleDerivative(ofstream &code_file, int eqr, int varr, } } +void +DynamicModel::initializeVariablesAndEquations() +{ + for(int j=0; j<equation_number(); j++) + { + equation_reordered.push_back(j); + variable_reordered.push_back(j); + } +} + + + void DynamicModel::computeTemporaryTermsOrdered() { @@ -190,14 +202,21 @@ DynamicModel::computeTemporaryTermsOrdered() it->second->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block); v_temporary_terms_inuse[block] = temporary_terms_in_use; } - // Add a mapping form node ID to temporary terms order - int j = 0; - for (temporary_terms_type::const_iterator it = temporary_terms.begin(); - it != temporary_terms.end(); it++) - map_idx[(*it)->idx] = j++; + computeTemporaryTermsMapping(); } } +void +DynamicModel::computeTemporaryTermsMapping() +{ + // Add a mapping form node ID to temporary terms order + int j = 0; + for (temporary_terms_type::const_iterator it = temporary_terms.begin(); + it != temporary_terms.end(); it++) + map_idx[(*it)->idx] = j++; +} + + void DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const { @@ -710,7 +729,118 @@ DynamicModel::writeModelEquationsOrdered_M(const string &dynamic_basename) const } void -DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const string bin_basename, map_idx_type map_idx) const +DynamicModel::writeModelEquationsCode(const string file_name, const string bin_basename, map_idx_type map_idx) const +{ + ostringstream tmp_output; + ofstream code_file; + bool file_open = false; + string main_name = file_name; + + main_name += ".cod"; + code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate); + if (!code_file.is_open()) + { + cout << "Error : Can't open file \"" << main_name << "\" for writing\n"; + exit(EXIT_FAILURE); + } + + + int count_u; + int u_count_int = 0; + BlockSimulationType simulation_type; + if ((max_endo_lag > 0) && (max_endo_lead > 0)) + simulation_type = SOLVE_TWO_BOUNDARIES_COMPLETE; + else if ((max_endo_lag >= 0) && (max_endo_lead == 0)) + simulation_type = SOLVE_FORWARD_COMPLETE; + else + simulation_type = SOLVE_BACKWARD_COMPLETE; + + Write_Inf_To_Bin_File(file_name, u_count_int, file_open, simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE, symbol_table.endo_nbr() ); + file_open = true; + + //Temporary variables declaration + FDIMT_ fdimt(temporary_terms.size()); + fdimt.write(code_file); + + FBEGINBLOCK_ fbeginblock(symbol_table.endo_nbr(), + simulation_type, + 0, + symbol_table.endo_nbr(), + variable_reordered, + equation_reordered, + false, + symbol_table.endo_nbr(), + 0, + 0, + u_count_int + ); + fbeginblock.write(code_file); + + compileTemporaryTerms(code_file, temporary_terms, map_idx, true, false); + + compileModelEquations(code_file, temporary_terms, map_idx, true, false); + + FENDEQU_ fendequ; + fendequ.write(code_file); + vector<vector<pair<pair<int, int>, int > > > derivatives; + derivatives.resize(symbol_table.endo_nbr()); + count_u = symbol_table.endo_nbr(); + for (first_derivatives_type::const_iterator it = first_derivatives.begin(); + it != first_derivatives.end(); it++) + { + int deriv_id = it->first.second; + if (getTypeByDerivID(deriv_id) == eEndogenous) + { + NodeID d1 = it->second; + unsigned int eq = it->first.first; + int symb = getSymbIDByDerivID(deriv_id); + unsigned int var = symbol_table.getTypeSpecificID(symb); + int lag = getLagByDerivID(deriv_id); + if (!derivatives[eq].size()) + derivatives[eq].clear(); + derivatives[eq].push_back(make_pair(make_pair(var, lag), count_u)); + d1->compile(code_file, false, temporary_terms, map_idx, true, false); + + FSTPU_ fstpu(count_u); + fstpu.write(code_file); + count_u++; + } + } + for (int i = 0; i < symbol_table.endo_nbr(); i++) + { + FLDR_ fldr(i); + fldr.write(code_file); + for(vector<pair<pair<int, int>, int> >::const_iterator it = derivatives[i].begin(); + it != derivatives[i].end(); it++) + { + FLDU_ fldu(it->second); + fldu.write(code_file); + FLDV_ fldv(eEndogenous, it->first.first, it->first.second); + fldv.write(code_file); + FBINARY_ fbinary(oTimes); + fbinary.write(code_file); + if (it != derivatives[i].begin()) + { + FBINARY_ fbinary(oPlus); + fbinary.write(code_file); + } + } + FBINARY_ fbinary(oMinus); + fbinary.write(code_file); + FSTPU_ fstpu(i); + fstpu.write(code_file); + } + FENDBLOCK_ fendblock; + fendblock.write(code_file); + FEND_ fend; + fend.write(code_file); + code_file.close(); +} + + + +void +DynamicModel::writeModelEquationsCode_Block(const string file_name, const string bin_basename, map_idx_type map_idx) const { struct Uff_l { @@ -766,7 +896,7 @@ DynamicModel::writeModelEquationsCodeOrdered(const string file_name, const strin if (simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE || simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_FORWARD_COMPLETE) { - Write_Inf_To_Bin_File(file_name, bin_basename, block, u_count_int, file_open, + Write_Inf_To_Bin_File_Block(file_name, bin_basename, block, u_count_int, file_open, simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE); file_open = true; } @@ -1109,7 +1239,7 @@ DynamicModel::reform(const string name1) const } void -DynamicModel::Write_Inf_To_Bin_File(const string &dynamic_basename, const string &bin_basename, const int &num, +DynamicModel::Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename, const int &num, int &u_count_int, bool &file_open, bool is_two_boundaries) const { int j; @@ -1940,7 +2070,7 @@ DynamicModel::collect_first_order_derivatives_endogenous() void DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, bool paramsDerivatives, - const eval_context_type &eval_context, bool no_tmp_terms, bool block, bool use_dll) + const eval_context_type &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode) { assert(jacobianExo || !(hessian || thirdDerivatives || paramsDerivatives)); @@ -2025,7 +2155,11 @@ DynamicModel::computingPass(bool jacobianExo, bool hessian, bool thirdDerivative } else if (!no_tmp_terms) - computeTemporaryTerms(!use_dll); + { + computeTemporaryTerms(!use_dll); + if (bytecode) + computeTemporaryTermsMapping(); + } } map<pair<pair<int, pair<int, int> >, pair<int, int> >, int> @@ -2274,7 +2408,9 @@ DynamicModel::writeDynamicFile(const string &basename, bool block, bool bytecode { int r; if (block && bytecode) - writeModelEquationsCodeOrdered(basename + "_dynamic", basename, map_idx); + writeModelEquationsCode_Block(basename + "_dynamic", basename, map_idx); + else if (!block && bytecode) + writeModelEquationsCode(basename + "_dynamic", basename, map_idx); else if (block && !bytecode) { #ifdef _WIN32 diff --git a/DynamicModel.hh b/DynamicModel.hh index 32da867a..0c40f5df 100644 --- a/DynamicModel.hh +++ b/DynamicModel.hh @@ -96,7 +96,10 @@ private: //! Writes the Block reordred structure of the model in M output void writeModelEquationsOrdered_M(const string &dynamic_basename) const; //! Writes the code of the Block reordred structure of the model in virtual machine bytecode - void writeModelEquationsCodeOrdered(const string file_name, const string bin_basename, map_idx_type map_idx) const; + void writeModelEquationsCode_Block(const string file_name, const string bin_basename, map_idx_type map_idx) const; + //! Writes the code of the model in virtual machine bytecode + void writeModelEquationsCode(const string file_name, const string bin_basename, map_idx_type map_idx) const; + //! Computes jacobian and prepares for equation normalization /*! Using values from initval/endval blocks and parameter initializations: - computes the jacobian for the model w.r. to contemporaneous variables @@ -112,7 +115,11 @@ private: string reform(string name) const; map_idx_type map_idx; + //! sorts the temporary terms in the blocks order void computeTemporaryTermsOrdered(); + + //! creates a mapping from the index of temporary terms to a natural index + void computeTemporaryTermsMapping(); //! Write derivative code of an equation w.r. to a variable void compileDerivative(ofstream &code_file, int eq, int symb_id, int lag, map_idx_type &map_idx) const; //! Write chain rule derivative code of an equation w.r. to a variable @@ -217,12 +224,12 @@ public: \param no_tmp_terms if true, no temporary terms will be computed in the dynamic files */ void computingPass(bool jacobianExo, bool hessian, bool thirdDerivatives, bool paramsDerivatives, - const eval_context_type &eval_context, bool no_tmp_terms, bool block, bool use_dll); + const eval_context_type &eval_context, bool no_tmp_terms, bool block, bool use_dll, bool bytecode); //! Writes model initialization and lead/lag incidence matrix to output void writeOutput(ostream &output, const string &basename, bool block, bool byte_code, bool use_dll) const; //! Adds informations for simulation in a binary file - void Write_Inf_To_Bin_File(const string &dynamic_basename, const string &bin_basename, + void Write_Inf_To_Bin_File_Block(const string &dynamic_basename, const string &bin_basename, const int &num, int &u_count_int, bool &file_open, bool is_two_boundaries) const; //! Writes dynamic model file void writeDynamicFile(const string &basename, bool block, bool bytecode, bool use_dll) const; @@ -235,6 +242,9 @@ public: //! Writes LaTeX file with the equations of the dynamic model void writeLatexFile(const string &basename) const; + //! Initialize equation_reordered & variable_reordered + void initializeVariablesAndEquations(); + virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException); virtual int getDynJacobianCol(int deriv_id) const throw (UnknownDerivIDException); diff --git a/ExprNode.hh b/ExprNode.hh index f305c611..4403e24c 100644 --- a/ExprNode.hh +++ b/ExprNode.hh @@ -108,6 +108,7 @@ class ExprNode friend class DataTree; friend class DynamicModel; friend class StaticModel; + friend class ModelTree; friend class ExprNodeLess; friend class NumConstNode; friend class VariableNode; diff --git a/ModFile.cc b/ModFile.cc index 0597b125..74016ef1 100644 --- a/ModFile.cc +++ b/ModFile.cc @@ -129,11 +129,6 @@ ModFile::checkPass() exit(EXIT_FAILURE); } - if (byte_code && !block) - { - cerr << "ERROR: In 'model' block, can't use option 'bytecode' without option 'block'" << endl; - exit(EXIT_FAILURE); - } if ( (stochastic_statement_present || mod_file_struct.check_present || mod_file_struct.steady_present) && no_static) { cerr << "no_static option is incompatible with stochastic simulation, estimation, optimal policy, steady or check command" << endl; @@ -193,12 +188,18 @@ ModFile::computingPass(bool no_tmp_terms) // Compute static model and its derivatives dynamic_model.toStatic(static_model); if(!no_static) - static_model.computingPass(global_eval_context, no_tmp_terms, false, block); + { + static_model.initializeVariablesAndEquations(); + static_model.computingPass(global_eval_context, no_tmp_terms, false, block, byte_code); + } // Set things to compute for dynamic model if (dynamic_model_needed) { if (mod_file_struct.simul_present) - dynamic_model.computingPass(false, false, false, false, global_eval_context, no_tmp_terms, block, use_dll); + { + dynamic_model.initializeVariablesAndEquations(); + dynamic_model.computingPass(false, false, false, false, global_eval_context, no_tmp_terms, block, use_dll, byte_code); + } else { if (mod_file_struct.order_option < 1 || mod_file_struct.order_option > 3) @@ -209,11 +210,11 @@ ModFile::computingPass(bool no_tmp_terms) bool hessian = mod_file_struct.order_option >= 2 || mod_file_struct.identification_present; bool thirdDerivatives = mod_file_struct.order_option == 3; bool paramsDerivatives = mod_file_struct.identification_present; - dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivatives, global_eval_context, no_tmp_terms, false, use_dll); + dynamic_model.computingPass(true, hessian, thirdDerivatives, paramsDerivatives, global_eval_context, no_tmp_terms, false, use_dll, byte_code); } } else - dynamic_model.computingPass(true, true, false, false, global_eval_context, no_tmp_terms, false, false); + dynamic_model.computingPass(true, true, false, false, global_eval_context, no_tmp_terms, false, false, byte_code); } for (vector<Statement *>::iterator it = statements.begin(); diff --git a/ModelTree.cc b/ModelTree.cc index d7d6f1e2..4490a338 100644 --- a/ModelTree.cc +++ b/ModelTree.cc @@ -1014,6 +1014,32 @@ ModelTree::writeTemporaryTerms(const temporary_terms_type &tt, ostream &output, output << ";" << endl; } +void +ModelTree::compileTemporaryTerms(ostream &code_file, const temporary_terms_type &tt, map_idx_type map_idx, bool dynamic, bool steady_dynamic) const +{ + // Local var used to keep track of temp nodes already written + temporary_terms_type tt2; + for (temporary_terms_type::const_iterator it = tt.begin(); + it != tt.end(); it++) + { + (*it)->compile(code_file, false, tt2, map_idx, dynamic, steady_dynamic); + if (dynamic) + { + FSTPT_ fstpt((int)(map_idx.find((*it)->idx)->second)); + fstpt.write(code_file); + } + else + { + FSTPST_ fstpst((int)(map_idx.find((*it)->idx)->second)); + fstpst.write(code_file); + } + // Insert current node into tt2 + tt2.insert(*it); + } +} + + + void ModelTree::writeModelLocalVariables(ostream &output, ExprNodeOutputType output_type) const { @@ -1079,6 +1105,89 @@ ModelTree::writeModelEquations(ostream &output, ExprNodeOutputType output_type) } } +void +ModelTree::compileModelEquations(ostream &code_file, const temporary_terms_type &tt, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const +{ + for (int eq = 0; eq < (int) equations.size(); eq++) + { + BinaryOpNode *eq_node = equations[eq]; + NodeID lhs = eq_node->get_arg1(); + NodeID 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_type()); + } + catch (ExprNode::EvalException &e) + { + } + + if (vrhs != 0) // The right hand side of the equation is not empty ==> residual=lhs-rhs; + { + lhs->compile(code_file, false, temporary_terms, map_idx, dynamic, steady_dynamic); + rhs->compile(code_file, false, temporary_terms, map_idx, dynamic, steady_dynamic); + + FBINARY_ fbinary(oMinus); + fbinary.write(code_file); + + FSTPR_ fstpr(eq); + fstpr.write(code_file); + } + else // The right hand side of the equation is empty ==> residual=lhs; + { + lhs->compile(code_file, false, temporary_terms, map_idx, dynamic, steady_dynamic); + FSTPR_ fstpr(eq); + fstpr.write(code_file); + } + } +} + +void +ModelTree::Write_Inf_To_Bin_File(const string &basename, + int &u_count_int, bool &file_open, bool is_two_boundaries, int block_mfs) const +{ + int j; + std::ofstream SaveCode; + const string bin_basename = basename + ".bin"; + if (file_open) + SaveCode.open(bin_basename.c_str(), ios::out | ios::in | ios::binary | ios::ate); + else + SaveCode.open(bin_basename.c_str(), ios::out | ios::binary); + if (!SaveCode.is_open()) + { + cout << "Error : Can't open file \"" << bin_basename << "\" for writing\n"; + exit(EXIT_FAILURE); + } + u_count_int = 0; + for (first_derivatives_type::const_iterator it = first_derivatives.begin();it != first_derivatives.end(); it++) + { + int deriv_id = it->first.second; + if (getTypeByDerivID(deriv_id) == eEndogenous) + { + int eq = it->first.first; + int symb = getSymbIDByDerivID(deriv_id); + int var = symbol_table.getTypeSpecificID(symb); + int lag = getLagByDerivID(deriv_id); + SaveCode.write(reinterpret_cast<char *>(&eq), sizeof(eq)); + int varr = var + lag * block_mfs; + SaveCode.write(reinterpret_cast<char *>(&varr), sizeof(varr)); + SaveCode.write(reinterpret_cast<char *>(&lag), sizeof(lag)); + int u = u_count_int + block_mfs; + SaveCode.write(reinterpret_cast<char *>(&u), sizeof(u)); + u_count_int++; + } + } + if (is_two_boundaries) + u_count_int += symbol_table.endo_nbr(); + for (j = 0; j < (int) symbol_table.endo_nbr(); j++) + SaveCode.write(reinterpret_cast<char *>(&j), sizeof(j)); + for (j = 0; j < (int) symbol_table.endo_nbr(); j++) + SaveCode.write(reinterpret_cast<char *>(&j), sizeof(j)); + SaveCode.close(); +} + void ModelTree::writeLatexModelFile(const string &filename, ExprNodeOutputType output_type) const { diff --git a/ModelTree.hh b/ModelTree.hh index 4614a12c..4bd6a0ef 100644 --- a/ModelTree.hh +++ b/ModelTree.hh @@ -109,11 +109,18 @@ protected: void computeTemporaryTerms(bool is_matlab); //! Writes temporary terms void writeTemporaryTerms(const temporary_terms_type &tt, ostream &output, ExprNodeOutputType output_type) const; + //! Compiles temporary terms + void compileTemporaryTerms(ostream &code_file, const temporary_terms_type &tt, map_idx_type map_idx, bool dynamic, bool steady_dynamic) const; + //! Adds informations for simulation in a binary file + void Write_Inf_To_Bin_File(const string &basename, int &u_count_int, bool &file_open, bool is_two_boundaries, int block_mfs) const; + //! Writes model local variables /*! No temporary term is used in the output, so that local parameters declarations can be safely put before temporary terms declaration in the output files */ void writeModelLocalVariables(ostream &output, ExprNodeOutputType output_type) const; //! Writes model equations void writeModelEquations(ostream &output, ExprNodeOutputType output_type) const; + //! Compiles model equations + void compileModelEquations(ostream &code_file, const temporary_terms_type &tt, map_idx_type &map_idx, bool dynamic, bool steady_dynamic) const; //! Writes LaTeX model file void writeLatexModelFile(const string &filename, ExprNodeOutputType output_type) const; diff --git a/StaticModel.cc b/StaticModel.cc index 6bce4e2b..581f8532 100644 --- a/StaticModel.cc +++ b/StaticModel.cc @@ -70,6 +70,16 @@ StaticModel::compileChainRuleDerivative(ofstream &code_file, int eqr, int varr, } } +void +StaticModel::initializeVariablesAndEquations() +{ + for(int j = 0; j < equation_number(); j++) + { + equation_reordered.push_back(j); + variable_reordered.push_back(j); + } +} + void StaticModel::computeTemporaryTermsOrdered() { @@ -173,11 +183,17 @@ StaticModel::computeTemporaryTermsOrdered() (*it)->collectTemporary_terms(temporary_terms, temporary_terms_in_use, block); v_temporary_terms_inuse[block] = temporary_terms_in_use; } + computeTemporaryTermsMapping(); } +} + +void +StaticModel::computeTemporaryTermsMapping() +{ // Add a mapping form node ID to temporary terms order int j = 0; for (temporary_terms_type::const_iterator it = temporary_terms.begin(); - it != temporary_terms.end(); it++) + it != temporary_terms.end(); it++) map_idx[(*it)->idx] = j++; } @@ -388,7 +404,115 @@ StaticModel::writeModelEquationsOrdered_M(const string &static_basename) const } void -StaticModel::writeModelEquationsCodeOrdered(const string file_name, const string bin_basename, map_idx_type map_idx) const +StaticModel::writeModelEquationsCode(const string file_name, const string bin_basename, map_idx_type map_idx) const +{ + + ostringstream tmp_output; + ofstream code_file; + bool file_open = false; + + string main_name = file_name; + main_name += ".cod"; + code_file.open(main_name.c_str(), ios::out | ios::binary | ios::ate); + if (!code_file.is_open()) + { + cout << "Error : Can't open file \"" << main_name << "\" for writing\n"; + exit(EXIT_FAILURE); + } + int count_u; + int u_count_int = 0; + + Write_Inf_To_Bin_File(file_name, u_count_int, file_open, false, symbol_table.endo_nbr()); + file_open = true; + + //Temporary variables declaration + FDIMT_ fdimt(temporary_terms.size()); + fdimt.write(code_file); + + FBEGINBLOCK_ fbeginblock(symbol_table.endo_nbr(), + SOLVE_FORWARD_COMPLETE, + 0, + symbol_table.endo_nbr(), + variable_reordered, + equation_reordered, + false, + symbol_table.endo_nbr(), + 0, + 0, + u_count_int + ); + fbeginblock.write(code_file); + + + // Add a mapping form node ID to temporary terms order + int j = 0; + for (temporary_terms_type::const_iterator it = temporary_terms.begin(); + it != temporary_terms.end(); it++) + map_idx[(*it)->idx] = j++; + compileTemporaryTerms(code_file, temporary_terms, map_idx, false, false); + + compileModelEquations(code_file, temporary_terms, map_idx, false, false); + + FENDEQU_ fendequ; + fendequ.write(code_file); + + vector<vector<pair<int, int> > > derivatives; + derivatives.resize(symbol_table.endo_nbr()); + count_u = symbol_table.endo_nbr(); + for (first_derivatives_type::const_iterator it = first_derivatives.begin(); + it != first_derivatives.end(); it++) + { + int deriv_id = it->first.second; + if (getTypeByDerivID(deriv_id) == eEndogenous) + { + NodeID d1 = it->second; + unsigned int eq = it->first.first; + int symb = getSymbIDByDerivID(deriv_id); + unsigned int var = symbol_table.getTypeSpecificID(symb); + if (!derivatives[eq].size()) + derivatives[eq].clear(); + derivatives[eq].push_back(make_pair(var, count_u)); + + d1->compile(code_file, false, temporary_terms, map_idx, false, false); + + FSTPSU_ fstpsu(count_u); + fstpsu.write(code_file); + count_u++; + } + } + for (int i = 0; i < symbol_table.endo_nbr(); i++) + { + FLDR_ fldr(i); + fldr.write(code_file); + for(vector<pair<int, int> >::const_iterator it = derivatives[i].begin(); + it != derivatives[i].end(); it++) + { + FLDSU_ fldsu(it->second); + fldsu.write(code_file); + FLDSV_ fldsv(eEndogenous, it->first); + fldsv.write(code_file); + FBINARY_ fbinary(oTimes); + fbinary.write(code_file); + if (it != derivatives[i].begin()) + { + FBINARY_ fbinary(oPlus); + fbinary.write(code_file); + } + } + FBINARY_ fbinary(oMinus); + fbinary.write(code_file); + FSTPSU_ fstpsu(i); + fstpsu.write(code_file); + } + FENDBLOCK_ fendblock; + fendblock.write(code_file); + FEND_ fend; + fend.write(code_file); + code_file.close(); +} + +void +StaticModel::writeModelEquationsCode_Block(const string file_name, const string bin_basename, map_idx_type map_idx) const { struct Uff_l { @@ -443,7 +567,7 @@ StaticModel::writeModelEquationsCodeOrdered(const string file_name, const string if (simulation_type == SOLVE_TWO_BOUNDARIES_SIMPLE || simulation_type == SOLVE_TWO_BOUNDARIES_COMPLETE || simulation_type == SOLVE_BACKWARD_COMPLETE || simulation_type == SOLVE_FORWARD_COMPLETE) { - Write_Inf_To_Bin_File(file_name, bin_basename, block, u_count_int, file_open); + Write_Inf_To_Bin_File_Block(file_name, bin_basename, block, u_count_int, file_open); file_open = true; } @@ -629,7 +753,7 @@ StaticModel::writeModelEquationsCodeOrdered(const string file_name, const string } void -StaticModel::Write_Inf_To_Bin_File(const string &static_basename, const string &bin_basename, const int &num, +StaticModel::Write_Inf_To_Bin_File_Block(const string &static_basename, const string &bin_basename, const int &num, int &u_count_int, bool &file_open) const { int j; @@ -697,7 +821,7 @@ StaticModel::collect_first_order_derivatives_endogenous() } void -StaticModel::computingPass(const eval_context_type &eval_context, bool no_tmp_terms, bool hessian, bool block) +StaticModel::computingPass(const eval_context_type &eval_context, bool no_tmp_terms, bool hessian, bool block, bool bytecode) { // Compute derivatives w.r. to all endogenous, and possibly exogenous and exogenous deterministic set<int> vars; @@ -753,11 +877,16 @@ StaticModel::computingPass(const eval_context_type &eval_context, bool no_tmp_te global_temporary_terms = true; if (!no_tmp_terms) computeTemporaryTermsOrdered(); - } else - if (!no_tmp_terms) - computeTemporaryTerms(true); + { + if (!no_tmp_terms) + { + computeTemporaryTerms(true); + if (bytecode) + computeTemporaryTermsMapping(); + } + } } void @@ -894,7 +1023,9 @@ StaticModel::writeStaticFile(const string &basename, bool block, bool bytecode) exit(EXIT_FAILURE); } if (block && bytecode) - writeModelEquationsCodeOrdered(basename + "_static", basename, map_idx); + writeModelEquationsCode_Block(basename + "_static", basename, map_idx); + else if (!block && bytecode) + writeModelEquationsCode(basename + "_static", basename, map_idx); else if (block && !bytecode) { chdir(basename.c_str()); diff --git a/StaticModel.hh b/StaticModel.hh index 1dbfb07d..8aee4242 100644 --- a/StaticModel.hh +++ b/StaticModel.hh @@ -61,7 +61,11 @@ private: void writeModelEquationsOrdered_M(const string &dynamic_basename) const; //! Writes the code of the Block reordred structure of the model in virtual machine bytecode - void writeModelEquationsCodeOrdered(const string file_name, const string bin_basename, map_idx_type map_idx) const; + void writeModelEquationsCode_Block(const string file_name, const string bin_basename, map_idx_type map_idx) const; + + //! Writes the code of the model in virtual machine bytecode + void writeModelEquationsCode(const string file_name, const string bin_basename, map_idx_type map_idx) const; + //! Computes jacobian and prepares for equation normalization /*! Using values from initval/endval blocks and parameter initializations: @@ -72,7 +76,11 @@ private: map_idx_type map_idx; + //! sorts the temporary terms in the blocks order void computeTemporaryTermsOrdered(); + //! creates a mapping from the index of temporary terms to a natural index + void computeTemporaryTermsMapping(); + //! Write derivative code of an equation w.r. to a variable void compileDerivative(ofstream &code_file, int eq, int symb_id, map_idx_type &map_idx) const; //! Write chain rule derivative code of an equation w.r. to a variable @@ -167,10 +175,10 @@ public: \param eval_context evaluation context for normalization \param no_tmp_terms if true, no temporary terms will be computed in the static files */ - void computingPass(const eval_context_type &eval_context, bool no_tmp_terms, bool hessian, bool block); + void computingPass(const eval_context_type &eval_context, bool no_tmp_terms, bool hessian, bool block, bool bytecode); - //! Adds informations for simulation in a binary file - void Write_Inf_To_Bin_File(const string &static_basename, const string &bin_basename, const int &num, + //! Adds informations for simulation in a binary file for a block decomposed model + void Write_Inf_To_Bin_File_Block(const string &static_basename, const string &bin_basename, const int &num, int &u_count_int, bool &file_open) const; //! Writes static model file @@ -182,6 +190,9 @@ public: //! Writes initializations in oo_.steady_state for the auxiliary variables void writeAuxVarInitval(ostream &output) const; + //! Initialize equation_reordered & variable_reordered + void initializeVariablesAndEquations(); + virtual int getDerivID(int symb_id, int lag) const throw (UnknownDerivIDException); //! Return the number of blocks -- GitLab