write C++ version of model functions without temporary terms
parent
bd1188f78e
commit
49b34d4c94
|
@ -2089,7 +2089,6 @@ DynamicModel::writeDynamicModel(ostream &DynamicOutput, bool use_dll) const
|
|||
ExprNodeOutputType output_type = (use_dll ? oCDynamicModel : oMatlabDynamicModel);
|
||||
|
||||
deriv_node_temp_terms_t tef_terms;
|
||||
writeModelLocalVariables(model_output, output_type, tef_terms);
|
||||
|
||||
writeTemporaryTerms(temporary_terms, model_output, output_type, tef_terms);
|
||||
|
||||
|
@ -4419,3 +4418,356 @@ DynamicModel::dynamicOnlyEquationsNbr() const
|
|||
return eqs.size();
|
||||
}
|
||||
|
||||
void
|
||||
DynamicModel::writeFirstDerivativesCC(const string &basename, bool cuda) const
|
||||
{
|
||||
string filename = basename + "_first_derivatives.cc";
|
||||
ofstream mDynamicModelFile, mDynamicMexFile;
|
||||
|
||||
mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary);
|
||||
if (!mDynamicModelFile.is_open())
|
||||
{
|
||||
cerr << "Error: Can't open file " << filename << " for writing" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
mDynamicModelFile << "/*" << endl
|
||||
<< " * " << filename << " : Computes first order derivatives of the model for Dynare" << endl
|
||||
<< " *" << endl
|
||||
<< " * Warning : this file is generated automatically by Dynare" << endl
|
||||
<< " * from model " << basename << "(.mod)" << endl
|
||||
<< " */" << endl
|
||||
<< "#include <math.h>" << endl;
|
||||
|
||||
mDynamicModelFile << "#include <stdlib.h>" << endl;
|
||||
|
||||
mDynamicModelFile << "#define max(a, b) (((a) > (b)) ? (a) : (b))" << endl
|
||||
<< "#define min(a, b) (((a) > (b)) ? (b) : (a))" << endl;
|
||||
|
||||
// Write function definition if oPowerDeriv is used
|
||||
writePowerDerivCHeader(mDynamicModelFile);
|
||||
|
||||
mDynamicModelFile << "void FirstDerivatives(const double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, double *g1, double *v2, double *v3)" << endl
|
||||
<< "{" << endl;
|
||||
|
||||
// this is always empty here, but needed by d1->writeOutput
|
||||
deriv_node_temp_terms_t tef_terms;
|
||||
|
||||
// Writing Jacobian
|
||||
for (first_derivatives_t::const_iterator it = first_derivatives.begin();
|
||||
it != first_derivatives.end(); it++)
|
||||
{
|
||||
int eq = it->first.first;
|
||||
int var = it->first.second;
|
||||
expr_t d1 = it->second;
|
||||
|
||||
jacobianHelper(mDynamicModelFile, eq, getDynJacobianCol(var), oCDynamicModel);
|
||||
mDynamicModelFile << "=";
|
||||
// oCstaticModel makes reference to the static variables
|
||||
d1->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms);
|
||||
mDynamicModelFile << ";" << endl;
|
||||
}
|
||||
|
||||
mDynamicModelFile << "}" << endl;
|
||||
|
||||
writePowerDeriv(mDynamicModelFile, true);
|
||||
mDynamicModelFile.close();
|
||||
|
||||
}
|
||||
|
||||
// using compressed sparse row format (CSR)
|
||||
void
|
||||
DynamicModel::writeSecondDerivativesCC_csr(const string &basename, bool cuda) const
|
||||
{
|
||||
|
||||
string filename = basename + "_second_derivatives.cc";
|
||||
ofstream mDynamicModelFile, mDynamicMexFile;
|
||||
|
||||
mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary);
|
||||
if (!mDynamicModelFile.is_open())
|
||||
{
|
||||
cerr << "Error: Can't open file " << filename << " for writing" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
mDynamicModelFile << "/*" << endl
|
||||
<< " * " << filename << " : Computes second order derivatives of the model for Dynare" << endl
|
||||
<< " *" << endl
|
||||
<< " * Warning : this file is generated automatically by Dynare" << endl
|
||||
<< " * from model " << basename << "(.mod)" << endl
|
||||
<< " */" << endl
|
||||
<< "#include <math.h>" << endl;
|
||||
|
||||
mDynamicModelFile << "#include <stdlib.h>" << endl;
|
||||
|
||||
mDynamicModelFile << "#define max(a, b) (((a) > (b)) ? (a) : (b))" << endl
|
||||
<< "#define min(a, b) (((a) > (b)) ? (b) : (a))" << endl;
|
||||
|
||||
// write function definition if oPowerDeriv is used
|
||||
writePowerDerivCHeader(mDynamicModelFile);
|
||||
|
||||
mDynamicModelFile << "void SecondDerivatives(const double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, int *row_ptr, int *col_ptr, double *value)" << endl
|
||||
<< "{" << endl;
|
||||
|
||||
// this is always empty here, but needed by d1->writeOutput
|
||||
deriv_node_temp_terms_t tef_terms;
|
||||
|
||||
// Indexing derivatives in column order
|
||||
vector<int> d_order(NNZDerivatives[1]);
|
||||
OrderByLinearAddress obla(NNZDerivatives[1]);
|
||||
int counter = 0;
|
||||
int dynHessianColsNbr = dynJacobianColsNbr*dynJacobianColsNbr;
|
||||
for (second_derivatives_t::const_iterator it = second_derivatives.begin();
|
||||
it != second_derivatives.end(); it++)
|
||||
{
|
||||
int eq = it->first.first;
|
||||
int var1 = it->first.second.first;
|
||||
int var2 = it->first.second.second;
|
||||
|
||||
int id1 = getDynJacobianCol(var1);
|
||||
int id2 = getDynJacobianCol(var2);
|
||||
|
||||
int col_nb = id1 * dynJacobianColsNbr + id2;
|
||||
int col_nb_sym = id2 * dynJacobianColsNbr + id1;
|
||||
|
||||
obla.linear_address[counter] = col_nb + eq*dynHessianColsNbr;
|
||||
d_order[counter] = counter;
|
||||
++counter;
|
||||
if (id1 != id2)
|
||||
{
|
||||
obla.linear_address[counter] = col_nb_sym + eq*dynHessianColsNbr;
|
||||
d_order[counter] = counter;
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
sort(d_order.begin(), d_order.end(), obla);
|
||||
|
||||
// Writing Hessian
|
||||
vector<int> row_ptr(equations.size());
|
||||
fill(row_ptr.begin(),row_ptr.end(),0.0);
|
||||
int k = 0; // Keep the order of a 2nd derivative
|
||||
for (second_derivatives_t::const_iterator it = second_derivatives.begin();
|
||||
it != second_derivatives.end(); it++)
|
||||
{
|
||||
int eq = it->first.first;
|
||||
int var1 = it->first.second.first;
|
||||
int var2 = it->first.second.second;
|
||||
expr_t d2 = it->second;
|
||||
|
||||
int id1 = getDynJacobianCol(var1);
|
||||
int id2 = getDynJacobianCol(var2);
|
||||
|
||||
int col_nb = id1 * dynJacobianColsNbr + id2;
|
||||
int col_nb_sym = id2 * dynJacobianColsNbr + id1;
|
||||
|
||||
row_ptr[eq]++;
|
||||
mDynamicModelFile << "col_ptr[" << d_order[k] << "] "
|
||||
<< "=" << col_nb << ";" << endl;
|
||||
mDynamicModelFile << "value[" << d_order[k] << "] = ";
|
||||
// oCstaticModel makes reference to the static variables
|
||||
d2->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms);
|
||||
mDynamicModelFile << ";" << endl;
|
||||
|
||||
k++;
|
||||
|
||||
// Treating symetric elements
|
||||
if (id1 != id2)
|
||||
{
|
||||
row_ptr[eq]++;
|
||||
mDynamicModelFile << "col_ptr[" << d_order[k] << "] "
|
||||
<< "=" << col_nb_sym << ";" << endl;
|
||||
mDynamicModelFile << "value[" << d_order[k] << "] = ";
|
||||
// oCstaticModel makes reference to the static variables
|
||||
d2->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms);
|
||||
mDynamicModelFile << ";" << endl;
|
||||
|
||||
k++;
|
||||
}
|
||||
}
|
||||
|
||||
// row_ptr must point to the relative address of the first element of the row
|
||||
int cumsum = 0;
|
||||
mDynamicModelFile << "row_ptr = [ 0";
|
||||
for (vector<int>::iterator it=row_ptr.begin(); it != row_ptr.end(); ++it)
|
||||
{
|
||||
cumsum += *it;
|
||||
mDynamicModelFile << ", " << cumsum;
|
||||
}
|
||||
mDynamicModelFile << "];" << endl;
|
||||
|
||||
mDynamicModelFile << "}" << endl;
|
||||
|
||||
writePowerDeriv(mDynamicModelFile, true);
|
||||
mDynamicModelFile.close();
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
DynamicModel::writeThirdDerivativesCC_csr(const string &basename, bool cuda) const
|
||||
{
|
||||
string filename = basename + "_third_derivatives.cc";
|
||||
ofstream mDynamicModelFile, mDynamicMexFile;
|
||||
|
||||
mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary);
|
||||
if (!mDynamicModelFile.is_open())
|
||||
{
|
||||
cerr << "Error: Can't open file " << filename << " for writing" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
mDynamicModelFile << "/*" << endl
|
||||
<< " * " << filename << " : Computes third order derivatives of the model for Dynare" << endl
|
||||
<< " *" << endl
|
||||
<< " * Warning : this file is generated automatically by Dynare" << endl
|
||||
<< " * from model " << basename << "(.mod)" << endl
|
||||
<< " */" << endl
|
||||
<< "#include <math.h>" << endl;
|
||||
|
||||
mDynamicModelFile << "#include <stdlib.h>" << endl;
|
||||
|
||||
mDynamicModelFile << "#define max(a, b) (((a) > (b)) ? (a) : (b))" << endl
|
||||
<< "#define min(a, b) (((a) > (b)) ? (b) : (a))" << endl;
|
||||
|
||||
// Write function definition if oPowerDeriv is used
|
||||
writePowerDerivCHeader(mDynamicModelFile);
|
||||
|
||||
mDynamicModelFile << "void ThirdDerivatives(const double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, double *g1, double *v2, double *v3)" << endl
|
||||
<< "{" << endl;
|
||||
|
||||
// this is always empty here, but needed by d1->writeOutput
|
||||
deriv_node_temp_terms_t tef_terms;
|
||||
|
||||
// Indexing derivatives in column order
|
||||
vector<int> d_order(NNZDerivatives[1]);
|
||||
OrderByLinearAddress obla(NNZDerivatives[1]);
|
||||
int counter = 0;
|
||||
int dynHessianColsNbr = dynJacobianColsNbr*dynJacobianColsNbr;
|
||||
for (third_derivatives_t::const_iterator it = third_derivatives.begin();
|
||||
it != third_derivatives.end(); it++)
|
||||
{
|
||||
int eq = it->first.first;
|
||||
int var1 = it->first.second.first;
|
||||
int var2 = it->first.second.second.first;
|
||||
int var3 = it->first.second.second.second;
|
||||
expr_t d3 = it->second;
|
||||
|
||||
int id1 = getDynJacobianCol(var1);
|
||||
int id2 = getDynJacobianCol(var2);
|
||||
int id3 = getDynJacobianCol(var3);
|
||||
|
||||
// Reference column number for the g3 matrix
|
||||
int ref_col = id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3;
|
||||
|
||||
sparseHelper(3, mDynamicModelFile, k, 0, oCDynamicModel);
|
||||
mDynamicModelFile << "=" << eq + 1 << ";" << endl;
|
||||
|
||||
sparseHelper(3, mDynamicModelFile, k, 1, oCDynamicModel);
|
||||
mDynamicModelFile << "=" << ref_col + 1 << ";" << endl;
|
||||
|
||||
sparseHelper(3, mDynamicModelFile, k, 2, oCDynamicModel);
|
||||
mDynamicModelFile << "=";
|
||||
// oCstaticModel makes reference to the static variables
|
||||
d3->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms);
|
||||
mDynamicModelFile << ";" << endl;
|
||||
|
||||
// Compute the column numbers for the 5 other permutations of (id1,id2,id3) and store them in a set (to avoid duplicates if two indexes are equal)
|
||||
set<int> cols;
|
||||
cols.insert(id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2);
|
||||
cols.insert(id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3);
|
||||
cols.insert(id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1);
|
||||
cols.insert(id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2);
|
||||
cols.insert(id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1);
|
||||
|
||||
int k2 = 1; // Keeps the offset of the permutation relative to k
|
||||
for (set<int>::iterator it2 = cols.begin(); it2 != cols.end(); it2++)
|
||||
if (*it2 != ref_col)
|
||||
{
|
||||
sparseHelper(3, mDynamicModelFile, k+k2, 0, oCDynamicModel);
|
||||
mDynamicModelFile << "=" << eq + 1 << ";" << endl;
|
||||
|
||||
sparseHelper(3, mDynamicModelFile, k+k2, 1, oCDynamicModel);
|
||||
mDynamicModelFile << "=" << *it2 + 1 << ";" << endl;
|
||||
|
||||
sparseHelper(3, mDynamicModelFile, k+k2, 2, oCDynamicModel);
|
||||
mDynamicModelFile << "=";
|
||||
sparseHelper(3, mDynamicModelFile, k, 2, oCDynamicModel);
|
||||
mDynamicModelFile << ";" << endl;
|
||||
|
||||
k2++;
|
||||
}
|
||||
k += k2;
|
||||
}
|
||||
|
||||
// Writing third derivatives
|
||||
int hessianColsNbr = dynJacobianColsNbr * dynJacobianColsNbr;
|
||||
int k = 0; // Keep the line of a 3rd derivative in v3
|
||||
for (third_derivatives_t::const_iterator it = third_derivatives.begin();
|
||||
it != third_derivatives.end(); it++)
|
||||
{
|
||||
int eq = it->first.first;
|
||||
int var1 = it->first.second.first;
|
||||
int var2 = it->first.second.second.first;
|
||||
int var3 = it->first.second.second.second;
|
||||
expr_t d3 = it->second;
|
||||
|
||||
int id1 = getDynJacobianCol(var1);
|
||||
int id2 = getDynJacobianCol(var2);
|
||||
int id3 = getDynJacobianCol(var3);
|
||||
|
||||
// Reference column number for the g3 matrix
|
||||
int ref_col = id1 * hessianColsNbr + id2 * dynJacobianColsNbr + id3;
|
||||
|
||||
sparseHelper(3, mDynamicModelFile, k, 0, oCDynamicModel);
|
||||
mDynamicModelFile << "=" << eq + 1 << ";" << endl;
|
||||
|
||||
sparseHelper(3, mDynamicModelFile, k, 1, oCDynamicModel);
|
||||
mDynamicModelFile << "=" << ref_col + 1 << ";" << endl;
|
||||
|
||||
sparseHelper(3, mDynamicModelFile, k, 2, oCDynamicModel);
|
||||
mDynamicModelFile << "=";
|
||||
// oCstaticModel makes reference to the static variables
|
||||
d3->writeOutput(mDynamicModelFile, oCStaticModel, temporary_terms, tef_terms);
|
||||
mDynamicModelFile << ";" << endl;
|
||||
|
||||
// Compute the column numbers for the 5 other permutations of (id1,id2,id3) and store them in a set (to avoid duplicates if two indexes are equal)
|
||||
set<int> cols;
|
||||
cols.insert(id1 * hessianColsNbr + id3 * dynJacobianColsNbr + id2);
|
||||
cols.insert(id2 * hessianColsNbr + id1 * dynJacobianColsNbr + id3);
|
||||
cols.insert(id2 * hessianColsNbr + id3 * dynJacobianColsNbr + id1);
|
||||
cols.insert(id3 * hessianColsNbr + id1 * dynJacobianColsNbr + id2);
|
||||
cols.insert(id3 * hessianColsNbr + id2 * dynJacobianColsNbr + id1);
|
||||
|
||||
int k2 = 1; // Keeps the offset of the permutation relative to k
|
||||
for (set<int>::iterator it2 = cols.begin(); it2 != cols.end(); it2++)
|
||||
if (*it2 != ref_col)
|
||||
{
|
||||
sparseHelper(3, mDynamicModelFile, k+k2, 0, oCDynamicModel);
|
||||
mDynamicModelFile << "=" << eq + 1 << ";" << endl;
|
||||
|
||||
sparseHelper(3, mDynamicModelFile, k+k2, 1, oCDynamicModel);
|
||||
mDynamicModelFile << "=" << *it2 + 1 << ";" << endl;
|
||||
|
||||
sparseHelper(3, mDynamicModelFile, k+k2, 2, oCDynamicModel);
|
||||
mDynamicModelFile << "=";
|
||||
sparseHelper(3, mDynamicModelFile, k, 2, oCDynamicModel);
|
||||
mDynamicModelFile << ";" << endl;
|
||||
|
||||
k2++;
|
||||
}
|
||||
k += k2;
|
||||
}
|
||||
|
||||
mDynamicModelFile << "}" << endl;
|
||||
|
||||
writePowerDeriv(mDynamicModelFile, true);
|
||||
mDynamicModelFile.close();
|
||||
|
||||
}
|
||||
|
||||
OrderByLinearAddress::OrderByLinearAddress(int size)
|
||||
{
|
||||
linear_address.resize(size);
|
||||
}
|
||||
|
||||
bool OrderByLinearAddress::operator()(const int i1, const int i2) const
|
||||
{
|
||||
return linear_address[i1] < linear_address[i2];
|
||||
}
|
||||
|
||||
|
|
|
@ -223,6 +223,12 @@ public:
|
|||
void writeDynamicFile(const string &basename, bool block, bool bytecode, bool use_dll, int order) const;
|
||||
//! Writes file containing parameters derivatives
|
||||
void writeParamsDerivativesFile(const string &basename) const;
|
||||
//! Writes CC file containing first order derivatives of model evaluated at steady state
|
||||
void writeFirstDerivativesCC(const string &basename, bool cuda) const;
|
||||
//! Writes CC file containing second order derivatives of model evaluated at steady state (compressed sparse column)
|
||||
void writeSecondDerivativesCC_csr(const string &basename, bool cuda) const;
|
||||
//! Writes CC file containing third order derivatives of model evaluated at steady state (compressed sparse column)
|
||||
void writeThirdDerivativesCC_csr(const string &basename, bool cuda) const;
|
||||
//! Converts to static model (only the equations)
|
||||
/*! It assumes that the static model given in argument has just been allocated */
|
||||
void toStatic(StaticModel &static_model) const;
|
||||
|
@ -467,4 +473,14 @@ public:
|
|||
bool isModelLocalVariableUsed() const;
|
||||
};
|
||||
|
||||
//! Class to re-order derivatives for various sparse storage formats
|
||||
class OrderByLinearAddress
|
||||
{
|
||||
public:
|
||||
//! vector of linear addresses in derivatives matrices
|
||||
vector<long unsigned int> linear_address;
|
||||
OrderByLinearAddress(int size);
|
||||
//! Order by linear address in a matrix
|
||||
bool operator()(const int i1, const int i2) const;
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -199,6 +199,8 @@ main(int argc, char **argv)
|
|||
cerr << "Incorrect syntax for ouput option" << endl;
|
||||
usage();
|
||||
}
|
||||
// we don't want temp terms in CC functions
|
||||
no_tmp_terms = true;
|
||||
if (strlen(argv[arg]) == 14 && !strncmp(argv[arg] + 7, "dynamic", 7))
|
||||
output_mode = dynamic;
|
||||
else if (strlen(argv[arg]) == 12 && !strncmp(argv[arg] + 7, "first", 5))
|
||||
|
|
|
@ -54,7 +54,7 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tm
|
|||
mod_file->evalAllExpressions(warn_uninit);
|
||||
|
||||
// Do computations
|
||||
mod_file->computingPass(no_tmp_terms);
|
||||
mod_file->computingPass(no_tmp_terms, output_mode);
|
||||
|
||||
// Write outputs
|
||||
if (output_mode != none)
|
||||
|
|
|
@ -673,6 +673,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
case oSteadyStateFile:
|
||||
output << "ys_(" << tsid + 1 << ")";
|
||||
break;
|
||||
case oCSteadyStateFile:
|
||||
output << "ys_[" << tsid << "]";
|
||||
break;
|
||||
default:
|
||||
cerr << "VariableNode::writeOutput: should not reach this point" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -715,6 +718,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
case oSteadyStateFile:
|
||||
output << "exo_(" << i << ")";
|
||||
break;
|
||||
case oCSteadyStateFile:
|
||||
output << "exo_[" << i - 1 << "]";
|
||||
break;
|
||||
default:
|
||||
cerr << "VariableNode::writeOutput: should not reach this point" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -757,6 +763,9 @@ VariableNode::writeOutput(ostream &output, ExprNodeOutputType output_type,
|
|||
case oSteadyStateFile:
|
||||
output << "exo_(" << i << ")";
|
||||
break;
|
||||
case oCSteadyStateFile:
|
||||
output << "exo_[" << i - 1 << "]";
|
||||
break;
|
||||
default:
|
||||
cerr << "VariableNode::writeOutput: should not reach this point" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
|
@ -4376,7 +4385,7 @@ ExternalFunctionNode::writeOutput(ostream &output, ExprNodeOutputType output_typ
|
|||
const temporary_terms_t &temporary_terms,
|
||||
deriv_node_temp_terms_t &tef_terms) const
|
||||
{
|
||||
if (output_type == oMatlabOutsideModel || output_type == oSteadyStateFile)
|
||||
if (output_type == oMatlabOutsideModel || output_type == oSteadyStateFile || output_type == oCSteadyStateFile)
|
||||
{
|
||||
output << datatree.symbol_table.getName(symb_id) << "(";
|
||||
writeExternalFunctionArguments(output, output_type, temporary_terms, tef_terms);
|
||||
|
|
|
@ -73,7 +73,8 @@ enum ExprNodeOutputType
|
|||
oMatlabDynamicSteadyStateOperator, //!< Matlab code, dynamic model, inside a steady state operator
|
||||
oMatlabDynamicSparseSteadyStateOperator, //!< Matlab code, dynamic block decomposed model, inside a steady state operator
|
||||
oCDynamicSteadyStateOperator, //!< C code, dynamic model, inside a steady state operator
|
||||
oSteadyStateFile //!< Matlab code, in the generated steady state file
|
||||
oSteadyStateFile, //!< Matlab code, in the generated steady state file
|
||||
oCSteadyStateFile //!< C code, in the generated steady state file
|
||||
};
|
||||
|
||||
#define IS_MATLAB(output_type) ((output_type) == oMatlabStaticModel \
|
||||
|
|
|
@ -30,7 +30,9 @@ using namespace std;
|
|||
class ExternalFiles
|
||||
{
|
||||
public:
|
||||
void eraseFiles(const string &basename);
|
||||
void writeHeaders(const string &basename, bool cuda);
|
||||
void writeModelCC(const string &basename, bool cuda);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -447,7 +447,7 @@ ModFile::transformPass(bool nostrict)
|
|||
}
|
||||
|
||||
void
|
||||
ModFile::computingPass(bool no_tmp_terms)
|
||||
ModFile::computingPass(bool no_tmp_terms, OutputType output)
|
||||
{
|
||||
// Mod file may have no equation (for example in a standalone BVAR estimation)
|
||||
if (dynamic_model.equation_number() > 0)
|
||||
|
@ -493,8 +493,14 @@ ModFile::computingPass(bool no_tmp_terms)
|
|||
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;
|
||||
bool thirdDerivatives = mod_file_struct.order_option == 3 || mod_file_struct.estimation_analytic_derivation;
|
||||
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);
|
||||
}
|
||||
|
@ -799,29 +805,9 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool no_log, b
|
|||
}
|
||||
|
||||
void
|
||||
ModFile::writeCOutputFiles(const string &basename) const
|
||||
ModFile::writeModelCC(const string &basename, bool cuda) const
|
||||
{
|
||||
// Erase possible remnants of previous runs
|
||||
string dynfile = basename + "_dynamic.m";
|
||||
unlink(dynfile.c_str());
|
||||
|
||||
dynfile = basename + "_dynamic.c";
|
||||
unlink(dynfile.c_str());
|
||||
|
||||
dynfile = basename + "_dynamic_mex.c";
|
||||
unlink(dynfile.c_str());
|
||||
|
||||
string statfile = basename + "_static.m";
|
||||
unlink(statfile.c_str());
|
||||
|
||||
statfile = basename + "_static.c";
|
||||
unlink(statfile.c_str());
|
||||
|
||||
statfile = basename + "_static_mex.c";
|
||||
unlink(statfile.c_str());
|
||||
|
||||
string filename = "preprocessorOutput.cc";
|
||||
unlink(filename.c_str());
|
||||
string filename = basename + ".cc";
|
||||
|
||||
ofstream mDriverCFile;
|
||||
mDriverCFile.open(filename.c_str(), ios::out | ios::binary);
|
||||
|
@ -847,8 +833,6 @@ ModFile::writeCOutputFiles(const string &basename) const
|
|||
// Write basic info
|
||||
symbol_table.writeCOutput(mDriverCFile);
|
||||
|
||||
dynamic_model.writeCOutput(mDriverCFile, basename, false, false, true, mod_file_struct.order_option, mod_file_struct.estimation_present);
|
||||
|
||||
mDriverCFile << "/*" << endl
|
||||
<< " * Writing statements" << endl
|
||||
<< " */" << endl
|
||||
|
@ -875,11 +859,6 @@ ModFile::writeCOutputFiles(const string &basename) const
|
|||
mDriverCFile << "}" << endl;
|
||||
mDriverCFile.close();
|
||||
|
||||
dynamic_model.writeDynamicFile(basename, false, false, true, mod_file_struct.order_option);
|
||||
if (!no_static)
|
||||
static_model.writeStaticFile(basename, false, false, true);
|
||||
|
||||
|
||||
// Write informational m file
|
||||
ofstream mOutputFile;
|
||||
|
||||
|
@ -914,22 +893,28 @@ ModFile::writeCOutputFiles(const string &basename) const
|
|||
void
|
||||
ModFile::writeExternalFiles(const string &basename, OutputType output, bool cuda) const
|
||||
{
|
||||
ExternalFiles::writeHeaders(basename, cuda);
|
||||
ExternalFiles::writeModelCC(cuda);
|
||||
writeModelCC(basename, cuda);
|
||||
steady_state_model.writeSteadyStateFileCC(basename, mod_file_struct.ramsey_policy_present, cuda);
|
||||
static_model.writeStaticFile(basename, block, byte_code, use_dll);
|
||||
static_model.writeParamsDerivativesFile(basename);
|
||||
static_model.writeAuxVarInitvalCC(mOutputFile, oMatlabOutsideModel);
|
||||
|
||||
dynamic_model.writeResiduals(basename, cuda);
|
||||
dynamic_model.writeParamsDerivativesFile(basename, cuda);
|
||||
dynamic_model.writeFirstDerivatives(basename, cuda);
|
||||
dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option);
|
||||
|
||||
if (!no_static)
|
||||
static_model.writeStaticFile(basename, false, false, true);
|
||||
|
||||
|
||||
// static_model.writeStaticCFile(basename, block, byte_code, use_dll);
|
||||
// static_model.writeParamsDerivativesFileCC(basename, cuda);
|
||||
// static_model.writeAuxVarInitvalCC(mOutputFile, oMatlabOutsideModel, cuda);
|
||||
|
||||
// dynamic_model.writeResidualsCC(basename, cuda);
|
||||
// dynamic_model.writeParamsDerivativesFileCC(basename, cuda);
|
||||
dynamic_model.writeFirstDerivativesCC(basename, cuda);
|
||||
|
||||
if (output == second)
|
||||
dynamic_model.writeSecondDerivatives(basename, cuda);
|
||||
dynamic_model.writeSecondDerivativesCC_csr(basename, cuda);
|
||||
else if (output == third)
|
||||
{
|
||||
dynamic_model.writeSecondDerivatives(basename, cuda);
|
||||
dynamic_model.writeThirdDerivatives(basename, cuda);
|
||||
dynamic_model.writeSecondDerivativesCC_csr(basename, cuda);
|
||||
dynamic_model.writeThirdDerivativesCC_csr(basename, cuda);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ public:
|
|||
void transformPass(bool nostrict);
|
||||
//! Execute computations
|
||||
/*! \param no_tmp_terms if true, no temporary terms will be computed in the static and dynamic files */
|
||||
void computingPass(bool no_tmp_terms);
|
||||
void computingPass(bool no_tmp_terms, OutputType output);
|
||||
//! Writes Matlab/Octave output files
|
||||
/*!
|
||||
\param basename The base name used for writing output files. Should be the name of the mod file without its extension
|
||||
|
@ -141,6 +141,7 @@ public:
|
|||
) const;
|
||||
//! Writes C output files only => No further Matlab processing
|
||||
void writeCOutputFiles(const string &basename) const;
|
||||
void writeModelCC(const string &basename, bool cuda) const;
|
||||
void writeExternalFiles(const string &basename, OutputType output, bool cuda) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -161,7 +161,6 @@ protected:
|
|||
void computeThirdDerivatives(const set<int> &vars);
|
||||
//! Computes derivatives of the Jacobian and Hessian w.r. to parameters
|
||||
void computeParamsDerivatives();
|
||||
|
||||
//! Write derivative of an equation w.r. to a variable
|
||||
void writeDerivative(ostream &output, int eq, int symb_id, int lag, ExprNodeOutputType output_type, const temporary_terms_t &temporary_terms) const;
|
||||
//! Computes temporary terms (for all equations and derivatives)
|
||||
|
|
|
@ -145,3 +145,58 @@ SteadyStateModel::writeSteadyStateFile(const string &basename, bool ramsey_polic
|
|||
<< "end" << endl;
|
||||
}
|
||||
|
||||
void
|
||||
SteadyStateModel::writeSteadyStateFileCC(const string &basename, bool ramsey_policy, bool cuda) const
|
||||
{
|
||||
string filename = basename + "_steadystate.cc";
|
||||
|
||||
ofstream output;
|
||||
output.open(filename.c_str(), ios::out | ios::binary);
|
||||
if (!output.is_open())
|
||||
{
|
||||
cerr << "ERROR: Can't open file " << filename << " for writing" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if (cuda)
|
||||
output << "__global__ ";
|
||||
|
||||
output << "void steadystate("
|
||||
<< "const double *exo_, const double *params_, double *ys_, int *info)" << endl
|
||||
<< "// Steady state file generated by Dynare preprocessor" << endl
|
||||
<< "{" << endl
|
||||
<< " info = 0;" << endl;
|
||||
|
||||
if (recursive_order.size() == 0)
|
||||
{
|
||||
output << " return;" << endl
|
||||
<< "}" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < recursive_order.size(); i++)
|
||||
{
|
||||
const vector<int> &symb_ids = recursive_order[i];
|
||||
output << " ";
|
||||
if (symb_ids.size() > 1)
|
||||
output << "[";
|
||||
for (size_t j = 0; j < symb_ids.size(); j++)
|
||||
{
|
||||
variable_node_map_t::const_iterator it = variable_node_map.find(make_pair(symb_ids[j], 0));
|
||||
assert(it != variable_node_map.end());
|
||||
dynamic_cast<ExprNode *>(it->second)->writeOutput(output, oSteadyStateFile);
|
||||
if (j < symb_ids.size()-1)
|
||||
output << ",";
|
||||
}
|
||||
if (symb_ids.size() > 1)
|
||||
output << "]";
|
||||
|
||||
output << "=";
|
||||
def_table.find(symb_ids)->second->writeOutput(output, oSteadyStateFile);
|
||||
output << ";" << endl;
|
||||
}
|
||||
output << " // Auxiliary equations" << endl;
|
||||
static_model.writeAuxVarInitval(output, oSteadyStateFile);
|
||||
output << "}" << endl;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
\param[in] ramsey_policy Is there a ramsey_policy statement in the MOD file? If yes, then use the "ys" in argument of the steady state file as initial values
|
||||
*/
|
||||
void writeSteadyStateFile(const string &basename, bool ramsey_policy) const;
|
||||
void writeSteadyStateFileCC(const string &basename, bool ramsey_policy, bool cuda) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue