Skip to content

[Code scan] Fix CALYPSO nested atom-choice validation to avoid infinite loops #356

Description

@njzjz

Found by Codex global repository scan of deepmodeling/dpgen2 at commit 2679611a3704f5c2646c8cb353e34177518db758.

The nested name_of_atoms validation is intended to reject impossible random choices before entering the selection loop:

if isinstance(name_of_atoms, list) and all(
[isinstance(i, list) for i in name_of_atoms]
):
overlap = set(name_of_atoms[0])
for temp in name_of_atoms[1:]:
overlap = overlap & set(temp)
if any(map(lambda s: (set(s) - overlap) == 0, name_of_atoms)):
raise ValueError(
f"Any sub-list should not equal with intersection, e.g. [[A,B,C], [B,C], [C]] is not allowed."
)
while True:
choice = []
for _atoms in name_of_atoms:
value = random.choice(_atoms)
logging.info(
f"randomly choose {value} from {_atoms}, already choose: {choice}"
)
if value in choice:
break
choice.append(value)
else:
break
self.name_of_atoms = choice

The condition compares a set to integer 0:

(set(s) - overlap) == 0

That is always false, so invalid inputs are not rejected. For example, [["A"], ["A"]] can never produce two unique choices. The loop repeatedly chooses duplicate A, breaks the inner loop, and then restarts forever.

Suggested fix: compare against an empty set or use a direct subset check, then add a test that the impossible nested atom-choice case raises ValueError instead of hanging.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status
    In Progress

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions