From 5b0c43108d161baaf77c69c3c786b882dd85f94b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Wed, 12 Dec 2018 16:39:27 -0500 Subject: [PATCH] detect missing initialization and run it instead of crashing with a non-descript segfault --- src/compute_reduce.cpp | 20 ++++++-- src/compute_reduce_chunk.cpp | 97 ++++++++++++++++++++--------------- src/compute_reduce_region.cpp | 13 ++++- 3 files changed, 82 insertions(+), 48 deletions(-) diff --git a/src/compute_reduce.cpp b/src/compute_reduce.cpp index e3c3c5b70a..16dc84628a 100644 --- a/src/compute_reduce.cpp +++ b/src/compute_reduce.cpp @@ -30,8 +30,8 @@ using namespace LAMMPS_NS; -enum{SUM,SUMSQ,MINN,MAXX,AVE,AVESQ}; // also in ReduceRegion -enum{X,V,F,COMPUTE,FIX,VARIABLE}; +enum{SUM,SUMSQ,MINN,MAXX,AVE,AVESQ}; // also in ComputeReduceRegion +enum{UNKNOWN=-1,X,V,F,COMPUTE,FIX,VARIABLE}; enum{PERATOM,LOCAL}; #define INVOKED_VECTOR 2 @@ -92,6 +92,10 @@ ComputeReduce::ComputeReduce(LAMMPS *lmp, int narg, char **arg) : flavor = new int[nargnew]; ids = new char*[nargnew]; value2index = new int[nargnew]; + for (int i=0; i < nargnew; ++i) { + which[i] = argindex[i] = flavor[i] = value2index[i] = UNKNOWN; + ids[i] = NULL; + } nvalues = 0; iarg = 0; @@ -345,7 +349,7 @@ void ComputeReduce::init() error->all(FLERR,"Variable name for compute reduce does not exist"); value2index[m] = ivariable; - } else value2index[m] = -1; + } else value2index[m] = UNKNOWN; } // set index and check validity of region @@ -468,8 +472,16 @@ double ComputeReduce::compute_one(int m, int flag) index = -1; int vidx = value2index[m]; - int aidx = argindex[m]; + // initialization in case it has not yet been run, e.g. when + // the compute was invoked right after it has been created + + if (vidx == UNKNOWN) { + init(); + vidx = value2index[m]; + } + + int aidx = argindex[m]; int *mask = atom->mask; int nlocal = atom->nlocal; diff --git a/src/compute_reduce_chunk.cpp b/src/compute_reduce_chunk.cpp index 32c4d9c786..f31672ef74 100644 --- a/src/compute_reduce_chunk.cpp +++ b/src/compute_reduce_chunk.cpp @@ -28,7 +28,7 @@ using namespace LAMMPS_NS; enum{SUM,MINN,MAXX}; -enum{COMPUTE,FIX,VARIABLE}; +enum{UNKNOWN=-1,COMPUTE,FIX,VARIABLE}; #define INVOKED_PERATOM 8 @@ -74,6 +74,10 @@ ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) : argindex = new int[nargnew]; ids = new char*[nargnew]; value2index = new int[nargnew]; + for (int i=0; i < nargnew; ++i) { + which[i] = argindex[i] = value2index[i] = UNKNOWN; + ids[i] = NULL; + } nvalues = 0; iarg = 0; @@ -123,46 +127,46 @@ ComputeReduceChunk::ComputeReduceChunk(LAMMPS *lmp, int narg, char **arg) : if (which[i] == COMPUTE) { int icompute = modify->find_compute(ids[i]); if (icompute < 0) - error->all(FLERR,"Compute ID for compute reduce/chunk does not exist"); + error->all(FLERR,"Compute ID for compute reduce/chunk does not exist"); if (!modify->compute[icompute]->peratom_flag) - error->all(FLERR,"Compute reduce/chunk compute does not " - "calculate per-atom values"); + error->all(FLERR,"Compute reduce/chunk compute does not " + "calculate per-atom values"); if (argindex[i] == 0 && - modify->compute[icompute]->size_peratom_cols != 0) - error->all(FLERR,"Compute reduce/chunk compute does not " - "calculate a per-atom vector"); + modify->compute[icompute]->size_peratom_cols != 0) + error->all(FLERR,"Compute reduce/chunk compute does not " + "calculate a per-atom vector"); if (argindex[i] && modify->compute[icompute]->size_peratom_cols == 0) - error->all(FLERR,"Compute reduce/chunk compute does not " - "calculate a per-atom array"); + error->all(FLERR,"Compute reduce/chunk compute does not " + "calculate a per-atom array"); if (argindex[i] && argindex[i] > modify->compute[icompute]->size_peratom_cols) - error->all(FLERR, - "Compute reduce/chunk compute array is accessed out-of-range"); + error->all(FLERR, + "Compute reduce/chunk compute array is accessed out-of-range"); } else if (which[i] == FIX) { int ifix = modify->find_fix(ids[i]); if (ifix < 0) - error->all(FLERR,"Fix ID for compute reduce/chunk does not exist"); + error->all(FLERR,"Fix ID for compute reduce/chunk does not exist"); if (!modify->fix[ifix]->peratom_flag) - error->all(FLERR,"Compute reduce/chunk fix does not " - "calculate per-atom values"); + error->all(FLERR,"Compute reduce/chunk fix does not " + "calculate per-atom values"); if (argindex[i] == 0 && - modify->fix[ifix]->size_peratom_cols != 0) - error->all(FLERR,"Compute reduce/chunk fix does not " - "calculate a per-atom vector"); + modify->fix[ifix]->size_peratom_cols != 0) + error->all(FLERR,"Compute reduce/chunk fix does not " + "calculate a per-atom vector"); if (argindex[i] && modify->fix[ifix]->size_peratom_cols == 0) - error->all(FLERR,"Compute reduce/chunk fix does not " - "calculate a per-atom array"); + error->all(FLERR,"Compute reduce/chunk fix does not " + "calculate a per-atom array"); if (argindex[i] && argindex[i] > modify->fix[ifix]->size_peratom_cols) - error->all(FLERR,"Compute reduce/chunk fix array is " + error->all(FLERR,"Compute reduce/chunk fix array is " "accessed out-of-range"); } else if (which[i] == VARIABLE) { int ivariable = input->variable->find(ids[i]); if (ivariable < 0) - error->all(FLERR,"Variable name for compute reduce/chunk does not exist"); + error->all(FLERR,"Variable name for compute reduce/chunk does not exist"); if (input->variable->atomstyle(ivariable) == 0) - error->all(FLERR,"Compute reduce/chunk variable is " + error->all(FLERR,"Compute reduce/chunk variable is " "not atom-style variable"); } } @@ -354,10 +358,19 @@ void ComputeReduceChunk::compute_one(int m, double *vchunk, int nstride) int *mask = atom->mask; int nlocal = atom->nlocal; - int index; + int index = -1; + int vidx = value2index[m]; + + // initialization in case it has not yet been run, e.g. when + // the compute was invoked right after it has been created + + if (vidx == UNKNOWN) { + init(); + vidx = value2index[m]; + } if (which[m] == COMPUTE) { - Compute *compute = modify->compute[value2index[m]]; + Compute *compute = modify->compute[vidx]; if (!(compute->invoked_flag & INVOKED_PERATOM)) { compute->compute_peratom(); @@ -367,26 +380,26 @@ void ComputeReduceChunk::compute_one(int m, double *vchunk, int nstride) if (argindex[m] == 0) { double *vcompute = compute->vector_atom; for (int i = 0; i < nlocal; i++) { - if (!(mask[i] & groupbit)) continue; - index = ichunk[i]-1; - if (index < 0) continue; - combine(vchunk[index*nstride],vcompute[i]); + if (!(mask[i] & groupbit)) continue; + index = ichunk[i]-1; + if (index < 0) continue; + combine(vchunk[index*nstride],vcompute[i]); } } else { double **acompute = compute->array_atom; int argindexm1 = argindex[m] - 1; for (int i = 0; i < nlocal; i++) { - if (!(mask[i] & groupbit)) continue; - index = ichunk[i]-1; - if (index < 0) continue; - combine(vchunk[index*nstride],acompute[i][argindexm1]); + if (!(mask[i] & groupbit)) continue; + index = ichunk[i]-1; + if (index < 0) continue; + combine(vchunk[index*nstride],acompute[i][argindexm1]); } } // access fix fields, check if fix frequency is a match } else if (which[m] == FIX) { - Fix *fix = modify->fix[value2index[m]]; + Fix *fix = modify->fix[vidx]; if (update->ntimestep % fix->peratom_freq) error->all(FLERR,"Fix used in compute reduce/chunk not " "computed at compatible time"); @@ -394,19 +407,19 @@ void ComputeReduceChunk::compute_one(int m, double *vchunk, int nstride) if (argindex[m] == 0) { double *vfix = fix->vector_atom; for (int i = 0; i < nlocal; i++) { - if (!(mask[i] & groupbit)) continue; - index = ichunk[i]-1; - if (index < 0) continue; - combine(vchunk[index*nstride],vfix[i]); + if (!(mask[i] & groupbit)) continue; + index = ichunk[i]-1; + if (index < 0) continue; + combine(vchunk[index*nstride],vfix[i]); } } else { double **afix = fix->array_atom; int argindexm1 = argindex[m] - 1; for (int i = 0; i < nlocal; i++) { - if (!(mask[i] & groupbit)) continue; - index = ichunk[i]-1; - if (index < 0) continue; - combine(vchunk[index*nstride],afix[i][argindexm1]); + if (!(mask[i] & groupbit)) continue; + index = ichunk[i]-1; + if (index < 0) continue; + combine(vchunk[index*nstride],afix[i][argindexm1]); } } @@ -419,7 +432,7 @@ void ComputeReduceChunk::compute_one(int m, double *vchunk, int nstride) memory->create(varatom,maxatom,"reduce/chunk:varatom"); } - input->variable->compute_atom(value2index[m],igroup,varatom,1,0); + input->variable->compute_atom(vidx,igroup,varatom,1,0); for (int i = 0; i < nlocal; i++) { if (!(mask[i] & groupbit)) continue; index = ichunk[i]-1; diff --git a/src/compute_reduce_region.cpp b/src/compute_reduce_region.cpp index 77cd6371c6..3dd671ce2b 100644 --- a/src/compute_reduce_region.cpp +++ b/src/compute_reduce_region.cpp @@ -28,8 +28,8 @@ using namespace LAMMPS_NS; -enum{SUM,SUMSQ,MINN,MAXX,AVE,AVESQ}; // also in ComputeReduce -enum{X,V,F,COMPUTE,FIX,VARIABLE}; +enum{SUM,SUMSQ,MINN,MAXX,AVE,AVESQ}; // also in ComputeReduce +enum{UNKNOWN=-1,X,V,F,COMPUTE,FIX,VARIABLE}; enum{PERATOM,LOCAL}; #define INVOKED_VECTOR 2 @@ -70,6 +70,15 @@ double ComputeReduceRegion::compute_one(int m, int flag) int nlocal = atom->nlocal; int n = value2index[m]; + + // initialization in case it has not yet been run, + // e.g. when invoked + if (n == UNKNOWN) { + init(); + n = value2index[m]; + } + + int aidx = argindex[m]; int j = argindex[m]; double one = 0.0;