Kształty i układ

Protokół XLA Shape (xla_data.proto) opisuje pozycję, rozmiar i typ danych w N-wymiarowej tablicy (w skrócie tablica).

Terminologia, notacja i konwencje

  • Pozycja tablicy jest równa liczbie wymiarów. Prawdziwa pozycja tablicy to liczba wymiarów, których rozmiar jest większy niż 1.

  • Dla tablicy wymiarowej N wymiary są numerowane od 0 do N-1. Numery wymiarów mają charakter dowolnych etykiet dla wygody użytkowników. Kolejność liczb tych wymiarów nie jest przesądzona w układzie kształtu. Układ jest określany przez proto Layout.

  • Zgodnie z konwencją wymiary są wyświetlane w kolejności rosnącej ich liczby. Na przykład w przypadku trójwymiarowej tablicy o rozmiarze [A x B x C] wymiar 0 ma rozmiar A, wymiar 1 ma rozmiar B, a wymiar 2 – C.

    Niektóre narzędzia w języku XLA obsługują również indeksowanie wykluczające w języku Python. Wymiar -1 to ostatni wymiar (odpowiednik N-1 w przypadku tablicy wymiarowej N). Na przykład w przypadku opisanej powyżej tablicy trójwymiarowej wymiar -1 ma rozmiar C, wymiar -2 ma rozmiar B itd.

  • Tablice dwu-, trzy- i czterowymiarowe często mają określone litery powiązane z wymiarami. Na przykład w przypadku tablicy 2D:

    • wymiar 0: y
    • wymiar 1: x

    W przypadku tablicy 3D:

    • wymiar 0: z
    • wymiar 1: y
    • wymiar 2: x

    W przypadku tablicy 4D:

    • wymiar 0: p
    • wymiar 1: z
    • wymiar 2: y
    • wymiar 3: x
  • Funkcje w interfejsie API XLA, które przyjmują wymiary, robią to w kolejności rosnącej liczby wymiarów. Odpowiada to kolejności stosowanej podczas przekazywania wymiarów jako initializer_list, np.

    ShapeUtil::MakeShape(F32, {A, B, C, D})

    utworzy kształt, którego tablica rozmiarów wymiarów składa się z sekwencji [A, B, C, D].

Układ

Proto Layout określa, jak tablica jest reprezentowana w pamięci. Protokół Layout zawiera te pola:

message Layout {
  repeated int64 minor_to_major = 1;
  repeated int64 padded_dimensions = 2;
  optional PaddingValue padding_value = 3;
}

Kolejność wymiarów od mniejszych do większych

Jedyne wymagane pole to minor_to_major. To pole opisuje kolejność od najmniejszej do głównej wartości wymiarów w obrębie kształtu. Wartości w polu minor_to_major określają kolejność wymiarów tablicy (od 0 do N-1 w przypadku tablicy wymiarowej N), gdzie pierwsza wartość jest najmniejszym wymiarem aż do ostatniej wartości, która jest najbardziej znaczącym wymiarem. Najmniejszy wymiar to ten, który zmienia się najszybciej, gdy przechodzi przez elementy tablicy zawarte w pamięci liniowej.

Przeanalizujmy na przykład tę tablicę 2D o rozmiarze [2 x 3]:

a b c
d e f

Tutaj wymiar 0 to rozmiar 2, a wymiar 1 to rozmiar 3. Jeśli pole minor_to_major w układzie ma wartość [0, 1], wymiar 0 jest najmniejszy, a najważniejszy – 1. Odpowiada to temu układowi w pamięci liniowej:

a d b e c f

Ta kolejność wymiarów od 0 do N-1 jest podobna do kolumny kolumna-główna (na pozycji 2). Zakładając monotoniczną kolejność wymiarów, możemy odnosić się do tego układu w kodzie po prostu „przyciemnianie 0 ma znaczenie”.

Z drugiej strony, jeśli pole minor_to_major w układzie ma wartość [1, 0], układ w pamięci liniowej wygląda tak:

a b c d e f

Porządek wymiarów od N-1 do 0 dla tablicy wymiarowej N jest podobny do wiersza dużego (na pozycji 2). Zakładając monotoniczną kolejność wymiarów, innym sposobem odwoływania się do tego układu w kodzie jest po prostu „przyciemnij 0 jest głównym”.

Domyślne zamówienia od małych do dużych

Domyślny układ nowo tworzonych kształtów to „kolejność wymiarów od dużych do mniejszych” (podobnie do wiersza-głównego na drugim miejscu).

Dopełnienie

Dopełnienie jest zdefiniowane w opcjonalnych polach padded_dimensions i padding_value. Pole padded_dimensions określa rozmiary (szerokość), do których jest dopełniany każdy wymiar. Liczba elementów w polu padded_dimensions musi być równa rangi kształtu.

Na przykład w zdefiniowanej powyżej tablicy [2 x 3], jeśli pole padded_dimensions ma wartość [3, 5], wymiar 0 jest dopełniany do szerokości 3, a wymiar 1 – do szerokości 5. Układ w pamięci liniowej (przy założeniu, że wartość dopełnienia wynosi 0 i układ „duży kolumny”):

a d 0 b e 0 c f 0 0 0 0 0 0 0

Jest to odpowiednik układu tej tablicy z tą samą kolejnością wymiarów od mniejszych do największych:

a b c 0 0
d e f 0 0
0 0 0 0 0

Indeksowanie do tablic

Klasa IndexUtil w dyrektywie index_util.h udostępnia narzędzia do konwertowania indeksów wielowymiarowych na indeksy liniowe o określonym kształcie i układzie. Indeksy wielowymiarowe mają indeks int64 dla każdego wymiaru. Indeksy liniowe to pojedyncza wartość int64, która jest indeksowana do bufora zawierającego tablicę. Zobacz shape_util.h i layout_util.h w tym samym katalogu, aby znaleźć narzędzia, które ułatwiają tworzenie kształtów i układów oraz manipulowanie nimi.