Skip to content

Merge patch_2Sept2026 into oxdrh - #41

Closed
ohenrich wants to merge 367 commits into
oxdrhfrom
develop
Closed

Merge patch_2Sept2026 into oxdrh#41
ohenrich wants to merge 367 commits into
oxdrhfrom
develop

Conversation

@ohenrich

@ohenrich ohenrich commented Sep 3, 2026

Copy link
Copy Markdown
Owner

No description provided.

akohlmey and others added 30 commits August 25, 2026 07:03
…hake

The host pack/unpack pair for the SHAKE unconstrained coordinates brings
xshake to the host before reading it and claims the host side after writing
it.  The device pair did neither: the pack read the device copy without
bringing it up to date, and the unpack wrote the ghost coordinates there
without claiming them.

Today the sequence in post_force() hides this, because
unconstrained_update() claims the device side immediately before the
communication, so the device copy happens to be the current one and the
sync that follows the communication has nothing to do.  Nothing in either
routine relies on that, though, and if the host side is the current one on
entry the pack sends whatever the device copy last held and the sync after
the communication then discards the ghosts the unpack just wrote.

Results are unchanged on a host-only build, where the two sides share an
allocation.
ModifyKokkos::energy_couple() and ModifyKokkos::energy_global() marked
the atom data listed in a fix's datamask_modify as modified after calling
compute_scalar(), but they were the only ModifyKokkos wrappers that did
not sync that fix's datamask_read first.  When the data was still dirty
on the host, marking it modified on the device triggered:

  Kokkos::DualView::modify_device ERROR: Concurrent modification of host
  and device views in DualView "atom:f"

This is reached with "fix langevin" plus "econserve" in thermo_style and
a "minimize" command: MinKokkos::setup() turns auto_sync off, then
ModifyKokkos::setup() marks all atom data as modified on the host for the
internal MINIMIZE/kk fix (it uses the default Host execution space and
ALL_MASK datamasks), and the following thermo output calls energy_couple()
which marks atom->f as modified on the device without syncing.

Add the missing sync to both routines, matching all other ModifyKokkos
wrappers.
FixMinimizeKokkos left datamask_read and datamask_modify at the Fix
defaults of ALL_MASK, with the default Host execution space.  The fix
has setmask() == 0 and overrides none of the callbacks Modify invokes,
and it syncs the atom data it does touch itself (reset_coords() syncs
X_MASK; grow_arrays(), copy_arrays() and the exchange routines only
touch its own vectors).  So the masks describe atom data the fix never
accesses through Modify.

The consequence is that ModifyKokkos::setup(), which loops over all
fixes, syncs all atom data to the host and then marks all of it as
modified on the host for this fix.  MINIMIZE/kk is added by Min::init()
and is therefore always the last fix in the list, so nothing in that
loop syncs the data back, and MinKokkos::setup() has turned auto_sync
off.  Every atom array is then left dirty on the host for the rest of
minimization setup, which is how the concurrent host/device modification
of atom->f reported in issue lammps#5080 came about.

Declare both masks EMPTY_MASK, as all other Kokkos fixes that manage
their own syncing do.
…tructors

The atom_vec_*_kokkos classes cache the per-atom arrays of the
corresponding atom->... fields and refresh them in grow_pointers().
Their constructors left those members uninitialized, so the pointers
are indeterminate if the object is destroyed or re-grown before
grow_pointers() first runs.  Coverity flags each constructor with
UNINIT (uninitialized pointer field).

Initialize the members to nullptr in the constructor initializer
lists, in declaration order.  AtomVecHybridKokkos already did this
for stylesKK.

Fixes lammps#5055
PairTIP4PKokkos::prepare() called ev_init() with the default alloc = 1,
so Pair::ev_setup() allocated the plain base-class eatom and vatom
arrays.  prepare() then replaced those pointers with Kokkos dual views
via destroy_kokkos()/create_kokkos(); since destroy_kokkos() only
clears the pointer, the plain allocations were orphaned and never
freed.  On a later reallocation Pair::ev_setup() would in addition call
memory->destroy() on a Kokkos-owned pointer.

Pass alloc = 0, as all other KOKKOS pair styles do, so the per-atom
arrays are managed only through k_eatom/k_vatom.

