OPENMP: add /omp variants for analysis computes, angle cosine/buck6d, more pair styles, and QEQ/ORIENT fixes#5009
Conversation
First OpenMP-threaded compute styles in the OPENMP package. Both are per-atom, output-only computes (they write per-atom result arrays and never touch atom->f), so they do not use the ThrOMP/ThrData per-thread force/virial machinery: they subclass the base compute and thread the per-atom loop with a plain "#pragma omp parallel for", relying on the OpenMP runtime thread count that fix omp already sets to comm->nthreads. compute coord/atom/omp threads the three per-atom loops (cutoff ncol==1, cutoff ncol>1, orientorder); each atom writes only its own output slot, so the result is bit-identical to the serial compute. compute orientorder/atom/omp uses per-thread scratch. To make the kernel reentrant, ComputeOrientOrderAtom::calc_boop() now takes the qnm_r/qnm_i accumulators as arguments instead of writing member scratch (select3() was already reentrant); this base change is behavior-preserving. The subclass pre-sizes the per-thread distsq/nearest/rlist and qnm_r/qnm_i buffers before the parallel region (hoisting the lazy reallocation out of the loop) and gives each thread its own slice. Verified bit-identical per-atom output for 1 vs 4 threads at np=1 and np=2, and identical to the serial base compute. Docs: add the OPENMP accelerator letter and /omp variant entries for both computes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Two more per-atom, output-only compute variants (Group A). Each threads its per-atom loop over nlocal with a plain "#pragma omp parallel for"; atoms write only their own output slot, so results are bit-identical to the serial computes. The base member arrays are widened from private to protected so the subclasses can reach them. Verified bit-identical per-atom output for 1 vs 4 threads and identical to the serial base computes; info computes confirms the /omp styles are selected under -sf omp. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Three neighbor-traversing structural-analysis computes (Group B). Each threads its per-atom loop; per-atom neighbor scratch is made thread-local so the reentrant base helpers (select/select2/calc_qn_complex) can be reused safely: - centro/atom/omp: thread-local distsq/nearest/pairs allocated inside the parallel region (both the plain and axes variants). - cna/atom/omp: two threaded phases with an implicit barrier between them (build per-atom nearest[]/nnearest[], then classify reading neighbors' rows); classification scratch is thread-private; the two "too many neighbors" counters use omp reductions, MPI_Allreduce stays collective outside the parallel region. - hexorder/atom/omp: thread-local distsq/nearest. calc_qn_complex/ calc_qn_trig lose their "inline" specifier in the base so the symbols have external linkage and the subclass can call them (the compiler still inlines them within the base translation unit). Each atom writes only its own output slot, so results are bit-identical to the serial computes (verified for 1 vs 4 threads and vs base). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ere/atom/omp Final batch of Group B (EXTRA-COMPUTE) structural-analysis computes. - ackland/atom/omp: thread-local distsq/nearest/nearest_n0/nearest_n1 scratch, per-iteration chi[] histogram; reuses reentrant select2. - cnp/atom/omp: same two-phase pattern as cna/atom/omp (build per-atom nearest[] rows, barrier, then accumulate cnpv[i]) with thread-private common[]/onenearest[] scratch and omp-reduced error counters. - entropy/atom/omp: thread-local g(r) gofr/integrand scratch, shared read-only rbin/rbinsq tables, per-iteration local density (for the local-density option). The optional averaging pass runs as a second omp-for region whose barrier guarantees all pair_entropy[] (including ghosts, spanned by inum+gnum) are filled before averaging. - ave/sphere/atom/omp: all scratch is stack-local per iteration; ghost velocities are forward-communicated before the threaded loop. Each atom writes only its own output, so results are bit-identical to the serial computes (verified 1 vs 4 threads and vs base). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Threads the RDF histogram tally loop (Group D). Each thread accumulates into a private partial histogram; the partials are summed into hist[] before the MPI_Allreduce. Every tally is an increment of 1.0, so the per-thread sums are exact integers and the reduced histogram is bit-identical to the serial compute regardless of thread count. Setup, normalization and the collective MPI_Allreduce remain serial. Verified bit-identical g(r)/coord(r) output for 1 vs 4 threads and vs the serial base compute. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
angle cosine/buck6d adds a buck6d nonbonded 1-3 term that is tallied into the *pair* accumulators (eng_vdwl / pair virial), in addition to the cosine angle term tallied into the angle accumulators -- structurally the angle analogue of dihedral charmm (1-4 nonbonded term). Threading it therefore needs the angle-and-pair combined reduction, so this adds a THR_ANGLE|THR_CHARMM case to ThrOMP::reduce_thr mirroring the existing THR_DIHEDRAL|THR_CHARMM case, and the AngleCosineBuck6dOMP subclass constructs ThrOMP with THR_ANGLE|THR_CHARMM. The eval is templated on EVFLAG/EFLAG/NEWTON_BOND like the other bonded /omp styles; the buck6d 1-3 term uses ev_tally_thr(force->pair, ...) and the angle term uses ev_tally_thr(this, ...). Verified against examples/PACKAGES/mofff (in.hkust1): per-atom forces are bit-identical to the serial base at 1 thread and match to ~5e-12 relative at 4 threads; global eangle, evdwl, ecoul and pressure are bit-identical at 1 and 4 threads; full -sf omp per-atom energy is bit-identical at 1 thread. (Per-atom energy in a hybrid angle at >1 thread carries the same reduction-order behavior as all existing /omp angle substyles.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds OpenMP-threaded variants for coul/long/cs, coul/wolf/cs, born/coul/long/cs, born/coul/dsf/cs, born/coul/wolf/cs, buck/coul/long/cs, lj/cut/coul/long/cs, and lj/class2/coul/long/cs (Tier 1 of the pair-style porting plan: mechanical ports of styles whose non-cs sibling is already threaded). Each /omp eval faithfully reproduces the corresponding SERIAL /cs compute() (the core-shell EPS_EWALD short-range handling and the higher-order B0..B5 erfc approximation), threaded via the standard ThrOMP per-thread force decomposition -- it is NOT derived from the base (non-cs) /omp eval, whose erfc approximation differs. The lj/cut and lj/class2 /cs variants keep respa disabled (respa_enable = 0), matching their base /cs classes. Verified on examples/coreshell (data.coreshell): per-atom forces and per-atom energy are bit-identical to the serial /cs styles at 1 thread and agree to ~1e-13 (round-off) at 4 threads; info/log confirm the /omp styles are selected under -sf omp. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adds OpenMP-threaded variants for lj/class2/soft, lj/class2/coul/cut/soft, lj/class2/coul/long/soft, morse/soft, and coul/cut/soft/gapsys (Tier 1 of the pair-style porting plan; soft-core analogues of the already-threaded lj/cut/soft family used for free-energy perturbation). Each /omp eval reproduces the serial soft-core compute() (the lambda-softened denominators denlj/denc, the morse shift_range branches, and the gapsys inner/outer split) threaded via the standard ThrOMP per-thread force decomposition. respa is disabled to match the base styles. Verified on a small charged FCC test system: per-atom forces and per-atom energy are bit-identical to the serial styles at 1 thread and agree to ~1e-13 (round-off) at 4 threads; -sf omp selects the /omp styles. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Completes Tier 1 of the pair-style porting plan with /omp variants for lj/charmmfsw/coul/long, lj/charmmfsw/coul/charmmfsh, lj/expand/coul/long, nm/cut/split, born/coul/dsf, coul/slater/cut, coul/slater/long, and coul/exclude -- all simple short-range pairwise styles whose non-/omp relatives are already threaded. Each /omp eval reproduces the serial compute() threaded via the standard ThrOMP per-thread force decomposition. As with the existing /omp pair styles, respa is disabled (respa_enable = 0): the styles that support rRESPA in their base class are computed at the outer level under the /omp variant rather than split across levels. Verified on small charged-FCC and bonded test systems: per-atom forces and per-atom energy are bit-identical to the serial styles at 1 thread and agree to round-off at 4 threads; -sf omp selects the /omp styles. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Threads the real-space part of lj/cut/dipole/long (Tier 2 of the pair-style porting plan). The single-pass force + dipole-torque loop is threaded via the standard ThrOMP per-thread force/torque decomposition (thr->get_torque(), ev_tally_xyz_thr), mirroring the existing lj/cut/dipole/cut/omp; the long-range (kspace) half is handled by the already-threaded ewald/disp solver. Verified on a dipolar test system (atom_style dipole + kspace ewald/disp): per-atom forces, torques and per-atom energy are bit-identical to the serial style at 1 thread and agree to ~1e-14 (round-off) at 4 threads; thermo (pe/ecoul/elong/press) bit-identical; -sf omp selects the /omp style. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Fix Tier F1 (QEQ charge equilibration family) and Tier F2 (ORIENT grain-boundary driving force) accelerator variants. QEQ (src/OPENMP/fix_qeq_*_omp): qeq/point, qeq/shielded, qeq/slater, qeq/ctip, qeq/dynamic, qeq/fire. The matrix-based variants thread the H-matrix build (two-pass count -> serial sum-scan offsets -> parallel fill, reproducing the serial packed-CSR layout) and the sparse matrix-vector product (per-thread b_temp buffer for the symmetric transpose scatter, then reduced). The matrix-free variants (dynamic, fire) thread compute_eneg() with the same per-thread accumulation buffer. The base CG / FIRE drivers and all collective MPI comm remain serial. Single charge solves match the serial result to machine precision (~1e-13); residual differences over MD trajectories are at the iterative solver's CG tolerance, the expected behavior for threaded iterative solvers (summation reorder). ORIENT (src/OPENMP/fix_orient_*_omp): orient/fcc, orient/bcc, orient/eco. Phase 1 (per-atom order parameter / Nbr build) threads with per-thread sort scratch and reduced added_energy / neighbor-count statistics. Phase 2 writes only f[i] (it reads neighbor data nbr[m]/nbr[j] acquired via forward_comm but never writes f[m]/f[j]), so the per-atom partition is race-free and needs no per-thread force buffer. orient/fcc and orient/bcc are bit-for-bit identical to the serial result; orient/eco matches to round-off (driven by the accompanying eam/omp pair). These do not use ThrOMP: QEQ fixes do not contribute to atom->f, and the ORIENT phase-2 force is written to disjoint owned-atom slots. Base-class changes are minimal and behavior-preserving: widen private members to protected where the subclass kernels need them; make FixQEqDynamic/FixQEqFire::compute_eneg() protected virtual; move the FixOrientECO::Nbr definition into the header so the subclass can see it. Docs: add /omp index entries, Accelerator Variants lines, and the accel_styles include to fix_qeq.rst, fix_orient.rst, fix_orient_eco.rst; add the (o) accelerator letter in Commands_fix.rst. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR expands the OPENMP package by adding /omp accelerator variants for multiple analysis computes, QEQ/ORIENT fixes, selected pair styles, and angle_style cosine/buck6d, with supporting base-class access/refactoring and documentation updates.
Changes:
- Adds new OPENMP style headers/implementations for computes, fixes, angle, and pair styles.
- Extends
ThrOMP::reduce_thr()for angle styles that also tally pair-style 1-3 terms. - Updates documentation and command indexes to advertise new
/ompvariants.
Reviewed changes
Copilot reviewed 138 out of 138 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
src/QEQ/fix_qeq_shielded.h |
Makes internals accessible to OMP subclass. |
src/QEQ/fix_qeq_fire.h |
Makes compute_eneg() virtual/protected for OMP override. |
src/QEQ/fix_qeq_dynamic.h |
Makes compute_eneg() virtual/protected for OMP override. |
src/ORIENT/fix_orient_fcc.h |
Makes internals accessible to OMP subclass. |
src/ORIENT/fix_orient_eco.h |
Exposes Nbr and internals for OMP subclass. |
src/ORIENT/fix_orient_eco.cpp |
Moves Nbr definition to header. |
src/ORIENT/fix_orient_bcc.h |
Makes internals accessible to OMP subclass. |
src/OPENMP/thr_omp.cpp |
Adds `THR_ANGLE |
src/OPENMP/pair_nm_cut_split_omp.h |
Registers nm/cut/split/omp. |
src/OPENMP/pair_nm_cut_split_omp.cpp |
Implements threaded nm/cut/split. |
src/OPENMP/pair_morse_soft_omp.h |
Registers morse/soft/omp. |
src/OPENMP/pair_morse_soft_omp.cpp |
Implements threaded morse/soft. |
src/OPENMP/pair_lj_expand_coul_long_omp.h |
Registers lj/expand/coul/long/omp. |
src/OPENMP/pair_lj_cut_dipole_long_omp.h |
Registers lj/cut/dipole/long/omp. |
src/OPENMP/pair_lj_cut_coul_long_cs_omp.h |
Registers core-shell LJ/Coul long OMP style. |
src/OPENMP/pair_lj_class2_soft_omp.h |
Registers lj/class2/soft/omp. |
src/OPENMP/pair_lj_class2_soft_omp.cpp |
Implements threaded lj/class2/soft. |
src/OPENMP/pair_lj_class2_coul_long_soft_omp.h |
Registers long Coulomb soft-core class2 OMP style. |
src/OPENMP/pair_lj_class2_coul_long_cs_omp.h |
Registers core-shell class2 Coul long OMP style. |
src/OPENMP/pair_lj_class2_coul_cut_soft_omp.h |
Registers cut Coulomb soft-core class2 OMP style. |
src/OPENMP/pair_lj_class2_coul_cut_soft_omp.cpp |
Implements threaded cut Coulomb soft-core class2 style. |
src/OPENMP/pair_lj_charmmfsw_coul_long_omp.h |
Registers CHARMM force-switch long OMP style. |
src/OPENMP/pair_lj_charmmfsw_coul_charmmfsh_omp.h |
Registers CHARMM force-switch/shift OMP style. |
src/OPENMP/pair_coul_wolf_cs_omp.h |
Registers coul/wolf/cs/omp. |
src/OPENMP/pair_coul_wolf_cs_omp.cpp |
Implements threaded core-shell Wolf Coulomb style. |
src/OPENMP/pair_coul_slater_long_omp.h |
Registers coul/slater/long/omp. |
src/OPENMP/pair_coul_slater_long_omp.cpp |
Implements threaded long-range Slater Coulomb style. |
src/OPENMP/pair_coul_slater_cut_omp.h |
Registers coul/slater/cut/omp. |
src/OPENMP/pair_coul_slater_cut_omp.cpp |
Implements threaded cut Slater Coulomb style. |
src/OPENMP/pair_coul_long_cs_omp.h |
Registers coul/long/cs/omp. |
src/OPENMP/pair_coul_exclude_omp.h |
Registers coul/exclude/omp. |
src/OPENMP/pair_coul_exclude_omp.cpp |
Implements threaded excluded Coulomb correction. |
src/OPENMP/pair_coul_cut_soft_gapsys_omp.h |
Registers Gapsys soft Coulomb OMP style. |
src/OPENMP/pair_coul_cut_soft_gapsys_omp.cpp |
Implements threaded Gapsys soft Coulomb style. |
src/OPENMP/pair_buck_coul_long_cs_omp.h |
Registers core-shell Buck/Coul long OMP style. |
src/OPENMP/pair_born_coul_wolf_cs_omp.h |
Registers core-shell Born/Wolf OMP style. |
src/OPENMP/pair_born_coul_long_cs_omp.h |
Registers core-shell Born/Coul long OMP style. |
src/OPENMP/pair_born_coul_dsf_omp.h |
Registers Born/DSF OMP style. |
src/OPENMP/pair_born_coul_dsf_cs_omp.h |
Registers core-shell Born/DSF OMP style. |
src/OPENMP/fix_qeq_slater_omp.h |
Registers QEQ Slater OMP fix. |
src/OPENMP/fix_qeq_shielded_omp.h |
Registers QEQ shielded OMP fix. |
src/OPENMP/fix_qeq_point_omp.h |
Registers QEQ point OMP fix. |
src/OPENMP/fix_qeq_fire_omp.h |
Registers QEQ FIRE OMP fix. |
src/OPENMP/fix_qeq_fire_omp.cpp |
Implements threaded FIRE electronegativity calculation. |
src/OPENMP/fix_qeq_dynamic_omp.h |
Registers QEQ dynamic OMP fix. |
src/OPENMP/fix_qeq_dynamic_omp.cpp |
Implements threaded dynamic electronegativity calculation. |
src/OPENMP/fix_qeq_ctip_omp.h |
Registers QEQ CTIP OMP fix. |
src/OPENMP/fix_orient_fcc_omp.h |
Registers orient/fcc OMP fix. |
src/OPENMP/fix_orient_eco_omp.h |
Registers orient/eco OMP fix. |
src/OPENMP/fix_orient_bcc_omp.h |
Registers orient/bcc OMP fix. |
src/OPENMP/compute_rdf_omp.h |
Registers RDF OMP compute. |
src/OPENMP/compute_orientorder_atom_omp.h |
Registers orientorder/atom OMP compute with scratch storage. |
src/OPENMP/compute_ke_atom_omp.h |
Registers ke/atom OMP compute. |
src/OPENMP/compute_ke_atom_omp.cpp |
Implements threaded per-atom kinetic energy. |
src/OPENMP/compute_hexorder_atom_omp.h |
Registers hexorder/atom OMP compute. |
src/OPENMP/compute_hexorder_atom_omp.cpp |
Implements threaded hexatic order calculation. |
src/OPENMP/compute_erotate_sphere_atom_omp.h |
Registers sphere rotational energy OMP compute. |
src/OPENMP/compute_erotate_sphere_atom_omp.cpp |
Implements threaded per-atom rotational energy. |
src/OPENMP/compute_entropy_atom_omp.h |
Registers entropy/atom OMP compute. |
src/OPENMP/compute_coord_atom_omp.h |
Registers coord/atom OMP compute. |
src/OPENMP/compute_coord_atom_omp.cpp |
Implements threaded coordination calculation. |
src/OPENMP/compute_cnp_atom_omp.h |
Registers cnp/atom OMP compute. |
src/OPENMP/compute_cna_atom_omp.h |
Registers cna/atom OMP compute. |
src/OPENMP/compute_centro_atom_omp.h |
Registers centro/atom OMP compute. |
src/OPENMP/compute_ave_sphere_atom_omp.h |
Registers ave/sphere/atom OMP compute. |
src/OPENMP/compute_ave_sphere_atom_omp.cpp |
Implements threaded local sphere averaging. |
src/OPENMP/compute_ackland_atom_omp.h |
Registers ackland/atom OMP compute. |
src/OPENMP/angle_cosine_buck6d_omp.h |
Registers cosine/buck6d OMP angle style. |
src/EXTRA-COMPUTE/compute_hexorder_atom.h |
Makes members accessible to OMP subclass. |
src/EXTRA-COMPUTE/compute_hexorder_atom.cpp |
Gives helper methods external linkage. |
src/EXTRA-COMPUTE/compute_entropy_atom.h |
Makes members accessible to OMP subclass. |
src/EXTRA-COMPUTE/compute_cnp_atom.h |
Makes members accessible to OMP subclass. |
src/EXTRA-COMPUTE/compute_ackland_atom.h |
Makes members accessible to OMP subclass. |
src/compute_rdf.h |
Makes RDF internals accessible to OMP subclass. |
src/compute_orientorder_atom.h |
Refactors helper signature for thread-local scratch. |
src/compute_orientorder_atom.cpp |
Updates calc_boop() to use passed accumulators. |
src/compute_ke_atom.h |
Makes KE storage accessible to OMP subclass. |
src/compute_erotate_sphere_atom.h |
Makes sphere rotational storage accessible. |
src/compute_cna_atom.h |
Makes CNA internals accessible to OMP subclass. |
src/compute_centro_atom.h |
Makes centro internals accessible to OMP subclass. |
src/.gitignore |
Adds some installed-copy ignore entries. |
doc/src/pair_nm.rst |
Documents nm/cut/split/omp. |
doc/src/pair_lj_expand.rst |
Documents lj/expand/coul/long/omp. |
doc/src/pair_fep_soft.rst |
Documents soft-core OMP pair variants. |
doc/src/pair_dipole.rst |
Documents lj/cut/dipole/long/omp. |
doc/src/pair_cs.rst |
Documents core-shell OMP pair variants. |
doc/src/pair_coul.rst |
Documents coul/exclude/omp. |
doc/src/pair_coul_slater.rst |
Documents Slater Coulomb OMP variants. |
doc/src/pair_charmm.rst |
Documents CHARMM force-switch OMP variants. |
doc/src/pair_born.rst |
Documents born/coul/dsf/omp. |
doc/src/fix_qeq.rst |
Documents QEQ OMP fix variants. |
doc/src/fix_orient.rst |
Documents orient/fcc and orient/bcc OMP fixes. |
doc/src/fix_orient_eco.rst |
Documents orient/eco OMP fix. |
doc/src/compute_rdf.rst |
Documents RDF OMP compute. |
doc/src/compute_orientorder_atom.rst |
Documents orientorder/atom OMP compute. |
doc/src/compute_ke_atom.rst |
Documents ke/atom OMP compute. |
doc/src/compute_hexorder_atom.rst |
Documents hexorder/atom OMP compute. |
doc/src/compute_erotate_sphere_atom.rst |
Documents sphere rotational OMP compute. |
doc/src/compute_entropy_atom.rst |
Documents entropy/atom OMP compute. |
doc/src/compute_coord_atom.rst |
Documents coord/atom OMP compute. |
doc/src/compute_cnp_atom.rst |
Documents cnp/atom OMP compute. |
doc/src/compute_cna_atom.rst |
Documents cna/atom OMP compute. |
doc/src/compute_centro_atom.rst |
Documents centro/atom OMP compute. |
doc/src/compute_ave_sphere_atom.rst |
Documents ave/sphere/atom OMP compute. |
doc/src/compute_ackland_atom.rst |
Documents ackland/atom OMP compute. |
doc/src/Commands_fix.rst |
Adds OMP markers for new fix variants. |
doc/src/Commands_compute.rst |
Adds OMP markers for new compute variants. |
doc/src/Commands_bond.rst |
Adds OMP marker for cosine/buck6d angle style. |
doc/src/angle_cosine_buck6d.rst |
Documents cosine/buck6d OMP angle variant. |
The compute and angle styles ported to the OPENMP package earlier in this branch declared an "Accelerator Variants:" line and /omp index entries but omitted the ".. include:: accel_styles.rst" directive, which doc/utils/check-styles.py flags. Add the standard include block (between horizontal rules, before the Restrictions section) to the ten affected files: angle cosine/buck6d and computes erotate/sphere/atom, ke/atom, centro/atom, cna/atom, hexorder/atom, ackland/atom, cnp/atom, entropy/atom, and rdf. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
stanmoore1
left a comment
There was a problem hiding this comment.
I approve. @akohlmey are there unit tests for all these new styles?
There should be, but one of my TODO items for the time after the feature release and before the stable release is to make a general audit of testing and code coverage. This will be particularly important after the granular testing PR is merged and all pending KOKKOS porting PRs are merged. I am currently not planning on doing more porting tasks, but rather move on to push the coding agent use into other regions that I have not yet explored. The writing of tutorials appears to be particularly effective: it gives me quite useful and detailed drafts and then I do a thorough evaluation of the tutorial myself and learn a lot of new things in the process. The tutorial created for determining melting points was very educational and taught me about a lot of unexpected pitfalls. Also, in many cases, seeing the draft inspires additional tasks which in turn improve the educational impact way beyond of what simply having a lightly commented (if commented at all) example does. |
Summary
Add OpenMP-threaded (
/omp) variants to the OPENMP package across analysiscomputes, one angle style, and short-range pair styles. Until now the
OPENMP package threaded essentially every mainstream force/neighbor style but
left gaps: no compute style was threaded, and many variant pair styles
(core-shell, soft-core, CHARMM force-switch, dipole, ...) lacked an
/ompcounterpart even though their close relatives had one.
Compute styles (13):
coord/atom/omp,orientorder/atom/omp,ke/atom/omp,erotate/sphere/atom/omp,centro/atom/omp,cna/atom/omp,hexorder/atom/omp,ackland/atom/omp,cnp/atom/omp,entropy/atom/omp,ave/sphere/atom/omp,rdf/omp. These write per-atom output (or aninteger-tallied histogram) and never touch
atom->f, so they thread theper-atom loop with a plain
#pragma omp parallel forand do not use theThrOMP per-thread force machinery.
Angle style (1):
cosine/buck6d/omp(the angle analogue of CHARMMdihedral: a buck6d 1-3 term tallied into the pair accumulators). Supporting it
added a
THR_ANGLE|THR_CHARMMcase toThrOMP::reduce_thrmirroring theexisting
THR_DIHEDRAL|THR_CHARMMcase.Pair styles, Tier 1 (21): mechanical ports of short-range pairwise styles
whose non-
/omprelatives are already threaded:coul/long/cs,coul/wolf/cs,born/coul/long/cs,born/coul/dsf/cs,born/coul/wolf/cs,buck/coul/long/cs,lj/cut/coul/long/cs,lj/class2/coul/long/cs;lj/class2/soft,lj/class2/coul/cut/soft,lj/class2/coul/long/soft,morse/soft,coul/cut/soft/gapsys;lj/charmmfsw/coul/long,lj/charmmfsw/coul/charmmfsh,lj/expand/coul/long,nm/cut/split,born/coul/dsf,coul/slater/cut,coul/slater/long,coul/exclude.Pair styles, Tier 2 (1):
lj/cut/dipole/long/omp-- threads thereal-space force + dipole-torque loop (using
thr->get_torque()/ev_tally_xyz_thr, mirroringlj/cut/dipole/cut/omp); the long-range half ishandled by the already-threaded
ewald/dispsolver.Each pair
/ompeval reproduces its serialcompute()(e.g. the core-shellEPS_EWALDhandling and higher-order B0..B5 erfc, the soft-corelambda-softened denominators, the CHARMM force-switch terms, the dipole
torque) threaded via the standard ThrOMP per-thread force/torque
decomposition; respa is disabled, matching the existing
/omppair-styleconvention.
Fix styles (9): OpenMP variants of the QEQ charge-equilibration family and
the ORIENT grain-boundary driving-force fixes.
qeq/point/omp,qeq/shielded/omp,qeq/slater/omp,qeq/ctip/omp,qeq/dynamic/omp,qeq/fire/omp. The matrix-based variantsthread the
H-matrix build (two-pass count -> serial sum-scan offsets ->parallel fill, reproducing the serial packed-CSR layout) and the sparse
matrix-vector product (a per-thread
b_tempbuffer absorbs the symmetrictranspose scatter, then is reduced). The matrix-free variants (
dynamic,fire) threadcompute_eneg()with the same per-thread buffer. The baseconjugate-gradient / FIRE drivers and all collective MPI communication stay
serial.
orient/fcc/omp,orient/bcc/omp,orient/eco/omp. Phase 1(per-atom order parameter and neighbor-term build) threads with per-thread
sort/gradient scratch and reduced
added_energy/ neighbor-count statistics;phase 2 writes only
f[i]-- it reads neighbor data acquired viaforward_commbut never writesf[m]/f[j]-- so the per-atom partition israce-free and needs no per-thread force buffer.
Neither fix family uses ThrOMP: the QEQ fixes do not contribute to
atom->f,and the ORIENT phase-2 force is written to disjoint owned-atom slots.
Related Issue(s)
None.
Author(s)
Axel Kohlmeyer (Temple University), akohlmey@gmail.com
Licensing
By submitting this pull request, I agree, that my contribution will be included in LAMMPS and redistributed under either the GNU General Public License version 2 (GPL v2) or the GNU Lesser General Public License version 2.1 (LGPL v2.1).
Artificial Intelligence (AI) Tools Usage
The
/ompsubclasses, the supporting base-class refactoring, the newThrOMP::reduce_thrcase, and the documentation updates in this pull requestwere generated with the assistance of an AI tool (Anthropic Claude, via Claude
Code), under the direction and review of the human author. The generated code
was reviewed, built, and verified by the author before submission (see the
Co-Authored-By: Claudetrailers on the commits).Backward Compatibility
No backward-incompatible changes. The PR is additive (new opt-in
/ompstylesselected only under
-sf omp). Edits to existing files are limited to:widening a few
private:members toprotected:in base compute classes;removing the
inlinespecifier from twoComputeHexOrderAtomhelpers so thesymbols have external linkage; making
ComputeOrientOrderAtom::calc_boop()reentrant by passing its accumulators as arguments; adding a new
(purely additive)
THR_ANGLE|THR_CHARMMcase toThrOMP::reduce_thr; widening a fewprivate:members toprotected:in the QEQ and ORIENT fix base classes; makingFixQEqDynamic/FixQEqFire::compute_eneg()protected virtual; and moving theFixOrientECO::Nbrstruct definition into its header so the/ompsubclass can see it.Implementation Notes
Verification: every ported style was checked to produce per-atom forces (and,
where applicable, per-atom torques/energy) that are bit-identical to the
serial style at 1 thread and agree to round-off (~1e-12..1e-13 relative) at
4 threads, at np == 1 and (for the computes) np == 2. Style selection was
confirmed via
info computes/infoand the log. Pair styles were tested onthe
examples/coreshellsystem and on small charged-FCC / bonded / dipolarsystems; the angle on
examples/PACKAGES/mofff. The fix/ompvariants were verified the same way:orient/fccandorient/bccare bit-identical to serial (per-atom force and order parameter),orient/ecoagrees to round-off, and the QEQ single charge solve matches serial to ~1e-13 with MD-trajectory differences bounded by the conjugate-gradient tolerance (the expected behavior for a threaded iterative solver); QEQ was tested onexamples/qeqandexamples/streitz, ORIENT onexamples/PACKAGES/orient_ecoand small fcc/bcc bicrystal setups.make check-whitespace/check-permissionsare clean; the build was verified with CMake(
-D PKG_OPENMP=on -D BUILD_OMP=on, plus FEP / MOFFF / CORESHELL / KSPACE /DIPOLE / MANYBODY).
Post Submission Checklist