schema_version: 1
mode: sanitizer
ticket: DAILY-CONSAN-GEMM
description: >
  Informational (non-gating) gfx950 ConSan run over a real, heavy f32 Type_SS
  hipBLASLt Tensile code object (generic public content extracted in CI from the
  synthetic gemm_shapes_unique.csv), driven via the source.consan_command path
  added in #347. This exercises the guardrail's behavior on large production code
  objects: whatever ConSan concludes, strict policy must reach a real verdict or
  fail closed, never a false pass. The observed outcome is whatever the run
  reports -- known rocjitsu limitations hit by this object are tracked in
  docs/sanitizers/consan-4112-overlapping-anchor-patches.md. Rendered on the
  dashboard's Workload survey tab (Tab 2) as an observed-only case; it does NOT
  gate the nightly.
sanitizer_plan:
  target: gfx950
  source:
    kind: kernel
    kernel:
      name: gemm_f32_ss
      code_object: fixtures/isa/consan_gemm_f32.hsaco
      code_object_index: 0
    consan_command: fixtures/bin/consan_gemm_load
    consan_log: true
  scope:
    kind: kernel
  selection:
    requirement: top_dispatch_count
    top_n: 1
  sanitizers:
    - consan
  policy:
    consan_policy: strict
    on_missing_backend: fail
    # Raised from the 300s cap of #364, which was chosen only because ROCm/rocm-systems#9964
    # made MOI inventory non-terminating: every ceiling produced the same
    # combined_hook_timeout, so a short one bought the identical row for a fraction of
    # the nightly. #9964 is fixed, so a ceiling that clears the run is now meaningful.
    #
    # Sizing history, because the trap here is subtle and worth recording. Three runs
    # on db0c47df measured 1283s, 1291s and 1416s, and an earlier revision of this
    # file chose 2000s as ~40% over the slowest. Every one of those runs ended in the
    # status=4112 transform rejection of ROCm/rocm-systems#10378 -- the object was
    # never actually instrumented, so they measured a run that gave up early rather
    # than the work this case represents. A budget measured against a failing run is
    # a lower bound, not an estimate.
    #
    # #10378 is now fixed (dc7c8e04) and published in bundle 4227d40fb5, which the
    # downloader selects. Re-measured against it, the same object transforms cleanly
    # (outcome=modified-valid, 75978 patches over 68894 access sites) and takes
    # 3696s and 4152s across two runs -- ~62-69 min -- before ending on strict
    # require-records at exit 86. 2000s would have guaranteed combined_hook_timeout:
    # the exact failure this recipe change exists to remove.
    #
    # 6000s is ~45% over the slower of the two. The headroom absorbs that spread
    # (both runs emitted an identical 508727 log lines, so the ~12% difference is
    # host contention, not workload variance) and the fact that the timing comes from
    # ROCm 7.0.2.2 while CI builds fixtures against 7.2.4 (#380), whose hipBLASLt may
    # extract a differently sized object.
    #
    # This case runs in the non-gating sanitizers-survey job, not on the gate job --
    # a ~69-min observed-only row does not belong in front of the Tab 1 verdict.
    #
    # Worth knowing before anyone tunes this again: ~76% of that 4152s is the hook
    # debug logging, not the instrumentation. The same object at RJ_CONSAN_LOG=1
    # completes in 991s with byte-identical results (75978 patches, 68894 sites);
    # the timed phases differ by ~3%. We cannot simply lower the level -- consan_log
    # maps to kLogDebug because the coverage cross-check needs the per-site records,
    # which no lower level emits -- so it is filed upstream as
    # ROCm/rocm-systems#10686. If that lands, this ceiling can drop to roughly a
    # quarter of its current value.
    timeout_seconds: 6000
  output:
    report: sanitizer_report.json
