El proto Shape
de XLA (xla_data.proto) describe el rango, el tamaño y el tipo de datos de un arreglo de n dimensiones (arreglo en resumen).
Terminología, notación y convenciones
El rango de un array es igual a la cantidad de dimensiones. La clasificación real de un array es la cantidad de dimensiones que tienen un tamaño mayor que 1.
Para un array de dimensiones
N
, las dimensiones están numeradas desde0
hastaN-1
. Los números de dimensión son etiquetas arbitrarias por conveniencia. El orden de estos números de dimensión no implica un orden menor o mayor particular en el diseño de la forma. El diseño está determinado por el protocoloLayout
.Por convención, las dimensiones se enumeran en orden creciente del número de dimensión. Por ejemplo, para un array tridimensional de tamaño
[A x B x C]
, la dimensión 0 tiene el tamañoA
, la dimensión 1 tiene el tamañoB
y la dimensión 2 tiene el tamañoC
.Algunas utilidades de XLA también admiten la indexación negativa similar a Python: la dimensión -1 es la última dimensión (equivalente a
N-1
para un array de dimensionesN
). Por ejemplo, para el array de 3 dimensiones descrito anteriormente, la dimensión -1 tiene el tamañoC
, la dimensión -2 tiene el tamañoB
, y así sucesivamente.Los arrays de dos, tres y cuatro dimensiones suelen tener letras específicas asociadas con dimensiones. Por ejemplo, para un array en 2D:
- dimensión 0:
y
- dimensión 1:
x
Para un array 3D:
- dimensión 0:
z
- dimensión 1:
y
- dimensión 2:
x
Para un array en 4D:
- dimensión 0:
p
- dimensión 1:
z
- dimensión 2:
y
- dimensión 3:
x
- dimensión 0:
Las funciones en la API de XLA que toman dimensiones lo hacen en orden creciente del número de dimensión. Coincide con el orden que se usa cuando se pasan dimensiones como
initializer_list
; p.ej.,ShapeUtil::MakeShape(F32, {A, B, C, D})
Esto creará una forma cuyo array de tamaño de dimensión consta de la secuencia
[A, B, C, D]
.
Diseño
El proto Layout
describe cómo se representa un array en la memoria. El protocolo Layout
incluye los siguientes campos:
message Layout {
repeated int64 minor_to_major = 1;
repeated int64 padded_dimensions = 2;
optional PaddingValue padding_value = 3;
}
Orden de dimensión menor a mayor
El único campo obligatorio es minor_to_major
. Este campo describe el orden de menor a mayor de las dimensiones dentro de una forma. Los valores en minor_to_major
son un orden de las dimensiones del array (de 0
a N-1
para un array dimensional N
). El primer valor es la dimensión más secundaria hasta el último valor, que es la dimensión más importante. La dimensión más secundaria es la dimensión que cambia más rápido cuando se recorren los elementos del array dispuestos en la memoria lineal.
Por ejemplo, considera el siguiente array 2D de tamaño [2 x 3]
:
a b c
d e f
Aquí la dimensión 0
es el tamaño 2 y la dimensión 1
es el tamaño 3. Si el campo minor_to_major
del diseño es [0, 1]
, la dimensión 0
es la más menor y la dimensión 1
es la más importante. Esto corresponde al siguiente diseño en la memoria lineal:
a d b e c f
Este orden de dimensión menor a mayor de 0
hasta N-1
es similar a columna mayor (en el rango 2). Suponiendo que las dimensiones tienen un orden monótono, otra forma en la que podemos referirnos a este diseño en el código es simplemente "atenuación 0 es menor".
Por otro lado, si el campo minor_to_major
del diseño es [1, 0]
, el diseño en la memoria lineal será el siguiente:
a b c d e f
Un orden de dimensión menor a mayor de N-1
a 0
para un array de dimensiones N
es similar a fila mayor (en el rango 2). Suponiendo que el orden de las dimensiones es monótono, otra forma en la que podemos referirnos a este diseño en el código es simplemente "la atenuación 0 es mayor".
Orden predeterminado de menor a mayor
El diseño predeterminado para las formas nuevas es "el orden de dimensión es mayor a menor" (similar a la fila mayor en el rango 2).
Padding
El relleno se define en los campos opcionales padded_dimensions
y padding_value
. El campo padded_dimensions
describe los tamaños (anchos) con los que se rellena cada dimensión. Si está presente, la cantidad de elementos en padded_dimensions
debe ser igual al rango de la forma.
Por ejemplo, dado el array [2 x 3]
definido anteriormente, si padded_dimensions
es [3, 5]
, la dimensión 0 se rellenará a un ancho de 3 y la dimensión 1 se rellenará hasta un ancho de 5. El diseño en la memoria lineal (suponiendo un valor de padding de 0 y un diseño de columna principal) es el siguiente:
a d 0 b e 0 c f 0 0 0 0 0 0 0
Esto equivale al diseño del siguiente array con el mismo orden de dimensión menor a mayor:
a b c 0 0
d e f 0 0
0 0 0 0 0
Indexa en arrays
La clase IndexUtil
de index_util.h proporciona utilidades para la conversión entre índices multidimensionales e índices lineales en función de una forma y un diseño. Los índices multidimensionales incluyen un índice int64
para cada dimensión. Los índices lineales son un valor int64
único que se indexa en el búfer que contiene el array. Consulta shape_util.h
y layout_util.h
en el mismo directorio para ver las utilidades que simplifican la creación y la manipulación de formas y diseños.