Formen und Layout

Das XLA-Proto Shape (xla_data.proto) beschreibt den Rang, die Größe und den Datentyp eines n-dimensionalen Arrays (kurz Array).

Terminologie, Notation und Konventionen

  • Der Rang eines Arrays entspricht der Anzahl der Dimensionen. Der wahre Rang eines Arrays ist die Anzahl der Dimensionen, die eine Größe größer als 1 haben.

  • Bei einem N-dimensionalen Array werden die Dimensionen von 0 bis N-1 nummeriert. Die Dimensionsnummern sind willkürliche Bezeichnungen. Die Reihenfolge dieser Abmessungsnummern impliziert keine bestimmte Neben-/Hauptreihenfolge im Layout der Form. Das Layout wird vom Layout-Proto festgelegt.

  • Konventionsgemäß werden Dimensionen in aufsteigender Reihenfolge nach der Anzahl der Dimensionen aufgelistet. Bei einem dreidimensionalen Array der Größe [A x B x C] hat beispielsweise Dimension 0 die Größe A, Dimension 1 die Größe B und Dimension 2 die Größe C.

    Einige Dienstprogramme in XLA unterstützen auch eine Python-ähnliche negative Indexierung: Dimension -1 ist die letzte Dimension (entspricht N-1 für ein N-Dimensionsarray). Für das oben beschriebene dreidimensionale Array hat beispielsweise Dimension -1 die Größe C, Dimension -2 die Größe B usw.

  • Zwei-, drei- und vierdimensionale Arrays haben oft bestimmte Buchstaben, die den Dimensionen zugeordnet sind. Hier ein Beispiel für ein 2D-Array:

    • Dimension 0: y
    • Dimension 1: x

    Bei einem 3D-Array:

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

    Bei einem 4D-Array:

    • Dimension 0: p
    • Dimension 1: z
    • Dimension 2: y
    • Dimension 3: x
  • Funktionen in der XLA API, die Dimensionen annehmen, tun dies in aufsteigender Reihenfolge der Dimensionsnummer. Dies entspricht der Reihenfolge, die beim Übergeben von Dimensionen als initializer_list verwendet wird, z.B.

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

    erstellt eine Form, deren Dimensionsgröße aus der Reihenfolge [A, B, C, D] besteht.

Layout

Der Layout-Proto beschreibt, wie ein Array im Speicher dargestellt wird. Das Layout-Proto enthält die folgenden Felder:

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

Reihenfolge der kleinen und großen Dimensionen

Das einzige Pflichtfeld ist minor_to_major. In diesem Feld wird die kleinere bis große Reihenfolge der Dimensionen innerhalb einer Form beschrieben. Werte in minor_to_major sind eine Reihenfolge der Dimensionen des Arrays (0 bis N-1 für ein N-dimensionales Array), wobei der erste Wert die kleinste Dimension bis zum letzten Wert ist, also die größte Dimension. Die kleinste Dimension ist die Dimension, die sich am schnellsten ändert, wenn die Elemente des Arrays im linearen Speicher durchgegangen werden.

Betrachten Sie beispielsweise das folgende 2D-Array der Größe [2 x 3]:

a b c
d e f

Hier hat die Dimension 0 die Größe 2 und die Dimension 1 die Größe 3. Wenn das Feld minor_to_major im Layout [0, 1] ist, ist die Dimension 0 die kleinste Dimension und die Dimension 1 die größte. Dies entspricht dem folgenden Layout im linearen Speicher:

a d b e c f

Diese Abfolge von zwei Dimensionen (aufsteigend) von 0 bis N-1 entspricht dem von column-major (bei Rang 2). Bei einer monotonen Reihenfolge der Dimensionen ist dieses Layout im Code auch einfach „dim 0 ist klein“ zu bezeichnen.

Wenn andererseits das Feld minor_to_major im Layout [1, 0] ist, dann sieht das Layout im linearen Arbeitsspeicher so aus:

a b c d e f

Eine Reihenfolge von Neben- nach Major-Dimensionen von N-1 bis 0 für ein N-dimensionales Array entspricht dem Zeilen-Hauptbereich (Rang 2). Bei einer monotonen Abfolge von Dimensionen kann dieses Layout im Code auch einfach als „dim 0 is main“ bezeichnet werden.

Standardsortierung von Neben- bis Hauptschritten

Das Standardlayout für neu erstellte Formen lautet „Reihenfolge der Dimensionen ist Haupt-zu-Klein“ (ähnlich wie Zeilen-Haupt-Rang 2).

Abstand

Der Abstand wird in den optionalen Feldern padded_dimensions und padding_value definiert. Im Feld padded_dimensions werden die Größen (Breiten) beschrieben, auf die die einzelnen Dimensionen aufgefüllt werden. Falls vorhanden, muss die Anzahl der Elemente in padded_dimensions dem Rang der Form entsprechen.

Wenn bei dem oben definierten Array [2 x 3] beispielsweise padded_dimensions gleich [3, 5] ist, wird die Dimension 0 auf eine Breite von 3 und die Dimension 1 auf eine Breite von 5 aufgefüllt. Das Layout im linearen Speicher (bei einem Padding-Wert von 0 und einem Spalten-Hauptlayout) sieht so aus:

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

Dies entspricht dem Layout des folgenden Arrays mit derselben untergeordneten bis großen Dimensionsreihenfolge:

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

In Arrays indexieren

Die Klasse IndexUtil in index_util.h bietet Dienstprogramme zum Konvertieren zwischen mehrdimensionalen Indizes und linearen Indexen bei einer Form und einem Layout. Mehrdimensionale Indexe enthalten für jede Dimension einen int64-Index. Lineare Indexe sind ein einzelner int64-Wert, der in den Zwischenspeicher indexiert wird, der das Array enthält. Unter shape_util.h und layout_util.h finden Sie im selben Verzeichnis Dienstprogramme, die das Erstellen und Bearbeiten von Formen und Layouts vereinfachen.