This affects tip4p/cut/kk, tip4p/long/kk, lj/cut/tip4p/cut/kk and
lj/cut/tip4p/long/kk.  Verified with valgrind on all four styles with
per-atom energy and virial output enabled; forces, energies and
stresses are unchanged.  The corresponding leak in pace/kk was already
fixed separately.

Fixes lammps#5062
FixPropertyAtomKokkos left datamask_read and datamask_modify at the Fix
defaults of ALL_MASK, with the default Host execution space, the same way
the internal MINIMIZE/kk fix did.  The fix has setmask() == 0 and
overrides none of the callbacks Modify invokes, and the per-atom arrays
it owns are synced through AtomKokkos::sync() and AtomKokkos::modified(),
which call into its own sync() and modified() rather than consulting the
datamasks.  So the masks describe atom data the fix never accesses
through Modify.

ModifyKokkos::setup() loops over all fixes and therefore marks every atom
array as modified on the host for this fix.  When "fix property/atom" is
the last fix defined, nothing later in that loop syncs the data back, and
the atom data stays dirty on the host through thermo output.  Reading
econserve then marks atom->f as modified on the device and aborts with a
concurrent host/device modification, the same failure as issue lammps#5080 but
reachable from a plain run, with no minimize involved.

Declare both masks EMPTY_MASK, as all other Kokkos fixes that manage
their own syncing do.
…ixes

The KOKKOS fixes that keep the per-atom virial in a Kokkos dual view
first let the base class allocate the plain vatom array and then
replaced the pointer with destroy_kokkos()/create_kokkos().  Since
destroy_kokkos() only clears the pointer, the plain allocation was
orphaned and never freed.  This is the same defect as in the tip4p/kk
and pace/kk pair styles, where Pair::ev_setup() already takes an alloc
argument to suppress the allocation.

Give Fix::ev_setup() and Fix::v_setup() (and the ev_init()/v_init()
wrappers) the same alloc argument, defaulting to 1 so that all other
fixes are unaffected, and pass alloc = 0 from fix shake/kk, fix
efield/kk and fix wall/region/kk.

For the fix wall styles the per-atom virial was additionally allocated
before FixWall::post_force() called v_init(), i.e. before vflag_atom
was known.  On the first invocation with per-atom virial output the
dual view was therefore still empty while the kernels tallied into it,
which segfaulted:

  fix wf all wall/lj93 zlo -9.0 1.0 1.0 6.0 units box
  compute st all stress/atom NULL fix

Add a v_setup_peratom() hook to FixWall that the accelerated styles
override, so the dual view is (re)allocated after v_init() has set the
flags.  fix wall/harmonic/kk, wall/lj93/kk, wall/lj126/kk,
wall/lj1043/kk and wall/morse/kk now reproduce the per-atom virial of
their CPU counterparts exactly.

Also drop a duplicated v_init() call in fix wall/region/kk and correct
two copy-and-paste memory labels in fix shake/kk.

Verified with valgrind on all eight styles: no bytes definitely lost,
no invalid reads or writes.  Per-atom and global virial, energy and
thermo output are identical to the plain CPU styles, and the KOKKOS
results of examples/{melt,micelle,indent,min,crack} are unchanged.
…dforce/kk

Three defects in fix addforce/kk, found while auditing the per-atom
virial handling of the KOKKOS fixes:

- The kernels never called v_tally(), which was therefore dead code.
  Neither the global nor the per-atom virial of the added force was
  tallied, so the pressure was wrong and compute stress/atom returned
  zero for the fix contribution.

- The every keyword was ignored: post_force() was missing the
  ntimestep % nevery test, so the force was added on every step.

- The sforce array was only grown for varflag == ATOM.  With an
  atom-style energy variable and equal-style force components
  (varflag == EQUAL, estyle == ATOM) it kept its initial length of one
  atom while compute_atom() wrote nlocal entries into it, and the
  values it did receive were never synced to the device.

Tally the virial as FixAddForce::post_force() does, honor nevery, and
grow and sync sforce for estyle == ATOM as well.  Also correct a
copy-and-paste memory label.

