improve-cutile-kernel-perf

Par nvidia · skills

Optimisez de façon itérative les performances des kernels cuTile grâce au profilage systématique, à l'analyse des goulots d'étranglement, à la comparaison IR et au réglage ciblé. Couvre les tailles de tuiles, l'occupancy, les configurations d'autotune, TMA, les hints de latence, l'ordonnancement persistant, num_ctas, flush_to_zero et le débogage au niveau IR. À utiliser lorsqu'on demande à « optimiser un kernel cuTile », « améliorer les perfs du kernel », « régler les performances cuTile », « accélérer le kernel », ou pour benchmarker et affiner de façon itérative un kernel GPU cuTile dans le projet TileGym.

npx skills add https://github.com/nvidia/skills --skill improve-cutile-kernel-perf

Optimisation itérative des performances du kernel cuTile

Profiler systématiquement, diagnostiquer les goulots d'étranglement et affiner itérativement les performances d'un kernel cuTile dans le repository TileGym.

Instructions

Suivez les trois phases dans l'ordre : Préparation de l'environnement et baseline, boucle d'Expérimentation avec un journal suivi, puis itérez La boucle d'expérimentation jusqu'à ce que les objectifs de perf soient atteints ou que les gains supplémentaires plafonnnent.

Préparation

Travaillez avec l'utilisateur pour préparer l'environnement d'optimisation :

  1. Créez une branche git fraîche : Proposez un nom de branche, par ex. cutile-perf-<kernel_name>-<date> à partir de la branche actuelle. Consultez git checkout -b <branch name>

  2. Localisez le kernel cible :

    • Les kernels cuTile se trouvent sous src/tilegym/suites/<suite>/cutile/ ou src/tilegym/ops/cutile/
    • Lisez le fichier kernel et identifiez : la fonction décorée @ct.kernel, le wrapper de lancement (ct.launch() ou ct_experimental.autotune_launch()), l'enregistrement @register_impl, et les configurations d'autotune actuelles (le cas échéant)
  3. Classifiez le kernel :

    • Intensité arithmétique < 10 -> Limité par la mémoire
    • Intensité arithmétique 10-50 -> Équilibré
    • Intensité arithmétique > 50 -> Limité par le calcul

    Note : la classification ne sert qu'à choisir l'ordre de priorité d'optimisation dans la boucle d'expérimentation. La métrique centrale est toujours latence (ms).

  4. Vérifiez l'environnement GPU :

    • Assurez-vous qu'un nœud GPU (B200/H100/H200) est disponible
    • Tous les commandes de benchmark suivantes doivent s'exécuter sur le nœud GPU
  5. Étudiez les références associées :

    • references/optimization-playbook.md : Recettes étape par étape pour chaque optimisation (A à J) avec exemples de code avant/après
    • references/perf-knobs-catalog.md : Catalogue complet de tous les paramètres ajustables (TMA, persistent scheduling, occupancy, tailles de tile, latency hints, etc.)
    • references/cutile-api-reference.md : Référence de l'API cuTile et 18 règles critiques
    • references/performance-model.md : Modèle Roofline/performance, diagnostic des goulots, autotuning
    • references/ir-dump-guide.md : IR dump, analyse et diagnostic d'erreurs
    • references/cutile-patterns-reference.md : Motifs cuTile courants et quick-reference de conversion
  6. Créez @sandbox/perf_results.md pour suivre la progression. La première exécution écrira une baseline

  7. Confirmez et lancez : Une fois que vous obtenez la confirmation, lancez l'expérimentation

Expérimentation

Chaque itération d'expérience applique UNE optimisation au kernel cible, vérifie la correction, benchmarke à nouveau et enregistre les résultats. Chaque itération doit être terminée en moins de 10 minutes.

L'objectif

  • Améliorer la métrique centrale : réduire la latence (ms)
  • Sous réserve de la contrainte centrale : La correction ne doit pas régresser — chaque optimisation DOIT préserver la correction numérique. La latence (ms) ne doit pas régresser de plus de 2% par rapport à la baseline.

Ce que vous pouvez modifier

  • Le fichier kernel cible sous src/tilegym/suites/<suite>/cutile/ ou src/tilegym/ops/cutile/ : corps du kernel, tailles de tile, occupancy, num_ctas, utilisation de TMA, latency hints, flush_to_zero, configs d'autotune, persistent scheduling, et autres paramètres spécifiques à cuTile
  • Le wrapper de lancement du kernel : calcul de grille, espace de config d'autotune
  • @sandbox/ : N'hésitez pas à ajouter de nouveaux fichiers ou modifier les fichiers que vous avez créés, mais ne les commitez pas à git

Ce que vous ne POUVEZ PAS modifier

  • La sémantique fonctionnelle du kernel (entrées, sorties, et comportement numérique dans la tolérance)
  • L'infrastructure de test et le harness de benchmark
  • Tout ce qui n'est pas listé ci-dessus

À quoi s'attendre des sorties d'expérimentation

Test de correction :

python -m pytest tests/suites/.../test_<kernel_name>.py -k "test_ and cutile and not test_perf" -v

Benchmark de performance :

Pour chaque itération :

  1. Exécutez le benchmark pytest : python -m pytest ... --print-record → extrayez la latence (ms)
  2. Enregistrez la latence dans perf_results.md

