Trasmissione in corso…

Questo documento descrive la semantica della trasmissione audio XLA.

Che cos'è la trasmissione?

La trasmissione è il processo con cui gli array con forme diverse hanno forme compatibili per le operazioni aritmetiche. La terminologia è presa in considerazione dalla trasmissione NumPy.

La trasmissione può essere necessaria per le operazioni tra array multidimensionali con ranking diversi o tra array multidimensionali con forme diverse ma compatibili. Considera l'addizione X+v dove X è una matrice (un array di ranking 2) e v è un vettore (un array di ranking 1). Per eseguire l'aggiunta in base agli elementi, XLA deve "trasmettere" il vettore v allo stesso ranking della matrice X, replicando v un determinato numero di volte. La lunghezza del vettore deve corrispondere ad almeno una delle dimensioni della matrice.

Ad esempio:

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

Le dimensioni della matrice sono (2,3), e la dimensione del vettore è (3). Il vettore viene trasmesso replicandolo sulle righe per ottenere:

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

In NumPy, questa procedura è chiamata trasmissione.

Princìpi

Il linguaggio XLA è il più rigoroso ed esplicito possibile, evitando caratteristiche "magiche" implicite. Queste funzionalità potrebbero semplificare la definizione di alcuni calcoli, ma a scapito di ulteriori ipotesi integrate nel codice utente che saranno difficili da modificare nel lungo termine. Se necessario, è possibile aggiungere caratteristiche magiche implicite in wrapper a livello di client.

Per quanto riguarda la trasmissione, XLA richiede specifiche di trasmissione esplicite sulle operazioni tra array di diversi livelli. È diverso da NumPy, che, se possibile, deduce la specifica.

Trasmissione di un array con ranking più basso a un array con ranking più alto

Gli scalar possono sempre essere trasmessi su array senza una specifica esplicita delle dimensioni di trasmissione. Un'operazione binaria a livello di elemento tra uno scalare e un array significa applicare l'operazione con lo scalare a ciascun elemento dell'array. Ad esempio, aggiungere uno scalare a una matrice significa produrre una matrice in cui ogni elemento è una somma dello scalare e dell'elemento corrispondente della matrice di input.

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

La maggior parte delle esigenze di trasmissione può essere acquisita utilizzando una tupla di dimensioni su un'operazione binaria. Quando gli input dell'operazione hanno ranking diversi, questa tupla di trasmissione specifica le dimensioni dell'array con ranking più elevato che corrispondono all'array di ranking più basso.

Considera l'esempio precedente. Invece di aggiungere uno scalare a una matrice (2,3), aggiungi un vettore di dimensione (3) a una matrice di dimensioni (2,3). Se non specifichi la trasmissione, questa operazione non è valida. Per richiedere correttamente l'aggiunta matrice-vettore, specifica che la dimensione di trasmissione deve essere (1), il che significa che la dimensione del vettore viene abbinata alla dimensione 1 della matrice. In 2D, se la dimensione 0 rappresenta righe e la dimensione 1 rappresenta le colonne, significa che ogni elemento del vettore diventa una colonna di dimensioni corrispondenti al numero di righe della matrice:

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

Come esempio più complesso, considera l'aggiunta di un vettore di 3 elementi (dimensione (3)) a una matrice 3x3 (dimensioni (3,3)). In questo esempio, ci sono due modi in cui può avvenire la trasmissione:

(1) È possibile usare una dimensione di trasmissione pari a 1. Ogni elemento vettoriale diventa una colonna e il vettore viene duplicato per ogni riga della matrice.

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

(2) È possibile utilizzare una dimensione di trasmissione pari a 0. Ogni elemento vettoriale diventa una riga e il vettore viene duplicato per ogni colonna della matrice.

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

Le dimensioni di trasmissione possono essere una tupla che descrive come una forma di ranking più piccola viene trasmessa in una forma di ranking più grande. Ad esempio, se una matrice cuboide 2x3x4 e una matrice 3x4, una tupla di trasmissione (1,2) indica l'abbinamento della matrice alle dimensioni 1 e 2 del cuboide.

Questo tipo di trasmissione viene utilizzato nelle operazioni binarie in XlaBuilder, se viene fornito l'argomento broadcast_dimensions. Ad esempio, consulta XlaBuilder::Add. Nel codice sorgente XLA, questo tipo di trasmissione a volte è chiamato "InDim".

Definizione formale