Constant force, equal-style and atom-style force variables, atom-style
energy variables and every N now all reproduce the pressure, energy
and per-atom stress of fix addforce exactly, and valgrind reports no
invalid accesses for the atom-style energy variable case, which
previously overflowed the sforce allocation.
FixHalt::~FixHalt() had no copymode guard, but halt/kk runs its bondmax
reduction with parallel_reduce(*this): the functor copies' destructor
chain freed idvar and dlimit_path (the latter is always allocated), so
any "fix halt ... bondmax" run corrupted the heap.  Also widen the
KK_FLOAT reduction result to double before the MPI_MAX allreduce, which
passed a float buffer as MPI_DOUBLE in single/mixed precision builds.
The group variants read the per-atom mask on the device but synced only
X_MASK, so a mask changed on the host was not seen by the kernel.  The
press/berendsen/kk and press/langevin/kk remap() with "dilate partial"
are the first callers of these variants.
spring/self/kk, ti/spring/kk, and gjf/kk store their per-atom state in
DualViews that are modified on the device during atom exchange, but the
base-class pack_restart()/unpack_restart() read and write the host copy.
A restart written after a device-side exchange therefore contained stale
values.  Wrap both restart hooks with the same sync/modify discipline as
the exchange hooks.  Also drop the bogus modify_host() from the host
pack_exchange() wrappers: the base method only reads the array, and
claiming a host write forced a needless transfer (flagged by Copilot on
the PR).  Move the tstyle enum of fix gjf into the class header so the
KK variant no longer hardcodes the ATOM enumerator value.
- accumulate the per-bin scatter sums in double regardless of the KOKKOS
  precision setting (atomic float adds degraded single/mixed builds)
- keep persistent host mirrors instead of allocating mirrors every call
- bin triclinic boxes on the device with the same kernel: the previous
  host fallback called bin_assign(), which reads coordinates on the host
  between the device-side x2lamda/lamda2x conversions and thus operated
  on stale data on GPU builds
- copy the device bin assignment back to the host bin[] array (nlocal
  ints) so the inherited per-atom remove_bias()/restore_bias() used by
  non-KOKKOS thermostats see the bins from the last temperature call
- replicate compute_array() in the KK class over bin_average_kk() for
  the same reason
Calling the host-facing restore_bias_all() on a kokkosable temperature
compute forced a device-to-host velocity sync every step in temp/csvr/kk
and langevin/kk; use the _kk variant like temp/berendsen and temp/rescale
do.  When the internal temperature compute is recreated because the fix
was requested with an explicit /kk suffix, create it with the same
host/device flavor as the fix itself instead of always temp/kk.
The port synced X/IMAGE to the host every step for group->xcm() and
group->gyration().  Replace both with device parallel_reduce kernels
(total mass + mass-weighted unwrapped coordinates, then the gyration
sum), eliminating all per-step host transfers.  Align the early-return
guard with the CPU style (rg == 0 or masstotal == 0) and remove the
shadowed atomKK/execution_space members here and in addtorque/group/kk,
the two files missed by the earlier shadowed-member cleanup.
fix move, restrain, and deform/pressure are on the do-NOT-port list, so
their destructor guards are dead code; fix heat and indent keep theirs
(heat is ported now, indent is a planned port).
Also remove the stale claim that fix gjf is not compatible with the
KOKKOS package.
compute temp/ramp/kk follows the temp/partial/kk pattern: templated
scalar/vector reductions plus device bias removal/restore kernels; the
ramp bias is recomputed from the coordinate, stored per atom for the
restore.  fix heat/kk reduces the group momentum and kinetic energy in
one device kernel and applies the velocity rescale/shift on the device;
the region keyword and atom-style heat-flux variables produce an error
(documented), and the heat_region test skips the KOKKOS variants.
fix indent remains the open Group F target; the device group-reduction
machinery for addtorque/group and compute temp/rotate is queued for a
follow-up.
fix shake/kk reported zero per-atom energy and virial where fix shake
reports real values, and the per-atom virial was additionally lost
whenever more than one thread was used.

- min_post_force() only accumulated the global virial.  Tally the
  per-atom energy and virial of the substituted bond restraints as
  FixShake::bond_force() does, through a new device ev_tally() that
  mirrors Fix::ev_tally().  The energy and virial of a restraint are
  shared out over the atoms of the pair that this processor owns, so
  the image indices the kernel uses for the positions are first mapped
  back onto their owners; a cluster reaching across a periodic
  boundary is then credited to both atoms, as on the CPU.

- post_force() and min_post_force() never contributed the duplicated
  per-atom virial scatter view back into the dual view, so with more
  than one OpenMP thread compute stress/atom saw only zeros.

- min_post_force() dispatched the kernel on vflag rather than evflag,
  which skipped the reduction, and with it the restraint energy,
  whenever only per-atom energy was requested.

