/* * Application.cc, part of Grid * * Copyright (C) 2015 Antonin Portelli * * Grid 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. * * Grid 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 Grid. If not, see . */ #include #include using namespace Grid; using namespace Hadrons; /****************************************************************************** * Application implementation * ******************************************************************************/ // constructor ///////////////////////////////////////////////////////////////// Application::Application(int argc, char *argv[]) : env_(Environment::getInstance()) , modFactory_(ModuleFactory::getInstance()) { if (argc < 2) { std::cerr << "usage: " << argv[0] << " [Grid options]"; std::cerr << std::endl; std::exit(EXIT_FAILURE); } parameterFileName_ = argv[1]; Grid_init(&argc, &argv); HadronsLogError.Active(GridLogError.isActive()); HadronsLogWarning.Active(GridLogWarning.isActive()); HadronsLogMessage.Active(GridLogMessage.isActive()); HadronsLogDebug.Active(GridLogDebug.isActive()); LOG(Message) << "Grid initialized" << std::endl; LOG(Message) << "Modules available:" << std::endl; auto list = modFactory_.getModuleList(); for (auto &m: list) { LOG(Message) << " " << m << std::endl; } } // destructor ////////////////////////////////////////////////////////////////// Application::~Application(void) { LOG(Message) << "Grid is finalizing now" << std::endl; Grid_finalize(); } // execute ///////////////////////////////////////////////////////////////////// void Application::run(void) { parseParameterFile(); schedule(); configLoop(); } // parse parameter file //////////////////////////////////////////////////////// class ModuleId: Serializable { public: GRID_SERIALIZABLE_CLASS_MEMBERS(ModuleId, std::string, name, std::string, type); }; void Application::parseParameterFile(void) { XmlReader reader(parameterFileName_); ModuleId id; LOG(Message) << "Reading '" << parameterFileName_ << "'..." << std::endl; read(reader, "parameters", par_); push(reader, "modules"); push(reader, "module"); do { read(reader, "id", id); module_[id.name] = modFactory_.create(id.type, id.name); module_[id.name]->parseParameters(reader, "options"); std::vector output = module_[id.name]->getOutput(); for (auto &n: output) { associatedModule_[n] = id.name; } } while (reader.nextElement("module")); pop(reader); pop(reader); } // schedule computation //////////////////////////////////////////////////////// void Application::schedule(void) { Graph moduleGraph; LOG(Message) << "Scheduling computation..." << std::endl; // create dependency graph for (auto &m: module_) { std::vector input = m.second->getInput(); for (auto &n: input) { try { moduleGraph.addEdge(associatedModule_.at(n), m.first); } catch (std::out_of_range &) { HADRON_ERROR("unknown object '" + n + "'"); } } } // topological sort std::map> m; unsigned int k = 0; std::vector> con = moduleGraph.getConnectedComponents(); LOG(Message) << "Program:" << std::endl; for (unsigned int i = 0; i < con.size(); ++i) { std::vector> t = con[i].allTopoSort(); m = makeDependencyMatrix(t); for (unsigned int j = 0; j < t[0].size(); ++j) { program_.push_back(t[0][j]); LOG(Message) << std::setw(4) << std::right << k << ": " << program_[k] << std::endl; k++; } } } // program execution /////////////////////////////////////////////////////////// void Application::configLoop(void) { auto range = par_.configs.range; for (unsigned int t = range.start; t < range.end; t += range.step) { LOG(Message) << "Starting measurement for trajectory " << t << std::endl; execute(); } } void Application::execute(void) { for (unsigned int i = 0; i < program_.size(); ++i) { LOG(Message) << "Measurement step (" << i+1 << "/" << program_.size() << ")" << std::endl; (*module_[program_[i]])(env_); } }