Skip to content

Let parallel_lottery_choices() assign the alternative with id 0 - #83

Merged
smmaurer merged 3 commits into
devfrom
fix/parallel-lottery-alt-zero
Sep 11, 2026
Merged

smmaurer merged 3 commits into
devfrom
fix/parallel-lottery-alt-zero

Conversation

@smmaurer

@smmaurer smmaurer commented Sep 11, 2026 •

Copy link
Copy Markdown
Member

Problem

parallel_lottery_choices() shares an array of already-chosen alternative ids between the worker processes. The array was allocated zero-filled, and workers treat every value in it as a taken alternative, so an alternative with id 0 always looked taken and was never assigned. With five alternatives numbered 0–4 and plenty of choosers, every run placed four choosers instead of five.

Found while writing the regression tests for #75. Code review of the first commit turned up three more silent-failure modes in the same function, fixed here as well.

Fix

  • The shared array starts out filled with a -1 sentinel, which the workers filter out when they read it, and uses 64-bit integers ('q') instead of 32-bit ('i') so large alternative ids are no longer silently truncated.
  • Alternative ids must be non-negative integers, which was already an implicit requirement. An unsupported index now raises a ValueError, and docstrings are updated. This also rules out an id colliding with the sentinel.
  • Omitting chooser_batch_size (the documented default) no longer crashes the worker on proc_num * None. The batch size defaults to the number of choosers.
  • A worker process that exits with an error now raises a RuntimeError in the caller instead of silently returning a partial result.
  • Improvements to tests.

Version 0.3.dev3, with a changelog entry.

The shared array that workers use to see which alternatives have already
been claimed was zero-filled, so an alternative with id 0 always looked
taken and was never assigned. The array now starts out filled with a -1
sentinel, which the workers filter out when they read it, and uses 64-bit
integers so large alternative ids are not truncated.

The existing parallel test asserted one fewer unique choice than there
are alternatives, which encoded the bug; it now expects every alternative
to be filled. The exhausted-alternatives test also uses ids 0 through 4
and asserts that all of them are chosen.
…face worker errors

- Alternative ids passed to parallel_lottery_choices() must be non-negative
  integers, since they travel between workers through a shared integer
  array; anything else now raises a ValueError before any worker starts.
  This also rules out an id colliding with the -1 sentinel, which would
  otherwise have let one alternative be assigned repeatedly.
- Omitting chooser_batch_size no longer crashes the single worker on
  `proc_num * None`; the batch size defaults to the number of choosers.
- A worker that exits with an error now raises a RuntimeError in the
  caller instead of silently returning a partial result.
- The existing parallel test makes the alternatives the binding constraint
  so it actually checks that every alternative gets filled.
The exhausted-alternatives tests used a without-replacement sampler with
sample size 3 to provoke a failure on an empty alternatives table, but it
also failed whenever a parallel worker saw one or two alternatives left,
which happens in a race between workers. They now use the default sampler
wrapped in an explicit check for an empty table.

The merged-choice-table test asserts that four uniform draws from three
alternatives do not all land on the same one, which is false about 1 run
in 81; it now fixes the random seed.
@smmaurer
smmaurer merged commit f1f8e49 into dev Sep 11, 2026
7 checks passed
@smmaurer
smmaurer deleted the fix/parallel-lottery-alt-zero branch September 11, 2026 20:01
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