jax-ml/jax · error · ValueError

Semaphore {sem_id} occurs as both fixed-id and internal.

Error message

Semaphore {sem_id} occurs as both fixed-id and internal.

What it means

A semaphore ID was found in both the fixed-ID semaphore table and the internal semaphore table. Mosaic lets clients create semaphores with explicit IDs, but those must not collide with internally generated semaphore IDs.

Source

Thrown at jax/_src/pallas/mosaic/interpret/shared_memory.py:831

    device_id = global_core_id // self.num_cores_per_device
    local_core_id = global_core_id % self.num_cores_per_device
    return (device_id, local_core_id)

  def print(self, device_id: int):
    device_id = int(device_id)
    if device_id == 0:
      with self.lock:
        print(self.mem)

  def _unsafe_get_semaphore(self, sem_id: int) -> Semaphore:
    """Returns the semaphore with the given ID. `self.lock` must be held."""

    if sem_id in self.fixed_id_sem:
      if sem_id in self.sem:
        # TODO(nrink): For now we make it the responsibility of the client to
        # ensure that fixed-ID semaphores do not collide with internal
        # semaphore IDs.
        raise ValueError(
            f'Semaphore {sem_id} occurs as both fixed-id and internal.'
        )
      return self.fixed_id_sem[sem_id]
    else:
      return self.sem[sem_id]

  def set_failed(
      self,
      exception: Exception,
      device_id: int | None = None,
      local_core_id: int | None = None,
      top_level: bool = True,
  ):
    with self.lock:
      if self._failure is None:
        self._failure = exception
        if device_id is not None and local_core_id is not None:
          self._failed_thread = (device_id, local_core_id)

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Use distinct, high or namespaced fixed semaphore IDs unlikely to collide
  2. Let the library allocate semaphores internally instead of using fixed IDs when possible
  3. Reproduce and print both self.fixed_id_sem and self.sem key sets to find the colliding ID
Defensive patterns

Strategy: validation

Validate before calling

assert not (sem_id in mgr.fixed_id_sem and sem_id in mgr.sem), f'semaphore id {sem_id} collides'

Try / catch

try:
    sem = mgr._unsafe_get_semaphore(sem_id)
except ValueError as e:
    if 'both fixed-id and internal' in str(e):
        sem = mgr.fixed_id_sem[sem_id]  # or re-register with a fresh id
    else:
        raise

Prevention

When it happens

Trigger: Creating a fixed-ID semaphore whose ID equals one already assigned to an internal semaphore in the same SharedMemManager, then looking it up via _unsafe_get_semaphore (used by semaphore ops and clock incrementing).

Common situations: Choosing small manual semaphore IDs (0, 1, 2...) that clash with internal allocation order; running multiple kernels sharing one manager; refactors changing internal semaphore allocation order.

Related errors


AI-assisted analysis of jax-ml/jax@1e1c6a8fc0 (2026-08-27). Data as JSON: /api/errors/4f26b7ed3246f189. Report an issue: GitHub.