Forme e layout

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 a N-1 per una matrice dimensionale N. 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 protocollo Layout.

  • 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 dimensione A, la dimensione 1 ha dimensione B e la dimensione 2 ha dimensione C.

    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 dimensionale N). Ad esempio, per l'array tridimensionale descritto sopra, la dimensione -1 ha dimensione C, la dimensione -2 ha dimensione B 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
  • 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 esempio

    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 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.