void ActionWithVessel::runAllTasks(){ if( getExchangeStep() && nactive_tasks!=fullTaskList.size() ) error("contributors must be unlocked during exchange steps"); plumed_massert( functions.size()>0, "you must have a call to readVesselKeywords somewhere" ); unsigned stride=comm.Get_size(); unsigned rank=comm.Get_rank(); if(serial){ stride=1; rank=0; } // Make sure jobs are done doJobsRequiredBeforeTaskList(); for(unsigned i=rank;i<nactive_tasks;i+=stride){ // The index of the task in the full list task_index=indexOfTaskInFullList[i]; // Store the task we are currently working on current=partialTaskList[i]; // Calculate the stuff in the loop for this action performTask(); // Weight should be between zero and one plumed_dbg_assert( thisval[1]>=0 && thisval[1]<=1.0 ); // Check for conditions that allow us to just to skip the calculation // the condition is that the weight of the contribution is low // N.B. Here weights are assumed to be between zero and one if( thisval[1]<tolerance ){ // Clear the derivatives clearAfterTask(); // Deactivate task if it is less than the neighbor list tolerance if( thisval[1]<nl_tolerance && contributorsAreUnlocked ) deactivate_task(); continue; } // Now calculate all the functions // If the contribution of this quantity is very small at neighbour list time ignore it // untill next neighbour list time if( !calculateAllVessels() && contributorsAreUnlocked ) deactivate_task(); } finishComputations(); }
void ActionWithVessel::runAllTasks(){ if( getExchangeStep() && nactive_tasks!=fullTaskList.size() ) error("contributors must be unlocked during exchange steps"); plumed_massert( functions.size()>0, "you must have a call to readVesselKeywords somewhere" ); unsigned stride=comm.Get_size(); unsigned rank=comm.Get_rank(); if(serial){ stride=1; rank=0; } // Make sure jobs are done if(timers) stopwatch.start("1 Prepare Tasks"); doJobsRequiredBeforeTaskList(); if(timers) stopwatch.stop("1 Prepare Tasks"); // Get number of threads for OpenMP unsigned nt=OpenMP::getNumThreads(); if( nt*stride*10>nactive_tasks) nt=nactive_tasks/stride/10; if( nt==0 ) nt=1; // Get size for buffer unsigned bsize=0, bufsize=getSizeOfBuffer( bsize ); // Clear buffer buffer.assign( buffer.size(), 0.0 ); // Switch off calculation of derivatives in main loop if( dertime_can_be_off ) dertime=false; // std::vector<unsigned> der_list; // if( mydata ) der_list.resize( mydata->getSizeOfDerivativeList(), 0 ); // Build storage stuff for loop // std::vector<double> buffer( bufsize, 0.0 ); if(timers) stopwatch.start("2 Loop over tasks"); #pragma omp parallel num_threads(nt) { std::vector<double> omp_buffer; if( nt>1 ) omp_buffer.resize( bufsize, 0.0 ); MultiValue myvals( getNumberOfQuantities(), getNumberOfDerivatives() ); MultiValue bvals( getNumberOfQuantities(), getNumberOfDerivatives() ); myvals.clearAll(); bvals.clearAll(); #pragma omp for nowait for(unsigned i=rank;i<nactive_tasks;i+=stride){ // Calculate the stuff in the loop for this action performTask( indexOfTaskInFullList[i], partialTaskList[i], myvals ); // Weight should be between zero and one plumed_dbg_assert( myvals.get(0)>=0 && myvals.get(0)<=1.0 ); // Check for conditions that allow us to just to skip the calculation // the condition is that the weight of the contribution is low // N.B. Here weights are assumed to be between zero and one if( myvals.get(0)<tolerance ){ // Deactivate task if it is less than the neighbor list tolerance if( myvals.get(0)<nl_tolerance && contributorsAreUnlocked ) deactivate_task( indexOfTaskInFullList[i] ); // Clear the derivatives myvals.clearAll(); continue; } // Now calculate all the functions // If the contribution of this quantity is very small at neighbour list time ignore it // untill next neighbour list time if( nt>1 ){ if( !calculateAllVessels( indexOfTaskInFullList[i], myvals, bvals, omp_buffer, der_list ) && contributorsAreUnlocked ) deactivate_task( indexOfTaskInFullList[i] ); } else { if( !calculateAllVessels( indexOfTaskInFullList[i], myvals, bvals, buffer, der_list ) && contributorsAreUnlocked ) deactivate_task( indexOfTaskInFullList[i] ); } // Clear the value myvals.clearAll(); } #pragma omp critical if(nt>1) for(unsigned i=0;i<bufsize;++i) buffer[i]+=omp_buffer[i]; } if(timers) stopwatch.stop("2 Loop over tasks"); // Turn back on derivative calculation dertime=true; if(timers) stopwatch.start("3 MPI gather"); // MPI Gather everything if( !serial && buffer.size()>0 ) comm.Sum( buffer ); // MPI Gather index stores if( mydata && !lowmem && !noderiv ){ comm.Sum( der_list ); mydata->setActiveValsAndDerivatives( der_list ); } // Update the elements that are makign contributions to the sum here // this causes problems if we do it in prepare if( !serial && contributorsAreUnlocked ) comm.Sum( taskFlags ); if(timers) stopwatch.stop("3 MPI gather"); if(timers) stopwatch.start("4 Finishing computations"); finishComputations( buffer ); if(timers) stopwatch.stop("4 Finishing computations"); }
void PathMSDBase::calculate(){ if(neigh_size>0 && getExchangeStep()) error("Neighbor lists for this collective variable are not compatible with replica exchange, sorry for that!"); //log.printf("NOW CALCULATE! \n"); // resize the list to full if(imgVec.empty()){ // this is the signal that means: recalculate all imgVec.resize(nframes); for(unsigned i=0;i<nframes;i++){ imgVec[i].property=indexvec[i]; imgVec[i].index=i; } } // THIS IS THE HEAVY PART (RMSD STUFF) unsigned stride=comm.Get_size(); unsigned rank=comm.Get_rank(); unsigned nat=pdbv[0].size(); plumed_assert(nat>0); plumed_assert(nframes>0); plumed_assert(imgVec.size()>0); std::vector<double> tmp_distances(imgVec.size(),0.0); std::vector<Vector> tmp_derivs; // this array is a merge of all tmp_derivs, so as to allow a single comm.Sum below std::vector<Vector> tmp_derivs2(imgVec.size()*nat); // if imgVec.size() is less than nframes, it means that only some msd will be calculated for(unsigned i=rank;i<imgVec.size();i+=stride){ // store temporary local results tmp_distances[i]=msdv[imgVec[i].index].calculate(getPositions(),tmp_derivs,true); plumed_assert(tmp_derivs.size()==nat); for(unsigned j=0;j<nat;j++) tmp_derivs2[i*nat+j]=tmp_derivs[j]; } // reduce over all processors comm.Sum(tmp_distances); comm.Sum(tmp_derivs2); // assign imgVec[i].distance and imgVec[i].distder for(unsigned i=0;i<imgVec.size();i++){ imgVec[i].distance=tmp_distances[i]; imgVec[i].distder.assign(&tmp_derivs2[i*nat],nat+&tmp_derivs2[i*nat]); } // END OF THE HEAVY PART vector<Value*> val_s_path; if(labels.size()>0){ for(unsigned i=0;i<labels.size();i++){ val_s_path.push_back(getPntrToComponent(labels[i].c_str()));} }else{ val_s_path.push_back(getPntrToComponent("sss")); } Value* val_z_path=getPntrToComponent("zzz"); vector<double> s_path(val_s_path.size());for(unsigned i=0;i<s_path.size();i++)s_path[i]=0.; double partition=0.; double tmp; // clean vector for(unsigned i=0;i< derivs_z.size();i++){derivs_z[i].zero();} typedef vector< class ImagePath >::iterator imgiter; for(imgiter it=imgVec.begin();it!=imgVec.end();++it){ (*it).similarity=exp(-lambda*((*it).distance)); //log<<"DISTANCE "<<(*it).distance<<"\n"; for(unsigned i=0;i<s_path.size();i++){ s_path[i]+=((*it).property[i])*(*it).similarity; } partition+=(*it).similarity; } for(unsigned i=0;i<s_path.size();i++){ s_path[i]/=partition; val_s_path[i]->set(s_path[i]) ;} val_z_path->set(-(1./lambda)*std::log(partition)); for(unsigned j=0;j<s_path.size();j++){ // clean up for(unsigned i=0;i< derivs_s.size();i++){derivs_s[i].zero();} // do the derivative for(imgiter it=imgVec.begin();it!=imgVec.end();++it){ double expval=(*it).similarity; tmp=lambda*expval*(s_path[j]-(*it).property[j])/partition; for(unsigned i=0;i< derivs_s.size();i++){ derivs_s[i]+=tmp*(*it).distder[i] ;} if(j==0){for(unsigned i=0;i< derivs_z.size();i++){ derivs_z[i]+=(*it).distder[i]*expval/partition;}} } for(unsigned i=0;i< derivs_s.size();i++){ setAtomsDerivatives (val_s_path[j],i,derivs_s[i]); if(j==0){setAtomsDerivatives (val_z_path,i,derivs_z[i]);} } } for(unsigned i=0;i<val_s_path.size();++i) setBoxDerivativesNoPbc(val_s_path[i]); setBoxDerivativesNoPbc(val_z_path); // // here set next round neighbors // if (neigh_size>0){ //if( int(getStep())%int(neigh_stride/getTimeStep())==0 ){ // enforce consistency: the stride is in time steps if( int(getStep())%int(neigh_stride)==0 ){ // next round do it all:empty the vector imgVec.clear(); } // time to analyze the results: if(imgVec.size()==nframes){ //sort by msd sort(imgVec.begin(), imgVec.end(), imgOrderByDist()); //resize imgVec.resize(neigh_size); } } //log.printf("CALCULATION DONE! \n"); }