Skip to content

Commit

Permalink
Changed the code so that values are transferred directly to the Value…
Browse files Browse the repository at this point in the history
… rather than to the buffer
  • Loading branch information
Gareth Aneurin Tribello authored and Gareth Aneurin Tribello committed Jul 31, 2024
1 parent e0f5606 commit e23214d
Show file tree
Hide file tree
Showing 16 changed files with 118 additions and 182 deletions.
4 changes: 2 additions & 2 deletions regtest/gridtools/rt-pairentropies/p_entropies.xyz.reference
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ X 0.1056 1.6641 -0.0477 -1.8340
X 0.7283 1.7274 0.7849 -1.1006
X 0.9103 2.4770 -0.1044 -1.6791
X 0.0688 2.5236 0.7617 -1.7107
X -0.1428 1.6741 1.8280 -2.2931
X -0.1428 1.6741 1.8280 -2.2930
X 0.7031 1.5181 2.4387 -1.2983
X 0.8450 2.4859 1.8490 -1.4526
X 0.0682 2.5773 2.6448 -1.7259
Expand Down Expand Up @@ -238,7 +238,7 @@ X 1.5343 -0.0986 -0.1431 -1.1706
X 2.4293 -0.2020 1.0139 -2.1738
X 2.6885 0.7142 0.0622 -2.1087
X 1.9617 0.7380 0.8137 -1.3226
X 1.6673 0.0998 1.7622 -1.7197
X 1.6673 0.0998 1.7622 -1.7196
X 2.4352 0.0073 2.5561 -2.1955
X 2.5243 0.9413 1.6602 -2.0844
X 1.8709 0.8862 2.6985 -1.8413
Expand Down
6 changes: 3 additions & 3 deletions src/colvar/MultiColvarTemplate.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class MultiColvarTemplate : public ActionWithVector {
unsigned getNumberOfDerivatives() override ;
void addValueWithDerivatives( const std::vector<unsigned>& shape=std::vector<unsigned>() ) override ;
void addComponentWithDerivatives( const std::string& name, const std::vector<unsigned>& shape=std::vector<unsigned>() ) override ;
void setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) override ;
void setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol ) override ;
void performTask( const unsigned&, MultiValue& ) const override ;
void calculate() override;
};
Expand Down Expand Up @@ -127,9 +127,9 @@ void MultiColvarTemplate<T>::addComponentWithDerivatives( const std::string& nam
}

template <class T>
void MultiColvarTemplate<T>::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) {
void MultiColvarTemplate<T>::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol ) {
if( wholemolecules ) makeWhole();
ActionWithVector::setupStreamedComponents( headstr, nquants, nmat, maxcol, nbookeeping );
ActionWithVector::setupStreamedComponents( headstr, nquants, nmat, maxcol );
}

template <class T>
Expand Down
4 changes: 2 additions & 2 deletions src/colvar/RMSDVector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,9 +269,9 @@ void RMSDVector::gatherStoredValue( const unsigned& valindex, const unsigned& co
const unsigned& bufstart, std::vector<double>& buffer ) const {
if( getConstPntrToComponent(valindex)->getRank()==1 ) { ActionWithVector::gatherStoredValue( valindex, code, myvals, bufstart, buffer ); return; }
const std::vector<Vector>& direction( myvals.getConstFirstAtomDerivativeVector()[1] );
unsigned natoms = direction.size(); unsigned vindex = bufstart + 3*code*natoms;
unsigned natoms = direction.size(); unsigned vindex = 3*code*natoms; Value* myval = const_cast<Value*>( getConstPntrToComponent(valindex) );
for(unsigned i=0; i<natoms; ++i) {
for(unsigned j=0; j<3; ++j ) buffer[vindex + j*natoms + i] += direction[i][j];
for(unsigned j=0; j<3; ++j ) myval->set(vindex + j*natoms + i, direction[i][j] );
}
}

Expand Down
93 changes: 30 additions & 63 deletions src/core/ActionWithMatrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,17 +51,15 @@ void ActionWithMatrix::getAllActionLabelsInMatrixChain( std::vector<std::string>
if( matrix_to_do_after ) matrix_to_do_after->getAllActionLabelsInMatrixChain( mylabels );
}

