Skip to content

Commit c73ecd0

Browse files
committed
opt dpa1
1 parent 91642c1 commit c73ecd0

44 files changed

Lines changed: 4632 additions & 1379 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

deepmd/dpmodel/utils/neighbor_graph/__init__.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
44
The unified edge/graph neighbor-list contract and its supporting machinery:
55
``graph`` (the ``NeighborGraph``/``GraphLayout`` contract + derived node-validity
6-
+ edge padding), ``builder`` (the carry-all ``build_neighbor_graph`` dispatcher +
7-
the ``from_dense_quartet`` legacy converter), ``segment`` (mask-aware
6+
+ edge padding), ``csr`` (backend-agnostic CSR construction and canonicalization),
7+
``builder`` (the carry-all ``build_neighbor_graph`` dispatcher + the
8+
``from_dense_quartet`` legacy converter), ``segment`` (mask-aware
89
segment-reduction toolkit), and ``derivatives`` (edge force/virial assembly).
910
See the design discussion wanghan-iapcm/deepmd-kit#4.
1011
"""
@@ -24,6 +25,10 @@
2425
build_neighbor_graph,
2526
from_dense_quartet,
2627
)
28+
from .csr import (
29+
build_edge_csr,
30+
canonicalize_neighbor_graph,
31+
)
2732
from .derivatives import (
2833
edge_force_virial,
2934
)
@@ -59,8 +64,10 @@
5964
"angle_to_node_sum",
6065
"attach_angles",
6166
"build_angle_index",
67+
"build_edge_csr",
6268
"build_neighbor_graph",
6369
"build_neighbor_graph_ase",
70+
"canonicalize_neighbor_graph",
6471
"center_edge_pairs",
6572
"edge_env_mat",
6673
"edge_force_virial",

deepmd/dpmodel/utils/neighbor_graph/ase_builder.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ def build_neighbor_graph_ase(
4242
box: Array | None,
4343
rcut: float,
4444
layout: GraphLayout | None = None,
45+
*,
46+
with_csr: bool = False,
47+
canonicalize: bool = False,
4548
) -> NeighborGraph:
4649
"""Build a CARRY-ALL NeighborGraph using ASE's O(N) cell-list search.
4750
@@ -66,6 +69,12 @@ def build_neighbor_graph_ase(
6669
cutoff radius.
6770
layout
6871
edge-axis length policy; ``None`` => dynamic (torch) with ``min_edges`` guards.
72+
with_csr
73+
Whether to construct destination/source CSR views for a consumer that
74+
requires edge-grouped reductions.
75+
canonicalize
76+
Whether to reorder every edge field into destination-major form. Implies
77+
``with_csr=True``.
6978
7079
Returns
7180
-------
@@ -137,5 +146,14 @@ def _to_cpu_numpy(x: Any) -> np.ndarray:
137146
S_all, nframe_all = S_all[keep], nframe_all[keep]
138147

139148
return neighbor_graph_from_ijs(
140-
i_all, j_all, S_all, coord, box, nframe_all, nloc, layout=layout
149+
i_all,
150+
j_all,
151+
S_all,
152+
coord,
153+
box,
154+
nframe_all,
155+
nloc,
156+
layout=layout,
157+
with_csr=with_csr,
158+
canonicalize=canonicalize,
141159
)

deepmd/dpmodel/utils/neighbor_graph/builder.py

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939

4040
import array_api_compat
4141

42+
from .csr import (
43+
build_edge_csr,
44+
)
4245
from .graph import (
4346
GraphLayout,
4447
NeighborGraph,
@@ -57,6 +60,9 @@ def from_dense_quartet(
5760
mapping: Array,
5861
layout: GraphLayout | None = None,
5962
compact: bool = True,
63+
*,
64+
with_csr: bool = False,
65+
canonicalize: bool = False,
6066
) -> NeighborGraph:
6167
"""Convert a legacy extended quartet into a ghost-free NeighborGraph (CONVERTER).
6268
@@ -98,6 +104,12 @@ def from_dense_quartet(
98104
``src`` pointing at the center (in-range, masked) -- so no ``nonzero`` is
99105
used and the converter is jit/export-traceable. The masked edges contribute
100106
zero in a downstream ``segment_sum``, so the descriptor output is unchanged.
107+
with_csr
108+
Whether to construct destination/source CSR views for a consumer that
109+
requires edge-grouped reductions.
110+
canonicalize
111+
Whether to reorder every edge field into destination-major form. Implies
112+
``with_csr=True``.
101113
102114
Returns
103115
-------
@@ -108,6 +120,7 @@ def from_dense_quartet(
108120
"""
109121
if layout is None:
110122
layout = GraphLayout()
123+
with_csr = with_csr or canonicalize
111124
xp = array_api_compat.array_namespace(extended_coord, nlist, mapping)
112125
dev = array_api_compat.device(extended_coord)
113126
nf, nloc, nsel = nlist.shape
@@ -148,11 +161,38 @@ def from_dense_quartet(
148161
edge_index = xp.astype(xp.stack([src, dst], axis=0), xp.int64)
149162
edge_mask = valid
150163
n_node = xp.full((nf,), nloc, dtype=xp.int64, device=dev)
164+
if not with_csr:
165+
return NeighborGraph(
166+
n_node=n_node,
167+
edge_index=edge_index,
168+
edge_vec=edge_vec,
169+
edge_mask=edge_mask,
170+
)
171+
(
172+
edge_index,
173+
edge_vec,
174+
edge_mask,
175+
destination_order,
176+
destination_row_ptr,
177+
source_row_ptr,
178+
source_order,
179+
) = build_edge_csr(
180+
edge_index,
181+
edge_vec,
182+
edge_mask,
183+
nf * nloc,
184+
canonicalize=canonicalize,
185+
)
151186
return NeighborGraph(
152187
n_node=n_node,
153188
edge_index=edge_index,
154189
edge_vec=edge_vec,
155190
edge_mask=edge_mask,
191+
destination_order=destination_order,
192+
destination_row_ptr=destination_row_ptr,
193+
source_row_ptr=source_row_ptr,
194+
source_order=source_order,
195+
destination_sorted=canonicalize,
156196
)
157197
else:
158198
# COMPACT: drop invalid slots via nonzero (dynamic shape -> eager only,
@@ -189,11 +229,38 @@ def from_dense_quartet(
189229
edge_index, edge_vec, layout.edge_capacity, layout.min_edges
190230
)
191231
n_node = xp.full((nf,), nloc, dtype=xp.int64, device=dev)
232+
if not with_csr:
233+
return NeighborGraph(
234+
n_node=n_node,
235+
edge_index=edge_index,
236+
edge_vec=edge_vec,
237+
edge_mask=edge_mask,
238+
)
239+
(
240+
edge_index,
241+
edge_vec,
242+
edge_mask,
243+
destination_order,
244+
destination_row_ptr,
245+
source_row_ptr,
246+
source_order,
247+
) = build_edge_csr(
248+
edge_index,
249+
edge_vec,
250+
edge_mask,
251+
nf * nloc,
252+
canonicalize=canonicalize,
253+
)
192254
return NeighborGraph(
193255
n_node=n_node,
194256
edge_index=edge_index,
195257
edge_vec=edge_vec,
196258
edge_mask=edge_mask,
259+
destination_order=destination_order,
260+
destination_row_ptr=destination_row_ptr,
261+
source_row_ptr=source_row_ptr,
262+
source_order=source_order,
263+
destination_sorted=canonicalize,
197264
)
198265

199266

@@ -203,6 +270,9 @@ def build_neighbor_graph(
203270
box: Array | None,
204271
rcut: float,
205272
layout: GraphLayout | None = None,
273+
*,
274+
with_csr: bool = False,
275+
canonicalize: bool = False,
206276
) -> NeighborGraph:
207277
"""Build a CARRY-ALL NeighborGraph DIRECTLY from coordinates (``dense`` search).
208278
@@ -236,6 +306,12 @@ def build_neighbor_graph(
236306
at non-binding ``sel``).
237307
layout
238308
edge-axis length policy; ``None`` => dynamic (torch) with ``min_edges`` guards.
309+
with_csr
310+
Whether to construct destination/source CSR views for a consumer that
311+
requires edge-grouped reductions.
312+
canonicalize
313+
Whether to reorder every edge field into destination-major form. Implies
314+
``with_csr=True``.
239315
"""
240316
from deepmd.dpmodel.utils.nlist import (
241317
extend_coord_with_ghosts,
@@ -246,6 +322,7 @@ def build_neighbor_graph(
246322

247323
if layout is None:
248324
layout = GraphLayout()
325+
with_csr = with_csr or canonicalize
249326
xp = array_api_compat.array_namespace(coord, atype)
250327
dev = array_api_compat.device(coord)
251328
nf, nloc = atype.shape[:2]
@@ -298,9 +375,36 @@ def build_neighbor_graph(
298375
edge_index, edge_vec, layout.edge_capacity, layout.min_edges
299376
)
300377
n_node = xp.full((nf,), nloc, dtype=xp.int64, device=dev)
378+
if not with_csr:
379+
return NeighborGraph(
380+
n_node=n_node,
381+
edge_index=edge_index,
382+
edge_vec=edge_vec,
383+
edge_mask=edge_mask,
384+
)
385+
(
386+
edge_index,
387+
edge_vec,
388+
edge_mask,
389+
destination_order,
390+
destination_row_ptr,
391+
source_row_ptr,
392+
source_order,
393+
) = build_edge_csr(
394+
edge_index,
395+
edge_vec,
396+
edge_mask,
397+
nf * nloc,
398+
canonicalize=canonicalize,
399+
)
301400
return NeighborGraph(
302401
n_node=n_node,
303402
edge_index=edge_index,
304403
edge_vec=edge_vec,
305404
edge_mask=edge_mask,
405+
destination_order=destination_order,
406+
destination_row_ptr=destination_row_ptr,
407+
source_row_ptr=source_row_ptr,
408+
source_order=source_order,
409+
destination_sorted=canonicalize,
306410
)

0 commit comments

Comments
 (0)