Skip to content

[Bug] Deadlock in compute_standardization_stats due to Dask + PyTorch DataLoader #198

Description

@Sharkyii

Description

The compute_standardization_stats.py script hangs indefinitely when run with default settings on Linux. The script gets stuck at 0% progress during the data loading phase and never completes.

Steps to Reproduce

  1. Install neural-lam from main branch on Linux
  2. Download and extract the MEPS example dataset
  3. Place the datastore config in the correct location:
    cp data/meps.datastore.yaml
  4. Run the standardization stats computation:
    python -m neural_lam.datastore.npyfilesmeps.compute_standardization_stats \
        --datastore_config_path data/meps_example/meps.datastore.yaml

Expected Behavior

The script should compute mean and standard deviation statistics for the dataset and complete within a few minutes for the small example dataset.

Actual Behavior

The script hangs indefinitely at:

Computing mean and std.-dev. for parameters...
0%|                                                              | 0/1 [00:00<?, ?it/s]
  • No progress is made
  • CPU usage drops to near zero
  • Process must be killed manually (Ctrl+C)
  • Tested for over 1 hour with no completion

Root Cause

This is a fork-safety deadlock specific to Linux, caused by PyTorch DataLoader using fork() after Dask has initialized thread pools.

It is NOT caused by Dask spawning processes inside workers.

What Actually Happens:

  1. The main process initializes Dask arrays
  2. Dask creates internal thread pools
  3. PyTorch DataLoader with num_workers > 0 uses fork() on Linux (default multiprocessing start method)
  4. fork() copies the entire memory space and lock states, but does NOT copy running threads
  5. Worker processes inherit locks that appear "held" by threads that don't exist in the child
  6. When Dask tries to acquire those locks in the worker, it blocks forever waiting for non-existent threads
  7. Result: Workers freeze, progress bar stays at 0%

Why This Only Happens on Linux:

Platform Default Start Method Behavior
Linux fork 💀 Deadlock (inherits broken locks)
Windows spawn ✅ Works (fresh interpreter per worker)
macOS spawn ✅ Works (fresh interpreter per worker)

Environment

  • OS: Linux (Ubuntu)
  • Python: 3.11

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions