compileiq-debug

par nvidia

Utilisez quand quelque chose ne va pas : Search() bloque, toutes les évaluations retournent INVALID_SCORE, les scores ne s'améliorent pas, chaque configuration retourne le même nombre, erreurs ptxas…

npx skills add https://github.com/nvidia/compileiq --skill compileiq-debug

compileiq-debug

A symptom-indexed cheat sheet. Find the row that matches what the user is seeing, follow the first action, then dig into the matching detail section.

Symptom table

SymptomMost-likely causeFirst action
Search hangs on first eval; socket timeoutSearch space too large for default CIQ_SOCKET_TIMEOUT=20; OR release fetch slow/blocked; OR forkserver issueRaise CIQ_SOCKET_TIMEOUT=120; if still hangs, CIQ_SEARCH_SPACES_DIR=<local mirror>; if still hangs, CIQ_PROCESS_MODE=spawn. Do NOT symlink BLAS — that fix is obsolete
Every eval returns INVALID_SCOREReturn-type mismatch (tuple vs scalar) / correctness gate / task_timeout too tightSearch.sample(1) + call objective by hand; check num_objectives vs return shape; raise task_timeout
Every eval returns the same scoreACF not reaching the compiler — framework cache is hiding itApply Debug-pack O0 ACF by hand; if the score doesn't regress, fix cache-bust (TRITON_ALWAYS_COMPILE=1, HELION_SKIP_CACHE=1, fresh TRITON_CACHE_DIR, drop FlashInfer cubin packages)
TypeError: fromhex() … not dictLegacy bytes.fromhex(config_blob) in objectiveReplace with save_compiler_config(acf_path, config) — see compileiq-author-objective
"not in expected format"Objective returned wrong shapenum_objectives must equal len(return_tuple); scalar return only when num_objectives=1
Convergence stalled (best score flat)Pool too small for space; mutate_rate too low; or kernel near-optimalRaise pool_size; raise mutate_rate; sample diversity with Search.sample(20)
Increasing invalid rate over generationsMutation arm spreading; compiler version drift mid-runCIQ_KEEP_CACHE=1, re-run, inspect failing configs offline
CV% > 10% on validationUnlocked clocks / thermal throttling / GPU contentionLock GPU + memory clocks; pin CUDA_VISIBLE_DEVICES; watch nvidia-smi dmon for thermals
Need to know why a winning ACF helpsProfile with NCUSee NCU section below

Details

Socket timeout / hang on first eval

Not BLAS. Do not send users to symlink libblas.so.

Current shipped binaries link only libm/libc/libstdc++/libgcc_s and do not require BLAS/LAPACK.

Real causes today, in order of frequency:

  1. CIQ_SOCKET_TIMEOUT too low. Default is 20 seconds, which is fine for small search spaces but fails on big ones. Raise to 120 first; raise to 300+ for very large spaces.
  2. Release-backed search-space fetch is slow or blocked. First call to PtxasSearchSpace().retrieve() downloads from github.com. On a corporate firewall this can stall. Pre-stage the mirror:
    gh release download search-spaces-latest -R NVIDIA/CompileIQ -D /shared/mirror
    export CIQ_SEARCH_SPACES_DIR=/shared/mirror
    
  3. forkserver is unsupported on the host. Set CIQ_PROCESS_MODE=spawn. IsoMultiProcessWorker already uses fork by default.

Every eval returns INVALID_SCORE

Sanity-check the shape before assuming the worst:

sample = tuner.sample(1)[0]
score = objective(sample)
print(type(score), score)

Common shape mismatches:

  • num_objectives=1 but objective returns a tuple (latency,). Drop the trailing comma.
  • num_objectives=2 but objective returns a scalar.
  • Correctness gate is rejecting everything because the reference call itself is wrong.
  • task_timeout is shorter than a clean compile takes; raise it.

Every eval returns the SAME score

Almost always a framework cache serving a stale binary. Run the O0/O3 canary from the Debug pack to confirm — see compileiq-booster-pack for the exact test. If O0 doesn't regress vs baseline, the ACF is not reaching PTXAS. Fix:

