jax-ml/jax · error · ValueError

Number of cores or threads must be at least 1, but got {self

Error message

Number of cores or threads must be at least 1, but got {self.num_cores_or_threads}.

What it means

The TPU interpret-mode parameters dataclass (mosaic interpret params) validates that num_cores_or_threads is at least 1; passing 0 or a negative value raises this ValueError at construction in __post_init__.

Source

Thrown at jax/_src/pallas/mosaic/interpret/params.py:94

      number of cores.
      This should be left at/set to `None` for interpreting GPU kernels. (For
      GPU kernels, the number of vector clocks is determined by the number of
      devices, `num_cores_or_threads`, and `num_tma_threads_per_device`.)
      Default: None.
    logging_mode: Logging mode for the kernel interpreter.
  """

  detect_races: bool = False
  out_of_bounds_reads: Literal["raise", "uninitialized"] = "raise"
  skip_floating_point_ops: bool = False
  uninitialized_memory: Literal["nan", "zero"] = "nan"
  num_cores_or_threads: int = 1
  vector_clock_size: int | None = None
  logging_mode: LoggingMode | None = None

  def __post_init__(self):
    if self.num_cores_or_threads < 1:
      raise ValueError(
          "Number of cores or threads must be at least 1, but got"
          f" {self.num_cores_or_threads}."
      )
    if self.vector_clock_size is not None and self.vector_clock_size < 1:
      # Further validation is done in `get_vector_clock_size` below.
      raise ValueError(
          "Vector clock size must be at least 1, but got"
          f" {self.vector_clock_size}."
      )

  def get_vector_clock_size(self, num_devices) -> int:
    """Returns the number of vector clocks to use for TPU interpret mode.`"""
    num_cores_or_threads = num_devices * self.num_cores_or_threads
    if self.vector_clock_size is not None:
      if num_cores_or_threads >= self.vector_clock_size:
        raise ValueError(
            f"Vector clock size ({self.vector_clock_size}) must be greater than"
            f" the total number of cores/threads ({num_cores_or_threads})."

View on GitHub (pinned to 1e1c6a8fc0)

Solutions

  1. Pass an explicit positive integer (default 1) for num_cores_or_threads
  2. Guard computed values: max(1, computed_cores)
  3. Validate user-facing config for core/thread settings before constructing params

Example fix

# before
params = interpret_params(num_cores_or_threads=len(tpu_chips))  # 0 if empty
# after
params = interpret_params(num_cores_or_threads=max(1, len(tpu_chips)))
Defensive patterns

Strategy: validation

Validate before calling

assert isinstance(num_cores_or_threads, int) and num_cores_or_threads >= 1, 'num_cores_or_threads must be >= 1'

Type guard

def is_valid_core_count(n) -> bool:
    return isinstance(n, int) and not isinstance(n, bool) and n >= 1

Try / catch

try:
    params = InterpretParams(num_cores_or_threads=n)
except ValueError as e:
    if 'at least 1' in str(e):
        params = InterpretParams(num_cores_or_threads=max(1, n))

Prevention

When it happens

Trigger: Constructing interpret-mode CompilerParams (e.g., via interpret options) with num_cores_or_threads=0 or negative — often derived from a computed core/thread count that can be zero.

Common situations: Setting simulated core count from len(devices) or a user config that is empty; multiplying/dividing to compute thread counts that underflow to 0; CLI-config override typos.

Related errors


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