3 points par GN⁺ 2025-12-10 | 1 commentaires | Partager sur WhatsApp
  • Partant de l'absence d'un débogueur capable d'interrompre l'exécution du GPU et d'en examiner l'état, l'article décrit la mise en œuvre directe de cette capacité sur les GPU AMD.
  • En communiquant directement avec le GPU via l'interface DRM et libdrm, il met en place étape par étape la création de contexte, l'allocation de buffers et l'envoi de commandes.
  • Il construit une architecture qui interrompt l'exécution du GPU avec les registres TBA/TMA et un trap handler, puis lit et restaure l'état grâce à une synchronisation avec le CPU.
  • En intégrant la compilation de code SPIR-V et RADV, l'environnement réel de débogage de shaders est étendu et les fonctions de breakpoint·stepping·watchpoint deviennent implémentables.
  • Cette approche, qui contrôle directement l'architecture interne du GPU, démontre la faisabilité d'un débogueur complet pour GPU AMD et laisse entrevoir une évolution vers une intégration Vulkan.

Besoin et approche du débogage GPU

  • L'approche part du constat qu'il n'existe pas d'outil pour arrêter l'exécution d'un GPU et inspecter son état comme sur un CPU.
    • Le modèle d'exécution parallèle du GPU rend le débogage nettement plus complexe.
  • Un rocgdb existe dans l'environnement AMD ROCm, mais il ne prend en charge qu'une zone limitée à ROCm.
  • En se basant sur la série d'articles de Marcell Kiss, une implémentation d'un débogueur communiquant directement avec le GPU est tentée.

Déboguer en communiquant directement avec le GPU

  • Le fonctionnement du pilote RADV est suivi pour apprendre à communiquer directement avec le GPU.
  • Après ouverture de /dev/dri/cardX, connexion au KMD (kernel-mode driver) puis appel de amdgpu_device_initialize.
  • Avec libdrm, création de contexte (amdgpu_cs_ctx_create) et allocation de buffers.
    • Deux buffers sont créés : un buffer de code et un buffer de commandes.
  • Les buffers sont mappés dans les espaces d'adresses virtuelles GPU/CPU.
    • Le mapping se fait via des appels IOCTL directs au lieu de amdgpu_bo_va_op.
  • Compilation de code assembleur de shader avec clang et objdump, puis extraction du binaire.
  • Construction de commandes GPU au format PM4 Packet pour envoyer les ordres d'exécution des shaders.

Utilisation des traps GPU et de debugfs

  • Les registres TBA/TMA de l'ISA RDNA3 servent à configurer le trap handler.
    • TBA : l'adresse du trap handler
    • TMA : l'adresse mémoire temporaire pour le trap handler
  • L'accès direct depuis l'espace utilisateur étant impossible, il faut utiliser l'interface debugfs.
    • Accès aux registres via le fichier /sys/kernel/debug/dri/{PCI address}/regs2.
    • Écriture des registres via amdgpu_debugfs_regs2_write.
  • Pour chaque VMID, TBA/TMA sont configurés afin d'activer le trap handler.
    • Chaque VMID distingue un contexte de processus GPU.

Implémentation du trap handler

  • Le trap handler est un programme shader privilégié exécuté lorsqu'un GPU rencontre une exception.
  • Les registres TTMP sont utilisés pour stocker l'état du GPU (STATUS, EXEC, VCC, etc.).
  • L'instruction global_store_addtid_b32 écrit en mémoire les valeurs de registres thread par thread.
  • Dès que le CPU détecte que le GPU a écrit les données, il suspend le GPU via le registre SQ_CMD.
    • Le CPU analyse ensuite les données, puis relance le GPU via SQ_CMD.
  • Lors du retour, le trap handler restaure le compteur de programme et l'état des registres.

