Found during a Codex global scan of deepmodeling/deepmd-kit at commit 73de44b1f94471b2e3bdb6b11f57b34d7bc791bb.
Problem
Several dpmodel statistics and LMDB reader paths treat negative/virtual atom types as real type indices.
Evidence:
collect_observed_types() records all unique atom-type values and only filters the upper bound, so -1 passes and becomes type_map[-1]:
|
observed_indices: set[int] = set() |
|
for system in sampled: |
|
atype = to_numpy_array(system["atype"]) # shape: [nframes, natoms] |
|
observed_indices.update(np.unique(atype).tolist()) |
|
observed_types = [ |
|
type_map[i] for i in sorted(observed_indices) if i < len(type_map) |
|
] |
|
return sort_element_type(observed_types) |
LmdbDataReader._compute_natoms_vec() calls np.bincount(atype, ...), which raises when atype contains negative virtual atoms:
|
def _compute_natoms_vec(self, atype: np.ndarray) -> np.ndarray: |
|
"""Compute natoms_vec from a frame's atype array. |
|
|
|
Returns [nloc, nloc, count_type0, count_type1, ...] with length ntypes+2. |
|
""" |
|
nloc = len(atype) |
|
counts = np.bincount(atype, minlength=self._ntypes)[: self._ntypes] |
|
vec = np.empty(self._ntypes + 2, dtype=np.int64) |
|
vec[0] = nloc |
|
vec[1] = nloc |
|
vec[2:] = counts |
|
return vec |
- When an LMDB type map is remapped, the reader indexes
self._type_remap[frame["atype"]]; atype == -1 is remapped to the last real model type:
|
if "atype" in frame and isinstance(frame["atype"], np.ndarray): |
|
frame["atype"] = frame["atype"].reshape(-1).astype(np.int64) |
|
# Remap atom types from LMDB's type_map to model's type_map |
|
if self._type_remap is not None: |
|
frame["atype"] = self._type_remap[frame["atype"]].astype(np.int64) |
Simple external checks confirm both symptoms: np.bincount(np.array([0, -1])) raises ValueError, while remap[np.array([0, -1, 1])] maps -1 through the last row.
Impact
Datasets containing virtual atoms can crash LMDB reading, report fake observed elements, or silently convert virtual atoms into a real species after type-map remapping.
Suggested Fix
Filter atom types with 0 <= atype < ntypes for statistics and counts, and preserve negative atom types during LMDB type remapping. Add tests with atype=[0, -1, 1] for observed-type collection, natoms-vector computation, and LMDB remapping.
Found during a Codex global scan of
deepmodeling/deepmd-kitat commit73de44b1f94471b2e3bdb6b11f57b34d7bc791bb.Problem
Several dpmodel statistics and LMDB reader paths treat negative/virtual atom types as real type indices.
Evidence:
collect_observed_types()records all unique atom-type values and only filters the upper bound, so-1passes and becomestype_map[-1]:deepmd-kit/deepmd/dpmodel/utils/stat.py
Lines 52 to 59 in 73de44b
LmdbDataReader._compute_natoms_vec()callsnp.bincount(atype, ...), which raises whenatypecontains negative virtual atoms:deepmd-kit/deepmd/dpmodel/utils/lmdb_data.py
Lines 466 to 477 in 73de44b
self._type_remap[frame["atype"]];atype == -1is remapped to the last real model type:deepmd-kit/deepmd/dpmodel/utils/lmdb_data.py
Lines 578 to 582 in 73de44b
Simple external checks confirm both symptoms:
np.bincount(np.array([0, -1]))raisesValueError, whileremap[np.array([0, -1, 1])]maps-1through the last row.Impact
Datasets containing virtual atoms can crash LMDB reading, report fake observed elements, or silently convert virtual atoms into a real species after type-map remapping.
Suggested Fix
Filter atom types with
0 <= atype < ntypesfor statistics and counts, and preserve negative atom types during LMDB type remapping. Add tests withatype=[0, -1, 1]for observed-type collection, natoms-vector computation, and LMDB remapping.