Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Los tensores de DirectML, respaldados por los búferes de Direct3D 12, se describen mediante propiedades conocidas como tamaños y desplazamientos del tensor. Los tamaños del tensor describen las dimensiones lógicas del tensor. Por ejemplo, un tensor 2D puede tener un alto de 2 y un ancho de 3. Lógicamente, el tensor tiene 6 elementos distintos, aunque los tamaños no especifican cómo se almacenan esos elementos en la memoria. Los desplazamientos del tensor describen la disposición de la memoria física de los elementos del tensor.
Matrices bidimensionales (2D)
Considere un tensor 2D que tiene un alto de 2 y un ancho de 3; los datos constan de caracteres textuales. En C/C++, esto puede expresarse mediante una matriz multidimensional.
constexpr int rows = 2;
constexpr int columns = 3;
char tensor[rows][columns];
tensor[0][0] = 'A';
tensor[0][1] = 'B';
tensor[0][2] = 'C';
tensor[1][0] = 'D';
tensor[1][1] = 'E';
tensor[1][2] = 'F';
La vista lógica del tensor anterior se visualiza a continuación.
A B C
D E F
En C/C++, una matriz multidimensional se almacena en orden principal de fila. En otras palabras, los elementos consecutivos a lo largo de la dimensión de ancho se almacenan de forma contigua en el espacio de memoria lineal.
Compensar: | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
Valor: | Un | B | C | D | E | F |
El paso de una dimensión es el número de elementos que se van a omitir para tener acceso al siguiente elemento de esa dimensión. Los pasos expresan el diseño del tensor en memoria. Con un orden por filas, el incremento de la dimensión de ancho siempre es 1, ya que los elementos adyacentes a lo largo de la dimensión se almacenan de forma contigua. El incremento de la dimensión de altura depende del tamaño de la dimensión de ancho; en el ejemplo de arriba, la distancia entre los elementos consecutivos a lo largo de la dimensión de altura (por ejemplo, desde A hasta D) es igual al ancho del tensor (que es 3 en este ejemplo).
Para ilustrar un diseño diferente, considere el orden principal de las columnas. En otras palabras, los elementos consecutivos a lo largo de la dimensión de altura se almacenan de forma contigua en el espacio de memoria lineal. En este caso, el paso de altura siempre es 1 y el paso de ancho es 2 (el tamaño de la dimensión de alto).
Compensar: | 0 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|---|
Valor: | Un | D | B | E | C | F |
Dimensiones más altas
Cuando se trata de más de dos dimensiones, no se puede hacer referencia a un diseño como fila principal o columna principal. Por lo tanto, el resto de este tema usa términos y etiquetas como estos.
- 2D: "HW": el alto es la dimensión de orden más alto (fila-principal).
- 2D: "WH": el ancho es la dimensión de orden más alto (columna principal).
- 3D: "DHW": la profundidad es la dimensión de orden más alto, seguida de la altura y, a continuación, el ancho.
- 3D: "WHD": el ancho es la dimensión de orden más alto, seguida de la altura y, a continuación, la profundidad.
- 4D: "NCHW": primero el número de imágenes (tamaño del lote), luego el número de canales, luego el alto y luego el ancho.
En general, el paso empaquetado de una dimensión es igual al producto de los tamaños de las dimensiones de orden inferior. Por ejemplo, con un diseño "DHW", el paso D es igual a H * W; el paso H es igual a W; y el paso W es igual a 1. Se dice que los pasos se empaquetan cuando el tamaño físico total del tensor es igual al tamaño lógico total del tensor; es decir, no hay espacio adicional ni elementos superpuestos.
Vamos a ampliar el ejemplo 2D a tres dimensiones, de modo que tengamos un tensor con profundidad 2, alto 2 y ancho 3 (para un total de 12 elementos lógicos).
A B C
D E F
G H I
J K L
Con un diseño "DHW", este tensor se almacena de la siguiente manera.
Compensar: | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
Valor: | Un | B | C | D | E | F | G | H | Yo | J | K | L |
- D-stride = altura (2) * ancho (3) = 6 (por ejemplo, la distancia entre "A" y "G").
- Inclinación H = ancho (3) = 3 (por ejemplo, la distancia entre 'A' y 'D').
- Salto W = 1 (por ejemplo, la distancia entre "A" y "B").
El producto de punto de los índices o coordenadas de un elemento y los pasos proporcionan el desplazamiento a ese elemento en el búfer. Por ejemplo, el desplazamiento del elemento H (d=1, h=0, w=1) es 7.
{1, 0, 1} ⋅ {6, 3, 1} = 1 * 6 + 0 * 3 + 1 * 1 = 7
Tensores empaquetados
Los ejemplos anteriores ilustran tensores empaquetados . Se dice que un tensor se empaqueta cuando el tamaño lógico del tensor (en elementos) es igual al tamaño físico del búfer (en elementos) y cada elemento tiene una dirección/desplazamiento única. Por ejemplo, se empaqueta un tensor 2x2x3 si el búfer tiene 12 elementos de longitud y ningún par de elementos comparten el mismo desplazamiento en el búfer. Los tensores empaquetados son el caso más común; pero los pasos permiten diseños de memoria más complejos.
Transmisión con avances
Si el tamaño de búfer de un tensor (en elementos) es menor que el producto de sus dimensiones lógicas, sigue que debe haber cierta superposición de elementos. El caso habitual para esto se conoce como difusión; donde los elementos de una dimensión son un duplicado de otra dimensión. Por ejemplo, vamos a revisar el ejemplo 2D. Supongamos que queremos un tensor que es lógicamente 2x3, pero la segunda fila es idéntica a la primera fila. Así es como se ve.
A B C
A B C
Esto se puede almacenar como un tensor HW/fila principal empaquetado. Pero un almacenamiento más compacto solo contendrá 3 elementos (A, B y C) y usaría un paso de altura de 0 en lugar de 3. En este caso, el tamaño físico del tensor es 3 elementos, pero el tamaño lógico es 6 elementos.
En general, si el paso de una dimensión es 0, todos los elementos de las dimensiones de orden inferior se repiten a lo largo de la dimensión retransmitida; Por ejemplo, si el tensor es NCHW y el paso de C es 0, cada canal tiene los mismos valores a lo largo de H y W.
Relleno con pasos
Se dice que un tensor se rellena si su tamaño físico es mayor que el tamaño mínimo necesario para ajustarse a sus elementos. Cuando no hay elementos de difusión ni superposición, el tamaño mínimo del tensor (en elementos) es simplemente el producto de sus dimensiones. Puede usar la función DMLCalcBufferTensorSize
auxiliar (consulte Funciones auxiliares de DirectML para obtener una lista de esa función) para calcular el tamaño mínimo del búfer para los tensores de DirectML.
Supongamos que un búfer contiene los valores siguientes (los elementos "x" indican valores de relleno).
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
Un | B | C | x | x | D | E | F | x | x |
El tensor acolchado se puede describir mediante un paso de altura de 5 en lugar de 3. En lugar de recorrer paso a paso 3 elementos para llegar a la siguiente fila, el paso es 5 elementos (3 elementos reales más 2 elementos de relleno). El relleno es común en los gráficos informáticos, por ejemplo, para garantizar que una imagen tenga una alineación de una potencia de dos.
A B C
D E F
Descripciones del tensor del búfer de DirectML
DirectML puede trabajar con una variedad de disposiciones físicas de tensores, ya que la estructura DML_BUFFER_TENSOR_DESC tiene tanto Sizes
como Strides
miembros. Algunas implementaciones de operador pueden ser más eficaces con un diseño específico, por lo que no es raro cambiar cómo se almacenan los datos tensor para mejorar el rendimiento.
La mayoría de los operadores directML requieren tensores 4D o 5D, y el orden de los tamaños y los valores de intervalos es fijo. Al corregir el orden de los tamaños y los valores de paso en una descripción de tensor, es posible que DirectML infiere diferentes diseños físicos.
4D
- DML_BUFFER_TENSOR_DESC::Tamaños = { Tamaño N, tamaño C, tamaño H, tamaño W }
- DML_BUFFER_TENSOR_DESC::Zancadas = { Zancada N, zancada C, zancada H, zancada W }
5D
- DML_BUFFER_TENSOR_DESC::Tamaños = { Tamaño N, tamaño C, tamaño D, tamaño H, tamaño W }
- DML_BUFFER_TENSOR_DESC::Zancadas = { N zancadas, C-zancadas, D-zancadas, H-zancadas, W-zancadas }
Si un operador DirectML requiere un tensor 4D o 5D, pero los datos reales tienen una clasificación más pequeña (por ejemplo, 2D), las dimensiones iniciales deben rellenarse con 1s. Por ejemplo, un tensor "HW" se establece mediante DML_BUFFER_TENSOR_DESC::Sizes = { 1, 1, H, W }.
Si los datos de tensor se almacenan en NCHW/NCDHW, no es necesario establecer DML_BUFFER_TENSOR_DESC::Strides, a menos que desee realizar broadcasting o padding. Puede establecer el campo de pasos en nullptr
. Sin embargo, si los datos de tensor se almacenan en otro diseño, como NHWC, necesita pasos para expresar la transformación de NCHW a ese diseño.
Para obtener un ejemplo sencillo, considere la descripción de un tensor 2D con alto 3 y ancho 5.
NCHW empaquetado (pasos implícitos)
- DML_BUFFER_TENSOR_DESC::Tamaños = { 1, 1, 3, 5 }
-
DML_BUFFER_TENSOR_DESC::Zancadas =
nullptr
NCHW empaquetado (pasos explícitos)
- N-stride = Tamaño-C * Tamaño-H * Tamaño-W = 1 * 3 * 5 = 15
- Zancada C = Talla H * Talla W = 3 * 5 = 15
- Paso H = Tamaño W = 5
- Stride de W = 1
- DML_BUFFER_TENSOR_DESC::Tamaños = { 1, 1, 3, 5 }
- DML_BUFFER_TENSOR_DESC::Zancadas = { 15, 15, 5, 1 }
NHWC empaquetado
- Zancada N = Talla H * Talla W * Talla C = 3 * 5 * 1 = 15
- Intervalo H = Tamaño W * Tamaño C = 5 * 1 = 5
- Paso de W = tamaño de C = 1
- Zancada en C = 1
- DML_BUFFER_TENSOR_DESC::Tamaños = { 1, 1, 3, 5 }
- DML_BUFFER_TENSOR_DESC::Zancadas = { 15, 1, 5, 1 }