W tym dokumencie opisujemy semantykę rozgłaszania XLA.
Co to jest transmisja?
Rozgłaszanie to proces, w którym tablice o różnych kształtach są przekształcane w tablice o kształtach zgodnych z operacjami arytmetycznymi. Terminologia pochodzi z rozgłaszania w NumPy.
Rozgłaszanie może być wymagane w przypadku operacji na wielowymiarowych tablicach o różnych rangach lub na wielowymiarowych tablicach o różnych, ale zgodnych kształtach. Rozważ dodawanie X+v, gdzie X to macierz (tablica 2-wymiarowa), a v to wektor (tablica 1-wymiarowa). Aby wykonać dodawanie elementów, XLA musi „rozgłosić” wektor v do tej samej liczby wymiarów co macierz X, replikując v określoną liczbę razy. Długość wektora musi być zgodna z co najmniej jednym wymiarem macierzy.
Na przykład:
|1 2 3| + |7 8 9|
|4 5 6|
Wymiary macierzy to (2,3), a wektora – (3). Wektor jest rozgłaszany przez replikowanie go w wierszach, aby uzyskać:
|1 2 3| + |7 8 9| = |8 10 12|
|4 5 6| |7 8 9| |11 13 15|
W NumPy nazywa się to rozgłaszaniem.
Zasady
Język XLA jest tak ścisły i jednoznaczny, jak to tylko możliwe, i nie zawiera żadnych domyślnych „magicznych” funkcji. Takie funkcje mogą nieco ułatwić definiowanie niektórych obliczeń, ale kosztem większej liczby założeń w kodzie użytkownika, które w dłuższej perspektywie będą trudne do zmiany. W razie potrzeby w otoczkach na poziomie klienta można dodać niejawne funkcje magiczne.
W przypadku transmisji XLA wymaga jawnych specyfikacji transmisji w operacjach między tablicami o różnych rangach. Różni się to od biblioteki NumPy, która w miarę możliwości wywnioskowuje specyfikację.
Rozgłaszanie tablicy o mniejszej liczbie wymiarów na tablicę o większej liczbie wymiarów
Skalary zawsze można transmitować w tablicach bez wyraźnego określenia wymiarów transmisji. Operacja binarna na poszczególnych elementach między wartością skalarną a tablicą oznacza zastosowanie operacji z wartością skalarną do każdego elementu tablicy. Na przykład dodanie skalaru do macierzy oznacza utworzenie macierzy, w której każdy element jest sumą skalaru i odpowiedniego elementu macierzy wejściowej.
|1 2 3| + 7 = |8 9 10|
|4 5 6| |11 12 13|
Większość potrzeb związanych z nadawaniem można zaspokoić, używając krotki wymiarów w operacji binarnej. Gdy dane wejściowe operacji mają różne rangi, ta krotka rozgłaszania określa, które wymiary w wielowymiarowej tablicy mają być dopasowane do niskowymiarowej tablicy.
Weźmy pod uwagę poprzedni przykład. Zamiast dodawać skalar do macierzy (2,3), dodaj wektor o wymiarze (3) do macierzy o wymiarach (2,3). Bez określenia transmisji ta operacja jest nieprawidłowa. Aby prawidłowo poprosić o dodanie macierzy do wektora, określ wymiar rozgłaszania jako (1), co oznacza, że wymiar wektora jest dopasowany do wymiaru 1 macierzy. W przypadku tablicy dwuwymiarowej, w której wymiar 0 reprezentuje wiersze, a wymiar 1 – kolumny, oznacza to, że każdy element wektora staje się kolumną o rozmiarze odpowiadającym liczbie wierszy w macierzy:
|7 8 9| ==> |7 8 9|
|7 8 9|
Bardziej złożony przykład: dodanie wektora 3-elementowego (wymiar (3)) do macierzy 3x3 (wymiary (3,3)). W tym przykładzie transmisja może odbywać się na 2 sposoby:
(1) Można użyć wymiaru transmisji 1. Każdy element wektora staje się kolumną, a wektor jest duplikowany w każdym wierszu macierzy.
|7 8 9| ==> |7 8 9|
|7 8 9|
|7 8 9|
(2) Można użyć wymiaru transmisji o wartości 0. Każdy element wektora staje się wierszem, a wektor jest duplikowany w każdej kolumnie macierzy.
|7| ==> |7 7 7|
|8| |8 8 8|
|9| |9 9 9|
Wymiary transmisji mogą być krotką opisującą, jak kształt o mniejszej liczbie wymiarów jest transmitowany do kształtu o większej liczbie wymiarów. Na przykład w przypadku prostopadłościanu o wymiarach 2x3x4 i macierzy 3x4 krotka rozgłaszania (1,2) oznacza dopasowanie macierzy do wymiarów 1 i 2 prostopadłościanu.
Ten typ transmisji jest używany w operacjach binarnych w XlaBuilder, jeśli podano argument broadcast_dimensions. Przykład znajdziesz w artykule XlaBuilder::Add.
W kodzie źródłowym XLA ten typ transmisji jest czasami nazywany transmisją „InDim”.
Formalna definicja
Atrybut rozgłaszania umożliwia dopasowanie tablicy o mniejszej liczbie wymiarów do tablicy o większej liczbie wymiarów przez określenie, które wymiary tablicy o większej liczbie wymiarów mają być dopasowane. Na przykład w przypadku tablicy o wymiarach MxNxPxQ wektor o wymiarze T można dopasować w ten sposób:
MxNxPxQ
dim 3: T
dim 2: T
dim 1: T
dim 0: T
W każdym przypadku T musi być równe pasującemu wymiarowi tablicy o większej liczbie wymiarów. Wartości wektora są następnie rozsyłane z dopasowanego wymiaru do wszystkich pozostałych wymiarów.
Aby dopasować macierz TxV do tablicy MxNxPxQ, używana jest para wymiarów transmisji:
MxNxPxQ
dim 2,3: T V
dim 1,2: T V
dim 0,3: T V
etc...
Kolejność wymiarów w krotce rozgłaszania musi być zgodna z kolejnością, w jakiej wymiary tablicy o mniejszej liczbie wymiarów mają pasować do wymiarów tablicy o większej liczbie wymiarów. Pierwszy element krotki określa, który wymiar w tablicy wielowymiarowej musi pasować do wymiaru 0 w tablicy o mniejszej liczbie wymiarów. Drugi element w krotce określa, który wymiar w tablicy wielowymiarowej musi pasować do wymiaru 1 w tablicy o mniejszej liczbie wymiarów itd. Kolejność wymiarów emisji musi być ściśle rosnąca. Na przykład w poprzednim przykładzie niedozwolone jest dopasowanie litery V do litery N i litery T do litery P. Niedozwolone jest też dopasowanie litery V do litery P i litery N.
Rozgłaszanie tablic o podobnych wymiarach z wymiarami zdegenerowanymi
Powiązanym problemem jest przesyłanie dwóch tablic o tej samej liczbie wymiarów, ale o różnych rozmiarach wymiarów. Podobnie jak w przypadku NumPy jest to możliwe tylko wtedy, gdy tablice są zgodne. Dwie tablice są zgodne, jeśli wszystkie ich wymiary są zgodne. Dwa wymiary są zgodne, jeśli:
- są równe,
- Jeden z nich to 1 (wymiar „zdegenerowany”).
Gdy napotkane zostaną 2 kompatybilne tablice, kształt wyniku będzie miał maksymalną wartość z 2 danych wejściowych przy każdym indeksie wymiaru.
Przykłady:
- (2,1) i (2,3) przesyłają do (2,3).
- (1,2,5) i (7,2,5) przesyłają do (7,2,5).
- (7,2,5) i (7,1,5) przesyłają do (7,2,5).
- Wersje (7,2,5) i (7,2,6) są niezgodne i nie można ich transmitować.
Występuje też przypadek specjalny, który jest również obsługiwany, w którym każda z tablic wejściowych ma zdegenerowany wymiar w innym indeksie. W tym przypadku wynikiem jest „operacja zewnętrzna”: (2,1) i (1,3) są rozgłaszane do (2,3). Więcej przykładów znajdziesz w dokumentacji NumPy na temat rozgłaszania.
Kompozycja transmisji
Rozgłaszanie tablicy o mniejszej liczbie wymiarów do tablicy o większej liczbie wymiarów i rozgłaszanie z użyciem wymiarów zdegenerowanych można wykonać w ramach tej samej operacji binarnej. Na przykład wektor o rozmiarze 4 i macierz o rozmiarze 1 × 2 można dodać do siebie, używając wymiarów rozgłaszania o wartości (0):
|1 2 3 4| + [5 6] // [5 6] is a 1x2 matrix, not a vector.
Najpierw wektor jest rozgłaszany do 2 wymiarów (macierzy) za pomocą wymiarów rozgłaszania. Pojedyncza wartość (0) w wymiarach transmisji wskazuje, że wymiar zerowy wektora pasuje do wymiaru zerowego macierzy. W ten sposób powstaje macierz o rozmiarze 4xM, gdzie wartość M jest wybierana tak, aby pasowała do odpowiedniego rozmiaru wymiaru w tablicy 1x2. W rezultacie powstaje macierz 4x2:
|1 1| + [5 6]
|2 2|
|3 3|
|4 4|
Następnie „transmisja zdegenerowanego wymiaru” transmituje wymiar zerowy macierzy 1x2, aby dopasować go do odpowiedniego rozmiaru wymiaru po prawej stronie:
|1 1| + |5 6| |6 7|
|2 2| + |5 6| = |7 8|
|3 3| + |5 6| |8 9|
|4 4| + |5 6| |9 10|
Bardziej skomplikowany przykład to macierz o rozmiarze 1x2 dodana do tablicy o rozmiarze 4x3x1 przy użyciu wymiarów rozgłaszania (1, 2). Najpierw macierz 1x2 jest rozgłaszana w 3 wymiarach za pomocą wymiarów rozgłaszania, aby utworzyć pośrednią tablicę Mx1x2, w której rozmiar wymiaru M jest określany przez rozmiar większego operandu (tablicy 4x3x1), co daje pośrednią tablicę 4x1x2. Macierz M znajduje się w wymiarze 0 (najbardziej po lewej), ponieważ wymiary 1 i 2 są mapowane na wymiary oryginalnej macierzy 1 x 2, tak jak wymiary transmisji (1, 2). Tę tablicę pośrednią można dodać do macierzy 4x3x1, używając rozgłaszania wymiarów zdegenerowanych, aby uzyskać tablicę wynikową 4x3x2.