Dynare parallel: preprocessor implementation

time-shift
Houtan Bastani 2010-10-25 18:20:58 +02:00
parent 9ebcecb266
commit c28d15d78a
7 changed files with 638 additions and 10 deletions

482
preprocessor/ConfigFile.cc Normal file
View File

@ -0,0 +1,482 @@
/*
* Copyright (C) 2010 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/>.
*/
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
#include "ConfigFile.hh"
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/lexical_cast.hpp>
using namespace std;
SlaveNode::SlaveNode(string &computerName_arg, int minCpuNbr_arg, int maxCpuNbr_arg, string &userName_arg,
string &password_arg, string &remoteDrive_arg, string &remoteDirectory_arg,
string &dynarePath_arg, string &matlabOctavePath_arg, bool singleCompThread_arg) :
computerName(computerName_arg), minCpuNbr(minCpuNbr_arg), maxCpuNbr(maxCpuNbr_arg), userName(userName_arg),
password(password_arg), remoteDrive(remoteDrive_arg), remoteDirectory(remoteDirectory_arg), dynarePath(dynarePath_arg),
matlabOctavePath(matlabOctavePath_arg), singleCompThread(singleCompThread_arg)
{
if (computerName.empty())
{
cerr << "ERROR: The node must have a ComputerName." << endl;
exit(EXIT_FAILURE);
}
}
Cluster::Cluster(vector<string> member_nodes_arg) : member_nodes(member_nodes_arg)
{
if (member_nodes.empty())
{
cerr << "ERROR: The cluster must have at least one member node." << endl;
exit(EXIT_FAILURE);
}
}
ConfigFile::ConfigFile(bool parallel_arg, bool parallel_test_arg,
bool parallel_slave_open_mode_arg, const string &cluster_name_arg) :
parallel(parallel_arg), parallel_test(parallel_test_arg),
parallel_slave_open_mode(parallel_slave_open_mode_arg), cluster_name(cluster_name_arg)
{
}
ConfigFile::~ConfigFile()
{
}
void
ConfigFile::getConfigFileInfo(const string &parallel_config_file)
{
if (!parallel && !parallel_test)
return;
ifstream *configFile;
if (parallel_config_file.empty())
{
// Test OS and try to open default file
#if defined(_WIN32) || defined(__CYGWIN32__)
string defaultConfigFile (getenv("APPDATA"));
if (&defaultConfigFile==NULL)
{
cerr << "ERROR: APPDATA environment variable not found." << endl;
exit(EXIT_FAILURE);
}
defaultConfigFile += "\\dynare.ini";
#else
string defaultConfigFile (getenv("HOME"));
if (&defaultConfigFile==NULL)
{
cerr << "ERROR: HOME environment variable not found." << endl;
exit(EXIT_FAILURE);
}
defaultConfigFile += "/.dynare";
#endif
configFile = new ifstream(defaultConfigFile.c_str(), fstream::in);
if (!configFile->is_open())
{
cerr << "ERROR: Could not open the default config file" << endl;
exit(EXIT_FAILURE);
}
}
else
{
configFile = new ifstream(parallel_config_file.c_str(), fstream::in);
if (!configFile->is_open())
{
cerr << "ERROR: Couldn't open file " << parallel_config_file << endl;;
exit(EXIT_FAILURE);
}
}
string name, computerName, userName, password, remoteDrive,
remoteDirectory, dynarePath, matlabOctavePath;
int minCpuNbr = 0, maxCpuNbr = 0;
bool singleCompThread = true;
vector<string> member_nodes;
bool inNode = false;
bool inCluster = false;
while (configFile->good())
{
string line;
getline(*configFile, line);
boost::trim(line);
if (line.empty())
continue;
if (!line.compare("[node]") || !line.compare("[cluster]"))
{
addConfFileElement(inNode, inCluster, member_nodes, name,
computerName, minCpuNbr, maxCpuNbr, userName,
password, remoteDrive, remoteDirectory,
dynarePath, matlabOctavePath, singleCompThread);
//! Reset communication vars / option defaults
if (!line.compare("[node]"))
{
inNode = true;
inCluster = false;
}
else
{
inNode = false;
inCluster = true;
}
name = userName = computerName = password = remoteDrive =
remoteDirectory = dynarePath = matlabOctavePath = "";
minCpuNbr = maxCpuNbr = 0;
singleCompThread = true;
member_nodes.clear();
}
else
{
vector<string> tokenizedLine;
boost::split(tokenizedLine, line, boost::is_any_of("="));
if (tokenizedLine.size() != 2)
{
cerr << "ERROR (in config file): Options should be formatted as 'option = value'." << endl;
exit(EXIT_FAILURE);
}
boost::trim(tokenizedLine.front());
boost::trim(tokenizedLine.back());
if (!tokenizedLine.front().compare("Name"))
name = tokenizedLine.back();
else if (!tokenizedLine.front().compare("CPUnbr"))
{
vector<string> tokenizedCpuNbr;
boost::split(tokenizedCpuNbr, tokenizedLine.back(), boost::is_any_of(":"));
try
{
if (tokenizedCpuNbr.size() == 1)
{
minCpuNbr = 1;
maxCpuNbr = boost::lexical_cast< int >(tokenizedCpuNbr.front());
}
else if (tokenizedCpuNbr.size() == 2 &&
tokenizedCpuNbr[0].at(0) == '[' &&
tokenizedCpuNbr[1].at(tokenizedCpuNbr[1].size()-1) == ']')
{
tokenizedCpuNbr[0].erase(0,1);
tokenizedCpuNbr[1].erase(tokenizedCpuNbr[1].size()-1,1);
minCpuNbr = boost::lexical_cast< int >(tokenizedCpuNbr[0]);
maxCpuNbr = boost::lexical_cast< int >(tokenizedCpuNbr[1]);
}
}
catch( const boost::bad_lexical_cast & )
{
cerr << "ERROR: Could not convert value to integer for CPUnbr." << endl;
exit(EXIT_FAILURE);
}
if (minCpuNbr <= 0 || maxCpuNbr <= 0)
{
cerr << "ERROR: Syntax for the CPUnbr option is as follows:" << endl
<< " 1) CPUnbr = <int>" << endl
<< " or 2) CPUnbr = [<int>:<int>]" << endl
<< " where <int> is an Integer > 0." << endl;
exit(EXIT_FAILURE);
}
minCpuNbr--;
maxCpuNbr--;
if (minCpuNbr > maxCpuNbr)
{
int tmp = maxCpuNbr;
maxCpuNbr = minCpuNbr;
minCpuNbr = tmp;
}
}
else if (!tokenizedLine.front().compare("ComputerName"))
computerName = tokenizedLine.back();
else if (!tokenizedLine.front().compare("UserName"))
userName = tokenizedLine.back();
else if (!tokenizedLine.front().compare("Password"))
password = tokenizedLine.back();
else if (!tokenizedLine.front().compare("RemoteDrive"))
remoteDrive = tokenizedLine.back();
else if (!tokenizedLine.front().compare("RemoteDirectory"))
remoteDirectory = tokenizedLine.back();
else if (!tokenizedLine.front().compare("DynarePath"))
dynarePath = tokenizedLine.back();
else if (!tokenizedLine.front().compare("MatlabOctavePath"))
matlabOctavePath = tokenizedLine.back();
else if (!tokenizedLine.front().compare("SingleCompThread"))
if (tokenizedLine.back().compare("true"))
singleCompThread = true;
else if (tokenizedLine.back().compare("false"))
singleCompThread = false;
else
{
cerr << "ERROR (in config file): The value passed to SingleCompThread may only be 'true' or 'false'." << endl;
exit(EXIT_FAILURE);
}
else if (!tokenizedLine.front().compare("Members"))
{
vector<string> tmp_member_nodes;
boost::split(tmp_member_nodes, tokenizedLine.back(), boost::is_any_of(";, "));
for ( vector<string>::iterator it = tmp_member_nodes.begin();
it < tmp_member_nodes.end(); it++ )
{
boost::trim(*it);
if (!it->empty())
member_nodes.push_back(*it);
}
}
else
{
cerr << "ERROR (in config file): Option " << tokenizedLine.front() << " is invalid." << endl;
exit(EXIT_FAILURE);
}
}
}
addConfFileElement(inNode, inCluster, member_nodes, name,
computerName, minCpuNbr, maxCpuNbr, userName,
password, remoteDrive, remoteDirectory,
dynarePath, matlabOctavePath, singleCompThread);
configFile->close();
delete configFile;
}
void
ConfigFile::addConfFileElement(bool inNode, bool inCluster, vector<string> member_nodes, string &name,
string &computerName, int minCpuNbr, int maxCpuNbr, string &userName,
string &password, string &remoteDrive, string &remoteDirectory,
string &dynarePath, string &matlabOctavePath, bool singleCompThread)
{
//! ADD NODE
if (inNode)
if (!member_nodes.empty())
{
cerr << "Invalid option passed to [node]." << endl;
exit(EXIT_FAILURE);
}
else
if (name.empty() || slave_nodes.find(name) != slave_nodes.end())
{
cerr << "ERROR: Every node must be assigned a unique name." << endl;
exit(EXIT_FAILURE);
}
else
slave_nodes[name] = new SlaveNode(computerName, minCpuNbr, maxCpuNbr, userName,
password, remoteDrive, remoteDirectory, dynarePath,
matlabOctavePath, singleCompThread);
//! ADD CLUSTER
else if (inCluster)
if ( minCpuNbr > 0 || maxCpuNbr > 0 || !userName.empty() ||
!password.empty() || !remoteDrive.empty() || !remoteDirectory.empty() ||
!dynarePath.empty() || !matlabOctavePath.empty())
{
cerr << "Invalid option passed to [cluster]." << endl;
exit(EXIT_FAILURE);
}
else
if (name.empty() || clusters.find(name) != clusters.end())
{
cerr << "ERROR: The cluster must be assigned a unique name." << endl;
exit(EXIT_FAILURE);
}
else
{
if (clusters.empty())
firstClusterName = name;
clusters[name] = new Cluster(member_nodes);
}
}
void
ConfigFile::checkPass() const
{
if (!parallel && !parallel_test)
return;
//! Check Slave Nodes
if (slave_nodes.empty())
{
cerr << "ERROR: At least one node must be defined in the config file." << endl;
exit(EXIT_FAILURE);
}
for (map<string, SlaveNode *>::const_iterator it = slave_nodes.begin();
it != slave_nodes.end(); it++)
{
#if !defined(_WIN32) && !defined(__CYGWIN32__)
//For Linux/Mac, check that cpuNbr starts at 0
if (it->second->minCpuNbr != 0)
cout << "WARNING: On Unix-based operating systems, you cannot specify the CPU that is used "
<< "in parallel processing. This will be adjusted for you such that the same number of CPUs "
<< "are used." << endl;
#endif
if (!it->second->computerName.compare("localhost")) // We are working locally
{
if (!it->second->remoteDrive.empty())
{
cerr << "ERROR (node " << it->first << "): the RemoteDrive option may not be passed for a local node." << endl;
exit(EXIT_FAILURE);
}
if (!it->second->remoteDirectory.empty())
{
cerr << "ERROR (node " << it->first << "): the RemoteDirectory option may not be passed for a local node." << endl;
exit(EXIT_FAILURE);
}
}
else
{
if (it->second->userName.empty())
{
cerr << "ERROR (node " << it->first << "): the UserName option must be passed for every remote node." << endl;
exit(EXIT_FAILURE);
}
#if defined(_WIN32) || defined(__CYGWIN32__)
if (it->second->userName.empty() || it->second->password.empty())
{
cerr << "ERROR (node " << it->first << "): the Password option must be passed under Windows for every remote node." << endl;
exit(EXIT_FAILURE);
}
if (it->second->remoteDrive.empty())
{
cerr << "ERROR (node " << it->first << "): the RemoteDrive option must be passed under Windows for every remote node." << endl;
exit(EXIT_FAILURE);
}
#endif
if (it->second->remoteDirectory.empty())
{
cerr << "ERROR (node " << it->first << "): the RemoteDirectory must be specified for every remote node." << endl;
exit(EXIT_FAILURE);
}
}
}
//! Check Clusters
if (clusters.empty())
{
cerr << "ERROR: At least one cluster must be defined in the config file." << endl;
exit(EXIT_FAILURE);
}
if (!cluster_name.empty() && clusters.find(cluster_name) == clusters.end())
{
cerr << "ERROR: Cluster Name " << cluster_name << " was not found in the config file." << endl;
exit(EXIT_FAILURE);
}
for (map<string, Cluster *>::const_iterator it = clusters.begin();
it != clusters.end(); it++)
for (vector<string>::const_iterator itmn = it->second->member_nodes.begin();
itmn < it->second->member_nodes.end(); itmn++)
if (slave_nodes.find(*itmn) == slave_nodes.end())
{
cerr << "Error: node " << *itmn << " specified in cluster " << it->first << " was not found" << endl;
exit(EXIT_FAILURE);
}
}
void
ConfigFile::transformPass()
{
if (!parallel && !parallel_test)
return;
#if !defined(_WIN32) && !defined(__CYGWIN32__)
//For Linux/Mac, check that cpuNbr starts at 0
for (map<string, SlaveNode *>::const_iterator it = slave_nodes.begin();
it != slave_nodes.end(); it++)
if (it->second->minCpuNbr != 0)
{
it->second->maxCpuNbr = it->second->maxCpuNbr - it->second->minCpuNbr;
it->second->minCpuNbr = 0;
}
#endif
}
void
ConfigFile::writeCluster(ostream &output) const
{
if (!parallel && !parallel_test)
return;
map<string, Cluster *>::const_iterator cluster_it ;
if (cluster_name.empty())
cluster_it = clusters.find(firstClusterName);
else
cluster_it = clusters.find(cluster_name);
int i = 1;
for (map<string, SlaveNode *>::const_iterator it = slave_nodes.begin();
it != slave_nodes.end(); it++)
{
bool slave_node_in_member_nodes = false;
for (vector<string>::const_iterator itmn = cluster_it->second->member_nodes.begin();
itmn < cluster_it->second->member_nodes.end(); itmn++)
if (!it->first.compare(*itmn))
slave_node_in_member_nodes = true;
if (!slave_node_in_member_nodes)
continue;
output << "options_.parallel";
if (i > 1)
output << "(" << i << ")";
i++;
output << " = struct('Local', ";
if (it->second->computerName.compare("localhost"))
output << "0, ";
else
output << "1, ";
output << "'ComputerName', '" << it->second->computerName << "', "
<< "'CPUnbr', [" << it->second->minCpuNbr << ":" << it->second->maxCpuNbr << "], "
<< "'UserName', '" << it->second->userName << "', "
<< "'Password', '" << it->second->password << "', "
<< "'RemoteDrive', '" << it->second->remoteDrive << "', "
<< "'RemoteDirectory', '" << it->second->remoteDirectory << "', "
<< "'DynarePath', '" << it->second->dynarePath << "', "
<< "'MatlabOctavePath', '" << it->second->matlabOctavePath << "', ";
if (it->second->singleCompThread)
output << "'SingleCompThread', 'true');" << endl;
else
output << "'SingleCompThread', 'false');" << endl;
}
if (parallel_slave_open_mode)
output << "options_.parallel_info.leaveSlaveOpen = 1;" << endl;
output << "InitializeComputationalEnvironment();" << endl;
if (parallel_test)
output << "ErrorCode = AnalyseComputationalEnvironment(options_.parallel, options_.parallel_info);" << endl
<< "disp(['AnalyseComputationalEnvironment returned with Error Code: ' num2str(ErrorCode)]);" << endl
<< "diary off;" << endl
<< "return;" << endl;
}
void
ConfigFile::writeEndParallel(ostream &output) const
{
if ((!parallel && !parallel_test) || !parallel_slave_open_mode)
return;
output << "if options_.parallel_info.leaveSlaveOpen == 1" << endl
<< " closeSlave(options_.parallel,options_.parallel_info.RemoteTmpFolder);" << endl
<< "end" << endl;
}