Lignes de commande du benchmark :

python -m pytest tests/suites/.../test_<kernel_name>.py -k "test_perf and cutile" --print-record -v

Exemple de latence :

Cutile: {'forward': {'mean': 3.7903138461538455, 'std': 0.0016941310873207053, 'rel_std': 0.044696327430505396, 'median': 3.789880999999999, 'min': 3.7883389999999992, 'max': 3.7941230000000004, 'nrep': 13, 'peak_mem_mb': 913}} ms

Suivre la progression de l'expérience

Utilisez @sandbox/perf_results.md pour enregistrer les résultats de chaque itération. Il doit contenir uniquement un tableau Markdown avec 5 colonnes :

  • iteration : numéro d'itération, commençant à 0 (baseline)
  • optimization : ce qui a été appliqué (par ex., "baseline", "TMA replace gather", "persistent scheduling")
  • latency_ms : latence du kernel en millisecondes, six décimales
  • correctness : PASS ou FAIL
  • status : Si cette itération était keep, revert, ou crash

Exemple de contenu :

| iteration | optimization       | latency_ms | correctness | status |
|----------:|:-------------------|-----------:|:------------|-------:|
| 0         | baseline           |   0.820000 | PASS        | keep   |
| 1         | TMA replace gather |   0.390000 | PASS        | keep   |

Créez l'en-tête du tableau si le fichier était vide. Ajoutez une ligne pour chaque itération.

La baseline

La première itération (itération 0) ne changera aucun code et exécutera simplement le test de correction et le benchmark de performance. Les résultats seront listés à la première ligne comme baseline.

La boucle d'expérimentation

La méthodologie centrale consiste à appliquer UNE optimisation par itération depuis le playbook, vérifier la correction, benchmarker, et décider de conserver ou revenir en arrière. Essayez une optimisation à la fois, et maintenez des enregistrements d'expérimentation propres.

BOUCLE :

  1. Vérifiez le statut git : Branche/commit git actuel sur lequel nous sommes

  2. Profilez et classifiez les goulots d'étranglement en utilisant une inspection de code rapide :

    Motif dans le code Goulot probable Optimisation
    ct.gather/ct.scatter où TMA est possible Fallback TMA A (TMA)
    Pas de for ... in range(bid, n, num_programs) Persistent manquant B (Persistent)
    @ct.kernel sans occupancy= ET sans autotune Occupancy non-ajustée C (Autotune)
    ct.mma(a, b, acc) sans protection TF32 TF32 manquant D (TF32)
    Pas de latency hints sur ct.load/ct.store Latency hints manquants E (Latency)
    ct.store() sans allow_tma=False Chemin de store suboptimal F (Store TMA)
    Tailles de tile fixes petites Désalignement de taille de tile G (Tile Size)
    A–J épuisées ou inapplicables Inconnu / kernel-spécifique K (Customized Creative Optimization Plan)
  3. Sélectionnez et appliquez UNE optimisation depuis references/optimization-playbook.md :

    • Priorité limité par la mémoire : A (TMA) -> B (Persistent) -> C (Autotune) -> F (Store TMA) -> G (Tile Size) -> E (Latency) -> K (Creative Optimization Plan)
    • Priorité limité par le calcul : D (TF32) -> G (Tile Size) -> C (Autotune + num_ctas) -> I (Swizzle) -> B (Persistent) -> K (Creative Optimization Plan)
  4. Vérifiez la correction — si elle échoue, revenez immédiatement en arrière. Causes courantes : flush_to_zero/rounding_mode=APPROX a changé les résultats, tile size OOB, sémantique allow_tma=False, erreur de limite de boucle persistent

  5. Benchmarquez à nouveau et comparez par rapport à la baseline actuelle

  6. Commitez sur git

  7. Enregistrez les résultats dans @sandbox/perf_results.md

  8. Règles de décision :

    Résultat Action
    Amélioration (latence (ms)) >= 5% Accepter comme nouvelle baseline, continuer
    Amélioration 2-5% Accepter, priorité inférieure pour l'itération suivante
    Amélioration < 2% Accepter mais arrêter à moins que l'utilisateur veuille plus
    Régression sur une quelconque config Revenir en arrière immédiatement, essayer l'optimisation suivante
    Pas d'amélioration après 2 itérations consécutives Arrêter
    La cause racine est scheduling ou unknown Escalader auprès de l'utilisateur
  9. Si vous gardez, avancez les chiffres de baseline et continuez la boucle

  10. Si vous revenez en arrière, git reset revenir à là où vous avez commencé et essayer l'optimisation suivante dans l'ordre de priorité JUSQU'À : toutes les tentatives sont terminées, ou plus de 20 itérations se sont produites, ou l'utilisateur interrompt

Soyez autonome : Posez des questions de clarification à l'utilisateur à la phase de préparation. Une fois entrés dans la boucle d'expérimentation, ne faites pas de pause pour demander des commentaires à l'utilisateur : Utilisez votre meilleur jugement pour la prise de décision, consultez rapidement le playbook d'optimisation et le catalogue de perf knobs, et réfléchissez davantage si vous êtes bloqué.

Skills similaires