L'attributo broadcasting consente di abbinare un array con ranking più basso a un array con ranking più alto specificando le dimensioni dell'array con ranking più alto da abbinare. Ad esempio, per un array con dimensioni MxNxPxQ, un vettore con dimensione T può essere abbinato come segue:

          MxNxPxQ

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

In ogni caso, T deve essere uguale alla dimensione corrispondente dell'array con ranking più alto. I valori del vettore vengono quindi trasmessi dalla dimensione corrispondente a tutte le altre dimensioni.

Per associare una matrice TxV all'array MxNxPxQ, viene utilizzata una coppia di dimensioni di trasmissione:

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

L'ordine delle dimensioni nella tupla di trasmissione deve essere l'ordine in cui le dimensioni dell'array di ranking inferiore dovrebbero corrispondere a quelle dell'array con ranking più alto. Il primo elemento della tupla specifica quale dimensione nell'array con ranking più elevato deve corrispondere alla dimensione 0 nell'array con ranking più basso. Il secondo elemento nella tupla specifica quale dimensione nell'array con ranking più alto deve corrispondere alla dimensione 1 nell'array con ranking più basso e così via. L'ordine delle dimensioni di trasmissione deve essere rigorosamente crescente. Ad esempio, nell'esempio precedente è illegale abbinare V a N e T a P; è anche illegale abbinare V a P e N.

Trasmissione di array con ranking simile con dimensioni degenerate

Un problema correlato è la trasmissione di due array con lo stesso ranking, ma con dimensioni di dimensioni diverse. Come con NumPy, questo è possibile solo quando gli array sono compatibili. Due array sono compatibili quando tutte le loro dimensioni sono compatibili. Due dimensioni sono compatibili se:

  • Sono uguali o
  • Una di queste è 1 (una dimensione "degenerata")

Quando vengono rilevati due array compatibili, la forma del risultato ha il massimo dei due input in ogni indice di dimensione.

Esempi:

  1. (2,1) e (2,3) trasmettono in (2,3).
  2. (1,2,5) e (7,2,5) trasmettere a (7,2,5).
  3. (7,2,5) e (7,1,5) trasmettere a (7,2,5).
  4. (7,2,5) e (7,2,6) non sono compatibili e non possono essere trasmessi.

Esiste un caso speciale (anche supportato) in cui ciascuna delle matrici di input ha una dimensione degenerata in un indice diverso. In questo caso, il risultato è un'"operazione esterna": (2,1) e (1,3) broadcast verso (2,3). Per altri esempi, consulta la documentazione di NumPy sulla trasmissione.

Composizione per trasmissioni

La trasmissione di un array di ranking più basso a un array di ranking più alto e la trasmissione utilizzando dimensioni degenerate possono essere entrambe eseguite nella stessa operazione binaria. Ad esempio, un vettore di dimensione 4 e una matrice di dimensioni 1 x 2 possono essere sommati utilizzando le dimensioni di trasmissione del valore (0):

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

Innanzitutto, il vettore viene trasmesso fino al ranking 2 (matrice) utilizzando le dimensioni di trasmissione. Il valore singolo (0) nelle dimensioni di trasmissione indica che la dimensione zero del vettore corrisponde alla dimensione zero della matrice. Ciò produce una matrice di dimensione 4 x M in cui il valore M viene scelto in base alla dimensione della dimensione corrispondente nell'array 1 x 2. Si ottiene quindi una matrice 4x2:

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

Successivamente, "degenera la trasmissione delle dimensioni", trasmette la dimensione zero della matrice 1x2 in modo che corrisponda alla dimensione della dimensione corrispondente sul lato destro:

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

Un esempio più complicato è una matrice di dimensioni 1 x 2 aggiunta a un array di dimensioni 4 x 3 x 1 utilizzando dimensioni di trasmissione di (1, 2). Innanzitutto, la matrice 1x2 viene trasmessa fino al rango 3 utilizzando le dimensioni di trasmissione per produrre un array Mx1x2 intermedio in cui la dimensione M è determinata dalla dimensione dell'operando più grande (l'array 4x3x1) che produce un array intermedio 4x1x2. La M si trova alla dimensione 0 (la dimensione più a sinistra) perché le dimensioni 1 e 2 sono mappate alle dimensioni della matrice 1x2 originale come le dimensioni di trasmissione (1, 2). Questo array intermedio può essere aggiunto alla matrice 4 x 3 x 1 utilizzando la trasmissione di dimensioni degenerate per produrre un risultato dell'array 4 x 3 x 2.