Rosetta 3.5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
WorkUnitManager.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/loops/LoopHashMap.cc
11 /// @brief
12 /// @author Mike Tyka
13 
14 // MPI headers
15 #ifdef USEMPI
16 #include <mpi.h> //keep this first
17 #endif
18 
21 
22 // AUTO-REMOVED #include <core/chemical/ChemicalManager.hh>
23 // AUTO-REMOVED #include <core/chemical/ResidueTypeSet.hh>
24 
25 // AUTO-REMOVED #include <core/import_pose/pose_stream/MetaPoseInputStream.hh>
26 // AUTO-REMOVED #include <core/import_pose/pose_stream/util.hh>
27 // AUTO-REMOVED #include <core/io/silent/SilentFileData.hh>
28 // AUTO-REMOVED #include <core/io/silent/SilentStructFactory.hh>
30 // AUTO-REMOVED #include <basic/options/keys/in.OptionKeys.gen.hh>
31 // AUTO-REMOVED #include <basic/options/keys/out.OptionKeys.gen.hh>
32 // AUTO-REMOVED #include <basic/options/option.hh>
33 // AUTO-REMOVED #include <core/pose/Pose.hh>
34 // AUTO-REMOVED #include <core/scoring/ScoreFunctionFactory.hh>
35 // AUTO-REMOVED #include <core/scoring/ScoreFunction.hh>
36 #include <basic/Tracer.hh>
38 #include <utility/assert.hh>
39 // AUTO-REMOVED #include <ios>
40 #include <iostream>
41 #include <fstream>
42 
43 //Auto Headers
44 #include <utility/vector1.hh>
45 #include <boost/function.hpp>
46 
47 
48 namespace protocols {
49 namespace wum {
50 
51 static basic::Tracer TR("WorkUnitManager");
52 
53 // 32 bit recognition integer to make sure we're infact about to read/write a WU to disk etc..
54 const unsigned int WUB_magic_header_integer = 0xAF34B14C;
55 
56 
57 
58 
59 
62 {
63  return *(wus_.begin());
64 }
65 
68 {
69  runtime_assert( size() != 0 );
70  WorkUnitBaseOP tmp = next();
71  wus_.pop_front();
72  return tmp;
73 }
74 
76  return wus_.erase( i );
77 }
78 
79 
81 {
82  runtime_assert( n_swap_total_ >= n_swap_dead_ );
83 
84  // if either we have to many structures in memory OR we have a running file swap already,
85  // add to swap pile, not to in-memory pile
86  if( ( wus_.size() > memory_limit_) ||
87  ( (n_swap_total_ - n_swap_dead_ ) > 0 ) ){
88  add_to_swap( new_wu );
89  } else {
90  // or call normal parent version
91  WorkUnitQueue::add( new_wu );
92  }
93 }
94 
95 
96 
98  swap_buffer_.add( new_wu );
99 
101  // drain buffer to disk swap
102  std::ofstream ofout( swap_file_.c_str() , std::ios::app | std::ios::binary );
103  wum_->write_queue( swap_buffer_, ofout );
104  ofout.close();
105 
106  // now empty the buffer, ready to take the next bunch of structures
108  }
109 
110 }
111 
112 
113 
114 
116  work_unit_list_.merge( work_unit_list );
117 }
118 
119 
121  std::ofstream ofout( std::string(prefix + ".outbound.queue").c_str() , std::ios::binary );
122  write_queue( outbound() , ofout );
123  ofout.close();
124  std::ofstream ofin( std::string(prefix + ".inbound.queue").c_str() , std::ios::binary );
125  write_queue( inbound() , ofin );
126  ofin.close();
127 }
128 
130  std::ifstream ifout( std::string(prefix + ".outbound.queue").c_str() , std::ios::binary );
131  TR << "Reading outbound queue..." << std::string(prefix + ".outbound.queue") << std::endl;
132  read_queue( outbound() , ifout );
133  ifout.close();
134  std::ifstream ifin( std::string(prefix + ".inbound.queue").c_str() , std::ios::binary );
135  TR << "Reading inbound queue..." << std::string(prefix + ".inbound.queue") << std::endl;
136  read_queue( inbound() , ifin );
137  ifin.close();
138 }
139 
140 
141 void WorkUnitManager::read_queue( WorkUnitQueue &the_queue, std::istream &fin ){
142  core::Size count=0;
143  while( !fin.eof() ){
144  TR.Debug << "Read: " << count << std::endl;
145  WorkUnitBaseOP new_wu;
146  if( !read_work_unit( new_wu, fin ) ) break;
147  the_queue.push_back( new_wu );
148  count++;
149  }
150 }
151 
152 
153 void WorkUnitManager::write_queue( const WorkUnitQueue &the_queue, std::ostream &out ) const {
154  for( WorkUnitQueue::const_iterator it = the_queue.begin();
155  it != the_queue.end(); ++it )
156  {
157  write_work_unit( *it, out );
158  }
159 }
160 
161 
162 
163 void WorkUnitManager::write_work_unit( const WorkUnitBaseOP& MPI_ONLY(wu), std::ostream& MPI_ONLY( out ) ) const {
164  #ifdef USEMPI
165  // serialize data
166  double time1=MPI_Wtime();
167  wu->serialize();
168  double time2=MPI_Wtime();
169  // now send data
170  int size_of_raw_data;
171  unsigned char * raw_data_ptr=NULL;
172  size_of_raw_data = wu->raw_data_dump( &raw_data_ptr );
173  TR.Debug << "Writing workunit .. " << std::endl;
174  out.write( (char*) &WUB_magic_header_integer, 4 );
175  out.write( (char*) &size_of_raw_data, 4 );
176  out.write( (char*)raw_data_ptr, size_of_raw_data );
177  TR.Debug << " Wrote data.. " << std::endl;
178  delete [] raw_data_ptr;
179  TR.Debug << " Deleted temp data.. " << std::endl;
180  wu->clear_serial_data();
181  double time3=MPI_Wtime();
182  TR.Debug << "S: " << time3-time2 << " " << time2-time1 << " " << std::endl;
183  #endif
184 }
185 
186 
187 bool WorkUnitManager::read_work_unit( WorkUnitBaseOP &qualified_wu, std::istream &in ){
188  unsigned int size_of_raw_data=0;
189  unsigned char * raw_data_ptr=NULL;
190  TR.Debug << "Reading a workunit..." << std::endl;
191 
192  unsigned int my_WUB_magic_header_integer=0;
193  // Read magic 32 bit int
194  in.read( (char*) &my_WUB_magic_header_integer, 4 );
195  if( in.eof() ){
196  TR.Debug << "EOF" << std::endl;
197  return false;
198  }
199  if(my_WUB_magic_header_integer != WUB_magic_header_integer){
200  TR.Error << "Magic Integer in file: " << my_WUB_magic_header_integer << " != " << WUB_magic_header_integer << std::endl;
201  TR.Error << "ERROR Reading in WorkUnit from stream - Magic integer does not match. " << std::endl;
202  std::cerr << "Magic Integer in file: " << my_WUB_magic_header_integer << " != " << WUB_magic_header_integer << std::endl;
203  utility_exit_with_message( "ERROR Reading in WorkUnit from stream - Magic integer does not match. " );
204  }
205 
206  in.read( (char*)&size_of_raw_data, 4 );
207  if( size_of_raw_data > (1024*1024*1024) ){
208  TR.Error << " Data corruption ? WorkUnitManager::read_work_unit found workunit with memory requirement > 1GB " << std::endl;
209  }
210 
211  TR.Debug << " READ WU: BLOCKSIZE: " << size_of_raw_data << std::endl;
212  raw_data_ptr = new unsigned char [size_of_raw_data];
213 
214  in.read( (char*)raw_data_ptr, (std::streamsize) size_of_raw_data );
215 
216  if( raw_data_ptr[size_of_raw_data-1] != 0){
217  utility_exit_with_message( " ERROR: cannot load data - terminal zero not found!" );
218  return false;
219  }
220  raw_data_ptr[size_of_raw_data-1] = 0;
221  TR.Debug << " READ WU: Data: " << std::endl;
222 
223  WorkUnitBaseOP wu = new WorkUnitBase;
224  runtime_assert( wu );
225  wu->raw_data_load( raw_data_ptr, size_of_raw_data );
226  delete [] raw_data_ptr;
227 
228  // Here at this point we have a WorkUnitBaseOP to a workUnitBase.
229  // Now we need to interpret the id field and upcast or somehow otherwise
230  // create the right type of work unit such that the polymorphic code
231  // for the interpretation of the serial data can take place.
232 
233  qualified_wu = work_unit_list().get_work_unit( *wu )->clone();
234  runtime_assert( qualified_wu );
235  // cope over data (the header and the serial data)
236  (*qualified_wu) = (*wu);
237 
238  TR.Debug << " Received: " << std::endl;
239  if( TR.Debug.visible() ) qualified_wu->print( TR );
240 
241  qualified_wu->deserialize( );
242  qualified_wu->clear_serial_data();
243 
244  TR.Debug << "DONE Receiving" << std::endl;
245  return true;
246 }
247 
248 
251  core::Size n_structs;
252  core::Size structs_memory;
253  core::Size WU_memory;
254  mem_stats( n_structs, structs_memory, WU_memory);
255  return WU_memory + structs_memory;
256 }
257 
258 void
260  core::Size &n_structs,
261  core::Size &structs_memory,
262  core::Size &WU_memory
263 ) const {
264  n_structs=0;
265  structs_memory=0;
266  WU_memory=0;
267 
268  for( const_iterator it = begin(); it != end(); it++ ){
269  WU_memory += (*it)->mem_footprint();
270  WorkUnitBaseOP wu_op = *it;
271  WorkUnit_SilentStructStoreOP structure_wu = dynamic_cast< WorkUnit_SilentStructStore * > ( wu_op() );
272  if ( structure_wu.get() == NULL ) continue;
273  SilentStructStore &decoys = structure_wu->decoys();
274  n_structs += structure_wu->decoys().size();
275  for( SilentStructStore::iterator jt = decoys.begin();
276  jt != decoys.end(); jt ++ )
277  {
278  structs_memory += (*jt)->mem_footprint();
279  }
280  }
281 
282 
283 }
284 
285 
286 
287 }
288 }
289