FrameworkCache-bust
TritonTRITON_ALWAYS_COMPILE=1 + unique TRITON_CACHE_DIR per eval
HelionHELION_SKIP_CACHE=1
FlashInferConfirm flashinfer_cubin and flashinfer_jit_cache packages are absent (docs/flashinfer_booster.md:56-64)
Raw nvccClean the build dir between candidates

TypeError around fromhex

Legacy pattern from the pre-2026 skill set:

# OLD — DO NOT USE
def objective(config_blob):
    with open(tmp_path, "wb") as f:
        f.write(bytes.fromhex(config_blob))
    ...

Replace with:

from compileiq.utils.helpers import save_compiler_config

def objective(config: str):
    save_compiler_config(tmp_path, config)
    ...

save_compiler_config does the bytes.fromhex internally. See compileiq-author-objective for the full pattern.

"Not in expected format"

The objective returned a shape CompileIQ's core doesn't expect. Rules:

  • num_objectives=1: objective must return a single scalar (int | float). Not a 1-tuple, not a list.
  • num_objectives>=2: objective must return a tuple or list of that length.
result = objective(sample)
assert (
    (search_config.num_objectives == 1 and isinstance(result, (int, float)))
    or (search_config.num_objectives  > 1 and len(result) == search_config.num_objectives)
), f"shape mismatch: {result!r} vs num_objectives={search_config.num_objectives}"

Convergence stalled

Three causes, in order:

  1. Pool too small for the space. pool_size = max(2 * num_objectives + 1, 32) is the auto-derived floor — for spaces with >1k design points, raise to 64-128.
  2. Mutation rate too low. Default mutate_rate=0.25. Raise to 0.3-0.5 if the search is converging on the first generation.
  3. The kernel is genuinely near-optimal. Verify by running Search.sample(20) and timing each sample by hand — if the spread is <5%, the search space is shallow.

Increasing invalid rate

Probably a mutation arm spreading a structurally-bad config across the population. Re-run with CIQ_KEEP_CACHE=1 so the failing configs are preserved at ~/.cache/compileiq/, then replay them by hand to identify the common factor.

High CV% on validation

If cv = std/mean > 10%, validation can't tell the signal from the noise.

Fixes, in order:

  1. Lock GPU and memory clocks (see compileiq-run-search for the nvidia-smi --lock-*-clocks snippet).
  2. Pin CUDA_VISIBLE_DEVICES=<gpu> so the validation has the GPU to itself.
  3. Watch nvidia-smi dmon -i <gpu> -s pucvm for thermal throttling events.
  4. Raise warmup count (50 → 100) and trial count (100 → 200).
  5. Switch from cudaEvent to NVBench (entropy-based stopping criterion, cold-cache between samples).

CIQ_KEEP_CACHE for post-mortem

When a search misbehaves, re-run with:

export CIQ_KEEP_CACHE=1

The cache at ~/.cache/compileiq/ is preserved after the run. You can:

  • Inspect each generation's serialized configs.
  • Replay a specific config without paying for a whole new search.
  • Compare two runs by diffing their cache directories.

Diagnose from the dump_results CSV

Quick pandas snippet:

import pandas as pd
df = pd.read_csv("results.csv")
df["score_numeric"] = pd.to_numeric(df["score_1"], errors="coerce")

gen_summary = df.groupby("generation").agg(
    n=("score_numeric", "size"),
    invalid=("score_numeric", lambda s: s.isna().sum() + (s > 1e10).sum()),
    best=("score_numeric", "min"),
)
print(gen_summary)

If invalid doesn't decrease across generations, your search is structurally broken — try the O0/O3 canary in compileiq-author-objective.

For an automated version: python scripts/diagnose_csv.py results.csv.

NCU section (replaces old /compileiq-profile)

Profile only after a validated ACF candidate exists. Don't profile every config — it's slow.

Two-shot pattern

# Baseline (no ACF)
ncu --set full -o baseline -f --kernel-name my_kernel python bench.py

# ACF-applied — match the injection your objective uses
# Raw PTXAS:
ncu --set full -o opt -f --kernel-name my_kernel \
    bash -c 'PTXAS_OPTIONS="--apply-controls=best.acf" python bench.py'
# NVCC build:
nvcc -Xptxas --apply-controls=best.acf bench.cu -o bench && \
    ncu --set full -o opt -f --kernel-name my_kernel ./bench