Exécution SPIR-V et intégration RADV

  • Au lieu de l'assemblage manuel, la compilation de code SPIR-V est prise en charge.
    • Le compilateur ACO de RADV est utilisé pour convertir SPIR-V en binaire GPU.
    • Le périphérique virtuel est créé avec la variable d'environnement RADV_FORCE_FAMILY.
  • En mode null_winsys de RADV, seule la compilation est exécutée, sans accès matériel réel.
  • Des informations de shader, de configuration des ressources et de débogage sont extraites du résultat de compilation.

Extension des fonctionnalités de débogage

  • Stepping : contrôle d'exécution au niveau des instructions via les bits RSRC1.DEBUG_MODE et RSRC3.TRAP_ON_START.
  • Breakpoints : calcul de la position du programmeur en fonction de l'adresse du buffer de code, puis gestion par trap.
  • Source Mapping : mappage des lignes de code source grâce aux informations de débogage du compilateur ACO.
  • Watchpoints : implémentation possible de la surveillance d'adresses via la protection de page GPU ou le registre SQ_WATCH.
  • Suivi des noms et types de variables : besoin d'améliorer la transmission des informations de débogage dans l'étape d'optimisation NIR de Mesa.
  • Intégration Vulkan : basée sur RADV, elle peut exploiter infos buffer, texture et constantes pour un débogage par frame.

Bonus : code de parcours de pages en mode utilisateur

  • Un exemple de code de parcours de table de pages pour GPU RDNA3 (gfx11) est fourni.
    • Définitions de structures PDE/PTE et fonctions de décodage incluses.
    • Implémentation de la conversion d'une adresse virtuelle vers une adresse physique.
  • En lisant les registres de tables de pages par VMID, il devient possible d'analyser la structure de mapping mémoire GPU.

Conclusion

  • L'approche démontre la faisabilité d'un débogueur complet pour GPU AMD par accès au niveau noyau et matériel.
  • Une boucle de communication bidirectionnelle CPU-GPU est mise en place pour permettre interruption, analyse d'état et reprise pendant l'exécution.
  • Une intégration future avec RADV et Vulkan laisse entrevoir une plateforme de débogage GPU plus conviviale pour les développeurs.

