Compatibilidad con StableHLO

StableHLO es un conjunto de operaciones de procesamiento de AA retrocompatible inspirado en HLO/MHLO. En este documento, se explican el tipo y el alcance de las garantías de compatibilidad que proporciona StableHLO, según el proceso establecido en la RFC de compatibilidad.

Versiones

La versión actual de StableHLO se puede encontrar en Version.h.

En la serie 0.x.x, la versión secundaria se transmite cada vez que se realizan cambios en el conjunto de operaciones StableHLO o el formato de serialización StableHLO, y la versión de parche se actualiza cada vez que integramos StableHLO en sentido descendente, es decir, en el repositorio de openxla/xla.

Garantías

6 meses de retrocompatibilidad: los artefactos portátiles serializados por una versión anterior de libStablehlo tienen la misma semántica* cuando se deserializan mediante una versión nueva de libStablehlo si estas versiones se compilan a partir de confirmaciones de openxla/stablehlo con menos de 6 meses de diferencia.

1 mes de compatibilidad posterior: Los artefactos portátiles serializados por una versión nueva de libStablehlo tienen la misma semántica* cuando se deserializan mediante una versión anterior de libStablehlo si estas versiones se compilan a partir de confirmaciones de openxla/stablehlo con menos de 1 mes de diferencia, a menos que el programa use funciones nuevas que se introdujeron desde la versión anterior.

* Los programas StableHLO se convierten en y desde artefactos portátiles a través de las APIs de compatibilidad, y la especificación de StableHLO define la semántica de estos programas. Consulta la sección "Fuera del alcance" para ver ejemplos de lo que no se incluye en esta definición de compatibilidad.

APIs

Se pueden crear artefactos portátiles con la herramienta stablehlo-translate o directamente en las APIs de C++ o Python. La serialización necesita una versión de destino de StableHLO para escribir un artefacto escrito en formato #.#.# (consulta Version.h para ver la versión actual). La deserialización usa la versión actual de StableHLO para leer un artefacto.

stablehlo-translate

Esta es la forma más fácil de crear y leer un artefacto portátil.

# Write a StableHLO program to a portable artifact
$ stablehlo-translate --serialize file.mlir --target=0.9.0 > portable_artifact.mlir.bc

# Read StableHLO portable artifact
$ stablehlo-translate --deserialize portable_artifact.mlir.bc

C++

Para los flujos de trabajo programáticos, StableHLO proporciona las siguientes APIs de compatibilidad:

// From: #include "stablehlo/api/PortableApi.h"

// Get the current StableHLO version.
//
// This value can be used as the `targetVersion` argument to
// `serializePortableArtifact`.
std::string getCurrentVersion();

// Get the minimum supported StableHLO version.
//
// This value can be used as the `targetVersion` argument to
// `serializePortableArtifact`.
std::string getMinimumVersion();

// From: #include "stablehlo/dialect/Serialization.h"

// Write a StableHLO program to a portable artifact
// Writes a stable payload for `module` to `os`. If compatibility with a
// previous version of StableHLO is required, provide the required version
// string `#.#.#` for `targetVersion`.
//
// Can fail if `module` cannot be expressed in the `targetVersion` version of
// StableHLO, e.g. if it's using new or removed features, or if it involves
// unsupported dialects.
LogicalResult serializePortableArtifact(ModuleOp module,
                                        StringRef targetVersion,
                                        raw_ostream& os);

// Read StableHLO portable artifact
//
// Can fail if `sourceStr` cannot be expressed in the current version of
// StableHLO, e.g. if it's using incompatible features. Returns nullptr if
// `sourceStr` is invalid or fails to deserialize.
OwningOpRef<ModuleOp> deserializePortableArtifact(StringRef sourceStr,
                                                  MLIRContext* context);

Consulta stablehlo/api/PortableApi.h y stablehlo/dialect/Serialization.h para ver las API completas.

Consulta StablehloTranslateMain.cpp para ver un ejemplo del uso de estas APIs.

Python

StableHLO también proporciona vinculaciones de Python a las API compatibles con C++:

def get_current_version() -> str: ...
def get_minimum_version() -> str: ...
def serialize_portable_artifact(module: ir.Module, target_version: str) -> bytes: ...
def serialize_portable_artifact(module: str, target_version: str) -> bytes: ...
def deserialize_portable_artifact(context: ir.Context, artifact: bytes) -> ir.Module: ...
def deserialize_portable_artifact(artifact: bytes) -> str: ...

Consulta StablehloModule.cpp para ver las API completas de Python.

Consulta stablehlo.py > test_serialization_apis para obtener ejemplos de ida y vuelta sobre el uso de las APIs de serialización de Python.

Pruebas

Tenemos un paquete de compatibilidad en stablehlo/pruebas que incluye un compendio completo de operaciones de StableHLO serializado para todas las versiones de StableHLO compatibles. Para cada solicitud de extracción, probamos la compatibilidad con versiones anteriores y posteriores, es decir, que se puede deserializar el paquete orientado a HEAD (compatibilidad con versiones anteriores), que el compendio se puede serializar con todas las versiones de StableHLO compatibles (compatibilidad con versiones posteriores) y que los resultados son sintácticamente idénticos a los programas StableHLO originales.

Trabajo futuro

Crea un paquete de compatibilidad en MLIR ascendente: Con los aprendizajes de establecer y mantener las garantías de StableHLO, planeamos aportar un paquete de compatibilidad en sentido ascendente con MLIR para proporcionar detección temprana de fallas de compatibilidad accidentales en la infraestructura de código de bytes MLIR (#1632).

Usa la implementación de referencias: Por el momento, las pruebas de compatibilidad consisten en deserializar el conjunto de compatibilidad serializado por versiones anteriores de libStablehlo y asegurarse de que produzca programas sintácticamente idénticos. También planeamos usar una implementación de referencia en estas pruebas para flexibilizar el requisito demasiado molesto de la identidad sintáctica y probar de manera exhaustiva la implementación de referencia (#1245).

Fuera del alcance

Artefactos no portátiles: Las garantías de compatibilidad solo se proporcionan para artefactos portátiles creados de una manera muy específica. Otros tipos de artefactos, p.ej., una representación con formato estilístico del dialecto StableHLO o incluso la representación en código de bytes del dialecto StableHLO, no tienen garantías de compatibilidad.

Funciones no especificadas: Es posible que hagamos cambios incompatibles en las funciones que históricamente se admiten en los programas StableHLO, pero que aún no forman parte de la especificación de StableHLO. P. ej., no proporcionamos garantías de compatibilidad para atributos no registrados.

Compatibilidad con errores: Es posible que realicemos cambios incompatibles si la implementación en libStablehlo contradice la especificación StableHLO; p.ej., si una definición en el dialecto VHLO es incorrecta o si un verificador del dialecto StableHLO no coincide con la especificación.

Precisión numérica: StableHLO tiene varias operaciones que tienen exactitud definida por la implementación entre los consumidores y, además, dentro del mismo consumidor en distintas versiones. Como resultado, StableHLO no pretende ofrecer garantías sobre la exactitud numérica, aunque esto puede cambiar en el futuro (#1156).

La compatibilidad de origen para las APIs de C, C++ y Python dentro de libStablehlo es un objetivo ambicioso. Por el momento, no ofrecemos garantías de compatibilidad de fuente, pero avísanos si este es un caso de uso importante para ti, y podremos conversar sobre su compatibilidad (#1247).