GEMS Memory Model¶
Status: fresh analysis of current main at af392e6.
Related documents: architecture, dataflow, hot paths, and developer guide.
Conceptual Model¶
The current code supports the intended model:
editable dynamic representation
-> compiled dense representation
-> compute-heavy kernels
but implements it as a set of layered structures rather than a monolithic compiled-state object.
Editable state:
group%alist: linked-list membership.gsel,gr(:),sys,ghost, and workflow-specific groups.- Per-atom fields and PBC/ghost membership.
Compiled/indexed state:
igroup%a(:): dense-ish atom pointer index.- atom
gr(:)/id(:)membership arrays. cgroup%head(:,:,:)andnext(:).ngroup%nn(:)andlist(:,:).
Compute-heavy state:
- concrete
ngroupinteraction objects (lj,smatb, field/bias/graph types). - integration groups.
- output accumulators and analysis/CV arrays.
Ownership¶
Atom Objects¶
Atoms are heap-allocated and attached to groups. The primary owner is not an isolated atom container; lifetime is controlled by group membership.
atom%destdetaches the atom from every group before deallocating internal arrays.group%destroy_allcallsa%dest()and deallocates atom objects.group%try_destroy_alldetaches atoms and deallocates only atoms with no remaining group references.- Ghost atoms are either preallocated in
atom%ghost(1:7)when PBC is enabled or allocated bynew_ghostin the older full ghost path.
Groups¶
group owns its membership list nodes, not necessarily the atom objects. Attaching an atom also registers the group id in the atom. Detaching removes both sides.
gindex stores pointers to groups. group_destroy removes the group from gindex but does not renumber group ids.
Indexed Groups¶
igroup owns a(:) and limbo.
a(:)stores atom pointers, not atom payload.amaxis the active scanned extent.- Detach can null slots or put atoms in
limbo. igroup_update_indexcompacts the pointer index and rewrites atom-local ids.
Cell Groups¶
cgroup owns cell-list arrays:
head(:,:,:): first atom index per cell.next(:): next atom index in cell chain.
It does not own atoms; it sorts existing indexed atoms.
Neighbor Groups¶
ngroup owns:
- internal
refgroup. - internal candidate
bcgroup. - inherited
igroupindex. - neighbor arrays
nn(:)andlist(:,:).
Concrete interaction objects extend ngroup and may own additional arrays, for example TB parameter matrices and band arrays.
Atom Field Storage¶
atom%pos, vel, force, and acel are Fortran pointers. By default, atom_allocate allocates each as a separate dm-length heap target.
group_switch_vectorial can replace per-atom vector allocations with slices into group-owned contiguous arrays:
atom vector allocations
-> group%pp/pv/pf/pa contiguous arrays
-> atom vector pointers redirected to slices
This improves contiguity for a chosen group but changes ownership of the atom vector targets. group_switch_objeto reverses it. The source comments mark this area as a workaround/TODO, so future refactors should treat it as fragile.
Invalidation And Recompile¶
Property invalidation:
gindex_all_changed,gindex_pos_changed,gindex_vel_changed, andgindex_epot_changedbroadcast cache invalidation to all registered groups.group_attach_atomandgroup_detach_linkcallall_changed.- integration steps call
gindex_all_changed.
Indexed group invalidation:
igroup_detach_atommay null slots and triggerigroup_update_indexwhen holes exceedaupd.igroup%updatesignals extended types that internal arrays may need rebuild.
Cell-list invalidation:
cgroup%tessellatedtracks whether cell storage is valid.cgroup_attach_atomtries to sort new atoms incrementally when tessellated; failures mark it stale.cgroup_detach_atomcan unsort or mark stale.test_updatetessellates and sortsngroup%bbefore checking neighbor rebuilds.
Neighbor-list invalidation:
ngroup%listedindicates whethernn/listare valid.test_updaterebuilds if a neighbor group is not listed.- It also rebuilds when the sum of the two largest displacements exceeds
nb_dcut. updaterecordspos_oldand calls each ngroup's selected neighbor builder.
Ghost invalidation:
set_pbcallocates/deallocates ghost arrays.box mic Fenablesuseghost;test_updatecallspbchalfghost(maxrcut).ghost_switchattaches/detaches active ghost atoms from every ghost-enabled group that contains the prime atom.
Dynamic Vs Compute-Oriented Structures¶
Dynamic/flexible:
group,gsel,gr(:).- atom group membership arrays.
- ghost activation/deactivation.
- parser variables and labels.
Compute-oriented:
igroup%a(:)for indexed atom access.cgroupcell arrays.ngroup%nn/list.- concrete interaction arrays.
- output/CV/NEB/TB work arrays.
Partially compute-oriented but still pointer-rich:
- force kernels use neighbor ids but dereference atom pointers and atom vector pointers.
- OpenMP tasks exist in neighbor search, but atom payload layout is not structure-of-arrays.
Locality / Cache Implications¶
Good locality:
- neighbor counts and lists are dense integer arrays.
- cell heads and next arrays are dense.
- group vectorization can make selected vector fields contiguous.
Poor or uncertain locality:
- atom objects are individually allocated.
- atom mechanical fields are separate pointer targets unless vectorized.
- linked-list traversal remains common in setup, properties, output, and some kernels.
ngroup%list -> ngroup%a -> atom -> pos/forcestill has multiple pointer hops.
OpenMP/GPU Readiness¶
Promising pieces:
- explicit indexing layers (
igroup,ngroup). - dense neighbor-list arrays.
- clear separation between neighbor update and interaction dispatch.
- linked-cell data structure.
Friction points:
- object/pointer-heavy atom payload.
- polymorphic interaction dispatch.
- ghost membership mutates groups at runtime.
- global module state and broad invalidation.
- no explicit device-ready compiled state or storage policy.
Before GPU work, document and stabilize a kernel contract: dense input arrays, force/energy outputs, ghost/halo ownership, and rebuild policy.