Skip to content

Commit 987d303

Browse files
authored
Merge branch 'master' into feat/pt_expt-auto-neighbor-graph-builder
2 parents c612f05 + e5fdff0 commit 987d303

70 files changed

Lines changed: 607 additions & 384 deletions

Some content is hidden

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

.github/workflows/test_cuda.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ jobs:
125125
# junit-aoti.xml = compile lane (T_A), junit-gpu.xml = GPU lane (T_B);
126126
# used to compare the two lanes against the pre-split serial baseline.
127127
if: always()
128-
uses: actions/upload-artifact@v4
128+
uses: actions/upload-artifact@v7
129129
with:
130130
name: cuda-pytest-junit
131131
path: |

deepmd/dpmodel/utils/lmdb_data.py

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,18 @@ def _remap_keys(frame: dict[str, Any]) -> dict[str, Any]:
149149
return out
150150

151151

152+
def _remap_atom_types(atype: np.ndarray, type_remap: np.ndarray) -> np.ndarray:
153+
"""Remap real atom types while preserving negative virtual sentinels.
154+
155+
Positive indices retain NumPy's normal bounds checking, so malformed LMDB
156+
data cannot be silently reinterpreted as a different species.
157+
"""
158+
remapped_atype = atype.astype(np.int64, copy=True)
159+
real_atom_mask = remapped_atype >= 0
160+
remapped_atype[real_atom_mask] = type_remap[remapped_atype[real_atom_mask]]
161+
return remapped_atype
162+
163+
152164
def is_lmdb(systems: str) -> bool:
153165
"""Check if systems points to an LMDB dataset."""
154166
return systems.endswith(".lmdb") or Path(systems, "data.mdb").is_file()
@@ -466,10 +478,16 @@ def __init__(
466478
def _compute_natoms_vec(self, atype: np.ndarray) -> np.ndarray:
467479
"""Compute natoms_vec from a frame's atype array.
468480
481+
Negative virtual types are excluded from the per-type counts, matching
482+
mixed-type NPY data handling. This function also excludes positive
483+
indices outside the configured type map. The leading nloc entries still
484+
include every atom slot.
485+
469486
Returns [nloc, nloc, count_type0, count_type1, ...] with length ntypes+2.
470487
"""
471488
nloc = len(atype)
472-
counts = np.bincount(atype, minlength=self._ntypes)[: self._ntypes]
489+
real_atype = atype[(atype >= 0) & (atype < self._ntypes)]
490+
counts = np.bincount(real_atype, minlength=self._ntypes)
473491
vec = np.empty(self._ntypes + 2, dtype=np.int64)
474492
vec[0] = nloc
475493
vec[1] = nloc
@@ -579,7 +597,7 @@ def __getitem__(self, index: int) -> dict[str, Any]:
579597
frame["atype"] = frame["atype"].reshape(-1).astype(np.int64)
580598
# Remap atom types from LMDB's type_map to model's type_map
581599
if self._type_remap is not None:
582-
frame["atype"] = self._type_remap[frame["atype"]].astype(np.int64)
600+
frame["atype"] = _remap_atom_types(frame["atype"], self._type_remap)
583601
if "virial" in frame and isinstance(frame["virial"], np.ndarray):
584602
frame["virial"] = (
585603
frame["virial"].reshape(9).astype(self._resolve_dtype("virial"))
@@ -1459,9 +1477,9 @@ def __init__(
14591477
and "atype" in frame
14601478
and isinstance(frame["atype"], np.ndarray)
14611479
):
1462-
frame["atype"] = self._type_remap[
1463-
frame["atype"].reshape(-1)
1464-
].astype(np.int64)
1480+
frame["atype"] = _remap_atom_types(
1481+
frame["atype"].reshape(-1), self._type_remap
1482+
)
14651483
self._frames.append(frame)
14661484

14671485
# Shuffle if requested

deepmd/dpmodel/utils/stat.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ def collect_observed_types(sampled: list[dict], type_map: list[str]) -> list[str
7272
Returns
7373
-------
7474
list[str]
75-
Sorted list of observed element symbols.
75+
Sorted list of observed element symbols. Negative virtual atom types
76+
and indices outside ``type_map`` are ignored.
7677
"""
7778
from deepmd.utils.econf_embd import (
7879
sort_element_type,
@@ -83,7 +84,7 @@ def collect_observed_types(sampled: list[dict], type_map: list[str]) -> list[str
8384
atype = to_numpy_array(system["atype"]) # shape: [nframes, natoms]
8485
observed_indices.update(np.unique(atype).tolist())
8586
observed_types = [
86-
type_map[i] for i in sorted(observed_indices) if i < len(type_map)
87+
type_map[i] for i in sorted(observed_indices) if 0 <= i < len(type_map)
8788
]
8889
return sort_element_type(observed_types)
8990

doc/README

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
To run the HTML documentation build, doxygen have to be installed.
1+
Building the documentation requires Python 3.11 or newer because the `docs`
2+
extra uses MyST-Parser 5.1 and Sphinx 8. Doxygen must also be installed to build
3+
the HTML documentation.

doc/backend.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,8 @@ The `.pd` extension is used for model checkpoint storage, which is commonly util
4545

4646
### DP {{ dpmodel_icon }}
4747

48-
:::{note}
49-
This backend is only for development and should not take into production.
50-
:::
48+
> [!NOTE]
49+
> This backend is only for development and should not take into production.
5150
5251
- Model filename extension: `.dp`, `.yaml`, `.yml`
5352

doc/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,7 @@
201201
"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.0/es5/tex-mml-chtml.min.js"
202202
)
203203
myst_enable_extensions = [
204+
"alert",
204205
"dollarmath",
205206
"colon_fence",
206207
"substitution",

doc/data/system.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,8 @@ In general, we always use the following convention of units:
5050

5151
## Mixed type
5252

53-
:::{note}
54-
Only the [DPA-1](../model/train-se-atten.md) and [DPA-2](../model/dpa2.md) descriptors support this format.
55-
:::
53+
> [!NOTE]
54+
> Only the [DPA-1](../model/train-se-atten.md) and [DPA-2](../model/dpa2.md) descriptors support this format.
5655
5756
In the standard data format, only those frames with the same fingerprint (i.e. the number of atoms of different elements) can be put together as a unified system.
5857
This may lead to sparse frame numbers in those rare systems.

doc/development/create-a-model-pt.md

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
# Create a model in other backends {{ pytorch_icon }} {{ dpmodel_icon }}
22

3-
:::{note}
4-
**Supported backends**: PyTorch {{ pytorch_icon }}, DP {{ dpmodel_icon }}
5-
6-
In the following context, we use the PyTorch backend as the example, while it also applies to other backends listed above.
7-
:::
3+
> [!NOTE]
4+
> **Supported backends**: PyTorch {{ pytorch_icon }}, DP {{ dpmodel_icon }}
5+
>
6+
> In the following context, we use the PyTorch backend as the example, while it also applies to other backends listed above.
87
98
If you'd like to create a new model that isn't covered by the existing DeePMD-kit library, but reuse DeePMD-kit's other efficient modules such as data processing, trainer, etc, you may want to read this section.
109

doc/development/type-embedding.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,5 @@ build -> _pass_filter -> _filter -> _filter_lower
8686

8787
In `fitting net`, it takes the descriptor vector as input, whose dimension is \[natoms, $M_1\times M_2$\]. Because we need to involve information on the centric atom in this step, we need to generate a matrix named `atype_embed` (of dim [natoms, nchanl]), in which each row is the type embedding vector of the specific centric atom. The input is sorted by type of centric atom, we also know the number of a particular atom type (stored in `natoms[2+i]`), thus we get the type vector of the centric atom. In the build phase of the fitting net, it will check whether type embedding exists in `input_dict` and fetch them. After that, call `embed_atom_type` function to look up the embedding vector for the type vector of the centric atom to obtain `atype_embed`, and concat input with it ([input, atype_embed]). The modified input goes through `fitting` net\` to get predicted energy.
8888

89-
:::{note}
90-
You can't apply the compression method while using atom-type embedding.
91-
:::
89+
> [!NOTE]
90+
> You can't apply the compression method while using atom-type embedding.

doc/env.md

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
# Runtime environment variables
22

3-
:::{note}
4-
For build-time environment variables, see [Install from source code](./install/install-from-source.md).
5-
:::
3+
> [!NOTE]
4+
> For build-time environment variables, see [Install from source code](./install/install-from-source.md).
65
76
## All interfaces
87

0 commit comments

Comments
 (0)