Übertragung läuft

In diesem Dokument wird die Sendesemantik von XLA beschrieben.

Was ist „Nachricht an alle“?

Beim Broadcasting werden Arrays mit unterschiedlichen Formen zu kompatiblen Formen für arithmetische Operationen erstellt. Die Terminologie wurde aus dem NumPy-Broadcasting übernommen.

Broadcasting kann für Vorgänge zwischen mehrdimensionalen Arrays unterschiedlicher Ränge oder zwischen mehrdimensionalen Arrays mit unterschiedlichen, aber kompatiblen Formen erforderlich sein. Betrachten Sie die Addition X+v, wobei X eine Matrix (ein Array von Rang 2) und v ein Vektor (ein Array von Rang 1) ist. Zum Durchführen der elementweisen Addition muss XLA den Vektor v in denselben Rang wie die Matrix X übertragen, indem v eine bestimmte Anzahl von Malen repliziert. Die Länge des Vektors muss mit mindestens einer der Dimensionen der Matrix übereinstimmen.

Beispiel:

|1 2 3| + |7 8 9|
|4 5 6|

Die Dimensionen der Matrix sind (2,3) und die Dimension des Vektors ist (3). Der Vektor wird übertragen, indem er über Zeilen repliziert wird, um Folgendes zu erhalten:

|1 2 3| + |7 8 9| = |8  10 12|
|4 5 6|   |7 8 9|   |11 13 15|

In NumPy wird dies als Broadcasting bezeichnet.

Grundprinzip

Die XLA-Sprache ist so streng und explizit wie möglich und vermeidet implizite "magische" Features. Solche Funktionen machen einige Berechnungen möglicherweise etwas einfacher zu definieren, allerdings auf Kosten von mehr Annahmen, die in Nutzercode verankert sind und sich auf lange Sicht nur schwer ändern lassen. Bei Bedarf können implizite magische Merkmale in Wrapper auf Clientebene hinzugefügt werden.

In Bezug auf das Broadcasting verlangt XLA explizite Broadcasting-Spezifikationen für Operationen zwischen Arrays unterschiedlicher Ränge. Dies unterscheidet sich von NumPy, bei dem die Spezifikation nach Möglichkeit abgeleitet wird.

Übertragen eines Arrays mit einem niedrigeren Rang in ein Array mit einem höheren Rang

Skalare können immer über Arrays ohne explizite Spezifikation von Übertragungsdimensionen übertragen werden. Bei einer elementweisen binären Operation zwischen einem Skalar und einem Array wird die Operation mit dem Skalar auf jedes Element im Array angewendet. Wenn Sie beispielsweise einen Skalar zu einer Matrix hinzufügen, wird eine Matrix erzeugt, in der jedes Element die Summe des Skalars und des entsprechenden Elements der Eingabematrix ist.

|1 2 3| + 7 = |8  9  10|
|4 5 6|       |11 12 13|

Die meisten Übertragungsanforderungen können mithilfe eines Tupel von Dimensionen für eine binäre Operation erfasst werden. Wenn die Eingaben für die Operation unterschiedliche Ränge haben, gibt dieses Broadcasting-Tupel an, welche Dimensionen im Array higher-rank mit dem Array lower-rank übereinstimmen.

Betrachten Sie das vorherige Beispiel. Statt einer (2,3)-Matrix einen Skalar hinzuzufügen, fügen Sie einen Dimensionsvektor (3) zu einer Matrizen (2,3) hinzu. Ohne Angabe einer Broadcasting-Funktion ist dieser Vorgang ungültig. Um die Matrix-Vektor-Addition korrekt anzufordern, geben Sie die Sendedimension auf (1) an, d. h. die Dimension des Vektors wird mit der Dimension 1 der Matrix abgeglichen. Wenn in 2D die Dimension 0 für Zeilen und die Dimension 1 für Spalten steht, bedeutet dies, dass jedes Element des Vektors zu einer Spalte wird, deren Größe der Anzahl der Zeilen in der Matrix entspricht:

|7 8 9| ==> |7 8 9|
            |7 8 9|

Ein komplexeres Beispiel ist das Hinzufügen eines Vektors mit drei Elementen (Dimension (3)) zu einer 3x3-Matrix (Dimensionen (3, 3)). Bei diesem Beispiel gibt es zwei Möglichkeiten für die Übertragung:

(1) Für die Sendedimension kann „1“ verwendet werden. Jedes Vektorelement wird zu einer Spalte und der Vektor wird für jede Zeile in der Matrix dupliziert.

|7 8 9| ==> |7 8 9|
            |7 8 9|
            |7 8 9|

(2) Es kann eine Übertragungsdimension von 0 verwendet werden. Jedes Vektorelement wird zu einer Zeile und der Vektor wird für jede Spalte der Matrix dupliziert.

 |7| ==> |7 7 7|
 |8|     |8 8 8|
 |9|     |9 9 9|

Die Übertragungsdimensionen können ein Tupel sein, das beschreibt, wie eine kleinere Rangform in eine größere Rangform übertragen wird. Bei einem Quadrat mit 2 × 3 × 4 und einer 3 × 4-Matrix bedeutet ein sendendes Tupel (1,2) beispielsweise, dass die Matrix mit den Abmessungen 1 und 2 des Quaders abgeglichen wird.

Diese Art von Broadcast wird in den binären Vorgängen in XlaBuilder verwendet, wenn das Argument broadcast_dimensions angegeben ist. Ein Beispiel ist XlaBuilder::Add. Im XLA-Quellcode wird diese Art der Übertragung manchmal als „InDim“ bezeichnet.

Formale Definition

