Nome do Projeto
Metaprogramação aplicada no desenvolvimento de abstrações combináveis para a programação de GPUs
Ênfase
Pesquisa
Data inicial - Data final
26/05/2025 - 25/05/2028
Unidade de Origem
Coordenador Atual
Área CNPq
Ciências Exatas e da Terra
Resumo
A programação de GPUs ocorre geralmente de três formas: através de linguagens de baixo nível como CUDA e OpenCL, através de DSLs (Linguagens de Domínio Específico), ou linguagens de alto-nível, como por exemplo Futhark e Julia. Quando programadores usam DSLs e linguagens de alto nível, eles possuem pouco ou nenhum controle sobre como suas computações são executadas nas GPUs.
Por outro lado, uma vantagem das DSLs e das linguagens de alto nível é que elas facilitam a combinação de diferentes componentes de software na construção de novos componentes que rodam em GPU. Hoje em dia, as principais linguagens usadas para a programação desses dispositivos são CUDA e OpenCL, que são linguagens de baixo nível, onde o programador precisa se preocupar com questões como alocação de memória, tamanho de blocos e grids. As linguagens de baixo nível, apesar de eficientes, pecam na falta de abstrações seguras para o desenvolvimento de software. Nessas linguagens, os programas misturam aspectos de coordenação da aplicação na GPU com os aspectos relativos à computação sendo executada, o que dificulta o reuso do código em outras aplicações ou dispositivos.
Neste trabalho, pretendemos juntar a facilidade de composição de software das linguagens de alto nível e DSLs, com a eficiência e o poder das linguagens de mais baixo nível, separando o código de orquestração da computação do que está sendo de fato computado. O objetivo deste projeto é o desenvolvimento de metodologias e ferramentas para se estender linguagens de programação com abstrações para a programação de GPUs. Pretende-se desenvolver um conjunto de abstrações componíveis de sofware, onde em um nível mais baixo, estão separados os aspectos de orquestração da computação e em um nível mais alto aspectos relativos à computação. Vários trabalhos, tentam desenvolver abstrações para a programação de GPUs que são específicas para certas linguagens. Nosso objetivo é que as abstrações aqui propostas sejam baseadas em metaprogramação e que possam ser implementadas em qualquer linguagem que suporte o conceito. Metaprogramação é uma abstração disponível em várias linguagens de programação que permite que o programador desenvolva programas que recebem programas como entrada e devolvem programas como saída. Metaprogramas podem ler, transformar e gerar novos programas, e, dessa forma, ela é muito utilizada para estender linguagens de programação com novas abstrações. Hoje em dia, várias linguagens apresentam de alguma forma esse conceito, como por exemplo, Python, Ruby, Rust, Java, Elixir, Haskell, LISP, etc.
Como resultado pretendemos obter uma teoria bem fundada sobre o uso de metaprogramação no desenvolvimento de abstrações componíveis para a programação de GPUs, suportada por um conjunto de bibliotecas e ferramentas que servirão como validação em uma coleção de estudos de caso. Pretende-se explorar a composição vertical, onde abstrações de baixo nível são os blocos usados para a construção das abstrações de mais alto nível, e a composição horizontal, que permite que a saída de uma dessas abstrações possa ser usada com a entrada da outra.
Objetivo Geral
O objetivo geral do projeto é a proposta de uma metodologia baseada em metaprogramação que permita o desenvolvimento abstrações componíveis de software para a programação de GPUs. A metodologia proposta neste projeto baseia-se na ideia de estender linguagens de programação que suportam metaprogramação com um conjunto de abstrações mínimas para a programação de GPUs. Essas abstrações devem ser componíveis de forma que construções de baixo nível possam ser combinadas em abstrações de mais alto nível.
Justificativa
GPUs (Graphics Processing Units) são unidades de hardware dedicado, inicialmente desenvolvidas para o processamento de aplicações gráficas e que, com a alta demanda por processamento dos dias de hoje, acabaram se tornando um elemento de processamento de propósito geral. O uso de GPUs tem crescido muito nos últimos anos devido a sua aplicabilidade no processamento de algoritmos de Machine Learning em geral, especialmente Deep Learning. Esses dispositivos são geralmente programados usando linguagens de baixo nível, como por exemplo CUDA e OpenCL. Com a alta demanda de uso desses dispositivos, é necessário que se encontre maneiras de tornar a programação de GPUs mais acessível, que é o objetivo deste projeto. A metodologia a ser definida neste projeto irá permitir estender linguagens que suportam metaprogramação com abstrações mínimas que permitam a construção de abstrações de mais alto nível para a programação de GPUs.
Metodologia
Para atingir o objetivo geral deste projeto, foi definida uma estratégia de ação baseada em objetivos mais específicos.
Objetivo 1: Abstração de baixo nível definida por metaprogramação
O objetivo desta parte do projeto é a definição de uma linguagem mínima que permita a expressividade de kernels de baixo nível e que possa ser definida através de metaprogramação em diferentes linguagens de programação.
A base inicial da metodologia proposta são os Kernels de Alta-Ordem (KAOs), ou seja, kernels que podem receber outros kernels ou funções como argumentos. Os Kernels de Alta-Ordem são o nível mais baixo de construção de novas abstrações na metodologia proposta. Esses kernels são parecidos com kernels CUDA ou OpenCL, onde o programador tem acesso à abstrações de baixo nível como blocos, grids, memória local, compartilhada ou global, etc. A adição da abstração de Kernels de Alta-Ordem, permite a definição de kernels reconfiguráveis, em que parte do algoritmo a ser executado é parametrizável. Dessa forma, o programador consegue separar o código de orquestração, da computação a ser realizada.
Nesta parte do trabalho pretende-se definir formalmente os KAOs usando construções que possam ser definidas por metaprogramação em diferentes linguagens. Além disso, pretende-se especificar como as construções dos KAOs podem ser mapeados para uma linguagem de mais baixo nível como CUDA ou OpenCL. Como estudo de caso, essa abstração será implementada em mais de uma linguagem de programação. Os KAOs serão definidos como uma extensão da linguagem GPotion, DSL desenvolvida pelo nosso grupo de pesquisa para a programação de GPUs.
Objetivo 2: Abstração de alto-nível, Esqueletos de paralelismo
Em um nível maior de abstração, pretendemos usar os Kernels de Alta-Ordem, para a implementação de esqueletos de paralelismo. Esqueletos de paralelismo são funções configuráveis que encapsulam padrões recorrentes de paralelismo. Ao usar esqueletos, o programador deve escolher esqueletos de acordo com o padrão de paralelismo necessário para a aplicação. Geralmente, o esqueleto é configurado somente com as computações sequenciais a serem executadas. A instanciação e execução paralela na GPU é feita de forma automática pelo esqueleto. Dois exemplos de esqueletos bem conhecidos são o Map e o Reduce. O Map aplica em paralelo uma computação em todos os elementos de um array gerando um array de resultados. O Reduce utiliza uma operação binária para reduzir os elementos do array de entrada a um resultado final. Existem vários trabalhos na literatura que descrevem a utilização de esqueletos para a programação de GPUs
Objetivo 3: Abstração de alto-nível, Compreensão de vetores
Outra abstração a ser desenvolvida são as {\it compreensões de vetores} para GPUs. Compreensão de listas é uma abstração utilizada em várias linguagens para a descrição de listas baseadas em listas já existentes. Essa abstração é derivada da notação para a descrição de conjuntos e começou a se popularizar através das linguagens de programação funcional. Hoje em dia a compreensão de listas está presente na maioria das linguagens de programação, como por exemplo, Python, Java, JavaScript, Elixir, etc.
A compreensão de arrays para GPUs proposta neste trabalho, estende a ideia da compreensão de listas, permitindo a descrição de novos arrays partindo de arrays existentes, onde a computação desse novo array acontece na GPU. A execução em GPUs de compreensões já foi investigada em outros trabalhos, como por exemplo, as Tensor Comprehensions desenvolvida pela Meta/Facebook. Aqui o foco é demonstrar que essa abstração de alto nível pode ser compilada usando metaprogramação para combinações das outras abstrações desenvolvidas no projeto, ou seja, esqueletos e kernels de alta ordem. Assim como as compreensões de listas das linguagens funcionais são implementadas através da tradução de sua notação, gerando uma composição de funções de alta ordem conhecidas, pretendemos demonstrar que as compreensões de arrays podem ser traduzidas para uma combinação de esqueletos e kernels de alta ordem, aplicando otimizações na composição desses esqueletos.
Objetivo 4: Abstração de alto-nível, Orquestração de Computações em GPU
As três abstrações propostas neste trabalho serão construídas utilizando uma composição vertical, onde os esqueletos são construídos através da composição de kernels de Alta-Ordem e a compreensão de vetores através da composição de esqueletos. Este trabalho pretende também permitir a composição horizontal dessas abstrações através de uma linguagem de orquestração, onde podemos ligar a saída de uma compreensão a entrada de um bloco de esqueletos, ou um vetor gerado por um kernel de alta ordem poderá ser transformado em um novo vetor através de uma compreensão, por exemplo. A linguagem de orquestração deve permitir ordenar e sincronizar a execução das computações na GPU. Durante a compilação da linguagem de orquestração, uma série de otimização estáticas e dinâmicas podem ser aplicadas na composição das abstrações a serem executadas na GPU.
Objetivo 1: Abstração de baixo nível definida por metaprogramação
O objetivo desta parte do projeto é a definição de uma linguagem mínima que permita a expressividade de kernels de baixo nível e que possa ser definida através de metaprogramação em diferentes linguagens de programação.
A base inicial da metodologia proposta são os Kernels de Alta-Ordem (KAOs), ou seja, kernels que podem receber outros kernels ou funções como argumentos. Os Kernels de Alta-Ordem são o nível mais baixo de construção de novas abstrações na metodologia proposta. Esses kernels são parecidos com kernels CUDA ou OpenCL, onde o programador tem acesso à abstrações de baixo nível como blocos, grids, memória local, compartilhada ou global, etc. A adição da abstração de Kernels de Alta-Ordem, permite a definição de kernels reconfiguráveis, em que parte do algoritmo a ser executado é parametrizável. Dessa forma, o programador consegue separar o código de orquestração, da computação a ser realizada.
Nesta parte do trabalho pretende-se definir formalmente os KAOs usando construções que possam ser definidas por metaprogramação em diferentes linguagens. Além disso, pretende-se especificar como as construções dos KAOs podem ser mapeados para uma linguagem de mais baixo nível como CUDA ou OpenCL. Como estudo de caso, essa abstração será implementada em mais de uma linguagem de programação. Os KAOs serão definidos como uma extensão da linguagem GPotion, DSL desenvolvida pelo nosso grupo de pesquisa para a programação de GPUs.
Objetivo 2: Abstração de alto-nível, Esqueletos de paralelismo
Em um nível maior de abstração, pretendemos usar os Kernels de Alta-Ordem, para a implementação de esqueletos de paralelismo. Esqueletos de paralelismo são funções configuráveis que encapsulam padrões recorrentes de paralelismo. Ao usar esqueletos, o programador deve escolher esqueletos de acordo com o padrão de paralelismo necessário para a aplicação. Geralmente, o esqueleto é configurado somente com as computações sequenciais a serem executadas. A instanciação e execução paralela na GPU é feita de forma automática pelo esqueleto. Dois exemplos de esqueletos bem conhecidos são o Map e o Reduce. O Map aplica em paralelo uma computação em todos os elementos de um array gerando um array de resultados. O Reduce utiliza uma operação binária para reduzir os elementos do array de entrada a um resultado final. Existem vários trabalhos na literatura que descrevem a utilização de esqueletos para a programação de GPUs
Objetivo 3: Abstração de alto-nível, Compreensão de vetores
Outra abstração a ser desenvolvida são as {\it compreensões de vetores} para GPUs. Compreensão de listas é uma abstração utilizada em várias linguagens para a descrição de listas baseadas em listas já existentes. Essa abstração é derivada da notação para a descrição de conjuntos e começou a se popularizar através das linguagens de programação funcional. Hoje em dia a compreensão de listas está presente na maioria das linguagens de programação, como por exemplo, Python, Java, JavaScript, Elixir, etc.
A compreensão de arrays para GPUs proposta neste trabalho, estende a ideia da compreensão de listas, permitindo a descrição de novos arrays partindo de arrays existentes, onde a computação desse novo array acontece na GPU. A execução em GPUs de compreensões já foi investigada em outros trabalhos, como por exemplo, as Tensor Comprehensions desenvolvida pela Meta/Facebook. Aqui o foco é demonstrar que essa abstração de alto nível pode ser compilada usando metaprogramação para combinações das outras abstrações desenvolvidas no projeto, ou seja, esqueletos e kernels de alta ordem. Assim como as compreensões de listas das linguagens funcionais são implementadas através da tradução de sua notação, gerando uma composição de funções de alta ordem conhecidas, pretendemos demonstrar que as compreensões de arrays podem ser traduzidas para uma combinação de esqueletos e kernels de alta ordem, aplicando otimizações na composição desses esqueletos.
Objetivo 4: Abstração de alto-nível, Orquestração de Computações em GPU
As três abstrações propostas neste trabalho serão construídas utilizando uma composição vertical, onde os esqueletos são construídos através da composição de kernels de Alta-Ordem e a compreensão de vetores através da composição de esqueletos. Este trabalho pretende também permitir a composição horizontal dessas abstrações através de uma linguagem de orquestração, onde podemos ligar a saída de uma compreensão a entrada de um bloco de esqueletos, ou um vetor gerado por um kernel de alta ordem poderá ser transformado em um novo vetor através de uma compreensão, por exemplo. A linguagem de orquestração deve permitir ordenar e sincronizar a execução das computações na GPU. Durante a compilação da linguagem de orquestração, uma série de otimização estáticas e dinâmicas podem ser aplicadas na composição das abstrações a serem executadas na GPU.
Indicadores, Metas e Resultados
Pretende-se como resultado final deste projeto obter-se uma teoria sobre a construção de abstrações combináveis para a programação de GPUs usando metaprogramação, apoiada por um conjunto de bibliotecas, ferramentas e estudos de caso.
Cada um dos objetivos do projeto irá produzir, além de um estudo teórico, um protótipo e benchmarks relacionados. As abstrações a serem desenvolvidas, os KAOs, esqueletos, compreensão de vetores e a linguagem de orquestração, serão apoiadas por um estudo teórico de sua semântica e propriedades, além de um conjunto de ferramentas e benchmarks. Quando as abstrações estiverem disponíveis, pretende-se desenvolver dois estudos de caso mais longos, o primeiro seria uma biblioteca de redes neurais e o segundo um simulador de computação quântica. Todo o software desenvolvido ao longo do projeto estará disponível para a comunidade em um repositório público.
Como impacto na sociedade, além da divulgação científica dos resultados obtidos, a realização deste projeto formará também novos cientistas. Prevê-se o envolvimento de pelo menos 2 alunos de mestrado e 1 de doutorado, além de 3 alunos de IC e alunos de conclusão de curso.
Cada um dos objetivos do projeto irá produzir, além de um estudo teórico, um protótipo e benchmarks relacionados. As abstrações a serem desenvolvidas, os KAOs, esqueletos, compreensão de vetores e a linguagem de orquestração, serão apoiadas por um estudo teórico de sua semântica e propriedades, além de um conjunto de ferramentas e benchmarks. Quando as abstrações estiverem disponíveis, pretende-se desenvolver dois estudos de caso mais longos, o primeiro seria uma biblioteca de redes neurais e o segundo um simulador de computação quântica. Todo o software desenvolvido ao longo do projeto estará disponível para a comunidade em um repositório público.
Como impacto na sociedade, além da divulgação científica dos resultados obtidos, a realização deste projeto formará também novos cientistas. Prevê-se o envolvimento de pelo menos 2 alunos de mestrado e 1 de doutorado, além de 3 alunos de IC e alunos de conclusão de curso.
Equipe do Projeto
Nome | CH Semanal | Data inicial | Data final |
---|---|---|---|
ANDRE RAUBER DU BOIS | 30 | ||
FREDERICO PEIXOTO ANTUNES | |||
GERSON GERALDO HOMRICH CAVALHEIRO | 5 | ||
HENRIQUE GABRIEL RODRIGUES DA ROSA | |||
VINÍCIUS GARCIA PERUZZI |
Fontes Financiadoras
Sigla / Nome | Valor | Administrador |
---|---|---|
FAPERGS / Fundação de Amparo a Pesquisa do Estado Rio Grande do Sul | R$ 41.952,00 | Coordenador |
Plano de Aplicação de Despesas
Descrição | Valor |
---|---|
339030 - Material de Consumo | R$ 18.672,00 |
449052 - Equipamentos e Material Permanente | R$ 23.280,00 |