Skip to content

Let a job script size each worker's threads (0.9.0) - #14

Merged
davidackerman merged 1 commit into
mainfrom
worker-threads-0.9
Oct 24, 2026
Merged

davidackerman merged 1 commit into
mainfrom
worker-threads-0.9

Conversation

@davidackerman

Copy link
Copy Markdown
Member

cellmap-analyze asked for this, for its dask workers. A worker's tensorstore pools should follow the CPUs the job gives it, not stay at 1 because OMP_NUM_THREADS is 1 for numpy. The datasets are opened on the driver before the cluster starts, so the number has to be read in each worker.

  • WORLDARRAY_THREADS. thread_budget() reads it ahead of OMP_NUM_THREADS and the job's slots. A job script exports, for example, max(1, ncpus // processes). A handle on shared_context(...) pickles as threads=None, so each worker rebuilds it with its own value. Anything but a positive integer raises ValueError, because no other program sets this variable. A blank value counts as unset. It's read when a context is first made, not at import.
  • shared_context(file_io_floor=). The least the file I/O pool takes under the thread budget, 8 by default as in 0.8. 1 keeps file I/O equal to the budget, which is what cellmap-analyze wants until 8 has been measured on /nrs at scale. It's part of the context's key and its pickle recipe, and ignored with threads=N or threads=0, so it never makes a second context there. 0.6 to 0.8 pickles still load.

No default changes: with the variable unset and no file_io_floor, every context is what 0.8 made.

Tests: the variable's precedence and its bad values; the floor at 1, 0, 8 and 16, its key and recipe; and a handle pickled on the driver and sized in a spawned worker by that worker's WORLDARRAY_THREADS. 192 pass on tensorstore 0.1.78 and on 0.1.68, the minimum. The lost-wakeup stress test passes, and mkdocs build --strict is clean.

https://claude.ai/code/session_0141wgF8mkGbjGfBFKfKhp64

thread_budget() reads WORLDARRAY_THREADS ahead of OMP_NUM_THREADS and the job's slots, so a
job script can give each dask worker its share of the job's cores where OMP_NUM_THREADS stays
1 for numpy and LSB_DJOB_NUMPROC counts the whole job. A handle opened on the driver on the
shared context is sized in each worker by that worker's value. A value that is not a positive
integer raises ValueError.

shared_context(file_io_floor=) sets the least the file I/O pool takes under the budget
(default FILE_IO_FLOOR, 8; 1 keeps file I/O at the budget). It is part of the context's key
and its pickle recipe, and is ignored with threads=N or threads=0. No default changes.

Claude-Session: https://claude.ai/code/session_0141wgF8mkGbjGfBFKfKhp64
@davidackerman
davidackerman merged commit af9801d into main Oct 24, 2026
4 checks passed
@davidackerman
davidackerman deleted the worker-threads-0.9 branch October 24, 2026 02:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant