Skip to content

metal_kernels

Fused Metal kernels for recurring molecular force paths.

Collapses the per-step pairwise LJ force op-chain (gather -> minimum image -> r^2 -> LJ scalar -> scatter-add) into a single mx.fast.metal_kernel dispatch. Diagnostic kernels write per-pair energy without contention, while force-only kernels omit those outputs and reductions entirely.

The simple kernel covers scalar reduced-unit LJ. The parameterized kernel covers per-atom Lorentz-Berthelot parameters, topology scales, shifts, and smooth switching for the production biomolecular path. A separate force-only kernel combines standard bond, angle, periodic-torsion, and improper interactions into one output. Unsupported cases fall back transparently.

Because tests/conftest.py forces MLX_ATOMISTIC_DEVICE=cpu, the kernel is built lazily on first use (not at import) so importing this module never triggers a Metal device load.

import mlx_atomistic.metal_kernels

def aligned_topology_lj_scales(pairs: mx.array, excluded_pairs: mx.array, one_four_pairs: mx.array, *, one_four_scale: float) -> mx.array

Build pair-aligned topology LJ scales on Metal.

Parameters

NameTypeDefaultDescription
pairsmx.arrayCandidate atom pairs with shape (n_pairs, 2).
excluded_pairsmx.arraySorted excluded pairs with shape (n_excluded, 2).
one_four_pairsmx.arraySorted non-excluded 1-4 pairs with shape (n_one_four, 2).
one_four_scalefloatLJ scale assigned to 1-4 pairs.

Returns

  • mx.array — Float32 scales with shape (n_pairs,). Excluded pairs are zero,
  • mx.array — ordinary pairs are one, and 1-4 pairs use one_four_scale.

Raises

  • ValueError — If any pair array has the wrong shape or the scale is invalid.
def fused_lj_forces(positions: mx.array, pairs: mx.array, box_lengths: mx.array, *, epsilon: float, sigma: float, cutoff: float, shift: bool) -> tuple[mx.array, mx.array]

Fused LJ energy + forces via a single Metal kernel (orthorhombic, scalar LJ).

Mirrors LennardJonesPotential._pair_energy_forces semantics: a half neighbor list pairs of shape (M, 2), an r^2 cutoff mask, and an optional energy shift at the cutoff. box_lengths are the orthorhombic edge lengths (mx.diag(cell.matrix)). Returns (energy_scalar, forces) with forces shape (N, 3).

Parameters

NameTypeDefaultDescription
positionsmx.array
pairsmx.array
box_lengthsmx.array
epsilonfloat
sigmafloat
cutofffloat
shiftbool

Returns

  • tuple[mx.array, mx.array]
def fused_parameterized_lj_forces(positions: mx.array, pairs: mx.array, box_lengths: mx.array, sigma: mx.array, epsilon: mx.array, scales: mx.array, *, cutoff: float, shift: bool, switch_distance: float | None) -> tuple[mx.array, mx.array]

Evaluate parameterized LJ energy and forces with one Metal dispatch.

Parameters

NameTypeDefaultDescription
positionsmx.arrayAtomic coordinates with shape (n_atoms, 3).
pairsmx.arrayHalf-neighbor pairs with shape (n_pairs, 2).
box_lengthsmx.arrayOrthorhombic cell lengths with shape (3,).
sigmamx.arrayPer-atom LJ sigma values.
epsilonmx.arrayPer-atom LJ epsilon values.
scalesmx.arrayEither one shared scale or one scale per pair.
cutofffloatFinite LJ cutoff.
shiftboolWhether to subtract each pair’s cutoff energy.
switch_distancefloat | NoneOptional start of the smooth potential switch.

Returns

  • tuple[mx.array, mx.array] — Scalar LJ energy and an (n_atoms, 3) force array.

Raises

  • ValueError — If the cutoff or scale count is invalid.
