Débogueur GPU AMD
(thegeeko.me)- 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
rocgdbexiste 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 deamdgpu_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.
- Le mapping se fait via des appels IOCTL directs au lieu de
- Compilation de code assembleur de shader avec
clangetobjdump, puis extraction du binaire. - Construction de commandes GPU au format
PM4 Packetpour 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 handlerTMA: 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.
- Accès aux registres via le fichier
- 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.
- Le CPU analyse ensuite les données, puis relance le GPU via
- 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
ACOde 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.
- Le compilateur
- En mode
null_winsysde 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_MODEetRSRC3.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
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
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
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
Ç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
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
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
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 APIBeaucoup 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
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
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
Même le modèle devstral:24b tournait assez vite
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