Formen und Layout

Das XLA-Proto Shape (xla_data.proto) beschreibt Rang, Größe und 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 sind die Dimensionen von 0 bis N-1 nummeriert. Die Dimensionsnummern sind willkürliche Bezeichnungen. Die Reihenfolge dieser Abmessungsnummern impliziert keine bestimmte Neben-/Hauptanordnung im Layout der Form. Das Layout wird vom Proto Layout bestimmt.

  • Konventionsgemäß werden Dimensionen in aufsteigender Reihenfolge nach der Nummer der Dimension aufgeführt. 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 die Python-ähnliche negative Indexierung: Dimension -1 ist die letzte Dimension (entspricht N-1 für ein N-dimensionales Array). Bei dem oben beschriebenen dreidimensionalen Array hat beispielsweise Dimension -1 die Größe C, Dimension -2 die Größe B usw.

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

    • Dimension 0: y
    • Dimension 1: x

    Für ein 3D-Array:

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

    Für ein 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. Sie entspricht der Reihenfolge, die beim Übergeben von Dimensionen als initializer_list verwendet wird. Beispiel:

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

    erstellt eine Form, deren Dimensionsgrößen-Array aus der Sequenz [A, B, C, D] besteht.

Layout

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

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

Sortierung von kleineren nach großen Dimensionen

Das einzige Pflichtfeld ist minor_to_major. In diesem Feld wird die Minor-to-Major-Reihenfolge der Abmessungen innerhalb einer Form beschrieben. Die Werte in minor_to_major sind eine Reihenfolge der Dimensionen des Arrays (0 bis N-1 bei einem N-dimensionalen Array), wobei der erste Wert die kleinste Dimension bis zum letzten Wert ist, also die wichtigste Dimension. Die kleinste Dimension ist die Dimension, die sich am schnellsten ändert, wenn Sie die Elemente des Arrays im linearen Speicher durchgehen.

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 wichtigste Dimension. Dies entspricht dem folgenden Layout im linearen Speicher:

a d b e c f

Diese Nebeneinander-Hauptdimensionsreihenfolge von 0 bis N-1 entspricht column-major (auf Rang 2). Bei einer monotonen Reihenfolge der Dimensionen können wir dieses Layout im Code auch einfach als „dim 0 ist Minor“ bezeichnen.

Wenn dagegen das Feld minor_to_major im Layout [1, 0] ist, sieht das Layout im linearen Speicher so aus:

a b c d e f

Eine kleinere nach großen Dimensionsreihenfolge von N-1 bis 0 für ein N-dimensionales Array entspricht Zeilenmajor (auf Rang 2). Bei einer monotonen Abfolge von Dimensionen können wir dieses Layout im Code auch einfach als „dim 0 is main“ bezeichnen.

Standardreihenfolge von Neben- bis Hauptschritten

Das Standardlayout für neu erstellte Formen lautet „Dimensionsreihenfolge ist Haupt-zu-Kleiner“ (ähnlich dem Zeilen-Hauptbereich auf Rang 2).

Abstand

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

Wenn beispielsweise bei dem oben definierten [2 x 3]-Array padded_dimensions gleich [3, 5] ist, wird Dimension 0 auf eine Breite von 3 und Dimension 1 auf eine Breite von 5 aufgefüllt. Das Layout im linearen Speicher (bei einem Padding-Wert von 0 und einem Layout des Spaltenhaupts) 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 Minor-to-Major-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 Indizes anhand einer Form und eines Layouts. Mehrdimensionale Indexe umfassen einen int64-Index für jede Dimension. Lineare Indexe sind einzelne int64-Werte, die in den Zwischenspeicher mit dem Array indexiert werden. Unter shape_util.h und layout_util.h im selben Verzeichnis finden Sie Dienstprogramme, die das Erstellen und Bearbeiten von Formen und Layouts vereinfachen.