xnn.common.deploy.torchscript#
Self-contained TorchScript export: a trained model as a standalone .pt.
The artifact produced here is driven purely by tensors and carries its own
neighbor list, so a consumer needs only libtorch / torch.jit.load –
no xnn import, no Python model code, no config file. That is what makes a
checkpoint usable from LAMMPS, i-PI, OpenMM, a C++ driver or any other MD
package.
Two entry points are exported on the same module:
forward(pos, atomic_numbers, cell, pbc)The whole-system ABI. The module builds its own neighbor list from the cutoff baked into it at export time. This is the general-purpose entry point and the only correct one for models carrying a long-range term.
forward_lammps(pos, edge_index, cell_shifts, atomic_numbers, cell)The pair-style ABI, matching
LAMMPSWrapper(and hence pair_nequip / pair_mace / pair_allegro): the caller supplies the neighbor list. Cheaper, because the MD engine already has a neighbor list, but see the long-range caveat below.
Calling conventions#
One structure per call (inputs are (N, 3), with no batch dimension).
Positions may be float32 or float64 whatever the weights’ dtype: the module
computes in its own dtype and answers in the caller’s. Wrapping the call in
torch.no_grad() is fine – forces come from autograd, so the module
re-enables grad internally and restores the caller’s mode afterwards – but
torch.inference_mode() raises, because tensors created under it can never
participate in autograd.
Add-on terms: LES long-range and D4 dispersion#
Two wrappers can sit on top of a core model, in either order or together:
LatentEwald (an Ewald energy over latent
charges) and DispersionCorrection (the DFT-D3 /
DFT-D4 corrections; D4’s EEQ charges couple every atom of the structure
through a dense linear system). Both are global: they do not decompose into a
local, per-domain neighbor list. A model exported with either must be driven
with the whole system on one rank (forward, or forward_lammps with a
full-system neighbor list) – an MPI-decomposed pair style that only ever sees
its own subdomain plus ghosts cannot reproduce the trained energy.
export_torchscript_potential() records long_range and dispersion
in the archive metadata so a consumer can check.
The dispersion wrapper also widens the neighbor list (its cutoffs default to the
upstream 60 / 40 / 30 / 25 bohr): the export bakes in the wrapper’s cutoff and
hands the core model only the edges within the core’s own radius, exactly as
the eager wrapper does. The total charge of the system is fixed at export
time (total_charge, default neutral), since neither tensor ABI carries it.
Functions
|
|
|
Script a trained model to a standalone |
|
Peel the LES / D4 wrappers off a model. |
Classes
|
Tensor-only, scriptable potential: positions in, energy/forces/stress out. |