Verified against the non-accelerated style with 1, 2 and 4 OpenMP
threads, for both the MD and the minimization path: global pressure,
global energy, and the per-atom energy and stress of every atom agree
to round-off (largest relative deviation 3e-11), and valgrind reports
no leaks or invalid accesses.

The Kokkos kernels do not compute the centroid virial of the
constraint forces, but the style inherited centroidstressflag =
CENTROID_AVAIL from FixShake and so silently contributed zeros to
compute centroid/stress/atom.  Set CENTROID_NOTAVAIL, as the KOKKOS
angle and dihedral styles do, so that combination is rejected with a
clear error instead, and document the restriction.
RegBlockKokkos and RegSphereKokkos kept the list of contacts between a
particle and the region surface in a single view owned by the region.
surface_kokkos() is called from inside a parallel region, once per
particle, so every thread wrote into the same list and read back
whichever contacts happened to survive.

fix wall/region/kk therefore computed wrong forces as soon as more
than one thread was used, and the result was not reproducible from run
to run.  With four OpenMP threads, 637 of the 1827 per-atom force and
stress components of a small test differed from the non-accelerated
style, by up to 170%.

Pass the contact list in from the caller instead, so that it can live
on the stack of the thread that uses it, and add a MAXCONTACT constant
to each region class for its length.  surface_kokkos(),
surface_interior_kokkos(), surface_exterior_kokkos() and the helpers
they call no longer modify the region and are now const, so that a
shared buffer cannot be reintroduced unnoticed.  The device-side
contact views and the destructors that freed them are gone.

Verified against the non-accelerated style with 1, 2 and 4 OpenMP
threads: forces and per-atom stresses of every atom are now bit for
bit identical for a block and a sphere region, inside and outside,
with open faces, with a moving region, and for the harmonic wall
style, and valgrind reports no leaks or invalid accesses.  The same
race affects the GPU backends, which could not be tested here.
stanmoore1 and others added 29 commits September 2, 2026 09:33
- min quickmin/kk: sync the per-type masses to the device in init()
- fix wall/harmonic/outside/kk: size the per-atom virial dual view in
  v_setup_peratom() with alloc = 0, after v_init() set vflag_atom
- compute reaxff/atom/kk: TAG_MASK/EMPTY_MASK datamasks and a host sync
  of the tags before compute_local(), instead of the ALL_MASK defaults
- compute temp/sphere/kk: sync and claim around the bias compute's
  remove_bias_all()/restore_bias_all(), as temp/deform/kk does
- pair mliap/kk: launch the comm packing kernels in RangePolicy<DeviceType>
  so the host instantiation does not run them on the device
- fix nvt/nph/npt/sphere/kk: remove leftover debug output
- comm_style tiled (plain and KOKKOS): reverse_comm(Pair*) honored the
  size argument backwards; match CommBrick
- fix shake/kk: pack_forward_comm() no longer claims a host write it does
  not make; drop the now unused i0
- pair uf3/kk: size the centroid virial with maxcvatom and free it in the
  destructor
- fix propel/self/kk: v_init(vflag,0), the per-atom virial is a dual view
- pair eam/kk: size the HIP team scratch with sizeof(KK_FLOAT)
- fix addtorque/atom/kk, settorque/atom/kk: release the base class array
  before the dual view takes it over
- fix qeq/reaxff/kk: struct/class tag mismatch on a friend declaration
- fix cmap/kk: tally the global virial and the per-atom energy and virial
  the way FixCMAP::post_force() does through Fix::ev_tally(): each
  crossterm split over its five atoms, only the owned ones counted.  The
  per-atom arrays are dual views sized after ev_init(eflag,vflag,0).
  Before this the fix's virial was zero and compute pe/atom and
  stress/atom silently omitted the CMAP term.
- pair hybrid/scaled under KOKKOS: a pair style that runs on the device
  but does not implement the KOKKOS packing communicated through a null
  KokkosBase pointer; both comm classes now take the host path for it
- remap/kk: wait for all receives before copying the shared scratch
  buffer to the device (the grid3d fix), fence the pack kernel before MPI
  reads the device buffer, copy only the message's own stretch of the host
  send buffer, and MPI_STATUSES_IGNORE for the Waitall
- pair dpd/kk: cache update->ntimestep on the host instead of
  dereferencing the Update object inside the team kernel