void ActionWithMatrix::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) {
ActionWithVector::setupStreamedComponents( headstr, nquants, nmat, maxcol, nbookeeping );
void ActionWithMatrix::setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol ) {
ActionWithVector::setupStreamedComponents( headstr, nquants, nmat, maxcol );

for(int i=0; i<getNumberOfComponents(); ++i) {
Value* myval=getPntrToComponent(i);
if( myval->getRank()!=2 || myval->hasDerivatives() ) continue;
myval->setPositionInMatrixStash(nmat); nmat++;
if( !myval->valueIsStored() ) continue;
if( myval->getShape()[1]>maxcol ) maxcol=myval->getShape()[1];
myval->setMatrixBookeepingStart(nbookeeping);
nbookeeping += myval->getShape()[0]*( 1 + myval->getNumberOfColumns() );
}
// Turn off clearning of derivatives after each matrix run if there are no matrices in the output of this action
clearOnEachCycle = false;
Expand Down Expand Up @@ -91,24 +89,21 @@ const ActionWithMatrix* ActionWithMatrix::getFirstMatrixInChain() const {
return matrix_to_do_before->getFirstMatrixInChain();
}

void ActionWithMatrix::getTotalMatrixBookeeping( unsigned& nbookeeping ) {
void ActionWithMatrix::setupMatrixStore() {
for(int i=0; i<getNumberOfComponents(); ++i) {
Value* myval=getPntrToComponent(i);
if( myval->getRank()!=2 || myval->hasDerivatives() || !myval->valueIsStored() ) continue;
myval->reshapeMatrixStore( getNumberOfColumns() );
nbookeeping += myval->getShape()[0]*( 1 + myval->getNumberOfColumns() );
}
if( next_action_in_chain ) next_action_in_chain->getTotalMatrixBookeeping( nbookeeping );
if( next_action_in_chain ) next_action_in_chain->setupMatrixStore();
}

void ActionWithMatrix::calculate() {
if( actionInChain() ) return ;
// Update all the neighbour lists
updateAllNeighbourLists();
// Setup the matrix indices
unsigned nbookeeping=0; getTotalMatrixBookeeping( nbookeeping );
if( matrix_bookeeping.size()!=nbookeeping ) matrix_bookeeping.resize( nbookeeping );
std::fill( matrix_bookeeping.begin(), matrix_bookeeping.end(), 0 );
setupMatrixStore();
// And run all the tasks
runAllTasks();
}
Expand All @@ -118,6 +113,16 @@ void ActionWithMatrix::updateAllNeighbourLists() {
if( next_action_in_chain ) next_action_in_chain->updateAllNeighbourLists();
}

void ActionWithMatrix::clearBookeepingBeforeTask( const unsigned& task_index ) const {
// Reset the bookeeping elements for storage
for(unsigned i=0; i<getNumberOfComponents(); ++i) {
Value* myval = const_cast<Value*>( getConstPntrToComponent(i) ); unsigned ncols = myval->getNumberOfColumns();
if( myval->getRank()!=2 || myval->hasDerivatives() || !myval->valueIsStored() || ncols>=myval->getShape()[1] ) continue;
myval->matrix_bookeeping[task_index*(1+ncols)]=0;

Check failure

Code scanning / CodeQL

Multiplication result converted to larger type High

Multiplication result may overflow 'unsigned int' before it is converted to 'size_type'.
}
if( matrix_to_do_after ) matrix_to_do_after->clearBookeepingBeforeTask( task_index );
}

void ActionWithMatrix::performTask( const unsigned& task_index, MultiValue& myvals ) const {
std::vector<unsigned> & indices( myvals.getIndices() );
if( matrix_to_do_before ) {
Expand All @@ -127,6 +132,9 @@ void ActionWithMatrix::performTask( const unsigned& task_index, MultiValue& myva
}
setupForTask( task_index, indices, myvals );

// Reset the bookeeping elements for storage
clearBookeepingBeforeTask( task_index );

// Now loop over the row of the matrix
unsigned ntwo_atoms = myvals.getSplitIndex();
for(unsigned i=1; i<ntwo_atoms; ++i) {
Expand All @@ -149,72 +157,31 @@ void ActionWithMatrix::runTask( const std::string& controller, const unsigned& c

if( hasval ) {
for(int i=0; i<getNumberOfComponents(); ++i) {
const Value* myval=getConstPntrToComponent(i);
const Value* myval=getConstPntrToComponent(i); unsigned ncols = myval->getNumberOfColumns();
if( myval->getRank()!=2 || myval->hasDerivatives() || !myval->valueIsStored() ) continue;
unsigned matindex = myval->getPositionInMatrixStash(), matbook_start = myval->getMatrixBookeepingStart(), col_stash_index = colno;
unsigned matindex = myval->getPositionInMatrixStash(), col_stash_index = colno;
if( colno>=myval->getShape()[0] ) col_stash_index = colno - myval->getShape()[0];
unsigned rowstart = matbook_start+current*(1+myval->getNumberOfColumns());
if( myval->forcesWereAdded() ) {
unsigned sind = myval->getPositionInStream(), find = myvals.getMatrixBookeeping()[rowstart];
double fforce = myval->getForce( myvals.getTaskIndex()*myval->getNumberOfColumns() + find );
if( getNumberOfColumns()>=myval->getShape()[1] ) fforce = myval->getForce( myvals.getTaskIndex()*myval->getShape()[1] + col_stash_index );
unsigned sind = myval->getPositionInStream();
double fforce = myval->getForce( myvals.getTaskIndex()*ncols + myval->matrix_bookeeping[current*(1+ncols)] );

Check failure

Code scanning / CodeQL

Multiplication result converted to larger type High

Multiplication result may overflow 'unsigned int' before it is converted to 'size_type'.
if( ncols>=myval->getShape()[1] ) fforce = myval->getForce( myvals.getTaskIndex()*myval->getShape()[1] + col_stash_index );
for(unsigned j=0; j<myvals.getNumberActive(sind); ++j) {
unsigned kindex = myvals.getActiveIndex(sind,j); myvals.addMatrixForce( matindex, kindex, fforce*myvals.getDerivative(sind,kindex ) );
}
}
double finalval = myvals.get( myval->getPositionInStream() );
if( fabs(finalval)>0 ) myvals.stashMatrixElement( matindex, rowstart, col_stash_index, finalval );
if( fabs(finalval)>0 ) {
Value* myv = const_cast<Value*>( myval );
if( ncols<myval->getShape()[1] ) {
myv->set( current*ncols + myval->matrix_bookeeping[current*(1+ncols)], finalval );

Check failure

Code scanning / CodeQL

Multiplication result converted to larger type High

Multiplication result may overflow 'unsigned int' before it is converted to 'size_type'.
myv->matrix_bookeeping[current*(1+ncols)]++; myv->matrix_bookeeping[current*(1+ncols)+myval->matrix_bookeeping[current*(1+ncols)]] = col_stash_index;

Check failure

Code scanning / CodeQL

Multiplication result converted to larger type High

Multiplication result may overflow 'unsigned int' before it is converted to 'size_type'.

Check failure

Code scanning / CodeQL

Multiplication result converted to larger type High

Multiplication result may overflow 'unsigned int' before it is converted to 'size_type'.
} else myv->set( current*myval->getShape()[1] + col_stash_index, finalval );
}
}
}
if( matrix_to_do_after ) matrix_to_do_after->runTask( controller, current, colno, myvals );
}

void ActionWithMatrix::gatherThreads( const unsigned& nt, const unsigned& bufsize, const std::vector<double>& omp_buffer, std::vector<double>& buffer, MultiValue& myvals ) {
ActionWithVector::gatherThreads( nt, bufsize, omp_buffer, buffer, myvals );
for(unsigned i=0; i<matrix_bookeeping.size(); ++i) matrix_bookeeping[i] += myvals.getMatrixBookeeping()[i];
}

void ActionWithMatrix::gatherProcesses( std::vector<double>& buffer ) {
ActionWithVector::gatherProcesses( buffer );
if( matrix_bookeeping.size()>0 && !runInSerial() ) comm.Sum( matrix_bookeeping );
unsigned nval=0; transferNonZeroMatrixElementsToValues( nval, matrix_bookeeping );
}

void ActionWithMatrix::transferNonZeroMatrixElementsToValues( unsigned& nval, const std::vector<unsigned>& matbook ) {
for(int i=0; i<getNumberOfComponents(); ++i) {
Value* myval=getPntrToComponent(i);
if( myval->getRank()!=2 || myval->hasDerivatives() || !myval->valueIsStored() || getNumberOfColumns()>=myval->getShape()[1] ) continue;
unsigned nelements = myval->getShape()[0]*( 1 + myval->getNumberOfColumns() );
for(unsigned j=0; j<nelements; ++j) myval->setMatrixBookeepingElement( j, matbook[nval+j] );
nval += nelements;
}
if( next_action_in_chain ) next_action_in_chain->transferNonZeroMatrixElementsToValues( nval, matbook );
}

void ActionWithMatrix::gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals,
const unsigned& bufstart, std::vector<double>& buffer ) const {
if( getConstPntrToComponent(valindex)->getRank()==1 ) { ActionWithVector::gatherStoredValue( valindex, code, myvals, bufstart, buffer ); return; }
const Value* myval=getConstPntrToComponent(valindex);
unsigned ncols = myval->getNumberOfColumns(), matind = myval->getPositionInMatrixStash();
unsigned matbook_start = myval->getMatrixBookeepingStart(), vindex = bufstart + code*myval->getNumberOfColumns();
const std::vector<unsigned> & matbook( myvals.getMatrixBookeeping() ); unsigned nelements = matbook[matbook_start+code*(1+ncols)];
if( ncols>=myval->getShape()[1] ) {
// In this case we store the full matrix
for(unsigned j=0; j<nelements; ++j) {
unsigned jind = matbook[matbook_start+code*(1+ncols)+1+j];
plumed_dbg_massert( vindex+j<buffer.size(), "failing in " + getLabel() + " on value " + myval->getName() );
buffer[vindex + jind] += myvals.getStashedMatrixElement( matind, jind );
}
} else {
// This is for storing sparse matrices when we can
for(unsigned j=0; j<nelements; ++j) {
unsigned jind = matbook[matbook_start+code*(1+ncols)+1+j];
plumed_dbg_massert( vindex+j<buffer.size(), "failing in " + getLabel() + " on value " + myval->getName() );
buffer[vindex + j] += myvals.getStashedMatrixElement( matind, jind );
}
}
}

bool ActionWithMatrix::checkForTaskForce( const unsigned& itask, const Value* myval ) const {
if( myval->getRank()<2 ) return ActionWithVector::checkForTaskForce( itask, myval );
unsigned nelements = myval->getRowLength(itask), startr = itask*myval->getNumberOfColumns();
Expand Down
16 changes: 4 additions & 12 deletions src/core/ActionWithMatrix.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,14 @@ class ActionWithMatrix : public ActionWithVector {
ActionWithMatrix* next_action_in_chain;
ActionWithMatrix* matrix_to_do_before;
ActionWithMatrix* matrix_to_do_after;
/// This holds the bookeeping arrays for sparse matrices
std::vector<unsigned> matrix_bookeeping;
/// Update all the neighbour lists in the chain
void updateAllNeighbourLists();
/// This clears all bookeeping arrays before the ith task
void clearBookeepingBeforeTask( const unsigned& task_index ) const ;
/// This is used to clear up the matrix elements
void clearMatrixElements( MultiValue& myvals ) const ;
/// This is used to find the total amount of space we need for storing matrix elements
void getTotalMatrixBookeeping( unsigned& stashsize );
/// This transfers the non-zero elements to the Value
void transferNonZeroMatrixElementsToValues( unsigned& nval, const std::vector<unsigned>& matbook );
void setupMatrixStore();
/// This does the calculation of a particular matrix element
void runTask( const std::string& controller, const unsigned& current, const unsigned colno, MultiValue& myvals ) const ;
protected:
Expand Down Expand Up @@ -71,17 +69,11 @@ class ActionWithMatrix : public ActionWithVector {
/// This should return the number of columns to help with sparse storage of matrices
virtual unsigned getNumberOfColumns() const = 0;
/// This requires some thought
void setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol, unsigned& nbookeeping ) override;
void setupStreamedComponents( const std::string& headstr, unsigned& nquants, unsigned& nmat, unsigned& maxcol ) override;
//// This does some setup before we run over the row of the matrix
virtual void setupForTask( const unsigned& task_index, std::vector<unsigned>& indices, MultiValue& myvals ) const = 0;
/// Run over one row of the matrix
virtual void performTask( const unsigned& task_index, MultiValue& myvals ) const ;
/// Gather a row of the matrix
void gatherStoredValue( const unsigned& valindex, const unsigned& code, const MultiValue& myvals, const unsigned& bufstart, std::vector<double>& buffer ) const override;
/// Gather all the data from the threads
void gatherThreads( const unsigned& nt, const unsigned& bufsize, const std::vector<double>& omp_buffer, std::vector<double>& buffer, MultiValue& myvals ) override ;
/// Gather all the data from the MPI processes
void gatherProcesses( std::vector<double>& buffer ) override;
/// This is the virtual that will do the calculation of the task for a particular matrix element
virtual void performTask( const std::string& controller, const unsigned& index1, const unsigned& index2, MultiValue& myvals ) const = 0;
/// This is the jobs that need to be done when we have run all the jobs in a row of the matrix
Expand Down
Loading

1 comment on commit e23214d

@PlumedBot
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found broken examples in automatic/ANGLES.tmp
Found broken examples in automatic/ANN.tmp
Found broken examples in automatic/CAVITY.tmp
Found broken examples in automatic/CLASSICAL_MDS.tmp
Found broken examples in automatic/CLUSTER_DIAMETER.tmp
Found broken examples in automatic/CLUSTER_DISTRIBUTION.tmp
Found broken examples in automatic/CLUSTER_PROPERTIES.tmp
Found broken examples in automatic/CONSTANT.tmp
Found broken examples in automatic/CONTACT_MATRIX.tmp
Found broken examples in automatic/CONTACT_MATRIX_PROPER.tmp
Found broken examples in automatic/COORDINATIONNUMBER.tmp
Found broken examples in automatic/DFSCLUSTERING.tmp
Found broken examples in automatic/DISTANCE_FROM_CONTOUR.tmp
Found broken examples in automatic/EDS.tmp
Found broken examples in automatic/EMMI.tmp
Found broken examples in automatic/ENVIRONMENTSIMILARITY.tmp
Found broken examples in automatic/FIND_CONTOUR.tmp
Found broken examples in automatic/FIND_CONTOUR_SURFACE.tmp
Found broken examples in automatic/FIND_SPHERICAL_CONTOUR.tmp
Found broken examples in automatic/FOURIER_TRANSFORM.tmp
Found broken examples in automatic/FUNCPATHGENERAL.tmp
Found broken examples in automatic/FUNCPATHMSD.tmp
Found broken examples in automatic/FUNNEL.tmp
Found broken examples in automatic/FUNNEL_PS.tmp
Found broken examples in automatic/GHBFIX.tmp
Found broken examples in automatic/GPROPERTYMAP.tmp
Found broken examples in automatic/HBOND_MATRIX.tmp
Found broken examples in automatic/INCLUDE.tmp
Found broken examples in automatic/INCYLINDER.tmp
Found broken examples in automatic/INENVELOPE.tmp
Found broken examples in automatic/INTERPOLATE_GRID.tmp
Found broken examples in automatic/LOCAL_AVERAGE.tmp
Found broken examples in automatic/MAZE_OPTIMIZER_BIAS.tmp
Found broken examples in automatic/MAZE_RANDOM_ACCELERATION_MD.tmp
Found broken examples in automatic/MAZE_SIMULATED_ANNEALING.tmp
Found broken examples in automatic/MAZE_STEERED_MD.tmp
Found broken examples in automatic/METATENSOR.tmp
Found broken examples in automatic/MULTICOLVARDENS.tmp
Found broken examples in automatic/OUTPUT_CLUSTER.tmp
Found broken examples in automatic/PAMM.tmp
Found broken examples in automatic/PCA.tmp
Found broken examples in automatic/PCAVARS.tmp
Found broken examples in automatic/PIV.tmp
Found broken examples in automatic/PLUMED.tmp
Found broken examples in automatic/PYCVINTERFACE.tmp
Found broken examples in automatic/PYTHONFUNCTION.tmp
Found broken examples in automatic/Q3.tmp
Found broken examples in automatic/Q4.tmp
Found broken examples in automatic/Q6.tmp
Found broken examples in automatic/QUATERNION.tmp
Found broken examples in automatic/SIZESHAPE_POSITION_LINEAR_PROJ.tmp
Found broken examples in automatic/SIZESHAPE_POSITION_MAHA_DIST.tmp
Found broken examples in automatic/SPRINT.tmp
Found broken examples in automatic/TETRAHEDRALPORE.tmp
Found broken examples in automatic/TORSIONS.tmp
Found broken examples in automatic/WHAM_WEIGHTS.tmp
Found broken examples in AnalysisPP.md
Found broken examples in CollectiveVariablesPP.md
Found broken examples in MiscelaneousPP.md

Please sign in to comment.