15 #include <utility/io/izstream.hh>
17 #include <basic/Tracer.hh>
24 #include <basic/options/option.hh>
37 #include <numeric/random/random.hh>
38 #include <numeric/numeric.functions.hh>
40 #include <utility/exit.hh>
41 #include <utility/file/file_sys_util.hh>
42 #include <utility/file/FileName.hh>
43 #include <utility/io/ozstream.hh>
44 #include <utility/vector1.hh>
45 #include <utility/pointer/ReferenceCount.hh>
47 #include <utility/string_util.hh>
51 #include <ObjexxFCL/string.functions.hh>
61 #include <basic/options/keys/out.OptionKeys.gen.hh>
62 #include <basic/options/keys/run.OptionKeys.gen.hh>
65 #include <numeric/random/random.fwd.hh>
74 overwrite_( basic::options::option[ basic::options::OptionKeys::out::overwrite ] ),
87 ignorefinished_( false ),
96 overwrite_( src.overwrite_ ),
98 current_job_( src.current_job_ ),
99 current_nstruct_( src.current_nstruct_ ),
100 is_started_( src.is_started_ ),
101 nproc_( src.nproc_ ),
102 proc_id_( src.proc_id_ ),
103 curr_jobid_( src.curr_jobid_ ),
105 mpi_rank_( src.mpi_rank_ ),
106 mpi_nprocs_( src.mpi_nprocs_ ),
109 ignorefinished_( src.ignorefinished_ ),
110 nooutput_( src.nooutput_ ),
111 inprogress_( src.inprogress_ ),
112 start_time_( src.start_time_ ),
113 random_counter_( src.random_counter_ ),
114 random_store_( src.random_store_ )
123 basic::Error() <<
"Must call shutdown() when finished using job distributor!" << std::endl;
133 JobDistributorTracer <<
"Node: " << mpi_rank_ <<
" next_job()" << std::endl;
137 if( ( basic::options::option[ basic::options::OptionKeys::run::maxruntime ].user() ) &&
138 ( basic::options::option[ basic::options::OptionKeys::run::maxruntime ]() > 0 ) &&
139 ( basic::options::option[ basic::options::OptionKeys::run::maxruntime ]() < elapsedtime ) )
141 std::cerr <<
"JobTerminated because runtime of " << elapsedtime <<
" s exceeded maxruntime of " << basic::options::option[ basic::options::OptionKeys::run::maxruntime ]() <<
" s " << std::endl;
147 basic::Error() <<
"Must call startup() before using job distributor!" << std::endl;
153 master_node_distribute_jobs();
156 bool const job_recieved = request_job_from_master_node();
157 if ( job_recieved ) {
164 #else // one machine, Condor cluster, or BOINC
166 if ( ! job_found )
return job_found;
175 #endif // BOINC vs MPI vs etc
186 bool shuffle_mode = basic::options::option[ basic::options::OptionKeys::run::shuffle ].user() ;
199 if( (
int)
curr_jobid_ >= (
int)basic::options::option[ basic::options::OptionKeys::out::nstruct]() )
return false;
206 JobDistributorTracer <<
"Looking for an available job: "
215 if( shuffle_mode && processed ){
break; }
216 if ( !processed && !skipped ) {
233 #ifdef AN_UNDEFINED_MACRO // never define this! replacing #if 0 for code parsing purposes
236 JobDistributorTracer <<
"Looking for an available job: " << current_nstruct_ <<
" " << current_job_ <<
" " << curr_jobid_ << std::endl;
242 if( current_job_ > jobs_.size() )
return false;
243 if( current_nstruct_ > jobs_[ current_job_ ]->nstruct() ) {
244 current_nstruct_ = 1;
248 if( current_job_ > jobs_.size() )
return false;
249 if( !overwrite_ && is_finished( jobs_[ current_job_ ], current_nstruct_ ) ) {
250 current_nstruct_ += 1;
254 if ( nproc_ && numeric::mod( curr_jobid_, nproc_ ) != ( proc_id_ - 1 ) ) {
255 current_nstruct_ += 1;
266 void BaseJobDistributor::startup()
269 basic::Error() <<
"Distributor already started, don't call startup() again!" << std::endl;
275 runtime_assert( MPI_has_been_initialized() );
276 MPI_Comm_rank (MPI_COMM_WORLD, &mpi_rank_);
277 MPI_Comm_size (MPI_COMM_WORLD, &mpi_nprocs_);
290 void BaseJobDistributor::shutdown()
293 basic::Error() <<
"Distributor not started or already stopped, don't call shutdown() again!" << std::endl;
300 JobDistributorTracer <<
"Node " << mpi_rank_ <<
" -- ready to call mpi finalize" << std::endl;
302 MPI_Barrier( MPI_COMM_WORLD );
307 bool shuffle_mode = basic::options::option[ basic::options::OptionKeys::run::shuffle ].user() ;
321 void BaseJobDistributor::begin_critical_section()
324 boinc_begin_critical_section();
331 void BaseJobDistributor::end_critical_section()
334 boinc_end_critical_section();
354 void BaseJobDistributor::score_map( std::map < std::string, core::Real > & )
359 return current_job()->output_tag( current_nstruct() );
363 return "STUBBED_IN_BASEJOBDISTRIBUTOR";
367 void BaseJobDistributor::checkpoint_read()
369 begin_critical_section();
372 utility::io::izstream izs(
"rng.state.gz");
373 numeric::random::RandomGenerator::restoreAllStates(izs);
377 end_critical_section();
384 void BaseJobDistributor::checkpoint_write()
386 begin_critical_section();
387 static time_t last_chkpt_time = time(NULL);
388 time_t time_now = time(NULL);
391 if( time_now - last_chkpt_time > 60 ) {
394 utility::io::ozstream ozs(
"rng.state.gz");
395 numeric::random::RandomGenerator::saveAllStates(ozs);
399 last_chkpt_time = time_now;
401 end_critical_section();
405 void BaseJobDistributor::checkpoint_clear()
409 utility::file::file_delete(
"rng.state.gz");
420 bool BaseJobDistributor::MPI_has_been_initialized()
const {
421 int already_initialized = 0;
422 MPI_Initialized( & already_initialized );
423 return already_initialized != 0;
429 runtime_assert( is_started_ );
435 int BaseJobDistributor::mpi_nprocs()
const {
436 runtime_assert( is_started_ );
440 void BaseJobDistributor::master_node_distribute_jobs()
450 int node_requesting_job( 0 );
452 JobDistributorTracer <<
"Master Node -- Waiting for job request; tag_ = " << tag_ << std::endl;
453 MPI_Recv( & node_requesting_job, 1, MPI_INT,
MPI_ANY_SOURCE, tag_, MPI_COMM_WORLD, & stat_ );
454 bool const available_job_found = find_available_job();
456 JobDistributorTracer <<
"Master Node --available job? " << available_job_found << std::endl;
458 Size job_index = ( available_job_found ? current_job_ : 0 );
459 int struct_n = ( available_job_found ? current_nstruct_ : 0 );
460 if ( ! available_job_found ) {
461 JobDistributorTracer <<
"Master Node -- Spinning down node " << node_requesting_job << std::endl;
462 MPI_Send( & job_index, 1, MPI_UNSIGNED_LONG, node_requesting_job, tag_, MPI_COMM_WORLD );
465 JobDistributorTracer <<
"Master Node -- Assigning job " << job_index <<
" " << struct_n <<
" to node " << node_requesting_job << std::endl;
466 MPI_Send( & job_index, 1, MPI_UNSIGNED_LONG, node_requesting_job, tag_, MPI_COMM_WORLD );
467 MPI_Send( & struct_n, 1, MPI_INT, node_requesting_job, tag_, MPI_COMM_WORLD );
474 Size nodes_left_to_spin_down( mpi_nprocs() - 1 - 1);
476 while ( nodes_left_to_spin_down > 0 ) {
477 int node_requesting_job( 0 );
478 int recieve_from_any( MPI::ANY_SOURCE );
479 MPI_Recv( & node_requesting_job, 1, MPI_INT, recieve_from_any, tag_, MPI_COMM_WORLD, & stat_ );
481 MPI_Send( & job_index, 1, MPI_UNSIGNED_LONG, node_requesting_job, tag_, MPI_COMM_WORLD );
482 JobDistributorTracer <<
"Master Node -- Spinning down node " << node_requesting_job <<
" with " << nodes_left_to_spin_down <<
" remaining nodes." << std::endl;
483 --nodes_left_to_spin_down;
488 bool BaseJobDistributor::request_job_from_master_node()
490 JobDistributorTracer <<
"Slave Node " << mpi_rank_ <<
" -- requesting job from master node; tag_ " << tag_ << std::endl;
493 MPI_Send( & mpi_rank_, 1, MPI_INT, 0, tag_, MPI_COMM_WORLD );
496 MPI_Recv( & current_job_, 1, MPI_UNSIGNED_LONG, 0, tag_, MPI_COMM_WORLD, & stat_ );
500 if ( current_job_ == 0 )
return false;
502 MPI_Recv( & current_nstruct_, 1, MPI_INT, 0, tag_, MPI_COMM_WORLD, & stat_ );
503 runtime_assert( current_nstruct_ != 0 );
508 int BaseJobDistributor::get_next_random_range(
int low,
int high)
511 if ( random_store_.size() == 0 ){
512 for (
int k = 0; k < 1000; k ++ ){
513 random_store_.push_back( numeric::random::uniform() );
518 if( random_counter_ > 1000 ) random_counter_ = 1;
527 int const range( high - low + 1 );
529 int range_result =
static_cast< int >( range * random_store_[random_counter_]) + low;
538 last_ref_pose_(NULL),
541 bondlen_precision_(2)
546 std::ostringstream oss;
547 oss << basic::options::option[ basic::options::OptionKeys::out::prefix ]() << outfile.base()
548 << basic::options::option[ basic::options::OptionKeys::out::suffix ]();
549 outfile.base( oss.str() );
550 outfile.path( basic::options::option[ basic::options::OptionKeys::out::path::pdb ]().path() );
551 outfile.vol( basic::options::option[ basic::options::OptionKeys::out::path::pdb ]().vol() );
552 if( basic::options::option[ basic::options::OptionKeys::out::pdb_gz ] && outfile.ext() !=
"gz" ) {
553 outfile.ext(
".gz" );
555 outfile_name = outfile.name();
560 utility::io::izstream in( outfile_name.c_str() );
562 utility_exit_with_message(
"Unable to open file: " + outfile_name +
"\n" );
566 std::map< std::string, core::Real > tmp_scores;
572 out_.open_append( outfile_name.c_str() );
574 out_.open( outfile_name.c_str() );
575 if( basic::options::option[ basic::options::OptionKeys::run::version ] ) {
579 if ( !
out_.good() ) {
580 utility_exit_with_message(
"Unable to open file: " + outfile_name +
"\n" );
588 std::map< std::string, core::Real >
const & scores,
595 std::map< std::string, core::Real > empty_scores;
600 basic::Error() <<
"Tag " << tag <<
" already exists in silent file; writing structure anyway..." << std::endl;
604 if (
out_.uncompressed() )
out_.flush();
612 int bondlen_precision
637 if (outfile_name !=
"none" ) {
641 std::ostringstream oss;
642 oss << basic::options::option[ basic::options::OptionKeys::out::prefix ]() << outfile.base()
643 << basic::options::option[ basic::options::OptionKeys::out::suffix ]();
644 outfile.base( oss.str() );
645 outfile.path( basic::options::option[ basic::options::OptionKeys::out::path::pdb ]().path() );
646 outfile.vol( basic::options::option[ basic::options::OptionKeys::out::path::pdb ]().vol() );
648 if( basic::options::option[ basic::options::OptionKeys::out::file::fullatom ] && outfile.ext() !=
"fasc" ) {
649 outfile.ext(
".fasc" );
651 outfile.ext(
".sc" );
653 outfile_name = outfile.name();
678 output_pdb_name.path( basic::options::option[ basic::options::OptionKeys::out::path::pdb ]().path() );
679 output_pdb_name.vol( basic::options::option[ basic::options::OptionKeys::out::path::pdb ]().vol() );
680 output_pdb_name.base( tag );
681 if( basic::options::option[ basic::options::OptionKeys::out::pdb_gz ] ) {
682 output_pdb_name.ext(
".pdb.gz" );
684 output_pdb_name.ext(
".pdb" );
686 return output_pdb_name.name();
694 output_pdb_name.path(
695 basic::options::option[ basic::options::OptionKeys::out::path::pdb ]().path() +
697 output_pdb_name.vol( basic::options::option[ basic::options::OptionKeys::out::path::pdb ]().vol() );
698 if( basic::options::option[ basic::options::OptionKeys::out::pdb_gz ] ) {
699 output_pdb_name.ext(
".pdb.gz" );
701 output_pdb_name.ext(
".pdb" );
703 std::cout <<
"output file name: " << output_pdb_name.name() << std::endl;
704 return output_pdb_name.name();
711 utility::io::ozstream tempfile;
713 tempfile.open( output_tag +
".in_progress" );
725 utility::io::ozstream out( outfile_name.c_str() );
727 utility_exit_with_message(
"Unable to open file: " + outfile_name +
"\n" );
734 utility::file::file_delete( outfile_name +
".in_progress" );
739 if ( basic::options::option[ basic::options::OptionKeys::out::file::o ].user() ) {
770 utility::io::ozstream & out,
778 ScoreTypeVec score_types;
781 if ( weights[ii] != 0 ) score_types.push_back(ii);
784 out <<
"# All scores below are weighted scores, not raw scores.\n";
785 out <<
"#BEGIN_POSE_ENERGIES_TABLE " << tag <<
"\n";
787 for(ScoreTypeVec::iterator ii = score_types.begin(), end_ii = score_types.end(); ii != end_ii; ++ii)
791 for(ScoreTypeVec::iterator ii = score_types.begin(), end_ii = score_types.end(); ii != end_ii; ++ii)
792 out <<
" " << weights[*ii];
796 for(ScoreTypeVec::iterator ii = score_types.begin(), end_ii = score_types.end(); ii != end_ii; ++ii) {
801 out <<
" " << pose_total <<
"\n";
805 for(ScoreTypeVec::iterator ii = score_types.begin(), end_ii = score_types.end(); ii != end_ii; ++ii) {
810 out <<
" " << rsd_total <<
"\n";
812 out <<
"#END_POSE_ENERGIES_TABLE " << tag <<
"\n";
850 rawfile_name_(), used_tags_()
853 std::ostringstream oss;
854 oss << basic::options::option[ basic::options::OptionKeys::out::prefix ]() << outfile.base()
855 << basic::options::option[ basic::options::OptionKeys::out::suffix ]();
856 outfile.base( oss.str() );
857 outfile.path( basic::options::option[ basic::options::OptionKeys::out::path::pdb ]().path() );
858 outfile.vol( basic::options::option[ basic::options::OptionKeys::out::path::pdb ]().vol() );
859 outfile_name = outfile.name();
864 core::io::raw_data::StructureMap::const_iterator iter;
868 JobDistributorTracer << *i << std::endl;
881 bool fa = basic::options::option[ basic::options::OptionKeys::out::file::fullatom ];
893 output_pdb_name.path( basic::options::option[ basic::options::OptionKeys::out::path::pdb ]().path() );
894 output_pdb_name.vol( basic::options::option[ basic::options::OptionKeys::out::path::pdb ]().vol() );
895 return output_pdb_name.name();
902 output_pdb_name.path(
903 basic::options::option[ basic::options::OptionKeys::out::path::pdb ]().path() +
905 output_pdb_name.vol( basic::options::option[ basic::options::OptionKeys::out::path::pdb ]().vol() );
906 std::cout <<
"output file name: " << output_pdb_name.name() << std::endl;
907 return output_pdb_name.name();
917 bool already_processed =
false;
920 if( (*i) == output_tag ) {
921 already_processed =
true;
922 JobDistributorTracer <<
"Tag: " << output_tag <<
" " << job->output_tag(struct_n) <<
923 " - already processed" << std::endl;
927 return already_processed;
942 int const & struct_n,
953 using namespace core::io::silent;
956 ss->fill_struct( pose, output_tag );
957 sfd->write_silent_struct( *ss, silent_file );
962 std::string silent_file = basic::options::option[ basic::options::OptionKeys::out::file::silent ]();
966 size_t lastslash = silent_file.find_last_of(
"/\\");
967 size_t lastdot = silent_file.find_last_of(
'.');
969 if ( !basic::options::option[ basic::options::OptionKeys::out::path::mpi_rank_dir ]() ) {
970 if ( lastdot == silent_file.npos || (lastslash > lastdot && lastslash != silent_file.npos) ) {
973 silent_file = silent_file.substr( 0,lastdot )+
"_"+utility::to_string(
parent::mpi_rank() )+silent_file.substr( lastdot );
976 if ( lastslash == silent_file.npos) {
979 silent_file = silent_file.substr( 0,lastslash )+
"/"+utility::to_string(
parent::mpi_rank() )+silent_file.substr( lastslash );
998 core::io::silent::Structure_Map::const_iterator iter;
1002 JobDistributorTracer << *i << std::endl;
1016 if ( found )
return found;
1020 querytag = querytag.substr(2);
1042 sfd->write_silent_struct( silent_struct, silent_file );
1077 if ( itag.size() ) itag =
"_" + itag;
1080 if ( basic::options::option[ basic::options::OptionKeys::out::user_tag ].user() ) {
1081 user_tag =
"_" + basic::options::option[ basic::options::OptionKeys::out::user_tag ];
1084 return prefix + itag + user_tag + number;