def fused_parameterized_pme_direct_components(positions: mx.array, pairs: mx.array, box_lengths: mx.array, sigma: mx.array, epsilon: mx.array, charges: mx.array, lj_scales: mx.array, *, cutoff: float, shift: bool, switch_distance: float | None, coulomb_constant: float, alpha: float) -> tuple[mx.array, mx.array, mx.array, mx.array]

Evaluate separated LJ/PME direct energies and combined forces in one dispatch.

Parameters

NameTypeDefaultDescription
positionsmx.arrayAtomic coordinates with shape (n_atoms, 3).
pairsmx.arrayShared half-neighbor candidates with shape (n_pairs, 2).
box_lengthsmx.arrayOrthorhombic cell lengths with shape (3,).
sigmamx.arrayPer-atom LJ sigma values.
epsilonmx.arrayPer-atom LJ epsilon values.
chargesmx.arrayPer-atom partial charges.
lj_scalesmx.arrayOne aligned LJ scale per candidate; zero excludes LJ only.
cutofffloatShared finite LJ and PME real-space cutoff.
shiftboolWhether to subtract each LJ pair’s cutoff energy.
switch_distancefloat | NoneOptional start of the smooth LJ potential switch.
coulomb_constantfloatCoulomb prefactor in the configured units.
alphafloatEwald splitting parameter.

Returns

  • mx.array — Combined energy, (n_atoms, 3) forces, LJ energy, and direct-space
  • mx.array — Coulomb energy.

Raises

  • ValueError — If the cutoff, alpha, or aligned scale count is invalid.

fused_parameterized_pme_direct_components_virial

Section titled “fused_parameterized_pme_direct_components_virial”
def fused_parameterized_pme_direct_components_virial(positions: mx.array, pairs: mx.array, box_lengths: mx.array, sigma: mx.array, epsilon: mx.array, charges: mx.array, lj_scales: mx.array, *, cutoff: float, shift: bool, switch_distance: float | None, coulomb_constant: float, alpha: float) -> tuple[mx.array, mx.array, mx.array, mx.array, mx.array]

Evaluate direct components, forces, and atomic diagonal virial.

Parameters

NameTypeDefaultDescription
positionsmx.arrayAtomic coordinates with shape (n_atoms, 3).
pairsmx.arrayShared half-neighbor candidates with shape (n_pairs, 2).
box_lengthsmx.arrayOrthorhombic cell lengths with shape (3,).
sigmamx.arrayPer-atom LJ sigma values.
epsilonmx.arrayPer-atom LJ epsilon values.
chargesmx.arrayPer-atom partial charges.
lj_scalesmx.arrayOne aligned LJ scale per candidate; zero excludes LJ only.
cutofffloatShared finite LJ and PME real-space cutoff.
shiftboolWhether to subtract each LJ pair’s cutoff energy.
switch_distancefloat | NoneOptional start of the smooth LJ potential switch.
coulomb_constantfloatCoulomb prefactor in the configured units.
alphafloatEwald splitting parameter.

Returns

  • mx.array — Combined energy, forces, LJ energy, direct Coulomb energy, and the
  • mx.array — three diagonal atomic-virial components.

Raises

  • ValueError — If the cutoff, alpha, or aligned scale count is invalid.
def fused_parameterized_pme_direct_force_only(positions: mx.array, pairs: mx.array, box_lengths: mx.array, sigma: mx.array, epsilon: mx.array, charges: mx.array, lj_scales: mx.array, *, cutoff: float, shift: bool, switch_distance: float | None, coulomb_constant: float, alpha: float) -> mx.array

Evaluate combined LJ plus PME direct-space forces without energy outputs.

Parameters

