Ü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 vom NumPy-Broadcasting übernommen.

Für Vorgänge zwischen mehrdimensionalen Arrays unterschiedlicher Ränge oder zwischen mehrdimensionalen Arrays mit unterschiedlichen, aber kompatiblen Formen kann Broadcasting 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. Für die elementweise 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 können einige Berechnungen etwas einfacher definieren, allerdings auf Kosten von weiteren Annahmen, die in den Nutzercode verankert sind und sich auf lange Sicht nur schwer ändern lassen. Bei Bedarf können implizite magische Funktionen in Wrappern auf Clientebene hinzugefügt werden.

In Bezug auf das Broadcasting erfordert XLA explizite Übertragungsspezifikationen für Operationen zwischen Arrays unterschiedlicher Ränge. Dies unterscheidet sich von NumPy, das die Spezifikation nach Möglichkeit ableitet.

Ein Array niedrigerer Stufe an ein Array mit einem höheren Rang übertragen

Skalare können immer über Arrays ohne ausdrückliche Spezifikation von Übertragungsdimensionen übertragen werden. Eine elementweise binäre Operation zwischen einem Skalar und einem Array bedeutet, dass die Operation mit dem Skalar auf jedes Element im Array angewendet wird. 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 Tupels von Dimensionen bei einem binären Vorgang 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 lower-rank-Array übereinstimmen sollen.

Nehmen wir das vorherige Beispiel. Anstatt einen Skalar zu einer (2,3)-Matrix hinzuzufügen, fügen Sie einen Dimensionsvektor (3) zu einer Matrix aus Dimensionen (2,3) hinzu. Ohne Angabe einer Broadcasting-Funktion ist dieser Vorgang ungültig. Damit der Matrixvektor korrekt hinzugefügt werden kann, muss als Sendedimension (1) angegeben werden, d. h., die Dimension des Vektors wird der Dimension 1 der Matrix zugeordnet. 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|

Für ein komplexeres Beispiel könnten Sie einen Vektor mit drei Elementen (Dimension (3)) zu einer 3x3-Matrix (Dimensionen (3,3)) hinzufügen. Für dieses Beispiel gibt es zwei Möglichkeiten für die Übertragung:

(1) Die Sendedimension 1 kann 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) Die Sendedimension 0 kann verwendet werden. Jedes Vektorelement wird zu einer Zeile und der Vektor wird für jede Spalte in der Matrix dupliziert.

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

Die Broadcasting-Dimensionen können ein Tupel sein, das beschreibt, wie eine kleinere Rangform in eine größere Rangform übertragen wird. Bei einem 2x3x4-Quadrat und einer 3x4-Matrix bedeutet ein Übertragungs-Tupel (1,2) beispielsweise, dass die Matrix mit den Dimensionen 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 finden Sie unter XlaBuilder::Add. Im XLA-Quellcode wird diese Art der Übertragung manchmal als "InDim" bezeichnet.

Formelle Definition

Mit dem Broadcasting-Attribut kann ein Array niedrigerer Rangfolge mit einem Array eines höheren Rangs abgeglichen werden, indem angegeben wird, welche Dimensionen des Arrays mit dem höheren Rang übereinstimmen sollen. Bei einem Array mit den Dimensionen MxNxPxQ kann beispielsweise 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 passenden Dimension des höherrangigen Arrays entsprechen. Die Werte des Vektors werden dann von der übereinstimmenden Dimension an alle anderen Dimensionen übertragen.

Zum Abgleichen 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 Reihenfolge der Dimensionen im Übertragungs-Tupel muss 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 Rang übereinstimmen muss. Das zweite Element im Tupel gibt an, welche Dimension im höherrangigen Array mit der Dimension 1 im niedrigeren Rang übereinstimmen muss, usw. Die Reihenfolge der Broadcast-Dimensionen muss stark steigen. 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 ähnliches 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 gefunden werden, hat die Ergebnisform bei jedem Dimensionsindex das Maximum der beiden Eingaben.

Beispiele:

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

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

Zusammensetzung der Übertragung

Das Broadcasting eines niedrigeren Arrays an ein Array mit einem höheren Rang und das Broadcasting mit degenerierten Dimensionen können beide in demselben Binärvorgang durchgeführt werden. Zum Beispiel können ein Vektor der Größe 4 und eine Matrix der Größe 1 x 2 mithilfe von Broadcast-Dimensionen des Werts (0) addiert werden:

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

Zuerst wird der Vektor mithilfe der Broadcast-Dimensionen bis zu Rang 2 (Matrix) übertragen. Der einzelne Wert (0) in den Broadcast-Dimensionen gibt an, dass die Dimension null des Vektors mit der Dimension null der Matrix übereinstimmt. Dies erzeugt eine Matrix der Größe 4xM, wobei 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 wird über „Degenerate Dimensions Broadcasting“ die Dimension null der 1x2-Matrix gesendet, um sie an die entsprechende Dimensionsgröße auf der rechten Seite anzupassen:

|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 1x2, die zu einem Array der Größe 4x3x1 mit Broadcast-Dimensionen von (1, 2) hinzugefügt wird. Zuerst wird die 1x2-Matrix unter Verwendung der Broadcast-Dimensionen bis zu 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 erzeugt wird. M befindet sich an der Dimension 0 (die Dimension ganz links), da die Dimensionen 1 und 2 den Dimensionen der ursprünglichen 1x2-Matrix zugeordnet werden, wie die Broadcast-Dimensionen (1, 2) sind. Dieses Zwischenarray kann der 4x3x1-Matrix durch Übertragung von degenerierten Dimensionen hinzugefügt werden, um ein 4x3x2-Arrayergebnis zu erzeugen.