MultiValue& ActionWithInputMatrix::getInputDerivatives( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms ) const { if( (mymatrix->function)->mybasemulticolvars.size()==0 ) { MultiValue& myder=mymatrix->getTemporyMultiValue(0); if( myder.getNumberOfValues()!=2 || myder.getNumberOfDerivatives()!=(mymatrix->function)->getNumberOfDerivatives() ) { myder.resize( 2, (mymatrix->function)->getNumberOfDerivatives() ); } myder.clearAll(); MultiValue myvals( (mymatrix->function)->getNumberOfQuantities(), (mymatrix->function)->getNumberOfDerivatives() ); for(unsigned i=0; i<mymatrix->getNumberOfColumns(); ++i) { if( mymatrix->undirectedGraph() && ind==i ) continue; addConnectionDerivatives( ind, i, myvals, myder ); } myder.updateDynamicList(); return myder; } return (mymatrix->function)->getInputDerivatives( ind, normed, myatoms ); }
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"); }