Skip to content

Commit 8628615

Browse files
Gareth Aneurin TribelloGareth Aneurin Tribello
Gareth Aneurin Tribello
authored and
Gareth Aneurin Tribello
committed
Store copies large vectors in ActionWithVector so that we can avoid a lot of malloc and optimise the code
1 parent 46f53ba commit 8628615

8 files changed

+41
-56
lines changed

src/adjmat/TopologyMatrix.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ double TopologyMatrix::calculateWeight( const Vector& pos1, const Vector& pos2,
127127
// Now run through all sea atoms
128128
HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( kerneltype );
129129
Vector g1derivf,g2derivf,lderivf; Tensor vir; double binlength = maxbins * binw_mat;
130-
MultiValue tvals( maxbins, myvals.getNumberOfDerivatives() );
130+
MultiValue tvals; tvals.resize( maxbins, myvals.getNumberOfDerivatives() );
131131
for(unsigned i=0; i<natoms; ++i) {
132132
// Position of sea atom (this will be the origin)
133133
Vector d2 = getPosition(i,myvals);

src/core/ActionWithVector.cpp

+27-24
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ void ActionWithVector::runAllTasks() {
191191
unsigned nt=OpenMP::getNumThreads();
192192
if( nt*stride*10>nactive_tasks ) nt=nactive_tasks/stride/10;
193193
if( nt==0 ) nt=1;
194+
if( myvals.size()!=nt ) myvals.resize(nt);
194195

195196
// Get the total number of streamed quantities that we need
196197
// Get size for buffer
@@ -210,28 +211,31 @@ void ActionWithVector::runAllTasks() {
210211

211212
// Recover the number of derivatives we require
212213
if( !doNotCalculateDerivatives() && !gridsInStream ) {
214+
unsigned nargs = getNumberOfArguments(); int nmasks=getNumberOfMasks();
215+
if( nargs>=nmasks && nmasks>0 ) nargs = nargs - nmasks;
213216
if( getNumberOfAtoms()>0 ) nderivatives += 3*getNumberOfAtoms() + 9;
214217
for(unsigned i=0; i<getNumberOfArguments(); ++i) nderivatives += getPntrToArgument(i)->getNumberOfValues();
215218
}
216219

217220
#pragma omp parallel num_threads(nt)
218221
{
219222
std::vector<double> omp_buffer;
223+
const unsigned t=OpenMP::getThreadNum();
220224
if( nt>1 ) omp_buffer.resize( bufsize, 0.0 );
221-
MultiValue myvals( getNumberOfComponents(), nderivatives, 0 );
222-
myvals.clearAll();
225+
if( myvals[t].getNumberOfValues()!=getNumberOfComponents() || myvals[t].getNumberOfDerivatives()!=nderivatives ) myvals[t].resize( getNumberOfComponents(), nderivatives );
226+
myvals[t].clearAll();
223227

224228
#pragma omp for nowait
225229
for(unsigned i=rank; i<nactive_tasks; i+=stride) {
226230
// Calculate the stuff in the loop for this action
227-
runTask( partialTaskList[i], myvals );
231+
runTask( partialTaskList[i], myvals[t] );
228232

229233
// Now transfer the data to the actions that accumulate values from the calculated quantities
230-
if( nt>1 ) gatherAccumulators( partialTaskList[i], myvals, omp_buffer );
231-
else gatherAccumulators( partialTaskList[i], myvals, buffer );
234+
if( nt>1 ) gatherAccumulators( partialTaskList[i], myvals[t], omp_buffer );
235+
else gatherAccumulators( partialTaskList[i], myvals[t], buffer );
232236

233237
// Clear the value
234-
myvals.clearAll();
238+
myvals[t].clearAll();
235239
}
236240
#pragma omp critical
237241
if( nt>1 ) for(unsigned i=0; i<bufsize; ++i) buffer[i]+=omp_buffer[i];
@@ -349,18 +353,14 @@ bool ActionWithVector::checkForForces() {
349353
unsigned nt=OpenMP::getNumThreads();
350354
if( nt*stride*10>nf_tasks ) nt=nf_tasks/stride/10;
351355
if( nt==0 ) nt=1;
356+
if( myvals.size()!=nt ) myvals.resize(nt);
357+
if( omp_forces.size()!=nt ) omp_forces.resize(nt);
352358

353-
// Now determine how big the multivalue needs to be
354-
unsigned nmatrices=0; ActionWithMatrix* am=dynamic_cast<ActionWithMatrix*>(this);
355-
if(am) {
356-
for(unsigned i=0; i<getNumberOfComponents(); ++i) {
357-
if( getConstPntrToComponent(i)->getRank()==2 && !getConstPntrToComponent(i)->hasDerivatives() ) { nmatrices=getNumberOfComponents(); }
358-
}
359-
}
360359
// Recover the number of derivatives we require (this should be equal to the number of forces)
361-
unsigned nderiv=0;
360+
unsigned nderiv=0, nargs = getNumberOfArguments(); int nmasks = getNumberOfMasks();
361+
if( nargs>=nmasks && nmasks>0 ) nargs = nargs - nmasks;
362362
if( getNumberOfAtoms()>0 ) nderiv += 3*getNumberOfAtoms() + 9;
363-
for(unsigned i=0; i<getNumberOfArguments(); ++i) {
363+
for(unsigned i=0; i<nargs; ++i) {
364364
nderiv += getPntrToArgument(i)->getNumberOfStoredValues();
365365
}
366366
if( forcesForApply.size()!=nderiv ) forcesForApply.resize( nderiv );
@@ -369,23 +369,26 @@ bool ActionWithVector::checkForForces() {
369369

370370
#pragma omp parallel num_threads(nt)
371371
{
372-
std::vector<double> omp_forces;
373-
if( nt>1 ) omp_forces.resize( forcesForApply.size(), 0.0 );
374-
MultiValue myvals( getNumberOfComponents(), nderiv, nmatrices );
375-
myvals.clearAll();
372+
const unsigned t=OpenMP::getThreadNum();
373+
if( nt>1 ) {
374+
if( omp_forces[t].size()!=forcesForApply.size() ) omp_forces[t].resize( forcesForApply.size(), 0.0 );
375+
else omp_forces[t].assign( forcesForApply.size(), 0.0 );
376+
}
377+
if( myvals[t].getNumberOfValues()!=getNumberOfComponents() || myvals[t].getNumberOfDerivatives()!=nderiv ) myvals[t].resize( getNumberOfComponents(), nderiv );
378+
myvals[t].clearAll();
376379

377380
#pragma omp for nowait
378381
for(unsigned i=rank; i<nf_tasks; i+=stride) {
379-
runTask( force_tasks[i], myvals );
382+
runTask( force_tasks[i], myvals[t] );
380383

381384
// Now get the forces
382-
if( nt>1 ) gatherForces( force_tasks[i], myvals, omp_forces );
383-
else gatherForces( force_tasks[i], myvals, forcesForApply );
385+
if( nt>1 ) gatherForces( force_tasks[i], myvals[t], omp_forces[t] );
386+
else gatherForces( force_tasks[i], myvals[t], forcesForApply );
384387

385-
myvals.clearAll();
388+
myvals[t].clearAll();
386389
}
387390
#pragma omp critical
388-
if(nt>1) for(unsigned i=0; i<forcesForApply.size(); ++i) forcesForApply[i]+=omp_forces[i];
391+
if(nt>1) for(unsigned i=0; i<forcesForApply.size(); ++i) forcesForApply[i]+=omp_forces[t][i];
389392
}
390393
// MPI Gather on forces
391394
if( !serial ) comm.Sum( forcesForApply );

src/core/ActionWithVector.h

+4
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ class ActionWithVector:
4545
bool forwardPass;
4646
/// The buffer that we use (we keep a copy here to avoid resizing)
4747
std::vector<double> buffer;
48+
/// A tempory vector of MultiValue so we can avoid doing lots of resizes
49+
std::vector<MultiValue> myvals;
50+
/// A tempory set of vectors for holding forces over threads
51+
std::vector<std::vector<double> > omp_forces;
4852
/// The list of active tasks
4953
std::vector<unsigned> active_tasks;
5054
/// Clear all the bookeeping arrays

src/function/FunctionOfVector.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,9 @@ void FunctionOfVector<T>::prepare() {
172172

173173
template <class T>
174174
void FunctionOfVector<T>::performTask( const unsigned& current, MultiValue& myvals ) const {
175-
unsigned argstart=myfunc.getArgStart(); std::vector<double> args( getNumberOfArguments()-argstart);
176-
for(unsigned i=argstart; i<getNumberOfArguments(); ++i) {
175+
unsigned nargs=getNumberOfArguments(); if( getNumberOfMasks()>0 ) nargs = nargs - getNumberOfMasks();
176+
unsigned argstart=myfunc.getArgStart(); std::vector<double> args( nargs-argstart);
177+
for(unsigned i=argstart; i<nargs; ++i) {
177178
if( getPntrToArgument(i)->getRank()==1 ) args[i-argstart]=getPntrToArgument(i)->get(current);
178179
else args[i-argstart] = getPntrToArgument(i)->get();
179180
}

src/refdist/MatrixProductDiagonal.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ void MatrixProductDiagonal::performTask( const unsigned& task_index, MultiValue&
127127
void MatrixProductDiagonal::calculate() {
128128
if( getPntrToArgument(1)->getRank()==1 ) {
129129
unsigned nder = getNumberOfDerivatives();
130-
MultiValue myvals( 1, nder, 0 ); performTask( 0, myvals );
130+
MultiValue myvals; myvals.resize( 1, nder ); performTask( 0, myvals );
131131

132132
Value* myval=getPntrToComponent(0); myval->set( myvals.get(0) );
133133
for(unsigned i=0; i<nder; ++i) myval->setDerivative( i, myvals.getDerivative(0,i) );

src/secondarystructure/SecondaryStructureRMSD.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -188,9 +188,6 @@ void SecondaryStructureRMSD::calculate() {
188188
}
189189

190190
void SecondaryStructureRMSD::performTask( const unsigned& current, MultiValue& myvals ) const {
191-
// Resize the derivatives if need be
192-
unsigned nderi = 3*getNumberOfAtoms()+9;
193-
if( myvals.getNumberOfDerivatives()!=nderi ) myvals.resize( myvals.getNumberOfValues(), nderi, 0 );
194191
// Retrieve the positions
195192
const unsigned natoms = colvar_atoms[current].size();
196193
std::vector<Vector> pos( natoms ), deriv( natoms );

src/tools/MultiValue.cpp

+3-23
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,11 @@
2424

2525
namespace PLMD {
2626

27-
MultiValue::MultiValue( const size_t& nvals, const size_t& nder, const size_t& nmat ):
28-
task_index(0),
29-
task2_index(0),
30-
values(nvals),
31-
nderivatives(nder),
32-
derivatives(nvals*nder),
33-
hasderiv(nvals*nder,false),
34-
nactive(nvals),
35-
active_list(nvals*nder),
36-
atLeastOneSet(false),
37-
vector_call(false),
38-
nindices(0),
39-
nsplit(0),
40-
matrix_force_stash(0),
41-
matrix_row_nderivatives(0),
42-
matrix_row_derivative_indices(nder)
43-
{
44-
if( nmat>0 ) matrix_force_stash.resize(nder,0);
45-
}
46-
47-
void MultiValue::resize( const size_t& nvals, const size_t& nder, const size_t& nmat ) {
48-
if( values.size()==nvals && nderivatives==nder ) return;
27+
void MultiValue::resize( const size_t& nvals, const size_t& nder ) {
28+
if( values.size()==nvals && nderivatives>nder ) return;
4929
values.resize(nvals); nderivatives=nder; derivatives.resize( nvals*nder );
5030
hasderiv.resize(nvals*nder,false); nactive.resize(nvals); active_list.resize(nvals*nder);
51-
if( nmat>0 ) matrix_force_stash.resize(nder,0);
31+
matrix_force_stash.resize(nder,0);
5232
matrix_row_nderivatives=0; matrix_row_derivative_indices.resize(nder); atLeastOneSet=false;
5333
}
5434

src/tools/MultiValue.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,8 @@ class MultiValue {
6262
std::vector<Tensor> tmp_atom_virial;
6363
std::vector<std::vector<double> > tmp_vectors;
6464
public:
65-
MultiValue( const std::size_t& nvals, const std::size_t& nder, const std::size_t& nmat=0 );
66-
void resize( const std::size_t& nvals, const std::size_t& nder, const std::size_t& nmat=0 );
65+
MultiValue() : task_index(0), task2_index(0), nderivatives(0), atLeastOneSet(false), vector_call(false), nindices(0), nsplit(0), matrix_row_nderivatives(0) {}
66+
void resize( const std::size_t& nvals, const std::size_t& nder );
6767
/// Set the task index prior to the loop
6868
void setTaskIndex( const std::size_t& tindex );
6969
///

0 commit comments

Comments
 (0)