NameTypeDefaultDescription
positionsmx.arrayAtomic coordinates with shape (n_atoms, 3).
pairsmx.arrayShared half-neighbor candidates with shape (n_pairs, 2).
box_lengthsmx.arrayOrthorhombic cell lengths with shape (3,).
sigmamx.arrayPer-atom LJ sigma values.
epsilonmx.arrayPer-atom LJ epsilon values.
chargesmx.arrayPer-atom partial charges.
lj_scalesmx.arrayOne aligned LJ scale per candidate; zero excludes LJ only.
cutofffloatShared finite LJ and PME real-space cutoff.
shiftboolWhether to subtract each LJ pair’s cutoff energy.
switch_distancefloat | NoneOptional start of the smooth LJ potential switch.
coulomb_constantfloatCoulomb prefactor in the configured units.
alphafloatEwald splitting parameter.

Returns

  • mx.array — An (n_atoms, 3) force array. The kernel allocates no per-pair
  • mx.array — energy outputs.

Raises

  • ValueError — If the cutoff, alpha, or aligned scale count is invalid.
def fused_parameterized_pme_direct_forces(positions: mx.array, pairs: mx.array, box_lengths: mx.array, sigma: mx.array, epsilon: mx.array, charges: mx.array, lj_scales: mx.array, *, cutoff: float, shift: bool, switch_distance: float | None, coulomb_constant: float, alpha: float) -> tuple[mx.array, mx.array]

Evaluate combined LJ plus PME direct-space energy and forces.

Parameters

NameTypeDefaultDescription
positionsmx.arrayAtomic coordinates with shape (n_atoms, 3).
pairsmx.arrayShared half-neighbor candidates with shape (n_pairs, 2).
box_lengthsmx.arrayOrthorhombic cell lengths with shape (3,).
sigmamx.arrayPer-atom LJ sigma values.
epsilonmx.arrayPer-atom LJ epsilon values.
chargesmx.arrayPer-atom partial charges.
lj_scalesmx.arrayOne aligned LJ scale per candidate; zero excludes LJ only.
cutofffloatShared finite LJ and PME real-space cutoff.
shiftboolWhether to subtract each LJ pair’s cutoff energy.
switch_distancefloat | NoneOptional start of the smooth LJ potential switch.
coulomb_constantfloatCoulomb prefactor in the configured units.
alphafloatEwald splitting parameter.

Returns

  • tuple[mx.array, mx.array] — Combined scalar direct-space energy and (n_atoms, 3) forces.
def fused_pme_cutoff_correction_virial(positions: mx.array, molecule_centers: mx.array, pairs: mx.array, box_lengths: mx.array, sigma: mx.array, epsilon: mx.array, charges: mx.array, lj_scales: mx.array, *, cutoff: float, strain_epsilon: float, coulomb_constant: float, alpha: float, include_lj: bool, include_coulomb: bool) -> mx.array

Evaluate the finite-strain cutoff correction in one Metal dispatch.

Parameters

NameTypeDefaultDescription
positionsmx.arrayAtomic coordinates with shape (n_atoms, 3).
molecule_centersmx.arrayPer-atom geometric molecule centers, shape (n_atoms, 3).
pairsmx.arrayCompact cutoff-shell pairs with shape (n_pairs, 2).
box_lengthsmx.arrayOrthorhombic cell lengths with shape (3,).
sigmamx.arrayPer-atom LJ sigma values.
epsilonmx.arrayPer-atom LJ epsilon values.
chargesmx.arrayPer-atom partial charges.
lj_scalesmx.arrayOne aligned LJ scale per candidate; zero excludes LJ.
cutofffloatShared finite LJ and PME real-space cutoff.
strain_epsilonfloatPositive central finite-strain displacement.
coulomb_constantfloatCoulomb prefactor in the configured units.
alphafloatEwald splitting parameter.
include_ljboolWhether to include the unswitched LJ correction.
include_coulombboolWhether to include the PME real-space boundary term.

Returns

  • mx.array — A diagonal (3, 3) cutoff-correction virial tensor.

Raises

  • ValueError — If shapes or positive scalar parameters are invalid.
def fused_sparse_pme_correction_forces(positions: mx.array, pairs: mx.array, box_lengths_and_inverses: mx.array, charge_products: mx.array, lj_sigma: mx.array, lj_epsilon: mx.array, *, coulomb_constant: float) -> mx.array

