Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MPI_WorkUnitManager_Slave.cc
Go to the documentation of this file.
1 // -*- mode:c++;tab-width:2;indent-tabs-mode:t;show-trailing-whitespace:t;rm-trailing-spaces:t -*-
2 // vi: set ts=2 noet:
3 //
4 // (c) Copyright Rosetta Commons Member Institutions.
5 // (c) This file is part of the Rosetta software suite and is made available under license.
6 // (c) The Rosetta software is developed by the contributing members of the Rosetta Commons.
7 // (c) For more information, see http://www.rosettacommons.org. Questions about this can be
8 // (c) addressed to University of Washington UW TechTransfer, email: license@u.washington.edu.
9 
10 /// @file protocols/wum/MPI_WorkUnitManager_Slave.cc
11 /// @brief
12 /// @author Mike Tyka
13 
14 #define TRDEBUG TR.Debug
15 
16 // MPI headers
17 #ifdef USEMPI
18 #include <mpi.h> //keep this first
19 #endif
20 
21 // AUTO-REMOVED #include <utility/assert.hh> //MPI_ONLY macro
22 
27 // AUTO-REMOVED #include <core/io/silent/SilentFileData.hh>
28 // AUTO-REMOVED #include <core/io/silent/SilentStructFactory.hh>
29 // AUTO-REMOVED #include <core/scoring/ScoreFunctionFactory.hh>
30 // AUTO-REMOVED #include <core/scoring/ScoreFunction.hh>
31 // AUTO-REMOVED #include <core/chemical/ResidueTypeSet.hh>
32 
33 // AUTO-REMOVED #include <core/chemical/ChemicalManager.hh>
34 #include <basic/Tracer.hh>
35 // AUTO-REMOVED #include <core/pose/Pose.hh>
36 // AUTO-REMOVED #include <core/import_pose/pose_stream/util.hh>
37 
38 /// ObjexxFCL headers
39 // AUTO-REMOVED #include <numeric/random/random.hh>
40 #include <ObjexxFCL/string.functions.hh>
41 #include <ObjexxFCL/format.hh>
42 
43 #include <utility/vector1.hh>
44 
45 
46 
47 #if defined(WIN32) || defined(__CYGWIN__)
48  #include <ctime>
49 #endif
50 
51 using namespace ObjexxFCL::fmt;
52 
53 namespace protocols {
54 namespace wum {
55 
56 static basic::Tracer TR("MPI_WUM_Slave");
57 
58 
59 MPI_WorkUnitManager_Slave::MPI_WorkUnitManager_Slave( core::Size my_master ):
60  MPI_WorkUnitManager( 'S' ), // this is the one-letter identifier used in printing statistics
61  my_master_( my_master )
62 {
63 
64 
65 }
66 
67 
68 void
70 {
71  TR << "Init Slave: " << mpi_rank() << std::endl;
72  init();
73 
74  do {
75  TRDEBUG << "Requesting new jobs.." << std::endl;
77 
78  TRDEBUG << "Slave: Waiting for and processing incoming messages... " << std::endl;
79  process_incoming_msgs( true );
80 
81  TRDEBUG << "Running jobs" << std::endl;
83 
84  TRDEBUG << "Slave: Processing outbound queue..." << std::endl;
86 
88  } while ( true );
89 
91 }
92 
93 /// @brief Process workunits on the slave node. I.e. Execute the WU jobs.
94 void
96 {
98  // for every workunit on the stack send execute it and transfer it to the outbound queue
99  while( inbound().size() > 0 ){
100  // run the WU
101  runtime_assert( inbound().next() );
102  TRDEBUG << "Slave: " << mpi_rank() << " running WU..." << std::endl;
103 
104  // special rule for wait workunit. Basically count execution of a wait workunit as
105  // IDLING and that of every other one as CPU time
106  if( inbound().next()->get_wu_type() == "waitwu") start_timer( TIMING_IDLE );
107 
108  inbound().next()->set_run_start(); // record starting time of run for stat analysis
109  inbound().next()->run(); // execute the workunit - i.e. do the work
110  inbound().next()->set_run_stop(); // stop the timer just set up above
111 
112  start_timer( TIMING_CPU ); // Now we're definitely back in CPU mode
113 
114  // Transfer results to the outbound queue
115  TRDEBUG << "Slave: " << mpi_rank() << " transferring WU..." << std::endl;
116  outbound().add( inbound().next() );
117  inbound().pop_next();
118  }
119 }
120 
121 
122 void
124 {
125  // For each item in the outbound queue, send the WorkUnit back to who ever sent it
126  while( outbound().size() > 0 ){
127  send_MPI_workunit( outbound().next(), (int)outbound().next()->last_received_from() );
128  // ERROR behaviour here ?
129  outbound().pop_next(); // This clears the WU just sent from the stack
130  }
131 }
132 
133 
134 void
136 {
137 #ifdef USEMPI
138  unsigned int data;
139 
140  // The first blocking send will only return when the master has recevied the data. Since the data transfer is negligible,
141  // We'll count that as waiting time, not sending time
143  TR.Trace << "Requesting new job.." << std::endl;
144  core::Size dest_rank = get_my_master();
145  runtime_assert( (int)dest_rank != mpi_rank() ); // no self-sending
146  MPI_Send( &data, 1, MPI_UNSIGNED, dest_rank, WUM_MPI_REQUEST_WU, MPI_COMM_WORLD );
148 #endif
149 }
150 
151 
152 
153 
154 } // namespace wum
155 } // namespace protocols
156 
157 
158 
159