Skip to content

[Code scan] Honor documented fparam/aparam shorthand in dpmodel DeepEval #5662

Description

@njzjz

This issue comes from a Codex global scan of deepmodeling/deepmd-kit at commit 73de44b1f94471b2e3bdb6b11f57b34d7bc791bb.

Problem

The dpmodel DeepEval backend documents broadcastable fparam and aparam input forms, but _eval_model() reshapes them directly to full multi-frame shapes.

The backend docstring says a single dim_fparam vector applies to all frames, and that aparam may be provided as natoms x dim_aparam or dim_aparam shorthand:

fparam
The frame parameter.
The array can be of size :
- nframes x dim_fparam.
- dim_fparam. Then all frames are assumed to be provided with the same fparam.
aparam
The atomic parameter
The array can be of size :
- nframes x natoms x dim_aparam.
- natoms x dim_aparam. Then all frames are assumed to be provided with the same aparam.
- dim_aparam. Then all frames and atoms are provided with the same aparam.

_eval_model() instead reshapes fparam directly to (nframes, dim_fparam):

if fparam is not None:
fparam_input = fparam.reshape(nframes, self.get_dim_fparam())
else:
fparam_input = None

It also reshapes aparam directly to (nframes, natoms, dim_aparam):

if aparam is not None:
aparam_input = aparam.reshape(nframes, natoms, self.get_dim_aparam())
else:
aparam_input = None

For nframes > 1, the documented shorthand arrays have too few elements for those reshapes and are rejected instead of being tiled.

The higher-level inference wrapper already implements this tiling contract:

if fparam is not None:
fdim = self.get_dim_fparam()
if fparam.size == nframes * fdim:
fparam = np.reshape(fparam, [nframes, fdim])
elif fparam.size == fdim:
fparam = np.tile(fparam.reshape([-1]), [nframes, 1])
else:
raise RuntimeError(
f"got wrong size of frame param, should be either {nframes} x {fdim} or {fdim}"
)
if aparam is not None:
fdim = self.get_dim_aparam()
if aparam.size == nframes * natoms * fdim:
aparam = np.reshape(aparam, [nframes, natoms * fdim])
elif aparam.size == natoms * fdim:
aparam = np.tile(aparam.reshape([-1]), [nframes, 1])
elif aparam.size == fdim:
aparam = np.tile(aparam.reshape([-1]), [nframes, natoms])
else:
raise RuntimeError(
f"got wrong size of frame param, should be either {nframes} x {natoms} x {fdim} or {natoms} x {fdim} or {fdim}"
)

Impact

Users calling the dpmodel backend directly can pass parameter arrays that the API explicitly documents as valid, only to get reshape failures for multi-frame inference.

Suggested fix

Normalize fparam and aparam in the dpmodel backend using the same size checks and tiling behavior as the higher-level inference wrapper. Add regressions for multi-frame dpmodel inference with fparam.shape == (dim_fparam,), aparam.shape == (natoms, dim_aparam), and aparam.shape == (dim_aparam,).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    In Progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions