void simrun_slave( const sim_parameters& par,const mpi::communicator& mpicomm) { Replica* rep = new Replica(par); if ( rep->prepare( par.init ) == false ) { delete rep; } // perform dry runs to reach thermal equilibrium rep->mcstep_dry( par.drysweeps ); unsigned int completed_bins_thisslave = 0; bool master_out_of_work = false; unsigned int scheduled_bins_thisslave; mpicomm.send( 0, MSGTAG_S_M_REQUEST_BINS ); mpicomm.recv( 0, MSGTAG_M_S_DISPATCHED_BINS, scheduled_bins_thisslave ); master_out_of_work = ( scheduled_bins_thisslave == 0 ); std::vector<double> q2_binmeans; std::vector<double> q4_binmeans; while ( scheduled_bins_thisslave > 0 ) { unsigned int new_scheduled_bins_thisslave; mpi::request master_answer; if ( !master_out_of_work ) { // ask the master for more work mpicomm.send( 0, MSGTAG_S_M_REQUEST_BINS ); master_answer = mpicomm.irecv( 0, MSGTAG_M_S_DISPATCHED_BINS, new_scheduled_bins_thisslave ); } // initialize binning array vector<double> q2_currentbin; vector<double> q4_currentbin; try { // try to allocate enough memory ... q2_currentbin.reserve( par.binwidth ); q4_currentbin.reserve( par.binwidth ); } catch ( bad_alloc ) { delete rep; } for (unsigned int mcs = 0;mcs < par.binwidth;++mcs ) { // perform a Monte Carlo step rep->mcs(); // measure observables double q2 = 0, q4 = 0; double thissample_q = rep->Q(); // remember the sample's properties to calculate their mean value q2 = thissample_q * thissample_q; q4 = thissample_q * thissample_q * thissample_q * thissample_q; q2_currentbin.push_back(q2); q4_currentbin.push_back(q4); } q2_binmeans.push_back( accumulate( q2_currentbin.begin(), q2_currentbin.end(), 0.0 ) / static_cast<double>( q2_currentbin.size() ) ); q2_currentbin.clear(); // report completion of the work mpicomm.send( 0, 2 ); ++completed_bins_thisslave; --scheduled_bins_thisslave; if ( !master_out_of_work ) { // wait for answer from master concerning the next bin master_answer.wait(); if ( new_scheduled_bins_thisslave == 1 ) { ++scheduled_bins_thisslave; } else { master_out_of_work = true; } } } assert( mpicomm.rank() != 0 ); mpi::gather( mpicomm, q2_binmeans, 0 ); return; }