Il protocollo Shape
XLA (xla_data.proto) descrive il ranking, la dimensione e il tipo di dati di un array N-dimensionale (array in breve).
Terminologia, notazione e convenzioni
Il rango di un array corrisponde al numero di dimensioni. Il ranking reale di un array rappresenta il numero di dimensioni che hanno una dimensione maggiore di 1.
Le dimensioni sono numerate da
0
fino aN-1
per una matrice dimensionaleN
. I numeri delle dimensioni sono etichette arbitrarie per praticità. L'ordine di questi numeri di dimensione non implica un particolare ordinamento minore/maggiore nel layout della forma. Il layout è determinato dal protocolloLayout
.Per convenzione, le dimensioni sono elencate in ordine crescente in base al numero. Ad esempio, per un array tridimensionale di dimensione
[A x B x C]
, la dimensione 0 ha dimensioneA
, la dimensione 1 ha dimensioneB
e la dimensione 2 ha dimensioneC
.Alcune utilità in XLA supportano anche l'indicizzazione negativa simile a Python: la dimensione -1 è l'ultima dimensione (equivalente a
N-1
per un array dimensionaleN
). Ad esempio, per l'array tridimensionale descritto sopra, la dimensione -1 ha dimensioneC
, la dimensione -2 ha dimensioneB
e così via.Gli array a due, tre e quattro dimensioni spesso hanno lettere specifiche associate alle dimensioni. Ad esempio, per un array 2D:
- dimensione 0:
y
- dimensione 1:
x
Per un array 3D:
- dimensione 0:
z
- dimensione 1:
y
- dimensione 2:
x
Per un array 4D:
- dimensione 0:
p
- dimensione 1:
z
- dimensione 2:
y
- dimensione 3:
x
- dimensione 0:
Le funzioni nell'API XLA che assumono dimensioni lo fanno in ordine crescente in base al numero di dimensione. Corrisponde all'ordine utilizzato per trasmettere le dimensioni come
initializer_list
; ad esempioShapeUtil::MakeShape(F32, {A, B, C, D})
creerà una forma il cui array di dimensioni delle dimensioni è costituito dalla sequenza
[A, B, C, D]
.
Layout
Il protocollo Layout
descrive come viene rappresentato un array in memoria. Il protocollo Layout
include i seguenti campi:
message Layout {
repeated int64 minor_to_major = 1;
repeated int64 padded_dimensions = 2;
optional PaddingValue padding_value = 3;
}
Ordine dimensione minore-maggiore
L'unico campo obbligatorio è minor_to_major
. Questo campo descrive l'ordinamento minore a maggiore delle dimensioni all'interno di una forma. I valori in minor_to_major
sono l'ordine delle dimensioni dell'array (da 0
a N-1
per un array dimensionale N
), in cui il primo valore corrisponde alla dimensione più minore fino all'ultimo, ovvero la dimensione più importante. La dimensione minore è quella che cambia più rapidamente quando si attraversano gli elementi dell'array disposti in memoria lineare.
Ad esempio, considera il seguente array 2D di dimensione [2 x 3]
:
a b c
d e f
Qui la dimensione 0
è la dimensione 2, mentre la dimensione 1
è la dimensione 3. Se il campo minor_to_major
nel layout è [0, 1]
, la dimensione 0
è la dimensione minore e la dimensione 1
è la dimensione più importante. Ciò corrisponde al seguente layout in memoria lineare:
a d b e c f
Questo ordine delle dimensioni da minore a maggiore di 0
fino a N-1
è simile a colonna maggiore (in ranking 2). Presumendo un ordine monotonico delle dimensioni, un altro modo in cui potremmo fare riferimento a questo layout nel codice è semplicemente "attenuato 0 è minore".
Se invece il campo minor_to_major
nel layout è [1, 0]
, il layout in memoria lineare sarà:
a b c d e f
Un ordine delle dimensioni da minore a maggiore di N-1
fino a 0
per un array dimensionale N
è simile a riga maggiore (in ranking 2). Supponendo un ordinamento monotonico delle dimensioni, un altro modo in cui possiamo fare riferimento a questo layout nel codice è semplicemente "attenuato 0 è maggiore".
Ordine predefinito da minore a maggiore
Il layout predefinito per le forme appena create è "l'ordine delle dimensioni è maggiore-inferiore" (simile alla riga maggiore nel ranking 2).
Spaziatura interna
La spaziatura interna è definita nei campi facoltativi padded_dimensions
e padding_value
. Il campo padded_dimensions
descrive le dimensioni (larghezze) in cui viene riempita ogni dimensione. Se presente, il numero di elementi in padded_dimensions
deve corrispondere al ranking della forma.
Ad esempio, dato l'array [2 x 3]
definito sopra, se padded_dimensions
è [3, 5]
, la dimensione 0 viene riempita con una larghezza di 3 e la dimensione 1 con una larghezza di 5. Il layout in memoria lineare (supponendo un valore di spaziatura interna pari a 0 e un layout maggiore della colonna) è:
a d 0 b e 0 c f 0 0 0 0 0 0 0
Equivale al layout del seguente array con lo stesso ordine delle dimensioni da minore a maggiore:
a b c 0 0
d e f 0 0
0 0 0 0 0
Indicizzazione in array
La classe IndexUtil
in index_util.h fornisce utilità per la conversione tra indici multidimensionali e indici lineari in base alla forma e al layout. Gli indici multidimensionali includono un indice int64
per ogni dimensione. Gli indici lineari sono un singolo valore int64
che indicizza nel buffer che contiene l'array. Visualizza shape_util.h
e
layout_util.h
nella stessa directory per accedere a utilità che semplificano la creazione e
la manipolazione di forme e layout.