Multithreaded MolStandardize *InPlace functions hang with numThreads=0 and race with negative numThreads
Maintainers usually reply within 3 days
Assessment
- Difficulty
- 1/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 85/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- backend, performance
Research direction
The bug is in standardizeMultipleMolsInPlace() in Code/GraphMol/MolStandardize/MolStandardize.cpp, where the worker loop strides by the raw numThreads argument instead of the resolved numThreadsToUse. Read how getNumThreadsToUse is called there, then change the stride to the resolved count. Done when CleanupInPlace(mols, 0) returns and each molecule is processed exactly once, which a regression test in the MolStandardize tests should check.
Written by the indexing model from the issue text.
Description
Describe the bug
The multi-molecule versions of the MolStandardize *InPlace() functions (CleanupInPlace, NormalizeInPlace, TautomerParentInPlace, ...) hang forever when called with numThreads=0 (which elsewhere in the RDKit means "use all available threads"). With negative values (e.g. -1, "all but one") several threads end up processing the same molecules concurrently while most molecules are never processed.
The cause is in standardizeMultipleMolsInPlace() in Code/GraphMol/MolStandardize/MolStandardize.cpp: the number of threads is resolved with getNumThreadsToUse(numThreads), but each worker advances by the raw argument:
for (auto mi = tidx; mi < mols.size(); mi += numThreads) {
With numThreads == 0 the stride is 0; with negative values the unsigned arithmetic wraps around.
To Reproduce
from rdkit import Chem
from rdkit.Chem.MolStandardize import rdMolStandardize
mols = [Chem.MolFromSmiles(smi) for smi in ('CCO', 'c1ccccc1', 'CC(=O)[O-].[Na+]', 'C[N+](=O)[O-]')]
rdMolStandardize.CleanupInPlace(mols, 0) # never returns (on a machine with >1 hardware thread)
Expected behavior
numThreads=0 should use all available threads and negative values all-but-N, as with other RDKit functions taking numThreads, and each molecule should be processed exactly once.
Configuration (please complete the following information):
- RDKit version: current master (fece8caa8, 2026.09.1)
- OS: Ubuntu 22.04 (WSL2)
- Python version (if relevant): 3.10
- Are you using conda? Yes, for the build environment
- If you are not using conda: how did you install the RDKit? Built from source
Additional context
The fix is a one-word change (stride by the resolved thread count, numThreadsToUse); I'm happy to submit a PR with a regression test.
- Dominant language
- HTML
- Stars
- 3.6k
- Forks
- 1.1k
- Avg merge
- 4d 7h
- Merged PRs (30d)
- 24
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from rdkit/rdkit
-
8-membered-ring atrop stereo lost in 2026.09.1Possibly taken @pechersky claimed this 4 days ago. Openbug
Difficulty 2/5 Half a day Newbie friendliness 86/100
rdkit/rdkit#9681 · 1 comment ·
Maintainers usually reply within 3 days
-
Make Catch2 optional when `RDK_BUILD_CPP_TESTS=OFF`Possibly taken @pechersky claimed this 6 days ago. Openbug
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 3 days
-
CMAKE_COMPILER_IS_CLANG is determined using the compiler executable name which is incorrectPossibly taken @barlowa124 claimed this 6 days ago. Openbug infrastructure
Difficulty 2/5 1-3 hours Newbie friendliness 75/100
rdkit/rdkit#9662 · 5 comments ·
Maintainers usually reply within 3 days
-
Clarify mol_from_smiles vs qmol_from_smarts for substruct_count queries in Postgresql cartridgeOpenenhancement
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
Maintainers usually reply within 3 days
-
enhancement
Difficulty 5/5 Over a week Newbie friendliness 8/100
Maintainers usually reply within 3 days
Similar issues
-
area:deploy task
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
wilanis/wilanis-js#1017 ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
eclipse-opensovd/classic-diagnostic-adapter#616 ·
Maintainers usually reply within 2 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
Maintainers usually reply within 1 day
-
nixos/hyprland: wrapper source is a bash script and fails the ensure-wrapper-integrity ELF checkOpen0.kind: bug 6.topic: nixos
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
vllm-project/vllm#61131 ·
Maintainers usually reply within 1 day