Example #1
0
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();
}
Example #2
0
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");
}
Example #3
0
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");
}