Das Broadcasting-Attribut ermöglicht den Abgleich eines Arrays mit einem niedrigeren Rang mit einem Array eines höheren Rangs, indem angegeben wird, welche Dimensionen des Arrays mit einem höheren Rang abgeglichen werden sollen. Beispielsweise kann bei einem Array mit den Dimensionen MxNxPxQ ein Vektor mit der Dimension T so abgeglichen werden:

          MxNxPxQ

dim 3:          T
dim 2:        T
dim 1:      T
dim 0:    T

In jedem Fall muss T der übereinstimmenden Dimension des höherrangigen Arrays entsprechen. Die Werte des Vektors werden dann von der übereinstimmenden Dimension an alle anderen Dimensionen übertragen.

Zum Abgleich einer TxV-Matrix mit dem MxNxPxQ-Array wird ein Paar von Übertragungsdimensionen verwendet:

          MxNxPxQ
dim 2,3:      T V
dim 1,2:    T V
dim 0,3:  T     V
etc...

Die Dimensionen im Tupel für die Übertragung müssen der Reihenfolge entsprechen, in der die Dimensionen des niedrigeren Arrays voraussichtlich mit den Dimensionen des höherrangigen Arrays übereinstimmen. Das erste Element im Tupel gibt an, welche Dimension im höherrangigen Array mit der Dimension 0 im niedrigeren Array übereinstimmen muss. Das zweite Element im Tupel gibt an, welche Dimension im höherrangigen Array mit Dimension 1 im niedrigeren Array übereinstimmen muss, und so weiter. Die Reihenfolge der Broadcast-Dimensionen muss strikt zunehmen. Im vorherigen Beispiel ist es beispielsweise nicht zulässig, V mit N und T mit P abzugleichen. Es ist auch nicht zulässig, V mit P und N abzugleichen.

Arrays mit ähnlichem Rang mit degenerierten Dimensionen übertragen

Ein verwandtes Problem besteht darin, zwei Arrays mit demselben Rang, aber unterschiedlichen Dimensionsgrößen zu übertragen. Wie bei NumPy ist dies nur möglich, wenn die Arrays kompatibel sind. Zwei Arrays sind kompatibel, wenn alle ihre Dimensionen kompatibel sind. Zwei Dimensionen sind in folgenden Fällen kompatibel:

  • Sie sind gleich oder
  • Eine davon ist „1“ (eine „degenerierte“ Dimension)

Wenn zwei kompatible Arrays vorhanden sind, hat die Ergebnisform bei jedem Dimensionsindex das Maximum der zwei Eingaben.

Beispiele:

  1. (2,1) und (2,3) übertragen an (2,3).
  2. (1,2,5) und (7,2,5) übertragen an (7,2,5).
  3. (7,2,5) und (7,1,5) übertragen an (7,2,5).
  4. (7,2,5) und (7,2,6) sind nicht kompatibel und können nicht übertragen werden.

In einem Sonderfall, der ebenfalls unterstützt wird, hat jedes Eingabearray eine degenerierte Dimension bei einem anderen Index. In diesem Fall ist das Ergebnis ein "äußerer Vorgang": (2,1) und (1,3) an (2,3) übertragen. Weitere Beispiele finden Sie in der NumPy-Dokumentation zum Broadcasting.

Komposition der Übertragung

Das Broadcasting eines niedrigeren Rangs an ein Array mit einem höheren Rang und das Senden mit degenerierten Dimensionen können beide im selben Binärvorgang durchgeführt werden. Beispielsweise können ein Vektor der Größe 4 und eine Matrix der Größe 1 x 2 mithilfe von Übertragungsdimensionen mit dem Wert 0 addiert werden:

|1 2 3 4| + [5 6]    // [5 6] is a 1x2 matrix, not a vector.

Zuerst wird der Vektor unter Verwendung der Broadcast-Dimensionen bis zu Rang 2 (Matrix) übertragen. Der einzelne Wert (0) in den Übertragungsdimensionen gibt an, dass die Dimension null des Vektors mit der Dimension null der Matrix übereinstimmt. Dies erzeugt eine Matrix der Größe 4xM, in der der Wert M so ausgewählt wird, dass er der entsprechenden Dimensionsgröße im 1x2-Array entspricht. Daher wird eine 4x2-Matrix erstellt:

|1 1| + [5 6]
|2 2|
|3 3|
|4 4|

Anschließend überträgt „Degenerate Dimension Broadcasting“ die Dimension null der 1x2-Matrix, um der entsprechenden Dimensionsgröße auf der rechten Seite zu entsprechen:

|1 1| + |5 6|     |6  7|
|2 2| + |5 6|  =  |7  8|
|3 3| + |5 6|     |8  9|
|4 4| + |5 6|     |9 10|

Ein komplizierteres Beispiel ist eine Matrix der Größe 1 x 2, die zu einem Array der Größe 4 x 3 x 1 mit Übertragungsabmessungen von (1, 2) hinzugefügt wird. Zuerst wird die 1x2-Matrix unter Verwendung der Übertragungsdimensionen bis zum Rang 3 übertragen, um ein Mx1x2-Zwischenarray zu erzeugen, wobei die Dimensionsgröße M durch die Größe des größeren Operanden (des 4x3x1-Arrays) bestimmt wird, wodurch ein 4x1x2-Zwischenarray entsteht. Das M befindet sich in der Dimension 0 (der Dimension ganz links), da die Dimensionen 1 und 2 den Dimensionen der ursprünglichen 1x2-Matrix zugeordnet werden, wie die Übertragungsdimensionen (1, 2) sind. Dieses Zwischenarray kann der 4x3x1-Matrix durch die Übertragung von degenerierten Dimensionen hinzugefügt werden, um ein 4x3x2-Arrayergebnis zu erzielen.