preprocessor: separate dynamic and static functions from their mexfiles
parent
ed82146c37
commit
5c0a17e9f2
|
@ -1518,7 +1518,8 @@ void
|
||||||
DynamicModel::writeDynamicCFile(const string &dynamic_basename, const int order) const
|
DynamicModel::writeDynamicCFile(const string &dynamic_basename, const int order) const
|
||||||
{
|
{
|
||||||
string filename = dynamic_basename + ".c";
|
string filename = dynamic_basename + ".c";
|
||||||
ofstream mDynamicModelFile;
|
string filename_mex = dynamic_basename + "_mex.c";
|
||||||
|
ofstream mDynamicModelFile, mDynamicMexFile;
|
||||||
|
|
||||||
mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary);
|
mDynamicModelFile.open(filename.c_str(), ios::out | ios::binary);
|
||||||
if (!mDynamicModelFile.is_open())
|
if (!mDynamicModelFile.is_open())
|
||||||
|
@ -1531,12 +1532,16 @@ DynamicModel::writeDynamicCFile(const string &dynamic_basename, const int order)
|
||||||
<< " *" << endl
|
<< " *" << endl
|
||||||
<< " * Warning : this file is generated automatically by Dynare" << endl
|
<< " * Warning : this file is generated automatically by Dynare" << endl
|
||||||
<< " * from model file (.mod)" << endl
|
<< " * from model file (.mod)" << endl
|
||||||
<< endl
|
|
||||||
<< " */" << endl
|
<< " */" << endl
|
||||||
<< "#include <math.h>" << endl
|
<< "#include <math.h>" << endl;
|
||||||
<< "#include \"mex.h\"" << endl
|
|
||||||
<< endl
|
if (external_functions_table.get_total_number_of_unique_model_block_external_functions())
|
||||||
<< "#define max(a, b) (((a) > (b)) ? (a) : (b))" << endl
|
// External Matlab function, implies Dynamic function will call mex
|
||||||
|
mDynamicModelFile << "#include \"mex.h\"" << endl;
|
||||||
|
else
|
||||||
|
mDynamicModelFile << "#include <stdlib.h>" << endl;
|
||||||
|
|
||||||
|
mDynamicModelFile << "#define max(a, b) (((a) > (b)) ? (a) : (b))" << endl
|
||||||
<< "#define min(a, b) (((a) > (b)) ? (b) : (a))" << endl;
|
<< "#define min(a, b) (((a) > (b)) ? (b) : (a))" << endl;
|
||||||
|
|
||||||
// Write function definition if oPowerDeriv is used
|
// Write function definition if oPowerDeriv is used
|
||||||
|
@ -1545,76 +1550,93 @@ DynamicModel::writeDynamicCFile(const string &dynamic_basename, const int order)
|
||||||
// Writing the function body
|
// Writing the function body
|
||||||
writeDynamicModel(mDynamicModelFile, true);
|
writeDynamicModel(mDynamicModelFile, true);
|
||||||
|
|
||||||
// Writing the gateway routine
|
|
||||||
mDynamicModelFile << "/* The gateway routine */" << endl
|
|
||||||
<< "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl
|
|
||||||
<< "{" << endl
|
|
||||||
<< " double *y, *x, *params, *steady_state;" << endl
|
|
||||||
<< " double *residual, *g1, *v2, *v3;" << endl
|
|
||||||
<< " int nb_row_x, it_;" << endl
|
|
||||||
<< endl
|
|
||||||
<< " /* Check that no derivatives of higher order than computed are being requested */ " << endl
|
|
||||||
<< " if (nlhs > " << order + 1 << ") " << endl
|
|
||||||
<< " mexErrMsgTxt(\"Derivatives of higher order than computed have been requested\"); " << endl
|
|
||||||
<< " /* Create a pointer to the input matrix y. */" << endl
|
|
||||||
<< " y = mxGetPr(prhs[0]);" << endl
|
|
||||||
<< endl
|
|
||||||
<< " /* Create a pointer to the input matrix x. */" << endl
|
|
||||||
<< " x = mxGetPr(prhs[1]);" << endl
|
|
||||||
<< endl
|
|
||||||
<< " /* Create a pointer to the input matrix params. */" << endl
|
|
||||||
<< " params = mxGetPr(prhs[2]);" << endl
|
|
||||||
<< endl
|
|
||||||
<< " /* Create a pointer to the input matrix steady_state. */" << endl
|
|
||||||
<< " steady_state = mxGetPr(prhs[3]);" << endl
|
|
||||||
<< endl
|
|
||||||
<< " /* Fetch time index */" << endl
|
|
||||||
<< " it_ = (int) mxGetScalar(prhs[4]) - 1;" << endl
|
|
||||||
<< endl
|
|
||||||
<< " /* Gets number of rows of matrix x. */" << endl
|
|
||||||
<< " nb_row_x = mxGetM(prhs[1]);" << endl
|
|
||||||
<< endl
|
|
||||||
<< " residual = NULL;" << endl
|
|
||||||
<< " if (nlhs >= 1)" << endl
|
|
||||||
<< " {" << endl
|
|
||||||
<< " /* Set the output pointer to the output matrix residual. */" << endl
|
|
||||||
<< " plhs[0] = mxCreateDoubleMatrix(" << equations.size() << ",1, mxREAL);" << endl
|
|
||||||
<< " /* Create a C pointer to a copy of the output matrix residual. */" << endl
|
|
||||||
<< " residual = mxGetPr(plhs[0]);" << endl
|
|
||||||
<< " }" << endl
|
|
||||||
<< endl
|
|
||||||
<< " g1 = NULL;" << endl
|
|
||||||
<< " if (nlhs >= 2)" << endl
|
|
||||||
<< " {" << endl
|
|
||||||
<< " /* Set the output pointer to the output matrix g1. */" << endl
|
|
||||||
|
|
||||||
<< " plhs[1] = mxCreateDoubleMatrix(" << equations.size() << ", " << dynJacobianColsNbr << ", mxREAL);" << endl
|
|
||||||
<< " /* Create a C pointer to a copy of the output matrix g1. */" << endl
|
|
||||||
<< " g1 = mxGetPr(plhs[1]);" << endl
|
|
||||||
<< " }" << endl
|
|
||||||
<< endl
|
|
||||||
<< " v2 = NULL;" << endl
|
|
||||||
<< " if (nlhs >= 3)" << endl
|
|
||||||
<< " {" << endl
|
|
||||||
<< " /* Set the output pointer to the output matrix v2. */" << endl
|
|
||||||
<< " plhs[2] = mxCreateDoubleMatrix(" << NNZDerivatives[1] << ", " << 3
|
|
||||||
<< ", mxREAL);" << endl
|
|
||||||
<< " v2 = mxGetPr(plhs[2]);" << endl
|
|
||||||
<< " }" << endl
|
|
||||||
<< endl
|
|
||||||
<< " v3 = NULL;" << endl
|
|
||||||
<< " if (nlhs >= 4)" << endl
|
|
||||||
<< " {" << endl
|
|
||||||
<< " /* Set the output pointer to the output matrix v3. */" << endl
|
|
||||||
<< " plhs[3] = mxCreateDoubleMatrix(" << NNZDerivatives[2] << ", " << 3 << ", mxREAL);" << endl
|
|
||||||
<< " v3 = mxGetPr(plhs[3]);" << endl
|
|
||||||
<< " }" << endl
|
|
||||||
<< endl
|
|
||||||
<< " /* Call the C subroutines. */" << endl
|
|
||||||
<< " Dynamic(y, x, nb_row_x, params, steady_state, it_, residual, g1, v2, v3);" << endl
|
|
||||||
<< "}" << endl;
|
|
||||||
writePowerDeriv(mDynamicModelFile, true);
|
writePowerDeriv(mDynamicModelFile, true);
|
||||||
mDynamicModelFile.close();
|
mDynamicModelFile.close();
|
||||||
|
|
||||||
|
mDynamicMexFile.open(filename_mex.c_str(), ios::out | ios::binary);
|
||||||
|
if (!mDynamicMexFile.is_open())
|
||||||
|
{
|
||||||
|
cerr << "Error: Can't open file " << filename_mex << " for writing" << endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Writing the gateway routine
|
||||||
|
mDynamicMexFile << "/*" << endl
|
||||||
|
<< " * " << filename_mex << " : The gateway routine used to call the Dynamic function "
|
||||||
|
<< "located in " << filename << endl
|
||||||
|
<< " *" << endl
|
||||||
|
<< " * Warning : this file is generated automatically by Dynare" << endl
|
||||||
|
<< " * from model file (.mod)" << endl
|
||||||
|
<< endl
|
||||||
|
<< " */" << endl << endl
|
||||||
|
<< "#include \"mex.h\"" << endl << endl
|
||||||
|
<< "void Dynamic(double *y, double *x, int nb_row_x, double *params, double *steady_state, int it_, double *residual, double *g1, double *v2, double *v3);" << endl
|
||||||
|
<< "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl
|
||||||
|
<< "{" << endl
|
||||||
|
<< " double *y, *x, *params, *steady_state;" << endl
|
||||||
|
<< " double *residual, *g1, *v2, *v3;" << endl
|
||||||
|
<< " int nb_row_x, it_;" << endl
|
||||||
|
<< endl
|
||||||
|
<< " /* Check that no derivatives of higher order than computed are being requested */" << endl
|
||||||
|
<< " if (nlhs > " << order + 1 << ")" << endl
|
||||||
|
<< " mexErrMsgTxt(\"Derivatives of higher order than computed have been requested\");" << endl
|
||||||
|
<< " /* Create a pointer to the input matrix y. */" << endl
|
||||||
|
<< " y = mxGetPr(prhs[0]);" << endl
|
||||||
|
<< endl
|
||||||
|
<< " /* Create a pointer to the input matrix x. */" << endl
|
||||||
|
<< " x = mxGetPr(prhs[1]);" << endl
|
||||||
|
<< endl
|
||||||
|
<< " /* Create a pointer to the input matrix params. */" << endl
|
||||||
|
<< " params = mxGetPr(prhs[2]);" << endl
|
||||||
|
<< endl
|
||||||
|
<< " /* Create a pointer to the input matrix steady_state. */" << endl
|
||||||
|
<< " steady_state = mxGetPr(prhs[3]);" << endl
|
||||||
|
<< endl
|
||||||
|
<< " /* Fetch time index */" << endl
|
||||||
|
<< " it_ = (int) mxGetScalar(prhs[4]) - 1;" << endl
|
||||||
|
<< endl
|
||||||
|
<< " /* Gets number of rows of matrix x. */" << endl
|
||||||
|
<< " nb_row_x = mxGetM(prhs[1]);" << endl
|
||||||
|
<< endl
|
||||||
|
<< " residual = NULL;" << endl
|
||||||
|
<< " if (nlhs >= 1)" << endl
|
||||||
|
<< " {" << endl
|
||||||
|
<< " /* Set the output pointer to the output matrix residual. */" << endl
|
||||||
|
<< " plhs[0] = mxCreateDoubleMatrix(" << equations.size() << ",1, mxREAL);" << endl
|
||||||
|
<< " /* Create a C pointer to a copy of the output matrix residual. */" << endl
|
||||||
|
<< " residual = mxGetPr(plhs[0]);" << endl
|
||||||
|
<< " }" << endl
|
||||||
|
<< endl
|
||||||
|
<< " g1 = NULL;" << endl
|
||||||
|
<< " if (nlhs >= 2)" << endl
|
||||||
|
<< " {" << endl
|
||||||
|
<< " /* Set the output pointer to the output matrix g1. */" << endl
|
||||||
|
<< " plhs[1] = mxCreateDoubleMatrix(" << equations.size() << ", " << dynJacobianColsNbr << ", mxREAL);" << endl
|
||||||
|
<< " /* Create a C pointer to a copy of the output matrix g1. */" << endl
|
||||||
|
<< " g1 = mxGetPr(plhs[1]);" << endl
|
||||||
|
<< " }" << endl
|
||||||
|
<< endl
|
||||||
|
<< " v2 = NULL;" << endl
|
||||||
|
<< " if (nlhs >= 3)" << endl
|
||||||
|
<< " {" << endl
|
||||||
|
<< " /* Set the output pointer to the output matrix v2. */" << endl
|
||||||
|
<< " plhs[2] = mxCreateDoubleMatrix(" << NNZDerivatives[1] << ", " << 3
|
||||||
|
<< ", mxREAL);" << endl
|
||||||
|
<< " v2 = mxGetPr(plhs[2]);" << endl
|
||||||
|
<< " }" << endl
|
||||||
|
<< endl
|
||||||
|
<< " v3 = NULL;" << endl
|
||||||
|
<< " if (nlhs >= 4)" << endl
|
||||||
|
<< " {" << endl
|
||||||
|
<< " /* Set the output pointer to the output matrix v3. */" << endl
|
||||||
|
<< " plhs[3] = mxCreateDoubleMatrix(" << NNZDerivatives[2] << ", " << 3 << ", mxREAL);" << endl
|
||||||
|
<< " v3 = mxGetPr(plhs[3]);" << endl
|
||||||
|
<< " }" << endl
|
||||||
|
<< endl
|
||||||
|
<< " /* Call the C subroutines. */" << endl
|
||||||
|
<< " Dynamic(y, x, nb_row_x, params, steady_state, it_, residual, g1, v2, v3);" << endl
|
||||||
|
<< "}" << endl;
|
||||||
|
mDynamicMexFile.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
string
|
string
|
||||||
|
|
|
@ -545,31 +545,33 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool console,
|
||||||
#if defined(_WIN32) || defined(__CYGWIN32__)
|
#if defined(_WIN32) || defined(__CYGWIN32__)
|
||||||
if (msvc)
|
if (msvc)
|
||||||
// MATLAB/Windows + Microsoft Visual C++
|
// MATLAB/Windows + Microsoft Visual C++
|
||||||
mOutputFile << " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Dynamic\" " << basename << "_dynamic.c')" << endl
|
mOutputFile << " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Dynamic\" " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl
|
||||||
<< " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Dynamic\" " << basename << "_static.c')" << endl;
|
<< " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Dynamic\" " << basename << "_static.c "<< basename << "_static_mex.c')" << endl;
|
||||||
else if (cygwin)
|
else if (cygwin)
|
||||||
// MATLAB/Windows + Cygwin g++
|
// 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')" << endl
|
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 Dynamic >> mex.def\" " << basename << "_static.c')" << endl;
|
<< " eval('mex -O PRELINK_CMDS1=\"echo EXPORTS > mex.def & echo mexFunction >> mex.def & echo Dynamic >> mex.def\" " << basename << "_static.c "<< basename << "_static_mex.c')" << endl;
|
||||||
else
|
else
|
||||||
mOutputFile << " error('When using the USE_DLL option, you must give either ''cygwin'' or ''msvc'' option to the ''dynare'' command')" << endl;
|
mOutputFile << " error('When using the USE_DLL option, you must give either ''cygwin'' or ''msvc'' option to the ''dynare'' command')" << endl;
|
||||||
#else
|
#else
|
||||||
# ifdef __linux__
|
# ifdef __linux__
|
||||||
// MATLAB/Linux
|
// MATLAB/Linux
|
||||||
mOutputFile << " eval('mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' " << basename << "_dynamic.c')" << endl
|
mOutputFile << " 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')" << endl;
|
<< " eval('mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' " << basename << "_static.c "<< basename << "_static_mex.c')" << endl;
|
||||||
# else // MacOS
|
# else // MacOS
|
||||||
// MATLAB/MacOS
|
// MATLAB/MacOS
|
||||||
mOutputFile << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " << basename << "_dynamic.c')" << endl
|
mOutputFile << " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' "
|
||||||
<< " eval('mex -O LDFLAGS=''-Wl,-twolevel_namespace -undefined error -arch \\$ARCHS -Wl,-syslibroot,\\$SDKROOT -mmacosx-version-min=\\$MACOSX_DEPLOYMENT_TARGET -bundle'' " << basename << "_static.c')" << endl;
|
<< 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;
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
mOutputFile << "else" << endl // Octave
|
mOutputFile << "else" << endl // Octave
|
||||||
<< " if ~octave_ver_less_than('3.2.0')" << endl // Workaround for bug in Octave >= 3.2, see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=550823
|
<< " if ~octave_ver_less_than('3.2.0')" << endl // Workaround for bug in Octave >= 3.2, see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=550823
|
||||||
<< " sleep(2)" << endl
|
<< " sleep(2)" << endl
|
||||||
<< " end" << endl
|
<< " end" << endl
|
||||||
<< " mex " << basename << "_dynamic.c" << endl
|
<< " mex " << basename << "_dynamic.c " << basename << "_dynamic_mex.c" << endl
|
||||||
<< " mex " << basename << "_static.c" << endl
|
<< " mex " << basename << "_static.c " << basename << "_static_mex.c" << endl
|
||||||
<< "end" << endl;
|
<< "end" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1288,6 +1288,7 @@ StaticModel::writeStaticCFile(const string &func_name) const
|
||||||
{
|
{
|
||||||
// Writing comments and function definition command
|
// Writing comments and function definition command
|
||||||
string filename = func_name + "_static.c";
|
string filename = func_name + "_static.c";
|
||||||
|
string filename_mex = func_name + "_static_mex.c";
|
||||||
|
|
||||||
ofstream output;
|
ofstream output;
|
||||||
output.open(filename.c_str(), ios::out | ios::binary);
|
output.open(filename.c_str(), ios::out | ios::binary);
|
||||||
|
@ -1303,10 +1304,15 @@ StaticModel::writeStaticCFile(const string &func_name) const
|
||||||
<< " * Warning : this file is generated automatically by Dynare" << endl
|
<< " * Warning : this file is generated automatically by Dynare" << endl
|
||||||
<< " * from model file (.mod)" << endl << endl
|
<< " * from model file (.mod)" << endl << endl
|
||||||
<< " */" << endl
|
<< " */" << endl
|
||||||
<< "#include <math.h>" << endl
|
<< "#include <math.h>" << endl;
|
||||||
<< "#include \"mex.h\"" << endl
|
|
||||||
<< endl
|
if (external_functions_table.get_total_number_of_unique_model_block_external_functions())
|
||||||
<< "#define max(a, b) (((a) > (b)) ? (a) : (b))" << endl
|
// External Matlab function, implies Static function will call mex
|
||||||
|
output << "#include \"mex.h\"" << endl;
|
||||||
|
else
|
||||||
|
output << "#include <stdlib.h>" << endl;
|
||||||
|
|
||||||
|
output << "#define max(a, b) (((a) > (b)) ? (a) : (b))" << endl
|
||||||
<< "#define min(a, b) (((a) > (b)) ? (b) : (a))" << endl;
|
<< "#define min(a, b) (((a) > (b)) ? (b) : (a))" << endl;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1317,8 +1323,26 @@ StaticModel::writeStaticCFile(const string &func_name) const
|
||||||
writeStaticModel(output, true);
|
writeStaticModel(output, true);
|
||||||
output << "}" << endl << endl;
|
output << "}" << endl << endl;
|
||||||
|
|
||||||
|
writePowerDeriv(output, true);
|
||||||
|
output.close();
|
||||||
|
|
||||||
|
output.open(filename_mex.c_str(), ios::out | ios::binary);
|
||||||
|
if (!output.is_open())
|
||||||
|
{
|
||||||
|
cerr << "ERROR: Can't open file " << filename_mex << " for writing" << endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
// Writing the gateway routine
|
// Writing the gateway routine
|
||||||
output << "/* The gateway routine */" << endl
|
output << "/*" << endl
|
||||||
|
<< " * " << filename_mex << " : The gateway routine used to call the Static function "
|
||||||
|
<< "located in " << filename << endl
|
||||||
|
<< " *" << endl
|
||||||
|
<< " * Warning : this file is generated automatically by Dynare" << endl
|
||||||
|
<< " * from model file (.mod)" << endl << endl
|
||||||
|
<< " */" << endl << endl
|
||||||
|
<< "#include \"mex.h\"" << endl << endl
|
||||||
|
<< "void Static(double *y, double *x, int nb_row_x, double *params, double *residual, double *g1, double *v2);" << endl
|
||||||
<< "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl
|
<< "void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])" << endl
|
||||||
<< "{" << endl
|
<< "{" << endl
|
||||||
<< " double *y, *x, *params;" << endl
|
<< " double *y, *x, *params;" << endl
|
||||||
|
@ -1367,7 +1391,6 @@ StaticModel::writeStaticCFile(const string &func_name) const
|
||||||
<< " /* Call the C subroutines. */" << endl
|
<< " /* Call the C subroutines. */" << endl
|
||||||
<< " Static(y, x, nb_row_x, params, residual, g1, v2);" << endl
|
<< " Static(y, x, nb_row_x, params, residual, g1, v2);" << endl
|
||||||
<< "}" << endl << endl;
|
<< "}" << endl << endl;
|
||||||
writePowerDeriv(output, true);
|
|
||||||
output.close();
|
output.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue