source: src/Fragmentation/Automation/controller.cpp@ ff60cfa

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
Last change on this file since ff60cfa was ff60cfa, checked in by Frederik Heber <heber@…>, 13 years ago

Controller has new function addjobs.

  • addjobs parses mpqc input file and creates MPQCCommandJob which is sent to send jobs
  • old sendjobs is now createjobs which creates empty SystemCommandJob.
  • added new class GlobalJobId which holds a global JobId such that FragmentJobs created by Controller each have a unique id. NOTE: This should probably be replaced by IdPool implementation when Fragmentation/Automation is integrated into rest of molecuilder.
  • dummyInit() to have MPQCCommandJob instances known to FragmentScheduler.
  • TESTFIX: Adapted regression tests Fragmentation/Automation adding-jobs, server-worker, and completerun due to command token change.
  • Property mode set to 100644
File size: 7.9 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2011 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * \file controller.cpp
10 *
11 * This file strongly follows the Serialization example from the boost::asio
12 * library (see client.cpp)
13 *
14 * Created on: Nov 27, 2011
15 * Author: heber
16 */
17
18
19// include config.h
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24// boost asio needs specific operator new
25#include <boost/asio.hpp>
26
27#include "CodePatterns/MemDebug.hpp"
28
29#include <fstream>
30#include <iostream>
31#include <map>
32#include <sstream>
33#include <streambuf>
34#include <vector>
35
36#include "atexit.hpp"
37#include "CodePatterns/Info.hpp"
38#include "CodePatterns/Log.hpp"
39#include "Controller/FragmentController.hpp"
40#include "Controller/Commands/CheckResultsOperation.hpp"
41#include "Controller/Commands/ReceiveJobsOperation.hpp"
42#include "Controller/Commands/SendResultsOperation.hpp"
43#include "Controller/Commands/ShutdownOperation.hpp"
44#include "GlobalJobId.hpp"
45#include "Jobs/MPQCCommandJob.hpp"
46#include "Jobs/SystemCommandJob.hpp"
47#include "Results/FragmentResult.hpp"
48
49enum CommandIndices {
50 UnknownCommandIndex = 0,
51 AddJobsIndex = 1,
52 CreateJobsIndex = 2,
53 CheckResultsIndex = 3,
54 ReceiveResultsIndex = 4,
55 ShutdownIndex = 5
56};
57
58// TODO: replace this instance by a IdPool owned by controller.
59GlobalJobId globalId;
60
61void createjobs(std::vector<FragmentJob::ptr> &jobs)
62{
63 FragmentJob::ptr testJob( new SystemCommandJob( std::string("cat"), std::string("Nothing"), globalId.getNextId()) );
64 FragmentJob::ptr othertestJob( new SystemCommandJob( std::string("cat"), std::string("Nothing"), globalId.getNextId()) );
65 jobs.push_back(testJob);
66 jobs.push_back(othertestJob);
67}
68
69void parsejob(std::vector<FragmentJob::ptr> &jobs, const std::string &filename)
70{
71 std::ifstream file;
72 file.open(filename.c_str());
73 ASSERT( file.good(), "parsejob() - file "+filename+" does not exist.");
74 std::string output((std::istreambuf_iterator<char>(file)),
75 std::istreambuf_iterator<char>());
76 FragmentJob::ptr testJob( new MPQCCommandJob(output, globalId.getNextId()) );
77 jobs.push_back(testJob);
78 file.close();
79 LOG(1, "INFO: Added MPQCCommandJob from file "+filename+".");
80}
81
82void addjobs(FragmentController &controller, std::vector<FragmentJob::ptr> &jobs)
83{
84 ReceiveJobsOperation *recjobs = static_cast<ReceiveJobsOperation *>(
85 controller.Commands.getByName("receivejobs"));
86 recjobs->addJobs(jobs);
87}
88
89void sendjobs(FragmentController &controller, const std::string &host, const std::string &service)
90{
91 ReceiveJobsOperation *recjobs = static_cast<ReceiveJobsOperation *>(
92 controller.Commands.getByName("receivejobs"));
93 (*recjobs)(host, service);
94}
95
96void checkresults(FragmentController &controller, const std::string &host, const std::string &service)
97{
98 CheckResultsOperation *checkres = static_cast<CheckResultsOperation *>(
99 controller.Commands.getByName("checkresults"));
100 (*checkres)(host, service);
101}
102
103void printdonejobs(FragmentController &controller)
104{
105 CheckResultsOperation *checkres = static_cast<CheckResultsOperation *>(
106 controller.Commands.getByName("checkresults"));
107 const size_t doneJobs = checkres->getDoneJobs();
108 LOG(1, "INFO: " << doneJobs << " jobs are calculated so far.");
109}
110
111void receiveresults(FragmentController &controller, const std::string &host, const std::string &service)
112{
113 SendResultsOperation *sendres = static_cast<SendResultsOperation *>(
114 controller.Commands.getByName("sendresults"));
115 (*sendres)(host, service);
116}
117
118void printreceivedresults(FragmentController &controller)
119{
120 SendResultsOperation *sendres = static_cast<SendResultsOperation *>(
121 controller.Commands.getByName("sendresults"));
122 std::vector<FragmentResult::ptr> results = sendres->getResults();
123 for (std::vector<FragmentResult::ptr>::const_iterator iter = results.begin();
124 iter != results.end(); ++iter)
125 LOG(1, "RESULT: job #"+toString((*iter)->getId())+": "+toString((*iter)->result));
126}
127
128void shutdown(FragmentController &controller, const std::string &host, const std::string &service)
129{
130 ShutdownOperation *shutdown = static_cast<ShutdownOperation *>(
131 controller.Commands.getByName("shutdown"));
132 (*shutdown)(host, service);
133}
134
135/** Returns a unique index for every command to allow switching over it.
136 *
137 * \param &commandmap map with command strings
138 * \param &cmd command string
139 * \return index from CommandIndices: UnkownCommandIndex - unknown command, else - command index
140 */
141CommandIndices getCommandIndex(std::map<std::string, CommandIndices> &commandmap, const std::string &cmd)
142{
143 std::map<std::string, CommandIndices>::const_iterator iter = commandmap.find(cmd);
144 if (iter != commandmap.end())
145 return iter->second;
146 else
147 return UnknownCommandIndex;
148}
149
150
151int main(int argc, char* argv[])
152{
153 // from this moment on, we need to be sure to deeinitialize in the correct order
154 // this is handled by the cleanup function
155 atexit(cleanUp);
156
157 setVerbosity(3);
158
159 size_t Exitflag = 0;
160 typedef std::map<std::string, CommandIndices> CommandsMap_t;
161 CommandsMap_t CommandsMap;
162 CommandsMap.insert( std::make_pair("addjobs", AddJobsIndex) );
163 CommandsMap.insert( std::make_pair("createjobs", CreateJobsIndex) );
164 CommandsMap.insert( std::make_pair("checkresults", CheckResultsIndex) );
165 CommandsMap.insert( std::make_pair("receiveresults", ReceiveResultsIndex) );
166 CommandsMap.insert( std::make_pair("shutdown", ShutdownIndex) );
167 try
168 {
169 // Check command line arguments.
170 if (argc < 4)
171 {
172 std::cerr << "Usage: " << argv[0] << " <host> <port> <command> [options to command]" << std::endl;
173 std::cerr << "List of available commands:" << std::endl;
174 for(CommandsMap_t::const_iterator iter = CommandsMap.begin();
175 iter != CommandsMap.end(); ++iter) {
176 std::cerr << "\t" << iter->first << std::endl;
177 }
178 return 1;
179 }
180
181 boost::asio::io_service io_service;
182 FragmentController controller(io_service);
183
184 switch(getCommandIndex(CommandsMap, argv[3])) {
185 case AddJobsIndex:
186 {
187 std::vector<FragmentJob::ptr> jobs;
188 if (argc == 4) {
189 ELOG(1, "Please add a filename for the MPQCCommandJob.");
190 } else {
191 for (int argcount = 4; argcount < argc; ++argcount) {
192 LOG(1, "INFO: Parsing job for file " << argv[argcount] << ".");
193 parsejob(jobs, argv[argcount]);
194 }
195 addjobs(controller, jobs);
196 sendjobs(controller, argv[1], argv[2]);
197 }
198 break;
199 }
200 case CreateJobsIndex:
201 {
202 std::vector<FragmentJob::ptr> jobs;
203 createjobs(jobs);
204 addjobs(controller, jobs);
205 sendjobs(controller, argv[1], argv[2]);
206 break;
207 }
208 case CheckResultsIndex:
209 {
210 checkresults(controller, argv[1], argv[2]);
211 break;
212 }
213 case ReceiveResultsIndex:
214 {
215 receiveresults(controller, argv[1], argv[2]);
216 break;
217 }
218 case ShutdownIndex:
219 {
220 shutdown(controller, argv[1], argv[2]);
221 break;
222 }
223 case UnknownCommandIndex:
224 default:
225 ELOG(0, "Unrecognized command '"+toString(argv[3])+"'.");
226 break;
227 }
228
229 {
230 Info info("io_service");
231 io_service.run();
232 }
233
234 switch(getCommandIndex(CommandsMap, argv[3])) {
235 case AddJobsIndex:
236 case CreateJobsIndex:
237 break;
238 case CheckResultsIndex:
239 {
240 printdonejobs(controller);
241 break;
242 }
243 case ReceiveResultsIndex:
244 {
245 printreceivedresults(controller);
246 break;
247 }
248 case ShutdownIndex:
249 break;
250 case UnknownCommandIndex:
251 default:
252 ELOG(0, "Unrecognized command '"+toString(argv[3])+"'.");
253 break;
254 }
255 Exitflag = controller.getExitflag();
256 }
257 catch (std::exception& e)
258 {
259 std::cerr << e.what() << std::endl;
260 }
261
262 return Exitflag;
263}
Note: See TracBrowser for help on using the repository browser.