The preprocessor now compiles the MEX when use_dll is specified
New options "mexext" and "matlabroot" are introduced, so that the preprocessor knows where to find MATLAB and which architecture to compile for. Only recent gcc is now supported. A set of optimization flags is used so that compilation goes reasonably fast on large models. Consequently, options "msvc", "mingw" and "cygwin" have been removed.issue#70
parent
1c33af4844
commit
4a974bb428
|
@ -2174,7 +2174,7 @@ PlannerObjectiveStatement::computingPass()
|
||||||
void
|
void
|
||||||
PlannerObjectiveStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
|
PlannerObjectiveStatement::writeOutput(ostream &output, const string &basename, bool minimal_workspace) const
|
||||||
{
|
{
|
||||||
model_tree.writeStaticFile(basename + ".objective", false, false, false, false);
|
model_tree.writeStaticFile(basename + ".objective", false, false, false, "", {}, {}, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -829,51 +829,6 @@ DataTree::writePowerDeriv(ostream &output) const
|
||||||
<< "}" << endl;
|
<< "}" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
DataTree::writeNormcdfCHeader(ostream &output) const
|
|
||||||
{
|
|
||||||
#if defined(_WIN32) || defined(__CYGWIN32__)
|
|
||||||
if (isTrinaryOpUsed(TrinaryOpcode::normcdf))
|
|
||||||
output << "#ifdef _MSC_VER" << endl
|
|
||||||
<< "double normcdf(double);" << endl
|
|
||||||
<< "#endif" << endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
DataTree::writeNormcdf(ostream &output) const
|
|
||||||
{
|
|
||||||
#if defined(_WIN32) || defined(__CYGWIN32__)
|
|
||||||
if (isTrinaryOpUsed(TrinaryOpcode::normcdf))
|
|
||||||
output << endl
|
|
||||||
<< "#ifdef _MSC_VER" << endl
|
|
||||||
<< "/*" << endl
|
|
||||||
<< " * Define normcdf for MSVC compiler" << endl
|
|
||||||
<< " */" << endl
|
|
||||||
<< "double normcdf(double x)" << endl
|
|
||||||
<< "{" << endl
|
|
||||||
<< "#if _MSC_VER >= 1700" << endl
|
|
||||||
<< " return 0.5 * erfc(-x * M_SQRT1_2);" << endl
|
|
||||||
<< "#else" << endl
|
|
||||||
<< " // From http://www.johndcook.com/blog/cpp_phi" << endl
|
|
||||||
<< " double a1 = 0.254829592;" << endl
|
|
||||||
<< " double a2 = -0.284496736;" << endl
|
|
||||||
<< " double a3 = 1.421413741;" << endl
|
|
||||||
<< " double a4 = -1.453152027;" << endl
|
|
||||||
<< " double a5 = 1.061405429;" << endl
|
|
||||||
<< " double p = 0.3275911;" << endl
|
|
||||||
<< " int sign = (x < 0) ? -1 : 1;" << endl
|
|
||||||
<< " x = fabs(x)/sqrt(2.0);" << endl
|
|
||||||
<< " // From the Handbook of Mathematical Functions by Abramowitz and Stegun, formula 7.1.26" << endl
|
|
||||||
<< " double t = 1.0/(1.0 + p*x);" << endl
|
|
||||||
<< " double y = 1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x);" << endl
|
|
||||||
<< " return 0.5*(1.0 + sign*y);" << endl
|
|
||||||
<< "#endif" << endl
|
|
||||||
<< "}" << endl
|
|
||||||
<< "#endif" << endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
string
|
string
|
||||||
DataTree::packageDir(const string &package)
|
DataTree::packageDir(const string &package)
|
||||||
{
|
{
|
||||||
|
|
|
@ -276,10 +276,6 @@ public:
|
||||||
void writePowerDerivCHeader(ostream &output) const;
|
void writePowerDerivCHeader(ostream &output) const;
|
||||||
//! Write getPowerDeriv in C
|
//! Write getPowerDeriv in C
|
||||||
void writePowerDeriv(ostream &output) const;
|
void writePowerDeriv(ostream &output) const;
|
||||||
//! Write the C Header for normcdf when use_dll is used
|
|
||||||
void writeNormcdfCHeader(ostream &output) const;
|
|
||||||
//! Write normcdf in C
|
|
||||||
void writeNormcdf(ostream &output) const;
|
|
||||||
//! Thrown when trying to access an unknown variable by deriv_id
|
//! Thrown when trying to access an unknown variable by deriv_id
|
||||||
class UnknownDerivIDException
|
class UnknownDerivIDException
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,8 +27,6 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
|
||||||
|
|
||||||
#include "DynamicModel.hh"
|
#include "DynamicModel.hh"
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1738,11 +1736,6 @@ DynamicModel::writeDynamicCFile(const string &basename, const int order) const
|
||||||
<< " * 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
|
||||||
#if defined(_WIN32) || defined(__CYGWIN32__)
|
|
||||||
<< "#ifdef _MSC_VER" << endl
|
|
||||||
<< "#define _USE_MATH_DEFINES" << endl
|
|
||||||
<< "#endif" << endl
|
|
||||||
#endif
|
|
||||||
<< "#include <math.h>" << endl;
|
<< "#include <math.h>" << endl;
|
||||||
|
|
||||||
if (external_functions_table.get_total_number_of_unique_model_block_external_functions())
|
if (external_functions_table.get_total_number_of_unique_model_block_external_functions())
|
||||||
|
@ -1756,7 +1749,6 @@ DynamicModel::writeDynamicCFile(const string &basename, const int order) const
|
||||||
|
|
||||||
// Write function definition if BinaryOpcode::powerDeriv is used
|
// Write function definition if BinaryOpcode::powerDeriv is used
|
||||||
writePowerDerivCHeader(mDynamicModelFile);
|
writePowerDerivCHeader(mDynamicModelFile);
|
||||||
writeNormcdfCHeader(mDynamicModelFile);
|
|
||||||
|
|
||||||
mDynamicModelFile << endl;
|
mDynamicModelFile << endl;
|
||||||
|
|
||||||
|
@ -1766,7 +1758,6 @@ DynamicModel::writeDynamicCFile(const string &basename, const int order) const
|
||||||
mDynamicModelFile << endl;
|
mDynamicModelFile << endl;
|
||||||
|
|
||||||
writePowerDeriv(mDynamicModelFile);
|
writePowerDeriv(mDynamicModelFile);
|
||||||
writeNormcdf(mDynamicModelFile);
|
|
||||||
mDynamicModelFile.close();
|
mDynamicModelFile.close();
|
||||||
|
|
||||||
mDynamicMexFile.open(filename_mex, ios::out | ios::binary);
|
mDynamicMexFile.open(filename_mex, ios::out | ios::binary);
|
||||||
|
@ -4920,7 +4911,7 @@ DynamicModel::collectBlockVariables()
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
DynamicModel::writeDynamicFile(const string &basename, bool block, bool linear_decomposition, bool bytecode, bool use_dll, int order, bool julia) const
|
DynamicModel::writeDynamicFile(const string &basename, bool block, bool linear_decomposition, bool bytecode, bool use_dll, const string &mexext, const boost::filesystem::path &matlabroot, const boost::filesystem::path &dynareroot, int order, bool julia) const
|
||||||
{
|
{
|
||||||
if (block && bytecode)
|
if (block && bytecode)
|
||||||
writeModelEquationsCode_Block(basename, map_idx, linear_decomposition);
|
writeModelEquationsCode_Block(basename, map_idx, linear_decomposition);
|
||||||
|
@ -4933,7 +4924,10 @@ DynamicModel::writeDynamicFile(const string &basename, bool block, bool linear_d
|
||||||
else if (block && !bytecode)
|
else if (block && !bytecode)
|
||||||
writeSparseDynamicMFile(basename);
|
writeSparseDynamicMFile(basename);
|
||||||
else if (use_dll)
|
else if (use_dll)
|
||||||
|
{
|
||||||
writeDynamicCFile(basename, order);
|
writeDynamicCFile(basename, order);
|
||||||
|
compileDll(basename, "dynamic", mexext, matlabroot, dynareroot);
|
||||||
|
}
|
||||||
else if (julia)
|
else if (julia)
|
||||||
writeDynamicJuliaFile(basename);
|
writeDynamicJuliaFile(basename);
|
||||||
else
|
else
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
#include <boost/crc.hpp>
|
#include <boost/crc.hpp>
|
||||||
|
|
||||||
#include "StaticModel.hh"
|
#include "StaticModel.hh"
|
||||||
|
@ -359,7 +361,7 @@ public:
|
||||||
void Write_Inf_To_Bin_File_Block(const string &basename,
|
void Write_Inf_To_Bin_File_Block(const string &basename,
|
||||||
const int &num, int &u_count_int, bool &file_open, bool is_two_boundaries, const bool linear_decomposition) const;
|
const int &num, int &u_count_int, bool &file_open, bool is_two_boundaries, const bool linear_decomposition) const;
|
||||||
//! Writes dynamic model file
|
//! Writes dynamic model file
|
||||||
void writeDynamicFile(const string &basename, bool block, bool linear_decomposition, bool bytecode, bool use_dll, int order, bool julia) const;
|
void writeDynamicFile(const string &basename, bool block, bool linear_decomposition, bool bytecode, bool use_dll, const string &mexext, const boost::filesystem::path &matlabroot, const boost::filesystem::path &dynareroot, int order, bool julia) const;
|
||||||
//! Writes file containing parameters derivatives
|
//! Writes file containing parameters derivatives
|
||||||
void writeParamsDerivativesFile(const string &basename, bool julia) const;
|
void writeParamsDerivativesFile(const string &basename, bool julia) const;
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
#include "ParsingDriver.hh"
|
#include "ParsingDriver.hh"
|
||||||
#include "ExtendedPreprocessorTypes.hh"
|
#include "ExtendedPreprocessorTypes.hh"
|
||||||
#include "ConfigFile.hh"
|
#include "ConfigFile.hh"
|
||||||
|
@ -41,13 +44,10 @@ void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool
|
||||||
bool nograph, bool nointeractive, bool parallel, ConfigFile &config_file,
|
bool nograph, bool nointeractive, bool parallel, ConfigFile &config_file,
|
||||||
WarningConsolidation &warnings_arg, bool nostrict, bool stochastic, bool check_model_changes,
|
WarningConsolidation &warnings_arg, bool nostrict, bool stochastic, bool check_model_changes,
|
||||||
bool minimal_workspace, bool compute_xrefs, FileOutputType output_mode,
|
bool minimal_workspace, bool compute_xrefs, FileOutputType output_mode,
|
||||||
LanguageOutputType lang, int params_derivs_order, bool transform_unary_ops
|
LanguageOutputType lang, int params_derivs_order, bool transform_unary_ops,
|
||||||
#if defined(_WIN32) || defined(__CYGWIN32__)
|
JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple,
|
||||||
, bool cygwin, bool msvc, bool mingw
|
bool nopreprocessoroutput, const string &mexext, const boost::filesystem::path &matlabroot,
|
||||||
#endif
|
const boost::filesystem::path &dynareroot);
|
||||||
, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple
|
|
||||||
, bool nopreprocessoroutput
|
|
||||||
);
|
|
||||||
|
|
||||||
void main1(string &modfile, string &basename, string &modfiletxt, bool debug, bool save_macro, string &save_macro_file,
|
void main1(string &modfile, string &basename, string &modfiletxt, bool debug, bool save_macro, string &save_macro_file,
|
||||||
bool no_line_macro, bool no_empty_line_macro, map<string, string> &defines, vector<string> &path, stringstream ¯o_output);
|
bool no_line_macro, bool no_empty_line_macro, map<string, string> &defines, vector<string> &path, stringstream ¯o_output);
|
||||||
|
@ -59,10 +59,8 @@ usage()
|
||||||
<< " [console] [nograph] [nointeractive] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test]"
|
<< " [console] [nograph] [nointeractive] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test]"
|
||||||
<< " [-D<variable>[=<value>]] [-I/path] [nostrict] [stochastic] [fast] [minimal_workspace] [compute_xrefs] [output=dynamic|first|second|third] [language=julia]"
|
<< " [-D<variable>[=<value>]] [-I/path] [nostrict] [stochastic] [fast] [minimal_workspace] [compute_xrefs] [output=dynamic|first|second|third] [language=julia]"
|
||||||
<< " [params_derivs_order=0|1|2] [transform_unary_ops]"
|
<< " [params_derivs_order=0|1|2] [transform_unary_ops]"
|
||||||
#if defined(_WIN32) || defined(__CYGWIN32__)
|
|
||||||
<< " [cygwin] [msvc] [mingw]"
|
|
||||||
#endif
|
|
||||||
<< " [json=parse|check|transform|compute] [jsonstdout] [onlyjson] [jsonderivsimple] [nopathchange] [nopreprocessoroutput]"
|
<< " [json=parse|check|transform|compute] [jsonstdout] [onlyjson] [jsonderivsimple] [nopathchange] [nopreprocessoroutput]"
|
||||||
|
<< " [dll=matlab|octave] [matlabroot=path]"
|
||||||
<< endl;
|
<< endl;
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
@ -99,11 +97,6 @@ main(int argc, char **argv)
|
||||||
bool console = false;
|
bool console = false;
|
||||||
bool nograph = false;
|
bool nograph = false;
|
||||||
bool nointeractive = false;
|
bool nointeractive = false;
|
||||||
#if defined(_WIN32) || defined(__CYGWIN32__)
|
|
||||||
bool cygwin = false;
|
|
||||||
bool msvc = false;
|
|
||||||
bool mingw = false;
|
|
||||||
#endif
|
|
||||||
string parallel_config_file;
|
string parallel_config_file;
|
||||||
bool parallel = false;
|
bool parallel = false;
|
||||||
string cluster_name;
|
string cluster_name;
|
||||||
|
@ -124,6 +117,11 @@ main(int argc, char **argv)
|
||||||
bool jsonderivsimple = false;
|
bool jsonderivsimple = false;
|
||||||
LanguageOutputType language{LanguageOutputType::matlab};
|
LanguageOutputType language{LanguageOutputType::matlab};
|
||||||
bool nopreprocessoroutput = false;
|
bool nopreprocessoroutput = false;
|
||||||
|
string mexext;
|
||||||
|
boost::filesystem::path matlabroot;
|
||||||
|
boost::filesystem::path dynareroot{argv[0]};
|
||||||
|
dynareroot = dynareroot.parent_path();
|
||||||
|
dynareroot = dynareroot / ".." / "..";
|
||||||
|
|
||||||
// Parse options
|
// Parse options
|
||||||
for (int arg = 2; arg < argc; arg++)
|
for (int arg = 2; arg < argc; arg++)
|
||||||
|
@ -180,14 +178,6 @@ main(int argc, char **argv)
|
||||||
nograph = true;
|
nograph = true;
|
||||||
else if (!strcmp(argv[arg], "nointeractive"))
|
else if (!strcmp(argv[arg], "nointeractive"))
|
||||||
nointeractive = true;
|
nointeractive = true;
|
||||||
#if defined(_WIN32) || defined(__CYGWIN32__)
|
|
||||||
else if (!strcmp(argv[arg], "cygwin"))
|
|
||||||
cygwin = true;
|
|
||||||
else if (!strcmp(argv[arg], "msvc"))
|
|
||||||
msvc = true;
|
|
||||||
else if (!strcmp(argv[arg], "mingw"))
|
|
||||||
mingw = true;
|
|
||||||
#endif
|
|
||||||
else if (strlen(argv[arg]) >= 8 && !strncmp(argv[arg], "conffile", 8))
|
else if (strlen(argv[arg]) >= 8 && !strncmp(argv[arg], "conffile", 8))
|
||||||
{
|
{
|
||||||
if (strlen(argv[arg]) <= 9 || argv[arg][8] != '=')
|
if (strlen(argv[arg]) <= 9 || argv[arg][8] != '=')
|
||||||
|
@ -332,6 +322,28 @@ main(int argc, char **argv)
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (strlen(argv[arg]) >= 6 && !strncmp(argv[arg], "mexext", 6))
|
||||||
|
{
|
||||||
|
string s{argv[arg]};
|
||||||
|
if (s.length() <= 7 || s.at(6) != '=')
|
||||||
|
{
|
||||||
|
cerr << "Incorrect syntax for mexext option" << endl;
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
s.erase(0, 7);
|
||||||
|
mexext = s;
|
||||||
|
}
|
||||||
|
else if (strlen(argv[arg]) >= 10 && !strncmp(argv[arg], "matlabroot", 10))
|
||||||
|
{
|
||||||
|
string s{argv[arg]};
|
||||||
|
if (s.length() <= 11 || s.at(10) != '=')
|
||||||
|
{
|
||||||
|
cerr << "Incorrect syntax for matlabroot option" << endl;
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
s.erase(0, 11);
|
||||||
|
matlabroot = boost::filesystem::path{s};
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cerr << "Unknown option: " << argv[arg] << endl;
|
cerr << "Unknown option: " << argv[arg] << endl;
|
||||||
|
@ -400,12 +412,9 @@ main(int argc, char **argv)
|
||||||
main2(macro_output, basename, debug, clear_all, clear_global,
|
main2(macro_output, basename, debug, clear_all, clear_global,
|
||||||
no_tmp_terms, no_log, no_warn, warn_uninit, console, nograph, nointeractive,
|
no_tmp_terms, no_log, no_warn, warn_uninit, console, nograph, nointeractive,
|
||||||
parallel, config_file, warnings, nostrict, stochastic, check_model_changes, minimal_workspace,
|
parallel, config_file, warnings, nostrict, stochastic, check_model_changes, minimal_workspace,
|
||||||
compute_xrefs, output_mode, language, params_derivs_order, transform_unary_ops
|
compute_xrefs, output_mode, language, params_derivs_order, transform_unary_ops,
|
||||||
#if defined(_WIN32) || defined(__CYGWIN32__)
|
json, json_output_mode, onlyjson, jsonderivsimple, nopreprocessoroutput,
|
||||||
, cygwin, msvc, mingw
|
mexext, matlabroot, dynareroot);
|
||||||
#endif
|
|
||||||
, json, json_output_mode, onlyjson, jsonderivsimple, nopreprocessoroutput
|
|
||||||
);
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,13 +32,10 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear
|
||||||
bool nograph, bool nointeractive, bool parallel, ConfigFile &config_file,
|
bool nograph, bool nointeractive, bool parallel, ConfigFile &config_file,
|
||||||
WarningConsolidation &warnings, bool nostrict, bool stochastic, bool check_model_changes,
|
WarningConsolidation &warnings, bool nostrict, bool stochastic, bool check_model_changes,
|
||||||
bool minimal_workspace, bool compute_xrefs, FileOutputType output_mode,
|
bool minimal_workspace, bool compute_xrefs, FileOutputType output_mode,
|
||||||
LanguageOutputType language, int params_derivs_order, bool transform_unary_ops
|
LanguageOutputType language, int params_derivs_order, bool transform_unary_ops,
|
||||||
#if defined(_WIN32) || defined(__CYGWIN32__)
|
JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple,
|
||||||
, bool cygwin, bool msvc, bool mingw
|
bool nopreprocessoroutput, const string &mexext, const boost::filesystem::path &matlabroot,
|
||||||
#endif
|
const boost::filesystem::path &dynareroot)
|
||||||
, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple
|
|
||||||
, bool nopreprocessoroutput
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
ParsingDriver p(warnings, nostrict);
|
ParsingDriver p(warnings, nostrict);
|
||||||
|
|
||||||
|
@ -72,12 +69,8 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool clear
|
||||||
mod_file->writeExternalFiles(basename, output_mode, language, nopreprocessoroutput);
|
mod_file->writeExternalFiles(basename, output_mode, language, nopreprocessoroutput);
|
||||||
else
|
else
|
||||||
mod_file->writeOutputFiles(basename, clear_all, clear_global, no_log, no_warn, console, nograph,
|
mod_file->writeOutputFiles(basename, clear_all, clear_global, no_log, no_warn, console, nograph,
|
||||||
nointeractive, config_file, check_model_changes, minimal_workspace, compute_xrefs
|
nointeractive, config_file, check_model_changes, minimal_workspace, compute_xrefs,
|
||||||
#if defined(_WIN32) || defined(__CYGWIN32__)
|
nopreprocessoroutput, mexext, matlabroot, dynareroot);
|
||||||
, cygwin, msvc, mingw
|
|
||||||
#endif
|
|
||||||
, nopreprocessoroutput
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!nopreprocessoroutput)
|
if (!nopreprocessoroutput)
|
||||||
cout << "Preprocessing completed." << endl;
|
cout << "Preprocessing completed." << endl;
|
||||||
|
|
|
@ -789,12 +789,10 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_deri
|
||||||
void
|
void
|
||||||
ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn,
|
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 console, bool nograph, bool nointeractive, const ConfigFile &config_file,
|
||||||
bool check_model_changes, bool minimal_workspace, bool compute_xrefs
|
bool check_model_changes, bool minimal_workspace, bool compute_xrefs,
|
||||||
#if defined(_WIN32) || defined(__CYGWIN32__)
|
const bool nopreprocessoroutput, const string &mexext,
|
||||||
, bool cygwin, bool msvc, bool mingw
|
const boost::filesystem::path &matlabroot,
|
||||||
#endif
|
const boost::filesystem::path &dynareroot) const
|
||||||
, const bool nopreprocessoroutput
|
|
||||||
) const
|
|
||||||
{
|
{
|
||||||
bool hasModelChanged = !dynamic_model.isChecksumMatching(basename, block);
|
bool hasModelChanged = !dynamic_model.isChecksumMatching(basename, block);
|
||||||
if (!check_model_changes)
|
if (!check_model_changes)
|
||||||
|
@ -955,32 +953,6 @@ 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
|
<< " error('DYNARE: Can''t find bytecode DLL. Please compile it or remove the ''bytecode'' option.')" << endl
|
||||||
<< "end" << endl;
|
<< "end" << endl;
|
||||||
|
|
||||||
// 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 << "', " << !check_model_changes << ")" << endl;
|
|
||||||
else if (cygwin)
|
|
||||||
// MATLAB/Windows + Cygwin g++
|
|
||||||
mOutputFile << "dyn_mex('cygwin', '" << basename << "', " << !check_model_changes << ")" << endl;
|
|
||||||
else if (mingw)
|
|
||||||
// MATLAB/Windows + MinGW g++
|
|
||||||
mOutputFile << "dyn_mex('mingw', '" << basename << "', " << !check_model_changes << ")" << endl;
|
|
||||||
else
|
|
||||||
mOutputFile << "if isoctave" << endl
|
|
||||||
<< " dyn_mex('', '" << basename << "', " << !check_model_changes << ")" << endl
|
|
||||||
<< "else" << endl
|
|
||||||
<< " error('When using the USE_DLL option on Matlab, you must give the ''cygwin'', ''msvc'', or ''mingw'' option to the ''dynare'' command')" << endl
|
|
||||||
<< "end" << endl;
|
|
||||||
#else
|
|
||||||
// other configurations
|
|
||||||
mOutputFile << "dyn_mex('', '" << basename << "', " << !check_model_changes << ")" << endl;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
mOutputFile << "M_.orig_eq_nbr = " << mod_file_struct.orig_eq_nbr << ";" << endl
|
mOutputFile << "M_.orig_eq_nbr = " << mod_file_struct.orig_eq_nbr << ";" << endl
|
||||||
<< "M_.eq_nbr = " << dynamic_model.equation_number() << ";" << endl
|
<< "M_.eq_nbr = " << dynamic_model.equation_number() << ";" << endl
|
||||||
<< "M_.ramsey_eq_nbr = " << mod_file_struct.ramsey_eq_nbr << ";" << endl
|
<< "M_.ramsey_eq_nbr = " << mod_file_struct.ramsey_eq_nbr << ";" << endl
|
||||||
|
@ -1060,17 +1032,17 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
|
||||||
{
|
{
|
||||||
if (!no_static)
|
if (!no_static)
|
||||||
{
|
{
|
||||||
static_model.writeStaticFile(basename, block, byte_code, use_dll, false);
|
static_model.writeStaticFile(basename, block, byte_code, use_dll, mexext, matlabroot, dynareroot, false);
|
||||||
static_model.writeParamsDerivativesFile(basename, false);
|
static_model.writeParamsDerivativesFile(basename, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (linear_decomposition)
|
if (linear_decomposition)
|
||||||
{
|
{
|
||||||
non_linear_equations_dynamic_model.writeDynamicFile(basename, block, linear_decomposition, byte_code, use_dll, mod_file_struct.order_option, false);
|
non_linear_equations_dynamic_model.writeDynamicFile(basename, block, linear_decomposition, byte_code, use_dll, mexext, matlabroot, dynareroot, mod_file_struct.order_option, false);
|
||||||
non_linear_equations_dynamic_model.writeParamsDerivativesFile(basename, false);
|
non_linear_equations_dynamic_model.writeParamsDerivativesFile(basename, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic_model.writeDynamicFile(basename, block, false, byte_code, use_dll, mod_file_struct.order_option, false);
|
dynamic_model.writeDynamicFile(basename, block, false, byte_code, use_dll, mexext, matlabroot, dynareroot, mod_file_struct.order_option, false);
|
||||||
|
|
||||||
dynamic_model.writeParamsDerivativesFile(basename, false);
|
dynamic_model.writeParamsDerivativesFile(basename, false);
|
||||||
}
|
}
|
||||||
|
@ -1189,11 +1161,11 @@ ModFile::writeExternalFilesJulia(const string &basename, FileOutputType output,
|
||||||
mod_file_struct.estimation_present, false, true);
|
mod_file_struct.estimation_present, false, true);
|
||||||
if (!no_static)
|
if (!no_static)
|
||||||
{
|
{
|
||||||
static_model.writeStaticFile(basename, false, false, false, true);
|
static_model.writeStaticFile(basename, false, false, false, "", {}, {}, true);
|
||||||
static_model.writeParamsDerivativesFile(basename, true);
|
static_model.writeParamsDerivativesFile(basename, true);
|
||||||
}
|
}
|
||||||
dynamic_model.writeDynamicFile(basename, block, linear_decomposition, byte_code, use_dll,
|
dynamic_model.writeDynamicFile(basename, block, linear_decomposition, byte_code, use_dll,
|
||||||
mod_file_struct.order_option, true);
|
"", {}, {}, mod_file_struct.order_option, true);
|
||||||
dynamic_model.writeParamsDerivativesFile(basename, true);
|
dynamic_model.writeParamsDerivativesFile(basename, true);
|
||||||
}
|
}
|
||||||
steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present, true);
|
steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_model_present, true);
|
||||||
|
|
|
@ -162,12 +162,8 @@ public:
|
||||||
*/
|
*/
|
||||||
void writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_log, bool no_warn,
|
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 console, bool nograph, bool nointeractive, const ConfigFile &config_file,
|
||||||
bool check_model_changes, bool minimal_workspace, bool compute_xrefs
|
bool check_model_changes, bool minimal_workspace, bool compute_xrefs,
|
||||||
#if defined(_WIN32) || defined(__CYGWIN32__)
|
const bool nopreprocessoroutput, const string &mexext, const boost::filesystem::path &matlabroot, const boost::filesystem::path &dynareroot) const;
|
||||||
, bool cygwin, bool msvc, bool mingw
|
|
||||||
#endif
|
|
||||||
, const bool nopreprocessoroutput
|
|
||||||
) const;
|
|
||||||
void writeExternalFiles(const string &basename, FileOutputType output, LanguageOutputType language, const bool nopreprocessoroutput) const;
|
void writeExternalFiles(const string &basename, FileOutputType output, LanguageOutputType language, const bool nopreprocessoroutput) const;
|
||||||
void writeExternalFilesJulia(const string &basename, FileOutputType output, const bool nopreprocessoroutput) const;
|
void writeExternalFilesJulia(const string &basename, FileOutputType output, const bool nopreprocessoroutput) const;
|
||||||
|
|
||||||
|
|
112
src/ModelTree.cc
112
src/ModelTree.cc
|
@ -2308,3 +2308,115 @@ ModelTree::writeJsonModelEquations(ostream &output, bool residuals) const
|
||||||
}
|
}
|
||||||
output << endl << "]" << endl;
|
output << endl << "]" << endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
string
|
||||||
|
ModelTree::matlab_arch(const string &mexext)
|
||||||
|
{
|
||||||
|
if (mexext == "mexglx")
|
||||||
|
return "glnx86";
|
||||||
|
else if (mexext == "mexa64")
|
||||||
|
return "glnxa64";
|
||||||
|
if (mexext == "mexw32")
|
||||||
|
return "win32";
|
||||||
|
else if (mexext == "mexw64")
|
||||||
|
return "win64";
|
||||||
|
else if (mexext == "mexmaci")
|
||||||
|
return "maci";
|
||||||
|
else if (mexext == "mexmaci64")
|
||||||
|
return "maci64";
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cerr << "ERROR: 'mexext' option to preprocessor incorrectly set, needed with 'use_dll'" << endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ModelTree::compileDll(const string &basename, const string &static_or_dynamic, const string &mexext, const boost::filesystem::path &matlabroot, const boost::filesystem::path &dynareroot)
|
||||||
|
{
|
||||||
|
const string opt_flags = "-O3 -g0 --param ira-max-conflict-table-size=1 -fno-forward-propagate -fno-gcse -fno-dce -fno-dse -fno-tree-fre -fno-tree-pre -fno-tree-cselim -fno-tree-dse -fno-tree-dce -fno-tree-pta -fno-gcse-after-reload";
|
||||||
|
|
||||||
|
boost::filesystem::path compiler;
|
||||||
|
ostringstream flags;
|
||||||
|
string libs;
|
||||||
|
|
||||||
|
if (mexext == "mex")
|
||||||
|
{
|
||||||
|
// Octave
|
||||||
|
compiler = matlabroot / "bin" / "mkoctfile";
|
||||||
|
flags << "--mex";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// MATLAB
|
||||||
|
compiler = "gcc";
|
||||||
|
string arch = matlab_arch(mexext);
|
||||||
|
auto include_dir = matlabroot / "extern" / "include";
|
||||||
|
flags << "-I " << include_dir;
|
||||||
|
auto bin_dir = matlabroot / "bin" / arch;
|
||||||
|
flags << " -L " << bin_dir;
|
||||||
|
flags << " -fexceptions -DNDEBUG";
|
||||||
|
libs = "-lmex -lmx -lmat -lmwlapack -lmwblas";
|
||||||
|
if (mexext == "mexglx" || mexext == "mexa64")
|
||||||
|
{
|
||||||
|
// GNU/Linux
|
||||||
|
flags << " -D_GNU_SOURCE -fPIC -pthread"
|
||||||
|
<< " -shared -Wl,--no-undefined -Wl,-rpath-link," << bin_dir;
|
||||||
|
libs += " -lm -lstdc++";
|
||||||
|
|
||||||
|
if (mexext == "mexglx")
|
||||||
|
flags << " -D_FILE_OFFSET_BITS=64 -m32";
|
||||||
|
else
|
||||||
|
flags << " -fno-omit-frame-pointer";
|
||||||
|
}
|
||||||
|
else if (mexext == "mexw32" || mexext == "mexw64")
|
||||||
|
{
|
||||||
|
// Windows
|
||||||
|
flags << " -static-libgcc -static-libstdc++ -shared";
|
||||||
|
// Put the MinGW environment shipped with Dynare in the path
|
||||||
|
boost::filesystem::path mingwpath = dynareroot / (string{"mingw"} + (mexext == "mexw32" ? "32" : "64")) / "bin";
|
||||||
|
string newpath = "PATH=" + mingwpath.string() + ';' + string{getenv("PATH")};
|
||||||
|
if (putenv(const_cast<char *>(newpath.c_str())) != 0)
|
||||||
|
{
|
||||||
|
cerr << "Can't set PATH" << endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// macOS
|
||||||
|
string archs = (mexext == "maci" ? "i386" : "x86_64");
|
||||||
|
flags << " -fno-common -arch " << archs << " -mmacosx-version-min=10.7 -Wl,-twolevel_namespace -undefined error -bundle";
|
||||||
|
libs += " -lm -lstdc++";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto model_dir = boost::filesystem::path{basename} / "model" / "src";
|
||||||
|
boost::filesystem::path main_src{model_dir / (static_or_dynamic + ".c")},
|
||||||
|
mex_src{model_dir / (static_or_dynamic + "_mex.c")};
|
||||||
|
|
||||||
|
boost::filesystem::path mex_dir{"+" + basename};
|
||||||
|
boost::filesystem::path binary{mex_dir / (static_or_dynamic + "." + mexext)};
|
||||||
|
|
||||||
|
ostringstream cmd;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
/* On Windows, system() hands the command over to "cmd.exe /C". We need to
|
||||||
|
enclose the whole command line within double quotes if we want the inner
|
||||||
|
quotes to be correctly handled. See "cmd /?" for more details. */
|
||||||
|
cmd << '"';
|
||||||
|
#endif
|
||||||
|
cmd << compiler << " " << opt_flags << " " << flags.str() << " " << main_src << " " << mex_src << " -o " << binary << " " << libs;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
cmd << '"';
|
||||||
|
#endif
|
||||||
|
|
||||||
|
cout << "Compiling " << static_or_dynamic << " MEX..." << endl << cmd.str() << endl;
|
||||||
|
|
||||||
|
if (system(cmd.str().c_str()))
|
||||||
|
{
|
||||||
|
cerr << "Compilation failed" << endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -29,6 +29,8 @@ using namespace std;
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
#include "DataTree.hh"
|
#include "DataTree.hh"
|
||||||
#include "ExtendedPreprocessorTypes.hh"
|
#include "ExtendedPreprocessorTypes.hh"
|
||||||
|
|
||||||
|
@ -338,6 +340,10 @@ private:
|
||||||
/*! Copies all the structures that contain ExprNode*, by the converting the
|
/*! Copies all the structures that contain ExprNode*, by the converting the
|
||||||
pointers into their equivalent in the new tree */
|
pointers into their equivalent in the new tree */
|
||||||
void copyHelper(const ModelTree &m);
|
void copyHelper(const ModelTree &m);
|
||||||
|
//! Returns the name of the MATLAB architecture given the extension used for MEX files
|
||||||
|
static string matlab_arch(const string &mexext);
|
||||||
|
//! Compiles the MEX file
|
||||||
|
static void compileDll(const string &basename, const string &static_or_dynamic, const string &mexext, const boost::filesystem::path &matlabroot, const boost::filesystem::path &dynareroot);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ModelTree(SymbolTable &symbol_table_arg,
|
ModelTree(SymbolTable &symbol_table_arg,
|
||||||
|
|
|
@ -25,8 +25,6 @@
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
|
||||||
|
|
||||||
#include "StaticModel.hh"
|
#include "StaticModel.hh"
|
||||||
#include "DynamicModel.hh"
|
#include "DynamicModel.hh"
|
||||||
|
|
||||||
|
@ -2061,11 +2059,6 @@ StaticModel::writeStaticCFile(const string &basename) 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
|
||||||
#if defined(_WIN32) || defined(__CYGWIN32__)
|
|
||||||
<< "#ifdef _MSC_VER" << endl
|
|
||||||
<< "#define _USE_MATH_DEFINES" << endl
|
|
||||||
<< "#endif" << endl
|
|
||||||
#endif
|
|
||||||
<< "#include <math.h>" << endl;
|
<< "#include <math.h>" << endl;
|
||||||
|
|
||||||
if (external_functions_table.get_total_number_of_unique_model_block_external_functions())
|
if (external_functions_table.get_total_number_of_unique_model_block_external_functions())
|
||||||
|
@ -2079,7 +2072,6 @@ StaticModel::writeStaticCFile(const string &basename) const
|
||||||
|
|
||||||
// Write function definition if BinaryOpcode::powerDeriv is used
|
// Write function definition if BinaryOpcode::powerDeriv is used
|
||||||
writePowerDerivCHeader(output);
|
writePowerDerivCHeader(output);
|
||||||
writeNormcdfCHeader(output);
|
|
||||||
|
|
||||||
output << endl;
|
output << endl;
|
||||||
|
|
||||||
|
@ -2089,7 +2081,6 @@ StaticModel::writeStaticCFile(const string &basename) const
|
||||||
output << endl;
|
output << endl;
|
||||||
|
|
||||||
writePowerDeriv(output);
|
writePowerDeriv(output);
|
||||||
writeNormcdf(output);
|
|
||||||
output.close();
|
output.close();
|
||||||
|
|
||||||
output.open(filename_mex, ios::out | ios::binary);
|
output.open(filename_mex, ios::out | ios::binary);
|
||||||
|
@ -2174,7 +2165,7 @@ StaticModel::writeStaticJuliaFile(const string &basename) const
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
StaticModel::writeStaticFile(const string &basename, bool block, bool bytecode, bool use_dll, bool julia) const
|
StaticModel::writeStaticFile(const string &basename, bool block, bool bytecode, bool use_dll, const string &mexext, const boost::filesystem::path &matlabroot, const boost::filesystem::path &dynareroot, bool julia) const
|
||||||
{
|
{
|
||||||
if (block && bytecode)
|
if (block && bytecode)
|
||||||
writeModelEquationsCode_Block(basename, map_idx, map_idx2);
|
writeModelEquationsCode_Block(basename, map_idx, map_idx2);
|
||||||
|
@ -2186,7 +2177,10 @@ StaticModel::writeStaticFile(const string &basename, bool block, bool bytecode,
|
||||||
writeStaticBlockMFSFile(basename);
|
writeStaticBlockMFSFile(basename);
|
||||||
}
|
}
|
||||||
else if (use_dll)
|
else if (use_dll)
|
||||||
|
{
|
||||||
writeStaticCFile(basename);
|
writeStaticCFile(basename);
|
||||||
|
compileDll(basename, "static", mexext, matlabroot, dynareroot);
|
||||||
|
}
|
||||||
else if (julia)
|
else if (julia)
|
||||||
writeStaticJuliaFile(basename);
|
writeStaticJuliaFile(basename);
|
||||||
else
|
else
|
||||||
|
|
|
@ -24,6 +24,8 @@ using namespace std;
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
#include "ModelTree.hh"
|
#include "ModelTree.hh"
|
||||||
|
|
||||||
class DynamicModel;
|
class DynamicModel;
|
||||||
|
@ -201,7 +203,7 @@ public:
|
||||||
int &u_count_int, bool &file_open) const;
|
int &u_count_int, bool &file_open) const;
|
||||||
|
|
||||||
//! Writes static model file
|
//! Writes static model file
|
||||||
void writeStaticFile(const string &basename, bool block, bool bytecode, bool use_dll, bool julia) const;
|
void writeStaticFile(const string &basename, bool block, bool bytecode, bool use_dll, const string &mexext, const boost::filesystem::path &matlabroot, const boost::filesystem::path &dynareroot, bool julia) const;
|
||||||
|
|
||||||
//! Write JSON Output (used by PlannerObjectiveStatement)
|
//! Write JSON Output (used by PlannerObjectiveStatement)
|
||||||
void writeJsonOutput(ostream &output) const;
|
void writeJsonOutput(ostream &output) const;
|
||||||
|
|
Loading…
Reference in New Issue