- pair pod/kk: drop the commented-out debugging dumpers, whose fwrite of
  a KK_FLOAT mirror with sizeof(double) was wrong in single precision
Kokkos 5.2 still supports the legacy view implementation; it goes away in
5.3, not before.  So there is no need yet to give up 64-bit offsets through
Kokkos_ENABLE_IMPL_VIEW_LEGACY, and none of the work that replaced them view
by view is needed either.  This puts every file back to where it was before
that work started, in one commit so that the history of what was tried, and
why, stays intact:

  4464ab5  use 64-bit index views for neighbor lists, ReaxFF, and short
              neighbor lists
  a161e64  stop forcing the legacy Kokkos view implementation
  050be9c  size the SNAP beta and ninside arrays by the chunk
  5d12962  correct the beta and ninside member comments
  00dbc72  reject a SNAP chunk size whose arrays cannot be indexed
  ccb7997  use 64-bit index views for the SNAP zlist and CPU u arrays
  ed47fe0  use 64-bit index views for the two newly ported short neighbor
              lists
  8cc20ad  KOKKOS: let a dual view be indexed with 64-bit arithmetic
  1c99065  use 64-bit index dual views for neighbor history and MLIAP
  67d8640  let a TransformView wrap a dual view with 64-bit indexing
  8be1467  widen the per-atom arrays that overflow at 250 million atoms
              per rank
  a28bf7f  drop the workaround markers from the 64-bit dual view
              declarations
  ace182e, 20f0524  comment fixes on the above
  72ce0b1  enforce disabling legacy views with Kokkos 5.2.x

The bundled Kokkos_DualView.hpp is byte-identical to Kokkos 5.2.1 again, and
KOKKOS.cmake is back to enabling the legacy views.  Changes that reached these
files from develop in the meantime are kept.  The SNAP beta and ninside
chunk-sizing, which stands on its own as a memory fix, follows separately.
An option() can be overridden from the command line; a forced cache entry
cannot, and this one must not be: without the legacy view implementation a
view of more than 2^31 entries is indexed incorrectly.  Kokkos 5.2 deprecates
that implementation ahead of removing it in 5.3, so also turn off the
deprecation warnings it would otherwise emit on every build.
…m list

PairSNAPKokkos chunks its per-atom work: SNAKokkos::grow_rij() sizes every
array by the padded chunk size and every kernel indexes them with a
chunk-relative atom index.  beta and ninside were the exceptions -- sized by
the full local atom count, a habit inherited from the CPU pair style, where
beta really is filled for the whole list in one pass before the force loop.
Here ComputeBeta runs inside the chunk loop and compute_yi reads the result in
the same iteration, and nothing ever adds chunk_offset to a beta or ninside
index, so the rows beyond the chunk are never touched.

With the default chunk size of 32768 the allocation was inum/32768 times too
large: 22 GB for beta alone at 1e8 atoms per rank and twojmax 8, next to a
chunking scheme that exists to keep memory bounded.  The same padding_factor
that makes the grow_rij() arrays safe for the routines that process yi_batch
atoms per thread applies unchanged.

Ported from the reverted 050be9c; the results are unaffected.
…r CUDA UVM

Kokkos 5.2 no longer has the Kokkos_ENABLE_CUDA_UVM option (deprecated in
4.0 in favor of Kokkos::SharedSpace, removed in 5.2).  The equivalent
whole-allocation switch is now the internal option
Kokkos_ENABLE_IMPL_CUDA_UNIFIED_MEMORY, which allocates all GPU memory as
CUDA managed memory.  Point the build and Kokkos speed docs at it, note
the CUDA 12.2 and Pascal-or-later requirements and that Kokkos treats the
option as internal, and mention that it also gives host code direct
access to device data for debugging.
…n is set

CMake accepts unknown -D settings silently, so a build script that still
passes Kokkos_ENABLE_CUDA_UVM=on would configure without unified memory
and give no indication of it.  Fail early and name the replacement
option instead.
- fix spring/kk, fix wall/flow/kk, compute ave/sphere/atom/kk: sync the
  per-type masses to the device before reading them, instead of relying
  on the integrator having done it
- compute temp/profile/kk: sync the legacy host side of the masses, which
  is what the host loop reads; sync<LMPHostType>() refreshes the other side
- atom map: map_one() claims its host write; map_clear() releases both
  sides before it overwrites the whole array
- compute inertia/kk: the host sync before inertia_extended() now covers
  the radius, the ellipsoid indices and the bonus data it reads
