/* * Project: MoleCuilder * Description: creates and alters molecular systems * Copyright (C) 2011 University of Bonn. All rights reserved. * Please see the LICENSE file or "Copyright notice" in builder.cpp for details. */ /* * \file controller.cpp * * This file strongly follows the Serialization example from the boost::asio * library (see client.cpp) * * Created on: Nov 27, 2011 * Author: heber */ // include config.h #ifdef HAVE_CONFIG_H #include #endif // boost asio needs specific operator new #include #include "CodePatterns/MemDebug.hpp" #include #include #include #include #include #include #include #include #include "atexit.hpp" #include "CodePatterns/Info.hpp" #include "CodePatterns/Log.hpp" #include "Fragmentation/EnergyMatrix.hpp" #include "Fragmentation/ForceMatrix.hpp" #include "Fragmentation/KeySetsContainer.hpp" #include "FragmentController.hpp" #include "Jobs/MPQCCommandJob.hpp" #include "Jobs/MPQCCommandJob_MPQCData.hpp" #include "Jobs/SystemCommandJob.hpp" #include "Results/FragmentResult.hpp" enum CommandIndices { UnknownCommandIndex = 0, AddJobsIndex = 1, CreateJobsIndex = 2, CheckResultsIndex = 3, ReceiveResultsIndex = 4, ReceiveMPQCIndex = 5, ShutdownIndex = 6, }; /** Creates a SystemCommandJob out of give \a command with \a argument. * * @param jobs created job is added to this vector * @param command command to execute for SystemCommandJob * @param argument argument for command to execute * @param nextid id for this job */ void createjobs( std::vector &jobs, const std::string &command, const std::string &argument, const JobId_t nextid) { FragmentJob::ptr testJob( new SystemCommandJob(command, argument, nextid) ); jobs.push_back(testJob); LOG(1, "INFO: Added one SystemCommandJob."); } /** Creates a MPQCCommandJob with argument \a filename. * * @param jobs created job is added to this vector * @param filename filename being argument to job * @param nextid id for this job */ void parsejob( std::vector &jobs, const std::string &filename, const JobId_t nextid) { std::ifstream file; file.open(filename.c_str()); ASSERT( file.good(), "parsejob() - file "+filename+" does not exist."); std::string output((std::istreambuf_iterator(file)), std::istreambuf_iterator()); FragmentJob::ptr testJob( new MPQCCommandJob(output, nextid) ); jobs.push_back(testJob); file.close(); LOG(1, "INFO: Added MPQCCommandJob from file "+filename+"."); } /** Print received results. * * @param results received results to print */ void printReceivedResults(std::vector &results) { for (std::vector::const_iterator iter = results.begin(); iter != results.end(); ++iter) LOG(1, "RESULT: job #"+toString((*iter)->getId())+": "+toString((*iter)->result)); } /** Print MPQCData from received results. * * @param results vector of all received FragmentResult's * @param KeySetFilename filename containing keysets */ bool printReceivedMPQCResults( std::vector &results, const std::string &KeySetFilename) { EnergyMatrix Energy; EnergyMatrix EnergyFragments; ForceMatrix Force; ForceMatrix ForceFragments; KeySetsContainer KeySet; // place results into EnergyMatrix and ForceMatrix //if (!Energy.ParseFragmentMatrix(argv[1], dir, EnergySuffix, 0,0)) return false; //if (!Force.ParseFragmentMatrix(argv[1], dir, ForcesSuffix, 0,0)) return false; // combine all found data std::vector fragmentData(results.size()); MPQCData combinedData; LOG(2, "DEBUG: Parsing now through " << results.size() << " results."); for (std::vector::const_iterator iter = results.begin(); iter != results.end(); ++iter) { LOG(1, "RESULT: job #"+toString((*iter)->getId())+": "+toString((*iter)->result)); MPQCData extractedData; std::stringstream inputstream((*iter)->result); boost::archive::text_iarchive ia(inputstream); ia >> extractedData; LOG(1, "INFO: extracted data is " << extractedData << "."); } if (!Energy.InitialiseIndices()) return false; if (!Force.ParseIndices(KeySetFilename.c_str())) return false; if (!KeySet.ParseKeySets(KeySetFilename.c_str(), Force.RowCounter, Force.MatrixCounter)) return false; if (!KeySet.ParseManyBodyTerms()) return false; if (!EnergyFragments.AllocateMatrix(Energy.Header, Energy.MatrixCounter, Energy.RowCounter, Energy.ColumnCounter)) return false; if (!ForceFragments.AllocateMatrix(Force.Header, Force.MatrixCounter, Force.RowCounter, Force.ColumnCounter)) return false; if(!Energy.SetLastMatrix(0., 0)) return false; if(!Force.SetLastMatrix(0., 2)) return false; for (int BondOrder=0;BondOrder &commandmap, const std::string &cmd) { std::map::const_iterator iter = commandmap.find(cmd); if (iter != commandmap.end()) return iter->second; else return UnknownCommandIndex; } int main(int argc, char* argv[]) { // from this moment on, we need to be sure to deeinitialize in the correct order // this is handled by the cleanup function atexit(cleanUp); setVerbosity(3); size_t Exitflag = 0; typedef std::map CommandsMap_t; CommandsMap_t CommandsMap; CommandsMap.insert( std::make_pair("addjobs", AddJobsIndex) ); CommandsMap.insert( std::make_pair("createjobs", CreateJobsIndex) ); CommandsMap.insert( std::make_pair("checkresults", CheckResultsIndex) ); CommandsMap.insert( std::make_pair("receiveresults", ReceiveResultsIndex) ); CommandsMap.insert( std::make_pair("receivempqc", ReceiveMPQCIndex) ); CommandsMap.insert( std::make_pair("shutdown", ShutdownIndex) ); try { // Check command line arguments. if (argc < 4) { std::cerr << "Usage: " << argv[0] << " [options to command]" << std::endl; std::cerr << "List of available commands:" << std::endl; for(CommandsMap_t::const_iterator iter = CommandsMap.begin(); iter != CommandsMap.end(); ++iter) { std::cerr << "\t" << iter->first << std::endl; } return false; } boost::asio::io_service io_service; FragmentController controller(io_service); // Initial phase: information gathering from server switch(getCommandIndex(CommandsMap, argv[3])) { case AddJobsIndex: { if (argc < 5) { ELOG(1, "Please add a filename for the MPQCCommandJob."); } else { // get an id for every filename for (int argcount = 4; argcount < argc; ++argcount) { controller.requestId(argv[1], argv[2]); } } break; } case CreateJobsIndex: { std::vector jobs; if (argc < 6) { ELOG(1, "'createjobs' requires two options: [command] [argument]."); } else { controller.requestId(argv[1], argv[2]); } break; } case CheckResultsIndex: break; case ReceiveResultsIndex: break; case ReceiveMPQCIndex: break; case ShutdownIndex: break; case UnknownCommandIndex: default: ELOG(1, "Unrecognized command '"+toString(argv[3])+"'."); break; } { io_service.reset(); Info info("io_service: Phase One"); io_service.run(); } // Second phase: Building jobs and sending information to server switch(getCommandIndex(CommandsMap, argv[3])) { case AddJobsIndex: { std::vector jobs; if (argc < 5) { ELOG(1, "Please add a filename for the MPQCCommandJob."); } else { for (int argcount = 4; argcount < argc; ++argcount) { const JobId_t next_id = controller.getAvailableId(); const std::string filename(argv[argcount]); LOG(1, "INFO: Creating MPQCCommandJob with filename'" +filename+"', and id "+toString(next_id)+"."); parsejob(jobs, filename, next_id); } controller.addJobs(jobs); controller.sendJobs(argv[1], argv[2]); } break; } case CreateJobsIndex: { std::vector jobs; if (argc < 6) { ELOG(1, "'createjobs' requires two options: [command] [argument]."); } else { const JobId_t next_id = controller.getAvailableId(); createjobs(jobs, argv[4], argv[5], next_id); controller.addJobs(jobs); controller.sendJobs(argv[1], argv[2]); } break; } case CheckResultsIndex: { controller.checkResults(argv[1], argv[2]); break; } case ReceiveResultsIndex: { controller.receiveResults(argv[1], argv[2]); break; } case ReceiveMPQCIndex: { controller.receiveResults(argv[1], argv[2]); break; } case ShutdownIndex: { controller.shutdown(argv[1], argv[2]); break; } case UnknownCommandIndex: default: ELOG(0, "Unrecognized command '"+toString(argv[3])+"'."); break; } { io_service.reset(); Info info("io_service: Phase Two"); io_service.run(); } // Final phase: Print result of command switch(getCommandIndex(CommandsMap, argv[3])) { case AddJobsIndex: case CreateJobsIndex: break; case CheckResultsIndex: { controller.printDoneJobs(); break; } case ReceiveResultsIndex: { std::vector results = controller.getReceivedResults(); printReceivedResults(results); break; } case ReceiveMPQCIndex: { if (argc == 4) { ELOG(1, "'receivempqc' requires one option: [KeySetFilename]."); } else { const std::string KeySetFilename = argv[4]; LOG(1, "INFO: Parsing id associations from " << KeySetFilename << "."); std::vector results = controller.getReceivedResults(); printReceivedMPQCResults(results, KeySetFilename); } break; } case ShutdownIndex: break; case UnknownCommandIndex: default: ELOG(0, "Unrecognized command '"+toString(argv[3])+"'."); break; } Exitflag = controller.getExitflag(); } catch (std::exception& e) { std::cerr << e.what() << std::endl; } return Exitflag; }