Conversation
The fast GPU edgewise path previously materialized an [E, 9, C] message between conv1, gate activation, and conv2. Preserve the existing m-major GEMM blocks across that boundary so the gate and conv2 consume them directly, while retaining the materialized path for S2 activation. For UMA-S-1p2 at 1000 atoms on one H100 with internal graph generation, merge_mole=True, compile dynamic shapes, the fast GPU backend, a 1024-edge CUDA graph bucket, 12 warmups, and 200 timed predictions, trajectory throughput increased from 23.8327 QPS to 25.8706 QPS across two repeats (+8.55%). Test Plan: ``` PYTHONPATH="$PWD/src" pytest tests/core/models/uma/nn/test_so2_layers.py -c packages/fairchem-core/pyproject.toml -q pre-commit run --files src/fairchem/core/models/uma/escn_md_block.py src/fairchem/core/models/uma/nn/activation.py src/fairchem/core/models/uma/nn/so2_layers.py tests/core/models/uma/nn/test_so2_layers.py ``` Authored with an AI coding assistant.
The fast GPU path still launched separate sigmoid, SiLU, multiply, split, and concatenate work between the packed conv1 and conv2 GEMMs. Add an FP32 Triton primitive that activates the three m-major blocks directly and provides a fused first-order VJP. Non-FP32 inference retains the packed PyTorch path. When autograd requests a higher-order graph, the VJP switches to an algebraically equivalent differentiable PyTorch implementation so loop-based UMA Hessian inference remains supported. Tests cover empty and strided inputs, dynamic full-graph compilation at multiple edge counts, and first- and second-order parity. For the same UMA-S-1p2 1000-atom H100 endpoint, the primitive increased trajectory throughput from 25.8706 QPS to 27.0886 QPS across two repeats (+4.71%). The exact final stack, including the following Wigner launch commit, reproduced at 27.4831 QPS over 200 timed predictions. Test Plan: ``` PYTHONPATH="$PWD/src" pytest tests/core/models/uma/uma_fast/test_fused_edgewise.py -c packages/fairchem-core/pyproject.toml -q -k packed_gate PYTHONPATH="$PWD/src" python /data/users/mlazos/pytorch/agent_space/bench_uma_internal_padding.py --variant captured --bucket-size 1024 --repeat 9 --warmups 12 --batches 10 --steps-per-batch 20 pre-commit run --files src/fairchem/core/models/uma/escn_md_block.py src/fairchem/core/models/uma/nn/execution_backends.py src/fairchem/core/models/uma/triton/__init__.py src/fairchem/core/models/uma/triton/kernels.py src/fairchem/core/models/uma/triton/packed_gate.py tests/core/models/uma/uma_fast/test_fused_edgewise.py ``` Authored with an AI coding assistant.
The fused Wigner kernels used a fixed 2,048-program grid and serially processed the remaining edges in each program. Size the grid from the symbolic edge count, capped at 131,072 programs, so the 78,848-edge inference bucket can expose one program per edge while retaining a grid-stride loop for larger graphs. A one-program minimum and explicit Wigner width preserve empty-graph behavior. Across the four forward/backward kernels at 78,848 edges, the selected one-warp launch reduced aggregate kernel time from 2.8196 ms to 2.7111 ms. On the UMA-S-1p2 1000-atom endpoint, trajectory throughput increased from 27.0886 QPS to 27.4774 QPS across two repeats (+1.44%). All five selected correctness tests reached pass status. This local development PyTorch build then aborted during interpreter teardown, after pytest reported 100%, which is a pre-existing shutdown issue for the Wigner Triton test module. Test Plan: ``` PYTHONPATH="$PWD/src" python /data/users/mlazos/pytorch/agent_space/bench_rebased_wigner_launch.py PYTHONPATH="$PWD/src" pytest tests/core/models/uma/uma_fast/test_fused_edgewise.py -c packages/fairchem-core/pyproject.toml -q -k "matches_pytorch or empty_graph" PYTHONPATH="$PWD/src" python /data/users/mlazos/pytorch/agent_space/bench_uma_internal_padding.py --variant captured --bucket-size 1024 --repeat 9 --warmups 12 --batches 10 --steps-per-batch 20 pre-commit run --files src/fairchem/core/models/uma/triton/constants.py src/fairchem/core/models/uma/triton/fused_wigner.py tests/core/models/uma/uma_fast/test_fused_edgewise.py ``` Authored with an AI coding assistant.
The fused Wigner conv1 backward previously materialized an [E, 9, 2C] gradient buffer and launched two index_add reductions to return gradients to the source and target nodes. Accumulate those contributions directly into the [N, 9, C] node-gradient tensor in the producer kernel when deterministic algorithms are disabled. When deterministic algorithms are enabled, specialize the same kernel to retain the per-edge buffer and established index_add path. On UMA-S-1p2 with 1000 atoms, internal NVIDIA graph generation v3, external_graph_gen=False, merge_mole=True, dynamic torch.compile, fast math, the umas_fast_gpu backend, a 1024-edge bucket, and full outer CUDA graph capture, three trajectory repeats average 29.575 QPS versus 27.466 QPS for the committed predecessor (+7.68%). Reserved memory falls from 8.135 GiB to 7.908 GiB. An isolated backward measurement improves from 2.361 ms to 0.935 ms (2.53x). The direct reduction differs from the prior atomic reduction by 2.97e-7 relative L2 in grad_x; grad_wigner and grad_radial are bitwise equal. The deterministic compiled fallback is bitwise repeatable. Test Plan: ```bash PYTHONPATH="$PWD/src" CUDA_VISIBLE_DEVICES=0 pytest -q tests/core/models/uma/uma_fast/test_fused_edgewise.py::test_wigner_conv1_fused_deterministic_backward -c packages/fairchem-core/pyproject.toml ``` ```bash PYTHONPATH="$PWD/src" CUDA_VISIBLE_DEVICES=0 pytest -q tests/core/models/uma/uma_fast/test_fused_edgewise.py::test_wigner_conv1_fused_dynamic_compile -c packages/fairchem-core/pyproject.toml ``` ```bash PYTHONPATH="$PWD/src" CUDA_VISIBLE_DEVICES=0 pytest -q tests/core/models/uma/uma_fast/test_fused_edgewise.py::test_wigner_conv1_fused_gradcheck -c packages/fairchem-core/pyproject.toml ``` Both gradcheck parameterizations pass before the local Triton runtime aborts during interpreter teardown. ```bash PYTHONPATH="$PWD/src:/data/users/mlazos/pytorch/agent_space:$PYTHONPATH" CUDA_VISIBLE_DEVICES=0 python /data/users/mlazos/pytorch/agent_space/bench_uma_internal_padding.py --variant captured --bucket-size 1024 --repeat 12 ``` ```bash pre-commit run --files src/fairchem/core/models/uma/triton/fused_wigner.py src/fairchem/core/models/uma/triton/kernels.py tests/core/models/uma/uma_fast/test_fused_edgewise.py ``` This commit was authored with assistance from Codex.
The fast GPU consumer previously wrote an [E, 9, C] inverse-rotated edge tensor, reread it in index_add to produce node embeddings, and gathered node gradients back into another edge tensor during backward. Add a compile-safe custom operation that accumulates the inverse rotation directly into target nodes and gathers node gradients inside the existing backward kernel. The default path uses relaxed FP32 atomics. When deterministic algorithms are enabled, it retains the materialized inverse rotation and PyTorch index_add so the deterministic contract is preserved. Graph-parallel target remapping stays an explicit input to the fused operation. On UMA-S-1p2 with 1000 atoms, internal NVIDIA graph generation v3, external_graph_gen=False, merge_mole=True, dynamic torch.compile, fast math, the umas_fast_gpu backend, a 1024-edge bucket, and full outer CUDA graph capture, two trajectory repeats average 32.066 QPS versus 29.575 QPS for the committed predecessor (+8.42%). Latency falls from 33.813 ms to 31.186 ms and reserved memory from 7.908 GiB to 7.169 GiB. An isolated forward measurement improves from 0.565 ms to 0.201 ms (2.81x). The fused output differs from the materialized atomic reduction by 2.15e-7 relative L2, while input and Wigner gradients are bitwise equal. The deterministic compiled forward and backward are bitwise repeatable. Test Plan: ```bash PYTHONPATH="$PWD/src" CUDA_VISIBLE_DEVICES=0 pytest -q tests/core/models/uma/uma_fast/test_fused_edgewise.py::test_wigner_inv_conv2_scatter_matches_materialized tests/core/models/uma/uma_fast/test_fused_edgewise.py::test_fused_edgewise_empty_graph -c packages/fairchem-core/pyproject.toml ``` ```bash PYTHONPATH="$PWD/src" CUDA_VISIBLE_DEVICES=0 pytest -q tests/core/models/uma/uma_fast/test_fused_edgewise.py::test_wigner_inv_conv2_scatter_dynamic_compile -c packages/fairchem-core/pyproject.toml ``` ```bash PYTHONPATH="$PWD/src" CUDA_VISIBLE_DEVICES=0 pytest -q tests/core/models/uma/uma_fast/test_fused_edgewise.py::test_wigner_inv_conv2_scatter_deterministic -c packages/fairchem-core/pyproject.toml ``` ```bash PYTHONPATH="$PWD/src" CUDA_VISIBLE_DEVICES=0 pytest -q tests/core/models/uma/uma_fast/test_execution_backends.py::test_umas_fast_gpu_forces_match_baseline_pbc tests/core/models/uma/uma_fast/test_execution_backends.py::test_umas_fast_gpu_forces_match_baseline_no_pbc -c packages/fairchem-core/pyproject.toml ``` Both force tests pass before the local Triton runtime aborts during interpreter teardown. ```bash PYTHONPATH="$PWD/src:/data/users/mlazos/pytorch/agent_space:$PYTHONPATH" CUDA_VISIBLE_DEVICES=0 python /data/users/mlazos/pytorch/agent_space/bench_uma_internal_padding.py --variant captured --bucket-size 1024 --repeat 13 ``` ```bash PYTHONPATH="$PWD/src:/data/users/mlazos/pytorch/agent_space:$PYTHONPATH" CUDA_VISIBLE_DEVICES=0 python /data/users/mlazos/pytorch/agent_space/bench_uma_internal_padding.py --variant captured --bucket-size 1024 --repeat 14 ``` ```bash pre-commit run --files src/fairchem/core/models/uma/nn/execution_backends.py src/fairchem/core/models/uma/triton/__init__.py src/fairchem/core/models/uma/triton/fused_wigner.py src/fairchem/core/models/uma/triton/kernels.py tests/core/models/uma/uma_fast/test_fused_edgewise.py ``` This commit was authored with assistance from Codex.
UMA-S lmax=2 Wigner matrices are block diagonal, but the fast GPU path materializes and carries 81 values per edge and direction while only 35 can be nonzero. Generate the three blocks directly, keep the compact layout through edge-degree and the fused Triton producer and consumer kernels, and reconstruct dense matrices only at legacy backend entry points. This reduces Wigner traffic and gradient storage without changing precision. Dynamic compiled generator and fused operation tests cover changing edge counts, deterministic fallbacks retain their behavior, and PBC energy, forces, and stress remain within the existing fast-backend tolerance. On UMA-S-1p2 with 1000 atoms, NVIDIA internal graph generation v3, external_graph_gen=False, merge_mole=True, dynamic torch.compile, fast math, the umas_fast_gpu backend, a 1024-edge bucket, and full outer CUDA graph capture, two trajectory repeats average 33.815 QPS versus 32.066 QPS for the committed predecessor (+5.45%). Reserved memory falls from 7.169 GiB to 7.096 GiB. Test Plan: ```bash PYTHONPATH="$PWD/src" CUDA_VISIBLE_DEVICES=0 pytest -q tests/core/models/uma/test_quaternion_wigner.py -k "compact_l2_matches_dense" -c packages/fairchem-core/pyproject.toml ``` ```bash PYTHONPATH="$PWD/src" CUDA_VISIBLE_DEVICES=0 pytest -q tests/core/models/uma/uma_fast/test_fused_edgewise.py -c packages/fairchem-core/pyproject.toml ``` ```bash PYTHONPATH="$PWD/src" CUDA_VISIBLE_DEVICES=0 pytest -q tests/core/models/uma/uma_fast/test_execution_backends.py::test_compact_edge_degree_matches_dense tests/core/models/uma/uma_fast/test_execution_backends.py::test_legacy_backend_rotations_accept_compact_wigner tests/core/models/uma/uma_fast/test_execution_backends.py::test_umas_fast_gpu_forces_match_baseline_pbc tests/core/models/uma/uma_fast/test_execution_backends.py::test_umas_fast_gpu_forces_match_baseline_no_pbc -c packages/fairchem-core/pyproject.toml ``` ```bash PYTHONPATH="$PWD/src:/data/users/mlazos/pytorch/agent_space:$PYTHONPATH" CUDA_VISIBLE_DEVICES=0 python /data/users/mlazos/pytorch/agent_space/bench_uma_internal_padding.py --variant captured --bucket-size 1024 --repeat 16 PYTHONPATH="$PWD/src:/data/users/mlazos/pytorch/agent_space:$PYTHONPATH" CUDA_VISIBLE_DEVICES=0 python /data/users/mlazos/pytorch/agent_space/bench_uma_internal_padding.py --variant captured --bucket-size 1024 --repeat 17 ``` ```bash pre-commit run --files src/fairchem/core/models/uma/common/quaternion/wigner_d_hybrid.py src/fairchem/core/models/uma/escn_md.py src/fairchem/core/models/uma/nn/execution_backends.py src/fairchem/core/models/uma/triton/fused_wigner.py src/fairchem/core/models/uma/triton/kernels.py tests/core/models/uma/test_quaternion_wigner.py tests/core/models/uma/uma_fast/test_execution_backends.py tests/core/models/uma/uma_fast/test_fused_edgewise.py tests/core/models/uma/uma_fast/triton_test_utils.py ``` The Triton-heavy pytest processes report all selected tests passed, then hit the existing local interpreter teardown abort. The compact generator and legacy fallback tests exit cleanly. This commit was authored with assistance from Codex.
The fast GPU backend can be selected for channel widths and autocast dtypes that the packed FP32 Triton gate does not support. Keep the packed GEMM outputs, but route their activation through the existing PyTorch block implementation unless the actual outputs are FP32 with a power-of-two channel width. This avoids rejecting valid fast-backend configurations without repeating the GEMMs. Compact Wigner storage also made the exported fused operations reject their prior dense [E, 9, 9] inputs. Pack dense block-diagonal inputs before entering custom autograd so the public interface, dense gradient shape, and zero off-block gradients are preserved. Test Plan: ```bash PYTHONPATH="$PWD/src" pytest -q tests/core/models/uma/uma_fast/test_execution_backends.py -k "gate_activation_fallback or compact_edge_degree_matches_dense" PYTHONPATH="$PWD/src" pytest -q tests/core/models/uma/uma_fast/test_fused_edgewise.py -k "exported_fused_ops_accept_dense_wigner or wigner_conv1_fused_dynamic_compile" pre-commit run --files src/fairchem/core/models/uma/escn_md_block.py src/fairchem/core/models/uma/nn/execution_backends.py src/fairchem/core/models/uma/triton/fused_wigner.py tests/core/models/uma/uma_fast/test_execution_backends.py tests/core/models/uma/uma_fast/test_fused_edgewise.py ``` Authored with assistance from an AI coding tool.
Torch compile can capture UMA compute regions, but internal neighbor generation changes the exact edge shape from one frame to the next. Those shape changes prevent reliable CUDA graph reuse even when the atom count is fixed. Expose reduce-overhead as an inference compile mode and mark prediction boundaries for CUDA graph trees. For internal NVIDIA v3 graphs, generate the neighbor list before model execution and pad its edges to a configurable bucket. Padded edges are moved beyond the cutoff so they contribute zero energy, force, and stress while keeping the compiled input shape stable. Neighbor construction remains outside capture because the released NVIDIA implementation allocates temporary buffers. The internal path is limited to CUDA, graph version 3, and non-distributed inference. External graphs can use reduce-overhead without padding. Test Plan: ``` PYTHONPATH="$PWD/src" pytest -q -s tests/core/graph/test_padded_nvidia_graph.py tests/core/models/uma/test_padded_edges.py tests/core/units/mlip_unit/test_inference_settings.py PYTHONPATH="$PWD/src" pytest -q -s tests/core/units/mlip_unit/test_predict.py::test_reduce_overhead_internal_graph_predict pre-commit run --files docs/core/common_tasks/ase_calculator.md src/fairchem/core/graph/padded_nvidia_graph.py src/fairchem/core/models/uma/escn_md.py src/fairchem/core/units/mlip_unit/api/inference.py src/fairchem/core/units/mlip_unit/predict.py tests/core/graph/test_padded_nvidia_graph.py tests/core/models/uma/test_padded_edges.py tests/core/units/mlip_unit/test_inference_settings.py tests/core/units/mlip_unit/test_predict.py ```
|
This PR has been marked as stale because it has been open for 30 days with no activity. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This adds an opt-in
compile_mode="reduce-overhead"inference setting sotorch.compilecan use its built-in CUDA graph support for UMA.Internal NVIDIA v3 neighbor generation remains outside the captured model
regions. Before the model runs, its variable-length edge list is padded to a
configurable bucket. Padded edges are moved beyond the cutoff, so they
contribute zero energy, force, and stress while keeping the compiled tensor
shape stable across nearby molecular-dynamics frames.
This uses released
nvalchemiops 0.4.0; it does not require a patched NVIDIAlibrary or a custom outer CUDA graph runner. It depends on #2154 for the UMA
fast-GPU kernel baseline.
Performance
Measured on one H100 with:
activation_checkpointing=Falsemerge_mole=Truecompile=True,dynamic=Trueexternal_graph_gen=Falseinternal_graph_gen_version=3execution_mode="umas_fast_gpu"Both predictors were compiled and warmed in the same process. Ten alternating
20-step blocks used identical position sequences.
reduce-overheadThis is a 7.09% median QPS improvement and a 5.53% mean QPS improvement. There
were no timed recompiles. Inductor reported 29 recorded CUDA graph regions.
The measured frame had 78,424 real edges and was padded to 78,848, adding 424
masked edges (0.54%). Separate-process steady reserved memory was 9.285 GiB for
the baseline and 7.533-7.660 GiB with
reduce-overhead.Numerical checks
At the same displaced 1,000-atom frame, maximum absolute differences versus
the dynamic compile baseline were:
NVIDIA v3 returns the same edge multiset in nondeterministic order. A
same-order padded-versus-unpadded check stayed within the variation seen when
repeating the unpadded path. Direct eager checks on single- and two-system
batches were also within 5.96e-8 for energy, 8.38e-9 for forces, and 1.64e-11
for stress.
The added CUDA regression uses the real UMA-S-1p2 checkpoint. It compares
eager and
reduce-overheadenergy, forces, and stress across repeated calls,retains an earlier output to detect replay-buffer overwrites, and crosses to a
different edge bucket before returning to the original bucket.
Limitations
reduce-overheadcurrently requires CUDA and NVIDIA graph version3.
implementation allocates temporary buffers.
to a previous bucket reuses its existing compiled graph.
Test plan