# Diff
ncu --import baseline.ncu-rep --import opt.ncu-rep --csv --page raw > diff.csv

Five metrics that explain most CompileIQ wins

MetricWhat it means
sm__throughput.avg.pct_of_peak_sustained_elapsedCompute throughput
gpu__compute_memory_throughput.avg.pct_of_peak_sustained_elapsedMemory throughput
sm__warps_active.avg.pct_of_peak_sustained_activeAchieved occupancy
launch__registers_per_threadRegister pressure
l2__throughput.avg.pct_of_peak_sustained_elapsedL2 pressure

If the ACF moved any of these meaningfully, that's the mechanism. If none of them moved but the win is real, look at lower-level metrics (warp stalls, issue slot utilization) — those are harder to interpret but often the answer.

Register-spill check (no NCU needed)

ptxas -v -arch=sm_100 --apply-controls best.acf kernel.ptx 2>&1 \
    | grep -E "registers|spill|stack"

Reports Used N registers, X bytes stack frame, Y bytes spill stores, Z bytes spill loads. If Y + Z goes up vs baseline, the ACF traded register pressure for memory traffic — sometimes a real win, sometimes not. Investigate before shipping.

Self-test

python scripts/diagnose_csv.py --self-test

Synthesizes a small results.csv covering each pathology (clean convergence, rising invalid rate, stalled best-score) and asserts the heuristic classifications match.

Explicitly dropped from this skill (vs old /compileiq-debug + /compileiq-profile)

  • BLAS symlink section — obsolete; current binaries don't link BLAS (verified by ldd). Carrying it forward sends users on a wild goose chase.
  • Verbose COMMON_PTXAS_ERRORS dict mapping individual ptxas error strings to fixes — users get INVALID_SCORE instead, no need to recognize specific messages.
  • Duplicate CUDA 13.3+ check — lives in compileiq-bootstrap.
  • validate_objective_function introspection helper — replaced by Search.sample(1) + the Debug-pack O0/O3 canary.

Next

  • For the canary itself: compileiq-booster-pack or compileiq-author-objective.
  • For environment issues: compileiq-bootstrap.
  • After fixing: re-run compileiq-run-search.

Plus de skills de nvidia

create-github-pr
nvidia
Créer des pull requests GitHub en utilisant l'interface en ligne de commande gh. Utiliser lorsque l'utilisateur souhaite créer une nouvelle PR, soumettre du code pour révision, ou ouvrir une pull request. Mots-clés de déclenchement -…
nemoclaw-maintainer-cross-issue-sweep
nvidia
Analyse les autres problèmes ouverts pour trouver ceux qu’une PR donnée pourrait également corriger ou casser accidentellement. Génère des opportunités de correctifs adjacents et des risques de contradiction avec fichier:ligne…
fhir-basics
nvidia
Apprend aux agents comment fonctionnent les API FHIR R4, quelles ressources sont disponibles, comment les interroger avec des paramètres de recherche, et comment analyser correctement tous les formats de réponse…
compileiq-validate-result
nvidia
Utiliser APRÈS qu'une recherche soit terminée et AVANT de réclamer un accélérateur ou d'expédier un ACF. Charge le CSV dump_results, extrait les K meilleurs candidats (mono-objectif)…
changelog-audit
nvidia
Auditer le CHANGELOG.md de Warp avant une publication : récupérer les entrées perdues, trier par impact utilisateur, affiner le langage des entrées, ajuster les retours à la ligne et (en mode branche de publication) mettre à jour la comparaison…
maintain-dynamic-plugins
nvidia
Maintenir les chargeurs de plugins dynamiques NeMo Relay, les manifestes, les SDK natifs Rust, le protocole worker gRPC, le SDK worker Python, la documentation, les tests et la couverture du workflow de publication
dgx-diagnose
nvidia
Diagnostiquer les problèmes courants du DGX Station GB300 — plantages CUDA, ciblage incorrect du GPU, bugs de conteneur vLLM/SGLang, problèmes d'état MIG, erreurs NVLink/Fabric Manager,…
case-summary
nvidia
Préparer un résumé clinique complet d’un patient à partir des endpoints FHIR. Utiliser lorsqu’on demande de résumer un patient, compiler un cas ou préparer une réunion de comité de tumeurs.