extended-preprocessor: adding line options output= and cuda; starting

to change ModFile::c_driver mechanism
time-shift
Michel Juillard 2013-08-13 21:16:02 +02:00
parent 5c1488fe23
commit 2885a00c8f
7 changed files with 367 additions and 6 deletions

View File

@ -29,6 +29,7 @@
#include "macro/MacroDriver.hh" #include "macro/MacroDriver.hh"
#include <unistd.h> #include <unistd.h>
#include "DynareOutput.hh"
/* Prototype for second part of main function /* Prototype for second part of main function
Splitting main() in two parts was necessary because ParsingDriver.h and MacroDriver.h can't be Splitting main() in two parts was necessary because ParsingDriver.h and MacroDriver.h can't be
@ -36,7 +37,7 @@
*/ */
void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tmp_terms, bool no_log, bool no_warn, bool warn_uninit, bool console, bool nograph, bool nointeractive, void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tmp_terms, bool no_log, bool no_warn, bool warn_uninit, bool console, bool nograph, bool nointeractive,
bool parallel, const string &parallel_config_file, const string &cluster_name, bool parallel_slave_open_mode, bool parallel, const string &parallel_config_file, const string &cluster_name, bool parallel_slave_open_mode,
bool parallel_test, bool nostrict bool parallel_test, bool nostrict, OutputType output_mode, bool cuda
#if defined(_WIN32) || defined(__CYGWIN32__) #if defined(_WIN32) || defined(__CYGWIN32__)
, bool cygwin, bool msvc , bool cygwin, bool msvc
#endif #endif
@ -47,7 +48,7 @@ usage()
{ {
cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [nolog] [warn_uninit]" cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [nolog] [warn_uninit]"
<< " [console] [nograph] [nointeractive] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test] " << " [console] [nograph] [nointeractive] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test] "
<< " [-D<variable>[=<value>]] [nostrict]" << " [-D<variable>[=<value>]] [nostrict] [-double=dynamic|first|second|third] [cuda]"
#if defined(_WIN32) || defined(__CYGWIN32__) #if defined(_WIN32) || defined(__CYGWIN32__)
<< " [cygwin] [msvc]" << " [cygwin] [msvc]"
#endif #endif
@ -95,6 +96,8 @@ main(int argc, char **argv)
bool parallel_test = false; bool parallel_test = false;
bool nostrict = false; bool nostrict = false;
map<string, string> defines; map<string, string> defines;
OutputType output_mode = none;
bool cuda = false;
// Parse options // Parse options
for (int arg = 2; arg < argc; arg++) for (int arg = 2; arg < argc; arg++)
@ -189,6 +192,29 @@ main(int argc, char **argv)
defines[key] = "1"; defines[key] = "1";
} }
} }
else if (strlen(argv[arg]) >= 6 && !strncmp(argv[arg], "output", 6))
{
if (strlen(argv[arg]) <= 7 || argv[arg][6] != '=')
{
cerr << "Incorrect syntax for ouput option" << endl;
usage();
}
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))
output_mode = first;
else if (strlen(argv[arg]) == 13 && !strncmp(argv[arg] + 7, "second", 6))
output_mode = second;
else if (strlen(argv[arg]) == 12 && !strncmp(argv[arg] + 7, "third", 5))
output_mode = third;
else
{
cerr << "Incorrect syntax for ouput option" << endl;
usage();
}
}
else if (!strcmp(argv[arg], "cuda"))
cuda = true;
else else
{ {
cerr << "Unknown option: " << argv[arg] << endl; cerr << "Unknown option: " << argv[arg] << endl;
@ -229,7 +255,7 @@ main(int argc, char **argv)
// Do the rest // Do the rest
main2(macro_output, basename, debug, clear_all, no_tmp_terms, no_log, no_warn, warn_uninit, console, nograph, nointeractive, main2(macro_output, basename, debug, clear_all, no_tmp_terms, no_log, no_warn, warn_uninit, console, nograph, nointeractive,
parallel, parallel_config_file, cluster_name, parallel_slave_open_mode, parallel_test, nostrict parallel, parallel_config_file, cluster_name, parallel_slave_open_mode, parallel_test, nostrict, output_mode, cuda
#if defined(_WIN32) || defined(__CYGWIN32__) #if defined(_WIN32) || defined(__CYGWIN32__)
, cygwin, msvc , cygwin, msvc
#endif #endif

View File

@ -22,11 +22,12 @@
#include "ParsingDriver.hh" #include "ParsingDriver.hh"
#include "ModFile.hh" #include "ModFile.hh"
#include "ConfigFile.hh" #include "ConfigFile.hh"
#include "DynareOutput.hh"
void void
main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tmp_terms, bool no_log, bool no_warn, bool warn_uninit, bool console, bool nograph, bool nointeractive, main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tmp_terms, bool no_log, bool no_warn, bool warn_uninit, bool console, bool nograph, bool nointeractive,
bool parallel, const string &parallel_config_file, const string &cluster_name, bool parallel_slave_open_mode, bool parallel, const string &parallel_config_file, const string &cluster_name, bool parallel_slave_open_mode,
bool parallel_test, bool nostrict bool parallel_test, bool nostrict, OutputType output_mode, bool cuda
#if defined(_WIN32) || defined(__CYGWIN32__) #if defined(_WIN32) || defined(__CYGWIN32__)
, bool cygwin, bool msvc , bool cygwin, bool msvc
#endif #endif
@ -56,8 +57,8 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tm
mod_file->computingPass(no_tmp_terms); mod_file->computingPass(no_tmp_terms);
// Write outputs // Write outputs
if (mod_file->c_driver) if (output_mode != none)
mod_file->writeCOutputFiles(basename); mod_file->writeExternalFiles(basename, output_mode, cuda);
else else
mod_file->writeOutputFiles(basename, clear_all, no_log, no_warn, console, nograph, nointeractive, config_file mod_file->writeOutputFiles(basename, clear_all, no_log, no_warn, console, nograph, nointeractive, config_file
#if defined(_WIN32) || defined(__CYGWIN32__) #if defined(_WIN32) || defined(__CYGWIN32__)

View File

@ -0,0 +1,12 @@
#ifndef _DYNARE_OUTPUT_HH
#define _DYNARE_OUTPUT_HH
enum OutputType
{
none, // outputs files for Matlab/Octave processing
dynamic, // outputs <fname>_dynamic.cc and related files
first, // outputs <fname>_first_derivatives and related files
second, // outputs <fname>_first_derivatives, <fname>_second_derivatives.cc and related files
third, // outputs <fname>_first_derivatives, <fname>_second_derivatives.cc, <fname>_third_derivatives.cc and related files
};
#endif

View File

@ -0,0 +1,259 @@
/*
* Copyright (C) 2006-2013 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
*/
#input "ExternalFiles.hh"
ExternalFiles::writeModelCCconst string &basename, bool cuda)
{
ofstream mOutputFile;
if (basename.size())
{
string fname(basename);
fname += ".cc";
cOutputFile.open(fname.c_str(), ios::out | ios::binary);
if (!cOutputFile.is_open())
{
cerr << "ERROR: Can't open file " << fname
<< " for writing" << endl;
exit(EXIT_FAILURE);
}
}
else
{
cerr << "ERROR: Missing file name" << endl;
exit(EXIT_FAILURE);
}
cOutputFile << "%" << endl
<< "% Status : dynare_model class initializing function " << endl
<< "%" << endl
<< "% Warning : this file is generated automatically by Dynare" << endl
<< "% from model file " << baseline << "(.mod)" << endl << endl;
cOutputFile << "#include \"dynare_model.hh\"" << endl << endl;
cOutputFile << "dynare_model::dynare_model(void)" << endl
<< "{" << endl
<< " model_name = \""<< basename << "\";" << endl;
symbol_table.writeOutputCC(hOutputFile);
// Initialize M_.Sigma_e and M_.H
mOutputFile << "M_.Sigma_e = zeros(" << symbol_table.exo_nbr() << ", "
<< symbol_table.exo_nbr() << ");" << endl;
if (mod_file_struct.calibrated_measurement_errors)
mOutputFile << "M_.H = zeros(" << symbol_table.observedVariablesNbr() << ", "
<< symbol_table.observedVariablesNbr() << ");" << endl;
else
mOutputFile << "M_.H = 0;" << endl;
if (linear == 1)
mOutputFile << "options_.linear = 1;" << endl;
mOutputFile << "options_.block=" << block << ";" << endl
<< "options_.bytecode=" << byte_code << ";" << endl
<< "options_.use_dll=" << use_dll << ";" << endl;
if (parallel_local_files.size() > 0)
{
mOutputFile << "options_.parallel_info.local_files = {" << endl;
for (size_t i = 0; i < parallel_local_files.size(); i++)
{
size_t j = parallel_local_files[i].find_last_of("/\\");
if (j == string::npos)
mOutputFile << "'', '" << parallel_local_files[i] << "';" << endl;
else
mOutputFile << "'" << parallel_local_files[i].substr(0, j+1) << "', '"
<< parallel_local_files[i].substr(j+1, string::npos) << "';" << endl;
}
mOutputFile << "};" << endl;
}
config_file.writeCluster(mOutputFile);
if (byte_code)
mOutputFile << "if exist('bytecode') ~= 3" << endl
<< " error('DYNARE: Can''t find bytecode DLL. Please compile it or remove the ''bytecode'' option.')" << endl
<< "end" << endl;
// Erase possible remnants of previous runs
string dynfile = basename + "_dynamic.m";
unlink(dynfile.c_str());
string statfile = basename + "_static.m";
unlink(statfile.c_str());
string steadystatefile = basename + "_steadystate2.m";
unlink(steadystatefile.c_str());
if (!use_dll)
{
mOutputFile << "erase_compiled_function('" + basename + "_static');" << endl;
mOutputFile << "erase_compiled_function('" + basename + "_dynamic');" << endl;
}
#if defined(_WIN32) || defined(__CYGWIN32__)
// If using USE_DLL with MSVC, check that the user didn't use a function not supported by MSVC (because MSVC doesn't comply with C99 standard)
if (use_dll && msvc)
{
if (dynamic_model.isUnaryOpUsed(oAcosh))
{
cerr << "ERROR: acosh() function is not supported with USE_DLL option and MSVC compiler; use Cygwin compiler instead." << endl;
exit(EXIT_FAILURE);
}
if (dynamic_model.isUnaryOpUsed(oAsinh))
{
cerr << "ERROR: asinh() function is not supported with USE_DLL option and MSVC compiler; use Cygwin compiler instead." << endl;
exit(EXIT_FAILURE);
}
if (dynamic_model.isUnaryOpUsed(oAtanh))
{
cerr << "ERROR: atanh() function is not supported with USE_DLL option and MSVC compiler; use Cygwin compiler instead." << endl;
exit(EXIT_FAILURE);
}
if (dynamic_model.isTrinaryOpUsed(oNormcdf))
{
cerr << "ERROR: normcdf() function is not supported with USE_DLL option and MSVC compiler; use Cygwin compiler instead." << endl;
exit(EXIT_FAILURE);
}
}
#endif
// Compile the dynamic MEX file for use_dll option
if (use_dll)
{
mOutputFile << "if ~exist('OCTAVE_VERSION')" << endl;
// Some mex commands are enclosed in an eval(), because otherwise it will make Octave fail
#if defined(_WIN32) || defined(__CYGWIN32__)
if (msvc)
// MATLAB/Windows + Microsoft Visual C++
mOutputFile << " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Dynamic\" " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl
<< " eval('mex -O LINKFLAGS=\"$LINKFLAGS /export:Static\" " << basename << "_static.c "<< basename << "_static_mex.c')" << endl;
else if (cygwin)
// MATLAB/Windows + Cygwin g++
mOutputFile << " eval('mex -O PRELINK_CMDS1=\"echo EXPORTS > mex.def & echo mexFunction >> mex.def & echo Dynamic >> mex.def\" " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl
<< " eval('mex -O PRELINK_CMDS1=\"echo EXPORTS > mex.def & echo mexFunction >> mex.def & echo Static >> mex.def\" " << basename << "_static.c "<< basename << "_static_mex.c')" << endl;
else
mOutputFile << " error('When using the USE_DLL option, you must give either ''cygwin'' or ''msvc'' option to the ''dynare'' command')" << endl;
#else
# ifdef __linux__
// MATLAB/Linux
mOutputFile << " eval('mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' " << basename << "_dynamic.c " << basename << "_dynamic_mex.c')" << endl
<< " eval('mex -O LDFLAGS=''-pthread -shared -Wl,--no-undefined'' " << basename << "_static.c "<< basename << "_static_mex.c')" << endl;
# else // 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 " << 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
mOutputFile << "else" << endl // Octave
<< " mex " << basename << "_dynamic.c " << basename << "_dynamic_mex.c" << endl
<< " mex " << basename << "_static.c " << basename << "_static_mex.c" << endl
<< "end" << endl;
}
// Add path for block option with M-files
if (block && !byte_code)
mOutputFile << "addpath " << basename << ";" << endl;
if (mod_file_struct.ramsey_policy_present)
mOutputFile << "M_.orig_eq_nbr = " << ramsey_policy_orig_eqn_nbr << ";" << endl;
if (dynamic_model.equation_number() > 0)
{
dynamic_model.writeOutput(mOutputFile, basename, block, byte_code, use_dll, mod_file_struct.order_option, mod_file_struct.estimation_present);
if (!no_static)
static_model.writeOutput(mOutputFile, block);
}
// Print statements
for (vector<Statement *>::const_iterator it = statements.begin();
it != statements.end(); it++)
{
(*it)->writeOutput(mOutputFile, basename);
/* Special treatment for initval block: insert initial values for the
auxiliary variables and initialize exo det */
InitValStatement *ivs = dynamic_cast<InitValStatement *>(*it);
if (ivs != NULL)
{
static_model.writeAuxVarInitval(mOutputFile, oMatlabOutsideModel);
ivs->writeOutputPostInit(mOutputFile);
}
// Special treatment for endval block: insert initial values for the auxiliary variables
EndValStatement *evs = dynamic_cast<EndValStatement *>(*it);
if (evs != NULL)
static_model.writeAuxVarInitval(mOutputFile, oMatlabOutsideModel);
// Special treatment for load params and steady state statement: insert initial values for the auxiliary variables
LoadParamsAndSteadyStateStatement *lpass = dynamic_cast<LoadParamsAndSteadyStateStatement *>(*it);
if (lpass && !no_static)
static_model.writeAuxVarInitval(mOutputFile, oMatlabOutsideModel);
}
// Remove path for block option with M-files
if (block && !byte_code)
mOutputFile << "rmpath " << basename << ";" << endl;
mOutputFile << "save('" << basename << "_results.mat', 'oo_', 'M_', 'options_');" << endl;
config_file.writeEndParallel(mOutputFile);
mOutputFile << endl << endl
<< "disp(['Total computing time : ' dynsec2hms(toc) ]);" << endl;
if (!no_warn)
{
if (warnings.countWarnings() > 0)
mOutputFile << "disp('Note: " << warnings.countWarnings() << " warning(s) encountered in the preprocessor')" << endl;
mOutputFile << "if ~isempty(lastwarn)" << endl
<< " disp('Note: warning(s) encountered in MATLAB/Octave code')" << endl
<< "end" << endl;
}
if (!no_log)
mOutputFile << "diary off" << endl;
mOutputFile.close();
// Create static and dynamic files
if (dynamic_model.equation_number() > 0)
{
if (!no_static)
{
static_model.writeStaticFile(basename, block, byte_code, use_dll);
static_model.writeParamsDerivativesFile(basename);
}
dynamic_model.writeDynamicFile(basename, block, byte_code, use_dll, mod_file_struct.order_option);
dynamic_model.writeParamsDerivativesFile(basename);
}
// Create steady state file
steady_state_model.writeSteadyStateFile(basename, mod_file_struct.ramsey_policy_present);
cout << "done" << endl;
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (C) 2006-2013 Dynare Team
*
* This file is part of Dynare.
*
* Dynare is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Dynare is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Dynare. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _EXTERNAL_FILES_HH
#define _EXTERNAL_FILES_HH
using namespace std;
#include <ostream>
#include "ModFile.hh"
class ExternalFiles
{
public:
void writeHeaders(const string &basename, bool cuda);
};
#endif

View File

@ -913,3 +913,26 @@ ModFile::writeCOutputFiles(const string &basename) const
<< "ls preprocessorOutput.cc" << endl << endl; << "ls preprocessorOutput.cc" << endl << endl;
mOutputFile.close(); mOutputFile.close();
} }
void
ModFile::writeExternalFiles(const string &basename, OutputType output, bool cuda) const
{
ExternalFiles::writeHeaders(basename, cuda);
ExternalFiles::writeModelCC(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);
if (output == second)
dynamic_model.writeSecondDerivatives(basename, cuda);
else if (output == third)
{
dynamic_model.writeSecondDerivatives(basename, cuda);
dynamic_model.writeThirdDerivatives(basename, cuda);
}
}

View File

@ -35,6 +35,8 @@ using namespace std;
#include "ExternalFunctionsTable.hh" #include "ExternalFunctionsTable.hh"
#include "ConfigFile.hh" #include "ConfigFile.hh"
#include "WarningConsolidation.hh" #include "WarningConsolidation.hh"
#include "DynareOutput.hh"
#include "ExternalFiles.hh"
//! The abstract representation of a "mod" file //! The abstract representation of a "mod" file
class ModFile class ModFile
@ -142,6 +144,7 @@ public:
) const; ) const;
//! Writes C output files only => No further Matlab processing //! Writes C output files only => No further Matlab processing
void writeCOutputFiles(const string &basename) const; void writeCOutputFiles(const string &basename) const;
void writeExternalFiles(const string &basename, OutputType output, bool cuda) const;
}; };
#endif // ! MOD_FILE_HH #endif // ! MOD_FILE_HH