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

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 509014 was 554809, checked in by Frederik Heber <heber@…>, 13 years ago

createjobs now gets two options: command, argument.

  • Property mode set to 100644
File size: 12.0 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/GetNextJobIdOperation.hpp"
42#include "Controller/Commands/ReceiveJobsOperation.hpp"
43#include "Controller/Commands/SendResultsOperation.hpp"
44#include "Controller/Commands/ShutdownOperation.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/** Requests an available id from server
59 *
60 * @param controller FragmentController with CommandRegistry
61 * @param host address of server
62 * @param service port/service of server
63 */
64void requestid(
65 FragmentController &controller,
66 const std::string &host,
67 const std::string &service)
68{
69 GetNextJobIdOperation *getnextid = static_cast<GetNextJobIdOperation *>(
70 controller.Commands.getByName("getnextjobid"));
71 (*getnextid)(host,service);
72}
73
74/** Returns another available id from a finished GetNextJobIdOperation.
75 *
76 * @param controller FragmentController with CommandRegistry
77 * @return next available id
78 */
79JobId_t getavailableid(FragmentController &controller)
80{
81 GetNextJobIdOperation *getnextid = static_cast<GetNextJobIdOperation *>(
82 controller.Commands.getByName("getnextjobid"));
83 const JobId_t nextid = getnextid->getNextId();
84 LOG(1, "INFO: Next available id is " << nextid << ".");
85 return nextid;
86}
87
88void createjobs(
89 std::vector<FragmentJob::ptr> &jobs,
90 const std::string &command,
91 const std::string &argument,
92 const JobId_t nextid)
93{
94 FragmentJob::ptr testJob( new SystemCommandJob(command, argument, nextid) );
95 jobs.push_back(testJob);
96 LOG(1, "INFO: Added one SystemCommandJob.");
97}
98
99/** Creates a MPQCCommandJob with argument \a filename.
100 *
101 * @param jobs created job is added to this vector
102 * @param filename filename being argument to job
103 * @param nextid id for this job
104 */
105void parsejob(
106 std::vector<FragmentJob::ptr> &jobs,
107 const std::string &filename,
108 const JobId_t nextid)
109{
110 std::ifstream file;
111 file.open(filename.c_str());
112 ASSERT( file.good(), "parsejob() - file "+filename+" does not exist.");
113 std::string output((std::istreambuf_iterator<char>(file)),
114 std::istreambuf_iterator<char>());
115 FragmentJob::ptr testJob( new MPQCCommandJob(output, nextid) );
116 jobs.push_back(testJob);
117 file.close();
118 LOG(1, "INFO: Added MPQCCommandJob from file "+filename+".");
119}
120
121/** Adds a vector of jobs to the send operation.
122 *
123 * @param controller FragmentController with CommandRegistry
124 * @param jobs jobs to add
125 */
126void addjobs(
127 FragmentController &controller,
128 std::vector<FragmentJob::ptr> &jobs)
129{
130 ReceiveJobsOperation *recjobs = static_cast<ReceiveJobsOperation *>(
131 controller.Commands.getByName("receivejobs"));
132 recjobs->addJobs(jobs);
133}
134
135/** Sends contained jobs in operation to server
136 *
137 * @param controller FragmentController with CommandRegistry
138 * @param host address of server
139 * @param service port/service of server
140 */
141void sendjobs(
142 FragmentController &controller,
143 const std::string &host,
144 const std::string &service)
145{
146 ReceiveJobsOperation *recjobs = static_cast<ReceiveJobsOperation *>(
147 controller.Commands.getByName("receivejobs"));
148 (*recjobs)(host, service);
149}
150
151/** Obtains scheduled and done jobs from server
152 *
153 * @param controller FragmentController with CommandRegistry
154 * @param host address of server
155 * @param service port/service of server
156 */
157void checkresults(
158 FragmentController &controller,
159 const std::string &host,
160 const std::string &service)
161{
162 CheckResultsOperation *checkres = static_cast<CheckResultsOperation *>(
163 controller.Commands.getByName("checkresults"));
164 (*checkres)(host, service);
165}
166
167/** Prints scheduled and done jobs.
168 *
169 * @param controller FragmentController with CommandRegistry
170 */
171void printdonejobs(FragmentController &controller)
172{
173 CheckResultsOperation *checkres = static_cast<CheckResultsOperation *>(
174 controller.Commands.getByName("checkresults"));
175 const size_t doneJobs = checkres->getDoneJobs();
176 const size_t presentJobs = checkres->getPresentJobs();
177 LOG(1, "INFO: #" << presentJobs << " are waiting in the queue and #" << doneJobs << " jobs are calculated so far.");
178}
179
180/** Obtains results from done jobs from server.
181 *
182 * @param controller FragmentController with CommandRegistry
183 * @param host address of server
184 * @param service port/service of server
185 */
186void receiveresults(
187 FragmentController &controller,
188 const std::string &host,
189 const std::string &service)
190{
191 SendResultsOperation *sendres = static_cast<SendResultsOperation *>(
192 controller.Commands.getByName("sendresults"));
193 (*sendres)(host, service);
194}
195
196/** Print received results.
197 *
198 * @param controller FragmentController with CommandRegistry
199 */
200void printreceivedresults(FragmentController &controller)
201{
202 SendResultsOperation *sendres = static_cast<SendResultsOperation *>(
203 controller.Commands.getByName("sendresults"));
204 std::vector<FragmentResult::ptr> results = sendres->getResults();
205 for (std::vector<FragmentResult::ptr>::const_iterator iter = results.begin();
206 iter != results.end(); ++iter)
207 LOG(1, "RESULT: job #"+toString((*iter)->getId())+": "+toString((*iter)->result));
208}
209
210/** Sends shutdown signal to server
211 *
212 * @param controller FragmentController with CommandRegistry
213 * @param host address of server
214 * @param service port/service of server
215 */
216void shutdown(
217 FragmentController &controller,
218 const std::string &host,
219 const std::string &service)
220{
221 ShutdownOperation *shutdown = static_cast<ShutdownOperation *>(
222 controller.Commands.getByName("shutdown"));
223 (*shutdown)(host, service);
224}
225
226/** Returns a unique index for every command to allow switching over it.
227 *
228 * \param &commandmap map with command strings
229 * \param &cmd command string
230 * \return index from CommandIndices: UnkownCommandIndex - unknown command, else - command index
231 */
232CommandIndices getCommandIndex(std::map<std::string, CommandIndices> &commandmap, const std::string &cmd)
233{
234 std::map<std::string, CommandIndices>::const_iterator iter = commandmap.find(cmd);
235 if (iter != commandmap.end())
236 return iter->second;
237 else
238 return UnknownCommandIndex;
239}
240
241
242int main(int argc, char* argv[])
243{
244 // from this moment on, we need to be sure to deeinitialize in the correct order
245 // this is handled by the cleanup function
246 atexit(cleanUp);
247
248 setVerbosity(3);
249
250 size_t Exitflag = 0;
251 typedef std::map<std::string, CommandIndices> CommandsMap_t;
252 CommandsMap_t CommandsMap;
253 CommandsMap.insert( std::make_pair("addjobs", AddJobsIndex) );
254 CommandsMap.insert( std::make_pair("createjobs", CreateJobsIndex) );
255 CommandsMap.insert( std::make_pair("checkresults", CheckResultsIndex) );
256 CommandsMap.insert( std::make_pair("receiveresults", ReceiveResultsIndex) );
257 CommandsMap.insert( std::make_pair("shutdown", ShutdownIndex) );
258 try
259 {
260 // Check command line arguments.
261 if (argc < 4)
262 {
263 std::cerr << "Usage: " << argv[0] << " <host> <port> <command> [options to command]" << std::endl;
264 std::cerr << "List of available commands:" << std::endl;
265 for(CommandsMap_t::const_iterator iter = CommandsMap.begin();
266 iter != CommandsMap.end(); ++iter) {
267 std::cerr << "\t" << iter->first << std::endl;
268 }
269 return 1;
270 }
271
272 boost::asio::io_service io_service;
273 FragmentController controller(io_service);
274
275 // Initial phase: information gathering from server
276
277 switch(getCommandIndex(CommandsMap, argv[3])) {
278 case AddJobsIndex:
279 {
280 if (argc < 5) {
281 ELOG(1, "Please add a filename for the MPQCCommandJob.");
282 } else {
283 // get an id for every filename
284 for (int argcount = 4; argcount < argc; ++argcount) {
285 requestid(controller, argv[1], argv[2]);
286 }
287 }
288 break;
289 }
290 case CreateJobsIndex:
291 {
292 std::vector<FragmentJob::ptr> jobs;
293 if (argc < 6) {
294 ELOG(1, "'createjobs' requires two options: [command] [argument].");
295 } else {
296 requestid(controller, argv[1], argv[2]);
297 }
298 break;
299 }
300 case CheckResultsIndex:
301 break;
302 case ReceiveResultsIndex:
303 break;
304 case ShutdownIndex:
305 break;
306 case UnknownCommandIndex:
307 default:
308 ELOG(1, "Unrecognized command '"+toString(argv[3])+"'.");
309 break;
310 }
311
312 {
313 io_service.reset();
314 Info info("io_service: Phase One");
315 io_service.run();
316 }
317
318 // Second phase: Building jobs and sending information to server
319
320 switch(getCommandIndex(CommandsMap, argv[3])) {
321 case AddJobsIndex:
322 {
323 std::vector<FragmentJob::ptr> jobs;
324 if (argc < 5) {
325 ELOG(1, "Please add a filename for the MPQCCommandJob.");
326 } else {
327 for (int argcount = 4; argcount < argc; ++argcount) {
328 const JobId_t next_id = getavailableid(controller);
329 const std::string filename(argv[argcount]);
330 LOG(1, "INFO: Creating MPQCCommandJob with filename'"
331 +filename+"', and id "+toString(next_id)+".");
332 parsejob(jobs, filename, next_id);
333 }
334 addjobs(controller, jobs);
335 sendjobs(controller, argv[1], argv[2]);
336 }
337 break;
338 }
339 case CreateJobsIndex:
340 {
341 std::vector<FragmentJob::ptr> jobs;
342 if (argc < 6) {
343 ELOG(1, "'createjobs' requires two options: [command] [argument].");
344 } else {
345 const JobId_t next_id = getavailableid(controller);
346 const std::string command(argv[4]);
347 const std::string argument(argv[5]);
348 LOG(1, "INFO: Creating SystemCommandJob with command '"
349 +command+"', argument '"+argument+"', and id "+toString(next_id)+".");
350 createjobs(jobs, command, argument, next_id);
351 }
352 addjobs(controller, jobs);
353 sendjobs(controller, argv[1], argv[2]);
354 break;
355 }
356 case CheckResultsIndex:
357 {
358 checkresults(controller, argv[1], argv[2]);
359 break;
360 }
361 case ReceiveResultsIndex:
362 {
363 receiveresults(controller, argv[1], argv[2]);
364 break;
365 }
366 case ShutdownIndex:
367 {
368 shutdown(controller, argv[1], argv[2]);
369 break;
370 }
371 case UnknownCommandIndex:
372 default:
373 ELOG(0, "Unrecognized command '"+toString(argv[3])+"'.");
374 break;
375 }
376
377 {
378 io_service.reset();
379 Info info("io_service: Phase Two");
380 io_service.run();
381 }
382
383 // Final phase: Print result of command
384
385 switch(getCommandIndex(CommandsMap, argv[3])) {
386 case AddJobsIndex:
387 case CreateJobsIndex:
388 break;
389 case CheckResultsIndex:
390 {
391 printdonejobs(controller);
392 break;
393 }
394 case ReceiveResultsIndex:
395 {
396 printreceivedresults(controller);
397 break;
398 }
399 case ShutdownIndex:
400 break;
401 case UnknownCommandIndex:
402 default:
403 ELOG(0, "Unrecognized command '"+toString(argv[3])+"'.");
404 break;
405 }
406 Exitflag = controller.getExitflag();
407 }
408 catch (std::exception& e)
409 {
410 std::cerr << e.what() << std::endl;
411 }
412
413 return Exitflag;
414}
Note: See TracBrowser for help on using the repository browser.