1 commentaires

 
GN⁺ 2025-12-10
Commentaire sur Hacker News
  • Ce n’est pas AMD, mais Metal propose vraiment un excellent débogueur et un très bon ensemble d’outils de développement
    C’est pourquoi, quand je travaille sur le GPU, je préfère toujours commencer avec Metal puis porter ensuite vers d’autres systèmes
    Il est utile de consulter la documentation du débogueur Metal
    Je ne suis pas développeur de jeux AAA, mais pour mes usages, c’était presque parfait
    La fonctionnalité qui permet d’afficher dans le shader des chaînes de log formatées, mélangées ensuite aux logs de l’application, est particulièrement impressionnante
    Je développe une application GPU qui utilise à la fois Metal et OpenGL, et côté OpenGL il a été difficile de trouver des outils au niveau de Metal

    • J’ai découvert les shaders pour la première fois en portant du code graphique OpenGL vers PS5 et Xbox
      Les deux plateformes fournissent chacune un débogueur dédié, et leur qualité était franchement bonne
      Au final, j’ai compris que quand on ne voit qu’un écran noir, l’outillage fait toute la différence
      Je me demande si utiliser DirectX à la place d’OpenGL permettrait d’avoir un meilleur outillage sous Windows
    • Le débogueur Metal est vraiment très bien conçu, mais il se fige souvent ou fait planter Xcode
      Surtout quand on travaille avec des compute shaders, le profiling fonctionne souvent mal
      C’est un outil pensé surtout pour le graphisme, donc il semble encore limité pour l’IA ou les traitements sur de très gros buffers
    • Le débogueur Metal de Xcode est excellent, et l’API Metal elle-même est intuitive
      Ça m’a beaucoup mieux convenu qu’OpenGL
      Côté OpenGL, as-tu essayé RenderDoc ? Pour Vulkan/OpenGL, c’est l’outil qui s’en rapproche le plus
    • J’ai du mal à être d’accord avec l’idée d’acheter un Mac pour apprendre le GPU
      Acheter une machine chère pour déboguer une API réservée à Metal est inefficace
      Pour apprendre sérieusement la programmation graphique, je pense qu’il vaut mieux apprendre DX12 ou Vulkan sur Windows ou Linux
      Avec des outils comme RenderDoc, c’est tout à fait faisable
      Metal est une bonne API, mais sa plus grande limite reste qu’elle ne peut pas être utilisée hors des plateformes Apple
    • Metal est séduisant, mais je pense que la dépendance à un fournisseur (vendor lock-in) pose problème
      Sur les serveurs ou dans le jeu, on utilise surtout des GPU AMD ou Nvidia, donc un développement centré sur Metal n’est pas très pratique
  • CUDA de NVIDIA dispose d’un GDB first-party appelé cuda-gdb
    Comme on peut le voir dans la documentation officielle, il est bien adapté au modèle de threads de CUDA
    En revanche, l’exécution pas à pas n’est possible qu’au niveau du warp

  • Sur les cartes NVIDIA, on peut utiliser NSight, et il existe aussi RenderDoc, qui fonctionne sur différents GPU

    • RenderDoc est plus proche d’un débogueur de haut niveau et il est aussi utile pour l’analyse des performances
      Quand il manque des visualisations de haut niveau comme QML ou QSG_VISUALIZE=overdraw, il est intéressant de suivre la scène appel API par appel API
    • nsys et nvtx sont aussi d’excellents outils
      Beaucoup de gens ne savent pas qu’on peut les utiliser même sans GPU
  • À la question de savoir s’il existe des outils officiels pour AMD, GDB prend en charge le débogage des GPU AMD
    Il existe aussi des outils comme UMR d’AMD,
    Radeon GPU Detective,
    ou encore la Radeon Developer Tool Suite

    • Un billet de blog mentionne aussi rocgdb, un débogueur pour AMD ROCm
  • Partage d’un outil de monitoring fait maison pour les GPU AMD
    Il s’agit d’un projet appelé picomon, créé pour résoudre les crashs fréquents de nvtop, jugé trop strict

  • Metal, CUDA, Pix, PS/Switch, etc. ont chacun leurs outils dédiés selon la plateforme
    C’est aussi pour cela que les chercheurs ont encore tendance à préférer CUDA
    Nsight Systems en fait partie

  • Je me demande si quelqu’un utilise un GPU 7900 XTX pour de l’inférence locale (inference) ou de la diffusion
    J’ai installé Linux, mais la machine reste la plupart du temps inutilisée, donc j’aimerais en faire quelque chose

    • Je l’utilise sur Gentoo depuis plusieurs années
      Il y avait autrefois des problèmes liés à Python, mais récemment c’est devenu stable, au point de permettre même img2video
      Avec 24 Go de VRAM, je pense que cela reste encore la carte au meilleur rapport qualité-prix
      ROCm a récemment fait l’objet d’une refonte majeure pour améliorer l’UX, donc je recommande de jeter un œil à TheRock
    • Sous Windows, j’ai hébergé localement un LLM avec une 7900XT via ollama, et ça a bien marché
      Même le modèle devstral:24b tournait assez vite
    • Quand je l’ai achetée au lancement, il y avait des erreurs OOM du noyau liées à ROCm
      Dans ComfyUI, ça fonctionnait globalement bien, mais c’était instable sur certains workloads atypiques
      J’ai entendu dire que c’était plus stable récemment
    • J’ai fait des tâches similaires avec une 6800XT ; c’est un peu plus délicat à cause d’un écosystème centré sur CUDA, mais c’était faisable
    • J’ai testé des modèles de génération d’images et de texte, et en remplaçant la bibliothèque torch de base par la version ROCm d’AMD, tout a fonctionné sans problème