View File

@ -0,0 +1,95 @@
/*
* Copyright (C) 2010 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 _CONFIG_FILE_HH
#define _CONFIG_FILE_HH
#include <map>
#include <vector>
using namespace std;
class SlaveNode
{
friend class ConfigFile;
public:
SlaveNode(string &computerName_arg, int minCpuNbr_arg, int maxCpuNbr_arg, string &userName_arg,
string &password_arg, string &remoteDrive_arg, string &remoteDirectory_arg,
string &dynarePath_arg, string &matlabOctavePath_arg, bool singleCompThread_arg);
~SlaveNode();
protected:
const string computerName;
int minCpuNbr;
int maxCpuNbr;
const string userName;
const string password;
const string remoteDrive;
const string remoteDirectory;
const string dynarePath;
const string matlabOctavePath;
const bool singleCompThread;
};
class Cluster
{
friend class ConfigFile;
public:
Cluster(vector<string> member_nodes_arg);
~Cluster();
protected:
const vector<string> member_nodes;
};
//! The abstract representation of a "config" file
class ConfigFile
{
public:
ConfigFile(bool parallel_arg, bool parallel_test_arg, bool parallel_slave_open_mode_arg, const string &cluster_name);
~ConfigFile();
private:
const bool parallel;
const bool parallel_test;
const bool parallel_slave_open_mode;
const string cluster_name;
string firstClusterName;
//! Cluster Table
map<string, Cluster *> clusters;
//! Node Map
map<string, SlaveNode *> slave_nodes;
//! Add a SlaveNode or a Cluster object
void addConfFileElement(bool inNode, bool inCluster, vector<string> member_nodes, string &name,
string &computerName, int minCpuNbr, int maxCpuNbr, string &userName,
string &password, string &remoteDrive, string &remoteDirectory,
string &dynarePath, string &matlabOctavePath, bool singleCompThread);
public:
//! Parse config file
void getConfigFileInfo(const string &parallel_config_file);
//! Check Pass
void checkPass() const;
//! Check Pass
void transformPass();
//! Create options_.parallel structure, write options
void writeCluster(ostream &output) const;
//! Close slave nodes if needed
void writeEndParallel(ostream &output) const;
};
#endif // ! CONFIG_FILE_HH

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2003-2009 Dynare Team * Copyright (C) 2003-2010 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -34,7 +34,9 @@ using namespace std;
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
included simultaneously (because of Bison limitations). included simultaneously (because of Bison limitations).
*/ */
void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tmp_terms, bool warn_uninit void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tmp_terms, bool warn_uninit,
bool parallel, const string &parallel_config_file, const string &cluster_name, bool parallel_slave_open_mode,
bool parallel_test
#if defined(_WIN32) || defined(__CYGWIN32__) #if defined(_WIN32) || defined(__CYGWIN32__)
, bool cygwin, bool msvc , bool cygwin, bool msvc
#endif #endif
@ -44,6 +46,7 @@ void
usage() usage()
{ {
cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [warn_uninit]" cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [warn_uninit]"
<< " [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test]"
#if defined(_WIN32) || defined(__CYGWIN32__) #if defined(_WIN32) || defined(__CYGWIN32__)
<< " [cygwin] [msvc]" << " [cygwin] [msvc]"
#endif #endif
@ -72,6 +75,11 @@ main(int argc, char **argv)
bool cygwin = false; bool cygwin = false;
bool msvc = false; bool msvc = false;
#endif #endif
string parallel_config_file;
bool parallel = false;
string cluster_name;
bool parallel_slave_open_mode = false;
bool parallel_test = false;
// Parse options // Parse options
for (int arg = 2; arg < argc; arg++) for (int arg = 2; arg < argc; arg++)
@ -107,6 +115,32 @@ main(int argc, char **argv)
else if (!strcmp(argv[arg], "msvc")) else if (!strcmp(argv[arg], "msvc"))
msvc = true; msvc = true;
#endif #endif
else if (strlen(argv[arg]) >= 8 && !strncmp(argv[arg], "conffile", 8))
{
if (strlen(argv[arg]) <= 9 || argv[arg][8] != '=')
{
cerr << "Incorrect syntax for conffile option" << endl;
usage();
}
parallel_config_file = string(argv[arg] + 9);
}
else if (!strcmp(argv[arg], "parallel_slave_open_mode"))
parallel_slave_open_mode = true;
else if (!strcmp(argv[arg], "parallel_test"))
parallel_test = true;
else if (strlen(argv[arg]) >= 8 && !strncmp(argv[arg], "parallel", 8))
{
parallel = true;
if (strlen(argv[arg]) > 8)
{
if (strlen(argv[arg]) == 9 || argv[arg][8] != '=')
{
cerr << "Incorrect syntax for parallel option" << endl;
usage();
}
cluster_name = string(argv[arg] + 9);
}
}
else else
{ {
cerr << "Unknown option: " << argv[arg] << endl; cerr << "Unknown option: " << argv[arg] << endl;
@ -146,7 +180,8 @@ main(int argc, char **argv)
return EXIT_SUCCESS; return EXIT_SUCCESS;
// Do the rest // Do the rest
main2(macro_output, basename, debug, clear_all, no_tmp_terms, warn_uninit main2(macro_output, basename, debug, clear_all, no_tmp_terms, warn_uninit,
parallel, parallel_config_file, cluster_name, parallel_slave_open_mode, parallel_test
#if defined(_WIN32) || defined(__CYGWIN32__) #if defined(_WIN32) || defined(__CYGWIN32__)
, cygwin, msvc , cygwin, msvc
#endif #endif

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2008 Dynare Team * Copyright (C) 2008-2010 Dynare Team
* *
* This file is part of Dynare. * This file is part of Dynare.
* *
@ -23,9 +23,12 @@ using namespace std;
#include "ParsingDriver.hh" #include "ParsingDriver.hh"
#include "ModFile.hh" #include "ModFile.hh"
#include "ConfigFile.hh"
void void
main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tmp_terms, bool warn_uninit main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tmp_terms, bool warn_uninit,
bool parallel, const string &parallel_config_file, const string &cluster_name, bool parallel_slave_open_mode,
bool parallel_test
#if defined(_WIN32) || defined(__CYGWIN32__) #if defined(_WIN32) || defined(__CYGWIN32__)
, bool cygwin, bool msvc , bool cygwin, bool msvc
#endif #endif
@ -35,12 +38,16 @@ main2(stringstream &in, string &basename, bool debug, bool clear_all, bool no_tm
// Do parsing and construct internal representation of mod file // Do parsing and construct internal representation of mod file
ModFile *mod_file = p.parse(in, debug); ModFile *mod_file = p.parse(in, debug);
ConfigFile config_file (parallel, parallel_test, parallel_slave_open_mode, cluster_name);
config_file.getConfigFileInfo(parallel_config_file);
// Run checking pass // Run checking pass
mod_file->checkPass(); mod_file->checkPass();
config_file.checkPass();
// Perform transformations on the model (creation of auxiliary vars and equations) // Perform transformations on the model (creation of auxiliary vars and equations)
mod_file->transformPass(); mod_file->transformPass();
config_file.transformPass();
// Evaluate parameters initialization, initval, endval and pounds // Evaluate parameters initialization, initval, endval and pounds
mod_file->evalAllExpressions(warn_uninit); mod_file->evalAllExpressions(warn_uninit);
@ -49,7 +56,7 @@ 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
mod_file->writeOutputFiles(basename, clear_all mod_file->writeOutputFiles(basename, clear_all, config_file
#if defined(_WIN32) || defined(__CYGWIN32__) #if defined(_WIN32) || defined(__CYGWIN32__)
, cygwin, msvc , cygwin, msvc
#endif #endif

View File

@ -36,6 +36,8 @@ dynare_m_SOURCES = \
DataTree.hh \ DataTree.hh \
ModFile.cc \ ModFile.cc \
ModFile.hh \ ModFile.hh \
ConfigFile.cc \
ConfigFile.hh \
Statement.cc \ Statement.cc \
Statement.hh \ Statement.hh \
ExprNode.cc \ ExprNode.cc \

View File

@ -22,6 +22,7 @@
#include <fstream> #include <fstream>
#include <typeinfo> #include <typeinfo>
#include "ModFile.hh" #include "ModFile.hh"
#include "ConfigFile.hh"
ModFile::ModFile() : expressions_tree(symbol_table, num_constants, external_functions_table), ModFile::ModFile() : expressions_tree(symbol_table, num_constants, external_functions_table),
dynamic_model(symbol_table, num_constants, external_functions_table), dynamic_model(symbol_table, num_constants, external_functions_table),
@ -344,7 +345,7 @@ ModFile::computingPass(bool no_tmp_terms)
} }
void void
ModFile::writeOutputFiles(const string &basename, bool clear_all ModFile::writeOutputFiles(const string &basename, bool clear_all, const ConfigFile &config_file
#if defined(_WIN32) || defined(__CYGWIN32__) #if defined(_WIN32) || defined(__CYGWIN32__)
, bool cygwin, bool msvc , bool cygwin, bool msvc
#endif #endif
@ -419,6 +420,8 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all
<< "options_.bytecode=" << byte_code << ";" << endl << "options_.bytecode=" << byte_code << ";" << endl
<< "options_.use_dll=" << use_dll << ";" << endl; << "options_.use_dll=" << use_dll << ";" << endl;
config_file.writeCluster(mOutputFile);
if (byte_code) if (byte_code)
mOutputFile << "if exist('bytecode') ~= 3" << endl mOutputFile << "if exist('bytecode') ~= 3" << endl
<< " 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
@ -530,8 +533,11 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all
if (block && !byte_code) if (block && !byte_code)
mOutputFile << "rmpath " << basename << ";" << endl; mOutputFile << "rmpath " << basename << ";" << endl;
mOutputFile << "save('" << basename << "_results.mat', 'oo_', 'M_', 'options_');" << endl mOutputFile << "save('" << basename << "_results.mat', 'oo_', 'M_', 'options_');" << endl;
<< "diary off" << endl
config_file.writeEndParallel(mOutputFile);
mOutputFile << "diary off" << endl
<< endl << "disp(['Total computing time : ' dynsec2hms(toc) ]);" << endl; << endl << "disp(['Total computing time : ' dynsec2hms(toc) ]);" << endl;
mOutputFile.close(); mOutputFile.close();

View File

@ -33,6 +33,7 @@ using namespace std;
#include "SteadyStateModel.hh" #include "SteadyStateModel.hh"
#include "Statement.hh" #include "Statement.hh"
#include "ExternalFunctionsTable.hh" #include "ExternalFunctionsTable.hh"
#include "ConfigFile.hh"
//! The abstract representation of a "mod" file //! The abstract representation of a "mod" file
class ModFile class ModFile
@ -106,7 +107,7 @@ public:
\param clear_all Should a "clear all" instruction be written to output ? \param clear_all Should a "clear all" instruction be written to output ?
\param msvc Should the MEX command of use_dll be adapted for MSVC? \param msvc Should the MEX command of use_dll be adapted for MSVC?
*/ */
void writeOutputFiles(const string &basename, bool clear_all void writeOutputFiles(const string &basename, bool clear_all, const ConfigFile &config_file
#if defined(_WIN32) || defined(__CYGWIN32__) #if defined(_WIN32) || defined(__CYGWIN32__)
, bool cygwin, bool msvc , bool cygwin, bool msvc
#endif #endif