Hi all,
It seems in the current version of the code that issues arise with the OMP version of bond_styles when a processor has a bondlist of length zero. In the attached example, "bond_style hybrid harmonic morse" is used. Most of the system (water) is composed of harmonic bonds, except for one small molecule (hydronium), which is composed of morse bonds. If the example is run on more than 1 processor with the omp package, then all processors that have a morse bondlist of length zero will run into trouble at this line near the beginning of BondMorseOMP::eval
const int3_t * _noalias const bondlist = (int3_t *) neighbor->bondlist[0];
A quick fix seems to be adding the following statement just before the offending line.
if(nto == 0) return; // no bonds to evaluate
const int3_t * _noalias const bondlist = (int3_t *) neighbor->bondlist[0];
After a quick glance, this issue would seem to also be present in all of the bond, angle, dihedral, and improper potentials in the USER-OMP package.
Is this reproducible by others?
chris
lmp.in (1.01 KB)
lmp.data (109 KB)
hi chris,
Hi all,
It seems in the current version of the code that issues arise with the OMP version of bond_styles when a processor has a bondlist of length zero. In the attached example, "bond_style hybrid harmonic morse" is used. Most of the system (water) is composed of harmonic bonds, except for one small molecule (hydronium), which is composed of morse bonds. If the example is run on more than 1 processor with the omp package, then all processors that have a morse bondlist of length zero will run into trouble at this line near the beginning of BondMorseOMP::eval
const int3_t * _noalias const bondlist = (int3_t *) neighbor->bondlist[0];
A quick fix seems to be adding the following statement just before the offending line.
yup. this is a definite bug that was introduced recently when adding
some optimizations. lammps stores a lot of things in arrays of arrays
(AoA) which help the code to look like it would be in fortran. and
same as in fortran theses arrays (when dimensioned fortran 77 style)
are based on a flat storage. however, the AoA layout in C/C++ leads to
the compiler not knowing whether the pointers in the leftmost
dimensions point to overlapping or non-overlapping storage, so it has
to assume that data is volatile and needs to be refetched from memory
all the time. by recasting those arrays of arrays into arrays of a
struct (AoS) and labeling that the AoS does not alias with other
arrays, the compiler can generate more efficient code (even better
would be to have a struct of arrays (SoA) layout, as that would allow
vectorization, too, but that is not possible with a simple cast, but
requires a massive rewrite).
thanks for pointing out the issue, i'll start working on a proper bugfix ASAP
if(nto == 0) return; // no bonds to evaluate
const int3_t * _noalias const bondlist = (int3_t *) neighbor->bondlist[0];
yup. that would do, but a better solution is avoid the parallel region
altogether.
axel.
bugfix is now available in LAMMPS-ICMS. will send to steve for
inclusion into the official sources ASAP.
http://git.icms.temple.edu/git/?p=lammps-icms.git;a=commitdiff;h=32f9fc8afc872418e542cb5695cf82b92899e928
axel.