Il proto Shape
XLA (xla_data.proto) descrive ranking, dimensioni e tipo di dati di un array N-dimensionale (array in breve).
Terminologia, notazione e convenzioni
Il rango di una matrice corrisponde al numero di dimensioni. Il ranking reale di un array è il numero di dimensioni che hanno una dimensione maggiore di 1.
Le dimensioni sono numerate da
0
fino aN-1
per una matrice dimensionaleN
. Per praticità, i numeri delle dimensioni sono etichette arbitrarie. 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 di tipo 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
, dimensione -2 ha dimensioneB
e così via.Gli array due, tre e quattro dimensionali 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 dell'API XLA che assumono dimensioni lo fanno in ordine crescente del numero di dimensione. Corrisponde all'ordine utilizzato per trasmettere le dimensioni come
initializer_list
; ad es.ShapeUtil::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 proto Layout
descrive il modo in cui un array viene rappresentato 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 delle dimensioni da minore a maggiore
L'unico campo obbligatorio è minor_to_major
. Questo campo descrive l'ordinamento minore-maggiore delle dimensioni all'interno di una forma. I valori in minor_to_major
sono un ordine delle dimensioni dell'array (da 0
a N-1
per un array dimensionale N
), dove il primo valore è la dimensione minore fino all'ultimo, che corrisponde alla dimensione maggiore. La dimensione più 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
In questo caso, la dimensione 0
corrisponde alla dimensione 2, mentre la dimensione 1
corrisponde alla 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 di dimensioni da minore a maggiore, compreso tra 0
e N-1
, è simile alla dimensione colonna maggiore (ranking 2). Presumendo un ordine monotonico delle dimensioni, un altro modo in cui possiamo fare riferimento a questo layout nel codice è semplicemente "dim 0 è minore".
Se invece il campo minor_to_major
nel layout è [1, 0]
, il layout in memoria lineare è:
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 alla riga maggiore (al ranking 2). Supponendo che le dimensioni siano un ordine monotonico, un altro modo in cui potremmo riferirci a questo layout nel codice è semplicemente "dim 0 è maggiore".
Ordine predefinito da minore a maggiore
Il layout predefinito per le forme appena create è "l'ordine delle dimensioni è da maggiore a minore" (simile alla riga maggiore al 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 aggiunta ogni dimensione. Se presente, il numero di elementi in padded_dimensions
deve corrispondere al rango della forma.
Ad esempio, dato l'array [2 x 3]
definito sopra, se padded_dimensions
è [3, 5]
, la dimensione 0 viene riempita fino a una larghezza di 3 e la dimensione 1 viene riempita fino a una larghezza di 5. Il layout in memoria lineare (presupponendo un valore di spaziatura interna pari a 0 e un layout colonna principale) è:
a d 0 b e 0 c f 0 0 0 0 0 0 0
Ciò 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 a una forma e a un layout. Gli indici multidimensionali includono un indice int64
per ogni dimensione. Gli indici lineari sono un singolo valore int64
che viene indicizzato nel buffer che contiene l'array. Visualizza shape_util.h
e layout_util.h
nella stessa directory per utilità che semplificano la creazione e la gestione di forme e layout.