3 puntos por GN⁺ 2025-12-10 | 1 comentarios | Compartir por WhatsApp
  • Parte de la ausencia de un depurador capaz de pausar la ejecución de la GPU e inspeccionar su estado, y explica el proceso de implementarlo directamente sobre una GPU de AMD
  • Se comunica directamente con la GPU mediante la interfaz DRM y libdrm, construyendo paso a paso el proceso de creación de contexto, asignación de búferes y envío de comandos
  • Aprovecha los registros TBA/TMA y un trap handler para detener la ejecución de la GPU, y construye una arquitectura para leer y restaurar el estado mediante sincronización con la CPU
  • Amplía el entorno real de depuración de shaders mediante la compilación de código SPIR-V y la integración con RADV, haciendo posible implementar funciones de breakpoint, stepping y watchpoint
  • Este enfoque, que controla directamente la estructura interna de la GPU, demuestra la posibilidad de implementar un depurador completo para GPUs AMD, con margen de evolución futura hacia la integración con Vulkan

La necesidad de depurar GPU y el enfoque

  • Parte de la falta de herramientas para pausar la ejecución de la GPU e inspeccionar su estado, como se hace en CPU
    • El modelo de ejecución paralela de la GPU hace que la depuración sea mucho más compleja
  • Existe rocgdb en el entorno AMD ROCm, pero solo admite un alcance limitado a ROCm
  • Tomando como referencia la serie de blogs de Marcell Kiss, se intenta implementar un depurador que se comunique directamente con la GPU

Comunicación directa con la GPU

  • Se aprende a comunicarse directamente con la GPU siguiendo el funcionamiento del driver RADV
  • Se abre /dev/dri/cardX para conectarse con el KMD (driver en modo kernel) y luego se llama a amdgpu_device_initialize
  • Mediante libdrm se realiza la creación de contexto (amdgpu_cs_ctx_create) y la asignación de búferes
    • Se crean dos búferes: uno de código y otro de comandos
  • Los búferes se mapean al espacio de direcciones virtuales de GPU/CPU
    • En lugar de amdgpu_bo_va_op, el mapeo se resuelve con llamadas directas a IOCTL
  • Con clang y objdump se compila el código ensamblador del shader y se extrae el binario
  • Se construyen comandos de GPU en formato PM4 Packet para enviar la orden de ejecutar el shader

Traps de GPU y uso de Debugfs

  • Se configuran trap handlers usando los registros TBA/TMA de la ISA RDNA3
    • TBA: dirección del trap handler
    • TMA: dirección de memoria temporal para el trap handler
  • Como no se puede acceder directamente desde espacio de usuario, se utiliza la interfaz debugfs
    • Se accede a los registros a través del archivo /sys/kernel/debug/dri/{PCI address}/regs2
    • La escritura en registros se realiza con amdgpu_debugfs_regs2_write
  • Se configuran TBA/TMA por VMID para activar el trap handler
    • Cada VMID distingue un contexto de proceso de GPU

Implementación del trap handler

  • El trap handler es un programa de shader privilegiado que se ejecuta cuando la GPU encuentra una excepción
  • Usa registros TTMP para guardar el estado de la GPU (STATUS, EXEC, VCC, etc.)
  • La instrucción global_store_addtid_b32 se usa para guardar en memoria los valores de registros por hilo
  • Cuando la GPU escribe los datos, la CPU lo detecta y pausa temporalmente la GPU con el registro SQ_CMD
    • Después de analizar los datos, la CPU vuelve a usar SQ_CMD para reanudar la ejecución de la GPU
  • Al regresar, el trap handler restaura el contador de programa y el estado de los registros

Ejecución de código SPIR-V e integración con RADV

  • Se añade soporte para compilar código SPIR-V en lugar de ensamblado manual
    • Se usa el compilador ACO de RADV para convertir SPIR-V en binario de GPU
    • La variable de entorno RADV_FORCE_FAMILY permite crear un dispositivo virtual
  • El modo null_winsys de RADV permite compilar sin acceder al hardware real
  • Del resultado de la compilación se extraen código de shader, configuración de recursos e información de depuración

Ampliación de funciones del depurador

  • Stepping: se controla la ejecución por instrucción usando los bits RSRC1.DEBUG_MODE y RSRC3.TRAP_ON_START
  • Breakpoints: se calcula la posición del contador de programa a partir de la dirección del búfer de código y luego se procesa el trap
  • Source Mapping: se mapean líneas del código fuente usando la información de depuración del compilador ACO
  • Watchpoints: es posible implementar vigilancia de direcciones mediante protección de páginas de GPU o el registro SQ_WATCH
  • Seguimiento de nombres y tipos de variables: en la fase de optimización NIR de Mesa, hace falta mejorar la propagación de información de depuración
  • Integración con Vulkan: sobre la base de RADV, puede habilitarse depuración por frame y aprovechar información de búferes, texturas y constantes

Bonus: código de page walking en modo usuario

  • Se ofrece un ejemplo de código de recorrido de tablas de páginas para GPU RDNA3 (gfx11)
    • Incluye definiciones de estructuras PDE/PTE y funciones de decodificación
    • Implementa el proceso de convertir direcciones virtuales en físicas
  • Al leer los registros de tablas de páginas por VMID, se puede analizar la estructura de mapeo de memoria de la GPU

