Kształty i układ

Prototyp Shape XLA (xla_data.proto) opisuje pozycję, rozmiar i typ danych dla 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óre mają rozmiar większy niż 1.

  • W przypadku tablicy wymiarowej N wymiary są numerowane od 0 do N-1. Numery wymiarów są dowolnymi etykietami dla wygody użytkowników. Kolejność liczb tych wymiarów nie wskazuje na kolejność elementów podrzędnych/dużych 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 liczby wymiarów. 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 XLA obsługują też indeksowanie wykluczające w Pythonie: Wymiar-1 to ostatni wymiar (odpowiednik N-1 dla tablicy wymiarowej N). Na przykład w 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 XLA API, które przyjmują wymiary, robią to w kolejności rosnącej ich liczby. Odpowiada ona 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;
}

Uporządkowanie wymiarów od najmniejszych do większych

Jedyne wymagane pole to minor_to_major. To pole opisuje drobne lub duże porządkowanie wymiarów w obrębie kształtu. Wartości w elemencie minor_to_major to kolejność wymiarów tablicy (od 0 do N-1 w przypadku tablicy wymiarowej N), przy czym pierwsza wartość jest najmniejszym wymiarem, aż do ostatniej, która jest najbardziej znaczącym wymiarem. Najmniejszy wymiar to taki, który zmienia się najszybciej podczas przechodzenia między elementami tablicy rozmieszczonej w pamięci liniowej.

Przyjrzyjmy się na przykład tej tablicy 2D o rozmiarze [2 x 3]:

a b c
d e f

Wymiar 0 to rozmiar 2, a wymiar 1 to rozmiar 3. Jeśli pole minor_to_major w układzie to [0, 1], wymiar 0 jest najmniejszy, a największy 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-dużej (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], to układ w pamięci liniowej to:

a b c d e f

W przypadku tablicy wymiarowej N kolejność wymiarów od N-1 do 0 jest podobna do wiersza dużego (na pozycji 2). Zakładając monotoniczną kolejność wymiarów, możemy odnosić się do tego układu w kodzie po prostu „przyciemnij 0 jest większe”.

Domyślne porządkowanie małych i dużych wartości

Domyślny układ nowo tworzonych kształtów to „kolejność wymiarów od dużych do mniejszych” (podobnie do wierszy dużych na pozycji 2).

Dopełnienie

Dopełnienie jest zdefiniowane w opcjonalnych polach padded_dimensions i padding_value. Pole padded_dimensions określa rozmiary (szerokość), do których są dopełniane poszczególne wymiary. Jeśli ten argument ma zastosowanie, liczba elementów w funkcji padded_dimensions musi być równa rankingu kształtu.

Na przykład 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 na kolumnę) to:

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 najmniejszych do większych:

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

Indeksowanie do tablic

Klasa IndexUtil w index_util.h udostępnia narzędzia do przekształcania indeksów wielowymiarowych i liniowych 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ę. W tym samym katalogu znajdziesz narzędzia shape_util.h i layout_util.h, które upraszczają tworzenie kształtów oraz układy oraz manipulowanie nimi.