Formes et mise en page

Le proto Shape XLA (xla_data.proto) décrit le rang, la taille et le type de données d'un tableau à N dimensions (tableau en abrégé).

Terminologie, notation et conventions

  • Le rang d'un tableau est égal au nombre de dimensions. Le classement réel d'un tableau correspond au nombre de dimensions de taille supérieure à 1.

  • Les dimensions sont numérotées de 0 à N-1 pour un tableau de dimensions N. Pour plus de commodité, les numéros de dimension sont des libellés arbitraires. L'ordre de ces numéros de dimension n'implique pas d'ordre mineur/majeur particulier dans la mise en page de la forme. La mise en page est déterminée par le fichier .proto Layout.

  • Par convention, les dimensions sont répertoriées par ordre croissant de numéro de dimension. Par exemple, pour un tableau tridimensionnel de taille [A x B x C], la dimension 0 a la taille A, la dimension 1 a la taille B et la dimension 2 a la taille C.

    Certains utilitaires de XLA sont également compatibles avec l'indexation négative de type Python : "-1" est la dernière dimension (équivalent à N-1 pour un tableau de dimensions N). Par exemple, pour le tableau tridimensionnel décrit ci-dessus, la dimension -1 a la taille C, la dimension -2 a la taille B, etc.

  • Les tableaux à deux, trois et quatre dimensions comportent souvent des lettres spécifiques associées à des dimensions. Par exemple, pour un tableau bidimensionnel:

    • dimension 0: y
    • dimension 1: x

    Pour un tableau 3D:

    • dimension 0: z
    • dimension 1: y
    • dimension 2: x

    Pour un tableau 4D:

    • dimension 0: p
    • dimension 1: z
    • dimension 2: y
    • dimension 3: x
  • Les fonctions de l'API XLA qui prennent des dimensions le font par ordre croissant du numéro de dimension. Cet ordre correspond à l'ordre utilisé lors de la transmission des dimensions en tant que initializer_list. Par exemple,

    ShapeUtil::MakeShape(F32, {A, B, C, D})

    crée une forme dont le tableau de dimensions comprend la séquence [A, B, C, D].

Mise en page

Le fichier proto Layout décrit comment un tableau est représenté en mémoire. Le fichier proto Layout comprend les champs suivants:

message Layout {
  repeated int64 minor_to_major = 1;
  repeated int64 padded_dimensions = 2;
  optional PaddingValue padding_value = 3;
}

Ordre des dimensions mineures à majeures

Le seul champ obligatoire est minor_to_major. Ce champ décrit l'ordre mineur à majeur des dimensions dans une forme. Les valeurs dans minor_to_major correspondent à l'ordre des dimensions du tableau (de 0 à N-1 pour un tableau de dimensions N), la première valeur étant la dimension la plus mineure jusqu'à la dernière valeur, qui est la dimension la plus grande. La dimension la plus mineure est celle qui change le plus rapidement lors de l'exploration des éléments du tableau disposés en mémoire linéaire.

Prenons l'exemple du tableau 2D suivant, de taille [2 x 3]:

a b c
d e f

Ici, la dimension 0 correspond à la taille 2, et la dimension 1 à la taille 3. Si le champ minor_to_major dans la mise en page est [0, 1], la dimension 0 est la dimension la plus mineure et la dimension 1 est la dimension la plus importante. Cela correspond à la mise en page suivante en mémoire linéaire:

a d b e c f

Cet ordre des dimensions mineures à majeures (de 0 à N-1) s'apparente à celui de majeure de colonne (au rang 2). En supposant un ordre monotone des dimensions, une autre façon de faire référence à cette mise en page dans le code est simplement "dim 0 is minor" (la luminosité du 0 est mineure).

En revanche, si le champ minor_to_major de la mise en page est [1, 0], la mise en page en mémoire linéaire se présente comme suit:

a b c d e f

Un ordre de dimension mineur à majeur allant de N-1 à 0 pour un tableau de dimensions N s'apparente à ligne-major (au rang 2). En supposant un ordre monotone des dimensions, nous pouvons également nous référer à cette mise en page dans le code : "dim 0 is major" (la luminosité 0 est majeure).

Ordre par défaut (mineur à majeur)

La mise en page par défaut pour les formes nouvellement créées est "l'ordre des dimensions est de majeur à mineur" (similaire à celui des lignes principales au rang 2).

Marge intérieure

La marge intérieure est définie dans les champs facultatifs padded_dimensions et padding_value. Le champ padded_dimensions décrit les tailles (largeurs) auxquelles chaque dimension est complétée. S'il est présent, le nombre d'éléments dans padded_dimensions doit être égal au rang de la forme.

Par exemple, pour le tableau [2 x 3] défini ci-dessus, si padded_dimensions est [3, 5], la dimension 0 est complétée jusqu'à une largeur de 3, et la dimension 1 est complétée jusqu'à une largeur de 5. La mise en page en mémoire linéaire (en supposant une valeur de marge intérieure de 0 et une mise en page de type colonne majeure) est la suivante:

a d 0 b e 0 c f 0 0 0 0 0 0 0

Cela équivaut à la mise en page du tableau suivant avec le même ordre des dimensions mineures/majeures:

a b c 0 0
d e f 0 0
0 0 0 0 0

Indexation dans des tableaux

La classe IndexUtil dans index_util.h fournit des utilitaires permettant de convertir des index multidimensionnels et des indices linéaires en fonction d'une forme et d'une mise en page. Les index multidimensionnels incluent un indice int64 pour chaque dimension. Les index linéaires sont une valeur int64 unique qui indexe le tampon contenant le tableau. Consultez shape_util.h et layout_util.h dans le même répertoire pour connaître les utilitaires qui simplifient la création et la manipulation de formes et de mises en page.