Changeset 685e28


Ignore:
Timestamp:
Jul 6, 2012, 10:18:43 AM (13 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
0aaf84
Parents:
9dcce3
git-author:
Frederik Heber <heber@…> (05/31/12 09:08:05)
git-committer:
Frederik Heber <heber@…> (07/06/12 10:18:43)
Message:

Removed the lot of switch statements in controller's main(), replaced by deque's of bound functions.

  • This will eventually allow the use to simply add another command by furnishing it with its own queue of bound functions.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/controller.cpp

    r9dcce3 r685e28  
    2727#include "CodePatterns/MemDebug.hpp"
    2828
    29 #include <boost/archive/text_oarchive.hpp>
    30 #include <boost/archive/text_iarchive.hpp>
     29#include <boost/assign.hpp>
    3130#include <boost/program_options.hpp>
     31#include <deque>
    3232#include <fstream>
    3333#include <iostream>
     
    5050#include "Fragmentation/Automation/Results/FragmentResult.hpp"
    5151
    52 enum CommandIndices {
    53   UnknownCommandIndex = 0,
    54   AddJobsIndex = 1,
    55   CreateJobsIndex = 2,
    56   CheckResultsIndex = 3,
    57   ReceiveResultsIndex = 4,
    58   ReceiveMPQCIndex = 5,
    59   RemoveAllIndex = 6,
    60   ShutdownIndex = 7,
    61 };
    62 
     52/** Print the status of scheduled and done jobs.
     53 *
     54 * @param status pair of number of schedule and done jobs
     55 */
     56void printJobStatus(const std::pair<size_t, size_t> &JobStatus)
     57{
     58  LOG(1, "INFO: #" << JobStatus.first << " are waiting in the queue and #"
     59      << JobStatus.second << " jobs are calculated so far.");
     60}
    6361
    6462/** Creates a SystemCommandJob out of give \a command with \a argument.
     
    7573    const JobId_t nextid)
    7674{
    77 
    7875  FragmentJob::ptr testJob( new SystemCommandJob(command, argument, nextid) );
    7976  jobs.push_back(testJob);
     
    109106 * @param results received results to print
    110107 */
    111 void printReceivedResults(std::vector<FragmentResult::ptr> &results)
     108void printReceivedResults(const std::vector<FragmentResult::ptr> &results)
    112109{
    113110  for (std::vector<FragmentResult::ptr>::const_iterator iter = results.begin();
     
    290287}
    291288
    292 
    293 /** Returns a unique index for every command to allow switching over it.
    294  *
    295  * \param &commandmap map with command strings
    296  * \param &cmd command string
    297  * \return index from CommandIndices: UnkownCommandIndex - unknown command, else - command index
    298  */
    299 CommandIndices getCommandIndex(std::map<std::string, CommandIndices> &commandmap, const std::string &cmd)
    300 {
    301   std::map<std::string, CommandIndices>::const_iterator iter = commandmap.find(cmd);
    302   if (iter != commandmap.end())
    303     return iter->second;
    304   else
    305     return UnknownCommandIndex;
    306 }
    307 
    308289struct ControllerOptions
    309290{
     291
    310292  int parseHelp(boost::program_options::variables_map &vm, const boost::program_options::options_description &desc) {
    311293    if (vm.count("help")) {
     
    388370};
    389371
     372struct ControllerOptions_MPQCCommandJob : public ControllerOptions_SystemCommandJob
     373{
     374  int parseFragmentpath(boost::program_options::variables_map &vm) {
     375    if (command == "receivempqc") {
     376      if (!vm.count("fragment-path")) {
     377        ELOG(1, "'"+command+"' requires two options: [fragment-path].");
     378        return 255;
     379      }
     380      fragmentpath = vm["fragment-path"].as< std::string >();
     381    }
     382    return 0;
     383  }
     384
     385  int parseJobfiles(boost::program_options::variables_map &vm) {
     386    if (command == "addjobs") {
     387      if (!vm.count("jobfiles")) {
     388        ELOG(1, "'"+command+"' requires two options: [executable] [jobfiles].");
     389        return 255;
     390      }
     391      jobfiles = vm["jobfiles"].as< std::vector<std::string> >();
     392    }
     393    return 0;
     394  }
     395
     396  std::string fragmentpath;
     397  std::vector<std::string> jobfiles;
     398};
     399
     400void creatingJob(FragmentController &controller, const ControllerOptions_SystemCommandJob &ControllerInfo)
     401{
     402  const JobId_t next_id = controller.getAvailableId();
     403  std::vector<FragmentJob::ptr> jobs;
     404  createjobs(jobs, ControllerInfo.executable, ControllerInfo.jobcommand, next_id);
     405  controller.addJobs(jobs);
     406  controller.sendJobs(ControllerInfo.server, ControllerInfo.serverport);
     407}
     408
     409/** Creates a MPQCCommandJob out of give \a command with \a argument.
     410 *
     411 * @param controller reference to controller to add jobs
     412 * @param ControllerInfo information on the job
     413 */
     414void AddJobs(FragmentController &controller, const ControllerOptions_MPQCCommandJob &ControllerInfo)
     415{
     416  std::vector<FragmentJob::ptr> jobs;
     417  for (std::vector< std::string >::const_iterator iter = ControllerInfo.jobfiles.begin();
     418      iter != ControllerInfo.jobfiles.end(); ++iter) {
     419    const JobId_t next_id = controller.getAvailableId();
     420    const std::string &filename = *iter;
     421    LOG(1, "INFO: Creating MPQCCommandJob with filename '"
     422        +filename+"', and id "+toString(next_id)+".");
     423    parsejob(jobs, ControllerInfo.executable, filename, next_id);
     424  }
     425  controller.addJobs(jobs);
     426  controller.sendJobs(ControllerInfo.server, ControllerInfo.serverport);
     427}
     428
    390429int main(int argc, char* argv[])
    391430{
     
    394433  atexit(cleanUp);
    395434
    396   setVerbosity(3);
    397 
    398435  size_t Exitflag = 0;
    399   typedef std::map<std::string, CommandIndices> CommandsMap_t;
     436
     437  ControllerOptions_MPQCCommandJob ControllerInfo;
     438  boost::asio::io_service io_service;
     439  FragmentController controller(io_service);
     440  boost::program_options::variables_map vm;
     441
     442  typedef boost::function<void ()> ControllerCommand;
     443  typedef std::map<std::string, std::deque<ControllerCommand> > CommandsMap_t;
    400444  CommandsMap_t CommandsMap;
    401   CommandsMap.insert( std::make_pair("addjobs", AddJobsIndex) );
    402   CommandsMap.insert( std::make_pair("createjobs", CreateJobsIndex) );
    403   CommandsMap.insert( std::make_pair("checkresults", CheckResultsIndex) );
    404   CommandsMap.insert( std::make_pair("receiveresults", ReceiveResultsIndex) );
    405   CommandsMap.insert( std::make_pair("receivempqc", ReceiveMPQCIndex) );
    406   CommandsMap.insert( std::make_pair("removeall", RemoveAllIndex) );
    407   CommandsMap.insert( std::make_pair("shutdown", ShutdownIndex) );
     445
     446  // prepare the command queues for each ControllerCommand
     447  // note: we need "< ControllerCommand >" because parseExecutable(),... return int
     448  // in contrast to other functions that return void
     449  std::deque<ControllerCommand> addjobsQueue = boost::assign::list_of< ControllerCommand >
     450      (boost::bind(&FragmentController::requestIds,
     451          boost::ref(controller), boost::cref(ControllerInfo.server), boost::cref(ControllerInfo.serverport),
     452          boost::bind(&std::vector<std::string>::size, boost::cref(ControllerInfo.jobfiles))))
     453      (boost::bind(&AddJobs, boost::ref(controller), boost::cref(ControllerInfo)))
     454      ;
     455  std::deque<ControllerCommand> createjobsQueue = boost::assign::list_of< ControllerCommand >
     456      (boost::bind(&FragmentController::requestIds,
     457          boost::ref(controller), boost::cref(ControllerInfo.server), boost::cref(ControllerInfo.serverport), 1))
     458      (boost::bind(&creatingJob, boost::ref(controller), boost::cref(ControllerInfo)))
     459      ;
     460  std::deque<ControllerCommand> checkresultsQueue = boost::assign::list_of< ControllerCommand >
     461      (boost::bind(&FragmentController::checkResults,
     462          boost::ref(controller), boost::cref(ControllerInfo.server), boost::cref(ControllerInfo.serverport)))
     463      (boost::bind(&printJobStatus,
     464          boost::bind(&FragmentController::getJobStatus, boost::ref(controller))))
     465      ;
     466  std::deque<ControllerCommand> receiveresultsQueue = boost::assign::list_of< ControllerCommand >
     467      (boost::bind(&FragmentController::receiveResults,
     468          boost::ref(controller), boost::cref(ControllerInfo.server), boost::cref(ControllerInfo.serverport)))
     469      (boost::bind(&printReceivedResults,
     470          boost::bind(&FragmentController::getReceivedResults, boost::ref(controller))))
     471      ;
     472  std::deque<ControllerCommand> receivempqcresultsQueue = boost::assign::list_of< ControllerCommand >
     473      (boost::bind(&FragmentController::receiveResults,
     474          boost::ref(controller), boost::cref(ControllerInfo.server), boost::cref(ControllerInfo.serverport)))
     475      (boost::bind(&printReceivedMPQCResults,
     476          boost::bind(&FragmentController::getReceivedResults, boost::ref(controller)),
     477          boost::cref(ControllerInfo.fragmentpath),
     478          boost::bind(&getNoAtomsFromAdjacencyFile, boost::cref(ControllerInfo.fragmentpath))))
     479      ;
     480  std::deque<ControllerCommand> removeallQueue = boost::assign::list_of< ControllerCommand >
     481      (boost::bind(&FragmentController::removeall,
     482          boost::ref(controller), boost::cref(ControllerInfo.server), boost::cref(ControllerInfo.serverport)))
     483      ;
     484  std::deque<ControllerCommand> shutdownQueue = boost::assign::list_of< ControllerCommand >
     485      (boost::bind(&FragmentController::shutdown,
     486          boost::ref(controller), boost::cref(ControllerInfo.server), boost::cref(ControllerInfo.serverport)))
     487      ;
     488  CommandsMap.insert( std::make_pair("addjobs", addjobsQueue) );
     489  CommandsMap.insert( std::make_pair("createjobs", createjobsQueue) );
     490  CommandsMap.insert( std::make_pair("checkresults", checkresultsQueue) );
     491  CommandsMap.insert( std::make_pair("receiveresults", receiveresultsQueue) );
     492  CommandsMap.insert( std::make_pair("receivempqc", receivempqcresultsQueue) );
     493  CommandsMap.insert( std::make_pair("removeall", removeallQueue) );
     494  CommandsMap.insert( std::make_pair("shutdown", shutdownQueue) );
    408495  std::vector<std::string> Commands;
    409496  for (CommandsMap_t::const_iterator iter = CommandsMap.begin(); iter != CommandsMap.end(); ++iter)
     
    418505      ("command", boost::program_options::value< std::string >(), (std::string("command to send to server: ")+toString(Commands)).c_str())
    419506      ("executable", boost::program_options::value< std::string >(), "executable for commands 'addjobs' and 'createjobs'")
    420       ("fragment-path", boost::program_options::value< std::string >(), "path to fragment files for 'receivempqcresults'")
     507      ("fragment-path", boost::program_options::value< std::string >(), "path to fragment files for 'receivempqc'")
    421508      ("jobcommand", boost::program_options::value< std::string >(), "command argument for executable for 'createjobs'")
    422509      ("jobfiles", boost::program_options::value< std::vector< std::string > >()->multitoken(), "list of files as single argument to executable for 'addjobs'")
    423510  ;
    424511
    425   boost::program_options::variables_map vm;
     512  // parse command line
    426513  boost::program_options::store(boost::program_options::parse_command_line(argc, argv, desc), vm);
    427514  boost::program_options::notify(vm);
    428   ControllerOptions_SystemCommandJob ControllerInfo;
    429 
     515
     516  // set controller information
    430517  ControllerInfo.parseHelp(vm, desc);
    431 
    432518  ControllerInfo.parseVerbosity(vm);
    433 
    434519  ControllerInfo.parseServerPort(vm);
    435 
    436520  ControllerInfo.parseCommand(vm, Commands);
    437   const CommandIndices commandIndex = getCommandIndex(CommandsMap, ControllerInfo.command);
    438 
     521
     522  // all later parse functions depend on parsed command
    439523  ControllerInfo.parseExecutable(vm);
    440524
    441525  ControllerInfo.parseJobCommand(vm);
    442526
    443   // check arguments
    444   switch(commandIndex) {
    445     case AddJobsIndex:
    446     case CreateJobsIndex:
    447       break;
    448     case CheckResultsIndex:
    449       break;
    450     case ReceiveResultsIndex:
    451       break;
    452     case ReceiveMPQCIndex:
    453       if (!vm.count("fragment-path")) {
    454         ELOG(1, "'"+ControllerInfo.command+"' require one option: [path to fragment files].");
    455         return 255;
    456       }
    457       break;
    458     case RemoveAllIndex:
    459       break;
    460     case ShutdownIndex:
    461       break;
    462     case UnknownCommandIndex:
    463     default:
    464       ELOG(1, "Unrecognized command '"+toString(ControllerInfo.command)+"'.");
    465       return 255;
    466       break;
    467   }
    468 
     527  ControllerInfo.parseFragmentpath(vm);
     528
     529  ControllerInfo.parseJobfiles(vm);
     530
     531  // parse given ControllerCommand
     532  if( CommandsMap.count(ControllerInfo.command) == 0) {
     533    ELOG(1, "Unrecognized command '"+toString(ControllerInfo.command)+"'.");
     534    return 255;
     535  }
     536  std::deque<ControllerCommand> &commands = CommandsMap[ControllerInfo.command];
    469537  try
    470538  {
    471 
    472     boost::asio::io_service io_service;
    473     FragmentController controller(io_service);
    474 
    475     // Initial phase: information gathering from server
    476 
    477     switch(commandIndex) {
    478       case AddJobsIndex:
    479         controller.requestIds(ControllerInfo.server, ControllerInfo.serverport, vm["jobfiles"].as< std::vector<std::string> >().size());
    480         break;
    481       case CreateJobsIndex:
    482         controller.requestIds(ControllerInfo.server, ControllerInfo.serverport, 1);
    483         break;
    484       case CheckResultsIndex:
    485         break;
    486       case ReceiveResultsIndex:
    487         break;
    488       case ReceiveMPQCIndex:
    489         break;
    490       case RemoveAllIndex:
    491         break;
    492       case ShutdownIndex:
    493         break;
    494       case UnknownCommandIndex:
    495       default:
    496         ELOG(0, "Unrecognized command '"+toString(ControllerInfo.command)+"'.");
    497         return 255;
    498         break;
    499     }
    500 
    501     {
    502       io_service.reset();
    503       Info info("io_service: Phase One");
    504       io_service.run();
    505     }
    506 
    507     // Second phase: Building jobs and sending information to server
    508 
    509     switch(commandIndex) {
    510       case AddJobsIndex:
     539    // execute each command in the queue synchronously
     540    size_t phase = 1;
     541    while (!commands.empty()) {
     542      ControllerCommand command = commands.front();
     543      commands.pop_front();
     544      command();
    511545      {
    512         std::vector<FragmentJob::ptr> jobs;
    513         const std::string executable(vm["executable"].as< std::string >());
    514         const std::vector< std::string > jobfiles = vm["jobfiles"].as< std::vector< std::string > >();
    515         for (std::vector< std::string >::const_iterator iter = jobfiles.begin();
    516             iter != jobfiles.end(); ++iter) {
    517           const JobId_t next_id = controller.getAvailableId();
    518           const std::string &filename = *iter;
    519           LOG(1, "INFO: Creating MPQCCommandJob with filename'"
    520               +filename+"', and id "+toString(next_id)+".");
    521           parsejob(jobs, executable, filename, next_id);
    522         }
    523         controller.addJobs(jobs);
    524         controller.sendJobs(ControllerInfo.server, ControllerInfo.serverport);
    525         break;
    526       }
    527       case CreateJobsIndex:
    528       {
    529         const JobId_t next_id = controller.getAvailableId();
    530         std::vector<FragmentJob::ptr> jobs;
    531         createjobs(jobs, ControllerInfo.executable, ControllerInfo.jobcommand, next_id);
    532         controller.addJobs(jobs);
    533         controller.sendJobs(ControllerInfo.server, ControllerInfo.serverport);
    534         break;
    535       }
    536       case CheckResultsIndex:
    537         controller.checkResults(ControllerInfo.server, ControllerInfo.serverport);
    538         break;
    539       case ReceiveResultsIndex:
    540       case ReceiveMPQCIndex:
    541         controller.receiveResults(ControllerInfo.server, ControllerInfo.serverport);
    542         break;
    543       case RemoveAllIndex:
    544         controller.removeall(ControllerInfo.server, ControllerInfo.serverport);
    545         break;
    546       case ShutdownIndex:
    547         controller.shutdown(ControllerInfo.server, ControllerInfo.serverport);
    548         break;
    549       case UnknownCommandIndex:
    550       default:
    551         ELOG(0, "Unrecognized command '"+toString(ControllerInfo.command)+"'.");
    552         return 255;
    553         break;
    554     }
    555 
    556     {
    557       io_service.reset();
    558       Info info("io_service: Phase Two");
    559       io_service.run();
    560     }
    561 
    562     // Final phase: Print result of command
    563 
    564     switch(commandIndex) {
    565       case AddJobsIndex:
    566       case CreateJobsIndex:
    567         break;
    568       case CheckResultsIndex:
    569       {
    570         const std::pair<size_t, size_t> JobStatus = controller.getJobStatus();
    571         LOG(1, "INFO: #" << JobStatus.first << " are waiting in the queue and #" << JobStatus.second << " jobs are calculated so far.");
    572         break;
    573       }
    574       case ReceiveResultsIndex:
    575       {
    576         std::vector<FragmentResult::ptr> results = controller.getReceivedResults();
    577         printReceivedResults(results);
    578         break;
    579       }
    580       case ReceiveMPQCIndex:
    581       {
    582         const std::string path = vm["fragment-path"].as< std::string >();
    583         LOG(1, "INFO: Parsing fragment files from " << path << ".");
    584         std::vector<FragmentResult::ptr> results = controller.getReceivedResults();
    585         printReceivedMPQCResults(
    586             results,
    587             path,
    588             getNoAtomsFromAdjacencyFile(path));
    589         break;
    590       }
    591       case RemoveAllIndex:
    592         break;
    593       case ShutdownIndex:
    594         break;
    595       case UnknownCommandIndex:
    596       default:
    597         ELOG(0, "Unrecognized command '"+toString(ControllerInfo.command)+"'.");
    598         return 255;
    599         break;
     546        io_service.reset();
     547        Info info((std::string("io_service: ")+toString(phase)).c_str());
     548        io_service.run();
     549      }
    600550    }
    601551    Exitflag = controller.getExitflag();
Note: See TracChangeset for help on using the changeset viewer.