Aşağıda XlaBuilder
arayüzünde tanımlanan işlemlerin semantiği açıklanmaktadır. Tipik olarak bu işlemler, RPC arayüzünde xla_data.proto
tanımlanan işlemlerle bire bir eşlenir.
İsimlendirmeyle ilgili bir not: XLA'nın ele aldığı genelleştirilmiş veri türü, bazı tekdüze türdeki öğeleri (32 bit kayan nokta gibi) tutan N boyutlu bir dizidir. Belgelerin tamamında dizi , rastgele boyutlu bir diziyi belirtmek için kullanılır. Kolaylık sağlamak için, özel durumların daha spesifik ve tanıdık isimleri vardır; örneğin bir vektör 1 boyutlu bir dizidir ve bir matris 2 boyutlu bir dizidir.
Nihayet
Ayrıca bkz. XlaBuilder::AfterAll
.
AfterAll değişken sayıda jeton alır ve tek bir jeton üretir. Jetonlar, siparişi zorlamak için yan etkili işlemler arasında aktarılabilen ilkel türlerdir. AfterAll
belirli bir işlemden sonra bir işlemi sipariş etmek için belirteçlerin birleştirilmesi olarak kullanılabilir.
AfterAll(operands)
Argümanlar | Tip | Anlambilim |
---|---|---|
operands | XlaOp | değişken sayıda jeton |
HepsiTopla
Ayrıca bkz. XlaBuilder::AllGather
.
Replikalar arasında birleştirme gerçekleştirir.
AllGather(operand, all_gather_dim, shard_count, replica_group_ids, channel_id)
Argümanlar | Tip | Anlambilim |
---|---|---|
operand | XlaOp | Kopyalar arasında birleştirilecek dizi |
all_gather_dim | int64 | Birleştirme boyutu |
replica_groups | int64 vektörlerinin vektörü | Aralarında birleştirme işleminin gerçekleştirildiği gruplar |
channel_id | isteğe bağlı int64 | Modüller arası iletişim için isteğe bağlı kanal kimliği |
-
replica_groups
aralarında birleştirme işleminin gerçekleştirildiği replika gruplarının bir listesidir (geçerli replikanın replika kimliğiReplicaId
kullanılarak alınabilir). Her gruptaki kopyaların sırası, girdilerin sonuçta yer alma sırasını belirler.replica_groups
ya boş olmalı (bu durumda tüm replikalar0
N - 1
kadar sıralanmış tek bir gruba ait olmalıdır) ya da replika sayısıyla aynı sayıda öğe içermelidir. Örneğin,replica_groups = {0, 2}, {1, 3}
0
ile2
ve1
ile3
replikaları arasında birleştirme işlemini gerçekleştirir. -
shard_count
her kopya grubunun boyutudur.replica_groups
boş olduğu durumlarda buna ihtiyacımız var. -
channel_id
modüller arası iletişim için kullanılır: yalnızca aynıchannel_id
sahipall-gather
işlemleri birbirleriyle iletişim kurabilir.
Çıkış şekli, all_gather_dim
shard_count
kat daha büyük hale getirildiği giriş şeklidir. Örneğin, iki kopya varsa ve işlenen iki kopyada sırasıyla [1.0, 2.5]
ve [3.0, 5.25]
değerine sahipse, bu durumda all_gather_dim
0
olduğu bu operasyonun çıktı değeri [1.0, 2.5, 3.0, 5.25]
olacaktır. [1.0, 2.5, 3.0, 5.25]
her iki kopyada da.
Tümünü Azalt
Ayrıca bkz. XlaBuilder::AllReduce
.
Replikalar arasında özel bir hesaplama gerçekleştirir.
AllReduce(operand, computation, replica_group_ids, channel_id)
Argümanlar | Tip | Anlambilim |
---|---|---|
operand | XlaOp | Replikalar arasında azaltılacak dizi veya boş olmayan bir dizi dizisi |
computation | XlaComputation | Azaltma hesaplaması |
replica_groups | int64 vektörlerinin vektörü | İndirgemelerin yapıldığı gruplar |
channel_id | isteğe bağlı int64 | Modüller arası iletişim için isteğe bağlı kanal kimliği |
-
operand
bir dizi dizisi olduğunda, tümünü azaltma işlemi dizinin her bir elemanı üzerinde gerçekleştirilir. -
replica_groups
aralarında azaltmanın gerçekleştirildiği replika gruplarının bir listesidir (geçerli replikanın replika kimliğiReplicaId
kullanılarak alınabilir).replica_groups
ya boş olmalıdır (bu durumda tüm replikalar tek bir gruba aittir) ya da replika sayısıyla aynı sayıda öğe içermelidir. Örneğin,replica_groups = {0, 2}, {1, 3}
0
ile2
ve1
ile3
replikaları arasında azaltma gerçekleştirir. -
channel_id
modüller arası iletişim için kullanılır: yalnızca aynıchannel_id
sahipall-reduce
işlemleri birbiriyle iletişim kurabilir.
Çıkış şekli giriş şekliyle aynıdır. Örneğin, iki kopya varsa ve işlenen iki kopyada sırasıyla [1.0, 2.5]
ve [3.0, 5.25]
değerine sahipse, bu işlem ve toplama hesaplamasından elde edilen çıktı değeri her ikisinde de [4.0, 7.75]
olacaktır. kopyalar. Giriş bir demet ise, çıktı da bir demettir.
AllReduce
sonucunun hesaplanması, her kopyadan bir girişin olmasını gerektirir; dolayısıyla bir kopya, bir AllReduce
düğümünü diğerinden daha fazla çalıştırırsa, eski kopya sonsuza kadar bekleyecektir. Kopyaların hepsi aynı programı çalıştırdığından, bunun gerçekleşmesi için çok fazla yol yoktur, ancak bir while döngüsünün koşulunun beslemeden gelen verilere bağlı olması ve beslenen verilerin while döngüsünün daha fazla yinelenmesine neden olması mümkündür. bir kopyada diğerine göre.
HepsindenHerkese
Ayrıca bkz. XlaBuilder::AllToAll
.
AllToAll, tüm çekirdeklerden tüm çekirdeklere veri gönderen kolektif bir işlemdir. İki aşaması vardır:
- Dağılım aşaması. Her çekirdekte işlenen,
split_dimensions
boyuncasplit_count
sayıda bloğa bölünür ve bloklar tüm çekirdeklere dağıtılır, örneğin i'inci blok i'inci çekirdeğe gönderilir. - Toplama aşaması. Her çekirdek alınan blokları
concat_dimension
boyunca birleştirir.
Katılan çekirdekler şu şekilde yapılandırılabilir:
-
replica_groups
: her ReplicaGroup, hesaplamaya katılan replika kimliklerinin bir listesini içerir (geçerli replikanın replika kimliğiReplicaId
kullanılarak alınabilir). AllToAll, alt gruplar içinde belirtilen sırayla uygulanacaktır. Örneğin,replica_groups = { {1,2,3}, {4,5,0} }
,{1, 2, 3}
kopyalarının içinde ve toplama aşamasında bir AllToAll'ın uygulanacağı ve alınan blokların uygulanacağı anlamına gelir. 1, 2, 3 ile aynı sırayla birleştirilebilir. Daha sonra, 4, 5, 0 kopyalarına başka bir AllToAll uygulanacaktır ve birleştirme sırası da 4, 5, 0 olacaktır.replica_groups
boşsa, tüm kopyalar bire ait olur grup, görünümlerine göre birleştirme sırasına göre.
Önkoşullar:
-
split_dimension
işlenenin boyut boyutusplit_count
bölünebilir. - İşlenenin şekli demet değildir.
AllToAll(operand, split_dimension, concat_dimension, split_count, replica_groups)
Argümanlar | Tip | Anlambilim |
---|---|---|
operand | XlaOp | n boyutlu giriş dizisi |
split_dimension | int64 | İşlenenin bölüneceği boyutu adlandıran, [0, n) aralığındaki bir değer |
concat_dimension | int64 | Bölünmüş blokların birleştirildiği boyutu adlandıran [0, n) aralığındaki bir değer |
split_count | int64 | Bu işleme katılan çekirdek sayısı. replica_groups boşsa bu, replikaların sayısı olmalıdır; aksi takdirde bu, her gruptaki kopya sayısına eşit olmalıdır. |
replica_groups | ReplicaGroup vektör | Her grup kopya kimliklerinin bir listesini içerir. |
Aşağıda Alltoall'un bir örneği gösterilmektedir.
XlaBuilder b("alltoall");
auto x = Parameter(&b, 0, ShapeUtil::MakeShape(F32, {4, 16}), "x");
AllToAll(x, /*split_dimension=*/1, /*concat_dimension=*/0, /*split_count=*/4);
Bu örnekte Alltoall'a katılan 4 çekirdek var. Her çekirdekte, işlenen 0 boyutu boyunca 4 parçaya bölünür, böylece her parça f32[4,4] şeklinde olur. 4 parça tüm çekirdeklere dağılmıştır. Daha sonra her çekirdek alınan parçaları boyut 1 boyunca çekirdek 0-4 sırasına göre birleştirir. Yani her çekirdeğin çıktısı f32[16,4] şeklindedir.
Toplu Norm Grad
Algoritmanın ayrıntılı bir açıklaması için ayrıca XlaBuilder::BatchNormGrad
ve orijinal toplu normalleştirme belgesine bakın.
Parti normunun gradyanlarını hesaplar.
BatchNormGrad(operand, scale, mean, variance, grad_output, epsilon, feature_index)
Argümanlar | Tip | Anlambilim |
---|---|---|
operand | XlaOp | normalleştirilecek n boyutlu dizi (x) |
scale | XlaOp | 1 boyutlu dizi (\(\gamma\)) |
mean | XlaOp | 1 boyutlu dizi (\(\mu\)) |
variance | XlaOp | 1 boyutlu dizi (\(\sigma^2\)) |
grad_output | XlaOp | BatchNormTraining aktarılan degradeler (\(\nabla y\)) |
epsilon | float | Epsilon değeri (\(\epsilon\)) |
feature_index | int64 | operand özellik boyutuna endeks |
Özellik boyutundaki her özellik için ( feature_index
, operand
özellik boyutunun indeksidir), işlem, tüm diğer boyutlar boyunca operand
, offset
ve scale
göre gradyanları hesaplar. feature_index
operand
özellik boyutu için geçerli bir dizin olmalıdır.
Üç degrade aşağıdaki formüllerle tanımlanır ( operand
olarak 4 boyutlu bir dizi varsayılarak ve özellik boyutu indeksi l
, toplu iş boyutu m
ve uzamsal boyutlar w
ve h
ile birlikte):
\[ \begin{split} c_l&= \frac{1}{mwh}\sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \left( \nabla y_{ijkl} \frac{x_{ijkl} - \mu_l}{\sigma^2_l+\epsilon} \right) \\\\ d_l&= \frac{1}{mwh}\sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \nabla y_{ijkl} \\\\ \nabla x_{ijkl} &= \frac{\gamma_{l} }{\sqrt{\sigma^2_{l}+\epsilon} } \left( \nabla y_{ijkl} - d_l - c_l (x_{ijkl} - \mu_{l}) \right) \\\\ \nabla \gamma_l &= \sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \left( \nabla y_{ijkl} \frac{x_{ijkl} - \mu_l}{\sqrt{\sigma^2_{l}+\epsilon} } \right) \\\\\ \nabla \beta_l &= \sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h \nabla y_{ijkl} \end{split} \]
Girdilerin mean
ve variance
toplu ve uzamsal boyutlardaki moment değerlerini temsil eder.
Çıkış türü üç tanıtıcıdan oluşan bir demettir:
çıktılar | Tip | Anlambilim |
---|---|---|
grad_operand | XlaOp | giriş operand göre gradyan ($\nabla x$) |
grad_scale | XlaOp | giriş scale göre gradyan ($\nabla \gamma$) |
grad_offset | XlaOp | giriş offset göre gradyan ($\nabla \beta$) |
Toplu Norm Çıkarımı
Algoritmanın ayrıntılı bir açıklaması için ayrıca XlaBuilder::BatchNormInference
ve orijinal toplu normalleştirme belgesine bakın.
Bir diziyi toplu ve uzamsal boyutlara göre normalleştirir.
BatchNormInference(operand, scale, offset, mean, variance, epsilon, feature_index)
Argümanlar | Tip | Anlambilim |
---|---|---|
operand | XlaOp | normalleştirilecek n boyutlu dizi |
scale | XlaOp | 1 boyutlu dizi |
offset | XlaOp | 1 boyutlu dizi |
mean | XlaOp | 1 boyutlu dizi |
variance | XlaOp | 1 boyutlu dizi |
epsilon | float | Epsilon değeri |
feature_index | int64 | operand özellik boyutuna endeks |
Özellik boyutundaki her özellik için ( feature_index
, operand
özellik boyutuna ilişkin dizindir), işlem, diğer tüm boyutlarda ortalamayı ve varyansı hesaplar ve operand
her öğeyi normalleştirmek için ortalamayı ve varyansı kullanır. feature_index
operand
özellik boyutu için geçerli bir dizin olmalıdır.
BatchNormInference
her toplu iş için mean
ve variance
hesaplamadan BatchNormTraining
çağırmaya eşdeğerdir. Tahmini değerler yerine girdi mean
ve variance
kullanır. Bu işlemin amacı çıkarımdaki gecikmeyi azaltmaktır, dolayısıyla BatchNormInference
adı verilmiştir.
Çıkış, giriş operand
aynı şekle sahip, n boyutlu, normalleştirilmiş bir dizidir.
Toplu Norm Eğitimi
Algoritmanın ayrıntılı bir açıklaması için ayrıca XlaBuilder::BatchNormTraining
ve the original batch normalization paper
bakın.
Bir diziyi toplu ve uzamsal boyutlara göre normalleştirir.
BatchNormTraining(operand, scale, offset, epsilon, feature_index)
Argümanlar | Tip | Anlambilim |
---|---|---|
operand | XlaOp | normalleştirilecek n boyutlu dizi (x) |
scale | XlaOp | 1 boyutlu dizi (\(\gamma\)) |
offset | XlaOp | 1 boyutlu dizi (\(\beta\)) |
epsilon | float | Epsilon değeri (\(\epsilon\)) |
feature_index | int64 | operand özellik boyutuna endeks |
Özellik boyutundaki her özellik için ( feature_index
, operand
özellik boyutuna ilişkin dizindir), işlem, diğer tüm boyutlarda ortalamayı ve varyansı hesaplar ve operand
her öğeyi normalleştirmek için ortalamayı ve varyansı kullanır. feature_index
operand
özellik boyutu için geçerli bir dizin olmalıdır.
Algoritma, uzaysal boyutların boyutu olarak w
ve h
ile m
öğe içeren \(x\) operand
her grup için aşağıdaki şekilde çalışır ( operand
4 boyutlu bir dizi olduğu varsayılarak):
Unsur boyutunda her
l
özelliği için \(\mu_l\) toplu ortalamasını hesaplar:\(\mu_l=\frac{1}{mwh}\sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h x_{ijkl}\)Toplu varyansı hesaplar \(\sigma^2_l\): $\sigma^2 l=\frac{1}{mwh}\sum {i=1}^m\sum {j=1}^w\sum {k=1}^h ( x_{ijkl} - \mu_l)^2$
Normalleştirir, ölçeklendirir ve değiştirir:\(y_{ijkl}=\frac{\gamma_l(x_{ijkl}-\mu_l)}{\sqrt[2]{\sigma^2_l+\epsilon} }+\beta_l\)
Sıfıra bölme hatalarını önlemek için genellikle küçük bir sayı olan epsilon değeri eklenir.
Çıkış türü üç XlaOp
oluşan bir demettir:
çıktılar | Tip | Anlambilim |
---|---|---|
output | XlaOp | giriş operand (y) ile aynı şekle sahip n boyutlu dizi |
batch_mean | XlaOp | 1 boyutlu dizi (\(\mu\)) |
batch_var | XlaOp | 1 boyutlu dizi (\(\sigma^2\)) |
batch_mean
ve batch_var
, yukarıdaki formüller kullanılarak toplu ve uzamsal boyutlar genelinde hesaplanan anlardır.
BitcastConvertType
Ayrıca bkz. XlaBuilder::BitcastConvertType
.
TensorFlow'daki tf.bitcast
benzer şekilde, bir veri şeklinden hedef şekle kadar öğe bazında bir bitcast işlemi gerçekleştirir. Giriş ve çıkış boyutu eşleşmelidir: örneğin s32
öğeleri, bitcast rutini aracılığıyla f32
öğeleri haline gelir ve bir s32
öğesi, dört s8
öğesi haline gelir. Bitcast, düşük seviyeli bir dönüşüm olarak uygulanır, bu nedenle farklı kayan nokta temsillerine sahip makineler farklı sonuçlar verecektir.
BitcastConvertType(operand, new_element_type)
Argümanlar | Tip | Anlambilim |
---|---|---|
operand | XlaOp | Dims D'li T tipi dizi |
new_element_type | PrimitiveType | U tipi |
Dönüşümden önce ve sonra ilkel boyutun oranına göre değişecek olan son boyut dışında, işlenenin ve hedef şeklin boyutları eşleşmelidir.
Kaynak ve hedef öğe türleri tanımlama grupları olmamalıdır.
Bitcast-farklı genişlikteki ilkel türe dönüştürme
BitcastConvert
HLO talimatı, T'
tipi çıkış elemanının boyutunun T
giriş elemanının boyutuna eşit olmadığı durumu destekler. Tüm işlem kavramsal olarak bir bit yayını olduğundan ve temeldeki baytları değiştirmediğinden, çıktı öğesinin şeklinin değişmesi gerekir. B = sizeof(T), B' = sizeof(T')
için iki olası durum vardır.
İlk olarak, B > B'
olduğunda, çıktı şekli B/B'
boyutunda yeni bir en küçük boyut alır. Örneğin:
f16[10,2]{1,0} %output = f16[10,2]{1,0} bitcast-convert(f32[10]{0} %input)
Etkili skalerler için kural aynı kalır:
f16[2]{0} %output = f16[2]{0} bitcast-convert(f32[] %input)
Alternatif olarak, B' > B
için komut, girdi şeklinin son mantıksal boyutunun B'/B
eşit olmasını gerektirir ve bu boyut, dönüştürme sırasında düşürülür:
f32[10]{0} %output = f32[10]{0} bitcast-convert(f16[10,2]{1,0} %input)
Farklı bit genişlikleri arasındaki dönüşümlerin öğe bazında olmadığını unutmayın.
Yayın
Ayrıca bkz. XlaBuilder::Broadcast
.
Dizideki verileri çoğaltarak diziye boyutlar ekler.
Broadcast(operand, broadcast_sizes)
Argümanlar | Tip | Anlambilim |
---|---|---|
operand | XlaOp | Çoğaltılacak dizi |
broadcast_sizes | ArraySlice<int64> | Yeni boyutların boyutları |
Yeni boyutlar sola eklenir, yani eğer broadcast_sizes
{a0, ..., aN}
değerlerine sahipse ve işlenen şekli {b0, ..., bM}
boyutlarına sahipse, çıktı şeklinin boyutları {a0, ..., aN, b0, ..., bM}
.
Yeni boyutlar işlenenin kopyalarına indekslenir, yani
output[i0, ..., iN, j0, ..., jM] = operand[j0, ..., jM]
Örneğin, operand
2.0f
değerine sahip bir skaler f32
ise ve broadcast_sizes
{2, 3}
ise, sonuç f32[2, 3]
şeklinde bir dizi olacaktır ve sonuçtaki tüm değerler 2.0f
olacaktır.
BroadcastInDim
Ayrıca bkz. XlaBuilder::BroadcastInDim
.
Dizideki verileri çoğaltarak dizinin boyutunu ve sıralamasını genişletir.
BroadcastInDim(operand, out_dim_size, broadcast_dimensions)
Argümanlar | Tip | Anlambilim |
---|---|---|
operand | XlaOp | Çoğaltılacak dizi |
out_dim_size | ArraySlice<int64> | Hedef şeklin boyutlarının boyutları |
broadcast_dimensions | ArraySlice<int64> | İşlenen şeklinin her bir boyutu, hedef şekildeki hangi boyuta karşılık gelir? |
Yayına benzer, ancak herhangi bir yere boyut eklenmesine ve mevcut boyutların boyut 1 ile genişletilmesine olanak tanır.
operand
out_dim_size
tarafından tanımlanan şekle yayınlanır. broadcast_dimensions
operand
boyutlarını hedef şeklin boyutlarıyla eşleştirir, yani işlenenin i'inci boyutu, çıktı şeklinin yayın_dimension[i]'inci boyutuyla eşlenir. operand
boyutları 1 boyutunda olmalı veya eşlendikleri çıktı şeklindeki boyutla aynı boyutta olmalıdır. Geri kalan boyutlar boyut 1'in boyutlarıyla doldurulur. Dejenere boyutlu yayın daha sonra çıktı şekline ulaşmak için bu dejenere boyutlar boyunca yayın yapar. Anlambilim yayın sayfasında ayrıntılı olarak anlatılmıştır.
Arama
Ayrıca bkz. XlaBuilder::Call
.
Verilen bağımsız değişkenlerle bir hesaplama başlatır.
Call(computation, args...)
Argümanlar | Tip | Anlambilim |
---|---|---|
computation | XlaComputation | T_0, T_1, ..., T_{N-1} -> S tipinin isteğe bağlı N parametreyle hesaplanması |
args | N XlaOp dizisi | İsteğe bağlı türde N bağımsız değişken |
args
niteliği ve türleri computation
parametreleriyle eşleşmelidir. args
olmamasına izin verilir.
Cholesky
Ayrıca bkz. XlaBuilder::Cholesky
.
Bir dizi simetrik (Hermitsel) pozitif tanımlı matrisin Cholesky ayrıştırmasını hesaplar.
Cholesky(a, lower)
Argümanlar | Tip | Anlambilim |
---|---|---|
a | XlaOp | karmaşık veya kayan nokta tipinde bir sıralama > 2 dizisi. |
lower | bool | a üst veya alt üçgeninin kullanılıp kullanılmayacağı. |
lower
true
ise, $a = l olacak şekilde alt üçgensel matrisler l
yi hesaplar. l^T$. lower
false
ise üst üçgen matrisleri u
\(a = u^T . u\)olacak şekilde hesaplar.
Giriş verileri, lower
değerine bağlı olarak a
öğesinin yalnızca alt/üst üçgeninden okunur. Diğer üçgenin değerleri göz ardı edilir. Çıkış verileri aynı üçgen içinde döndürülür; diğer üçgendeki değerler uygulama tanımlıdır ve herhangi bir şey olabilir.
a
derecesi 2'den büyükse, a
, bir matris kümesi olarak ele alınır; burada küçük 2 boyut dışındaki tüm boyutlar yığın boyutlarıdır.
Eğer a
simetrik (Hermitian) pozitif tanımlı değilse, sonuç uygulama tanımlıdır.
Kelepçe
Ayrıca bkz. XlaBuilder::Clamp
.
Bir işleneni minimum ve maksimum değer arasındaki aralığa sıkıştırır.
Clamp(min, operand, max)
Argümanlar | Tip | Anlambilim |
---|---|---|
min | XlaOp | T tipi dizi |
operand | XlaOp | T tipi dizi |
max | XlaOp | T tipi dizi |
Bir işlenen ile minimum ve maksimum değerler verildiğinde, minimum ve maksimum arasındaki aralıktaysa işleneni döndürür, aksi takdirde işlenen bu aralığın altındaysa minimum değeri veya işlenen bu aralığın üzerindeyse maksimum değeri döndürür. Yani, clamp(a, x, b) = min(max(a, x), b)
.
Her üç dizi de aynı şekilde olmalıdır. Alternatif olarak, sınırlı bir yayın biçimi olarak min
ve/veya max
, T
türünde bir skaler olabilir.
Skaler min
ve max
ile örnek:
let operand: s32[3] = {-1, 5, 9};
let min: s32 = 0;
let max: s32 = 6;
==>
Clamp(min, operand, max) = s32[3]{0, 5, 6};
Yıkılmak
Ayrıca bkz. XlaBuilder::Collapse
ve tf.reshape
işlemi.
Bir dizinin boyutlarını tek boyuta daraltır.
Collapse(operand, dimensions)
Argümanlar | Tip | Anlambilim |
---|---|---|
operand | XlaOp | T tipi dizi |
dimensions | int64 vektör | T boyutlarının sıralı, ardışık alt kümesi. |
Daralt, işlenenin boyutlarının verilen alt kümesini tek bir boyutla değiştirir. Giriş bağımsız değişkenleri, T türünde isteğe bağlı bir dizi ve boyut endekslerinin derleme zamanı sabit bir vektörüdür. Boyut endeksleri, T boyutlarının sıralı (düşükten yükseğe boyut sayıları) ardışık bir alt kümesi olmalıdır. Dolayısıyla, {0, 1, 2}, {0, 1} veya {1, 2}'nin tümü geçerli boyut kümeleridir ancak {1, 0} veya {0, 2} değildir. Bunlar, değiştirdikleri boyut sıralamasında aynı konumda, yeni boyut boyutu orijinal boyut boyutlarının çarpımına eşit olacak şekilde tek bir yeni boyutla değiştirilir. dimensions
en düşük boyut sayısı, bu boyutları daraltan döngü yuvasındaki en yavaş değişen boyuttur (en büyük), en yüksek boyut numarası ise en hızlı değişendir (en küçük). Daha genel bir daraltma sıralaması gerekiyorsa tf.reshape
operatörüne bakın.
Örneğin v'nin 24 öğeden oluşan bir dizi olduğunu varsayalım:
let v = f32[4x2x3] { { {10, 11, 12}, {15, 16, 17} },
{ {20, 21, 22}, {25, 26, 27} },
{ {30, 31, 32}, {35, 36, 37} },
{ {40, 41, 42}, {45, 46, 47} } };
// Collapse to a single dimension, leaving one dimension.
let v012 = Collapse(v, {0,1,2});
then v012 == f32[24] {10, 11, 12, 15, 16, 17,
20, 21, 22, 25, 26, 27,
30, 31, 32, 35, 36, 37,
40, 41, 42, 45, 46, 47};
// Collapse the two lower dimensions, leaving two dimensions.
let v01 = Collapse(v, {0,1});
then v01 == f32[4x6] { {10, 11, 12, 15, 16, 17},
{20, 21, 22, 25, 26, 27},
{30, 31, 32, 35, 36, 37},
{40, 41, 42, 45, 46, 47} };
// Collapse the two higher dimensions, leaving two dimensions.
let v12 = Collapse(v, {1,2});
then v12 == f32[8x3] { {10, 11, 12},
{15, 16, 17},
{20, 21, 22},
{25, 26, 27},
{30, 31, 32},
{35, 36, 37},
{40, 41, 42},
{45, 46, 47} };
Toplu Permute
Ayrıca bkz. XlaBuilder::CollectivePermute
.
CollectivePermute, çapraz veri kopyaları gönderip alan toplu bir işlemdir.
CollectivePermute(operand, source_target_pairs)
Argümanlar | Tip | Anlambilim |
---|---|---|
operand | XlaOp | n boyutlu giriş dizisi |
source_target_pairs | <int64, int64> vektörü | (source_replica_id, target_replica_id) çiftlerinin listesi. Her çift için işlenen, kaynak kopyadan hedef kopyaya gönderilir. |
source_target_pair
aşağıdaki kısıtlamaların bulunduğunu unutmayın:
- Herhangi iki çift aynı hedef replika kimliğine sahip olmamalı ve aynı kaynak replika kimliğine sahip olmamalıdır.
- Bir kopya kimliği herhangi bir çiftte hedef değilse, o kopyadaki çıktı, girişle aynı şekle sahip 0'lardan oluşan bir tensördür.
Birleştir
Ayrıca bkz. XlaBuilder::ConcatInDim
.
Concatenate, birden fazla dizi işleneninden bir dizi oluşturur. Dizi, giriş dizisi işlenenlerinin her biri ile aynı sıradadır (birbirleriyle aynı sırada olmalıdır) ve bağımsız değişkenleri belirtildikleri sırayla içerir.
Concatenate(operands..., dimension)
Argümanlar | Tip | Anlambilim |
---|---|---|
operands | N XlaOp dizisi | [L0, L1, ...] boyutlarına sahip T tipi N dizi. N >= 1 gerektirir. |
dimension | int64 | operands arasında birleştirilecek boyutu adlandıran [0, N) aralığındaki bir değer. |
dimension
haricinde tüm boyutlar aynı olmalıdır. Bunun nedeni XLA'nın "düzensiz" dizileri desteklememesidir. Ayrıca, sıra-0 değerlerinin birleştirilemeyeceğini unutmayın (çünkü birleştirmenin gerçekleştiği boyutu adlandırmak imkansızdır).
1 boyutlu örnek:
Concat({ {2, 3}, {4, 5}, {6, 7} }, 0)
>>> {2, 3, 4, 5, 6, 7}
2 boyutlu örnek:
let a = {
{1, 2},
{3, 4},
{5, 6},
};
let b = {
{7, 8},
};
Concat({a, b}, 0)
>>> {
{1, 2},
{3, 4},
{5, 6},
{7, 8},
}
Diyagram:
Koşullu
Ayrıca bkz. XlaBuilder::Conditional
.
Conditional(pred, true_operand, true_computation, false_operand, false_computation)
Argümanlar | Tip | Anlambilim |
---|---|---|
pred | XlaOp | PRED tipi skaler |
true_operand | XlaOp | \(T_0\)tipi bağımsız değişken |
true_computation | XlaComputation | \(T_0 \to S\)türünün hesaplanması |
false_operand | XlaOp | \(T_1\)türü argümanı |
false_computation | XlaComputation | \(T_1 \to S\)türünün hesaplanması |
pred
true
ise true_computation
, pred
false
ise false_computation
çalıştırır ve sonucu döndürür.
true_computation
\(T_0\) tipinde tek bir argüman almalıdır ve aynı tipte olması gereken true_operand
ile çağrılacaktır. false_computation
\(T_1\) tipinde tek bir argüman almalı ve aynı tipte olması gereken false_operand
ile çağrılmalıdır. true_computation
ve false_computation
döndürülen değerinin türü aynı olmalıdır.
pred
değerine bağlı olarak true_computation
ve false_computation
yalnızca birinin yürütüleceğini unutmayın.
Conditional(branch_index, branch_computations, branch_operands)
Argümanlar | Tip | Anlambilim |
---|---|---|
branch_index | XlaOp | S32 tipi skaler |
branch_computations | N XlaComputation dizisi | Xla \(T_0 \to S , T_1 \to S , ..., T_{N-1} \to S\)tipi hesaplamalar |
branch_operands | N XlaOp dizisi | \(T_0 , T_1 , ..., T_{N-1}\)türündeki bağımsız değişkenler |
branch_computations[branch_index]
çalıştırır ve sonucu döndürür. branch_index
< 0 veya >= N olan bir S32
ise, bu durumda branch_computations[N-1]
varsayılan dal olarak yürütülür.
Her branch_computations[b]
\(T_b\) türünde tek bir argüman almalıdır ve aynı türde olması gereken branch_operands[b]
ile çağrılacaktır. Her branch_computations[b]
döndürülen değerinin türü aynı olmalıdır.
branch_index
değerine bağlı olarak branch_computations
yalnızca birinin yürütüleceğini unutmayın.
Dönüşüm (evrişim)
Ayrıca bkz. XlaBuilder::Conv
.
ConvWithGeneralPadding olarak, ancak dolgu, SAME veya VALID olarak kısa yoldan belirtilir. SAME dolgusu girişi ( lhs
) sıfırlarla doldurur, böylece uzun adımlarla ilerleme dikkate alınmadığında çıktı girişle aynı şekle sahip olur. GEÇERLİ dolgu, yalnızca dolgu yok anlamına gelir.
ConvWithGeneralPadding (evrişim)
Ayrıca bkz. XlaBuilder::ConvWithGeneralPadding
.
Sinir ağlarında kullanılan türden bir evrişimi hesaplar. Burada bir evrişim, n boyutlu bir taban alanı boyunca hareket eden n boyutlu bir pencere olarak düşünülebilir ve pencerenin olası her konumu için bir hesaplama gerçekleştirilir.
Argümanlar | Tip | Anlambilim |
---|---|---|
lhs | XlaOp | sıra n+2 giriş dizisi |
rhs | XlaOp | rütbe n+2 çekirdek ağırlıkları dizisi |
window_strides | ArraySlice<int64> | çekirdek adımlarının nd dizisi |
padding | ArraySlice< pair<int64,int64>> | (düşük, yüksek) dolgu dizisi |
lhs_dilation | ArraySlice<int64> | nd lhs genişleme faktörü dizisi |
rhs_dilation | ArraySlice<int64> | nd rhs genişleme faktörü dizisi |
feature_group_count | int64 | özellik gruplarının sayısı |
batch_group_count | int64 | parti gruplarının sayısı |
Uzamsal boyutların sayısı n olsun. lhs
argümanı, taban alanını tanımlayan n+2 sıralı bir dizidir. Her ne kadar rhs de bir girdi olsa da buna girdi denir. Bir sinir ağında bunlar giriş aktivasyonlarıdır. n+2 boyut şu sırayla verilmiştir:
-
batch
: Bu boyuttaki her koordinat, evrişimin gerçekleştirildiği bağımsız bir girişi temsil eder. -
z/depth/features
: Taban alanındaki her (y,x) konumu, kendisiyle ilişkilendirilmiş ve bu boyuta giren bir vektöre sahiptir. -
spatial_dims
: Pencerenin hareket ettiği taban alanını tanımlayann
uzamsal boyutu açıklar.
rhs
argümanı, evrişimli filtreyi/çekirdeği/pencereyi tanımlayan n+2 dereceli bir dizidir. Boyutlar bu sıraya göre:
-
output-z
: Çıktınınz
boyutu. -
input-z
: Bu boyutun boyutu çarpıfeature_group_count
lhs cinsindenz
boyutunun boyutuna eşit olmalıdır. -
spatial_dims
: Taban alanı boyunca hareket eden pencereyi tanımlayann
mekansal boyutu açıklar.
window_strides
bağımsız değişkeni, evrişimli pencerenin uzamsal boyutlardaki adımını belirtir. Örneğin, birinci uzaysal boyuttaki adım 3 ise pencere yalnızca birinci uzaysal indeksin 3'e bölünebildiği koordinatlara yerleştirilebilir.
padding
argümanı, taban alanına uygulanacak sıfır dolgu miktarını belirtir. Dolgu miktarı negatif olabilir; negatif dolgunun mutlak değeri, evrişim yapılmadan önce belirtilen boyuttan kaldırılacak öğe sayısını gösterir. padding[0]
y
boyutu için dolguyu belirtir ve padding[1]
x
boyutu için dolguyu belirtir. Her çiftin birinci elemanı düşük dolgu, ikinci elemanı ise yüksek dolgudur. Düşük dolgulama daha düşük indeksler yönünde uygulanırken, yüksek dolgulama daha yüksek indeksler yönünde uygulanır. Örneğin padding[1]
(2,3)
ise ikinci uzaysal boyutta solda 2 sıfır, sağda 3 sıfır dolgu olacaktır. Dolgu kullanmak, evrişimi yapmadan önce aynı sıfır değerlerini girişe ( lhs
) eklemeye eşdeğerdir.
lhs_dilation
ve rhs_dilation
bağımsız değişkenleri, her uzamsal boyutta sırasıyla lhs ve rhs'ye uygulanacak genişleme faktörünü belirtir. Uzamsal boyuttaki genişleme faktörü d ise, bu boyuttaki girişlerin her birinin arasına örtülü olarak d-1 delikleri yerleştirilerek dizinin boyutu artırılır. Delikler, evrişim için sıfır anlamına gelen, işlem yapılmayan bir değerle doldurulur.
Rhs'nin genişlemesine aynı zamanda atröz evrişim de denir. Daha fazla ayrıntı için bkz tf.nn.atrous_conv2d
. Lhs'nin genişlemesine aynı zamanda transpoze evrişim de denir. Daha fazla ayrıntı için bkz tf.nn.conv2d_transpose
.
feature_group_count
bağımsız değişkeni (varsayılan değer 1), gruplandırılmış evrişimler için kullanılabilir. feature_group_count
hem giriş hem de çıkış özellik boyutunun böleni olması gerekir. feature_group_count
1'den büyük olması, kavramsal olarak giriş ve çıkış özellik boyutunun ve rhs
çıktı özellik boyutunun birçok feature_group_count
grubuna eşit şekilde bölündüğü anlamına gelir; her grup, ardışık bir özellik alt dizisinden oluşur. rhs
giriş özelliği boyutunun, lhs
giriş özelliği boyutunun feature_group_count
bölünmesine eşit olması gerekir (bu nedenle zaten bir giriş özellikleri grubunun boyutuna sahiptir). İ'inci gruplar, birçok ayrı evrişim için feature_group_count
hesaplamak için birlikte kullanılır. Bu evrişimlerin sonuçları çıktı özelliği boyutunda birleştirilir.
Derinlemesine evrişim için feature_group_count
argümanı giriş özelliği boyutuna ayarlanacak ve filtre, [filter_height, filter_width, in_channels, channel_multiplier]
den [filter_height, filter_width, 1, in_channels * channel_multiplier]
a yeniden şekillendirilecektir. Daha fazla ayrıntı için bkz tf.nn.depthwise_conv2d
.
batch_group_count
(varsayılan değer 1) bağımsız değişkeni, geri yayılım sırasında gruplandırılmış filtreler için kullanılabilir. batch_group_count
lhs
(giriş) toplu iş boyutunun boyutunun bir böleni olması gerekir. batch_group_count
1'den büyük olması, çıktı toplu boyutunun input batch / batch_group_count
boyutunda olması gerektiği anlamına gelir. batch_group_count
çıktı özelliği boyutunun bir böleni olmalıdır.
Çıktı şekli şu boyutlara şu sırayla sahiptir:
-
batch
: Bu boyutun boyutu ilebatch_group_count
lhs cinsindenbatch
boyutunun boyutuna eşit olmalıdır. -
z
: Çekirdekteki (rhs
)output-z
ile aynı boyuttadır. -
spatial_dims
: Evrişimli pencerenin her geçerli yerleşimi için bir değer.
Yukarıdaki şekil, batch_group_count
alanının nasıl çalıştığını göstermektedir. Etkili bir şekilde, her lhs grubunu batch_group_count
gruplarına ayırıyoruz ve aynısını çıktı özellikleri için yapıyoruz. Daha sonra, bu grupların her biri için ikili evrişimler yapıyoruz ve çıktıyı, çıktı özelliği boyutu boyunca birleştiriyoruz. Diğer tüm boyutların (özellik ve mekansal) operasyonel semantiği aynı kalır.
Evrişimli pencerenin geçerli yerleşimleri, adımlara ve doldurmadan sonraki taban alanının boyutuna göre belirlenir.
Bir evrişimin ne yaptığını açıklamak için, bir 2d evrişimi düşünün ve çıktıda bazı sabit batch
z
, y
, x
koordinatlarını seçin. O halde (y,x)
pencerenin bir köşesinin taban alanı içindeki konumudur (örneğin, uzaysal boyutları nasıl yorumladığınıza bağlı olarak sol üst köşe). Artık her 2 boyutlu noktanın 1 boyutlu bir vektörle ilişkilendirildiği taban alanından alınan 2 boyutlu bir penceremiz var, böylece 3 boyutlu bir kutu elde ederiz. Evrişimli çekirdekten, z
çıktı koordinatını sabitlediğimizden, ayrıca bir 3 boyutlu kutumuz var. İki kutu aynı boyutlara sahiptir, dolayısıyla iki kutu arasındaki eleman bazında çarpımların toplamını alabiliriz (nokta çarpıma benzer şekilde). Çıkış değeri budur.
output-z
örneğin 5 ise, pencerenin her konumunun çıktıda çıktının z
boyutunda 5 değer ürettiğini unutmayın. Bu değerler evrişimli çekirdeğin hangi bölümünün kullanıldığına göre farklılık gösterir; her output-z
koordinatı için kullanılan ayrı bir 3 boyutlu değer kutusu vardır. Yani bunu her biri için farklı filtreye sahip 5 ayrı evrişim olarak düşünebilirsiniz.
Dolgu ve uzun adımlarla 2 boyutlu bir evrişimin sözde kodu:
for (b, oz, oy, ox) { // output coordinates
value = 0;
for (iz, ky, kx) { // kernel coordinates and input z
iy = oy*stride_y + ky - pad_low_y;
ix = ox*stride_x + kx - pad_low_x;
if ((iy, ix) inside the base area considered without padding) {
value += input(b, iz, iy, ix) * kernel(oz, iz, ky, kx);
}
}
output(b, oz, oy, ox) = value;
}
ConvertElementType
Ayrıca bkz. XlaBuilder::ConvertElementType
.
C++'daki öğe bazında static_cast
benzer şekilde, bir veri şeklinden bir hedef şekle öğe bazında dönüştürme işlemi gerçekleştirir. Boyutlar eşleşmelidir ve dönüşüm öğe bazındadır; örneğin s32
öğeleri, s32
f32
dönüştürme rutini aracılığıyla f32
öğeleri haline gelir.
ConvertElementType(operand, new_element_type)
Argümanlar | Tip | Anlambilim |
---|---|---|
operand | XlaOp | Dims D'li T tipi dizi |
new_element_type | PrimitiveType | U tipi |
İşlenenin ve hedef şeklin boyutları eşleşmelidir. Kaynak ve hedef öğe türleri tanımlama grupları olmamalıdır.
T=s32
U=f32
gibi bir dönüştürme, yuvarlaktan en yakına çift gibi normalleştirici bir int'den kayan noktaya dönüştürme rutini gerçekleştirecektir.
let a: s32[3] = {0, 1, 2};
let b: f32[3] = convert(a, f32);
then b == f32[3]{0.0, 1.0, 2.0}
Çapraz Çoğaltma Toplamı
Toplama hesaplamasıyla AllReduce
gerçekleştirir.
Özel Çağrı
Ayrıca bkz. XlaBuilder::CustomCall
.
Bir hesaplama içinde kullanıcı tarafından sağlanan bir işlevi çağırın.
CustomCall(target_name, args..., shape)
Argümanlar | Tip | Anlambilim |
---|---|---|
target_name | string | Fonksiyonun adı. Bu sembol adını hedef alan bir çağrı talimatı yayınlanacaktır. |
args | N XlaOp dizisi | İşleve aktarılacak isteğe bağlı türde N bağımsız değişken. |
shape | Shape | Fonksiyonun çıkış şekli |
Argümanların niteliğine veya türüne bakılmaksızın işlev imzası aynıdır:
extern "C" void target_name(void* out, void** in);
Örneğin CustomCall şu şekilde kullanılıyorsa:
let x = f32[2] {1,2};
let y = f32[2x3] { {10, 20, 30}, {40, 50, 60} };
CustomCall("myfunc", {x, y}, f32[3x3])
İşte myfunc
uygulamasının bir örneği:
extern "C" void myfunc(void* out, void** in) {
float (&x)[2] = *static_cast<float(*)[2]>(in[0]);
float (&y)[2][3] = *static_cast<float(*)[2][3]>(in[1]);
EXPECT_EQ(1, x[0]);
EXPECT_EQ(2, x[1]);
EXPECT_EQ(10, y[0][0]);
EXPECT_EQ(20, y[0][1]);
EXPECT_EQ(30, y[0][2]);
EXPECT_EQ(40, y[1][0]);
EXPECT_EQ(50, y[1][1]);
EXPECT_EQ(60, y[1][2]);
float (&z)[3][3] = *static_cast<float(*)[3][3]>(out);
z[0][0] = x[1] + y[1][0];
// ...
}
Kullanıcı tarafından sağlanan işlevin yan etkileri olmamalıdır ve yürütülmesi kusursuz olmalıdır.
Nokta
Ayrıca bkz. XlaBuilder::Dot
.
Dot(lhs, rhs)
Argümanlar | Tip | Anlambilim |
---|---|---|
lhs | XlaOp | T tipi dizi |
rhs | XlaOp | T tipi dizi |
Bu işlemin tam anlamı işlenenlerin sırasına bağlıdır:
Giriş | Çıktı | Anlambilim |
---|---|---|
vektör [n] dot vektör [n] | skaler | vektör nokta çarpımı |
matris [mxk] dot vektör [k] | vektör [m] | matris-vektör çarpımı |
matris [mxk] dot matris [kxn] | matris [mxn] | matris-matris çarpımı |
İşlem, lhs
ikinci boyutu (veya derece 1'e sahipse birincisi) ve rhs
birinci boyutu üzerindeki çarpımların toplamını gerçekleştirir. Bunlar "daralmış" boyutlardır. lhs
ve rhs
daraltılmış boyutları aynı boyutta olmalıdır. Uygulamada, vektörler arasında nokta çarpımlar, vektör/matris çarpımları veya matris/matris çarpımları gerçekleştirmek için kullanılabilir.
NoktaGenel
Ayrıca bkz. XlaBuilder::DotGeneral
.
DotGeneral(lhs, rhs, dimension_numbers)
Argümanlar | Tip | Anlambilim |
---|---|---|
lhs | XlaOp | T tipi dizi |
rhs | XlaOp | T tipi dizi |
dimension_numbers | DotDimensionNumbers | taahhüt ve parti boyut numaraları |
Dot'a benzer, ancak hem lhs
hem de rhs
için sözleşme ve toplu boyut numaralarının belirtilmesine olanak tanır.
DotDimensionNumbers Alanları | Tip | Anlambilim |
---|---|---|
lhs_contracting_dimensions | tekrarlanan int64 | lhs daralma boyut numaraları |
rhs_contracting_dimensions | tekrarlanan int64 | rhs daralma boyut numaraları |
lhs_batch_dimensions | tekrarlanan int64 | lhs toplu boyut numaraları |
rhs_batch_dimensions | tekrarlanan int64 | rhs toplu boyut numaraları |
DotGeneral, ürünlerin toplamını, dimension_numbers
belirtilen daralma boyutları üzerinden gerçekleştirir.
lhs
ve rhs
ilgili daralma boyut numaralarının aynı olması gerekmez ancak aynı boyut boyutlarına sahip olmaları gerekir.
Daraltma boyut numaralarına örnek:
lhs = { {1.0, 2.0, 3.0},
{4.0, 5.0, 6.0} }
rhs = { {1.0, 1.0, 1.0},
{2.0, 2.0, 2.0} }
DotDimensionNumbers dnums;
dnums.add_lhs_contracting_dimensions(1);
dnums.add_rhs_contracting_dimensions(1);
DotGeneral(lhs, rhs, dnums) -> { {6.0, 12.0},
{15.0, 30.0} }
lhs
ve rhs
ilişkili parti boyutu numaraları aynı boyut boyutlarına sahip olmalıdır.
Parti boyutu numaralarıyla örnek (toplu iş boyutu 2, 2x2 matrisler):
lhs = { { {1.0, 2.0},
{3.0, 4.0} },
{ {5.0, 6.0},
{7.0, 8.0} } }
rhs = { { {1.0, 0.0},
{0.0, 1.0} },
{ {1.0, 0.0},
{0.0, 1.0} } }
DotDimensionNumbers dnums;
dnums.add_lhs_contracting_dimensions(2);
dnums.add_rhs_contracting_dimensions(1);
dnums.add_lhs_batch_dimensions(0);
dnums.add_rhs_batch_dimensions(0);
DotGeneral(lhs, rhs, dnums) -> { { {1.0, 2.0},
{3.0, 4.0} },
{ {5.0, 6.0},
{7.0, 8.0} } }
Giriş | Çıktı | Anlambilim |
---|---|---|
[b0, m, k] dot [b0, k, n] | [b0, m, n] | toplu matmul |
[b0, b1, m, k] dot [b0, b1, k, n] | [b0, b1, m, n] | toplu matmul |
Sonuç olarak ortaya çıkan boyut numarası parti boyutuyla başlar, ardından lhs
daralmayan/toplu olmayan boyut ve son olarak rhs
daralmayan/toplu olmayan boyutla başlar.
Dinamik Dilim
Ayrıca bkz. XlaBuilder::DynamicSlice
.
DynamicSlice, dinamik start_indices
adresindeki giriş dizisinden bir alt dizi çıkarır. Her boyuttaki dilimin boyutu, her boyuttaki özel dilim aralıklarının bitiş noktasını belirten size_indices
ile iletilir: [başlangıç, başlangıç + boyut). start_indices
şekli, boyut boyutu operand
sırasına eşit olacak şekilde rütbe == 1 olmalıdır.
DynamicSlice(operand, start_indices, size_indices)
Argümanlar | Tip | Anlambilim |
---|---|---|
operand | XlaOp | T tipi N boyutlu dizi |
start_indices | N XlaOp dizisi | Her boyut için dilimin başlangıç indekslerini içeren N skaler tamsayıların listesi. Değer sıfırdan büyük veya sıfıra eşit olmalıdır. |
size_indices | ArraySlice<int64> | Her boyut için dilim boyutunu içeren N tam sayının listesi. Modulo boyut boyutunun kaydırılmasını önlemek için her değer kesinlikle sıfırdan büyük olmalı ve başlangıç + boyut, boyutun boyutundan küçük veya ona eşit olmalıdır. |
Etkili dilim indeksleri, dilim gerçekleştirilmeden önce [1, N)
deki her bir i
indeksi için aşağıdaki dönüşümün uygulanmasıyla hesaplanır:
start_indices[i] = clamp(start_indices[i], 0, operand.dimension_size[i] - size_indices[i])
Bu, çıkarılan dilimin işlenen dizisine göre her zaman sınırlar içinde olmasını sağlar. Dilim dönüşüm uygulanmadan önce sınırsızsa, dönüşümün bir etkisi yoktur.
1 boyutlu örnek:
let a = {0.0, 1.0, 2.0, 3.0, 4.0}
let s = {2}
DynamicSlice(a, s, {2}) produces:
{2.0, 3.0}
2 boyutlu örnek:
let b =
{ {0.0, 1.0, 2.0},
{3.0, 4.0, 5.0},
{6.0, 7.0, 8.0},
{9.0, 10.0, 11.0} }
let s = {2, 1}
DynamicSlice(b, s, {2, 2}) produces:
{ { 7.0, 8.0},
{10.0, 11.0} }
DynamicUpdateslice
Ayrıca bkz. XlaBuilder::DynamicUpdateSlice
.
DynamicUpdatesLice, start_indices
yazılmış bir dilim update
ile giriş dizisi operand
değeri olan bir sonuç oluşturur. update
şekli, güncellenen sonucun alt payının şeklini belirler. start_indices
şekli, boyut boyutu operand
sırasına eşit olan sıralama == 1 olmalıdır.
DynamicUpdateSlice(operand, update, start_indices)
Argümanlar | Tip | Semantik |
---|---|---|
operand | XlaOp | N Boyutlu T tipi T tipi |
update | XlaOp | N Dilim güncellemesini içeren T tipi T tipi. Güncelleme şeklinin her boyutu kesinlikle sıfırdan daha büyük olmalı ve Start + güncellemesi, sınır dışı güncelleme endeksleri üretmeyi önlemek için her boyut için işlenen boyutundan daha az veya eşit olmalıdır. |
start_indices | n XlaOp dizisi | Her boyut için dilimin başlangıç indekslerini içeren N skaler tamsayıların listesi. Değer sıfırdan daha büyük veya eşit olmalıdır. |
Etkili dilim indeksleri, dilimi gerçekleştirmeden önce [1, N)
her i
için aşağıdaki dönüşüm uygulanarak hesaplanır:
start_indices[i] = clamp(start_indices[i], 0, operand.dimension_size[i] - update.dimension_size[i])
Bu, güncellenmiş dilimin işlenen dizisine göre her zaman bağlı olmasını sağlar. Dilim dönüşüm uygulanmadan önce sınırsızsa, dönüşümün bir etkisi yoktur.
1 boyutlu örnek:
let a = {0.0, 1.0, 2.0, 3.0, 4.0}
let u = {5.0, 6.0}
let s = {2}
DynamicUpdateSlice(a, u, s) produces:
{0.0, 1.0, 5.0, 6.0, 4.0}
2 boyutlu örnek:
let b =
{ {0.0, 1.0, 2.0},
{3.0, 4.0, 5.0},
{6.0, 7.0, 8.0},
{9.0, 10.0, 11.0} }
let u =
{ {12.0, 13.0},
{14.0, 15.0},
{16.0, 17.0} }
let s = {1, 1}
DynamicUpdateSlice(b, u, s) produces:
{ {0.0, 1.0, 2.0},
{3.0, 12.0, 13.0},
{6.0, 14.0, 15.0},
{9.0, 16.0, 17.0} }
Element bazında ikili aritmetik operasyonlar
Ayrıca bkz. XlaBuilder::Add
.
Bir dizi element çapında ikili aritmetik işlem desteklenir.
Op(lhs, rhs)
Op
, Add
(ADD), Sub
(Çıkarma), Mul
(Çarpma), Div
(Bölüm), Rem
(Kalan), Max
(Maksimum), Min
(Minimum), LogicalAnd
(Mantıksal ve) veya LogicalOr
(mantıksal VEYA).
Argümanlar | Tip | Semantik |
---|---|---|
lhs | XlaOp | Sol taraftaki işlenen: T tipi Tip |
rhs | XlaOp | Sağ taraf işlenen: T tipi Tip |
Argümanların şekilleri benzer veya uyumlu olmalıdır. Şekillerin uyumlu olmasının ne anlama geldiğine dair yayın belgelerine bakın. Bir işlemin sonucu, iki giriş dizisinin yayınlanmasının bir sonucu olan bir şekle sahiptir. Bu varyantta, işlenenlerden biri bir skaler olmadıkça, farklı saflardaki diziler arasındaki işlemler desteklenmez .
Op
Rem
olduğunda, sonucun işareti temettüden alınır ve sonucun mutlak değeri her zaman bölenin mutlak değerinden daha azdır.
Tamsayı bölümü taşması (İmzalı/İmzasız Bölüm/Sıfır veya -1
ile INT_SMIN
Bölüm/Kalan Bölüm/Kalanlar) Uygulama tanımlı bir değer üretir.
Bu işlemler için farklı dereceli yayın desteğine sahip alternatif bir varyant vardır:
Op(lhs, rhs, broadcast_dimensions)
Op
yukarıdakilerle aynı olduğu yer. Operasyonun bu varyantı, farklı saflardaki diziler arasındaki aritmetik işlemler için kullanılmalıdır (bir vektöre bir matris eklemek gibi).
Ek broadcast_dimensions
işlenen, alt sıralı işlenen rütbesini daha yüksek rütbeli işlenen rütbesine kadar genişletmek için kullanılan bir dizgidir. broadcast_dimensions
alt sıradaki şeklinin boyutlarını daha yüksek sıradaki şeklin boyutlarıyla eşler. Genişletilmemiş şeklin kaldırılmamış boyutları birinci boyutun boyutları ile doldurulur. Dejenere-Boyut Yayınları daha sonra her iki işlenenlerin şekillerini eşitlemek için bu dejenere boyutlar boyunca şekilleri yayınlar. Semantik yayın sayfasında ayrıntılı olarak açıklanmaktadır.
Eleman-bazlı karşılaştırma işlemleri
Ayrıca bkz XlaBuilder::Eq
.
Bir dizi standart eleman-bilge ikili karşılaştırma işlemi desteklenir. Kayan nokta türleri karşılaştırılırken standart IEEE 754 Kayan Nokta Karşılaştırma semantiğinin geçerli olduğunu unutmayın.
Op(lhs, rhs)
Op
, Eq
(Eşit), Ne
(Eşit Değil), Ge
(daha büyük ya da eşit), Gt
(daha büyük), Le
(daha az veya eşit), Lt
(daha az). EQTOTalorder, NetotalOrder, GetotalOrder, GttotalOrder, LetotalOrder ve LttotalOrder, aynı işlevsellikleri sağlar, ancak -nan <-inf <-finite <-0 ile yüzen nokta sayıları üzerinde toplam bir siparişi desteklemeleri dışında aynı işlevsellikleri sağlar. <+0 < +sonlu < +inf < +nan.
Argümanlar | Tip | Semantik |
---|---|---|
lhs | XlaOp | Sol taraftaki işlenen: T tipi Tip |
rhs | XlaOp | Sağ taraf işlenen: T tipi Tip |
Argümanların şekilleri benzer veya uyumlu olmalıdır. Şekillerin uyumlu olmasının ne anlama geldiğine dair yayın belgelerine bakın. Bir işlemin sonucu, iki giriş dizisini PRED
eleman tipi ile yayınlamanın bir sonucu olan bir şekle sahiptir. Bu varyantta, işlenenlerden biri bir skaler olmadıkça, farklı saflardaki diziler arasındaki işlemler desteklenmez .
Bu işlemler için farklı dereceli yayın desteğine sahip alternatif bir varyant vardır:
Op(lhs, rhs, broadcast_dimensions)
Op
yukarıdakilerle aynı olduğu yer. İşlemin bu varyantı, farklı sıralardaki diziler arasındaki karşılaştırma işlemleri için kullanılmalıdır (bir vektöre bir matris eklemek gibi).
Ek broadcast_dimensions
işlenmesi, işlenenleri yayınlamak için kullanılacak boyutları belirten bir tamsayı dilimidir. Semantik yayın sayfasında ayrıntılı olarak açıklanmaktadır.
Eleman-Unary işlevleri
XLabuilder, bu öğe açısından unary işlevlerini destekler:
Abs(operand)
Element -Base abs x -> |x|
.
Ceil(operand)
Element -çapında tavan x -> ⌈x⌉
.
Cos(operand)
eleman -bilge kosinüs x -> cos(x)
.
Exp(operand)
eleman -bazlı doğal üstel x -> e^x
.
Floor(operand)
eleman -temel kat x -> ⌊x⌋
.
Imag(operand)
karmaşık (veya gerçek) bir şeklin element çapında hayali kısmı. x -> imag(x)
. İşlenen yüzer bir nokta türüyse, 0 döner.
IsFinite(operand)
operand
her elementinin sonlu olup olmadığını test eder, yani pozitif veya negatif sonsuzluk değildir ve NaN
değildir. Giriş ile aynı şekle sahip bir PRED
değeri dizisi döndürür, burada her bir öğenin true
olduğu ve yalnızca karşılık gelen giriş öğesi sonlu olması durumunda.
Log(operand)
element bazlı doğal logaritma x -> ln(x)
.
LogicalNot(operand)
Element -bazında mantıksal değil x -> !(x)
.
Logistic(operand)
element çapında lojistik fonksiyon hesaplama x -> logistic(x)
.
PopulationCount(operand)
operand
her elemanında ayarlanan bit sayısını hesaplar.
Neg(operand)
element çapında olumsuzluk x -> -x
.
Real(operand)
kompleks (veya gerçek) bir şeklin element olarak gerçek kısmı. x -> real(x)
. İşlenen bir yüzer nokta türüyse, aynı değeri döndürür.
Rsqrt(operand)
kare kök operasyonunun element bazında karşılıklı olarak karşılıklı. x -> 1.0 / sqrt(x)
.
Sign(operand)
Eleman -bazlı işaret işlemi x -> sgn(x)
nerede
\[\text{sgn}(x) = \begin{cases} -1 & x < 0\\ -0 & x = -0\\ NaN & x = NaN\\ +0 & x = +0\\ 1 & x > 0 \end{cases}\]
operand
tipinin karşılaştırma operatörünü kullanma.
Sqrt(operand)
eleman -kare kök işlemi x -> sqrt(x)
.
Cbrt(operand)
element bazında kübik kök operasyonu x -> cbrt(x)
.
Tanh(operand)
element -çapında hiperbolik teğet x -> tanh(x)
.
Round(operand)
element çapında yuvarlama, sıfırdan uzaklaşır.
RoundNearestEven(operand)
element bazında yuvarlama, en yakın olanla bağlar.
Argümanlar | Tip | Semantik |
---|---|---|
operand | XlaOp | İşlevin işlevi |
İşlev, operand
dizideki her bir öğeye uygulanır, bu da aynı şekle sahip bir dizi ile sonuçlanır. operand
için bir skaler olmasına izin verilir (Sıra 0).
FFT
XLA FFT işlemi, gerçek ve karmaşık girişler/çıkışlar için ileri ve ters Fourier dönüşümlerini uygular. 3 eksene kadar çok boyutlu FFT'ler desteklenir.
Ayrıca bkz XlaBuilder::Fft
.
Argümanlar | Tip | Semantik |
---|---|---|
operand | XlaOp | Fourier Dönüştürüyoruz. |
fft_type | FftType | Aşağıdaki tabloya bakın. |
fft_length | ArraySlice<int64> | Eksenlerin zaman alanı uzunlukları dönüştürülür. RFFT(fft_length=[16]) RFFT(fft_length=[17]) ile aynı çıkış şekline sahip olduğundan, özellikle IRFFT'nin en içteki ekseni sağ boyutlandırması için bu gereklidir. |
FftType | Semantik |
---|---|
FFT | İleri karmaşık-karmaşık FFT. Şekil değişmez. |
IFFT | Ters kompleks-karmaşık FFT. Şekil değişmez. |
RFFT | Gerçek-Karmaşa FFT'yi ileriye dönük. En içteki eksenin şekli, fft_length[-1] fft_length[-1] // 2 + 1 indirgenir. |
IRFFT | Tersine komplekse gerçek FFT (IE karmaşık alır, gerçek döner). En içteki eksenin şekli fft_length[-1] fft_length[-1] olmayan bir değer ise, dönüştürülmüş sinyalin kısmını 1 ila fft_length[-1] // 2 + 1 olarak genişletilir. fft_length[-1] // 2 + 1 girişler. |
Çok boyutlu FFT
1'den fazla fft_length
sağlandığında, bu en iç eksenlerin her birine bir FFT operasyonunun bir kaskadını uygulamak için eşdeğerdir. Gerçek-> karmaşık ve karmaşık ve gerçek durumlar için, en içteki eksen dönüşümünün (etkili bir şekilde) önce gerçekleştirildiğini (RFFT; son IRFFT için), bu yüzden en iç eksen boyutunu değiştiren eksendir. Diğer eksen dönüşümleri daha sonra karmaşık-> karmaşık olacaktır.
Uygulama ayrıntıları
CPU FFT, Eigen'in Tensorfft tarafından desteklenir. GPU FFT CUFFT kullanır.
Toplamak
XLA, bir giriş dizisinin birkaç dilimini (her biri potansiyel olarak farklı bir çalışma zamanı ofsetinde dilim) bir araya getirir.
Genel anlamsal
Ayrıca bkz. XlaBuilder::Gather
. Daha sezgisel bir açıklama için aşağıdaki "Gayri resmi açıklama" bölümüne bakın.
gather(operand, start_indices, offset_dims, collapsed_slice_dims, slice_sizes, start_index_map)
Argümanlar | Tip | Semantik |
---|---|---|
operand | XlaOp | Topladığımız dizi. |
start_indices | XlaOp | Topladığımız dilimlerin başlangıç indekslerini içeren dizi. |
index_vector_dim | int64 | start_indices başlangıç endekslerini "içeren" boyut. Ayrıntılı bir açıklama için aşağıya bakın. |
offset_dims | ArraySlice<int64> | İşlenenden dilimlenmiş bir diziye dengelenen çıkış şeklindeki boyut kümesi. |
slice_sizes | ArraySlice<int64> | slice_sizes[i] i boyutundaki dilim için sınırlardır. |
collapsed_slice_dims | ArraySlice<int64> | Her dilimdeki çökmüş boyut kümesi. Bu boyutların boyutu 1 olmalıdır. |
start_index_map | ArraySlice<int64> | start_indices endekslerin yasal endekslerle işlenenle nasıl eşleneceğini açıklayan bir harita. |
indices_are_sorted | bool | Endekslerin arayan tarafından sıralanması garanti edilip edilmeyeceği. |
unique_indices | bool | Endekslerin arayan tarafından benzersiz olacağı garanti edilip edilmediği. |
Kolaylık sağlamak için, offset_dims
batch_dims
olarak olmayan çıkış dizisindeki boyutları etiketliyoruz.
Çıktı, bir dizi sıralı batch_dims.size
+ offset_dims.size
.
operand.rank
offset_dims.size
ve collapsed_slice_dims.size
toplamına eşit olmalıdır. Ayrıca, slice_sizes.size
operand.rank
eşit olmalıdır.
index_vector_dim
start_indices.rank
eşit ise, start_indices
dolaylı olarak 1
boyuta sahip olduğunu düşünürüz (yani start_indices
şekil [6,7]
ve index_vector_dim
2 ise 2
ise, start_indices
şeklini [6,7,1]
olarak düşünürüz [6,7,1]
).
i
boyutu boyunca çıkış dizisinin sınırları aşağıdaki gibi hesaplanır:
Eğer
batch_dims
i
(start_indices.shape.dims
bazık
içinbatch_dims[k]
'e eşitse, o zamanstart_indices.shape
, atlamaindex_vector_dim
(yanik
k
index_vector_dim
vestart_indices.shape.dims
[k
+1
] aksi takdirde).offset_dims
(yanioffset_dims
[k
]k
ai
,collapsed_slice_dims
hesaba kattıktan sonraslice_sizes
karşılık gelen sınırları seçeriz (yaniadjusted_slice_sizes
adjusted_slice_sizes
slice_sizes
slice_esimscollapsed_slice_dims
k
capped_slices remeed ).
Resmi olarak, belirli bir Out
In
karşılık gelen işlenen endeksi aşağıdaki gibi hesaplanır:
G
= {Out
[k
]batch_dims
} 'dek
için olsun.S
S
i
] =start_indices
[kombine (G
,i
)] olarak dilimlemek içinG
kullanın (a, b) B'yiindex_vector_dim
konumuna ekler.G
boş olsa bile bunun iyi tanımlandığını unutmayın. :G
boşsa,S
=start_indices
.S
S
S
operand
in
başlangıç dizinistart_index_map
. Daha kesin:S
in
[start_index_map
[k
]] =S
[k
]k
<start_index_map.size
ise.S
in
_
] =0
aksi takdirde.
Endeksleri Ofset
Out
collapsed_slice_dims
setine göre dağıtarakoperand
in
birO
oluşturun. Daha kesin:O
in
[remapped_offset_dims
(k
)] =Out
[offset_dims
[k
]]k
<offset_dims.size
(remapped_offset_dims
aşağıda tanımlanmışsa).O
in
[_
] =0
aksi takdirde.
In
O
sin
+S
in
WHERE + element-temel eklenir.
remapped_offset_dims
[ 0
, offset_dims.size
) ve aralık [ 0
, operand.rank
) \ collapsed_slice_dims
alanına sahip monotonik bir işlevdir. remapped_offset_dims
2
collapsed_slice_dims
0
offset_dims.size
4
0
6
operand.rank
1
1
3
2
4
3
5
indices_are_sorted
true olarak ayarlanmışsa, XLA start_indices
kullanıcı tarafından sıralandığını (artan start_index_map
siparişinde) varsayabilir. Eğer değilse, anlambilim uygulama tanımlanır.
unique_indices
true olarak ayarlanmışsa, XLA dağılmış tüm öğelerin benzersiz olduğunu varsayabilir. Böylece XLA atomik olmayan operasyonları kullanabilir. unique_indices
true olarak ayarlanmışsa ve dağılmış endeksler benzersiz değilse, anlambilim uygulama tanımlanır.
Gayri resmi açıklama ve örnekler
Gayri resmi olarak, Out
dizisindeki her dizin, işlenen dizisinde aşağıdaki gibi hesaplanan bir E
öğesine karşılık gelir:
start_indices
bir başlangıç dizinine bakmak içinOut
parti boyutlarını kullanıyoruz.Başlangıç dizinini (boyutu işlenenden daha az olabilen)
operand
"tam" başlangıç dizinine eşlemek içinstart_index_map
kullanıyoruz.Tam başlangıç dizinini kullanarak
slice_sizes
boyutlarında bir dilim dinamik dilim.collapsed_slice_dims
boyutlarını çökerterek dilimi yeniden şekillendiriyoruz. Çökmüş tüm dilim boyutlarının 1'i olması gerektiğinden, bu yeniden şekillendirme her zaman yasaldır.Out
dizinine karşılık gelen giriş öğesiniE
Out
için bu dilime indeks için Outset Boyutlarını kullanıyoruz.
index_vector_dim
aşağıdaki örneklerde start_indices.rank
- 1
olarak ayarlanmıştır. index_vector_dim
için daha ilginç değerler işlemi temelde değiştirmez, ancak görsel gösterimi daha hantal hale getirir.
Yukarıdakilerin hepsinin birbirine nasıl uyduğuna dair bir sezgi elde etmek için, [16,11]
dizisinden 5 dilim şekil [8,6]
toplayan bir örneğe bakalım. Bir dilimin [16,11]
dizisine konumu, şekil S64[2]
'nin bir dizin vektörü olarak temsil edilebilir, böylece 5 konum kümesi bir S64[5,2]
dizisi olarak temsil edilebilir.
Toplama işleminin davranışı daha sonra, çıkış şeklindeki bir dizin olan [ G
, O
0
, O
1
] alan bir dizin dönüşümü olarak tasvir edilebilir ve giriş dizisindeki bir öğeye aşağıdaki şekilde eşleştirebilir:
İlk olarak Golla Endeksleri dizisinden G
kullanılarak bir ( X
, Y
) vektör seçiyoruz. Dizin [ G
, O
0
, O
1
] 'deki çıkış dizisindeki eleman daha sonra indeks [ X
+ O
0
, Y
+ O
1
]' deki giriş dizisindeki elemandır.
slice_sizes
, O 0
ve O 1
aralığına karar veren [8,6]
dır ve bu da dilimin sınırlarına karar verir.
Bu toplama işlemi, parti boyutu olarak G
ile parti dinamik bir dilim olarak işlev görür.
Toplama endeksleri çok boyutlu olabilir. Örneğin, yukarıdaki örneğin bir "dizin topla" şekil dizisini kullanarak [4,5,2]
daha genel bir versiyonu şöyle endeksleri tercüme edecektir:
Yine, bu, toplu boyutlar olarak parti dinamik bir dilim G
0
ve G
1
olarak işlev görür. Dilim boyutu hala [8,6]
.
XLA'daki toplanma operasyonu, yukarıda belirtilen gayri resmi semantiği aşağıdaki şekillerde genelleştirir:
Çıkış şeklindeki hangi boyutların ofset boyutları olduğunu (son örnekte
O
0
,O
1
içeren boyutlar) yapılandırabiliriz. Çıkış toplu boyutları (son örnekteG
0
,G
1
içeren boyutlar), ofset boyutları olmayan çıkış boyutları olarak tanımlanır.Çıkış şeklinde açıkça bulunan çıkış ofseti boyutlarının sayısı giriş sıralamasından daha küçük olabilir. Açıkça
collapsed_slice_dims
olarak listelenen bu "eksik" boyutların bir dilim boyutu1
olması gerekir.1
dilim boyutuna sahip oldukları için onlar için tek geçerli dizin0
ve bunları elden çıkarmak belirsizlik getirmez."Endeksleri Gat" dizisinden çıkarılan dilim ((
X
,Y
) son örnekte) giriş dizisi sıralamasından daha az öğeye sahip olabilir ve açık bir eşleme, dizinin giriş ile aynı sıraya sahip olacak şekilde nasıl genişletilmesi gerektiğini belirler. .
Son bir örnek olarak, (2) ve (3) 'yi tf.gather_nd
uygulamak için kullanıyoruz:
G
0
ve G
1
, başlangıç dizininin yalnızca bir elemanı olan X
olması dışında, her zamanki gibi toplama endeksleri dizisinden bir başlangıç dizinini dilimlemek için kullanılır. Benzer şekilde, O
0
değeri olan yalnızca bir çıkış ofseti dizin vardır. Bununla birlikte, giriş dizisine indeks olarak kullanılmadan önce, bunlar "dizin eşleme toplama" (resmi açıklamada start_index_map
) ve "ofset eşleme" (resmi açıklamada remapped_offset_dims
) [ X
, 0] ve [x, 0
] ve [ 0
, O
0
], [ X
, O
0
] 'a eklenir. Başka bir deyişle, çıkış indeksi [ G
0
, G
1
, O
0
], bize tf.gather_nd
için anlambilim veren giriş dizinine [ GatherIndices
[ G
0
, G
1
, 0
], O
0
] eşler.
Bu durum için slice_sizes
[1,11]
. Sezgisel olarak bu, toplama endeksleri dizisindeki her dizin X
bir satır seçtiği ve sonucun tüm bu satırların birleştirilmesi olduğu anlamına gelir.
GetDImensionsionSize
Ayrıca bkz XlaBuilder::GetDimensionSize
.
İşlenenlerin verilen boyutunun boyutunu döndürür. İşlenen dizi şekillendirilmelidir.
GetDimensionSize(operand, dimension)
Argümanlar | Tip | Semantik |
---|---|---|
operand | XlaOp | n Boyutlu Giriş Dizi |
dimension | int64 | Boyutu belirten [0, n) aralığında bir değer |
SetDimensionsionSize
Ayrıca bkz XlaBuilder::SetDimensionSize
.
XLAOP'un verilen boyutunun dinamik boyutunu ayarlar. İşlenen dizi şekillendirilmelidir.
SetDimensionSize(operand, size, dimension)
Argümanlar | Tip | Semantik |
---|---|---|
operand | XlaOp | n Boyutlu Giriş Dizisi. |
size | XlaOp | INT32, çalışma zamanı dinamik boyutunu temsil eder. |
dimension | int64 | Boyutu belirten [0, n) aralığındaki bir değer. |
Derleyici tarafından izlenen dinamik boyut ile sonuç olarak işlenenden geçin.
Yastıklı değerler aşağı akış azaltma ops ile göz ardı edilecektir.
let v: f32[10] = f32[10]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
let five: s32 = 5;
let six: s32 = 6;
// Setting dynamic dimension size doesn't change the upper bound of the static
// shape.
let padded_v_five: f32[10] = set_dimension_size(v, five, /*dimension=*/0);
let padded_v_six: f32[10] = set_dimension_size(v, six, /*dimension=*/0);
// sum == 1 + 2 + 3 + 4 + 5
let sum:f32[] = reduce_sum(padded_v_five);
// product == 1 * 2 * 3 * 4 * 5
let product:f32[] = reduce_product(padded_v_five);
// Changing padding size will yield different result.
// sum == 1 + 2 + 3 + 4 + 5 + 6
let sum:f32[] = reduce_sum(padded_v_six);
GettupleElement
Ayrıca bkz XlaBuilder::GetTupleElement
.
Dizma süresi sabit bir değere sahip bir tuple indeksler.
Değer, şekil çıkarımının ortaya çıkan değerin türünü belirleyebilmesi için bir derleme zamanı uyumlu olmalıdır.
Bu, C ++ 'da std::get<int N>(t)
için benzerdir. Kavramsal olarak:
let v: f32[10] = f32[10]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
let s: s32 = 5;
let t: (f32[10], s32) = tuple(v, s);
let element_1: s32 = gettupleelement(t, 1); // Inferred shape matches s32.
Ayrıca bkz tf.tuple
.
İhlal etmek
Ayrıca bkz. XlaBuilder::Infeed
.
Infeed(shape)
Argüman | Tip | Semantik |
---|---|---|
shape | Shape | INFEED arayüzünden okunan verilerin şekli. ŞEKİL'in düzen alanı, cihaza gönderilen verilerin düzenine uyacak şekilde ayarlanmalıdır; Aksi takdirde davranışı tanımlanmamıştır. |
Verileri verilen şekil ve düzeni olarak yorumlayarak, cihazın örtük infed akış arayüzünden tek bir veri öğesini okur ve verilerin bir XlaOp
döndürür. Bir hesaplamada birden fazla besleme işlemine izin verilir, ancak besleme işlemleri arasında toplam bir sipariş olmalıdır. Örneğin, aşağıdaki koddaki iki infedin toplam siparişi vardır, çünkü WIRE döngüleri arasında bir bağımlılık vardır.
result1 = while (condition, init = init_value) {
Infeed(shape)
}
result2 = while (condition, init = result1) {
Infeed(shape)
}
İç içe geçme şekilleri desteklenmez. Boş bir tuple şekli için, besleme işlemi etkili bir şekilde bir optir ve cihazın beslenmesinden herhangi bir veri okumadan ilerler.
Iota
Ayrıca bkz. XlaBuilder::Iota
.
Iota(shape, iota_dimension)
Potansiyel olarak büyük bir ana bilgisayar transferi yerine cihaz üzerinde sabit bir gerçekleştirir. Şekil belirtilen ve sıfırdan başlayan ve belirtilen boyut boyunca bir tane artan değerleri tutan bir dizi oluşturur. Kayan nokta türleri için, üretilen dizi, Iota
ayrılmaz tipte olduğu ve dönüşümün kayan nokta tipine olduğu ConvertElementType(Iota(...))
ile eşdeğerdir.
Argümanlar | Tip | Semantik |
---|---|---|
shape | Shape | Iota() tarafından oluşturulan dizinin şekli |
iota_dimension | int64 | Artış boyutu. |
Örneğin, Iota(s32[4, 8], 0)
döner
[[0, 0, 0, 0, 0, 0, 0, 0 ],
[1, 1, 1, 1, 1, 1, 1, 1 ],
[2, 2, 2, 2, 2, 2, 2, 2 ],
[3, 3, 3, 3, 3, 3, 3, 3 ]]
Iota(s32[4, 8], 1)
Dönüşler
[[0, 1, 2, 3, 4, 5, 6, 7 ],
[0, 1, 2, 3, 4, 5, 6, 7 ],
[0, 1, 2, 3, 4, 5, 6, 7 ],
[0, 1, 2, 3, 4, 5, 6, 7 ]]
Harita
Ayrıca bkz. XlaBuilder::Map
.
Map(operands..., computation)
Argümanlar | Tip | Semantik |
---|---|---|
operands | n XlaOp s dizisi | N Tip Tipleri T 0..T {n-1} |
computation | XlaComputation | T_0, T_1, .., T_{N + M -1} -> S tipinin hesaplanması, Tip Tip ve M parametreleri ile keyfi tipte |
dimensions | int64 dizi | Harita boyutları dizisi |
Verilen operands
dizileri üzerinde skaler bir işlev uygular ve her elemanın giriş dizilerindeki karşılık gelen öğelere uygulanan eşlenmiş işlevin sonucu olduğu aynı boyutların bir dizisini üretir.
Eşlenen işlev, skaler tip T
girişlerine ve S
tipi tek bir çıkışa sahip olduğu kısıtlamasına sahip keyfi bir hesaplamadır. Çıktı, T tipinin S değiştirilmesi dışında, işlenenlerle aynı boyutlara sahiptir.
Örneğin: Map(op1, op2, op3, computation, par1)
elem_out <- computation(elem1, elem2, elem3, par1)
haritaları Çıkış dizisini üretmek için giriş dizilerindeki her (çok boyutlu) dizin.
Optimizasyon Barrier
Hareketli hesaplamalardan herhangi bir optimizasyon geçişini engeller.
Tüm girişlerin bariyerin çıkışlarına bağlı herhangi bir operatörden önce değerlendirilmesini sağlar.
Ped
Ayrıca bkz. XlaBuilder::Pad
.
Pad(operand, padding_value, padding_config)
Argümanlar | Tip | Semantik |
---|---|---|
operand | XlaOp | T Tipi Tip |
padding_value | XlaOp | Eklenen dolguyu doldurmak için T tipinin skaleri |
padding_config | PaddingConfig | Her iki kenarda (düşük, yüksek) ve her bir boyutun öğeleri arasında dolgu miktarı |
Verilen operand
dizisini, dizinin etrafında ve verilen padding_value
ile dizinin öğeleri arasında dolgu olarak genişletir. padding_config
her boyut için kenar dolgu ve iç dolgu miktarını belirtir.
PaddingConfig
, her boyut için üç alan içeren tekrarlanan bir PaddingConfigDimension
alanıdır: edge_padding_low
, edge_padding_high
ve interior_padding
.
edge_padding_low
ve edge_padding_high
Her bir boyutun düşük uçta (dizin 0'ın yanında) ve üst düzey (en yüksek dizinin yanında) eklenen dolgu miktarını belirtin. Kenar dolgusu miktarı negatif olabilir - negatif dolgunun mutlak değeri, belirtilen boyuttan çıkarılacak eleman sayısını gösterir.
interior_padding
her boyuttaki iki eleman arasında eklenen dolgu miktarını belirtir; Olumsuz olmayabilir. İç dolgu, kenar dolgusundan önce mantıksal olarak gerçekleşir, bu nedenle negatif kenar dolgu durumunda elemanlar iç paded işlenenden çıkarılır.
Kenar dolgu çiftlerinin hepsi (0, 0) ve iç dolgu değerlerinin hepsi 0 ise bu işlem bir op'dur. Aşağıdaki şekil, iki boyutlu bir dizi için farklı edge_padding
ve interior_padding
değerlerinin örneklerini göstermektedir.
Recv
Ayrıca bkz. XlaBuilder::Recv
.
Recv(shape, channel_handle)
Argümanlar | Tip | Semantik |
---|---|---|
shape | Shape | alınacak verilerin şekli |
channel_handle | ChannelHandle | Her gönderme/recv çifti için benzersiz tanımlayıcı |
Verilen şeklin verilerini, aynı kanal kolunu paylaşan başka bir hesaplamada bir Send
talimatından alır. Alınan veriler için bir XLAOP döndürür.
Recv
işleminin istemci API'sı senkron iletişimi temsil eder. Bununla birlikte, talimat asenkron veri transferlerini sağlamak için dahili olarak 2 HLO talimatına ( Recv
ve RecvDone
) ayrıştırılır. Ayrıca HloInstruction::CreateRecv
HloInstruction::CreateRecvDone
Recv(const Shape& shape, int64 channel_id)
Aynı kanal_idiyle bir Send
talimatından veri almak için gereken kaynakları tahsis eder. Veri aktarımının tamamlanmasını beklemek için aşağıdaki bir RecvDone
talimatı tarafından kullanılan tahsis edilen kaynaklar için bir bağlam döndürür. Bağlam, {alma tamponu (şekil), istek tanımlayıcısı (u32)} birikimidir ve yalnızca bir RecvDone
talimatı ile kullanılabilir.
RecvDone(HloInstruction context)
Bir Recv
talimatı tarafından oluşturulan bir bağlam göz önüne alındığında, veri aktarımının tamamlanmasını bekler ve alınan verileri döndürür.
Azaltmak
Ayrıca bkz. XlaBuilder::Reduce
.
Paralel olarak bir veya daha fazla diziye indirgeme işlevi uygular.
Reduce(operands..., init_values..., computation, dimensions)
Argümanlar | Tip | Semantik |
---|---|---|
operands | N XlaOp dizisi | N T_0, ..., T_{N-1} türlerinin dizileri. |
init_values | N XlaOp dizisi | N T_0, ..., T_{N-1} türlerinin skalerleri. |
computation | XlaComputation | T_0, ..., T_{N-1}, T_0, ..., T_{N-1} -> Collate(T_0, ..., T_{N-1}) . |
dimensions | int64 dizi | Azaltmak için sıralanmamış boyut dizisi. |
Nerede:
- N'nin 1'e eşit veya eşit olması gerekir.
- Hesaplama "kabaca" ilişkili olmalıdır (aşağıya bakınız).
- Tüm giriş dizileri aynı boyutlara sahip olmalıdır.
- Tüm başlangıç değerleri
computation
altında bir kimlik oluşturmalıdır. -
N = 1
ise,Collate(T)
T
. -
N > 1
ise,Collate(T_0, ..., T_{N-1})
T
tipiN
elemanlarının bir çubuktur.
Bu işlem, her bir giriş dizisinin bir veya daha fazla boyutunu skalerlere düşürür. Dönen her dizinin sırası rank(operand) - len(dimensions)
. OP'nin çıkışı, Q_i
boyutları aşağıda açıklanan bir T_i
tipi olduğu bir Collate(Q_0, ..., Q_N)
.
Farklı arka uçların azaltma hesaplamasını yeniden değerlendirmesine izin verilir. Bu, ilave gibi bazı indirgeme fonksiyonları şamandıralar için ilişkili olmadığından sayısal farklılıklara yol açabilir. Bununla birlikte, verilerin aralığı sınırlıysa, kayan nokta ilavesi çoğu pratik kullanım için ilişkili olacak kadar yakındır.
Örnekler
Değerlerle [10, 11, 12, 13]
değerlerle tek bir 1D dizisinde bir boyutta azalırken, f
(bu computation
) ile azaltma fonksiyonu (bu hesaplama)
f(10, f(11, f(12, f(init_value, 13)))
Ama başka birçok olasılık da var, örneğin
f(init_value, f(f(10, f(init_value, 11)), f(f(init_value, 12), f(init_value, 13))))
Aşağıda, Summating'in başlangıç değeri 0 ile indirgeme hesaplaması olarak kullanılarak, indirgemenin nasıl uygulanabileceğine dair kaba bir sahte kod örneği bulunmaktadır.
result_shape <- remove all dims in dimensions from operand_shape
# Iterate over all elements in result_shape. The number of r's here is equal
# to the rank of the result
for r0 in range(result_shape[0]), r1 in range(result_shape[1]), ...:
# Initialize this result element
result[r0, r1...] <- 0
# Iterate over all the reduction dimensions
for d0 in range(dimensions[0]), d1 in range(dimensions[1]), ...:
# Increment the result element with the value of the operand's element.
# The index of the operand's element is constructed from all ri's and di's
# in the right order (by construction ri's and di's together index over the
# whole operand shape).
result[r0, r1...] += operand[ri... di]
İşte bir 2D diziyi (matris) azaltma örneği. Şekil 2, boyut 2, boyut 0 ve 3 boyutunun boyutu 1'e sahiptir:
"Ekle" işlevi ile 0 veya 1 boyutlarını azaltma sonuçları:
Her iki azaltma sonucunun 1D dizileri olduğunu unutmayın. Diyagram biri sütun, diğeri sadece görsel kolaylık için satır olarak gösterir.
Daha karmaşık bir örnek için, burada bir 3D dizi. Sıralaması 3, boyut 4 boyutu 0, boyut 2'nin boyutu 1 ve 3 boyutunun boyutu 2'dir. Basitlik için 1 ila 6 değerleri 0 boyutu arasında çoğaltılır.
2D örneğe benzer şekilde, sadece bir boyutu azaltabiliriz. Örneğin 0 boyutunu azaltırsak, 0 boyutundaki tüm değerlerin bir skalere katlandığı bir RANK-2 dizisi alırız:
| 4 8 12 |
| 16 20 24 |
Boyut 2'yi azaltırsak, 2 boyutundaki tüm değerlerin bir skalere katlandığı bir RANK-2 dizisi de alırız:
| 6 15 |
| 6 15 |
| 6 15 |
| 6 15 |
Girişte kalan boyutlar arasındaki göreceli sıranın çıktıda korunduğunu, ancak bazı boyutlara yeni sayılar atanabileceğini (rütbe değiştiği için) alınabileceğini unutmayın.
Ayrıca birden fazla boyutu azaltabiliriz. 0 ve 1 ekleme boyutları 1D dizisini üretir [20, 28, 36]
.
3D dizinin tüm boyutları üzerinden azaltılması skaler 84
üretir.
Çeşitli Azaltma
N > 1
olduğunda, tüm girişlere eşzamanlı olarak uygulandığı için işlev uygulamasını azaltma uygulaması biraz daha karmaşıktır. İşlenenler hesaplamaya aşağıdaki sırayla sağlanır:
- İlk işlenen için azaltılmış değer çalıştırma
- ...
- N'th işlenen için azaltılmış değer
- İlk işlenen için giriş değeri
- ...
- N'th işlenen için giriş değeri
Örneğin, 1-B dizisinin maksimum ve argMax'ını paralel olarak hesaplamak için kullanılabilecek aşağıdaki indirgeme işlevini göz önünde bulundurun:
f: (Float, Int, Float, Int) -> Float, Int
f(max, argmax, value, index):
if value >= max:
return (value, index)
else:
return (max, argmax)
1-D Giriş Dizileri V = Float[N], K = Int[N]
ve INIT değerleri I_V = Float, I_K = Int
, sadece giriş boyutu boyunca indirgeme sonucu f_(N-1)
Özyinelemeli uygulamayı takip eden:
f_0 = f(I_V, I_K, V_0, K_0)
f_1 = f(f_0.first, f_0.second, V_1, K_1)
...
f_(N-1) = f(f_(N-2).first, f_(N-2).second, V_(N-1), K_(N-1))
Bu indirgeyi bir dizi değere ve bir dizi sıralı endekse (yani IE IOTA) uygulamak, diziler üzerinde birlikte yapacak ve maksimum değeri ve eşleşen dizin içeren bir tuple döndürecektir.
Azaltma
Ayrıca bkz. XlaBuilder::ReducePrecision
.
Kayan nokta değerlerini daha düşük hassasiyetli bir formata (IEEE-FP16 gibi) dönüştürmenin etkisini ve orijinal formata geri döndürür. Tüm bit boyutları tüm donanım uygulamalarında desteklenemese de, daha düşük hassasiyet formatındaki üs ve Mantissa bitlerinin sayısı keyfi olarak belirtilebilir.
ReducePrecision(operand, mantissa_bits, exponent_bits)
Argümanlar | Tip | Semantik |
---|---|---|
operand | XlaOp | Yüzen nokta tipi T . |
exponent_bits | int32 | Daha düşük hassasiyetli formatta üs biti sayısı |
mantissa_bits | int32 | Mantissa bitlerinin sayısı düşük hassasiyetli formatta |
Sonuç, bir dizi T
. Giriş değerleri, verilen Mantissa bit sayısıyla ("hatta" semantiklere bağlar kullanılarak) temsil edilebilecek en yakın değere yuvarlanır ve üs bit sayısına göre belirtilen aralığı aşan değerler pozitif veya negatif sonsuza kenetlenir. NaN
değerleri korunur, ancak kanonik NaN
değerlerine dönüştürülebilirler.
Daha düşük hassasiyet formatında en az bir üs bitine sahip olmalıdır (her ikisi de sıfır bir Mantissa'ya sahip olduğu için sıfır değeri bir sonsuzluktan ayırt etmek için) ve negatif olmayan Mantissa bitine sahip olmalıdır. Üs veya Mantissa bit sayısı, T
tipi için karşılık gelen değeri aşabilir; Dönüşümün karşılık gelen kısmı sadece bir op.
Reducescatter
Ayrıca bkz. XlaBuilder::ReduceScatter
.
Reducescatter, etkili bir şekilde bir alreduce yapan ve daha sonra sonucu, scatter_dimension
boyunca shard_count
bloklarına bölerek ve çoğaltma grubundaki i
ith
alır.
ReduceScatter(operand, computation, scatter_dim, shard_count, replica_group_ids, channel_id)
Argümanlar | Tip | Semantik |
---|---|---|
operand | XlaOp | Kopyalar arasında azalmak için dizi veya boş olmayan bir dizi çubuk. |
computation | XlaComputation | Azaltma hesaplaması |
scatter_dimension | int64 | Dağılım boyutu. |
shard_count | int64 | Split scatter_dimension için Blok Sayısı |
replica_groups | int64 vektörlerinin vektörü | Azaltmaların yapıldığı gruplar |
channel_id | isteğe bağlı int64 | Modüller arası iletişim için isteğe bağlı kanal kimliği |
-
operand
bir dizi bir dizi olduğunda, tuple'nin her elemanında azaltma azalması gerçekleştirilir. -
replica_groups
, azaltmanın gerçekleştirildiği çoğaltma gruplarının bir listesidir (geçerli çoğaltma için çoğaltma kimliğiReplicaId
kullanılarak alınabilir). Her gruptaki kopyaların sırası, tüm azaltma sonucunun dağıldığı sırayı belirler.replica_groups
boş olmalıdır (bu durumda tüm kopyalar tek bir gruba aittir) veya kopya sayısı ile aynı sayıda öğe içermelidir. Birden fazla çoğaltma grubu olduğunda, hepsi aynı boyutta olmalıdır. Örneğin,replica_groups = {0, 2}, {1, 3}
2
0
ve 2 ve1
ve3
arasında indirgeme gerçekleştirir ve daha sonra sonucu dağıtır. -
shard_count
her çoğaltma grubunun boyutudur.replica_groups
boş olduğu durumlarda buna ihtiyacımız var.replica_groups
boş değilse,shard_count
her çoğaltma grubunun boyutuna eşit olmalıdır. -
channel_id
modüller arası iletişim için kullanılır: yalnızca aynıchannel_id
ile elde edilen operasyonlarıreduce-scatter
birbiriyle iletişim kurabilir.
Çıkış şekli, shard_count
zamanları daha küçük olan scatter_dimension
ile giriş şeklidir. Örneğin, iki kopya varsa ve işlenen iki kopyada sırasıyla [1.0, 2.25]
ve [3.0, 5.25]
değerine sahipse, bu OP'den çıkış değeri, scatter_dim
0
olduğu ilk olarak [4.0]
olacaktır İkinci çoğaltma için kopya ve [7.5]
.
Azaltma
Ayrıca bkz. XlaBuilder::ReduceWindow
.
Çıktı olarak N çok boyutlu dizilerin bir veya bir Tuple üreterek bir n çok boyutlu dizinin bir dizisinin her penceresindeki tüm elemanlara bir indirgeme işlevi uygular. Her çıkış dizisi, pencerenin geçerli konumlarının sayısı ile aynı sayıda öğeye sahiptir. Bir havuz katmanı bir ReduceWindow
olarak ifade edilebilir. Reduce
benzer şekilde, uygulanan computation
her zaman sol taraftaki init_values
geçirilir.
ReduceWindow(operands..., init_values..., computation, window_dimensions, window_strides, padding)
Argümanlar | Tip | Semantik |
---|---|---|
operands | N XlaOps | Her biri pencerenin yerleştirildiği temel alanı temsil eden T_0,..., T_{N-1} türlerinin çok boyutlu dizileri dizisi. |
init_values | N XlaOps | Azaltma için n başlangıç değerleri, N işlenenlerinin her biri için bir tane. Ayrıntılar için indirgeme bakın. |
computation | XlaComputation | T_0, ..., T_{N-1}, T_0, ..., T_{N-1} -> Collate(T_0, ..., T_{N-1}) Tüm giriş işlenenlerinin her penceresindeki elemanlar. |
window_dimensions | ArraySlice<int64> | pencere boyutu değerleri için tamsayılar dizisi |
window_strides | ArraySlice<int64> | Pencere Adım değerleri için tamsayılar dizisi |
base_dilations | ArraySlice<int64> | Baz dilatasyon değerleri için tamsayılar dizisi |
window_dilations | ArraySlice<int64> | Pencere dilatasyon değerleri için tamsayılar dizisi |
padding | Padding | Pencere için dolgu türü (dolgu :: kseame, adım 1 ise girişle aynı çıkış şekline sahip olacak şekilde pedyar veya dolgu :: Kvalid, dolgu kullanmayan ve pencereyi artık uymadıktan sonra "durdurur") |
Nerede:
- N'nin 1'e eşit veya eşit olması gerekir.
- Tüm giriş dizileri aynı boyutlara sahip olmalıdır.
-
N = 1
ise,Collate(T)
T
. -
N > 1
ise,Collate(T_0, ..., T_{N-1})
tipte(T0,...T{N-1})
N
elemanlarının bir tuple'sidir.
Aşağıdaki kod ve şekil, ReduceWindow
kullanma örneğini göstermektedir. Giriş boyutunda [4x6] bir matristur ve hem Window_Dimensions hem de Window_Stride_Dimensions [2x3].
// Create a computation for the reduction (maximum).
XlaComputation max;
{
XlaBuilder builder(client_, "max");
auto y = builder.Parameter(0, ShapeUtil::MakeShape(F32, {}), "y");
auto x = builder.Parameter(1, ShapeUtil::MakeShape(F32, {}), "x");
builder.Max(y, x);
max = builder.Build().value();
}
// Create a ReduceWindow computation with the max reduction computation.
XlaBuilder builder(client_, "reduce_window_2x3");
auto shape = ShapeUtil::MakeShape(F32, {4, 6});
auto input = builder.Parameter(0, shape, "input");
builder.ReduceWindow(
input,
/*init_val=*/builder.ConstantLiteral(LiteralUtil::MinValue(F32)),
*max,
/*window_dimensions=*/{2, 3},
/*window_stride_dimensions=*/{2, 3},
Padding::kValid);
Bir boyuttaki 1'lik adım, bir pencerenin boyuttaki konumunun bitişik penceresinden 1 eleman uzakta olduğunu belirtir. In order to specify that no windows overlap with each other, window_stride_dimensions should be equal to window_dimensions. The figure below illustrates the use of two different stride values. Padding is applied to each dimension of the input and the calculations are the same as though the input came in with the dimensions it has after padding.
For a non-trivial padding example, consider computing reduce-window minimum (initial value is MAX_FLOAT
) with dimension 3
and stride 2
over the input array [10000, 1000, 100, 10, 1]
. Padding kValid
computes minimums over two valid windows: [10000, 1000, 100]
and [100, 10, 1]
, resulting in the output [100, 1]
. Padding kSame
first pads the array so that the shape after the reduce-window would be the same as input for stride one by adding initial elements on both sides, getting [MAX_VALUE, 10000, 1000, 100, 10, 1, MAX_VALUE]
. Running reduce-window over the padded array operates on three windows [MAX_VALUE, 10000, 1000]
, [1000, 100, 10]
, [10, 1, MAX_VALUE]
, and yields [1000, 10, 1]
.
The evaluation order of the reduction function is arbitrary and may be non-deterministic. Therefore, the reduction function should not be overly sensitive to reassociation. See the discussion about associativity in the context of Reduce
for more details.
Çoğaltma Kimliği
See also XlaBuilder::ReplicaId
.
Returns the unique ID (U32 scalar) of the replica.
ReplicaId()
The unique ID of each replica is an unsigned integer in the interval [0, N)
, where N
is the number of replicas. Since all the replicas are running the same program, a ReplicaId()
call in the program will return a different value on each replica.
Yeniden şekillendir
See also XlaBuilder::Reshape
and the Collapse
operation.
Reshapes the dimensions of an array into a new configuration.
Reshape(operand, new_sizes)
Reshape(operand, dimensions, new_sizes)
Argümanlar | Tip | Semantics |
---|---|---|
operand | XlaOp | array of type T |
dimensions | int64 vector | order in which dimensions are collapsed |
new_sizes | int64 vector | vector of sizes of new dimensions |
Conceptually, reshape first flattens an array into a one-dimensional vector of data values, and then refines this vector into a new shape. The input arguments are an arbitrary array of type T, a compile-time-constant vector of dimension indices, and a compile-time-constant vector of dimension sizes for the result. The values in the dimension
vector, if given, must be a permutation of all of T's dimensions; the default if not given is {0, ..., rank - 1}
. The order of the dimensions in dimensions
is from slowest-varying dimension (most major) to fastest-varying dimension (most minor) in the loop nest which collapses the input array into a single dimension. The new_sizes
vector determines the size of the output array. The value at index 0 in new_sizes
is the size of dimension 0, the value at index 1 is the size of dimension 1, and so on. The product of the new_size
dimensions must equal the product of the operand's dimension sizes. When refining the collapsed array into the multidimensional array defined by new_sizes
, the dimensions in new_sizes
are ordered from slowest varying (most major) and to fastest varying (most minor).
For example, let v be an array of 24 elements:
let v = f32[4x2x3] { { {10, 11, 12}, {15, 16, 17} },
{ {20, 21, 22}, {25, 26, 27} },
{ {30, 31, 32}, {35, 36, 37} },
{ {40, 41, 42}, {45, 46, 47} } };
In-order collapse:
let v012_24 = Reshape(v, {0,1,2}, {24});
then v012_24 == f32[24] {10, 11, 12, 15, 16, 17, 20, 21, 22, 25, 26, 27,
30, 31, 32, 35, 36, 37, 40, 41, 42, 45, 46, 47};
let v012_83 = Reshape(v, {0,1,2}, {8,3});
then v012_83 == f32[8x3] { {10, 11, 12}, {15, 16, 17},
{20, 21, 22}, {25, 26, 27},
{30, 31, 32}, {35, 36, 37},
{40, 41, 42}, {45, 46, 47} };
Out-of-order collapse:
let v021_24 = Reshape(v, {1,2,0}, {24});
then v012_24 == f32[24] {10, 20, 30, 40, 11, 21, 31, 41, 12, 22, 32, 42,
15, 25, 35, 45, 16, 26, 36, 46, 17, 27, 37, 47};
let v021_83 = Reshape(v, {1,2,0}, {8,3});
then v021_83 == f32[8x3] { {10, 20, 30}, {40, 11, 21},
{31, 41, 12}, {22, 32, 42},
{15, 25, 35}, {45, 16, 26},
{36, 46, 17}, {27, 37, 47} };
let v021_262 = Reshape(v, {1,2,0}, {2,6,2});
then v021_262 == f32[2x6x2] { { {10, 20}, {30, 40},
{11, 21}, {31, 41},
{12, 22}, {32, 42} },
{ {15, 25}, {35, 45},
{16, 26}, {36, 46},
{17, 27}, {37, 47} } };
As a special case, reshape can transform a single-element array to a scalar and vice versa. Örneğin,
Reshape(f32[1x1] { {5} }, {0,1}, {}) == 5;
Reshape(5, {}, {1,1}) == f32[1x1] { {5} };
Rev (reverse)
See also XlaBuilder::Rev
.
Rev(operand, dimensions)
Argümanlar | Tip | Semantics |
---|---|---|
operand | XlaOp | array of type T |
dimensions | ArraySlice<int64> | dimensions to reverse |
Reverses the order of elements in the operand
array along the specified dimensions
, generating an output array of the same shape. Each element of the operand array at a multidimensional index is stored into the output array at a transformed index. The multidimensional index is transformed by reversing the index in each dimension to be reversed (ie, if a dimension of size N is one of the reversing dimensions, its index i is transformed into N - 1 - i).
One use for the Rev
operation is to reverse the convolution weight array along the two window dimensions during the gradient computation in neural networks.
RngNormal
See also XlaBuilder::RngNormal
.
Constructs an output of a given shape with random numbers generated following the \(N(\mu, \sigma)\) normal distribution. The parameters \(\mu\) and \(\sigma\), and output shape have to have a floating point elemental type. The parameters furthermore have to be scalar valued.
RngNormal(mu, sigma, shape)
Argümanlar | Tip | Semantics |
---|---|---|
mu | XlaOp | Scalar of type T specifying mean of generated numbers |
sigma | XlaOp | Scalar of type T specifying standard deviation of generated |
shape | Shape | Output shape of type T |
RngUniform
See also XlaBuilder::RngUniform
.
Constructs an output of a given shape with random numbers generated following the uniform distribution over the interval \([a,b)\). The parameters and output element type have to be a boolean type, an integral type or a floating point types, and the types have to be consistent. The CPU and GPU backends currently only support F64, F32, F16, BF16, S64, U64, S32 and U32. Furthermore, the parameters need to be scalar valued. If \(b <= a\) the result is implementation-defined.
RngUniform(a, b, shape)
Argümanlar | Tip | Semantics |
---|---|---|
a | XlaOp | Scalar of type T specifying lower limit of interval |
b | XlaOp | Scalar of type T specifying upper limit of interval |
shape | Shape | Output shape of type T |
RngBitGenerator
Generates an output with a given shape filled with uniform random bits using the specified algorithm (or backend default) and returns an updated state (with the same shape as initial state) and the generated random data.
Initial state is the initial state of the current random number generation. It and the required shape and valid values are dependent on the algorithm used.
The output is guaranteed to be a deterministic function of the initial state but it is not guaranteed to be deterministic between backends and different compiler versions.
RngBitGenerator(algorithm, key, shape)
Argümanlar | Tip | Semantics |
---|---|---|
algorithm | RandomAlgorithm | PRNG algorithm to be used. |
initial_state | XlaOp | Initial state for the PRNG algorithm. |
shape | Shape | Output shape for generated data. |
Available values for algorithm
:
rng_default
: Backend specific algorithm with backend specific shape requirements.rng_three_fry
: ThreeFry counter-based PRNG algorithm. Theinitial_state
shape isu64[2]
with arbitrary values. Somon ve ark. SC 2011. Parallel random numbers: as easy as 1, 2, 3.rng_philox
: Philox algorithm to generate random numbers in parallel. Theinitial_state
shape isu64[3]
with arbitrary values. Somon ve ark. SC 2011. Parallel random numbers: as easy as 1, 2, 3.
Dağılım
The XLA scatter operation generates a sequence of results which are the values of the input array operands
, with several slices (at indices specified by scatter_indices
) updated with the sequence of values in updates
using update_computation
.
See also XlaBuilder::Scatter
.
scatter(operands..., scatter_indices, updates..., update_computation, index_vector_dim, update_window_dims, inserted_window_dims, scatter_dims_to_operand_dims)
Argümanlar | Tip | Semantics |
---|---|---|
operands | Sequence of N XlaOp | N arrays of types T_0, ..., T_N to be scattered into. |
scatter_indices | XlaOp | Array containing the starting indices of the slices that must be scattered to. |
updates | Sequence of N XlaOp | N arrays of types T_0, ..., T_N . updates[i] contains the values that must be used for scattering operands[i] . |
update_computation | XlaComputation | Computation to be used for combining the existing values in the input array and the updates during scatter. This computation should be of type T_0, ..., T_N, T_0, ..., T_N -> Collate(T_0, ..., T_N) . |
index_vector_dim | int64 | The dimension in scatter_indices that contains the starting indices. |
update_window_dims | ArraySlice<int64> | The set of dimensions in updates shape that are window dimensions . |
inserted_window_dims | ArraySlice<int64> | The set of window dimensions that must be inserted into updates shape. |
scatter_dims_to_operand_dims | ArraySlice<int64> | A dimensions map from the scatter indices to the operand index space. This array is interpreted as mapping i to scatter_dims_to_operand_dims[i] . It has to be one-to-one and total. |
indices_are_sorted | bool | Whether the indices are guaranteed to be sorted by the caller. |
Nerede:
- N is required to be greater or equal to 1.
-
operands
[0
], ...,operands
[N-1
] must all have the same dimensions. -
updates
[0
], ...,updates
[N-1
] must all have the same dimensions. - If
N = 1
,Collate(T)
isT
. - If
N > 1
,Collate(T_0, ..., T_N)
is a tuple ofN
elements of typeT
.
If index_vector_dim
is equal to scatter_indices.rank
we implicitly consider scatter_indices
to have a trailing 1
dimension.
We define update_scatter_dims
of type ArraySlice<int64>
as the set of dimensions in updates
shape that are not in update_window_dims
, in ascending order.
The arguments of scatter should follow these constraints:
Each
updates
array must be of rankupdate_window_dims.size + scatter_indices.rank - 1
.Bounds of dimension
i
in eachupdates
array must conform to the following:- If
i
is present inupdate_window_dims
(ie equal toupdate_window_dims
[k
] for somek
), then the bound of dimensioni
inupdates
must not exceed the corresponding bound ofoperand
after accounting for theinserted_window_dims
(ieadjusted_window_bounds
[k
], whereadjusted_window_bounds
contains the bounds ofoperand
with the bounds at indicesinserted_window_dims
removed). - If
i
is present inupdate_scatter_dims
(ie equal toupdate_scatter_dims
[k
] for somek
), then the bound of dimensioni
inupdates
must be equal to the corresponding bound ofscatter_indices
, skippingindex_vector_dim
(iescatter_indices.shape.dims
[k
], ifk
<index_vector_dim
andscatter_indices.shape.dims
[k+1
] otherwise).
- If
update_window_dims
must be in ascending order, not have any repeating dimension numbers, and be in the range[0, updates.rank)
.inserted_window_dims
must be in ascending order, not have any repeating dimension numbers, and be in the range[0, operand.rank)
.operand.rank
must equal the sum ofupdate_window_dims.size
andinserted_window_dims.size
.scatter_dims_to_operand_dims.size
must be equal toscatter_indices.shape.dims
[index_vector_dim
], and its values must be in the range[0, operand.rank)
.
For a given index U
in each updates
array, the corresponding index I
in the corresponding operands
array into which this update has to be applied is computed as follows:
- Let
G
= {U
[k
] fork
inupdate_scatter_dims
}. UseG
to look up an index vectorS
in thescatter_indices
array such thatS
[i
] =scatter_indices
[Combine(G
,i
)] where Combine(A, b) inserts b at positionsindex_vector_dim
into A. - Create an index
S
in
intooperand
usingS
by scatteringS
using thescatter_dims_to_operand_dims
map. Daha resmi:-
S
in
[scatter_dims_to_operand_dims
[k
]] =S
[k
] ifk
<scatter_dims_to_operand_dims.size
. -
S
in
[_
] =0
otherwise.
-
- Create an index
W
in
into eachoperands
array by scattering the indices atupdate_window_dims
inU
according toinserted_window_dims
. Daha resmi:-
W
in
[window_dims_to_operand_dims
(k
)] =U
[k
] ifk
is inupdate_window_dims
, wherewindow_dims_to_operand_dims
is the monotonic function with domain [0
,update_window_dims.size
) and range [0
,operand.rank
) \inserted_window_dims
. (For example, ifupdate_window_dims.size
is4
,operand.rank
is6
, andinserted_window_dims
is {0
,2
} thenwindow_dims_to_operand_dims
is {0
→1
,1
→3
,2
→4
,3
→5
}). -
W
in
[_
] =0
otherwise.
-
-
I
isW
in
+S
in
where + is element-wise addition.
In summary, the scatter operation can be defined as follows.
- Initialize
output
withoperands
, ie for all indicesJ
, for all indicesO
in theoperands
[J
] array:
output
[J
][O
] =operands
[J
][O
] - For every index
U
in theupdates
[J
] array and the corresponding indexO
in theoperand
[J
] array, ifO
is a valid index foroutput
:
(output
[0
][O
], ...,output
[N-1
][O
]) =update_computation
(output
[0
][O
], ..., ,output
[N-1
][O
],updates
[0
][U
], ...,updates
[N-1
][U
])
The order in which updates are applied is non-deterministic. So, when multiple indices in updates
refer to the same index in operands
, the corresponding value in output
will be non-deterministic.
Note that the first parameter that is passed into the update_computation
will always be the current value from the output
array and the second parameter will always be the value from the updates
array. This is important specifically for cases when the update_computation
is not commutative .
If indices_are_sorted
is set to true then XLA can assume that start_indices
are sorted (in ascending start_index_map
order) by the user. If they are not then the semantics is implementation defined.
Informally, the scatter op can be viewed as an inverse of the gather op, ie the scatter op updates the elements in the input that are extracted by the corresponding gather op.
For a detailed informal description and examples, refer to the "Informal Description" section under Gather
.
Seçme
See also XlaBuilder::Select
.
Constructs an output array from elements of two input arrays, based on the values of a predicate array.
Select(pred, on_true, on_false)
Argümanlar | Tip | Semantics |
---|---|---|
pred | XlaOp | array of type PRED |
on_true | XlaOp | array of type T |
on_false | XlaOp | array of type T |
The arrays on_true
and on_false
must have the same shape. This is also the shape of the output array. The array pred
must have the same dimensionality as on_true
and on_false
, with the PRED
element type.
For each element P
of pred
, the corresponding element of the output array is taken from on_true
if the value of P
is true
, and from on_false
if the value of P
is false
. As a restricted form of broadcasting , pred
can be a scalar of type PRED
. In this case, the output array is taken wholly from on_true
if pred
is true
, and from on_false
if pred
is false
.
Example with non-scalar pred
:
let pred: PRED[4] = {true, false, false, true};
let v1: s32[4] = {1, 2, 3, 4};
let v2: s32[4] = {100, 200, 300, 400};
==>
Select(pred, v1, v2) = s32[4]{1, 200, 300, 4};
Example with scalar pred
:
let pred: PRED = true;
let v1: s32[4] = {1, 2, 3, 4};
let v2: s32[4] = {100, 200, 300, 400};
==>
Select(pred, v1, v2) = s32[4]{1, 2, 3, 4};
Selections between tuples are supported. Tuples are considered to be scalar types for this purpose. If on_true
and on_false
are tuples (which must have the same shape!) then pred
has to be a scalar of type PRED
.
SelectAndScatter
See also XlaBuilder::SelectAndScatter
.
This operation can be considered as a composite operation that first computes ReduceWindow
on the operand
array to select an element from each window, and then scatters the source
array to the indices of the selected elements to construct an output array with the same shape as the operand sıralamak. The binary select
function is used to select an element from each window by applying it across each window, and it is called with the property that the first parameter's index vector is lexicographically less than the second parameter's index vector. The select
function returns true
if the first parameter is selected and returns false
if the second parameter is selected, and the function must hold transitivity (ie, if select(a, b)
and select(b, c)
are true
, then select(a, c)
is also true
) so that the selected element does not depend on the order of the elements traversed for a given window.
The function scatter
is applied at each selected index in the output array. It takes two scalar parameters:
- Current value at the selected index in the output array
- The scatter value from
source
that applies to the selected index
It combines the two parameters and returns a scalar value that's used to update the value at the selected index in the output array. Initially, all indices of the output array are set to init_value
.
The output array has the same shape as the operand
array and the source
array must have the same shape as the result of applying a ReduceWindow
operation on the operand
array. SelectAndScatter
can be used to backpropagate the gradient values for a pooling layer in a neural network.
SelectAndScatter(operand, select, window_dimensions, window_strides, padding, source, init_value, scatter)
Argümanlar | Tip | Semantics |
---|---|---|
operand | XlaOp | array of type T over which the windows slide |
select | XlaComputation | binary computation of type T, T -> PRED , to apply to all elements in each window; returns true if the first parameter is selected and returns false if the second parameter is selected |
window_dimensions | ArraySlice<int64> | array of integers for window dimension values |
window_strides | ArraySlice<int64> | array of integers for window stride values |
padding | Padding | padding type for window (Padding::kSame or Padding::kValid) |
source | XlaOp | array of type T with the values to scatter |
init_value | XlaOp | scalar value of type T for the initial value of the output array |
scatter | XlaComputation | binary computation of type T, T -> T , to apply each scatter source element with its destination element |
The figure below shows examples of using SelectAndScatter
, with the select
function computing the maximal value among its parameters. Note that when the windows overlap, as in the figure (2) below, an index of the operand
array may be selected multiple times by different windows. In the figure, the element of value 9 is selected by both of the top windows (blue and red) and the binary addition scatter
function produces the output element of value 8 (2 + 6).
The evaluation order of the scatter
function is arbitrary and may be non-deterministic. Therefore, the scatter
function should not be overly sensitive to reassociation. See the discussion about associativity in the context of Reduce
for more details.
Göndermek
See also XlaBuilder::Send
.
Send(operand, channel_handle)
Argümanlar | Tip | Semantics |
---|---|---|
operand | XlaOp | data to send (array of type T) |
channel_handle | ChannelHandle | unique identifier for each send/recv pair |
Sends the given operand data to a Recv
instruction in another computation that shares the same channel handle. Does not return any data.
Similar to the Recv
operation, the client API of Send
operation represents synchronous communication, and is internally decomposed into 2 HLO instructions ( Send
and SendDone
) to enable asynchronous data transfers. See also HloInstruction::CreateSend
and HloInstruction::CreateSendDone
.
Send(HloInstruction operand, int64 channel_id)
Initiates an asynchronous transfer of the operand to the resources allocated by the Recv
instruction with the same channel id. Returns a context, which is used by a following SendDone
instruction to wait for the completion of the data transfer. The context is a tuple of {operand (shape), request identifier (U32)} and it can only be used by a SendDone
instruction.
SendDone(HloInstruction context)
Given a context created by a Send
instruction, waits for the data transfer to complete. The instruction does not return any data.
Scheduling of channel instructions
The execution order of the 4 instructions for each channel ( Recv
, RecvDone
, Send
, SendDone
) is as below.
-
Recv
happens beforeSend
-
Send
happens beforeRecvDone
-
Recv
happens beforeRecvDone
-
Send
happens beforeSendDone
When the backend compilers generate a linear schedule for each computation that communicates via channel instructions, there must not be cycles across the computations. For example, below schedules lead to deadlocks.
Dilim
See also XlaBuilder::Slice
.
Slicing extracts a sub-array from the input array. The sub-array is of the same rank as the input and contains the values inside a bounding box within the input array where the dimensions and indices of the bounding box are given as arguments to the slice operation.
Slice(operand, start_indices, limit_indices, strides)
Argümanlar | Tip | Semantics |
---|---|---|
operand | XlaOp | N dimensional array of type T |
start_indices | ArraySlice<int64> | List of N integers containing the starting indices of the slice for each dimension. Values must be greater than or equal to zero. |
limit_indices | ArraySlice<int64> | List of N integers containing the ending indices (exclusive) for the slice for each dimension. Each value must be greater than or equal to the respective start_indices value for the dimension and less than or equal to the size of the dimension. |
strides | ArraySlice<int64> | List of N integers that decides the input stride of the slice. The slice picks every strides[d] element in dimension d . |
1-dimensional example:
let a = {0.0, 1.0, 2.0, 3.0, 4.0}
Slice(a, {2}, {4}) produces:
{2.0, 3.0}
2-dimensional example:
let b =
{ {0.0, 1.0, 2.0},
{3.0, 4.0, 5.0},
{6.0, 7.0, 8.0},
{9.0, 10.0, 11.0} }
Slice(b, {2, 1}, {4, 3}) produces:
{ { 7.0, 8.0},
{10.0, 11.0} }
Düzenlemek
See also XlaBuilder::Sort
.
Sort(operands, comparator, dimension, is_stable)
Argümanlar | Tip | Semantics |
---|---|---|
operands | ArraySlice<XlaOp> | The operands to sort. |
comparator | XlaComputation | The comparator computation to use. |
dimension | int64 | The dimension along which to sort. |
is_stable | bool | Whether stable sorting should be used. |
If only one operand is provided:
If the operand is a rank-1 tensor (an array), the result is a sorted array. If you want to sort the array into ascending order, the comparator should perform a less-than comparison. Formally, after the array is sorted, it holds for all index positions
i, j
withi < j
that eithercomparator(value[i], value[j]) = comparator(value[j], value[i]) = false
orcomparator(value[i], value[j]) = true
.If the operand has higher rank, the operand is sorted along the provided dimension. For example, for a rank-2 tensor (a matrix), a dimension value of
0
will independently sort every column, and a dimension value of1
will independently sort each row. If no dimension number is provided, then the last dimension is chosen by default. For the dimension which is sorted, the same sorting order applies as in the rank-1 case.
If n > 1
operands are provided:
All
n
operands must be tensors with the same dimensions. The element types of the tensors may be different.All operands are sorted together, not individually. Conceptually the operands are treated as a tuple. When checking whether the elements of each operand at index positions
i
andj
need to be swapped, the comparator is called with2 * n
scalar parameters, where parameter2 * k
corresponds to the value at positioni
from thek-th
operand, and parameter2 * k + 1
corresponds to the value at positionj
from thek-th
operand. Usually, the comparator would thus compare parameters2 * k
and2 * k + 1
with each other and possibly use other parameter pairs as tie breakers.The result is a tuple that consists of the operands in sorted order (along the provided dimension, as above). The
i-th
operand of the tuple corresponds to thei-th
operand of Sort.
For example, if there are three operands operand0 = [3, 1]
, operand1 = [42, 50]
, operand2 = [-3.0, 1.1]
, and the comparator compares only the values of operand0
with less-than, then the output of the sort is the tuple ([1, 3], [50, 42], [1.1, -3.0])
.
If is_stable
is set to true, the sort is guaranteed to be stable, that is, if there are elements which are considered to be equal by the comparator, the relative order of the equal values is preserved. Two elements e1
and e2
are equal if and only if comparator(e1, e2) = comparator(e2, e1) = false
. By default, is_stable
is set to false.
Transpose
See also the tf.reshape
operation.
Transpose(operand)
Argümanlar | Tip | Semantics |
---|---|---|
operand | XlaOp | The operand to transpose. |
permutation | ArraySlice<int64> | How to permute the dimensions. |
Permutes the operand dimensions with the given permutation, so ∀ i . 0 ≤ i < rank ⇒ input_dimensions[permutation[i]] = output_dimensions[i]
.
This is the same as Reshape(operand, permutation, Permute(permutation, operand.shape.dimensions)).
TriangularSolve
See also XlaBuilder::TriangularSolve
.
Solves systems of linear equations with lower or upper triangular coefficient matrices by forward- or back-substitution. Broadcasting along leading dimensions, this routine solves one of the matrix systems op(a) * x = b
, or x * op(a) = b
, for the variable x
, given a
and b
, where op(a)
is either op(a) = a
, or op(a) = Transpose(a)
, or op(a) = Conj(Transpose(a))
.
TriangularSolve(a, b, left_side, lower, unit_diagonal, transpose_a)
Argümanlar | Tip | Semantics |
---|---|---|
a | XlaOp | a rank > 2 array of a complex or floating-point type with shape [..., M, M] . |
b | XlaOp | a rank > 2 array of the same type with shape [..., M, K] if left_side is true, [..., K, M] otherwise. |
left_side | bool | indicates whether to solve a system of the form op(a) * x = b ( true ) or x * op(a) = b ( false ). |
lower | bool | whether to use the upper or lower triangle of a . |
unit_diagonal | bool | if true , the diagonal elements of a are assumed to be 1 and not accessed. |
transpose_a | Transpose | whether to use a as is, transpose it or take its conjugate transpose. |
Input data is read only from the lower/upper triangle of a
, depending on the value of lower
. Values from the other triangle are ignored. Output data is returned in the same triangle; the values in the other triangle are implementation-defined and may be anything.
If the rank of a
and b
are greater than 2, they are treated as batches of matrices, where all except the minor 2 dimensions are batch dimensions. a
and b
must have equal batch dimensions.
Tuple
See also XlaBuilder::Tuple
.
A tuple containing a variable number of data handles, each of which has its own shape.
This is analogous to std::tuple
in C++. Conceptually:
let v: f32[10] = f32[10]{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
let s: s32 = 5;
let t: (f32[10], s32) = tuple(v, s);
Tuples can be deconstructed (accessed) via the GetTupleElement
operation.
Sırasında
See also XlaBuilder::While
.
While(condition, body, init)
Argümanlar | Tip | Semantics |
---|---|---|
condition | XlaComputation | XlaComputation of type T -> PRED which defines the termination condition of theloop. |
body | XlaComputation | XlaComputation of type T -> T which defines the body of the loop. |
init | T | Initial value for the parameter of condition and body . |
Sequentially executes the body
until the condition
fails. This is similar to a typical while loop in many other languages except for the differences and restrictions listed below.
- A
While
node returns a value of typeT
, which is the result from the last execution of thebody
. - The shape of the type
T
is statically determined and must be the same across all iterations.
The T parameters of the computations are initialized with the init
value in the first iteration and are automatically updated to the new result from body
in each subsequent iteration.
One main use case of the While
node is to implement the repeated execution of training in neural networks. Simplified pseudocode is shown below with a graph that represents the computation. The code can be found in while_test.cc
. The type T
in this example is a Tuple
consisting of an int32
for the iteration count and a vector[10]
for the accumulator. For 1000 iterations, the loop keeps adding a constant vector to the accumulator.
// Pseudocode for the computation.
init = {0, zero_vector[10]} // Tuple of int32 and float[10].
result = init;
while (result(0) < 1000) {
iteration = result(0) + 1;
new_vector = result(1) + constant_vector[10];
result = {iteration, new_vector};
}