La computación de alto rendimiento (HPC) y las cargas de trabajo de IA/ML modernas enfrentan desafíos crecientes debido a las arquitecturas de memoria complejas, la heterogeneidad del hardware (CPUs, GPUs, aceleradores) y la necesidad de una gestión eficiente de la concurrencia y la comunicación en sistemas distribuidos a gran escala. Estos problemas fundamentales de la computación distribuida, como la sincronización sin contención y la localidad de datos, se exacerban con la escala y la diversidad de los sistemas actuales.
CARTS aborda estos desafíos mediante un enfoque de compilación centrado en tareas y eventos, inspirado en el modelo Codelet. Este modelo descompone la computación en unidades pequeñas e independientes que se ejecutan tan pronto como sus dependencias de datos se satisfacen. Al modelar explícitamente tareas, bloques de datos, eventos y épocas, CARTS busca facilitar el análisis y la optimización de la ejecución de tareas en entornos distribuidos, mejorando la utilización de recursos y la eficiencia general del sistema.
Arquitectura del Sistema
CARTS se construye sobre ARTS (Abstract Runtime System), que implementa un modelo de ejecución de tareas basado en eventos. Los componentes clave de ARTS son Event-Driven Tasks (EDTs), que son unidades de trabajo programables; DataBlocks, que representan regiones de memoria con datos para las tareas; Events, señales que indican la disponibilidad de DataBlocks o la finalización de tareas; y Epochs, límites de sincronización que agrupan tareas. Este modelo permite una sincronización ligera y una gestión eficiente de los datos.
El pipeline del compilador CARTS comienza con la traducción de código C/OpenMP a MLIR utilizando Clang/Polygeist. Esta etapa maneja múltiples dialectos de MLIR, incluyendo OpenMP, SCF, Affine y Arith. Posteriormente, un dialecto ARTS personalizado convierte las tareas OpenMP de alto nivel en representaciones directas de EDTs, DataBlocks, eventos y épocas, facilitando el análisis y la optimización. Las fases de optimización incluyen la eliminación de tareas redundantes, la gestión de DataBlocks basada en patrones de acceso a memoria, la asignación de eventos y optimizaciones clásicas como la eliminación de código muerto. Finalmente, el MLIR mejorado con ARTS se convierte a LLVM IR, donde las regiones EDT se delinean en funciones y se insertan llamadas a la API de ARTS para la gestión en tiempo de ejecución. El binario resultante se ejecuta en el runtime de ARTS, que programa dinámicamente las tareas basándose en la disponibilidad de datos.
Pipeline de Compilación CARTS
- 1 C/OpenMP Source Código fuente de la aplicación HPC
- 2 Clang/Polygeist Conversión a MLIR (OpenMP, SCF, Affine, Arith dialects)
- 3 ARTS Dialect Transformación a EDTs, DataBlocks, Events, Epochs
- 4 Optimization Passes Optimización de EDTs, gestión de DataBlocks, manejo de eventos
- 5 Lowering to LLVM IR Generación de LLVM IR con llamadas a la API de ARTS
- 6 ARTS Runtime Ejecución dinámica de tareas basada en disponibilidad de datos
| Capa | Tecnología | Justificación |
|---|---|---|
| data-processing | MLIR | Infraestructura de representación intermedia flexible para múltiples dialectos y transformaciones de compilador. |
| data-processing | LLVM | Backend de compilación para la generación de código máquina optimizado y la integración con el runtime ARTS. |
| data-processing | Clang | Frontend de compilación para C/OpenMP, utilizado para la fase inicial de parsing y análisis sintáctico. |
| data-processing | Polygeist | Herramienta para la traducción de código C/OpenMP a MLIR, extendiendo la capacidad de Clang. |
| orchestration | ARTS (Abstract Runtime System) | Runtime de ejecución que gestiona EDTs, DataBlocks, Events y Epochs en sistemas distribuidos. |
Fundamentos Teóricos
El modelo Codelet, que inspira ARTS, es una evolución de conceptos fundamentales en la programación paralela y los sistemas de ejecución orientados a datos. Se relaciona con el modelo de Dataflow Computing, propuesto en la década de 1970 por autores como Dennis y Arvind, donde las instrucciones se ejecutan cuando todos sus operandos están disponibles. Este enfoque contrasta con el modelo de control-flow tradicional y busca explotar el paralelismo inherente a los datos.
La gestión de dependencias y la programación de tareas en CARTS también se conecta con la teoría de grafos de tareas (Task Graph Scheduling), un área de investigación activa en la optimización de la ejecución paralela. Algoritmos clásicos como el Critical Path Method (CPM) o los algoritmos de lista de programación (List Scheduling) buscan minimizar el tiempo de ejecución total de un conjunto de tareas con dependencias. La explicitación de EDTs y DataBlocks en CARTS permite aplicar principios de análisis de dependencias de datos y control similares a los estudiados en la compilación de lenguajes paralelos y la optimización de bucles en los años 80 y 90, por ejemplo, los trabajos de Kennedy y Allen sobre análisis de dependencias para vectorización y paralelización automática.