Dokumen ini menjelaskan semantik penyiaran XLA.
Apa itu penyiaran?
{i>Broadcasting<i} adalah proses pembuatan {i>array<i} dengan bentuk yang berbeda memiliki bentuk yang kompatibel untuk operasi aritmatika. Terminologi ini dipinjam dari Penyiaran NumPy.
Penyiaran mungkin diperlukan untuk operasi antara array multi-dimensi
peringkat yang berbeda, atau antara array multi-dimensi dengan
bentuk yang kompatibel. Pertimbangkan penambahan X+v
dengan X
sebagai matriks (array
dari peringkat 2) dan v
adalah vektor (array peringkat 1). Untuk melakukan {i>element<i}-{i>wise<i}
selain itu, XLA perlu "menyiarkan" vektor v
ke urutan yang sama dengan
matriks X
, dengan mereplikasi v
beberapa kali. Panjang vektor
harus sesuai dengan minimal salah satu dimensi matriks.
Contoh:
|1 2 3| + |7 8 9|
|4 5 6|
Dimensi matriks adalah (2,3), dan dimensi vektor adalah (3). Vektor disiarkan dengan mereplikasinya ke baris untuk mendapatkan:
|1 2 3| + |7 8 9| = |8 10 12|
|4 5 6| |7 8 9| |11 13 15|
Di NumPy, ini disebut penyiaran.
Prinsip
Bahasa XLA dibuat seketat dan sejelas mungkin, menghindari "ajaib" baru. Fitur tersebut dapat membuat beberapa perhitungan sedikit lebih mudah definisikan, tetapi mengorbankan lebih banyak asumsi yang dimasukkan ke dalam kode pengguna, yang akan sulit untuk diubah dalam jangka panjang. Jika perlu, fitur ajaib implisit dapat ditambahkan di wrapper tingkat klien.
Sehubungan dengan penyiaran, XLA memerlukan spesifikasi penyiaran yang eksplisit pada operasi di antara {i>array<i} dari peringkat yang berbeda. Ini berbeda dari NumPy, yang menyimpulkan spesifikasi jika memungkinkan.
Menyiarkan array peringkat lebih rendah ke array peringkat lebih tinggi
Scalars selalu dapat disiarkan melalui array tanpa spesifikasi eksplisit dimensi penyiaran. Operasi biner berbasis elemen antara skalar dan array berarti menerapkan operasi dengan skalar ke setiap elemen dalam . Misalnya, menambahkan skalar ke matriks berarti menghasilkan matriks dalam di mana setiap elemen adalah jumlah skalar dan elemen yang sesuai dari matriks input.
|1 2 3| + 7 = |8 9 10|
|4 5 6| |11 12 13|
Sebagian besar kebutuhan penyiaran dapat ditangkap dengan menggunakan tuple dimensi operasi biner. Ketika input ke operasi memiliki peringkat yang berbeda, tuple penyiaran menentukan dimensi mana dalam array peringkat yang lebih tinggi untuk cocok dengan array peringkat yang lebih rendah.
Pertimbangkan contoh sebelumnya. Alih-alih menambahkan skalar ke matriks (2,3), tambahkan vektor dimensi (3) ke matriks dimensi (2,3). Tanpa menentukan siaran, operasi ini tidak valid. Untuk meminta vektor-matriks dengan benar tentukan dimensi penyiaran menjadi (1), yang berarti nilai vektor dimensi dicocokkan dengan dimensi 1 dari matriks. Dalam 2D, jika dimensi 0 mewakili baris dan dimensi 1 mewakili kolom, ini berarti bahwa setiap elemen vektor menjadi kolom dengan ukuran yang sesuai dengan jumlah baris dalam matriks:
|7 8 9| ==> |7 8 9|
|7 8 9|
Sebagai contoh yang lebih kompleks, pertimbangkan untuk menambahkan vektor 3 elemen (dimensi (3)) ke matriks 3 x 3 (dimensi (3,3)). Ada dua cara penyiaran dapat dilakukan untuk contoh ini:
(1) Dimensi penyiaran 1 dapat digunakan. Setiap elemen vektor menjadi dan vektor diduplikasi untuk setiap baris dalam matriks.
|7 8 9| ==> |7 8 9|
|7 8 9|
|7 8 9|
(2) Dimensi penyiaran 0 dapat digunakan. Setiap elemen vektor menjadi baris dan vektor diduplikasi untuk setiap kolom dalam matriks.
|7| ==> |7 7 7|
|8| |8 8 8|
|9| |9 9 9|
Dimensi siaran dapat berupa tuple yang menjelaskan bagaimana peringkat yang lebih kecil {i>shape<i} disiarkan ke bentuk peringkat yang lebih besar. Misalnya, jika sebuah balok 2x3x4 dan matriks 3x4, tuple penyiaran (1,2) berarti mencocokkan matriks dengan dimensi 1 dan 2 balok.
Jenis siaran ini digunakan dalam operasi biner di XlaBuilder
, jika
Argumen broadcast_dimensions
diberikan. Misalnya, lihat
XlaBuilder::Add.
Dalam kode sumber XLA, jenis penyiaran ini terkadang disebut "InDim"
penyiaran.
Definisi formal
Atribut penyiaran memungkinkan pencocokan array yang berperingkat lebih rendah ke array yang berperingkat lebih tinggi dengan menentukan dimensi array berperingkat lebih tinggi yang akan dicocokkan. Sebagai misalnya, untuk larik dengan dimensi MxNxPxQ, vektor dengan dimensi T dapat cocok sebagai berikut:
MxNxPxQ
dim 3: T
dim 2: T
dim 1: T
dim 0: T
Dalam setiap kasus, T harus sama dengan dimensi yang sesuai dari peringkat yang lebih tinggi . Nilai vektor kemudian disiarkan dari dimensi yang cocok ke semua dimensi lainnya.
Untuk mencocokkan matriks TxV ke himpunan MxNxPxQ, sepasang dimensi penyiaran digunakan:
MxNxPxQ
dim 2,3: T V
dim 1,2: T V
dim 0,3: T V
etc...
Urutan dimensi dalam tuple penyiaran harus berupa urutan dimensi himpunan berperingkat lebih rendah diharapkan sesuai dengan array berperingkat lebih tinggi. Elemen pertama dalam tuple menentukan dimensi dalam tuple array berperingkat lebih tinggi harus cocok dengan dimensi 0 di array peringkat lebih rendah. Tujuan elemen kedua dalam tuple menentukan dimensi mana dalam array peringkat yang lebih tinggi harus cocok dengan dimensi 1 dalam array peringkat yang lebih rendah, dan seterusnya. Urutan dari dimensi siaran harus meningkat ketat. Misalnya, pada misalnya mencocokkan V ke N dan T ke P; juga ilegal untuk mencocokkan dengan V baik untuk P maupun N.
Menyiarkan array dengan peringkat serupa tetapi dimensinya berubah
Masalah terkait adalah menyiarkan dua {i>array<i} yang memiliki peringkat yang sama tetapi ukuran dimensi yang berbeda. Seperti halnya NumPy, hal ini hanya mungkin jika kompatibel. Dua array kompatibel jika semua dimensinya yang kompatibel. Dua dimensi akan kompatibel jika:
- Mereka sama, atau
- Salah satunya adalah 1 (dimensi "berubah")
Apabila dua array yang kompatibel ditemui, bentuk hasil memiliki maksimum dua input di setiap indeks dimensi.
Contoh:
- (2,1) dan (2,3) disiarkan ke (2,3).
- (1,2,5) dan (7,2,5) disiarkan ke (7,2,5).
- (7,2,5) dan (7,1,5) disiarkan ke (7,2,5).
- (7,2,5) dan (7,2,6) tidak kompatibel dan tidak dapat disiarkan.
Kasus khusus muncul, dan juga didukung, di mana masing-masing {i>array<i} input memiliki dimensi terdegenerasi pada indeks yang berbeda. Dalam hal ini, hasilnya adalah "operasi luar": (2,1) dan (1,3) disiarkan ke (2,3). Untuk contoh lainnya, baca Dokumentasi NumPy tentang penyiaran.
Komposisi siaran
Menyiarkan array dengan peringkat lebih rendah ke array dengan peringkat yang lebih tinggi dan penyiaran menggunakan dimensi yang turun dapat dilakukan dalam operasi biner yang sama. Sebagai contoh, sebuah vektor berukuran 4 dan matriks berukuran 1x2 dapat ditambahkan bersama-sama. menggunakan dimensi siaran bernilai (0):
|1 2 3 4| + [5 6] // [5 6] is a 1x2 matrix, not a vector.
Pertama, vektor disiarkan hingga peringkat 2 (matriks) menggunakan format broadcast dimensi kustom. Nilai tunggal (0) dalam dimensi siaran menunjukkan bahwa dimensi nol vektor cocok dengan dimensi nol dari matriks. Hal ini menghasilkan matriks berukuran 4xM di mana nilai M dipilih agar sesuai dengan ukuran dimensi dalam array 1x2. Jadi, matriks 4x2 dihasilkan:
|1 1| + [5 6]
|2 2|
|3 3|
|4 4|
Kemudian, "turunkan penyiaran dimensi" dimensi siaran nol dari 1x2 agar sesuai dengan ukuran dimensi sisi kanan yang sesuai:
|1 1| + |5 6| |6 7|
|2 2| + |5 6| = |7 8|
|3 3| + |5 6| |8 9|
|4 4| + |5 6| |9 10|
Contoh yang lebih rumit adalah matriks berukuran 1x2 yang ditambahkan ke array ukuran 4x3x1 menggunakan dimensi siaran (1, 2). Pertama, matriks 1x2 disiarkan ke atas ke peringkat 3 menggunakan dimensi siaran untuk menghasilkan array Mx1x2 perantara di mana ukuran dimensi M ditentukan oleh ukuran operand yang lebih besar (ukuran 4x3x1) menghasilkan array perantara 4x1x2. M berada pada dimensi 0 ( dimensi paling kiri) karena dimensi 1 dan 2 dipetakan ke dimensi dari matriks 1x2 asli sebagai dimensi broadcast adalah (1, 2). Ini himpunan perantara dapat ditambahkan ke matriks 4 x 3 x 1 menggunakan penyiaran dari mengubah dimensi sehingga hasilnya adalah 4x3x2.