O dialeto VHLO

Consulte vhlo_checklist.md para saber quais etapas seguir ao fazer alterações no VHLO.

O que é o dialeto VHLO?

O dialeto VHLO (Versioned StableHLO) é usado para serialização e estabilidade. Ele fornece um resumo do dialeto StableHLO em um determinado momento, fazendo a versão de elementos de programa individuais.

O VHLO é um dialeto de adição com operações, tipos e atributos versionados, o que significa que, depois que um recurso é adicionado ao dialeto, ele não pode ser modificado de nenhuma forma que afete a semântica.

Qualquer mudança em uma operação, tipo ou atributo exige que uma nova versão seja adicionada ao dialeto. Por exemplo, se um my_op hipotético fosse adicionado ao StableHLO em 0.9.0, mas mudado na versão 0.11.0, teríamos o seguinte em VHLO:

// This represents the StableHLO version of the op from 0.9.0 -> 0.10.0
// Both the lower and the upper bound of versions are inclusive
def VHLO_MyOpV1 : VHLO_Op<"my_op_v1", "0.9.0", "0.10.0"> {
  let arguments = (ins
    VHLO_AnyType:$operand
  );
  let results = (outs VHLO_AnyType:$result);
}

// This represents the StableHLO version of the op from 0.11.0 -> current
def VHLO_MyOpV2 : VHLO_Op<"my_op_v2", "0.11.0", "current"> {
  let arguments = (ins
    VHLO_AnyType:$operand,
    VHLO_AnyAttr:$attr  // New attribute added to StableHLO in 0.11.0
  );
  let results = (outs VHLO_AnyType:$result);
}

O dialeto StableHLO tem apenas a versão mais recente das operações. No exemplo em execução, o dialeto StableHLO na v0.11.0 teria apenas o StableHLO_MyOp que tem operand e attr, enquanto o VHLO captura cada fase da evolução da operação.

Por que o VHLO é útil?

Ter um dialeto com controle de versão permite segmentar versões anteriores da opset StableHLO. Isso encapsula a compatibilidade anterior e posterior em conversões entre operações no dialeto VHLO.

Compatibilidade com versões futuras:a compatibilidade com versões futuras é fornecida pela conversão para VHLO e pelo downgrade das operações para uma versão de destino. Se cada operação/tipo/atributo em um programa VHLO puder ser rebaixado para a versão de destino, ele será desserializável e convertível em StableHLO em um consumidor que execute uma versão maior ou igual à versão de destino, já que o VHLO tem um instantâneo do opset naquele momento.

Imagem de compatibilidade com versões futuras

Essa conversão de downgrade falhará se operações ou recursos que não existem na versão anterior da opset forem usados. Isso significa que a compatibilidade futura é descoberta no produtor, e não no momento de execução.

Compatibilidade com versões anteriores: a compatibilidade com versões anteriores é fornecida atualizando as operações VHLO para a versão mais recente (se necessário) e convertendo uma operação de volta para StableHLO. Todos os programas VHLO na janela de compatibilidade podem ser atualizados para o StableHLO, o que significa que diferentes versões dos consumidores podem desserializar o mesmo payload VHLO de uma versão anterior.

Imagem de compatibilidade com versões anteriores

Mais importante, o VHLO é abstrato por trás da serialização. Isso significa que os frameworks de ML (produtores) só precisam segmentar operações StableHLO, e os back-ends do compilador (consumidores) só precisam oferecer suporte à versão mais recente, que é o conjunto de operações StableHLO. As conversões de e para VHLO são feitas com máquinas mantidas no repositório StableHLO.

Versões do formato de bytecode do MLIR

Para manter a compatibilidade com versões futuras, as versões do StableHLO têm uma versão associada do formato MLIR Bytecode. Além disso, a versão mais recente do StableHLO vai usar a versão mais recente do formato de bytecode MLIR. Quando a versão do formato de bytecode do MLIR é incrementada, a próxima versão do StableHLO incrementa a versão secundária e atualiza Version.cpp para usar a versão mais recente do formato de bytecode do MLIR.

Para detalhes sobre o formato MLIR Bytecode e a lógica para usá-lo no StableHLO, consulte bytecode.md.