Occa: Solicitação de recurso: adicione a opção de parar o analisador para substituir as variáveis ​​definidas por seus valores

Criado em 29 jul. 2018  ·  10Comentários  ·  Fonte: libocca/occa

Atualmente, se p_N for definido como 5, quando um kernel for analisado e gerado, todas as instâncias de p_N serão substituídas por 5.

Seria útil adicionar uma opção de analisador para que os #defines sejam incluídos no código-fonte gerado e as variáveis ​​do compilador como p_N sejam deixadas no código-fonte gerado.

Isso tornará o código gerado muito mais fácil de ler.

feature parser

Comentários muito úteis

Isso soa razoável

Existem alguns recursos que precisarão ser adicionados primeiro

  • Crie variáveis ​​globais a partir de definições numéricas passadas como propriedades do kernel em vez de #define

    • :warning: Ser capaz de fazer isso para todos os #defines é muito difícil, pois precisaríamos rastrear onde eles são definidos e quais escopos eles tocam após as transformações

  • [Novo recurso] Durante parser::getExpression , substitua constexpr por seus valores

    • Inicialmente apenas variáveis const

    • Expandir para funções constexpr

  • Adicione de volta #define linhas ao topo como de costume

Todos 10 comentários

Infelizmente, todas as definições precisam ser expandidas para aplicar transformações de código
Os valores #define podem ser encontrados em dois lugares

raw_source.cpp

> head ~/.occa/cache/c8141715ac4e4272/raw_source.cpp 
#define  block 256

/* The MIT License (MIT)
 *

build.json

> cat ~/.occa/cache/c8141715ac4e4272/build.json | jq .kernel.props.defines
{
  "block": 256
}

Concordo que é útil fazer isso para extrair os limites de loop reais e imagino que o analisador foi projetado para fazer isso. No entanto, parece improvável que seja impossível preservar as definições no código. Manter o controle de como os valores são calculados evitaria a necessidade de imprimir seus valores numéricos.

É mais difícil do que parece manter o código e transformá-lo
Define pode ser qualquer coisa, mesmo código parcial

#define foo 3 +

for (int i = 0; i < foo 5; ++i) {}

Manter as linhas #define também pode causar problemas, pois o compilador ainda executará o pré-processador

... e se o Define for apenas uma constante numérica... ?

... e por que precisamos de lógica extra para isso ....?

Este é um exemplo do kernel de saída

extern "C" __global__ void _occa_ellipticPreconCoarsenHex3D_0(const int Nelements,
                                                              const double * __restrict__ R,
                                                              const double * __restrict__ qf,
                                                              double * __restrict__ qc) {
  {
    int e = 0 + blockIdx.x;
    __shared__ double s_qfff[8][8][8];
    __shared__ double s_qcff[2][8][8];
    __shared__ double s_qccf[2][2][8];
    __shared__ double s_qccc[2][2][2];
    __shared__ double s_R[2][8];
    {
      int k = 0 + threadIdx.z;
      {
        int j = 0 + threadIdx.y;
        {
          int i = 0 + threadIdx.x;
          const int id = i + j * 8 + k * 8 * 8 + e * 512;
          s_qfff[k][j][i] = qf[id];
          if ((k == 0) && (j < 2)) {
            s_R[j][i] = R[j * 8 + i];
          }
        }
      }
    }

Os kernels estão perdendo legibilidade na tradução. Todos esses números foram Definidos.

Dando um passo para trás, o motivo da solicitação de recurso foi

tornar o código gerado muito mais fácil de ler

O código gerado é destinado ao compilador, não aos usuários (semelhante às saídas pré-processadas pelo compilador). Se houver um problema de análise, especialmente porque o analisador ainda não está maduro, pode ser útil dar uma olhada. No entanto, esses problemas devem ser resolvidos ao longo do tempo.

Se o objetivo é facilitar a depuração, concordo que devemos adicionar #line para corresponder ao código-fonte original

Eu concordo que para depurar isso seria um verdadeiro bônus - boa ideia!

Eu deveria ter sido mais claro sobre o raciocínio por trás dessa solicitação: um caso de uso importante que imagino para as novas ferramentas de geração de código no OCCA 1.0 é como um tradutor de OKL para linguagem de encadeamento nativa para aplicativos não-OCCA. Nesse caso, será importante preservar a legibilidade, pois o código CUDA/OpenCL/HIP/OpenMP gerado será separado do código OKL.

Isso soa razoável

Existem alguns recursos que precisarão ser adicionados primeiro

  • Crie variáveis ​​globais a partir de definições numéricas passadas como propriedades do kernel em vez de #define

    • :warning: Ser capaz de fazer isso para todos os #defines é muito difícil, pois precisaríamos rastrear onde eles são definidos e quais escopos eles tocam após as transformações

  • [Novo recurso] Durante parser::getExpression , substitua constexpr por seus valores

    • Inicialmente apenas variáveis const

    • Expandir para funções constexpr

  • Adicione de volta #define linhas ao topo como de costume

Obrigado por contemplar a solicitação de recurso!

Esta página foi útil?
0 / 5 - 0 avaliações

Questões relacionadas

amikstcyr picture amikstcyr  ·  11Comentários

jeremylt picture jeremylt  ·  12Comentários

awehrfritz picture awehrfritz  ·  7Comentários

dmed256 picture dmed256  ·  4Comentários

tcew picture tcew  ·  22Comentários