1
0
mirror of https://github.com/paboyle/Grid.git synced 2024-11-15 02:05:37 +00:00
Grid/Hadrons/Application.cc

297 lines
9.7 KiB
C++
Raw Normal View History

2016-12-15 18:26:39 +00:00
/*************************************************************************************
2016-02-25 12:07:21 +00:00
Grid physics library, www.github.com/paboyle/Grid
2018-09-01 21:30:30 +01:00
Source file: Hadrons/Application.cc
2016-02-25 12:07:21 +00:00
2019-02-05 18:55:24 +00:00
Copyright (C) 2015-2019
2016-02-25 12:07:21 +00:00
Author: Antonin Portelli <antonin.portelli@me.com>
This program 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 2 of the License, or
(at your option) any later version.
This program 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 this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2016-12-15 18:26:39 +00:00
See the full license in the file "LICENSE" in the top level distribution directory
*************************************************************************************/
2016-12-15 18:21:52 +00:00
/* END LEGAL */
#include <Hadrons/Application.hpp>
#include <Hadrons/GeneticScheduler.hpp>
#include <Hadrons/Modules.hpp>
using namespace Grid;
using namespace Hadrons;
#define BIG_SEP "================"
#define SEP "----------------"
2016-05-07 21:26:56 +01:00
/******************************************************************************
* Application implementation *
******************************************************************************/
2016-11-28 07:02:15 +00:00
// constructors ////////////////////////////////////////////////////////////////
2018-06-25 19:08:39 +01:00
#define MACOUT(macro) macro << " (" << #macro << ")"
#define MACOUTS(macro) HADRONS_STR(macro) << " (" << #macro << ")"
2016-11-28 07:02:15 +00:00
Application::Application(void)
{
initLogger();
auto dim = GridDefaultLatt(), mpi = GridDefaultMpi(), loc(dim);
2019-02-22 18:41:26 +00:00
if (dim.size())
{
2019-02-22 18:41:26 +00:00
locVol_ = 1;
for (unsigned int d = 0; d < dim.size(); ++d)
{
loc[d] /= mpi[d];
locVol_ *= loc[d];
}
LOG(Message) << "====== HADRONS APPLICATION INITIALISATION ======" << std::endl;
LOG(Message) << "** Dimensions" << std::endl;
LOG(Message) << "Global lattice: " << dim << std::endl;
LOG(Message) << "MPI partition : " << mpi << std::endl;
LOG(Message) << "Local lattice : " << loc << std::endl;
LOG(Message) << std::endl;
LOG(Message) << "** Default parameters (and associated C macros)" << std::endl;
LOG(Message) << "ASCII output precision : " << MACOUT(DEFAULT_ASCII_PREC) << std::endl;
LOG(Message) << "Fermion implementation : " << MACOUTS(FIMPLBASE) << std::endl;
LOG(Message) << "z-Fermion implementation: " << MACOUTS(ZFIMPLBASE) << std::endl;
LOG(Message) << "Scalar implementation : " << MACOUTS(SIMPLBASE) << std::endl;
LOG(Message) << "Gauge implementation : " << MACOUTS(GIMPLBASE) << std::endl;
LOG(Message) << "Eigenvector base size : "
<< MACOUT(HADRONS_DEFAULT_LANCZOS_NBASIS) << std::endl;
LOG(Message) << "Schur decomposition : " << MACOUTS(HADRONS_DEFAULT_SCHUR) << std::endl;
LOG(Message) << std::endl;
}
}
2016-11-28 07:02:15 +00:00
Application::Application(const Application::GlobalPar &par)
: Application()
{
setPar(par);
}
Application::Application(const std::string parameterFileName)
: Application()
{
parameterFileName_ = parameterFileName;
}
// access //////////////////////////////////////////////////////////////////////
void Application::setPar(const Application::GlobalPar &par)
{
par_ = par;
}
const Application::GlobalPar & Application::getPar(void)
{
return par_;
}
// execute /////////////////////////////////////////////////////////////////////
void Application::run(void)
{
LOG(Message) << "====== HADRONS APPLICATION START ======" << std::endl;
if (!parameterFileName_.empty() and (vm().getNModule() == 0))
2016-11-28 07:02:15 +00:00
{
parseParameterFile(parameterFileName_);
2016-11-28 07:02:15 +00:00
}
if (getPar().runId.empty())
{
HADRONS_ERROR(Definition, "run id is empty");
}
LOG(Message) << "RUN ID '" << getPar().runId << "'" << std::endl;
BinaryIO::latticeWriteMaxRetry = getPar().parallelWriteMaxRetry;
LOG(Message) << "Attempt(s) for resilient parallel I/O: "
<< BinaryIO::latticeWriteMaxRetry << std::endl;
vm().setRunId(getPar().runId);
vm().printContent();
env().printContent();
if (getPar().saveSchedule or getPar().scheduleFile.empty())
{
schedule();
if (getPar().saveSchedule)
{
std::string filename;
filename = (getPar().scheduleFile.empty()) ?
"hadrons.sched" : getPar().scheduleFile;
saveSchedule(filename);
}
}
else
{
loadSchedule(getPar().scheduleFile);
}
printSchedule();
if (!getPar().graphFile.empty())
{
makeFileDir(getPar().graphFile, env().getGrid());
vm().dumpModuleGraph(getPar().graphFile);
}
configLoop();
}
// parse parameter file ////////////////////////////////////////////////////////
class ObjectId: Serializable
{
public:
GRID_SERIALIZABLE_CLASS_MEMBERS(ObjectId,
std::string, name,
std::string, type);
};
void Application::parseParameterFile(const std::string parameterFileName)
{
XmlReader reader(parameterFileName);
2016-12-05 02:44:36 +00:00
GlobalPar par;
ObjectId id;
LOG(Message) << "Building application from '" << parameterFileName << "'..." << std::endl;
2016-12-05 02:44:36 +00:00
read(reader, "parameters", par);
setPar(par);
if (!push(reader, "modules"))
{
HADRONS_ERROR(Parsing, "Cannot open node 'modules' in parameter file '"
2017-12-13 16:36:15 +00:00
+ parameterFileName + "'");
}
if (!push(reader, "module"))
{
HADRONS_ERROR(Parsing, "Cannot open node 'modules/module' in parameter file '"
2017-12-13 16:36:15 +00:00
+ parameterFileName + "'");
}
do
{
read(reader, "id", id);
vm().createModule(id.name, id.type, reader);
} while (reader.nextElement("module"));
pop(reader);
pop(reader);
}
void Application::saveParameterFile(const std::string &parameterFileName, const std::vector<std::string> &Except, unsigned int prec)
{
LOG(Message) << "Saving application to '" << parameterFileName << "'..." << std::endl;
2018-01-23 17:26:50 +00:00
if (env().getGrid()->IsBoss())
{
2018-01-23 17:26:50 +00:00
XmlWriter writer(parameterFileName);
writer.setPrecision(prec);
2018-01-23 17:26:50 +00:00
ObjectId id;
const unsigned int nMod = vm().getNModule();
write(writer, "parameters", getPar());
push(writer, "modules");
for (unsigned int i = 0; i < nMod; ++i)
{
id.name = vm().getModuleName(i);
if( std::find( Except.begin(), Except.end(), id.name ) == Except.end() )
{
push(writer, "module");
id.type = vm().getModule(i)->getRegisteredName();
write(writer, "id", id);
vm().getModule(i)->saveParameters(writer, "options");
pop(writer);
}
2018-01-23 17:26:50 +00:00
}
pop(writer);
pop(writer);
}
}
void Application::saveParameterFile(const std::string &parameterFileName, unsigned int prec)
{
const std::vector<std::string> Except;
saveParameterFile(parameterFileName, Except, prec);
}
// schedule computation ////////////////////////////////////////////////////////
void Application::schedule(void)
{
2017-12-13 16:36:15 +00:00
if (!scheduled_ and !loadedSchedule_)
2015-12-02 19:33:34 +00:00
{
2017-12-13 16:36:15 +00:00
program_ = vm().schedule(par_.genetic);
scheduled_ = true;
}
}
void Application::saveSchedule(const std::string filename)
{
LOG(Message) << "Saving current schedule to '" << filename << "'..."
<< std::endl;
2018-01-23 17:26:50 +00:00
if (env().getGrid()->IsBoss())
{
2018-01-23 17:26:50 +00:00
TextWriter writer(filename);
std::vector<std::string> program;
if (!scheduled_)
{
HADRONS_ERROR(Definition, "Computation not scheduled");
2018-01-23 17:26:50 +00:00
}
for (auto address: program_)
{
program.push_back(vm().getModuleName(address));
}
write(writer, "schedule", program);
}
}
void Application::loadSchedule(const std::string filename)
{
TextReader reader(filename);
std::vector<std::string> program;
LOG(Message) << "Loading schedule from '" << filename << "'..."
<< std::endl;
read(reader, "schedule", program);
program_.clear();
for (auto &name: program)
{
program_.push_back(vm().getModuleAddress(name));
}
2017-12-13 16:36:15 +00:00
loadedSchedule_ = true;
2018-08-07 18:26:49 +01:00
scheduled_ = true;
}
void Application::printSchedule(void)
{
2018-08-07 18:26:49 +01:00
if (!scheduled_ and !loadedSchedule_)
{
HADRONS_ERROR(Definition, "Computation not scheduled");
}
2017-12-13 16:36:15 +00:00
auto peak = vm().memoryNeeded(program_);
LOG(Message) << "Schedule (memory needed: " << sizeString(peak) << "):"
<< std::endl;
for (unsigned int i = 0; i < program_.size(); ++i)
{
LOG(Message) << std::setw(4) << i + 1 << ": "
<< vm().getModuleName(program_[i]) << std::endl;
}
}
// loop on configurations //////////////////////////////////////////////////////
void Application::configLoop(void)
{
auto range = par_.trajCounter;
for (unsigned int t = range.start; t < range.end; t += range.step)
{
2016-05-07 21:26:56 +01:00
LOG(Message) << BIG_SEP << " Starting measurement for trajectory " << t
<< " " << BIG_SEP << std::endl;
vm().setTrajectory(t);
vm().executeProgram(program_);
}
LOG(Message) << BIG_SEP << " End of measurement " << BIG_SEP << std::endl;
env().freeAll();
}