Was macht Optimierungs-Handoff (kernel-optimize)?
Wenn das Ziel darin besteht, einen Kernel an das Hardware-Limit zu bringen (nicht nur kurz die Performance zu prüfen), ist diese Datei die Schnittstelle zwischen Primus-Turbo und der autonomen Optimierungsschleife in ../../kernel-optimize/SKILL.md. Sie liefert die erforderlichen Voraussetzungsinformationen, die jene Schleife benötigt. Lies zuerst den Hub ../SKILL.md.
Ablauf
- Umgebung überprüfen –
pip show primus_turbo; bei Bedarf bearbeitbar neu installieren (HubSKILL.md→ Build). kernel-optimize/SKILL.md„Voraussetzungsinformationen“ lesen – um zu erfahren, was die Schleife benötigt.- Voraussetzungen sammeln für den Ziel-Op (Tabellen unten + Code-Map / Befehle im Hub
SKILL.md). - Übergabe an
kernel-optimize/SKILL.md; dort läuft DEFINE_TARGET → PREPARE_ENVIRONMENT → BASELINE → (ANALYZE → OPTIMIZE → VALIDATE)* → REPORT. - Abnahme – zurück im Projekt: die vollständige Suite
pytest tests/pytorch/ -vausführen, den Report prüfen, einen sauberen Diff/Commit bestätigen.
Bevor die Schleife startet, lies ../../../rules/iteration_rules.mdc: eine Hypothese pro Runde, Korrektheits-Gate vor Performance, Akzeptanz-/Rollback-Abstammung, und jeder akzeptierte Gewinn muss auf einen echten Trainingsschritt übertragen werden (keine id(...)-basierten Aktivierungs-/Gradienten-Caches, keine GroupGemm-Abkürzungen nur mit Gleichverteilung).
Voraussetzungsinformationen (pro Op)
| Anforderung | Woher beziehen |
|---|---|
| Kernel-Quellcodedatei-Pfad | Hub SKILL.md → Code-Map |
| Fokussierter Testbefehl | Hub SKILL.md → Test & Bench; z. B. pytest tests/pytorch/ops/test_gemm_fp8.py -v -k "blockweise und TRITON" |
| Fokussierter Benchmarkbefehl | ../verify-performance/SKILL.md; z. B. PRIMUS_TURBO_GEMM_BACKEND=TRITON python benchmark/ops/training/bench_gemm_turbo.py --dtype fp8 --granularity blockweise |
| Benchmark-Ausgabeformat / Metriken | ../verify-performance/SKILL.md (Vorwärts/Rückwärts TFLOPS, Check-Gate) |
| Schnellvalidierungs-Harness | „Schnellvalidierung“ unten |
| Bewertungsregeln | „Optimierungsbewertung“ unten |
execution_mode + Neubau | „Optimierungsumgebung“ unten |
Optimierungsumgebung
| Backend / Sprache | Empfohlener execution_mode | Neubau nach Änderung |
|---|---|---|
| Triton (Python) | repo-mode | keiner (editierbare Installation) |
| HIP / CK (C++), kleine/Parameter-Änderungen | repo-mode | GPU_ARCHS=<arch> pip install --no-build-isolation -e . -v |
| HIP / CK (C++), neuer Kernel / umfangreiches Trial-and-Error | workspace-mode | gemäß dem minimalen Stack in kernel-optimize/SKILL.md |
Optimierungsbewertung
Die Check-Spalte ist ein hartes Gate – jedes FAIL/ERROR-Shape lehnt den Kandidaten ab.
| Kampagnentyp | primary_metric (Aggregat = geometrischer Mittelwert über PASS-Shapes) |
|---|---|
| Rechenintensiv, nur Vorwärts | Vorwärts TFLOPS |
| Rechenintensiv, Vorwärts + Rückwärts (Training) | Kombinierter Schritt TFLOPS (Vorwärts/Rückwärts als Diagnostik behalten) |
| Speichergebunden (elementweise, quant) | Vorwärts GB/s / Rückwärts GB/s |
Die Ableitung des kombinierten Schritts (bevorzugt für fwd+bwd GEMM-ähnliche Ops) befindet sich in ../verify-performance/SKILL.md. Bestätige primary_metric mit dem Benutzer bei DEFINE_TARGET.
Schnellvalidierung
Zwei Werkzeuge, getrennte Rollen – vergleiche keine absoluten Zahlen zwischen ihnen (sie verwenden unterschiedliche Timing-Engines):
quick_test_bench.py(dieser Ordner, in das Kampagnenverzeichnis kopiert) ist die maßgebliche Quelle für die rundenweise Shape-Regressionsbewertung. BASELINE (Runde 1) und jede VALIDATE-Runde führen DIESES Skript aus und vergleichen seine--summary-csv-Ausgabe. Es verwendet eine handgebautetime.perf_counter-Schleife.- das vollständige
bench_<op>_turbo.py(siehe../verify-performance/SKILL.md,torch.utils.benchmark.Timer) wird nur verwendet, um (i)representative_shapesaus der vollständigen Shape-Menge auszuwählen und (ii) die endgültige Abnahme nach der Kampagne durchzuführen.
Beide Validierungsebenen laufen über quick_test_bench.py und unterscheiden sich nur in SHAPES:
- vollständige Validierung (BASELINE + endgültige Abnahme) →
SHAPES= alletarget_shapes. - Schnellvalidierung (jede VALIDATE-Runde) →
SHAPES= die 3–5representative_shapes-Teilmenge.
representative_shapes: nur Check=PASS-Shapes aus dem BASELINE-Durchlauf, die kleine (Start-Overhead) + große (Berechnung/Speicher) Skalen abdecken, bevorzugt Shapes mit hoher Varianz. Notiere sie in manifest.yaml: representative_shapes.
Harness: die Vorlage quick_test_bench.py ist die kanonische Referenz. Während PREPARE_ENVIRONMENT kopiere sie in <campaign_dir>/quick_test_bench.py mit SHAPES leer und <target_backend> gesetzt; fülle SHAPES mit allen target_shapes für BASELINE, verkleinere sie dann auf representative_shapes für die VALIDATE-Runden. Passe den Op/die Konfiguration für dein Ziel an; behalte den --summary-csv-Writer und das Spaltenschema bei (siehe den Schema-Gültigkeitsbereich unten für Nicht-GEMM-Ops).
Messkonsistenz-Vertrag: BASELINE (Runde 1) und jede VALIDATE lesen dieselbe maßgebliche CSV über --summary-csv, die rundenübergreifend identisch geparst wird, und zwar durch denselben CSV-Reader – den optionalen mcp__turbo__parse_bench_csv MCP-Helfer, falls konfiguriert, andernfalls einen direkten csv.DictReader, der auf die untenstehenden Spalten schlüsselt. Der spezifische Reader spielt keine Rolle; das Einfrieren des Schemas jedoch schon. Das Schema MUSS diese Spalten wörtlich übereinstimmen (jede Abweichung deaktiviert das per-Shape-Regressionsgate stillschweigend):
label,B,M,N,K,Check,Forward TFLOPS,Forward TFLOPS_stddev,Backward TFLOPS,Backward TFLOPS_stddev,Forward Time (ms),Backward Time (ms),out_snr,da_snr,db_snr
Check verwendet PASS/FAIL; *_stddev sind absolute Standardabweichungen in der Einheit der Metrik. Notiere den Aufruf in manifest.yaml als quick_command: "python <campaign_dir>/quick_test_bench.py"; BASELINE und jede VALIDATE hängen --summary-csv <runden_dir>/artifacts/benchmark.csv an.
Schema-Gültigkeitsbereich: die obigen Spalten sind GEMM-klassenspezifisch (M,N,K-Dimensionen, Forward/Backward TFLOPS, out_snr/da_snr/db_snr). Für einen Nicht-GEMM-Op behalte label, Check und die *_stddev-Konvention, ersetze aber die GEMM-spezifischen Spalten durch diejenigen, die deine primary_metric benötigt – z. B. verwendet ein speichergebundener Op (gemäß „Optimierungsbewertung“) Forward GB/s / Backward GB/s anstelle von TFLOPS, und ein Op mit einer einzelnen Ausgabe ersetzt out_snr/da_snr/db_snr durch seine eigene Korrektheitsmetrik. Welches Schema du auch wählst, friere es bei BASELINE ein, halte es über alle Runden byte-identisch und aktualisiere den verwendeten CSV-Reader (die mcp__turbo__parse_bench_csv-Zuordnung, falls konfiguriert, andernfalls deinen direkten csv.DictReader) entsprechend – das per-Shape-Regressionsgate schlüsselt auf exakte Spaltennamen.