Evaluate sparse PME exclusions, exceptions, and 1-4 force corrections.

Parameters

NameTypeDefaultDescription
positionsmx.array
pairsmx.array
box_lengths_and_inversesmx.array
charge_productsmx.array
lj_sigmamx.array
lj_epsilonmx.array
coulomb_constantfloat

Returns

  • mx.array
def neighbor_pair_cutoff_mask(positions: mx.array, pairs_i: mx.array, pairs_j: mx.array, box_lengths: mx.array, *, search_radius: float) -> mx.array

Return the periodic cutoff mask for aligned candidate pairs on Metal.

Parameters

NameTypeDefaultDescription
positionsmx.arrayAtomic coordinates with shape (n_atoms, 3).
pairs_imx.arrayLeft atom indices with shape (n_pairs,).
pairs_jmx.arrayRight atom indices with shape (n_pairs,).
box_lengthsmx.arrayOrthorhombic cell lengths with shape (3,).
search_radiusfloatPositive neighbor search radius.

Returns

  • mx.array — Boolean mask with one entry per candidate pair.

Raises

  • ValueError — If an input shape or the search radius is invalid.
def neighbor_pair_ordered_scatter(pairs_i: mx.array, pairs_j: mx.array, close: mx.array, prefix: mx.array) -> tuple[mx.array, mx.array]

Scatter accepted neighbor candidates by their stable prefix positions.

Parameters

NameTypeDefaultDescription
pairs_imx.arrayLeft atom indices with shape (n_pairs,).
pairs_jmx.arrayRight atom indices with shape (n_pairs,).
closemx.arrayBoolean cutoff mask with shape (n_pairs,).
prefixmx.arrayInclusive integer prefix sum of close.

Returns

  • mx.array — Candidate-sized left and right output buffers whose leading accepted
  • mx.array — entries preserve the input candidate order.

Raises

  • ValueError — If the inputs are not matching one-dimensional arrays.
def pme_order5_charge_grid(positions: mx.array, charges: mx.array, cell_lengths: mx.array, mesh_shape: tuple[int, int, int]) -> mx.array

Spread particle charges onto a PME mesh with one Metal dispatch.

Parameters

NameTypeDefaultDescription
positionsmx.arrayAtomic coordinates with shape (n_atoms, 3).
chargesmx.arrayPer-atom charges with shape (n_atoms,).
cell_lengthsmx.arrayOrthorhombic cell lengths with shape (3,).
mesh_shapetuple[int, int, int]Three positive PME mesh dimensions.

Returns

  • mx.array — The float32 order-five B-spline charge grid.

Raises

  • ValueError — If input shapes or mesh dimensions are invalid.
def pme_order5_energy_forces(positions: mx.array, charges: mx.array, potential_grid: mx.array, cell_lengths: mx.array) -> tuple[mx.array, mx.array]

Interpolate order-five PME energy and forces with one Metal dispatch.

Parameters

NameTypeDefaultDescription
positionsmx.arrayAtomic coordinates with shape (n_atoms, 3).
chargesmx.arrayPer-atom charges with shape (n_atoms,).
potential_gridmx.arrayScalar three-dimensional reciprocal potential mesh.
cell_lengthsmx.arrayOrthorhombic cell lengths with shape (3,).

Returns

  • tuple[mx.array, mx.array] — Scalar reciprocal energy and (n_atoms, 3) forces.

Raises

  • ValueError — If input shapes are invalid.
def tile_topology_lj_masks(atom_blocks: mx.array, tile_blocks: mx.array, member_mask: mx.array, excluded_pairs: mx.array, one_four_pairs: mx.array) -> tuple[mx.array, mx.array]

Build tile-aligned LJ eligibility and 1-4 masks on Metal.

Parameters

NameTypeDefaultDescription
atom_blocksmx.array
tile_blocksmx.array
member_maskmx.array
excluded_pairsmx.array
one_four_pairsmx.array

Returns

  • tuple[mx.array, mx.array]