Skip to content

Commit 1d751b3

Browse files
authored
Add files via upload
1 parent 9ec10b2 commit 1d751b3

1 file changed

Lines changed: 24 additions & 8 deletions

File tree

multioptpy/Wrapper/mapper.py

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -606,7 +606,12 @@ def _kabsch_rmsd(pa: np.ndarray, pb: np.ndarray) -> float:
606606
return float("inf")
607607

608608
E0 = np.sum(pa ** 2) + np.sum(pb ** 2)
609-
rmsd_sq = max(0.0, E0 - 2.0 * (S[0] + S[1] + d * S[2])) / len(pa)
609+
# After the d < 0 guard we know d > 0 (proper rotation), so the
610+
# sign correction is +1 and all three singular values contribute.
611+
# Using `d * S[2]` (where d is a float ≈ 1.0 ± 1e-15) is technically
612+
# incorrect and introduces unnecessary floating-point bias; np.sum(S)
613+
# is exact.
614+
rmsd_sq = max(0.0, E0 - 2.0 * np.sum(S)) / len(pa)
610615
return float(np.sqrt(rmsd_sq))
611616

612617

@@ -2414,12 +2419,6 @@ def _make_executor() -> ProcessPoolExecutor:
24142419
self._finalize_iteration(run_dir, task, "FAILED", [], priority_log)
24152420
continue
24162421

2417-
# Persist the exploration record only after confirming success
2418-
self.explored_log.record(task.node_id, atom_i, atom_j, gamma_sign)
2419-
# Call release() after record() so that is_submitted() returns
2420-
# True throughout the entire [pop() → record() → release()] window
2421-
self.queue.release((task.node_id, tuple(task.afir_params)))
2422-
24232422
logger.info(
24242423
"Iter %06d: _run_autots returned %d profile director%s.",
24252424
self._iteration, len(profile_dirs),
@@ -2428,6 +2427,17 @@ def _make_executor() -> ProcessPoolExecutor:
24282427
for pdir in profile_dirs:
24292428
self._process_profile(pdir, run_dir)
24302429

2430+
# Persist the exploration record only after confirming success
2431+
# (profile processing complete). Placing record() before
2432+
# _process_profile() — the previous order — would mark the task
2433+
# as explored even when _process_profile raises (e.g. disk full
2434+
# in _persist_node_xyz), making it non-retryable on resume.
2435+
# Must mirror the parallel path in _process_single_result.
2436+
self.explored_log.record(task.node_id, atom_i, atom_j, gamma_sign)
2437+
# Call release() after record() so that is_submitted() returns
2438+
# True throughout the entire [pop() → record() → release()] window
2439+
self.queue.release((task.node_id, tuple(task.afir_params)))
2440+
24312441
# Notify queue of updated graph (required by RCMCQueue)
24322442
if hasattr(self.queue, "set_graph"):
24332443
self.queue.set_graph(self.graph)
@@ -2533,10 +2543,11 @@ def _new_executor() -> ProcessPoolExecutor:
25332543
# ── Inner helpers ──────────────────────────────────────────────────
25342544

25352545
_stop_logged = False
2546+
_max_iter_logged = False
25362547

25372548
def _should_stop() -> bool:
25382549
"""True when the outer loop should not submit more tasks."""
2539-
nonlocal _stop_logged
2550+
nonlocal _stop_logged, _max_iter_logged
25402551
if os.path.isfile(os.path.join(self.output_dir, "stop.txt")):
25412552
if not _stop_logged:
25422553
logger.info(
@@ -2547,6 +2558,11 @@ def _should_stop() -> bool:
25472558
_stop_logged = True
25482559
return True
25492560
if self.max_iterations > 0 and self._iteration >= self.max_iterations:
2561+
if not _max_iter_logged:
2562+
logger.info(
2563+
"Reached max_iterations (%d). Stopping.", self.max_iterations
2564+
)
2565+
_max_iter_logged = True
25502566
return True
25512567
return False
25522568

0 commit comments

Comments
 (0)