Conclusión

  • Se demuestra la posibilidad de implementar un depurador completo para GPU AMD mediante acceso a nivel de kernel y hardware
  • Se construye un bucle de comunicación bidireccional entre CPU y GPU para pausar la ejecución, analizar el estado y reanudarla
  • En el futuro, la integración con RADV y Vulkan podría convertirlo en un entorno de depuración de GPU más amigable para desarrolladores

1 comentarios

 
GN⁺ 2025-12-10
Opiniones en Hacker News
  • No es AMD, pero Metal ofrece un debugger y un conjunto de herramientas de desarrollo realmente excelentes
    Por eso, cuando trabajo con GPU, siempre prefiero usar primero Metal y luego portar a otros sistemas
    Vale la pena consultar la documentación de Metal Debugger
    No soy desarrollador de juegos AAA, pero para mi uso fue casi perfecto
    En especial, me sorprendió la función que permite imprimir cadenas de log con formato desde los shaders y mostrarlas mezcladas con los logs de la app
    Estoy desarrollando una app basada en GPU que usa tanto Metal como OpenGL, y del lado de OpenGL fue difícil encontrar herramientas al nivel de Metal

    • Yo conocí los shaders por primera vez mientras portaba código gráfico de OpenGL a PS5 y Xbox
      Ambas plataformas ofrecen debuggers dedicados, y la calidad era bastante buena
      Al final entendí que cuando solo ves una pantalla negra, las herramientas lo son todo
      Me pregunto si usando DirectX en lugar de OpenGL se obtienen mejores herramientas en Windows
    • El debugger de Metal está realmente bien hecho, pero a menudo se congela o hace que Xcode se cierre de forma forzada
      En especial, al trabajar con compute shader, muchas veces el profiling no funciona bien
      Como es una herramienta diseñada con foco en gráficos, parece que todavía tiene limitaciones para IA o trabajo con buffers grandes
    • El debugger de Metal en Xcode es excelente, y la propia API de Metal también es intuitiva
      Me encajó mucho mejor que OpenGL
      Del lado de OpenGL, ¿has probado RenderDoc? Es la herramienta más parecida para Vulkan/OpenGL
    • Me cuesta estar de acuerdo con la idea de comprar una Mac para aprender GPU
      Comprar una computadora cara para hacer debugging de una API exclusiva de Metal es ineficiente
      Si quieres aprender programación gráfica en serio, creo que es mejor aprender DX12 o Vulkan en Windows o Linux
      Con herramientas como RenderDoc se puede perfectamente
      Metal es una buena API, pero su mayor limitación es que no puede usarse fuera de las plataformas de Apple
    • Metal está genial, pero creo que el problema es la dependencia del proveedor (vendor lock-in)
      En entornos de servidores o juegos, la mayoría usa GPU de AMD o Nvidia, así que un desarrollo centrado en Metal no es práctico
  • CUDA de NVIDIA tiene un GDB oficial llamado cuda-gdb
    Como puede verse en la documentación oficial, está bien adaptado al modelo de hilos de CUDA
    Eso sí, solo permite ejecutar paso a paso a nivel de warp

  • En tarjetas NVIDIA se puede usar NSight, y también está RenderDoc, que funciona con distintas GPU

    • RenderDoc se parece más a un debugger de alto nivel y también es útil para análisis de rendimiento
      Cuando faltan visualizaciones de alto nivel como QML o QSG_VISUALIZE=overdraw, es interesante rastrear la escena a nivel de llamadas de API
    • nsys y nvtx también son herramientas excelentes
      Mucha gente no sabe que pueden usarse incluso sin GPU
  • Ante la pregunta de si hay herramientas oficiales para AMD, GDB soporta debugging de AMD GPU
    También existen herramientas como UMR de AMD,
    Radeon GPU Detective y
    Radeon Developer Tool Suite

    • En la entrada del blog también se menciona rocgdb, un debugger para AMD ROCm
  • Comparto una herramienta de monitoreo hecha por mí para AMD GPU
    Es un proyecto llamado picomon, que hice para resolver el problema de que nvtop era demasiado estricto y se caía con frecuencia

  • Cada plataforma, como Metal, CUDA, Pix o PS/Switch, tiene sus propias herramientas dedicadas
    Por eso los investigadores todavía tienden a preferir CUDA
    Nsight Systems es una de ellas

  • Me pregunto si alguien usa una GPU 7900 XTX para inferencia local (inference) o diffusion
    Instalé Linux, pero la mayor parte del tiempo está sin usarse y me gustaría aprovecharla

    • La llevo usando varios años en Gentoo
      Antes había problemas relacionados con Python, pero recientemente se estabilizó y ya permite hasta img2video
      Con 24GB de VRAM, sigo pensando que es la tarjeta con mejor relación precio-rendimiento
      ROCm fue renovado a fondo recientemente para mejorar la UX, así que recomiendo revisar TheRock
    • En Windows probé hospedar un LLM localmente con una 7900XT mediante ollama, y funcionó bien
      El modelo devstral:24b también corría bastante rápido
    • Cuando la compré al poco tiempo de salir, había errores de kernel OOM relacionados con ROCm
      En ComfyUI casi todo funcionaba bien, pero en tareas raras era inestable
      He oído que recientemente se estabilizó
    • También probé tareas similares con una 6800XT, y aunque el ecosistema está centrado en CUDA y es un poco más complicado, sí se podía
    • Probé modelos de generación de imágenes y texto, y al reemplazar la librería torch estándar por la versión ROCm de AMD, todo funcionó sin problemas