{"record":{"id":"2b22b1c8bc96f048","repo":"jax-ml/jax","slug":"unsupported-trace-scope-trace-scope","errorCode":null,"errorMessage":"Unsupported trace scope: {trace_scope}","messagePattern":"Unsupported trace scope: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"jax/experimental/mosaic/gpu/profiler.py","lineNumber":203,"sourceCode":"        event costs 2 entries, and 3 entries are reserved for a header.\n      dump_path: Where to write the trace.\n      trace_scope: Whether one trace covers a warp or a warpgroup.\n      bounds_check: If True, events past the buffer capacity are dropped (the\n        trace is truncated) at the cost of a slightly higher per-event overhead.\n        If False (default), overflowing the buffer corrupts neighbouring SMEM,\n        which usually crashes the kernel.\n    \"\"\"\n    self.entries_per_warpgroup = entries_per_warpgroup\n    self.interned_names: dict[str, int] = {}\n    self.bounds_check = bounds_check\n    if dump_path == \"sponge\":\n      self.dump_path = os.getenv(\n          \"TEST_UNDECLARED_OUTPUTS_DIR\", tempfile.gettempdir()\n      )\n    else:\n      self.dump_path = dump_path\n    if trace_scope not in (ThreadSubset.WARP, ThreadSubset.WARPGROUP):\n      raise ValueError(f\"Unsupported trace scope: {trace_scope}\")\n    self.trace_scope = trace_scope\n\n  def _num_traces(\n      self, grid: tuple[int, ...], block: tuple[int, ...]\n  ) -> int:\n    if self.trace_scope == ThreadSubset.WARP:\n      scope_size = WARP_SIZE\n    elif self.trace_scope == ThreadSubset.WARPGROUP:\n      scope_size = WARPGROUP_SIZE\n    else:\n      raise NotImplementedError(f\"Scope {self.trace_scope} not supported\")\n\n    if math.prod(block) % scope_size:\n      raise ValueError(f\"Block size is not a multiple of {scope_size}\")\n    return math.prod(grid) * math.prod(block) // scope_size\n\n  def mlir_buffer_type(\n      self, grid: tuple[int, ...], block: tuple[int, ...]","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/jax-ml/jax/blob/1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb/jax/experimental/mosaic/gpu/profiler.py#L185-L221","documentation":"ProfilerSpec.__init__ validates that trace_scope is one of ThreadSubset.WARP or ThreadSubset.WARPGROUP, since trace buffer layout depends on the scope size (32 vs 128 threads). Any other value (including other ThreadSubset enum members like BLOCK) is rejected.","triggerScenarios":"Constructing ProfilerSpec(trace_scope=ThreadSubset.BLOCK) or passing an arbitrary integer/string as trace_scope.","commonSituations":"Assuming the profiler works at block granularity because ThreadSubset has other members; upgrading code written against a version that silently accepted other scopes.","solutions":["Use ThreadSubset.WARP or ThreadSubset.WARPGROUP explicitly","If you need block-level tracing, profile per warp and aggregate in dump()"],"exampleFix":"# before\nspec = ProfilerSpec(trace_scope=ThreadSubset.BLOCK)\n\n# after\nspec = ProfilerSpec(trace_scope=ThreadSubset.WARPGROUP)","handlingStrategy":"type-guard","validationCode":"from jax.experimental.mosaic.gpu import profiler as P\nassert P.ProfilerSpec.trace_scope.__class__  # inspect\nvalid = {P.ThreadSubset.WARP, P.ThreadSubset.WARPGROUP}\nif trace_scope not in valid:\n    raise ValueError(f'trace_scope must be one of {valid}')","typeGuard":"def is_supported_scope(s) -> bool:\n    return s in (ThreadSubset.WARP, ThreadSubset.WARPGROUP)","tryCatchPattern":null,"preventionTips":["Only use WARP/WARPGROUP scopes","Centralize ProfilerSpec construction so scope is validated once"],"tags":["profiling","mosaic","gpu","argument-validation"],"backgroundTag":"unsupported-enum-value","analyzedSha":"1e1c6a8fc06dfcd1247076ec5cae4640cea5d7bb","analyzedAt":"2026-08-27T09:53:25.647Z","schemaVersion":2},"datasetVersion":"2026-08-27T13:17:12.746Z"}