Skip to content

Commit 35d031d

Browse files
committed
private triton
1 parent 64166f6 commit 35d031d

4 files changed

Lines changed: 37 additions & 108 deletions

File tree

deepmd/pt/model/descriptor/sezm_nn/so2.py

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -958,19 +958,27 @@ def __init__(
958958
self._rotate_to_local_fn = None
959959
self._rotate_back_fn = None
960960
if self.use_triton_infer:
961-
from .triton import (
961+
from .triton.so2_rotation import (
962962
rotate_back_block,
963963
rotate_back_dense,
964964
rotate_to_local_block,
965965
rotate_to_local_dense,
966966
)
967967

968968
if self.mmax == 1:
969-
self._rotate_to_local_fn = rotate_to_local_block
970-
self._rotate_back_fn = rotate_back_block
969+
self._rotate_to_local_fn = lambda x, src, wigner: rotate_to_local_block(
970+
x, src, wigner, self.lmax
971+
)
972+
self._rotate_back_fn = lambda x_local, wigner: rotate_back_block(
973+
x_local, wigner, self.lmax
974+
)
971975
else:
972-
self._rotate_to_local_fn = rotate_to_local_dense
973-
self._rotate_back_fn = rotate_back_dense
976+
self._rotate_to_local_fn = lambda x, src, wigner: rotate_to_local_dense(
977+
x, src, wigner, self.coeff_index_m, self.ebed_dim_full
978+
)
979+
self._rotate_back_fn = lambda x_local, wigner: rotate_back_dense(
980+
x_local, wigner, self.coeff_index_m, self.ebed_dim_full
981+
)
974982

975983
# === Step 1. Precompute coefficient indices for m-major reduced layout ===
976984
coeff_index_m = build_m_major_index(self.lmax, self.mmax, device=self.device)
@@ -1460,12 +1468,10 @@ def forward(
14601468
# ``self._rotate_to_local_fn`` was bound in ``__init__`` (the
14611469
# block kernel for the m-major ``mmax == 1`` layout, dense
14621470
# otherwise).
1463-
x_local = self._rotate_to_local_fn(
1464-
x, src, D_full, self.coeff_index_m, self.ebed_dim_full
1465-
) # (E, D_m, C_wide)
1471+
x_local = self._rotate_to_local_fn(x, src, D_full) # (E, D_m, C_wide)
14661472
if self.node_wise_grid_product is not None:
14671473
x_dst_local = self._rotate_to_local_fn(
1468-
x, dst, D_full, self.coeff_index_m, self.ebed_dim_full
1474+
x, dst, D_full
14691475
) # (E, D_m, C_wide)
14701476
else:
14711477
D_m_prime = project_D_to_m(
@@ -1623,12 +1629,7 @@ def apply_bias_correction(
16231629
with nvtx_range("SO2Conv/rotate_back"):
16241630
Dt_full = edge_cache.Dt_full
16251631
if self.use_triton_infer and not self.training:
1626-
x_message = self._rotate_back_fn(
1627-
x_local,
1628-
Dt_full,
1629-
self.coeff_index_m,
1630-
self.ebed_dim_full,
1631-
) # (E, D, C_wide)
1632+
x_message = self._rotate_back_fn(x_local, Dt_full) # (E, D, C_wide)
16321633
else:
16331634
Dt_from_m = project_Dt_from_m(
16341635
Dt_full=Dt_full,

deepmd/pt/model/descriptor/sezm_nn/triton/__init__.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,14 @@
22
"""Hardware-accelerated SeZM/DPA4 operators.
33
44
This package hosts ``make_fx``-composable Triton implementations of SeZM hot
5-
paths. The SO(2) rotation API exposes a general dense path that honors arbitrary
6-
coefficient indices and a block path for the canonical m-major ``mmax=1`` layout.
5+
paths. Kernel entry points are internal implementation details of the SeZM
6+
descriptor; the package-level API only exposes availability.
77
"""
88

99
from .so2_rotation import (
10-
rotate_back_block,
11-
rotate_back_dense,
12-
rotate_to_local_block,
13-
rotate_to_local_dense,
10+
TRITON_ROTATION_AVAILABLE,
1411
)
1512

1613
__all__ = [
17-
"rotate_back_block",
18-
"rotate_back_dense",
19-
"rotate_to_local_block",
20-
"rotate_to_local_dense",
14+
"TRITON_ROTATION_AVAILABLE",
2115
]

deepmd/pt/model/descriptor/sezm_nn/triton/so2_rotation.py

Lines changed: 13 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,6 @@
5858
annotations,
5959
)
6060

61-
import math
62-
6361
import torch
6462
from torch import (
6563
Tensor,
@@ -71,12 +69,6 @@
7169

7270
__all__ = [
7371
"TRITON_ROTATION_AVAILABLE",
74-
"rotate_back_block",
75-
"rotate_back_dense",
76-
"rotate_back_reference",
77-
"rotate_to_local_block",
78-
"rotate_to_local_dense",
79-
"rotate_to_local_reference",
8072
]
8173

8274
try:
@@ -1159,30 +1151,8 @@ def _launch_rotate_back_bwd(
11591151

11601152

11611153
# ======================================================================
1162-
# Block-diagonal launch wrappers + layout detection (mmax == 1)
1154+
# Block-diagonal launch wrappers (mmax == 1)
11631155
# ======================================================================
1164-
def _block_layout_lmax(coeff_index: Tensor, dim_full: int) -> int:
1165-
"""Return ``lmax`` if ``(coeff_index, dim_full)`` is the m-major ``mmax=1``
1166-
layout that the block-diagonal kernels assume, else ``-1``.
1167-
1168-
This intentionally checks only shape-level invariants. The block kernels
1169-
ignore ``coeff_index`` values, so production callers must only use the block
1170-
entry points when they own the canonical m-major ``mmax=1`` index.
1171-
"""
1172-
dim_full = int(dim_full)
1173-
root = math.isqrt(dim_full)
1174-
if root * root != dim_full:
1175-
return -1
1176-
lmax = root - 1
1177-
try:
1178-
numel = int(coeff_index.shape[0])
1179-
except Exception: # pragma: no cover - exotic shape proxies
1180-
return -1
1181-
if lmax < 1 or numel != 3 * lmax + 1:
1182-
return -1
1183-
return lmax
1184-
1185-
11861156
def _launch_bd_to_local_fwd(
11871157
x: Tensor, src: Tensor, wigner: Tensor, lmax: int
11881158
) -> Tensor:
@@ -1619,37 +1589,23 @@ def rotate_back_dense(
16191589
return _rotate_back_op(x_local, wigner, coeff_index, int(dim_full))
16201590

16211591

1622-
def rotate_to_local_block(
1623-
x: Tensor, src: Tensor, wigner: Tensor, coeff_index: Tensor, dim_full: int
1624-
) -> Tensor:
1592+
def rotate_to_local_block(x: Tensor, src: Tensor, wigner: Tensor, lmax: int) -> Tensor:
16251593
"""Apply the block-diagonal ``global -> local`` rotation.
16261594
1627-
Use this only when the caller owns the invariant that ``coeff_index`` is the
1628-
canonical m-major ``mmax=1`` index produced by
1629-
:func:`build_m_major_index`. The kernel ignores the tensor values in
1630-
``coeff_index`` and derives the layout from ``lmax``.
1595+
Use this when the caller owns the invariant that the reduced layout is the
1596+
canonical m-major ``mmax=1`` layout for ``lmax``. The block kernel derives
1597+
the reduced row order from ``lmax`` and does not consume a coefficient-index
1598+
tensor.
16311599
"""
1632-
lmax = _block_layout_lmax(coeff_index, dim_full)
1633-
if lmax < 0:
1634-
raise ValueError(
1635-
"rotate_to_local_block requires the m-major mmax=1 coefficient layout."
1636-
)
1637-
return _block_to_local_op(x, src, wigner, lmax)
1600+
return _block_to_local_op(x, src, wigner, int(lmax))
16381601

16391602

1640-
def rotate_back_block(
1641-
x_local: Tensor, wigner: Tensor, coeff_index: Tensor, dim_full: int
1642-
) -> Tensor:
1603+
def rotate_back_block(x_local: Tensor, wigner: Tensor, lmax: int) -> Tensor:
16431604
"""Apply the block-diagonal ``local -> global`` rotation.
16441605
1645-
Use this only when the caller owns the invariant that ``coeff_index`` is the
1646-
canonical m-major ``mmax=1`` index produced by
1647-
:func:`build_m_major_index`. The kernel ignores the tensor values in
1648-
``coeff_index`` and derives the layout from ``lmax``.
1606+
Use this when the caller owns the invariant that ``x_local`` is ordered in
1607+
the canonical m-major ``mmax=1`` layout for ``lmax``. The block kernel
1608+
derives the reduced column order from ``lmax`` and does not consume a
1609+
coefficient-index tensor.
16491610
"""
1650-
lmax = _block_layout_lmax(coeff_index, dim_full)
1651-
if lmax < 0:
1652-
raise ValueError(
1653-
"rotate_back_block requires the m-major mmax=1 coefficient layout."
1654-
)
1655-
return _block_back_op(x_local, wigner, lmax)
1611+
return _block_back_op(x_local, wigner, int(lmax))

source/tests/pt/model/test_descriptor_sezm_triton.py

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -94,28 +94,6 @@ def test_noncanonical_same_length_uses_dense_reference(self):
9494
rotate_back_reference(x_local, wigner, coeff_index, dim),
9595
)
9696

97-
def test_explicit_block_uses_shape_contract_only(self):
98-
device = torch.device("cpu")
99-
dtype = torch.float32
100-
lmax = 3
101-
dim = get_so3_dim_of_lmax(lmax)
102-
canonical = build_m_major_index(lmax, 1, device=device)
103-
coeff_index = torch.roll(canonical, shifts=1)
104-
x = torch.randn(4, dim, 3, device=device, dtype=dtype)
105-
src = torch.tensor([0, 2, 1, 3, 0], dtype=torch.long, device=device)
106-
wigner = torch.randn(src.numel(), dim, dim, device=device, dtype=dtype)
107-
x_local = torch.randn(
108-
src.numel(), coeff_index.numel(), 3, device=device, dtype=dtype
109-
)
110-
111-
self.assertEqual(
112-
rotate_to_local_block(x, src, wigner, coeff_index, dim).shape, x_local.shape
113-
)
114-
self.assertEqual(
115-
rotate_back_block(x_local, wigner, coeff_index, dim).shape,
116-
(src.numel(), dim, 3),
117-
)
118-
11997
def test_symbolic_trace_noncanonical_same_length_uses_dense_op(self):
12098
device = torch.device("cpu")
12199
dtype = torch.float32
@@ -186,7 +164,7 @@ def _assert_to_local_matches_reference(self, x0, src, w0, coeff_index, dim):
186164

187165
xa = x0.clone().requires_grad_(True)
188166
wa = w0.clone().requires_grad_(True)
189-
out = rotate_to_local_block(xa, src, wa, coeff_index, dim)
167+
out = rotate_to_local_block(xa, src, wa, lmax)
190168
xr = x0.clone().requires_grad_(True)
191169
wr = w0.clone().requires_grad_(True)
192170
ref = rotate_to_local_reference(xr, src, wr, coeff_index, dim)
@@ -206,7 +184,7 @@ def _assert_back_matches_reference(self, xl0, w0, coeff_index, dim):
206184

207185
xa = xl0.clone().requires_grad_(True)
208186
wa = w0.clone().requires_grad_(True)
209-
out = rotate_back_block(xa, wa, coeff_index, dim)
187+
out = rotate_back_block(xa, wa, lmax)
210188
xr = xl0.clone().requires_grad_(True)
211189
wr = w0.clone().requires_grad_(True)
212190
ref = rotate_back_reference(xr, wr, coeff_index, dim)
@@ -248,7 +226,7 @@ def test_symbolic_make_fx_rotate_to_local_forward_backward_matches_eager(self):
248226
def forward_and_grad(x, wigner):
249227
x_req = x.detach().requires_grad_(True)
250228
w_req = wigner.detach().requires_grad_(True)
251-
out = rotate_to_local_block(x_req, src, w_req, coeff_index, dim)
229+
out = rotate_to_local_block(x_req, src, w_req, lmax)
252230
grad_x, grad_wigner = torch.autograd.grad(
253231
out,
254232
(x_req, w_req),
@@ -291,7 +269,7 @@ def test_symbolic_make_fx_rotate_back_forward_backward_matches_eager(self):
291269
def forward_and_grad(x_local, wigner):
292270
x_req = x_local.detach().requires_grad_(True)
293271
w_req = wigner.detach().requires_grad_(True)
294-
out = rotate_back_block(x_req, w_req, coeff_index, dim)
272+
out = rotate_back_block(x_req, w_req, lmax)
295273
grad_x, grad_wigner = torch.autograd.grad(
296274
out,
297275
(x_req, w_req),

0 commit comments

Comments
 (0)