- fix nh/sphere/kk, compute temp/sphere/kk: sync the host copies before
  the radius/mask loops of init() and dof_compute()
- fix rigid/small/kk and its Nose-Hoover variants: v_init(vflag,0), the
  per-atom virial is a dual view the fix zeroes itself
- pair gran/hooke/kk, gran/hooke/history/kk, gran/hertz/history/kk: stop
  claiming and copying a per-atom energy that is never written
- comm_style tiled/kk: MPI_STATUSES_IGNORE for Waitall, and take the send
  pointer after the pack that may resize the buffer
- NBin gets a copymode guard, set by nbin/kk and nbin/ssa/kk while a copy
  of the object lives in a device functor; likewise MLIAP_SO3Kokkos
- region ellipsoid/kk: rotate() locals no longer shadow the semi-axes
- pair lj/gromacs/kk: drop the cut_inner dual views nothing reads
Update Bundled Kokkos library in LAMMPS to v5.2.0
pair_style hybrid/scaled/kk kept its accumulators as plain host arrays,
so every sub-style needed the forces (and torques) copied back and forth
between host and device on each timestep.  Do the work in Kokkos kernels
instead:

- fsum/tsum become dual views and the save/clear/scale-add/restore steps
  run as parallel_for kernels
- init_style() picks the memory space for the sum: the device when every
  sub-style runs there, so the forces stay resident on the device, and
  the Kokkos host space otherwise
- virial_fdotr is only synced to the device when it is actually needed

Per-atom scale factors from an atom-style variable are now communicated
through KokkosBase::pack/unpack_forward_comm_kokkos.  Previously the
forward communication of a Device pair style dispatched to the device
path and dereferenced a null KokkosBase, which crashed in compute() and
in single().  The variable itself is still evaluated on the host, so the
local values are uploaded and the ghost values filled in by the
exchange; single() and born_matrix() read them back from the dual view.

Verified against pair_style lj/cut with sub-style scale factors summing
to one (constant, equal-style, and spatially varying atom-style), with
atom_style sphere for the torque path, with a mix of /kk and plain
sub-styles, and against the CPU hybrid/scaled for compute group/group.
The force-style unit tests pass in double/legacy-layout and in
mixed-precision/default-layout builds.
Respa::init() called into the styles' KOKKOS execution spaces itself and
refused any force style on the device.  Move the decision into
KokkosLMP::respa_check(), so that respa.cpp keeps a single guarded call
and the dummy interface a no-op, and make the criterion what rRESPA
actually needs: every participant on the host side of the atom data.
That admits a build without a device backend as before, and now also a
device build whose styles all use the /kk/host suffix with comm, sort and
atom/map on the host; it refuses a style, fix or compute in the device
execution space and device-side communication, sorting or atom map, and
names what to change.

Drop the versionchanged directive from the run_style documentation: the
KOKKOS package never supported rRESPA, so nothing changed for users.
KOKKOS: fix host/device coherence bugs and include-group binning
…pass

The pack functor of fix spring/self/kk ignored the "final" flag of the
Kokkos parallel_scan it runs in.  The scan invokes the functor once to
accumulate the buffer offsets and once more to do the actual packing.
Since the functor also refilled the slot of the departing atom i with
the data of atom j in the first pass, the final pass then packed the
reference coordinates of atom j instead of those of atom i, and the
receiving process tethered the migrated atom to the wrong position.

With the OpenMP backend, 2 or more MPI ranks and "package kokkos comm
device" (or "comm host"), a tethered LJ liquid of 2048 atoms at T=3
blew up within 50 steps, with a spring energy per atom of 21.5 instead
of 0.28.  Do the packing and the refill only when "final" is set, as
fix shake/kk and fix neigh/history/kk already do.  The results with 1,
2 and 4 ranks and all "comm" settings now agree with the
non-accelerated fix to round-off.

Same fix as maintenance commit fb24de6.
The test driver did not finalize Kokkos, so it was torn down by static
destructors at program exit.  With the Serial backend the default execution
space instance then frees its scratch memory through a fence on the
execution space registry, which has already been destroyed at that point,
and the test segfaulted after all its checks had passed.  Finalize the
KOKKOS package explicitly after running the tests, like the force-style,
c-library and FFT3d test drivers do.
Update version strings for stable release candidate
@ohenrich ohenrich closed this Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants