यहां XlaBuilder
इंटरफ़ेस में बताए गए ऑपरेशन के सिमेंटिक्स के बारे में बताया गया है. आम तौर पर, ये कार्रवाइयां xla_data.proto
में RPC इंटरफ़ेस में बताई गई सभी कार्रवाइयों से वन-टू-वन मैप की जाती हैं.
नामकरण के बारे में एक जानकारी: XLA, सामान्य डेटा टाइप के साथ काम करता है. यह एक ऐसा N-डाइमेंशनल कलेक्शन होता है जिसमें एक जैसे टाइप के एलिमेंट होते हैं, जैसे कि 32-बिट वाला फ़्लोट. पूरे दस्तावेज़ में, अरे का इस्तेमाल आर्बिट्ररी-डाइमेंशन वाले अरे को दिखाने के लिए किया जाता है. सुविधा के लिए, खास मामलों के लिए ज़्यादा सटीक और जाने-पहचाने नाम होते हैं. उदाहरण के लिए, वेक्टर एक डाइमेंशन वाला ऐरे होता है और मैट्रिक दो डाइमेंशन वाला ऐरे होता है.
AfterAll
XlaBuilder::AfterAll
भी देखें.
AfterAll अलग-अलग संख्या के टोकन लेता है और एक टोकन बनाता है. टोकन, प्राइमटिव टाइप होते हैं. इन्हें ऑर्डर लागू करने के लिए, साइड-इफ़ेक्ट वाले ऑपरेशन के बीच थ्रेड किया जा सकता है. सेट की गई कार्रवाइयों के बाद, कार्रवाई का ऑर्डर देने के लिए, AfterAll
का इस्तेमाल टोकन के जॉइन की तरह किया जा सकता है.
AfterAll(operands)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operands |
XlaOp |
टोकन की वैरिएबल संख्या |
AllGather
XlaBuilder::AllGather
भी देखें.
सभी रेप्लिक में कनेक्शन करता है.
AllGather(operand, all_gather_dim, shard_count, replica_group_ids,
channel_id)
तर्क | टाइप | सिमैंटिक |
---|---|---|
operand
|
XlaOp
|
प्रतिकृतियों को जोड़ने के लिए कलेक्शन |
all_gather_dim |
int64 |
स्ट्रिंग जोड़ने का डाइमेंशन |
replica_groups
|
int64 के वेक्टर का वेक्टर |
वे ग्रुप जिनके बीच में कनकैनेटेशन किया जाता है |
channel_id
|
ज़रूरी नहीं int64
|
क्रॉस-मॉड्यूल कम्यूनिकेशन के लिए वैकल्पिक चैनल आईडी |
replica_groups
, उन रेप्लिक ग्रुप की सूची होती है जिनके बीच में जोड़ने की कार्रवाई की जाती है. मौजूदा रेप्लिक का आईडी,ReplicaId
का इस्तेमाल करके वापस पाया जा सकता है. हर ग्रुप में रेप्लिक का क्रम, नतीजे में उनके इनपुट के क्रम को तय करता है.replica_groups
या तो खाली होना चाहिए (इस मामले में, सभी रीप्लिक एक ही ग्रुप से जुड़े होते हैं, जो0
सेN - 1
तक के क्रम में होते हैं) या इसमें उतने ही एलिमेंट होने चाहिए जितने रीप्लिक हैं. उदाहरण के लिए,replica_groups = {0, 2}, {1, 3}
,0
और2
के साथ-साथ1
और3
के बीच में समानता रखता है.shard_count
, हर एक रेप्लिक ग्रुप का साइज़ है. हमें इसकी ज़रूरत उन मामलों में होती है जहांreplica_groups
खाली होता है.channel_id
का इस्तेमाल, अलग-अलग मॉड्यूल के बीच कम्यूनिकेशन के लिए किया जाता है: सिर्फ़ एक हीchannel_id
वालेall-gather
ऑपरेशन, एक-दूसरे से कम्यूनिकेट कर सकते हैं.
आउटपुट आकार, इनपुट आकार का ही होता है. इसमें all_gather_dim
को shard_count
गुना बड़ा किया जाता है. उदाहरण के लिए, अगर दो कॉपी हैं और ऑपरेंड की वैल्यू [1.0, 2.5]
और [3.0, 5.25]
है, तो दोनों कॉपी पर इस ऑपरेशन की आउटपुट वैल्यू [1.0, 2.5, 3.0,
5.25]
होगी, जहां all_gather_dim
0
है.
AllReduce
XlaBuilder::AllReduce
भी देखें.
प्रतिकृतियों में कस्टम कंप्यूटेशन करता है.
AllReduce(operand, computation, replica_group_ids, channel_id)
तर्क | टाइप | सिमैंटिक |
---|---|---|
operand
|
XlaOp
|
सभी प्रतिकृति में घटाने के लिए, ऐरे या ऐरे का ऐसा टुपल जो खाली न हो |
computation |
XlaComputation |
कटौती का हिसाब लगाना |
replica_groups
|
int64 के वेक्टर का वेक्टर |
वे ग्रुप जिनके बीच कमी की जाती है |
channel_id
|
ज़रूरी नहीं int64
|
क्रॉस-मॉड्यूल कम्यूनिकेशन के लिए वैकल्पिक चैनल आईडी |
- जब
operand
, सरणियों का ट्यूपल होता है, तो ऑल-डिड्यूस, टपल के हर एलिमेंट पर किया जाता है. replica_groups
प्रतिकृति समूहों की ऐसी सूची है जिसमें कमी की जाती है (मौजूदा प्रतिकृति के रेप्लिका आईडी कोReplicaId
का उपयोग करके वापस पाया जा सकता है).replica_groups
खाली होनी चाहिए (जिस स्थिति में सभी प्रतिकृतियां एक ही समूह से संबंधित हों) या उसमें प्रतिरूपों की संख्या के बराबर तत्व हों. उदाहरण के लिए,replica_groups = {0, 2}, {1, 3}
,0
और2
के बीच और1
और3
के बीच डेटा को कम करता है.- क्रॉस-मॉड्यूल कम्यूनिकेशन के लिए,
channel_id
का इस्तेमाल किया जाता है: एक जैसेchannel_id
वाले सिर्फ़all-reduce
ऑपरेशन एक-दूसरे से इंटरैक्ट कर सकते हैं.
आउटपुट का शेप, इनपुट के शेप जैसा ही होता है. उदाहरण के लिए, अगर दो प्रतिकृतियां हैं और ऑपरेंड की वैल्यू [1.0, 2.5]
और [3.0, 5.25]
है, तो दोनों कॉपी पर इस ऑप और समेशन कंप्यूटेशन की आउटपुट वैल्यू [4.0, 7.75]
होगी. अगर इनपुट ट्यूपल है, तो आउटपुट भी ट्यूपल होगा.
AllReduce
के नतीजे की गिनती करने के लिए, हर रेप्लिका से एक इनपुट होना ज़रूरी है.
इसलिए, अगर कोई एक कॉपी किसी AllReduce
नोड को दूसरे से ज़्यादा बार एक्ज़ीक्यूट करता है, तो पहले वाला रेप्लिका हमेशा के लिए इंतज़ार करेगा. सभी प्रतिकृति एक ही प्रोग्राम चला रही हैं, इसलिए ऐसा होने के कई तरीके नहीं हैं. हालांकि, ऐसा तब हो सकता है, जब किसी 'जब तक' लूप की शर्त, इनफ़ीड के डेटा पर निर्भर हो और इनफ़ीड किए गए डेटा की वजह से, 'जब तक' लूप किसी एक प्रतिकृति पर दूसरे की तुलना में ज़्यादा बार दोहराया जाए.
AllToAll
XlaBuilder::AllToAll
भी देखें.
AllToAll एक सामूहिक ऑपरेशन है, जो सभी कोर से सभी कोर पर डेटा भेजता है. इसमें दो चरण होते हैं:
- स्कैटर फ़ेज़. हर कोर पर, ऑपरेंड को
split_dimensions
के साथsplit_count
ब्लॉक में बांटा जाता है और ब्लॉक सभी कोर में भेजे जाते हैं. उदाहरण के लिए, ith ब्लॉक को ith कोर पर भेजा जाता है. - इकट्ठा करने का चरण. हर कोर, मिले ब्लॉक को
concat_dimension
के साथ जोड़ता है.
हिस्सा लेने वाले कोर इन तरीकों से कॉन्फ़िगर किए जा सकते हैं:
replica_groups
: हर ReplicaGroup में कंप्यूटेशन में हिस्सा ले रहे प्रतिरूप आईडी की सूची होती है (मौजूदा प्रतिकृति के डुप्लीकेट आईडी कोReplicaId
का इस्तेमाल करके वापस पाया जा सकता है). AllToAll, तय किए गए क्रम में सबग्रुप में लागू किया जाएगा. उदाहरण के लिए,replica_groups = { {1,2,3}, {4,5,0} }
का मतलब है कि इकट्ठा करने के फ़ेज़ में,{1, 2, 3}
के रेप्लिक में एक-दूसरे से जुड़े सभी ब्लॉक लागू किए जाएंगे. साथ ही, मिले ब्लॉक को 1, 2, 3 के क्रम में जोड़ दिया जाएगा. इसके बाद, 4, 5, 0 वाले रिप्लिक में एक और AllToAll लागू किया जाएगा. साथ ही, कनकैनेटेशन का क्रम भी 4, 5, 0 होगा. अगरreplica_groups
खाली है, तो सभी रेप्लिक एक ग्रुप के होते हैं. ये ग्रुप, दिखने के क्रम में जोड़े जाते हैं.
ज़रूरी शर्तें:
split_dimension
पर ऑपरेंड का डाइमेंशन साइज़,split_count
से डिवाइड किया जा सकता है.- ऑपरेंड का आकार टपल नहीं होता.
AllToAll(operand, split_dimension, concat_dimension, split_count,
replica_groups)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
n डाइमेंशन वाला इनपुट ऐरे |
split_dimension
|
int64
|
इंटरवल [0,
n) में मौजूद एक वैल्यू, जो उस डाइमेंशन का नाम देती है
जिसके साथ ऑपरेंड को बांटा जाता है |
concat_dimension
|
int64
|
इंटरवल [0,
n) में मौजूद वैल्यू, जो उस डाइमेंशन का नाम बताती है जिसके साथ स्प्लिट किए गए ब्लॉक को जोड़ा जाता है |
split_count
|
int64
|
इस ऑपरेशन में हिस्सा लेने वाली कोर की संख्या. अगर replica_groups खाली है, तो यह वैल्यू, रीप्लिक की संख्या होनी चाहिए. अगर यह वैल्यू नहीं है, तो यह वैल्यू हर ग्रुप में मौजूद रीप्लिक की संख्या के बराबर होनी चाहिए. |
replica_groups
|
ReplicaGroup वेक्टर
|
हर ग्रुप में, डुप्लीकेट आईडी की सूची होती है. |
नीचे ऑलटोल का एक उदाहरण दिया गया है.
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);
इस उदाहरण में, Alltoall में चार कोर शामिल हैं. हर कोर पर, ऑपरेंड को डाइमेंशन 0 के हिसाब से चार हिस्सों में बांटा जाता है. इसलिए, हर हिस्से का शेप f32[4,4] होता है. 4 भाग, सभी कोर पर बिखरे हुए हैं. इसके बाद, हर कोर, डाइमेंशन 1 के साथ मिले हिस्सों को कोर 0 से 4 के क्रम में जोड़ता है. इसलिए, हर कोर पर आउटपुट का साइज़ f32[16,4] होता है.
BatchNormGrad
एल्गोरिदम के बारे में ज़्यादा जानकारी के लिए, XlaBuilder::BatchNormGrad
और ओरिजनल बैच नॉर्मलाइज़ेशन पेपर भी देखें.
बैच नॉर्म के ग्रेडिएंट की गणना करता है.
BatchNormGrad(operand, scale, mean, variance, grad_output, epsilon, feature_index)
तर्क | टाइप | सिमैंटिक |
---|---|---|
operand |
XlaOp |
नॉर्मलाइज़ की जाने वाली n डाइमेंशन वाली सरणी (x) |
scale |
XlaOp |
एक डाइमेंशन वाला अरे (\(\gamma\)) |
mean |
XlaOp |
एक डाइमेंशन वाला अरे (\(\mu\)) |
variance |
XlaOp |
एक डाइमेंशन वाला अरे (\(\sigma^2\)) |
grad_output |
XlaOp |
BatchNormTraining (\(\nabla y\)) को पास किए गए ग्रेडिएंट |
epsilon |
float |
एप्सिलॉन वैल्यू (\(\epsilon\)) |
feature_index |
int64 |
operand में सुविधा के डाइमेंशन के लिए इंडेक्स |
सुविधा डाइमेंशन की हर सुविधा के लिए (feature_index
, operand
में फ़ीचर डाइमेंशन के लिए इंडेक्स है). यह कार्रवाई, अन्य सभी डाइमेंशन में operand
, offset
, और scale
के हिसाब से ग्रेडिएंट की गिनती करती है. feature_index
, operand
में मौजूद फ़ीचर डाइमेंशन के लिए एक मान्य इंडेक्स होना चाहिए.
तीन ग्रेडिएंट को इन फ़ॉर्मूला से तय किया जाता है (यह मानते हुए कि
4-डाइमेंशन वाला अरे operand
के रूप में और सुविधा डाइमेंशन इंडेक्स l
, बैच साइज़ m
, और स्पेशल साइज़ w
और h
) है):
\[ \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} \]
इनपुट mean
और variance
, बैच और जगह के डाइमेंशन में, पल की वैल्यू दिखाते हैं.
आउटपुट टाइप में तीन हैंडल शामिल होते हैं:
आउटपुट | टाइप | सिमैंटिक |
---|---|---|
grad_operand
|
XlaOp
|
इनपुट operand के हिसाब से ग्रेडिएंट ($\nabla
x$) |
grad_scale
|
XlaOp
|
इनपुट scale ($\nabla
\gamma$) के मुताबिक ग्रेडिएंट |
grad_offset
|
XlaOp
|
इनपुट offset के हिसाब से ग्रेडिएंट ($\nabla
\beta$) |
BatchNormInference
एल्गोरिदम के बारे में ज़्यादा जानकारी के लिए, XlaBuilder::BatchNormInference
और ओरिजनल बैच नॉर्मलाइज़ेशन पेपर भी देखें.
बैच और स्पेशल डाइमेंशन के हिसाब से अरे को नॉर्मलाइज़ करता है.
BatchNormInference(operand, scale, offset, mean, variance, epsilon, feature_index)
तर्क | टाइप | सिमैंटिक |
---|---|---|
operand |
XlaOp |
नॉर्मलाइज़ की जाने वाली n डाइमेंशन वाली कैटगरी |
scale |
XlaOp |
1 डाइमेंशन वाला अरे |
offset |
XlaOp |
एक डाइमेंशन वाला ऐरे |
mean |
XlaOp |
एक डाइमेंशन वाला ऐरे |
variance |
XlaOp |
एक डाइमेंशन वाला ऐरे |
epsilon |
float |
एप्सिलॉन वैल्यू |
feature_index |
int64 |
operand में सुविधा के डाइमेंशन के लिए इंडेक्स |
फ़ीचर डाइमेंशन (feature_index
, operand
में फ़ीचर डाइमेंशन का इंडेक्स है) में मौजूद हर फ़ीचर के लिए, ऑपरेशन बाकी सभी डाइमेंशन में औसत और वैरिएंस का हिसाब लगाता है. साथ ही, operand
में हर एलिमेंट को सामान्य बनाने के लिए, औसत और वैरिएंस का इस्तेमाल करता है. operand
में मौजूद सुविधा डाइमेंशन के लिए, feature_index
एक मान्य इंडेक्स होना चाहिए.
BatchNormInference
, हर बैच के लिए mean
और variance
का हिसाब लगाए बिना, BatchNormTraining
को कॉल करने के बराबर है. यह अनुमानित वैल्यू के तौर पर, इनपुट mean
और
variance
का इस्तेमाल करता है. इस ऑपरेशन का मकसद, अनुमान लगाने में लगने वाले समय को कम करना है. इसलिए, इसका नाम BatchNormInference
है.
आउटपुट एक एन-डाइमेंशन वाला नॉर्मलाइज़्ड अरे होता है, जिसका आकार इनपुट operand
के जैसा होता है.
BatchNormTraining
एल्गोरिदम के बारे में ज़्यादा जानकारी के लिए, XlaBuilder::BatchNormTraining
और the original batch normalization paper
भी देखें.
बैच और स्पेस डाइमेंशन में मौजूद किसी ऐरे को सामान्य बनाता है.
BatchNormTraining(operand, scale, offset, epsilon, feature_index)
तर्क | टाइप | सिमैंटिक |
---|---|---|
operand |
XlaOp |
नॉर्मलाइज़ की जाने वाली n डाइमेंशन वाली सरणी (x) |
scale |
XlaOp |
एक डाइमेंशन वाला अरे (\(\gamma\)) |
offset |
XlaOp |
एक डाइमेंशन वाला अरे (\(\beta\)) |
epsilon |
float |
एप्सिलॉन मान (\(\epsilon\)) |
feature_index |
int64 |
operand में, फ़ीचर डाइमेंशन का इंडेक्स |
फ़ीचर डाइमेंशन (feature_index
, operand
में फ़ीचर डाइमेंशन का इंडेक्स है) में मौजूद हर फ़ीचर के लिए, ऑपरेशन बाकी सभी डाइमेंशन में औसत और वैरिएंस का हिसाब लगाता है. साथ ही, operand
में हर एलिमेंट को सामान्य बनाने के लिए, औसत और वैरिएंस का इस्तेमाल करता है. operand
में मौजूद सुविधा डाइमेंशन के लिए, feature_index
एक मान्य इंडेक्स होना चाहिए.
operand
\(x\) में मौजूद हर बैच के लिए, एल्गोरिदम इस तरह काम करता है. इसमें m
एलिमेंट होते हैं, जिनमें स्पेस डाइमेंशन का साइज़ w
और h
होता है. यह मानते हुए कि operand
एक चार डाइमेंशन वाला कलेक्शन है:
यह फ़ंक्शन, सुविधा डाइमेंशन में मौजूद हर सुविधा
l
के लिए \(\mu_l\) बैच के माध्य की गणना करता है: \(\mu_l=\frac{1}{mwh}\sum_{i=1}^m\sum_{j=1}^w\sum_{k=1}^h x_{ijkl}\)बैच वैरियंस कैलकुलेट करता है \(\sigma^2_l\): $\sigma^2l=\frac{1}{mwh}\sum{i=1}^m\sum{j=1}^w\sum{k=1}^h (x_{ijkl} - \mu_l)^2$
नॉर्मलाइज़, स्केल, और शिफ़्ट: \(y_{ijkl}=\frac{\gamma_l(x_{ijkl}-\mu_l)}{\sqrt[2]{\sigma^2_l+\epsilon} }+\beta_l\)
एप्सिलॉन वैल्यू, आम तौर पर एक छोटी संख्या को, 'शून्य से भाग देने पर' वाली गड़बड़ियों से बचने के लिए जोड़ा जाता है.
आउटपुट टाइप, तीन XlaOp
के टपल होता है:
आउटपुट | टाइप | सिमैंटिक्स |
---|---|---|
output
|
XlaOp
|
n डाइमेंशन वाला अरे, जिसका आकार इनपुट के जैसा है
operand (y) |
batch_mean |
XlaOp |
एक डाइमेंशन वाला ऐरे (\(\mu\)) |
batch_var |
XlaOp |
एक डाइमेंशन वाला अरे (\(\sigma^2\)) |
batch_mean
और batch_var
मोमेंट को बैच और स्पेशल डाइमेंशन के हिसाब से कैलकुलेट किया जाता है. इसके लिए, ऊपर दिए गए फ़ॉर्मूले इस्तेमाल करें.
BitcastConvertType
XlaBuilder::BitcastConvertType
भी देखें.
TensorFlow के tf.bitcast
की तरह ही, यह डेटा आकार से टारगेट आकार तक एलिमेंट के हिसाब से बिटकास्ट
कार्रवाई करता है. इनपुट और आउटपुट का साइज़ एक जैसा होना चाहिए: उदाहरण के लिए, बिटकस्ट रूटीन की मदद से s32
एलिमेंट, f32
एलिमेंट में बदल जाते हैं. साथ ही, एक s32
एलिमेंट चार s8
एलिमेंट में बदल जाता है. Bitcast को लो-लेवल कास्ट के तौर पर लागू किया जाता है, इसलिए अलग-अलग फ़्लोटिंग-पॉइंट दिखाने वाली मशीनों से अलग-अलग नतीजे मिलते हैं.
BitcastConvertType(operand, new_element_type)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
डाइमेंशन D के साथ टाइप T का ऐरे |
new_element_type |
PrimitiveType |
U टाइप करें |
ऑपरेंड और टारगेट शेप के डाइमेंशन मैच होने चाहिए. हालांकि, आखिरी डाइमेंशन के लिए ऐसा ज़रूरी नहीं है. यह डाइमेंशन, कन्वर्ज़न से पहले और बाद में प्रिमाइटिव साइज़ के अनुपात के हिसाब से बदल जाएगा.
सोर्स और डेस्टिनेशन एलिमेंट के टाइप टूपल नहीं होने चाहिए.
बिटकास्ट-अलग-अलग चौड़ाई वाले प्रिमिटिव टाइप में बदलना
BitcastConvert
HLO निर्देश तब काम करता है, जब आउटपुट एलिमेंट टाइप T'
का साइज़, इनपुट एलिमेंट T
के साइज़ से मेल न खाता हो. पूरी प्रोसेस को कॉन्सेप्ट के हिसाब से बिटकस्ट माना जाता है. इसमें, मौजूदा बाइट में कोई बदलाव नहीं होता. इसलिए, आउटपुट एलिमेंट का शेप बदलना पड़ता है. B = sizeof(T), B' =
sizeof(T')
के लिए, दो संभावित मामले हैं.
सबसे पहले, जब B > B'
, आउटपुट आकार को साइज़ का नया सबसे छोटा डाइमेंशन मिलता है
B/B'
. उदाहरण के लिए:
f16[10,2]{1,0} %output = f16[10,2]{1,0} bitcast-convert(f32[10]{0} %input)
लागू स्केलर के लिए नियम समान ही रहता है:
f16[2]{0} %output = f16[2]{0} bitcast-convert(f32[] %input)
इसके अलावा, B' > B
के लिए निर्देश में यह ज़रूरी है कि इनपुट शेप का आखिरी लॉजिकल डाइमेंशन, B'/B
के बराबर हो. साथ ही, कन्वर्ज़न के दौरान इस डाइमेंशन को हटा दिया जाता है:
f32[10]{0} %output = f32[10]{0} bitcast-convert(f16[10,2]{1,0} %input)
ध्यान दें कि अलग-अलग बिटविड्थ के बीच कन्वर्ज़न, एलिमेंट के मुताबिक नहीं होते हैं.
ब्रॉडकास्ट करना
XlaBuilder::Broadcast
भी देखें.
ऐरे में मौजूद डेटा का डुप्लीकेट बनाकर, ऐरे में डाइमेंशन जोड़ता है.
Broadcast(operand, broadcast_sizes)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
डुप्लीकेट किया जाने वाला अरे |
broadcast_sizes |
ArraySlice<int64> |
नए डाइमेंशन के साइज़ |
नए डाइमेंशन बाईं ओर डाले जाते हैं. इसका मतलब है कि अगर broadcast_sizes
में वैल्यू {a0, ..., aN}
है और ऑपरेंड के शेप में डाइमेंशन {b0, ..., bM}
हैं, तो आउटपुट के शेप में डाइमेंशन {a0, ..., aN, b0, ..., bM}
होंगे.
नए डाइमेंशन, ऑपरेंड की कॉपी में इंडेक्स होते हैं, जैसे कि
output[i0, ..., iN, j0, ..., jM] = operand[j0, ..., jM]
उदाहरण के लिए, अगर operand
एक स्केलर f32
है, जिसकी वैल्यू 2.0f
है और
broadcast_sizes
{2, 3}
है, तो नतीजा एक ऐरे होगा, जिसका शेप
f32[2, 3]
होगा और नतीजे में सभी वैल्यू 2.0f
होंगी.
BroadcastInDim
XlaBuilder::BroadcastInDim
भी देखें.
अरे में डेटा का डुप्लीकेट बनाकर, किसी कलेक्शन का साइज़ और रैंक बढ़ाता है.
BroadcastInDim(operand, out_dim_size, broadcast_dimensions)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
डुप्लीकेट किया जाने वाला अरे |
out_dim_size |
ArraySlice<int64> |
टारगेट किए गए आकार के डाइमेंशन का साइज़ |
broadcast_dimensions |
ArraySlice<int64> |
ऑपरेंड शेप का हर डाइमेंशन, टारगेट शेप के किस डाइमेंशन से मेल खाता है |
यह ब्रॉडकास्ट की तरह है, लेकिन इसमें कहीं भी डाइमेंशन जोड़ने और पहले से मौजूद डाइमेंशन को बड़ा करने की सुविधा मिलती है.
operand
को out_dim_size
से बताए गए आकार पर ब्रॉडकास्ट किया जाता है.
broadcast_dimensions
, operand
के डाइमेंशन को टारगेट शेप के डाइमेंशन से मैप करता है. इसका मतलब है कि ऑपरेंड का i'th डाइमेंशन, आउटपुट शेप के broadcast_dimension[i]'th डाइमेंशन से मैप होता है. operand
के डाइमेंशन का साइज़ 1 होना चाहिए या वह आउटपुट शेप में मौजूद डाइमेंशन के साइज़ के बराबर होना चाहिए जिस पर डाइमेंशन को मैप किया गया है. बाकी डाइमेंशन, साइज़ 1 के डाइमेंशन से भरे जाते हैं. इसके बाद, डीजनरेट-डाइमेंशन ब्रॉडकास्टिंग, आउटपुट शेप तक पहुंचने के लिए इन डीजनरेट डाइमेंशन के साथ ब्रॉडकास्ट करती है. सिमेंटिक्स के बारे में ब्रॉडकास्ट करने वाले पेज पर
पूरी जानकारी दी गई है.
कॉल करें
XlaBuilder::Call
भी देखें.
दिए गए आर्ग्युमेंट के साथ कैलकुलेशन को शुरू करता है.
Call(computation, args...)
तर्क | टाइप | सिमैंटिक |
---|---|---|
computation |
XlaComputation |
आर्बिट्रेरी टाइप के N पैरामीटर के साथ T_0, T_1, ..., T_{N-1} -> S टाइप की कंप्यूटेशन |
args |
N XlaOp s का क्रम |
आर्बिट्रेरी टाइप के N आर्ग्युमेंट |
args
की ऐरिटी और टाइप, computation
के पैरामीटर से मेल खाने चाहिए. कोई args
नहीं होना चाहिए.
Cholesky
XlaBuilder::Cholesky
भी देखें.
यह सिमेट्रिक (हर्मिटियन) पॉज़िटिव डेफ़ाइनाइट मैट्रिक्स के बैच का चोलस्की डिकंपोज़िशन करता है.
Cholesky(a, lower)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
a |
XlaOp |
कॉम्प्लेक्स या फ़्लोटिंग-पॉइंट टाइप की रैंक > दो अरे. |
lower |
bool |
a के ऊपरी या निचले त्रिभुज का इस्तेमाल करना है. |
अगर lower
true
है, तो निचले त्रिकोणीय आव्यूहों का l
इस तरह से हिसाब करता है कि $a = l .
l^T$. अगर lower
false
है, तो ऊपरी त्रिभुजों वाले आव्यूहों का u
इस तरह से हिसाब करता है
\(a = u^T . u\).
इनपुट डेटा को सिर्फ़ a
के निचले/ऊपरी त्रिकोण से पढ़ा जाता है. यह lower
की वैल्यू पर निर्भर करता है. दूसरे त्रिभुज की वैल्यू नज़रअंदाज़ कर दी जाती हैं. आउटपुट डेटा, उसी ट्राएंगल में दिखाया जाता है. दूसरे ट्राएंगल में मौजूद वैल्यू, लागू करने के तरीके के हिसाब से तय होती हैं और वे कुछ भी हो सकती हैं.
अगर a
की रैंक दो से ज़्यादा है, तो a
को मैट्रिक के बैच के तौर पर माना जाता है. इसमें दो छोटे डाइमेंशन को छोड़कर, सभी डाइमेंशन बैच डाइमेंशन होते हैं.
अगर a
, सिमेट्रिक (हर्मिटियन) पॉज़िटिव नहीं है, तो नतीजा लागू करने के तरीके के आधार पर तय होता है.
क्लैंप
XlaBuilder::Clamp
भी देखें.
ऑपरेंड को कम से कम और ज़्यादा से ज़्यादा वैल्यू की रेंज में क्लैंप करता है.
Clamp(min, operand, max)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
min |
XlaOp |
T टाइप का अरे |
operand |
XlaOp |
T टाइप का कलेक्शन |
max |
XlaOp |
T टाइप का कलेक्शन |
ऑपरेंड और कम से कम और ज़्यादा से ज़्यादा वैल्यू दी गई है. अगर ऑपरेंड, कम से कम और ज़्यादा से ज़्यादा वैल्यू के बीच की रेंज में है, तो ऑपरेंड दिखाता है. अगर ऑपरेंड इस रेंज से कम है, तो कम से कम वैल्यू दिखाता है. अगर ऑपरेंड इस रेंज से ज़्यादा है, तो ज़्यादा से ज़्यादा वैल्यू दिखाता है. इसका मतलब है कि clamp(a, x, b) = min(max(a, x), b)
.
तीनों सरणियों का आकार एक जैसा होना चाहिए. इसके अलावा, ब्रॉडकास्ट के पाबंदी वाले फ़ॉर्म के तौर पर, min
और/या max
, T
टाइप का स्केलर हो सकता है.
min
और max
स्केलर के साथ उदाहरण:
let operand: s32[3] = {-1, 5, 9};
let min: s32 = 0;
let max: s32 = 6;
==>
Clamp(min, operand, max) = s32[3]{0, 5, 6};
छोटा करें
XlaBuilder::Collapse
और tf.reshape
कार्रवाई भी देखें.
किसी ऐरे के डाइमेंशन को एक डाइमेंशन में छोटा कर देता है.
Collapse(operand, dimensions)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
T टाइप का अरे |
dimensions |
int64 वेक्टर |
क्रम में, T के डाइमेंशन का लगातार सबसेट. |
'छोटा करें', ऑपरेंड के डाइमेंशन के दिए गए सबसेट को एक डाइमेंशन से बदल देता है. इनपुट आर्ग्युमेंट, टाइप T का कोई भी अरे और डाइमेंशन इंडेक्स का संकलन के समय का कॉन्स्टेंट वेक्टर होता है. डाइमेंशन इंडेक्स, क्रम में (कम से ज़्यादा डाइमेंशन नंबर) और T डाइमेंशन के
एक के बाद एक सबसेट होने चाहिए. इसलिए, {0, 1, 2}, {0, 1} या {1, 2} सभी मान्य डाइमेंशन सेट हैं, लेकिन
{1, 0} या {0, 2} नहीं हैं. इनकी जगह एक नए डाइमेंशन को डाइमेंशन के क्रम में उसी जगह पर रखा जाता है जहां ये डाइमेंशन होते हैं. साथ ही, नए डाइमेंशन का साइज़, ओरिजनल डाइमेंशन के साइज़ के प्रॉडक्ट के बराबर होता है. dimensions
में डाइमेंशन की सबसे कम संख्या, लूप नेस्ट में सबसे धीरे बदलने वाला डाइमेंशन (सबसे ज़्यादा मेजर) होता है. यह लूप नेस्ट, इन डाइमेंशन को छोटा कर देता है. वहीं, डाइमेंशन की सबसे ज़्यादा संख्या, सबसे तेज़ी से बदलने वाला डाइमेंशन (सबसे मामूली) होता है. अगर सामान्य रूप से छोटा करने का क्रम ज़रूरी हो, तो tf.reshape
ऑपरेटर देखें.
उदाहरण के लिए, मान लें कि v 24 एलिमेंट का ऐरे है:
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} };
CollectivePermute
XlaBuilder::CollectivePermute
भी देखें.
CollectivePermute एक ऐसा ऑपरेशन है जो डेटा को क्रॉस रिप्लिकेट में भेजता और पाता है.
CollectivePermute(operand, source_target_pairs)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
n डाइमेंशन वाला इनपुट ऐरे |
source_target_pairs |
<int64, int64> वेक्टर |
(source_Replica_id, target_Replica_id) जोड़े की सूची. हर पेयर के लिए ऑपरेंड को सोर्स रेप्लिका से टारगेट रेप्लिका में भेजा जाता है. |
ध्यान दें कि source_target_pair
पर ये पाबंदियां हैं:
- किसी भी दो पेयर में एक ही टारगेट रेप्लिका आईडी नहीं होना चाहिए और उनमें एक ही सोर्स रेप्लिका आईडी नहीं होना चाहिए.
- अगर प्रतिकृति आईडी किसी भी जोड़े में टारगेट नहीं है, तो उस प्रतिकृति पर मौजूद आउटपुट एक टेंसर होगा, जिसमें इनपुट के समान आकार के 0 होंगे.
जोड़ें
XlaBuilder::ConcatInDim
भी देखें.
Concatenate फ़ंक्शन, कई ऐरे ऑपरेंड से एक ऐरे बनाता है. अरे की रैंक उसी क्रम में होती है जिसमें हर इनपुट अरे ऑपरेंड (जिसकी रैंक एक-दूसरे के जैसी होनी चाहिए) में होती है. इसमें आर्ग्युमेंट उसी क्रम में होते हैं जिस क्रम में वे तय किए गए होते हैं.
Concatenate(operands..., dimension)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operands |
N XlaOp का क्रम |
डाइमेंशन [L0, L1, ...] वाले T टाइप के N ऐरे. इसके लिए, N >= 1 होना ज़रूरी है. |
dimension |
int64 |
इंटरवल [0, N) में मौजूद एक वैल्यू, जो operands के बीच जोड़ने वाले डाइमेंशन को नाम देती है. |
dimension
को छोड़कर, सभी डाइमेंशन एक जैसे होने चाहिए. ऐसा इसलिए है, क्योंकि XLA में "रैग्ड" ऐरे काम नहीं करते. यह भी ध्यान दें कि रैंक-0 की वैल्यू को एक साथ नहीं जोड़ा जा सकता. ऐसा इसलिए, क्योंकि उस डाइमेंशन का नाम नहीं दिया जा सकता जिसमें वैल्यू को जोड़ा जाता है.
एक डाइमेंशन वाला उदाहरण:
Concat({ {2, 3}, {4, 5}, {6, 7} }, 0)
>>> {2, 3, 4, 5, 6, 7}
दो डाइमेंशन वाला उदाहरण:
let a = {
{1, 2},
{3, 4},
{5, 6},
};
let b = {
{7, 8},
};
Concat({a, b}, 0)
>>> {
{1, 2},
{3, 4},
{5, 6},
{7, 8},
}
डायग्राम:
कंडीशनल
XlaBuilder::Conditional
भी देखें.
Conditional(pred, true_operand, true_computation, false_operand,
false_computation)
तर्क | टाइप | सिमैंटिक |
---|---|---|
pred |
XlaOp |
PRED टाइप का स्केलर |
true_operand |
XlaOp |
\(T_0\)टाइप का आर्ग्युमेंट |
true_computation |
XlaComputation |
\(T_0 \to S\)टाइप का XlaComputation |
false_operand |
XlaOp |
\(T_1\)टाइप का आर्ग्युमेंट |
false_computation |
XlaComputation |
\(T_1 \to S\)टाइप का Xla Computeation |
अगर pred
true
है, तो true_computation
को एक्ज़ीक्यूट करता है. अगर pred
false
है, तो false_computation
लागू होता है. यह नतीजा दिखाता है.
true_computation
में \(T_0\) टाइप का एक आर्ग्युमेंट होना चाहिए. साथ ही, इसे true_operand
के साथ कॉल किया जाएगा, जो एक ही टाइप का होना चाहिए. false_computation
में \(T_1\) टाइप का एक आर्ग्युमेंट होना चाहिए. साथ ही, इसे false_operand
के साथ इस्तेमाल किया जाएगा, जो एक ही टाइप का होना चाहिए. true_computation
और false_computation
की रिटर्न वैल्यू का टाइप एक ही होना चाहिए.
ध्यान दें कि pred
की वैल्यू के आधार पर, true_computation
और false_computation
में से किसी एक को लागू किया जाएगा.
Conditional(branch_index, branch_computations, branch_operands)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
branch_index |
XlaOp |
S32 टाइप का स्केलर |
branch_computations |
N XlaComputation का क्रम |
\(T_0 \to S , T_1 \to S , ..., T_{N-1} \to S\)टाइप के XlaComputations |
branch_operands |
N XlaOp का क्रम |
\(T_0 , T_1 , ..., T_{N-1}\)टाइप के आर्ग्युमेंट |
branch_computations[branch_index]
को लागू करता है और नतीजा दिखाता है. अगर branch_index
एक ऐसा S32
है जो < 0 या >= N है, तो branch_computations[N-1]
को डिफ़ॉल्ट शाखा के तौर पर चलाया जाता है.
हर branch_computations[b]
में \(T_b\) टाइप का एक आर्ग्युमेंट होना चाहिए और इसे branch_operands[b]
के साथ शुरू किया जाएगा, जो एक ही टाइप का होना चाहिए. हर branch_computations[b]
की रिटर्न वैल्यू का टाइप एक ही होना चाहिए.
ध्यान दें कि branch_index
की वैल्यू के आधार पर, branch_computations
में से सिर्फ़ एक को एक्ज़ीक्यूट किया जाएगा.
कन्वर्ज़न (कन्वर्ज़न)
XlaBuilder::Conv
भी देखें.
ConvWithGeneralPadding की तरह ही, लेकिन पैडिंग को कम शब्दों में SAME या VALID के तौर पर बताया गया है. SAME पैडिंग, इनपुट (lhs
) को शून्य से पैड करती है, ताकि बिना स्ट्राइडिंग के आउटपुट का साइज़, इनपुट के साइज़ जैसा ही रहे. मान्य पैडिंग (जगह) का मतलब है, कोई पैडिंग नहीं.
ConvWithGeneralPadding (कन्वोलूशन)
XlaBuilder::ConvWithGeneralPadding
भी देखें.
न्यूरल नेटवर्क में इस्तेमाल किए जाने वाले टाइप के कॉन्वोल्यूशन को कंप्यूट करता है. यहां, कॉन्वोल्यूशन को n-डाइमेंशनल विंडो के तौर पर देखा जा सकता है, जो n-डाइमेंशनल बेस एरिया में चलती है. साथ ही, विंडो की हर संभावित स्थिति के लिए हिसाब लगाया जाता है.
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
lhs |
XlaOp |
इनपुट के n+2 रेंज को रैंक करें |
rhs |
XlaOp |
n+2 रैंक वाला, कर्नेल वेट का ऐरे |
window_strides |
ArraySlice<int64> |
कर्नेल की चौड़ाई के n-d ऐरे |
padding |
ArraySlice< pair<int64,int64>> |
(कम, ज़्यादा) पैडिंग का n-d अरे |
lhs_dilation |
ArraySlice<int64> |
n-d lhs फैलाव के तरीके का फ़ैक्टर अरे |
rhs_dilation |
ArraySlice<int64> |
n-d rhs dilation factor array |
feature_group_count |
int64 | फ़ीचर ग्रुप की संख्या |
batch_group_count |
int64 | बैच ग्रुप की संख्या |
मान लें कि n स्थानिक डाइमेंशन की संख्या है. lhs
आर्ग्युमेंट, बेस एरिया की जानकारी देने वाला रैंक n+2 वाला ऐरे होता है. इसे इनपुट कहा जाता है, भले ही, rhs भी एक इनपुट है. न्यूरल नेटवर्क में, ये इनपुट ऐक्टिवेशन हैं.
n+2 डाइमेंशन इस क्रम में होते हैं:
batch
: इस डाइमेंशन में मौजूद हर कोऑर्डिनेट, एक अलग इनपुट दिखाता है. इसके लिए, कॉन्वोल्यूशन किया जाता है.z/depth/features
: बेस एरिया में हर (y,x) पोज़िशन से जुड़ा एक वेक्टर होता है, जो इस डाइमेंशन में जाता है.spatial_dims
:n
स्पेस डाइमेंशन के बारे में बताता है. इससे उस आधार क्षेत्र के बारे में पता चलता है जिस पर विंडो चलती है.
rhs
आर्ग्युमेंट, रैंक n+2 वाली एक ऐरे है, जो कॉन्वोल्यूशनल फ़िल्टर/कर्नल/विंडो के बारे में बताती है. डाइमेंशन इस क्रम में होते हैं:
output-z
: आउटपुट काz
डाइमेंशन.input-z
: इस डाइमेंशन के साइज़ कोfeature_group_count
से गुणा करने पर, lhs में मौजूदz
डाइमेंशन के साइज़ के बराबर होना चाहिए.spatial_dims
:n
स्पेस डाइमेंशन के बारे में बताता है. ये डाइमेंशन, बेस एरिया में चलने वाली n-d विंडो तय करते हैं.
window_strides
आर्ग्युमेंट, जगह के हिसाब से डाइमेंशन में कॉन्वोलूशनल विंडो की स्ट्राड के बारे में बताता है. उदाहरण के लिए, अगर पहले स्पेशल डाइमेंशन में स्ट्राड 3 है, तो विंडो को सिर्फ़ ऐसे निर्देशांक पर रखा जा सकता है जहां पहले स्पेशल इंडेक्स को 3 से डिवाइड किया जा सकता है.
padding
आर्ग्युमेंट से पता चलता है कि बेस एरिया में कितनी शून्य पैडिंग लागू की जानी है. पैडिंग (जगह) की मात्रा नेगेटिव हो सकती है -- नेगेटिव पैडिंग की पूरी वैल्यू, तय किए गए डाइमेंशन से हटाए जाने वाले एलिमेंट की संख्या बताती है. padding[0]
, डाइमेंशन y
के लिए पैडिंग तय करता है और padding[1]
, डाइमेंशन x
के लिए पैडिंग तय करता है. हर जोड़े में, पहले एलिमेंट के तौर पर कम पैडिंग और दूसरे एलिमेंट के तौर पर ज़्यादा पैडिंग होती है. कम पैडिंग, इंडेक्स के निचले हिस्से में लागू होती है, जबकि ज़्यादा पैडिंग, इंडेक्स के ऊपरी हिस्से में लागू होती है. उदाहरण के लिए, अगर
padding[1]
(2,3)
है, तो बाईं ओर दो शून्यों तक पैडिंग (जगह) और दूसरी स्पेशल डाइमेंशन में दाईं ओर 3 शून्य होगी. पैडिंग का इस्तेमाल करना, कॉन्वोल्यूशन करने से पहले इनपुट (lhs
) में वही शून्य वैल्यू डालने के बराबर है.
lhs_dilation
और rhs_dilation
आर्ग्युमेंट से, हर स्पेस डाइमेंशन में, lhs और rhs पर लागू होने वाला डाइलेशन फ़ैक्टर तय होता है. अगर किसी स्पेशल डाइमेंशन में डाइलेशन फ़ैक्टर d है, तो उस डाइमेंशन में हर एंट्री के बीच d-1 होल मौजूद होते हैं. इससे अरे का साइज़ बढ़ जाता है. छेदों में नो-ऑप वैल्यू डाली जाती है. इसका मतलब है कि पॉइंट शून्य हैं.
आरएचएस के डायलेशन को एट्रियल कॉन्वोल्यूशन भी कहा जाता है. ज़्यादा जानकारी के लिए, tf.nn.atrous_conv2d
देखें. बाईं ओर मौजूद हेडर को बड़ा करने की प्रोसेस को ट्रांसपोज़्ड
कन्वोल्यूशन भी कहा जाता है. ज़्यादा जानकारी के लिए, tf.nn.conv2d_transpose
देखें.
feature_group_count
आर्ग्युमेंट (डिफ़ॉल्ट वैल्यू 1) का इस्तेमाल, ग्रुप किए गए कॉन्वोल्यूशन के लिए किया जा सकता है. feature_group_count
को इनपुट और आउटपुट सुविधा डाइमेंशन, दोनों का भाजक होना चाहिए. अगर feature_group_count
एक से ज़्यादा है, तो इसका मतलब है कि कॉन्सेप्ट के हिसाब से, इनपुट और आउटपुट फ़ीचर डाइमेंशन और rhs
आउटपुट फ़ीचर डाइमेंशन को बराबर तौर पर कई feature_group_count
ग्रुप में बांटा गया है. हर ग्रुप में, फ़ीचर का एक क्रम होता है. rhs
की इनपुट फ़ीचर डाइमेंशन की वैल्यू, lhs
की इनपुट फ़ीचर डाइमेंशन की वैल्यू को feature_group_count
से भाग देने पर मिलने वाली वैल्यू के बराबर होनी चाहिए. ऐसा इसलिए, क्योंकि इसमें इनपुट फ़ीचर के ग्रुप का साइज़ पहले से मौजूद होता है. कई अलग-अलग कॉन्वोल्यूशन के लिए feature_group_count
का हिसाब लगाने के लिए, i-th ग्रुप का एक साथ इस्तेमाल किया जाता है. इस तरह की बातचीत के नतीजों को आउटपुट सुविधा के डाइमेंशन में जोड़ा जाता है.
डेप्थ-वाइज़ कन्वोल्यूशन के लिए, feature_group_count
आर्ग्युमेंट को इनपुट फ़ीचर डाइमेंशन पर सेट किया जाएगा. साथ ही, फ़िल्टर को [filter_height, filter_width, in_channels, channel_multiplier]
से [filter_height, filter_width, 1, in_channels * channel_multiplier]
में बदल दिया जाएगा. ज़्यादा जानकारी के लिए, tf.nn.depthwise_conv2d
देखें.
बैकप्रोपगेशन के दौरान, ग्रुप किए गए फ़िल्टर के लिए batch_group_count
(डिफ़ॉल्ट वैल्यू 1) आर्ग्युमेंट का इस्तेमाल किया जा सकता है. batch_group_count
, lhs
(इनपुट) बैच डाइमेंशन के साइज़ का डिवाइज़र होना चाहिए. अगर batch_group_count
का मान 1 से ज़्यादा है, तो इसका मतलब है कि आउटपुट बैच डाइमेंशन का साइज़ input batch
/ batch_group_count
होना चाहिए. batch_group_count
, आउटपुट फ़ीचर के साइज़ का डिविज़र होना चाहिए.
आउटपुट आकार में ये डाइमेंशन, इस क्रम में होते हैं:
batch
: इस आयाम का आकारbatch_group_count
सेकंड मेंbatch
आयाम के आकार के बराबर होना चाहिए.z
: कर्नेल परoutput-z
के बराबर आकार (rhs
).spatial_dims
: कॉन्वलूशनल विंडो के हर मान्य प्लेसमेंट के लिए एक वैल्यू.
ऊपर दिए गए इलस्ट्रेशन में दिखाया गया है कि batch_group_count
फ़ील्ड कैसे काम करता है. हम हर lhs बैच को batch_group_count
ग्रुप में बांटते हैं. साथ ही, आउटपुट फ़ीचर के लिए भी ऐसा ही करते हैं. इसके बाद, इनमें से हर ग्रुप के लिए, हम एक-दूसरे के साथ कॉन्वोल्यूशन करते हैं और आउटपुट फ़ीचर डाइमेंशन के साथ आउटपुट को जोड़ते हैं. अन्य सभी डाइमेंशन (सुविधा और स्पेस) के ऑपरेशनल सिमेंटिक में कोई बदलाव नहीं हुआ है.
कॉन्वोल्यूशनल विंडो की सही जगहें, पैडिंग के बाद आधार क्षेत्र के साइज़ और स्ट्राइड के हिसाब से तय की जाती हैं.
कॉन्वोल्यूशन क्या करता है, यह बताने के लिए, 2D कॉन्वोल्यूशन पर विचार करें और आउटपुट में कुछ तय batch
, z
, y
, x
निर्देशांक चुनें. इसके बाद, (y,x)
, बेस एरिया में विंडो के कोने की पोज़िशन होती है. उदाहरण के लिए, ऊपरी बायां कोना, जो स्पेस डाइमेंशन के हिसाब से तय होता है. अब हमारे पास बेस एरिया से ली गई 2D विंडो है, जहां हर 2D पॉइंट 1D वेक्टर से जुड़ा होता है. इससे हमें 3D बॉक्स मिलता है. कन्वोल्यूशनल कर्नेल से, हमने आउटपुट कोऑर्डिनेट z
को तय किया है. इसलिए, हमारे पास 3D बॉक्स भी है. दोनों बॉक्स के डाइमेंशन एक जैसे हैं. इसलिए, हम दोनों बॉक्स के एलिमेंट के हिसाब से प्रॉडक्ट का जोड़ (डॉट प्रॉडक्ट की तरह) ले सकते हैं. यह आउटपुट वैल्यू है.
ध्यान दें कि अगर output-z
, 5 का इस्तेमाल किया जाता है, तो विंडो की हर पोज़िशन, आउटपुट के z
डाइमेंशन में पांच वैल्यू जनरेट करती है. ये वैल्यू, कॉन्वोल्यूशनल केरल के किस हिस्से में इस्तेमाल की जाती हैं, इस आधार पर अलग-अलग होती हैं - हर output-z
कोऑर्डिनेट के लिए, वैल्यू का एक अलग 3D बॉक्स होता है. इसलिए, इसे पांच अलग-अलग कॉन्वोल्यूशन के तौर पर देखा जा सकता है. इनमें से हर कॉन्वोल्यूशन के लिए अलग फ़िल्टर का इस्तेमाल किया जाता है.
पैडिंग और स्ट्राइडिंग के साथ 2D कन्वोल्यूशन के लिए, यहां स्यूडो-कोड दिया गया है:
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
XlaBuilder::ConvertElementType
भी देखें.
C++ में एलिमेंट के हिसाब से static_cast
की तरह ही, यह भी डेटा शेप से टारगेट शेप में एलिमेंट के हिसाब से कन्वर्ज़न ऑपरेशन करता है. डाइमेंशन एक जैसे होने चाहिए और कन्वर्ज़न, एलिमेंट के हिसाब से होना चाहिए. उदाहरण के लिए, s32
से f32
कन्वर्ज़न रूटीन की मदद से, s32
एलिमेंट f32
एलिमेंट बन जाते हैं.
ConvertElementType(operand, new_element_type)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
डाइमेंशन D के साथ टाइप T का ऐरे |
new_element_type |
PrimitiveType |
टाइप U |
ऑपरेंड और टारगेट आकार के डाइमेंशन मैच होने चाहिए. सोर्स और डेस्टिनेशन एलिमेंट टाइप, टुपल नहीं होने चाहिए.
T=s32
से U=f32
जैसे कन्वर्ज़न के लिए, सामान्य int-to-float कन्वर्ज़न रूटीन लागू होगा. जैसे, राउंड-टू-नियरेस्ट-ईवन.
let a: s32[3] = {0, 1, 2};
let b: f32[3] = convert(a, f32);
then b == f32[3]{0.0, 1.0, 2.0}
CrossReplicaSum
यह फ़ंक्शन, जोड़ने की कैलकुलेशन के साथ AllReduce
करता है.
CustomCall
XlaBuilder::CustomCall
भी देखें.
कैलकुलेशन में, उपयोगकर्ता के दिए गए फ़ंक्शन को कॉल करना.
CustomCall(target_name, args..., shape)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
target_name |
string |
फ़ंक्शन का नाम. इस सिंबल के नाम को टारगेट करने वाला कॉल निर्देश जारी किया जाएगा. |
args |
N XlaOp s का क्रम |
किसी भी टाइप के N आर्ग्युमेंट, जिन्हें फ़ंक्शन में पास किया जाएगा. |
shape |
Shape |
फ़ंक्शन का आउटपुट आकार |
फ़ंक्शन सिग्नेचर, एक जैसा होता है. इससे कोई फ़र्क़ नहीं पड़ता कि एलिमेंट किस तरह का है या किस तरह का आर्ग है:
extern "C" void target_name(void* out, void** in);
उदाहरण के लिए, अगर CustomCall का इस्तेमाल इस तरह किया जाता है:
let x = f32[2] {1,2};
let y = f32[2x3] { {10, 20, 30}, {40, 50, 60} };
CustomCall("myfunc", {x, y}, f32[3x3])
यहां myfunc
को लागू करने का एक उदाहरण दिया गया है:
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];
// ...
}
उपयोगकर्ता के दिए गए फ़ंक्शन से कोई खराब असर नहीं पड़ना चाहिए. साथ ही, इसे एक ही तरीके से लागू किया जाना चाहिए.
डॉट
XlaBuilder::Dot
भी देखें.
Dot(lhs, rhs)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
lhs |
XlaOp |
T टाइप का अरे |
rhs |
XlaOp |
T टाइप का कलेक्शन |
इस ऑपरेशन के सटीक सिमैंटिक, ऑपरेंड की रैंक पर निर्भर करते हैं:
इनपुट | आउटपुट | सिमैंटिक |
---|---|---|
वेक्टर [n] dot वेक्टर [n] |
स्केलर | वेक्टर डॉट प्रॉडक्ट |
मैट्रिक्स [m x k] dot वेक्टर [k] |
वेक्टर [m] | मैट्रिक्स-वेक्टर मल्टीप्लिकेशन |
मैट्रिक्स [m x k] dot मैट्रिक्स [k x n] |
मैट्रिक्स [m x n] | मैट्रिक्स-मैट्रिक्स मल्टीप्लिकेशन |
यह ऑपरेशन, lhs
के दूसरे डाइमेंशन (या अगर इसकी रैंक 1 है, तो पहले डाइमेंशन) और rhs
के पहले डाइमेंशन में मौजूद प्रॉडक्ट का जोड़ करता है. ये "छोटे किए गए" डाइमेंशन हैं. lhs
और rhs
के कॉन्ट्रैक्ट किए गए डाइमेंशन एक जैसे होने चाहिए. इसका इस्तेमाल, सदिशों के बीच डॉट प्रॉडक्ट करने, सदिश/मैट्रिक्स के गुणन या मैट्रिक्स/मैट्रिक्स के गुणन के लिए किया जा सकता है.
DotGeneral
XlaBuilder::DotGeneral
भी देखें.
DotGeneral(lhs, rhs, dimension_numbers)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
lhs |
XlaOp |
T टाइप का अरे |
rhs |
XlaOp |
T टाइप का कलेक्शन |
dimension_numbers |
DotDimensionNumbers |
कॉन्ट्रैक्टिंग और बैच डाइमेंशन नंबर |
Dot की तरह ही है, लेकिन इससे lhs
और rhs
, दोनों के लिए कॉन्ट्रैक्ट और बैच डाइमेंशन नंबर तय किए जा सकते हैं.
DotdimensionNumbers फ़ील्ड | टाइप | सिमैंटिक्स |
---|---|---|
lhs_contracting_dimensions
|
दोहराया गया int64 | lhs कॉन्ट्रैक्टिंग डाइमेंशन के लिए
संख्याएं |
rhs_contracting_dimensions
|
repeated int64 | कॉन्ट्रैक्टिंग डाइमेंशन की rhs
संख्याएं |
lhs_batch_dimensions
|
दोहराया गया int64 | lhs बैच डाइमेंशन के नंबर |
rhs_batch_dimensions
|
दोहराया गया int64 | rhs बैच डाइमेंशन
नंबर |
DotGeneral, dimension_numbers
में बताए गए कॉन्ट्रैक्टिंग डाइमेंशन के हिसाब से प्रॉडक्ट का कुल योग करता है.
lhs
और rhs
से जुड़े कॉन्ट्रैक्टिंग डाइमेंशन नंबर एक जैसे होने ज़रूरी नहीं हैं. हालांकि, इनका डाइमेंशन साइज़ एक जैसा होना चाहिए.
डाइमेंशन नंबर कम करने का उदाहरण:
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
और rhs
से जुड़े बैच डाइमेंशन नंबर के डाइमेंशन साइज़ एक जैसे होने चाहिए.
बैच डाइमेंशन नंबर वाला उदाहरण (बैच साइज़ 2, 2x2 मैट्रिक्स):
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} } }
इनपुट | आउटपुट | सिमैंटिक्स |
---|---|---|
[b0, m, k] dot [b0, k, n] |
[b0, m, n] | batch matmul |
[b0, b1, m, k] dot [b0, b1, k, n] |
[b0, b1, m, n] | बैच Matmul |
इसके बाद, बनने वाला डाइमेंशन नंबर बैच डाइमेंशन से शुरू होता है. इसके बाद, lhs
नॉन-कॉन्ट्रैक्टिंग/नॉन-बैच डाइमेंशन और आखिर में rhs
नॉन-कॉन्ट्रैक्टिंग/न-बैच डाइमेंशन से शुरू होता है.
DynamicSlice
XlaBuilder::DynamicSlice
भी देखें.
DynamicSlice, डाइनैमिक
start_indices
पर इनपुट कलेक्शन से एक सब-कलेक्शन निकालता है. हर डाइमेंशन में स्लाइस का साइज़, size_indices
में पास किया जाता है. यह हर डाइमेंशन में एक्सक्लूज़िव स्लाइस इंटरवल के आखिरी पॉइंट की जानकारी देता है: [start, start + size). start_indices
का शेप, रैंक ==
1 होना चाहिए. साथ ही, डाइमेंशन का साइज़ operand
की रैंक के बराबर होना चाहिए.
DynamicSlice(operand, start_indices, size_indices)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
T टाइप का N डाइमेंशन वाला ऐरे |
start_indices |
N XlaOp का क्रम |
N स्केलर इंटिजर की सूची, जिसमें हर डाइमेंशन के लिए स्लाइस के शुरुआती इंडेक्स शामिल होते हैं. वैल्यू, शून्य से ज़्यादा या उसके बराबर होनी चाहिए. |
size_indices |
ArraySlice<int64> |
N पूर्णांकों की सूची, जिसमें हर डाइमेंशन के लिए स्लाइस का साइज़ शामिल होता है. हर वैल्यू, शून्य से ज़्यादा होनी चाहिए. साथ ही, शुरू + साइज़, डाइमेंशन के साइज़ से कम या उसके बराबर होना चाहिए, ताकि डाइमेंशन के साइज़ के हिसाब से रैपिंग न हो. |
स्लाइस करने से पहले, [1, N)
में मौजूद हर इंडेक्स i
पर यह ट्रांसफ़ॉर्मेशन लागू करके, असरदार स्लाइस इंडेक्स का हिसाब लगाया जाता है:
start_indices[i] = clamp(start_indices[i], 0, operand.dimension_size[i] - size_indices[i])
इससे यह पक्का होता है कि निकाला गया स्लाइस, ऑपरेंड ऐरे के हिसाब से हमेशा इन-बाउंड हो. अगर ट्रांसफ़ॉर्मेशन लागू होने से पहले स्लाइस इन-बाउंड है, तो ट्रांसफ़ॉर्मेशन का कोई असर नहीं पड़ता.
एक डाइमेंशन वाला उदाहरण:
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-डाइमेंशन वाला उदाहरण:
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
XlaBuilder::DynamicUpdateSlice
भी देखें.
DynamicUpdateSlice फ़ंक्शन, एक नतीजा जनरेट करता है. यह नतीजा, इनपुट ऐरे operand
की वैल्यू होती है. इसमें start_indices
पर ओवरराइट की गई स्लाइस update
होती है.
update
का आकार, नतीजे के उस सब-ऐरे का आकार तय करता है जिसे अपडेट किया जाता है.
start_indices
का शेप, रैंक == 1 होना चाहिए. साथ ही, डाइमेंशन का साइज़ operand
की रैंक के बराबर होना चाहिए.
DynamicUpdateSlice(operand, update, start_indices)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
T टाइप का N डाइमेंशन वाला अरे |
update |
XlaOp |
टाइप T का N डाइमेंशन वाला ऐरे, जिसमें स्लाइस अपडेट शामिल है. अपडेट आकार का हर डाइमेंशन शून्य से ज़्यादा होना चाहिए. साथ ही, आउट-ऑफ़-बाउंड अपडेट इंडेक्स जनरेट होने से रोकने के लिए, हर डाइमेंशन के शुरू और अपडेट का साइज़, ऑपरेंड साइज़ से कम या उसके बराबर होना चाहिए. |
start_indices |
N XlaOp का क्रम |
N अदिश पूर्णांकों की सूची, जिनमें हर डाइमेंशन के लिए स्लाइस के शुरुआती इंडेक्स शामिल हैं. वैल्यू, शून्य से ज़्यादा या उसके बराबर होनी चाहिए. |
स्लाइस करने से पहले, [1, N)
में हर इंडेक्स i
के लिए यहां दिए गए ट्रांसफ़ॉर्मेशन ऐक्शन को लागू करके, असरदार स्लाइस इंडेक्स का पता लगाया जाता है:
start_indices[i] = clamp(start_indices[i], 0, operand.dimension_size[i] - update.dimension_size[i])
इससे यह पक्का होता है कि अपडेट किया गया स्लाइस, ऑपरेंड कलेक्शन के हिसाब से हमेशा सीमाओं के अंदर हो. अगर स्लाइस, ट्रांसफ़ॉर्मेशन के लागू होने से पहले रेंज में है, तो इसका कोई असर नहीं पड़ेगा.
एक डाइमेंशन वाला उदाहरण:
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}
दो डाइमेंशन वाला उदाहरण:
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} }
एलिमेंट के हिसाब से बाइनरी अरिथमेटिक ऑपरेशन
XlaBuilder::Add
भी देखें.
एलिमेंट के हिसाब से बाइनरी अंकगणितीय ऑपरेशन का एक सेट काम करता है.
Op(lhs, rhs)
जहां Op
, Add
(जोड़), Sub
(सबट्रेक्शन), Mul
(गुणा), Div
(डिवीज़न), Pow
(पावर), Rem
(बचा हुआ), Max
(ज़्यादा से ज़्यादा), Min
(कम से कम), And
(लॉजिकल AND), Or
(लॉजिकल
OR), Xor
(लॉजिकल XOR), ShiftLeft
(लेफ़्ट शिफ़्ट) और ShiftRightArithmetic
(अरिथमेटिक राइट Shift या ShiftRightLogical
) में से कोई एक होAtan2
Complex
तर्क | टाइप | सिमैंटिक |
---|---|---|
lhs |
XlaOp |
बाईं ओर का ऑपरेंड: T टाइप का ऐरे |
rhs |
XlaOp |
दाईं ओर मौजूद ऑपरेंड: T टाइप का अरे |
आर्ग्युमेंट के आकार एक जैसे या काम के होने चाहिए. ब्रॉडकास्टिंग से जुड़ा दस्तावेज़ देखें. इसमें यह बताया गया है कि आकार के साथ काम करने का क्या मतलब है. किसी ऑपरेशन का नतीजा, दो इनपुट ऐरे को ब्रॉडकास्ट करने का नतीजा होता है. इस वैरिएंट में, अलग-अलग रैंक के ऐरे के बीच ऑपरेशन नहीं किए जा सकते. ऐसा तब तक नहीं किया जा सकता, जब तक कि ऑपरेंड में से कोई एक स्केलर न हो.
जब Op
Rem
होता है, तो नतीजे का चिह्न, डिवीडेंड से लिया जाता है. साथ ही, नतीजे की पूर्ण वैल्यू हमेशा, डिवीज़र की पूर्ण वैल्यू से कम होती है.
इंटिज़र डिवीज़न ओवरफ़्लो (शून्य से साइन किया गया/साइन नहीं किया गया डिवीज़न/शून्य से बचा हुआ या -1
के साथ INT_SMIN
का साइन किया हुआ विभाजन/बचाव) लागू करने के लिए तय की गई वैल्यू जनरेट करता है.
इन ऑपरेशन के लिए, अलग-अलग रैंक के ब्रॉडकास्टिंग वाला एक दूसरा वैरिएंट मौजूद है:
Op(lhs, rhs, broadcast_dimensions)
यहां Op
वही है जो ऊपर दिया गया है. ऑपरेशन के इस वैरिएंट का इस्तेमाल, अलग-अलग रैंक के ऐरे के बीच अंकगणितीय ऑपरेशन के लिए किया जाना चाहिए. जैसे, किसी वेक्टर में मैट्रिक्स जोड़ना.
अतिरिक्त broadcast_dimensions
ऑपरेंड, पूर्णांकों का एक हिस्सा होता है. इसका इस्तेमाल, निचले रैंक वाले ऑपरेंड की रैंक को उच्च रैंक ऑपरेटर तक बढ़ाने के लिए किया जाता है. broadcast_dimensions
, छोटी रैंक वाले आकार के डाइमेंशन को बेहतर रैंक वाले आकार के डाइमेंशन पर मैप करता है. बड़े किए गए आकार के उन डाइमेंशन को साइज़ एक के डाइमेंशन से भरा जाता है जिन्हें मैप नहीं किया गया है. इसके बाद, डीजनरेट-डाइमेंशन ब्रॉडकास्टिंग, दोनों ऑपरेंड के शेप को बराबर करने के लिए, इन डीजनरेट डाइमेंशन के साथ शेप को ब्रॉडकास्ट करती है. सिमेंटिक्स के बारे में ब्रॉडकास्ट करने वाले पेज पर पूरी जानकारी दी गई है.
एलिमेंट के हिसाब से तुलना करने वाले ऑपरेशन
XlaBuilder::Eq
भी देखें.
एलिमेंट के हिसाब से, बाइनरी तुलना करने वाले स्टैंडर्ड ऑपरेशन का एक सेट काम करता है. ध्यान दें कि फ़्लोटिंग-पॉइंट टाइप की तुलना करते समय, स्टैंडर्ड IEEE 754 फ़्लोटिंग-पॉइंट कंपैरिज़न सिमैंटिक का इस्तेमाल किया जा सकता है.
Op(lhs, rhs)
यहां Op
, Eq
(बराबर है), Ne
(बराबर नहीं है), Ge
(इससे ज़्यादा या इसके बराबर है), Gt
(इससे ज़्यादा है), Le
(इससे कम या इसके बराबर है), Lt
(इससे कम है) में से कोई एक है. ऑपरेटर का एक और सेट, EqTotalOrder, NeTotalOrder, GeTotalOrder,
GtTotalOrder, LeTotalOrder, और LtTotalOrder, एक जैसी सुविधाएं देता है. हालांकि, ये फ़्लोटिंग पॉइंट वाली संख्याओं के लिए, कुल क्रम की सुविधा भी देते हैं. इसके लिए, -NaN < -Inf < -Finite < -0 < +0 < +Finite < +Inf < +NaN का इस्तेमाल किया जाता है.
तर्क | टाइप | सिमैंटिक |
---|---|---|
lhs |
XlaOp |
बाईं ओर का ऑपरेंड: T टाइप का ऐरे |
rhs |
XlaOp |
दाईं ओर मौजूद ऑपरेंड: T टाइप का अरे |
आर्ग्युमेंट के आकार एक जैसे या काम के होने चाहिए. ब्रॉडकास्टिंग से जुड़ा दस्तावेज़ देखें. इसमें यह बताया गया है कि आकार के साथ काम करने का क्या मतलब है. किसी ऑपरेशन का नतीजा, एलिमेंट टाइप PRED
के साथ दो इनपुट ऐरे को ब्रॉडकास्ट करने का नतीजा होता है. इस वैरिएंट में, अलग-अलग रैंक के ऐरे के बीच ऑपरेशन नहीं किए जा सकते. ऐसा तब तक नहीं किया जा सकता, जब तक ऑपरेंड में से कोई एक स्केलर न हो.
इन ऑपरेशन के लिए, अलग-अलग रैंक के ब्रॉडकास्टिंग वाला एक दूसरा वैरिएंट मौजूद है:
Op(lhs, rhs, broadcast_dimensions)
यहां Op
वही है जो ऊपर दिया गया है. ऑपरेशन के इस वैरिएंट का इस्तेमाल, अलग-अलग रैंक वाले अरे के बीच तुलना करने के लिए किया जाना चाहिए. जैसे, किसी वेक्टर में मैट्रिक्स जोड़ना.
अतिरिक्त broadcast_dimensions
ऑपरेंड, पूर्णांकों का एक स्लाइस होता है. इसमें ऑपरेंड को ब्रॉडकास्ट करने के लिए इस्तेमाल किए जाने वाले डाइमेंशन की जानकारी होती है. सिमेंटिक्स के बारे में ब्रॉडकास्ट करने वाले पेज पर
पूरी जानकारी दी गई है.
एलिमेंट के हिसाब से यूनीऐरी फ़ंक्शन
XlaBuilder, एलिमेंट के हिसाब से इन यूनीऐरी फ़ंक्शन के साथ काम करता है:
Abs(operand)
एलिमेंट के हिसाब से एब्सोल्यूट वैल्यू x -> |x|
.
Cbrt(operand)
एलिमेंट के हिसाब से घनमूल निकालने का ऑपरेशन x -> cbrt(x)
.
Ceil(operand)
एलिमेंट के हिसाब से सील x -> ⌈x⌉
.
Clz(operand)
एलिमेंट के हिसाब से, शुरुआत में मौजूद शून्य की गिनती करें.
Cos(operand)
एलिमेंट के हिसाब से कोसाइन x -> cos(x)
.
Erf(operand)
एलिमेंट के हिसाब से गड़बड़ी का फ़ंक्शन x -> erf(x)
, जहां
\(\text{erf}(x) = \frac{2}{\sqrt{\pi} }\int_0^x e^{-t^2} \, dt\).
Exp(operand)
एलिमेंट के हिसाब से नेचुरल एक्सपोनेंशियल x -> e^x
.
Expm1(operand)
एलिमेंट के हिसाब से नेचुरल एक्सपोनेंशियल माइनस वन x -> e^x - 1
.
Floor(operand)
एलिमेंट के हिसाब से मंज़िल x -> ⌊x⌋
.
Imag(operand)
कॉम्प्लेक्स (या रीयल) आकार के एलिमेंट के हिसाब से काल्पनिक हिस्सा. x -> imag(x)
. अगर ऑपरेंड फ़्लोटिंग पॉइंट टाइप का है, तो 0 दिखाता है.
IsFinite(operand)
जांच करता है कि operand
का हर एलिमेंट सीमित है या नहीं. इसका मतलब है कि वह वैल्यू पॉज़िटिव या नेगेटिव इनफ़िनिटी नहीं है और NaN
नहीं है. इनपुट के तौर पर दिए गए वैल्यू के क्रम के हिसाब से, PRED
वैल्यू का एक कलेक्शन दिखाता है. इसमें हर एलिमेंट true
होता है, लेकिन सिर्फ़ तब, जब इनपुट में मौजूद उससे जुड़ा एलिमेंट सीमित हो.
Log(operand)
एलिमेंट के हिसाब से नैचुरल लॉगारिद्म x -> ln(x)
.
Log1p(operand)
एलिमेंट के हिसाब से शिफ़्ट किया गया नैचुरल लॉगारिद्म x -> ln(1+x)
.
Logistic(operand)
एलिमेंट के हिसाब से लॉजिस्टिक फ़ंक्शन का हिसाब लगाना x ->
logistic(x)
.
Neg(operand)
एलिमेंट के हिसाब से निगेशन x -> -x
.
Not(operand)
एलिमेंट के हिसाब से लॉजिकल नॉट x -> !(x)
.
PopulationCount(operand)
operand
के हर एलिमेंट में सेट किए गए बिट की संख्या का हिसाब लगाता है.
Real(operand)
किसी कॉम्प्लेक्स (या रीयल) आकार का एलिमेंट के हिसाब से असली हिस्सा.
x -> real(x)
. अगर ऑपरेंड किसी फ़्लोटिंग पॉइंट टाइप का है, तो वही वैल्यू दिखाता है.
Round(operand)
एलिमेंट के हिसाब से राउंडिंग, शून्य से दूर होती है.
RoundNearestEven(operand)
एलिमेंट के हिसाब से पूर्णांकन, सबसे नज़दीकी सम के बराबर होता है.
Rsqrt(operand)
एलिमेंट के हिसाब से वर्गमूल के ऑपरेशन का रिसिप्रोकल
x -> 1.0 / sqrt(x)
.
Sign(operand)
एलिमेंट के हिसाब से साइन ऑपरेशन x -> sgn(x)
, जहां
\[\text{sgn}(x) = \begin{cases} -1 & x < 0\\ -0 & x = -0\\ NaN & x = NaN\\ +0 & x = +0\\ 1 & x > 0 \end{cases}\]
operand
एलिमेंट टाइप के तुलना ऑपरेटर का इस्तेमाल करके.
Sin(operand)
एलिमेंट के हिसाब से साइन x -> sin(x)
.
Sqrt(operand)
एलिमेंट के हिसाब से स्क्वेयर रूट ऑपरेशन x -> sqrt(x)
.
Tan(operand)
एलिमेंट के हिसाब से टेंगेंट x -> tan(x)
.
Tanh(operand)
एलिमेंट के हिसाब से हाइपरबोलिक टैंजेंट x -> tanh(x)
.
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
फ़ंक्शन के लिए ऑपरेंड |
फ़ंक्शन को operand
कलेक्शन में मौजूद हर एलिमेंट पर लागू किया जाता है. इससे एक अरे बन जाता है, जिसका आकार एक जैसा हो जाता है. operand
के लिए एक अदिश (रैंक 0) होना आवश्यक है.
एफ़एफ़टी
XLA FFT ऑपरेशन, रीयल और कॉम्प्लेक्स इनपुट/आउटपुट के लिए, फ़ोरवर्ड और इनवर्स फ़ुरिअर ट्रांसफ़ॉर्म लागू करता है. ज़्यादा से ज़्यादा तीन ऐक्सिस पर मल्टीडाइमेंशनल एफ़एफ़टी का इस्तेमाल किया जा सकता है.
XlaBuilder::Fft
भी देखें.
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
वह सरणी हम फूरिये बदल रहे हैं. |
fft_type |
FftType |
नीचे दी गई टेबल देखें. |
fft_length |
ArraySlice<int64> |
ट्रांसफ़ॉर्म किए जा रहे ऐक्सिस की टाइम-डोमेन लंबाई. यह खास तौर पर, IRFFT के लिए ज़रूरी है, ताकि सबसे अंदर मौजूद ऐक्सिस का साइज़ सही हो. इसकी वजह यह है कि RFFT(fft_length=[16]) का आउटपुट शेप, RFFT(fft_length=[17]) जैसा ही होता है. |
FftType |
सिमैंटिक्स |
---|---|
FFT |
फ़ॉरवर्ड कॉम्प्लेक्स-टू-कॉम्प्लेक्स एफ़टीटी. आकार में कोई बदलाव नहीं होता. |
IFFT |
इनवर्स कॉम्प्लेक्स से कॉम्प्लेक्स एफ़एफ़टी. आकार में कोई बदलाव नहीं होता. |
RFFT |
असल से मुश्किल एफ़एफ़टी फ़ॉरवर्ड करें. अगर fft_length[-1] एक शून्य वैल्यू है, तो सबसे अंदरूनी ऐक्सिस का आकार fft_length[-1] // 2 + 1 तक कम कर दिया जाता है. ऐसा करने से, बदले गए सिग्नल के रिवर्स कॉन्जुगेट वाले हिस्से को Nyquist फ़्रीक्वेंसी से बाहर कर दिया जाता है. |
IRFFT |
इनवर्स रीयल-टू-कॉम्प्लेक्स FFT (यानी जटिल लेता, वास्तविक लौटाता है). अगर fft_length[-1] की वैल्यू शून्य से ज़्यादा है, तो सबसे अंदर मौजूद ऐक्सिस का शेप fft_length[-1] तक बड़ा हो जाता है. इससे, 1 से fft_length[-1] // 2 + 1 एंट्री के रिवर्स कॉंजुगेट से, ट्रांसफ़ॉर्म किए गए सिग्नल के हिस्से को न्योक्विस्ट फ़्रीक्वेंसी से परे अनुमानित किया जाता है. |
मल्टीडाइमेंशनल एफ़एफ़टी
एक से ज़्यादा fft_length
देने पर, यह सबसे अंदरूनी अक्षों में से हर एक पर, एफ़एफ़टी ऑपरेशन का कैस्केड लागू करने के बराबर होता है. ध्यान दें कि रीयल->कॉम्प्लेक्स और कॉम्प्लेक्स->रीयल मामलों के लिए, सबसे अंदरूनी ऐक्सिस ट्रांसफ़ॉर्मेशन (असल में) सबसे पहले किया जाता है (RFFT; IRFFT के लिए आखिर में). यही वजह है कि सबसे अंदरूनी ऐक्सिस का साइज़ बदलता है. इसके बाद, अन्य ऐक्सिस ट्रांसफ़ॉर्म, complex->complex होंगे.
क्रियान्वयन विवरण
CPU FFT, Eigen's TensorFFT पर आधारित है. जीपीयू FFT, cuFFT का इस्तेमाल करता है.
इकट्ठा करना
XLA इकट्ठा करने की प्रोसेस, इनपुट ऐरे के कई स्लाइस (हर स्लाइस, संभावित रूप से अलग रनटाइम ऑफ़सेट पर) को एक साथ जोड़ती है.
जनरल सिमैंटिक्स
XlaBuilder::Gather
भी देखें.
ज़्यादा आसान जानकारी के लिए, नीचे दिया गया "अनौपचारिक ब्यौरा" सेक्शन देखें.
gather(operand, start_indices, offset_dims, collapsed_slice_dims, slice_sizes, start_index_map)
तर्क | टाइप | सिमैंटिक |
---|---|---|
operand |
XlaOp |
जिस कलेक्शन से हम जानकारी इकट्ठा कर रहे हैं. |
start_indices |
XlaOp |
वह कलेक्शन जिसमें हम इकट्ठा किए गए स्लाइस के शुरुआती इंडेक्स शामिल हैं. |
index_vector_dim |
int64 |
start_indices में मौजूद वह डाइमेंशन जिसमें शुरुआती इंडेक्स "शामिल" हैं. ज़्यादा जानकारी के लिए नीचे देखें. |
offset_dims |
ArraySlice<int64> |
आउटपुट शेप में डाइमेंशन का सेट, जो ऑपरेंड से काटे गए ऐरे में ऑफ़सेट होता है. |
slice_sizes |
ArraySlice<int64> |
slice_sizes[i] , डाइमेंशन i पर स्लाइस के लिए बाउंड है. |
collapsed_slice_dims |
ArraySlice<int64> |
हर स्लाइस में मौजूद डाइमेंशन का सेट, जिसे छोटा कर दिया गया है. इन डाइमेंशन का साइज़ 1 होना ज़रूरी है. |
start_index_map |
ArraySlice<int64> |
ऐसा मैप जो start_indices में इंडेक्स को कानूनी इंडेक्स में ऑपरेंड के तौर पर मैप करने के तरीके की जानकारी देता है. |
indices_are_sorted |
bool |
क्या इंडेक्स को कॉलर के हिसाब से क्रम में लगाने की गारंटी है. |
आपकी सुविधा के लिए, हम आउटपुट ऐरे में डाइमेंशन को offset_dims
के बजाय batch_dims
के तौर पर लेबल करते हैं.
आउटपुट, रैंक batch_dims.size
+ offset_dims.size
का ऐरे होता है.
operand.rank
, offset_dims.size
और
collapsed_slice_dims.size
के योग के बराबर होना चाहिए. slice_sizes.size
, operand.rank
के बराबर होना चाहिए.
अगर index_vector_dim
, start_indices.rank
के बराबर है, तो हम start_indices
में आखिर में 1
डाइमेंशन होने का अनुमान लगाते हैं. इसका मतलब है कि अगर start_indices
का आकार [6,7]
है और index_vector_dim
2
है, तो हम start_indices
का आकार [6,7,1]
मानते हैं.
डाइमेंशन i
के साथ आउटपुट कलेक्शन के सीमाओं का हिसाब इस तरह लगाया जाता है:
अगर
i
batch_dims
में मौजूद है (यानी कुछk
के लिएbatch_dims[k]
के बराबर है), तो हमstart_indices.shape
में से बाउंड का इस्तेमाल कर सकते हैं. हालांकि,index_vector_dim
को छोड़ देंगे. अगरk
<index_vector_dim
है, तोstart_indices.shape.dims
[k
] है या अलग सेstart_indices.shape.dims
[k
+1
] है).अगर
i
,offset_dims
में मौजूद है (यानी कुछk
के लिएoffset_dims
[k
] के बराबर है), तो हमcollapsed_slice_dims
को ध्यान में रखते हुए,slice_sizes
से उससे जुड़ा बाउंड चुनते हैं. इसका मतलब है कि हमadjusted_slice_sizes
[k
] चुनते हैं, जहांadjusted_slice_sizes
,slice_sizes
है और इंडेक्सcollapsed_slice_dims
के बाउंड हटा दिए गए हैं.
औपचारिक रूप से, किसी दिए गए आउटपुट इंडेक्स Out
से जुड़े ऑपरेंड इंडेक्स In
की गिनती इस तरह से की जाती है:
मान लें कि
G
= {Out
[k
] fork
inbatch_dims
}.G
का इस्तेमाल करके, वैक्टरS
को इस तरह काटें किS
[i
] =start_indices
[Combine(G
,i
)] हो. यहां Combine(A, b), A मेंindex_vector_dim
पोज़िशन पर b डालता है. ध्यान दें किG
के खाली होने पर भी, यह अच्छी तरह से तय किया गया है: अगरG
खाली है, तोS
=start_indices
.start_index_map
की मदद सेS
को अलग-अलग करके,S
का इस्तेमाल करकेoperand
मेंS
in
का शुरुआती इंडेक्स बनाएं. ज़्यादा सटीक रूप से:S
in
[start_index_map
[k
]] =S
[k
], अगरk
<start_index_map.size
.S
in
[_
] =0
नहीं तो.
collapsed_slice_dims
सेट के हिसाब से,Out
में ऑफ़सेट डाइमेंशन के इंडेक्स को स्कैटर करके,operand
मेंO
in
इंडेक्स बनाएं. ज़्यादा सटीक रूप से:अगर
k
<offset_dims.size
है, तोO
in
[remapped_offset_dims
(k
)] =Out
[offset_dims
[k
]] (remapped_offset_dims
की जानकारी नीचे दी गई है).O
in
[_
] =0
नहीं तो.
In
,O
in
+S
in
है, जहां एलिमेंट के हिसाब से + का मतलब है.
remapped_offset_dims
एक मोनोटोनिक फ़ंक्शन है, जिसमें डोमेन [0
,
offset_dims.size
) और रेंज [0
, operand.rank
) \ collapsed_slice_dims
शामिल है. उदाहरण के लिए, अगर offset_dims.size
, 4
है, operand.rank
, 6
है, और
collapsed_slice_dims
, {0
, 2
} है, तो remapped_offset_dims
, {0
→1
,
1
→3
, 2
→4
, 3
→5
} है.
अगर indices_are_sorted
को 'सही' पर सेट किया गया है, तो XLA यह मान सकता है कि उपयोगकर्ता ने start_indices
को क्रम से लगाया है. start_indices
को क्रम से लगाने के लिए, start_index_map
के हिसाब से वैल्यू को अलग-अलग करके, इसके बाद उन्हें बढ़ते क्रम में लगाया जाता है. अगर ऐसा नहीं है, तो सेमेटिक्स को लागू करने के तरीके से तय किया जाता है.
सामान्य जानकारी और उदाहरण
अनौपचारिक रूप से, आउटपुट अरे में मौजूद हर इंडेक्स Out
, ऑपरेंड कैटगरी में मौजूद एक एलिमेंट E
से मेल खाता है. इसकी गिनती इस तरह की जाती है:
हम
start_indices
से शुरुआती इंडेक्स खोजने के लिए,Out
में बैच डाइमेंशन का इस्तेमाल करते हैं.हम
start_index_map
का इस्तेमाल करके, शुरुआती इंडेक्स (जिसका साइज़, ऑपरेंड के रैंक से कम हो सकता है) कोoperand
में "पूरे" शुरुआती इंडेक्स में मैप करते हैं.हम शुरुआती इंडेक्स का इस्तेमाल करके,
slice_sizes
साइज़ का स्लाइस डाइनैमिक तौर पर काटते हैं.हम
collapsed_slice_dims
डाइमेंशन को छोटा करके, स्लाइस का आकार बदलते हैं. सभी छोटा किए गए स्लाइस डाइमेंशन का बाउंड 1 होना चाहिए. इसलिए, यह रीशेप हमेशा मान्य होता है.हम इस स्लाइस में इंडेक्स करने के लिए,
Out
में मौजूद ऑफ़सेट डाइमेंशन का इस्तेमाल करते हैं. इससे हमें आउटपुट इंडेक्सOut
से जुड़ा इनपुट एलिमेंटE
मिलता है.
यहां दिए गए सभी उदाहरणों में, index_vector_dim
को start_indices.rank
- 1
पर सेट किया गया है. index_vector_dim
के लिए ज़्यादा दिलचस्प वैल्यू, ऑपरेशन को बुनियादी तौर पर नहीं बदलतीं, बल्कि विज़ुअल तरीके को ज़्यादा मुश्किल बनाती हैं.
ऊपर बताई गई सभी चीज़ें एक साथ कैसे काम करती हैं, यह समझने के लिए एक उदाहरण देखें. इसमें, [16,11]
कलेक्शन से [8,6]
आकार के पांच स्लाइस इकट्ठा किए गए हैं. [16,11]
कलेक्शन में स्लाइस की पोज़िशन को S64[2]
के आकार वाले इंडेक्स वेक्टर के तौर पर दिखाया जा सकता है. इसलिए, पांच स्थितियों के सेट को S64[5,2]
कलेक्शन के तौर पर दिखाया जा सकता है.
इसके बाद, इकट्ठा करने की कार्रवाई के व्यवहार को इंडेक्स ट्रांसफ़ॉर्मेशन के तौर पर दिखाया जा सकता है. यह [G
,O
0
,O
1
] को आउटपुट शेप में इंडेक्स के तौर पर लेता है और इसे इनपुट कलेक्शन के एलिमेंट पर इस तरह मैप करता है:
हम सबसे पहले G
का इस्तेमाल करके, इकट्ठा किए गए इंडेक्स के कलेक्शन से एक (X
,Y
) वेक्टर चुनते हैं.
आउटपुट ऐरे में इंडेक्स [G
,O
0
,O
1
] पर मौजूद एलिमेंट, इनपुट ऐरे में इंडेक्स [X
+O
0
,Y
+O
1
] पर मौजूद एलिमेंट होता है.
slice_sizes
, [8,6]
है. इससे O0
और
O1
की रेंज तय होती है. साथ ही, इससे स्लाइस के बाउंड तय होते हैं.
यह इकट्ठा करने की कार्रवाई एक बैच डाइनैमिक स्लाइस के तौर पर काम करती है, जिसमें G
बैच डाइमेंशन के तौर पर काम करता है.
इकट्ठा किए गए इंडेक्स, कई डाइमेंशन वाले हो सकते हैं. उदाहरण के लिए, ऊपर दिए गए उदाहरण का ज़्यादा सामान्य वर्शन, [4,5,2]
आकार के "इकट्ठा इंडेक्स" कलेक्शन का इस्तेमाल करके, इंडेक्स को इस तरह से ट्रांसलेट करेगा:
यह फिर से बैच डाइमेंशन के तौर पर, बैच डाइनैमिक स्लाइस G
0
और
G
1
के तौर पर काम करता है. स्लाइस का साइज़ अब भी [8,6]
है.
XLA में डेटा इकट्ठा करने की प्रक्रिया में, ऊपर बताए गए अनौपचारिक सिमेंटिक्स को इन तरीकों से सामान्य बनाया गया है:
हम कॉन्फ़िगर कर सकते हैं कि आउटपुट आकार में कौनसे डाइमेंशन, ऑफ़सेट डाइमेंशन हैं. (आखिरी उदाहरण में, वे डाइमेंशन
O
0
,O
1
हैं). आउटपुट बैच डाइमेंशन (पिछले उदाहरण मेंG
0
,G
1
वाले डाइमेंशन), ऐसे आउटपुट डाइमेंशन होते हैं जो ऑफ़सेट डाइमेंशन नहीं होते.आउटपुट आकार में साफ़ तौर पर मौजूद आउटपुट ऑफ़सेट डाइमेंशन की संख्या, इनपुट रैंक से कम हो सकती है. इन "मिसिंग" डाइमेंशन का साइज़
1
होना चाहिए. इन्हेंcollapsed_slice_dims
के तौर पर साफ़ तौर पर सूची में शामिल किया गया है. इनका स्लाइस साइज़1
है. इसलिए, इनके लिए सिर्फ़0
इंडेक्स मान्य है. साथ ही, इन्हें हटाने से कोई समस्या नहीं होती."सूची इकट्ठा करें" श्रेणी (पिछले उदाहरण में (
X
,Y
)) से निकाले गए स्लाइस में, इनपुट अरे की रैंक से कम एलिमेंट हो सकते हैं. साथ ही, साफ़ तौर पर मैप करने से यह तय होता है कि इंडेक्स को, इनपुट से मिलती-जुलती रैंक कैसे करना चाहिए.
आखिरी उदाहरण के तौर पर, हम tf.gather_nd
को लागू करने के लिए (2) और (3) का इस्तेमाल करते हैं:
G
0
और G
1
का इस्तेमाल, इंडेक्स इकट्ठा करने वाले कलेक्शन से, स्टार्टिंग इंडेक्स को अलग करने के लिए किया जाता है. हालांकि, स्टार्टिंग इंडेक्स में सिर्फ़ एक एलिमेंट, X
होता है. इसी तरह, O
0
वैल्यू वाला सिर्फ़ एक आउटपुट ऑफ़सेट इंडेक्स है. हालांकि, इनपुट कलेक्शन में इंडेक्स के तौर पर इस्तेमाल किए जाने से पहले, इन्हें "इकट्ठा करने के लिए इंडेक्स मैपिंग" (औपचारिक ब्यौरे में start_index_map
) और "ऑफ़सेट मैपिंग" (औपचारिक ब्यौरे में remapped_offset_dims
) के हिसाब से [X
,0
] और [0
,O
0
] में बड़ा किया जाता है. इन दोनों को जोड़ने पर [X
,O
0
] बनता है. दूसरे शब्दों में, आउटपुट इंडेक्स [G
0
,G
1
,O
0
] को इनपुट इंडेक्स [GatherIndices
[G
0
,G
1
,0
],O
0
] पर मैप किया जाता है. इससे हमें tf.gather_nd
के लिए सेमेटिक्स मिलते हैं.
इस केस के लिए slice_sizes
, [1,11]
है. इसका मतलब है कि इकट्ठा किए गए इंडेक्स कलेक्शन में मौजूद हर इंडेक्स X
, एक पूरी लाइन चुनता है. साथ ही, इन सभी लाइनों को जोड़कर नतीजा मिलता है.
GetDimensionSize
XlaBuilder::GetDimensionSize
भी देखें.
ऑपरेंड के दिए गए डाइमेंशन का साइज़ दिखाता है. ऑपरेंड अरे के आकार में होना चाहिए.
GetDimensionSize(operand, dimension)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
n डाइमेंशन वाला इनपुट ऐरे |
dimension |
int64 |
इंटरवल [0, n) में मौजूद एक वैल्यू, जो डाइमेंशन को तय करती है |
SetDimensionSize
XlaBuilder::SetDimensionSize
भी देखें.
XlaOp के दिए गए डाइमेंशन का डाइनैमिक साइज़ सेट करता है. ऑपरेंड, ऐरे के तौर पर होना चाहिए.
SetDimensionSize(operand, size, dimension)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
n डाइमेंशन वाला इनपुट ऐरे. |
size |
XlaOp |
रनटाइम के डाइनैमिक साइज़ को दिखाने वाला int32. |
dimension |
int64 |
इंटरवल [0, n) में मौजूद एक वैल्यू, जो डाइमेंशन के बारे में बताती है. |
ऑपरेंड को नतीजे के तौर पर पास करें. साथ ही, डाइनैमिक डाइमेंशन को कंपाइलर से ट्रैक करें.
पैड किए गए वैल्यू को डाउनस्ट्रीम रिडक्शन ऑपरेशन के ज़रिए अनदेखा कर दिया जाएगा.
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
XlaBuilder::GetTupleElement
भी देखें.
कंपाइल के समय की कॉन्स्टेंट वैल्यू वाले ट्यूपल में इंडेक्स करता है.
वैल्यू, कंपाइल के समय की कॉन्स्टेंट होनी चाहिए, ताकि आकार का अनुमान लगाने की सुविधा, नतीजे की वैल्यू का टाइप तय कर सके.
यह C++ में मौजूद std::get<int N>(t)
के जैसा है. सैद्धांतिक तौर पर:
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.
tf.tuple
भी देखें.
Infeed
XlaBuilder::Infeed
भी देखें.
Infeed(shape)
आर्ग्यूमेंट | टाइप | सिमैंटिक्स |
---|---|---|
shape |
Shape |
इनफ़ीड इंटरफ़ेस से पढ़े गए डेटा का टाइप. आकृति का लेआउट फ़ील्ड इस तरह सेट होना चाहिए कि वह डिवाइस को भेजे गए डेटा के लेआउट से मिलता-जुलता हो; ऐसा न होने पर, इसके व्यवहार के बारे में जानकारी नहीं मिलती. |
डिवाइस के इनफ़ीड स्ट्रीमिंग इंटरफ़ेस से एक डेटा आइटम पढ़ता है. साथ ही, डेटा को दिए गए शेप और उसके लेआउट के तौर पर समझता है और डेटा का XlaOp
दिखाता है. कैलकुलेशन में एक से ज़्यादा इनफ़ीड ऑपरेशन की अनुमति है. हालांकि, इनफ़ीड ऑपरेशन के बीच एक क्रम होना चाहिए. उदाहरण के लिए, नीचे दिए गए कोड में दो इनफ़ीड का कुल क्रम है, क्योंकि while लूप के बीच एक-दूसरे पर निर्भरता है.
result1 = while (condition, init = init_value) {
Infeed(shape)
}
result2 = while (condition, init = result1) {
Infeed(shape)
}
नेस्ट किए गए ट्यूपल शेप का इस्तेमाल नहीं किया जा सकता. खाली ट्यूपल शेप के लिए, इनफ़ीड ऑपरेशन का कोई असर नहीं होता. साथ ही, यह डिवाइस के इनफ़ीड से कोई डेटा पढ़े बिना आगे बढ़ता है.
आयोटा
XlaBuilder::Iota
भी देखें.
Iota(shape, iota_dimension)
होस्ट से बड़े डेटा ट्रांसफ़र के बजाय, डिवाइस पर एक कॉन्स्टेंट लिटरल बनाता है. ऐसा अरे बनाता है, जिसमें तय किया गया आकार होता है और उसमें वैल्यू होती हैं. ये वैल्यू, शून्य से शुरू होती हैं और तय डाइमेंशन में एक-एक करके बढ़ती हैं. फ़्लोटिंग-पॉइंट टाइप के लिए, जनरेट किया गया कलेक्शन ConvertElementType(Iota(...))
के बराबर होता है, जहां Iota
इंटिग्रल टाइप का होता है और कन्वर्ज़न, फ़्लोटिंग-पॉइंट टाइप में होता है.
तर्क | टाइप | सिमैंटिक |
---|---|---|
shape |
Shape |
Iota() ने जो ऐरे बनाया है उसका शेप |
iota_dimension |
int64 |
वह डाइमेंशन जिसे बढ़ाना है. |
उदाहरण के लिए, Iota(s32[4, 8], 0)
से
[[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)
का शुल्क देकर, प्रॉडक्ट को लौटाया जा सकता है
[[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 ]]
मैप
XlaBuilder::Map
भी देखें.
Map(operands..., computation)
तर्क | टाइप | सिमैंटिक |
---|---|---|
operands |
N XlaOp s का क्रम |
T0..T{N-1} टाइप की N कैटगरी |
computation |
XlaComputation |
टाइप T के N पैरामीटर और किसी भी टाइप के M पैरामीटर के साथ T_0, T_1, .., T_{N + M -1} -> S टाइप का हिसाब लगाना |
dimensions |
int64 ऐरे |
मैप डाइमेंशन का कलेक्शन |
यह दिए गए operands
ऐरे पर स्केलर फ़ंक्शन लागू करता है. इससे, एक ही डाइमेंशन वाला ऐरे बनता है, जहां हर एलिमेंट, इनपुट ऐरे के एलिमेंट पर लागू किए गए मैप किए गए फ़ंक्शन का नतीजा होता है.
मैप किया गया फ़ंक्शन, एक ऐसा कैलकुलेशन है जिसमें स्केलर टाइप T
के N इनपुट और टाइप S
का एक आउटपुट होता है. आउटपुट में ऑपरेंड के जैसे ही डाइमेंशन होते हैं. हालांकि, एलिमेंट टाइप T को S से बदल दिया जाता है.
उदाहरण के लिए: Map(op1, op2, op3, computation, par1)
, आउटपुट ऐरे बनाने के लिए, इनपुट ऐरे में हर (मल्टी-डाइमेंशनल) इंडेक्स पर elem_out <-
computation(elem1, elem2, elem3, par1)
को मैप करता है.
OptimizationBarrier
यह किसी भी ऑप्टिमाइज़ेशन पास को, पूरी रुकावट के बीच कंप्यूटेशन (कंप्यूटेशन) को चलाने से रोकता है.
यह पक्का करता है कि बाधा के आउटपुट पर निर्भर किसी भी ऑपरेटर से पहले, सभी इनपुट का आकलन किया जाए.
पैड
XlaBuilder::Pad
भी देखें.
Pad(operand, padding_value, padding_config)
तर्क | टाइप | सिमैंटिक |
---|---|---|
operand |
XlaOp |
T टाइप का कलेक्शन |
padding_value |
XlaOp |
जोड़ा गया पैडिंग भरने के लिए, T टाइप का स्केलर |
padding_config |
PaddingConfig |
दोनों किनारों (कम, ज़्यादा) और हर डाइमेंशन के एलिमेंट के बीच पैडिंग (जगह) की मात्रा |
दिए गए operand
ऐरे को बड़ा करता है. इसके लिए, ऐरे के आस-पास और ऐरे के एलिमेंट के बीच, दिए गए padding_value
के साथ पैडिंग जोड़ता है. padding_config
हर डाइमेंशन के लिए, एज पैडिंग (जगह) और अंदरूनी पैडिंग की जानकारी देता है.
PaddingConfig
, PaddingConfigDimension
का दोहराया गया फ़ील्ड है. इसमें हर डाइमेंशन के लिए तीन फ़ील्ड होते हैं: edge_padding_low
, edge_padding_high
, और
interior_padding
.
edge_padding_low
और edge_padding_high
, हर डाइमेंशन के लो-एंड (इंडेक्स 0 के बगल में) और हाई-एंड (सबसे ज़्यादा इंडेक्स के बगल में) पर जोड़ी गई पैडिंग की मात्रा के बारे में बताते हैं. एज पैडिंग की मात्रा नेगेटिव हो सकती है --
नेगेटिव पैडिंग की पूरी वैल्यू, तय किए गए डाइमेंशन से हटाए जाने वाले एलिमेंट की संख्या बताती है.
interior_padding
से पता चलता है कि हर डाइमेंशन में, किसी भी दो एलिमेंट के बीच कितनी पैडिंग जोड़ी गई है. यह वैल्यू नेगेटिव नहीं हो सकती. अंदरूनी पैडिंग, एज पैडिंग से पहले होती है. इसलिए, नेगेटिव एज पैडिंग के मामले में, अंदरूनी पैडिंग वाले ऑपरेंड से एलिमेंट हटा दिए जाते हैं.
अगर किनारे के पैडिंग पेयर सभी (0, 0) हैं और अंदरूनी पैडिंग की वैल्यू सभी 0 हैं, तो यह कार्रवाई नहीं की जाती. यहां दिए गए डायग्राम में दो डाइमेंशन वाले कलेक्शन के लिए, edge_padding
और interior_padding
की अलग-अलग वैल्यू के उदाहरण दिए गए हैं.
Recv
XlaBuilder::Recv
भी देखें.
Recv(shape, channel_handle)
तर्क | टाइप | सिमैंटिक |
---|---|---|
shape |
Shape |
पाने के लिए डेटा का टाइप |
channel_handle |
ChannelHandle |
हर भेजने/पाने वाले पेयर के लिए यूनीक आइडेंटिफ़ायर |
दिए गए आकार का डेटा, उसी चैनल का हैंडल इस्तेमाल करने वाले किसी दूसरे कंप्यूटेशन में Send
निर्देश से लेता है. जो डेटा मिला है उसके लिए XlaOp दिखाता है.
Recv
ऑपरेशन का क्लाइंट एपीआई, सिंक्रोनस कम्यूनिकेशन दिखाता है.
हालांकि, असाइनमेंट को अंदरूनी तौर पर दो एचएलओ निर्देशों (Recv
और RecvDone
) में बांटा जाता है, ताकि डेटा को अलग-अलग समय पर ट्रांसफ़र किया जा सके. HloInstruction::CreateRecv
और HloInstruction::CreateRecvDone
भी देखें.
Recv(const Shape& shape, int64 channel_id)
एक ही channel_id वाले Send
निर्देश से डेटा पाने के लिए ज़रूरी संसाधनों को ऐलोकेट करता है. यह, ऐलोकेट किए गए रिसॉर्स के लिए एक कॉन्टेक्स्ट दिखाता है. इसका इस्तेमाल, डेटा ट्रांसफ़र पूरा होने का इंतज़ार करने के लिए, RecvDone
निर्देश के बाद किया जाता है. कॉन्टेक्स्ट, {receive buffer (shape), request identifier
(U32)} का ट्यूपल है. इसका इस्तेमाल सिर्फ़ RecvDone
निर्देश से किया जा सकता है.
RecvDone(HloInstruction context)
Recv
निर्देश से बनाए गए संदर्भ में, डेटा ट्रांसफ़र के पूरा होने का इंतज़ार करता है और मिला डेटा दिखाता है.
Reduce
XlaBuilder::Reduce
भी देखें.
एक या उससे ज़्यादा ऐरे पर, रिडक्शन फ़ंक्शन को एक साथ लागू करता है.
Reduce(operands..., init_values..., computation, dimensions)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operands |
N XlaOp का क्रम |
T_0, ..., T_{N-1} टाइप के N ऐरे. |
init_values |
N XlaOp का क्रम |
T_0, ..., T_{N-1} टाइप के N स्केलर. |
computation |
XlaComputation |
T_0, ..., T_{N-1}, T_0, ..., T_{N-1} -> Collate(T_0, ..., T_{N-1}) टाइप का कैलकुलेशन. |
dimensions |
int64 ऐरे |
कम किए जाने वाले डाइमेंशन का बिना क्रम वाला कलेक्शन. |
कहां:
- N, 1 से बड़ा या उसके बराबर होना चाहिए.
- कैलकुलेशन "लगभग" असोसिएटिव होना चाहिए (नीचे देखें).
- सभी इनपुट ऐरे के डाइमेंशन एक ही होने चाहिए.
- सभी शुरुआती वैल्यू को,
computation
में एक पहचान बनानी चाहिए. - अगर
N = 1
,Collate(T)
T
है. - अगर
N > 1
,Collate(T_0, ..., T_{N-1})
,T
टाइप केN
एलिमेंट का ट्यूपल है.
इस ऑपरेशन से, हर इनपुट ऐरे के एक या एक से ज़्यादा डाइमेंशन, स्केलर में बदल जाते हैं.
दिखाए गए हर ऐरे की रैंक rank(operand) - len(dimensions)
होती है. ऑप का आउटपुट Collate(Q_0, ..., Q_N)
है, जहां Q_i
T_i
टाइप का अरे है, जिसके डाइमेंशन के बारे में नीचे बताया गया है.
अलग-अलग बैकएंड, डेटा कम करने के तरीके को फिर से जोड़ सकते हैं. इससे अंकों में अंतर हो सकता है, क्योंकि जोड़ने जैसे कुछ रिडक्शन फ़ंक्शन फ़्लोट के लिए एक साथ नहीं आते हैं. हालांकि, अगर डेटा की रेंज सीमित है, तो ज़्यादातर काम के लिए, फ़्लोटिंग-पॉइंट जोड़ने की सुविधा, असोसिएटिव के बराबर ही होती है.
उदाहरण
[10, 11,
12, 13]
वैल्यू वाले एक 1D ऐरे में, एक डाइमेंशन में घटाने पर, f
(यह computation
है) फ़ंक्शन का इस्तेमाल किया जाता है. इसका हिसाब इस तरह से लगाया जा सकता है
f(10, f(11, f(12, f(init_value, 13)))
हालांकि, इसके अलावा और भी कई संभावनाएं हैं, जैसे कि
f(init_value, f(f(10, f(init_value, 11)), f(f(init_value, 12), f(init_value, 13))))
यहां एक उदाहरण के तौर पर, घटाने की सुविधा को लागू करने का तरीका बताया गया है. इसमें शुरुआती वैल्यू 0 के साथ, घटाने की गिनती के तौर पर जोड़ का इस्तेमाल किया गया है.
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]
यहां 2D अरे (मैट्रिक्स) को कम करने का एक उदाहरण दिया गया है. आकार में रैंक 2, साइज़ 2 का डाइमेंशन 0, और साइज़ 3 का डाइमेंशन 1 है:
"जोड़ें" फ़ंक्शन से डाइमेंशन 0 या 1 को घटाने के नतीजे:
ध्यान दें कि रिडक्शन के दोनों नतीजे 1D कैटगरी होते हैं. इस डायग्राम में एक कॉलम को कॉलम के तौर पर और दूसरी को सिर्फ़ विज़ुअल की सुविधा के लिए लाइन के तौर पर दिखाया गया है.
ज़्यादा मुश्किल उदाहरण के लिए, यहां एक 3D ऐरे दिया गया है. इसकी रैंक 3 है, साइज़ 4 का डाइमेंशन 0, साइज़ 2 का डाइमेंशन 1, और साइज़ 3 का डाइमेंशन 2 है. इसे आसानी से समझने के लिए, 1 से 6 तक की वैल्यू को डाइमेंशन 0 में दोहराया जाता है.
2D उदाहरण की तरह ही, हम सिर्फ़ एक डाइमेंशन कम कर सकते हैं. उदाहरण के लिए, अगर हम डाइमेंशन 0 को कम करते हैं, तो हमें रैंक-2 का कलेक्शन मिलता है, जिसमें डाइमेंशन 0 के सभी वैल्यू को अदिश में फ़ोल्ड किया जाता है:
| 4 8 12 |
| 16 20 24 |
अगर हम डाइमेंशन 2 को कम करते हैं, तो हमें रैंक-2 का एक ऐरे भी मिलता है, जहां डाइमेंशन 2 की सभी वैल्यू को स्केलर में फ़ोल्ड किया गया था:
| 6 15 |
| 6 15 |
| 6 15 |
| 6 15 |
ध्यान दें कि इनपुट में मौजूद बाकी डाइमेंशन के बीच का क्रम, आउटपुट में भी बना रहता है. हालांकि, कुछ डाइमेंशन को नई संख्याएं असाइन की जा सकती हैं, क्योंकि रैंक बदल जाती है.
हम एक से ज़्यादा डाइमेंशन भी कम कर सकते हैं. डाइमेंशन 0 और 1 को जोड़ने से, 1D ऐरे [20, 28, 36]
बनता है.
3D अरे को इसके सभी डाइमेंशन पर कम करने से, अदिश 84
जनरेट होती है.
वैरिडिक रिड्यूस
N > 1
के लिए, घटाने वाले फ़ंक्शन को लागू करना थोड़ा मुश्किल होता है, क्योंकि यह सभी इनपुट पर एक साथ लागू होता है. ऑपरेंड को कैलकुलेशन में इस क्रम में दिया जाता है:
- पहले ऑपरेंड के लिए कम की जा रही वैल्यू
- ...
- Nवें ऑपरेंड के लिए, कम की गई वैल्यू का इस्तेमाल किया जा रहा है
- पहले ऑपरेंड के लिए इनपुट वैल्यू
- ...
- Nवें ऑपरेंड के लिए इनपुट वैल्यू
उदाहरण के लिए, नीचे दिए गए रिडक्शन फ़ंक्शन पर ध्यान दें. इसका इस्तेमाल, साथ-साथ 1-D कलेक्शन के मैक्सिमम और ऑर्गमैक्स का पता लगाने के लिए किया जा सकता है:
f: (Float, Int, Float, Int) -> Float, Int
f(max, argmax, value, index):
if value >= max:
return (value, index)
else:
return (max, argmax)
1-D इनपुट अरे V = Float[N], K = Int[N]
और इनिट वैल्यू
I_V = Float, I_K = Int
के लिए, सिर्फ़ इनपुट डाइमेंशन में कम करने का f_(N-1)
नतीजा इन बार-बार होने वाले ऐप्लिकेशन के बराबर होता है:
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))
इस कमी को वैल्यू के कलेक्शन और क्रम में चलने वाले इंडेक्स (जैसे, iota) पर लागू करने पर, कई रेंज के साथ-साथ वैल्यू को फिर से दोहराया जाएगा. साथ ही, सबसे ज़्यादा वैल्यू और मैचिंग इंडेक्स वाला टपल दिखेगा.
ReducePrecision
XlaBuilder::ReducePrecision
भी देखें.
यह फ़ंक्शन, फ़्लोटिंग-पॉइंट वैल्यू को कम सटीक फ़ॉर्मैट (जैसे, IEEE-FP16) में बदलने और फिर उन्हें ओरिजनल फ़ॉर्मैट में बदलने के असर का मॉडल बनाता है. कम सटीक फ़ॉर्मैट में, एक्सपोनेंट और मैन्टिसा बिट की संख्या को मनमुताबिक तय किया जा सकता है. हालांकि, हो सकता है कि सभी बिट साइज़, सभी हार्डवेयर पर काम न करें.
ReducePrecision(operand, mantissa_bits, exponent_bits)
तर्क | टाइप | सिमैंटिक |
---|---|---|
operand |
XlaOp |
फ़्लोटिंग-पॉइंट टाइप T का ऐरे. |
exponent_bits |
int32 |
कम सटीक फ़ॉर्मैट में एक्सपोनेंट बिट की संख्या |
mantissa_bits |
int32 |
कम सटीक फ़ॉर्मैट में मैन्टिसा बिट की संख्या |
नतीजा, T
टाइप का ऐरे होता है. इनपुट वैल्यू को, दिए गए मैन्टिसा बिट की संख्या के साथ दिखाई जा सकने वाली सबसे नज़दीकी वैल्यू पर राउंड किया जाता है. इसके लिए, "सम संख्या पर बराबर करें" सेमेटिक्स का इस्तेमाल किया जाता है. साथ ही, एक्सपोनेंट बिट की संख्या से तय की गई रेंज से ज़्यादा की वैल्यू को, धनात्मक या ऋणात्मक अनंत पर क्लैंप किया जाता है. NaN
वैल्यू को बरकरार रखा जाता है. हालांकि, इन्हें कैननिकल NaN
वैल्यू में बदला जा सकता है.
कम सटीक फ़ॉर्मैट में कम से कम एक एक्सपोनेंट बिट होना चाहिए, ताकि शून्य वैल्यू को अनंत से अलग किया जा सके. ऐसा इसलिए है, क्योंकि दोनों में मैन्टिसा शून्य होता है. साथ ही, मैन्टिसा बिट की संख्या भी गैर-नेगेटिव होनी चाहिए. एक्सपोनेंट या मैनटिसा बिट की संख्या, टाइप T
के लिए उससे जुड़ी वैल्यू से ज़्यादा हो सकती है. ऐसे में, कन्वर्ज़न का उससे जुड़ा हिस्सा सिर्फ़ कोई काम नहीं करता.
ReduceScatter
XlaBuilder::ReduceScatter
भी देखें.
ReduceScatter एक ऐसा ग्रुप ऑपरेशन है जो असरदार तरीके से AllReduce करता है और फिर नतीजे को scatter_dimension
के साथ shard_count
ब्लॉक में बांटकर उसे स्कैटर करता है. साथ ही, रीप्लिक ग्रुप में रीप्लिक i
को ith
वाला शर्ड मिलता है.
ReduceScatter(operand, computation, scatter_dim, shard_count,
replica_group_ids, channel_id)
तर्क | टाइप | सिमैंटिक |
---|---|---|
operand |
XlaOp |
सभी रिप्लिकेट में कम करने के लिए, ऐरे या ऐरे का कोई ऐसा टुपल जो खाली न हो. |
computation |
XlaComputation |
कटौती का हिसाब लगाना |
scatter_dimension |
int64 |
स्कैटर करने के लिए डाइमेंशन. |
shard_count |
int64 |
ब्लॉक की संख्या scatter_dimension |
replica_groups |
int64 के वेक्टर का वेक्टर |
वे ग्रुप जिनके बीच की कमियां की जाती हैं |
channel_id |
ज़रूरी नहीं int64 |
अलग-अलग मॉड्यूल के बीच कम्यूनिकेशन के लिए वैकल्पिक चैनल आईडी |
- जब
operand
, अरे का ट्यूपल होता है, तो टपल के हर एलिमेंट पर रिड्यूस-स्कैटर किया जाता है. replica_groups
रेप्लिका ग्रुप की ऐसी सूची है जिसमें कमी की जाती है (मौजूदा प्रतिकृति के रेप्लिका आईडी कोReplicaId
का इस्तेमाल करके वापस लाया जा सकता है). हर ग्रुप में कॉपी के क्रम से वह क्रम तय होता है जिसमें सभी-घटाने वाले नतीजे स्कैटर हो जाएंगे.replica_groups
या तो खाली होना चाहिए (इस मामले में, सभी रेप्लिक एक ही ग्रुप से जुड़े होते हैं) या इसमें रेप्लिक की संख्या के बराबर एलिमेंट होने चाहिए. अगर एक से ज़्यादा डुप्लीकेट ग्रुप हैं, तो सभी ग्रुप का साइज़ एक जैसा होना चाहिए. उदाहरण के लिए,replica_groups = {0, 2}, {1, 3}
,0
और2
, और1
और3
के बीच डेटा को कम करता है. इसके बाद, वह नतीजे को अलग-अलग जगहों पर भेजता है.shard_count
, हर एक कॉपी ग्रुप का साइज़ है. हमें इसकी ज़रूरत तब होती है, जबreplica_groups
खाली हों. अगरreplica_groups
खाली नहीं है, तोshard_count
हर रेप्लिक ग्रुप के साइज़ के बराबर होना चाहिए.channel_id
का इस्तेमाल, अलग-अलग मॉड्यूल के बीच कम्यूनिकेशन के लिए किया जाता है: सिर्फ़ एक हीchannel_id
वालेreduce-scatter
ऑपरेशन, एक-दूसरे के साथ कम्यूनिकेट कर सकते हैं.
आउटपुट आकार, इनपुट आकार का scatter_dimension
गुना छोटा होता है. उदाहरण के लिए, अगर दो कॉपी हैं और ऑपरेटर की वैल्यू इन दो कॉपी पर क्रम से [1.0, 2.25]
और [3.0, 5.25]
है, तो इस सेशन का आउटपुट वैल्यू, जहां scatter_dim
0
है, वहां पहली कॉपी के लिए [4.0]
और दूसरी कॉपी के लिए [7.5]
होगा.
ReduceWindow
XlaBuilder::ReduceWindow
भी देखें.
N बहु-आयामी सरणियों के क्रम की हर विंडो में सभी एलिमेंट पर रिडक्शन फ़ंक्शन लागू करता है. इससे आउटपुट के तौर पर, N बहु-आयामी सरणियों का एक या टपल बनता है. हर आउटपुट कलेक्शन में उतने ही एलिमेंट होते हैं जितनी विंडो की मान्य पोज़िशन होती हैं. पूलिंग लेयर को ReduceWindow
के तौर पर दिखाया जा सकता है. Reduce
की तरह ही, लागू किया गया computation
हमेशा बाईं ओर मौजूद init_values
से पास किया जाता है.
ReduceWindow(operands..., init_values..., computation, window_dimensions,
window_strides, padding)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operands |
N XlaOps |
T_0,..., T_{N-1} टाइप की N बहु-डाइमेंशन वाली सरणियों का क्रम, जिनमें से हर उस बेस एरिया को दिखाती है जिस पर विंडो को रखा गया है. |
init_values |
N XlaOps |
घटाने के लिए N शुरुआती वैल्यू, N ऑपरेंड में से हर एक के लिए एक. ज़्यादा जानकारी के लिए, कम करें देखें. |
computation |
XlaComputation |
सभी इनपुट ऑपरेंड की हर विंडो के एलिमेंट पर लागू करने के लिए, T_0, ..., T_{N-1}, T_0, ..., T_{N-1} -> Collate(T_0, ..., T_{N-1}) टाइप का रिडक्शन फ़ंक्शन. |
window_dimensions |
ArraySlice<int64> |
विंडो डाइमेंशन की वैल्यू के लिए, पूर्णांकों का कलेक्शन |
window_strides |
ArraySlice<int64> |
विंडो स्ट्राइड वैल्यू के लिए पूर्णांकों का अरे |
base_dilations |
ArraySlice<int64> |
बेस डाइलेशन वैल्यू के लिए, पूर्णांकों का कलेक्शन |
window_dilations |
ArraySlice<int64> |
विंडो फैलाव की वैल्यू के लिए पूर्णांकों का कलेक्शन |
padding |
Padding |
विंडो के लिए पैडिंग टाइप (Padding::kSame, जो पैड करता है, ताकि स्ट्राइड 1 होने पर आउटपुट का आकार इनपुट जैसा हो या Padding::kValid, जो पैडिंग का इस्तेमाल नहीं करता और विंडो के फ़िट न होने पर उसे "बंद" कर देता है) |
कहां:
- N की वैल्यू 1 या उससे ज़्यादा होनी चाहिए.
- सभी इनपुट अरे के डाइमेंशन एक जैसे होने चाहिए.
- अगर
N = 1
,Collate(T)
है, तोT
है. - अगर
N > 1
है, तोCollate(T_0, ..., T_{N-1})
,(T0,...T{N-1})
टाइप केN
एलिमेंट का टपल है.
नीचे दिए गए कोड और फ़ोटो में, ReduceWindow
का इस्तेमाल करने का उदाहरण दिया गया है. इनपुट, [4x6] साइज़ का मैट्रिक्स है और window_dimensions और 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);
किसी डाइमेंशन में 1 चलने से यह पता चलता है कि डाइमेंशन में किसी विंडो की पोज़िशन, उसके पास वाली विंडो से 1 एलिमेंट की दूरी पर है. यह बताने के लिए कि कोई भी विंडो एक-दूसरे से ओवरलैप नहीं होती, window_stride_dimensions का वैल्यू, window_dimensions के बराबर होनी चाहिए. नीचे दिए गए इलस्ट्रेशन में, दो अलग-अलग स्ट्राइड वैल्यू के इस्तेमाल के बारे में बताया गया है. पैडिंग, इनपुट के हर डाइमेंशन पर लागू होती है. साथ ही, कैलकुलेशन वैसे ही होते हैं जैसे कि इनपुट, पैडिंग के बाद के डाइमेंशन के साथ आया हो.
नॉन-ट्रिवियल पैडिंग (जगह) के उदाहरण के लिए, डाइमेंशन 3
के साथ कम से कम विंडो की कम से कम वैल्यू (शुरुआती वैल्यू MAX_FLOAT
है) की गणना करें और इनपुट कलेक्शन [10000, 1000, 100, 10, 1]
पर 2
घुमाएं. पैडिंग kValid
, दो मान्य विंडो: [10000, 1000, 100]
और [100, 10, 1]
पर कम से कम वैल्यू का हिसाब लगाता है. इससे [100, 1]
का आउटपुट मिलता है. kSame
को पैडिंग करने पर, सबसे पहले अरे को पैड किया जाता है, ताकि रिड्यूस विंडो के बाद का आकार एक ही रहे इनपुट के जैसा ही रहे. ऐसा करने के लिए, दोनों ओर शुरुआती एलिमेंट जोड़ें और [MAX_VALUE, 10000, 1000, 100, 10, 1,
MAX_VALUE]
पाएं. पैड किए गए ऐरे पर reduce-window फ़ंक्शन चलाने पर, यह तीन विंडो [MAX_VALUE, 10000, 1000]
, [1000, 100, 10]
, [10, 1, MAX_VALUE]
पर काम करता है और [1000, 10, 1]
दिखाता है.
रिडक्शन फ़ंक्शन का आकलन करने का क्रम मनमुताबिक होता है और यह तय नहीं होता. इसलिए, रिडक्शन फ़ंक्शन को फिर से असोसिएट करने के लिए ज़्यादा संवेदनशील नहीं होना चाहिए. ज़्यादा जानकारी के लिए, Reduce
के संदर्भ में, असोसिएटिविटी के बारे में चर्चा देखें.
ReplicaId
XlaBuilder::ReplicaId
भी देखें.
नकल का यूनीक आईडी (U32 स्केलर) दिखाता है.
ReplicaId()
हर प्रतिकृति का यूनीक आईडी, [0, N)
इंटरवल में एक साइन नहीं किया गया पूर्णांक होता है,
जहां N
, प्रतिरूपों की संख्या होती है. सभी प्रतिकृति एक ही प्रोग्राम चला रही हैं, इसलिए प्रोग्राम में ReplicaId()
कॉल करने पर, हर प्रतिकृति पर एक अलग वैल्यू दिखेगी.
आकार बदलें
XlaBuilder::Reshape
और Collapse
ऑपरेशन भी देखें.
किसी ऐरे के डाइमेंशन को नए कॉन्फ़िगरेशन में बदलता है.
Reshape(operand, new_sizes)
Reshape(operand, dimensions, new_sizes)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
T टाइप का अरे |
dimensions |
int64 वेक्टर |
जिस क्रम में डाइमेंशन को छोटा किया जाता है |
new_sizes |
int64 वेक्टर |
नए डाइमेंशन के साइज़ का वेक्टर |
सैद्धांतिक तौर पर, पहले किसी अरे को डेटा वैल्यू के एक-डाइमेंशन वाले वेक्टर में फ़्लैट करता है और फिर इस वेक्टर को नए आकार में बदल देता है. इनपुट आर्ग्युमेंट, टाइप T का कोई भी ऐरे होता है. साथ ही, नतीजे के लिए डाइमेंशन इंडेक्स का कॉम्पाइल-टाइम-कॉन्स्टेंट वेक्टर और डाइमेंशन साइज़ का कॉम्पाइल-टाइम-कॉन्स्टेंट वेक्टर होता है.
अगर dimension
वेक्टर में वैल्यू दी गई हैं, तो वे सभी T डाइमेंशन के क्रम के हिसाब से होनी चाहिए. अगर वैल्यू नहीं दी गई है, तो डिफ़ॉल्ट तौर पर यह वैल्यू {0, ..., rank - 1}
होती है. dimensions
में डाइमेंशन का क्रम, लूप नेस्ट में सबसे धीरे बदलने वाले डाइमेंशन (सबसे ज़्यादा मेजर) से लेकर सबसे तेज़ी से बदलने वाले डाइमेंशन (सबसे ज़्यादा माइनर) तक होता है. यह क्रम, इनपुट कलेक्शन को एक डाइमेंशन में बदल देता है. new_sizes
वेक्टर, आउटपुट अरे का साइज़ तय करता है. new_sizes
में इंडेक्स 0 पर मौजूद वैल्यू, डाइमेंशन 0 का साइज़ है. इंडेक्स 1 पर मौजूद वैल्यू, डाइमेंशन 1 का साइज़ है, और इसी तरह आगे भी. new_size
डाइमेंशन का प्रॉडक्ट, ऑपरेंड के डाइमेंशन साइज़ के प्रॉडक्ट के बराबर होना चाहिए. जब new_sizes
से तय किए गए मल्टीडाइमेंशनल अरे में, छोटा किया गया अरे बेहतर बनाया जाता है, तो new_sizes
में डाइमेंशन को सबसे धीमे बदलाव (सबसे ज़्यादा मेजर) से लेकर सबसे तेज़ बदलाव (सबसे ज़्यादा माइनर) के हिसाब से क्रम में लगाया जाता है.
उदाहरण के लिए, मान लें कि v 24 एलिमेंट का ऐरे है:
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} } };
किसी खास मामले में, reshape फ़ंक्शन किसी एक एलिमेंट वाले ऐरे को स्केलर में बदल सकता है और स्केलर को ऐरे में बदल सकता है. उदाहरण के लिए,
Reshape(f32[1x1] { {5} }, {0,1}, {}) == 5;
Reshape(5, {}, {1,1}) == f32[1x1] { {5} };
Rev (रिवर्स)
XlaBuilder::Rev
भी देखें.
Rev(operand, dimensions)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
T टाइप का कलेक्शन |
dimensions |
ArraySlice<int64> |
रिवर्स करने के लिए डाइमेंशन |
यह फ़ंक्शन, operand
ऐरे में एलिमेंट के क्रम को, तय किए गए
dimensions
के हिसाब से उलट देता है. साथ ही, उसी आकार का आउटपुट ऐरे जनरेट करता है. मल्टीडाइमेंशनल इंडेक्स में ऑपरेंड कलेक्शन के हर एलिमेंट को, ट्रांसफ़ॉर्म किए गए इंडेक्स में आउटपुट कलेक्शन में स्टोर किया जाता है. कई डाइमेंशन वाले इंडेक्स को हर डाइमेंशन में मौजूद इंडेक्स को उलटा करके बदल दिया जाता है. इसका मतलब है कि अगर साइज़ N का डाइमेंशन, रिवर्सिंग डाइमेंशन में से एक है, तो इसका इंडेक्स i N - 1 - i में बदल जाता है.
Rev
ऑपरेशन का एक इस्तेमाल, नेटवर्क में ग्रेडिएंट कैलकुलेशन के दौरान, दो विंडो डाइमेंशन के साथ-साथ कॉन्वोल्यूशन वेट कलेक्शन को उलटने के लिए किया जाता है.
RngNormal
XlaBuilder::RngNormal
भी देखें.
\(N(\mu, \sigma)\) नॉर्मल डिस्ट्रिब्यूशन के हिसाब से जनरेट किए गए रैंडम नंबर की मदद से, किसी दिए गए आकार का आउटपुट बनाता है. पैरामीटर \(\mu\) और \(\sigma\)और आउटपुट आकार का फ़्लोटिंग पॉइंट एलिमेंट टाइप होना चाहिए. इसके अलावा, पैरामीटर की वैल्यू स्केलर होनी चाहिए.
RngNormal(mu, sigma, shape)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
mu |
XlaOp |
जनरेट की गई संख्याओं का औसत बताने वाला, T टाइप का स्केलर |
sigma |
XlaOp |
जनरेट किए गए डेटा के स्टैंडर्ड डीविएशन की जानकारी देने वाला, T टाइप का स्केलर |
shape |
Shape |
T प्रकार का आउटपुट आकार |
RngUniform
XlaBuilder::RngUniform
भी देखें.
किसी दिए गए आकार का आउटपुट बनाता है. इसके लिए, इंटरवल \([a,b)\)में यूनिफ़ॉर्म डिस्ट्रिब्यूशन के हिसाब से जनरेट किए गए रैंडम नंबर का इस्तेमाल किया जाता है. पैरामीटर और आउटपुट एलिमेंट का टाइप, बूलियन टाइप, इंटिग्रल टाइप या फ़्लोटिंग पॉइंट टाइप होना चाहिए. साथ ही, टाइप एक जैसे होने चाहिए. फ़िलहाल, सीपीयू और जीपीयू बैकएंड में सिर्फ़ F64, F32, F16, BF16, S64, U64, S32, और U32 का इस्तेमाल किया जा सकता है. इसके अलावा, पैरामीटर का अदिश मान डालना ज़रूरी है. अगर \(b <= a\) नतीजा, लागू करने के तरीके से तय होता है.
RngUniform(a, b, shape)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
a |
XlaOp |
T प्रकार का स्केलर, जिसमें अंतराल की निचली सीमा तय होती है |
b |
XlaOp |
इंटरवल की ऊपरी सीमा बताने वाला, T टाइप का स्केलर |
shape |
Shape |
T प्रकार का आउटपुट आकार |
RngBitGenerator
दिए गए एल्गोरिदम (या बैकएंड डिफ़ॉल्ट) का इस्तेमाल करके, दिए गए आकार के साथ एक आउटपुट जनरेट करता है और जनरेट किया गया रैंडम डेटा और अपडेट की गई स्थिति दिखाता है.
शुरुआती स्थिति, मौजूदा रैंडम नंबर जनरेशन की शुरुआती स्थिति होती है. यह और ज़रूरी आकार और मान्य वैल्यू, इस्तेमाल किए गए एल्गोरिदम पर निर्भर करती हैं.
यह पक्का है कि आउटपुट, शुरुआती स्थिति का डेटरमिनिस्टिक फ़ंक्शन होगा. हालांकि, यह नहीं पक्का है कि बैकएंड और कंपाइलर के अलग-अलग वर्शन के बीच आउटपुट डेटरमिनिस्टिक होगा.
RngBitGenerator(algorithm, key, shape)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
algorithm |
RandomAlgorithm |
इस्तेमाल किया जाने वाला पीआरएनजी एल्गोरिदम. |
initial_state |
XlaOp |
पीआरएनजी एल्गोरिदम की शुरुआती स्थिति. |
shape |
Shape |
जनरेट किए गए डेटा का आउटपुट शेप. |
algorithm
के लिए उपलब्ध वैल्यू:
rng_default
: बैकएंड के हिसाब से बने एल्गोरिदम, जिसमें बैकएंड के हिसाब से आकार की ज़रूरी शर्तें होती हैं.rng_three_fry
: ThreeFry काउंटर पर आधारित पीआरएनजी एल्गोरिदम.initial_state
केu64[2]
आकार में, मनमुताबिक वैल्यू दी गई हैं. Salmon et al. SC 2011. पैरलल रैंडम नंबर: 1, 2, 3 जितने आसान.rng_philox
: साथ-साथ रैंडम नंबर जनरेट करने के लिए Pilox एल्गोरिदम.initial_state
आकारu64[3]
है, जिसमें मनमुताबिक वैल्यू दी गई हैं. Salmon et al. SC 2011. पैरलल रैंडम नंबर: बेहद आसान.
स्कैटर
XLA स्कैटर ऑपरेशन, नतीजों का एक क्रम जनरेट करता है. ये नतीजे, इनपुट ऐरे operands
की वैल्यू होते हैं. इनमें कई स्लाइस (scatter_indices
से तय किए गए इंडेक्स पर) होते हैं, जिन्हें update_computation
का इस्तेमाल करके updates
में वैल्यू के क्रम के साथ अपडेट किया जाता है.
XlaBuilder::Scatter
भी देखें.
scatter(operands..., scatter_indices, updates..., update_computation,
index_vector_dim, update_window_dims, inserted_window_dims,
scatter_dims_to_operand_dims)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operands |
N XlaOp का क्रम |
T_0, ..., T_N टाइप के N ऐरे, जिन्हें अलग-अलग ऐरे में बांटना है. |
scatter_indices |
XlaOp |
वह कलेक्शन जिसमें उन स्लाइस के शुरुआती इंडेक्स मौजूद हैं जिन्हें बिखरा हुआ होना चाहिए. |
updates |
N XlaOp का क्रम |
T_0, ..., T_N टाइप की N कैटगरी. updates[i] में वे वैल्यू होती हैं जिनका इस्तेमाल operands[i] को स्कैटर करने के लिए किया जाना चाहिए. |
update_computation |
XlaComputation |
इनपुट ऐरे में मौजूद मौजूदा वैल्यू और स्कैटर के दौरान अपडेट को जोड़ने के लिए इस्तेमाल किया जाने वाला कैलकुलेशन. हिसाब लगाने की यह गिनती T_0, ..., T_N, T_0, ..., T_N -> Collate(T_0, ..., T_N) टाइप की होनी चाहिए. |
index_vector_dim |
int64 |
scatter_indices का वह डाइमेंशन जिसमें शुरुआती इंडेक्स शामिल हैं. |
update_window_dims |
ArraySlice<int64> |
updates आकार में डाइमेंशन का सेट, जो विंडो के डाइमेंशन होते हैं. |
inserted_window_dims |
ArraySlice<int64> |
विंडो डाइमेंशन का सेट, जिसे updates आकार में शामिल किया जाना चाहिए. |
scatter_dims_to_operand_dims |
ArraySlice<int64> |
स्कैटर इंडेक्स से ऑपरेंड इंडेक्स स्पेस तक का डाइमेंशन मैप. इस कलेक्शन को i को scatter_dims_to_operand_dims[i] से मैप करने के तौर पर माना जाता है . यह एक-एक और कुल होना चाहिए. |
indices_are_sorted |
bool |
क्या इंडेक्स को कॉलर के हिसाब से क्रम में लगाने की गारंटी है. |
unique_indices |
bool |
क्या कॉलर ने इंडेक्स के यूनीक होने की गारंटी दी है. |
कहां:
- N की वैल्यू 1 या उससे ज़्यादा होनी चाहिए.
operands
[0
], ...,operands
[N-1
] में सभी डाइमेंशन एक जैसे होने चाहिए.updates
[0
], ...,updates
[N-1
] सभी के डाइमेंशन एक जैसे होने चाहिए.- अगर
N = 1
,Collate(T)
T
है. - अगर
N > 1
है, तोCollate(T_0, ..., T_N)
,T
टाइप केN
एलिमेंट का टपल है.
अगर index_vector_dim
, scatter_indices.rank
के बराबर है, तो हम यह मान लेते हैं कि scatter_indices
में आखिर में 1
डाइमेंशन है.
हम ArraySlice<int64>
टाइप के update_scatter_dims
को, updates
शेप में डाइमेंशन के ऐसे सेट के तौर पर परिभाषित करते हैं जो update_window_dims
में नहीं हैं. साथ ही, ये डाइमेंशन बढ़ते हुए क्रम में होते हैं.
स्कैटर के आर्ग्युमेंट इन सीमाओं के मुताबिक होने चाहिए:
हर
updates
ऐरे की रैंकupdate_window_dims.size + scatter_indices.rank - 1
होनी चाहिए.हर
updates
कलेक्शन में डाइमेंशनi
की सीमाएं, इनके मुताबिक होनी चाहिए:- अगर
i
,update_window_dims
में मौजूद है (यानी कुछk
के लिएupdate_window_dims
[k
] के बराबर है), तोupdates
में डाइमेंशनi
का बाउंड,inserted_window_dims
को ध्यान में रखते हुएoperand
के बाउंड से ज़्यादा नहीं होना चाहिए (यानीadjusted_window_bounds
[k
], जहांadjusted_window_bounds
मेंoperand
के बाउंड होते हैं और इंडेक्सinserted_window_dims
के बाउंड हटा दिए जाते हैं). - अगर
i
,update_scatter_dims
में मौजूद है (यानी कुछk
के लिएupdate_scatter_dims
[k
] के बराबर है), तोupdates
में डाइमेंशनi
की सीमा,scatter_indices
की संबंधित सीमा के बराबर होनी चाहिए. हालांकि,index_vector_dim
को छोड़कर आगे बढ़ने पर, (यानीscatter_indices.shape.dims
[k
], अगरk
<index_vector_dim
औरscatter_indices.shape.dims
[k+1
]), तोupdates
में डाइमेंशन की सीमा,scatter_indices
की संबंधित सीमा के बराबर होनी चाहिए.
- अगर
update_window_dims
को बढ़ते क्रम में होना चाहिए, उसमें कोई दोहराया गया डाइमेंशन नंबर नहीं होना चाहिए और उसे[0, updates.rank)
की रेंज में होना चाहिए.inserted_window_dims
को बढ़ते क्रम में होना चाहिए, उसमें कोई दोहराया गया डाइमेंशन नंबर नहीं होना चाहिए और उसे[0, operand.rank)
की रेंज में होना चाहिए.operand.rank
,update_window_dims.size
औरinserted_window_dims.size
के योग के बराबर होना चाहिए.scatter_dims_to_operand_dims.size
का मान,scatter_indices.shape.dims
[index_vector_dim
] के बराबर होना चाहिए. साथ ही, इसकी वैल्यू,[0, operand.rank)
की रेंज में होनी चाहिए.
हर updates
कलेक्शन में मौजूद किसी इंडेक्स U
के लिए, उससे जुड़े operands
कलेक्शन में मौजूद इंडेक्स I
का हिसाब इस तरह लगाया जाता है:
- मान लें कि
G
= {U
[k
] fork
inupdate_scatter_dims
}.G
का इस्तेमाल करके,scatter_indices
कलेक्शन में इंडेक्स वेक्टरS
को खोजें, ताकिS
[i
] =scatter_indices
[Combine(G
,i
)] हो. यहां Combine(A, b), A मेंindex_vector_dim
पोज़िशन पर b को डालता है. scatter_dims_to_operand_dims
मैप की मदद सेS
को स्कैटर करकेS
का इस्तेमाल करके,operand
मेंS
in
इंडेक्स बनाएं. ज़्यादा औपचारिक तौर पर:S
in
[scatter_dims_to_operand_dims
[k
]] =S
[k
], अगरk
<scatter_dims_to_operand_dims.size
.S
in
[_
] =0
, अगर ऐसा नहीं है.
W
in
इंडेक्स को हरoperands
ऐरे में बनाएं. इसके लिए,inserted_window_dims
के हिसाब सेU
मेंupdate_window_dims
पर इंडेक्स को अलग-अलग जगह पर डालें. फ़ॉर्मल तरीके से:W
in
[window_dims_to_operand_dims
(k
)] =U
[k
] अगरk
update_window_dims
में है, जहांwindow_dims_to_operand_dims
, डोमेन [0
,update_window_dims.size
) और रेंज [0
,operand.rank
) \inserted_window_dims
के साथ है, तो यह मोनोटोनिक फ़ंक्शन है. उदाहरण के लिए, अगरupdate_window_dims.size
4
,operand.rank
6
, औरinserted_window_dims
{0
,2
} है, तोwindow_dims_to_operand_dims
{0
→1
,1
→3
,2
→4
,3
→5
} है.W
in
[_
] =0
नहीं तो.
I
,W
in
+S
in
है. यहां + का मतलब एलिमेंट के हिसाब से जोड़ना है.
खास जानकारी में, स्कैटर ऑपरेशन को इस तरह परिभाषित किया जा सकता है.
output
कोoperands
से शुरू करें. इसका मतलब है किoperands
[J
] कलेक्शन में मौजूद सभी इंडेक्सJ
के लिए, सभी इंडेक्सO
के लिए:
output
[J
][O
] =operands
[J
][O
]updates
[J
] कलेक्शन में मौजूद हर इंडेक्सU
औरoperand
[J
] कलेक्शन मेंO
से जुड़े इंडेक्स के लिए, अगरO
output
के लिए मान्य इंडेक्स है:
(output
[0
][O
], ...,output
[N-1
][O
]) =update_computation
(output
[0
][O
], ..., ,output
[N-1
][O
],updates
[0
][U
], ...,updates
[N-1
][U
])
अपडेट लागू करने का क्रम तय नहीं होता. इसलिए, जब updates
में कई इंडेक्स, operands
में एक ही इंडेक्स को रेफ़र करते हैं, तो output
में इनसे जुड़ी वैल्यू, तय नहीं होगी.
ध्यान दें कि update_computation
में पास किया जाने वाला पहला पैरामीटर,
output
कलेक्शन की मौजूदा वैल्यू होगा. साथ ही, दूसरा पैरामीटर
हमेशा updates
कलेक्शन की वैल्यू होगा. यह खास तौर पर उन मामलों में ज़रूरी होता है जब update_computation
कम्यूटेटिव नहीं होता है.
अगर indices_are_sorted
को 'सही' पर सेट किया गया है, तो XLA यह मान सकता है कि उपयोगकर्ता ने scatter_indices
को क्रम से लगाया है. scatter_indices
को क्रम से लगाने के लिए, scatter_dims_to_operand_dims
के हिसाब से वैल्यू को अलग-अलग करके, इसके बाद उन्हें बढ़ते क्रम में लगाया जाता है. अगर ऐसा नहीं है, तो सिमेंटिक्स को लागू किया जाएगा.
अगर unique_indices
को 'सही है' पर सेट किया जाता है, तो XLA यह मान सकता है कि अलग-अलग स्प्रेडशीट में मौजूद सभी एलिमेंट यूनीक हैं. इसलिए, XLA ऐसी कार्रवाइयों का इस्तेमाल कर सकता है जो ऐटमिक नहीं हैं. अगर
unique_indices
को 'सही है' पर सेट किया गया है और स्कैटर किए जा रहे इंडेक्स यूनीक नहीं हैं, तो सिमेंटिक्स लागू किया जाएगा.
अनौपचारिक रूप से, स्कैटर ऑप को कलेक्ट ऑप के इनवर्स के रूप में देखा जा सकता है. इसका मतलब है कि स्कैटर ऑप, इनपुट में मौजूद उन एलिमेंट को अपडेट करता है जिन्हें इससे जुड़े कलेक्ट ऑप से एक्सट्रैक्ट किया जाता है.
अनौपचारिक ब्यौरा और उदाहरणों के लिए, Gather
में जाकर "अनौपचारिक ब्यौरा" सेक्शन देखें.
चुनें
XlaBuilder::Select
भी देखें.
प्रेडिकेट अरे की वैल्यू के आधार पर, दो इनपुट ऐरे के एलिमेंट से आउटपुट अरे बनाता है.
Select(pred, on_true, on_false)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
pred |
XlaOp |
PRED टाइप का ऐरे |
on_true |
XlaOp |
T टाइप का कलेक्शन |
on_false |
XlaOp |
T टाइप का अरे |
on_true
और on_false
सरणियों का आकार एक जैसा होना चाहिए. यह आउटपुट अरे का साइज़ भी होता है. ऐरे pred
की डाइमेंशनलिटी, on_true
और on_false
की डाइमेंशनलिटी के बराबर होनी चाहिए. साथ ही, इसमें PRED
एलिमेंट टाइप होना चाहिए.
pred
के हर एलिमेंट P
के लिए, आउटपुट कलेक्शन का एलिमेंट on_true
से लिया जाता है. ऐसा तब किया जाता है, जब P
की वैल्यू true
हो. वहीं, अगर P
की वैल्यू false
है, तो on_false
से लिया जाता है. ब्रॉडकास्ट करने के प्रतिबंधित तरीके के तौर पर, pred
PRED
टाइप का एक स्केलर हो सकता है. इस मामले में, अगर pred
true
है, तो आउटपुट कलेक्शन पूरी तरह से on_true
से लिया जाता है. वहीं, अगर pred
false
है, तो आउटपुट कलेक्शन पूरी तरह से on_false
से लिया जाता है.
स्केलर न होने वाले 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};
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};
ट्यूपल के बीच चुनने का विकल्प उपलब्ध है. इस काम के लिए, ट्यूपल को स्केलर टाइप माना जाता है. अगर on_true
और on_false
ट्यूपल हैं (जिनका आकार एक जैसा होना चाहिए!), तो pred
को PRED
टाइप का स्केलर होना चाहिए.
SelectAndScatter
XlaBuilder::SelectAndScatter
भी देखें.
इस ऑपरेशन को एक कंपोज़िट ऑपरेशन माना जा सकता है जो पहली बार हर विंडो से कोई एलिमेंट चुनने के लिए, operand
अरे पर ReduceWindow
कंप्यूट करता है. इसके बाद, source
अरे को चुने गए एलिमेंट के इंडेक्स तक स्कैटर करता है, ताकि आउटपुट अरे बनाया जा सके. बाइनरी
select
फ़ंक्शन का इस्तेमाल, हर विंडो में इसे लागू करके, हर विंडो से एक एलिमेंट चुनने के लिए किया जाता है. साथ ही, इसे इस प्रॉपर्टी के साथ कॉल किया जाता है कि पहले
पैरामीटर का इंडेक्स वेक्टर, दूसरे पैरामीटर के इंडेक्स वेक्टर से, शब्दकोश के हिसाब से कम है. अगर पहला पैरामीटर चुना जाता है, तो select
फ़ंक्शन true
दिखाता है और अगर दूसरा पैरामीटर चुना जाता है, तो false
दिखाता है. साथ ही, फ़ंक्शन में ट्रांज़िटिविटी (जैसे, अगर select(a, b)
और select(b, c)
true
हैं, तो select(a, c)
भी true
है) होनी चाहिए, ताकि चुना गया एलिमेंट किसी दी गई विंडो के लिए, ट्रैवर्स किए गए एलिमेंट के क्रम पर निर्भर न हो.
फ़ंक्शन scatter
, आउटपुट ऐरे में चुने गए हर इंडेक्स पर लागू होता है. इसमें दो स्केलर पैरामीटर होते हैं:
- आउटपुट कलेक्शन में चुने गए इंडेक्स की मौजूदा वैल्यू
- चुने गए इंडेक्स पर लागू होने वाली
source
की स्कैटर वैल्यू
यह दो पैरामीटर को जोड़ता है और स्केलर वैल्यू दिखाता है. इसका इस्तेमाल, आउटपुट कलेक्शन में चुने गए इंडेक्स की वैल्यू को अपडेट करने के लिए किया जाता है. शुरुआत में, आउटपुट कलेक्शन के सभी इंडेक्स init_value
पर सेट होते हैं.
आउटपुट अरे का आकार, operand
अरे के आकार जैसा ही होता है. साथ ही, source
अरे का आकार, operand
अरे पर ReduceWindow
कार्रवाई लागू करने से मिले नतीजे के जैसा ही होना चाहिए. SelectAndScatter
का इस्तेमाल, किसी न्यूरल नेटवर्क में पूलिंग लेयर के लिए ग्रेडिएंट वैल्यू को बैकप्रोपगेट करने के लिए किया जा सकता है.
SelectAndScatter(operand, select, window_dimensions, window_strides,
padding, source, init_value, scatter)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
T टाइप का ऐरे, जिस पर विंडो स्लाइड करती हैं |
select |
XlaComputation |
हर विंडो के सभी एलिमेंट पर लागू करने के लिए, T, T -> PRED टाइप की बाइनरी कंप्यूटेशन; पहला पैरामीटर चुनने पर true लौटाता है और दूसरा पैरामीटर चुने जाने पर false लौटाता है |
window_dimensions |
ArraySlice<int64> |
विंडो डाइमेंशन की वैल्यू के लिए, पूर्णांकों का कलेक्शन |
window_strides |
ArraySlice<int64> |
विंडो स्ट्राइड वैल्यू के लिए पूर्णांकों का अरे |
padding |
Padding |
विंडो के लिए पैडिंग टाइप (Padding::kSame या Padding::kValid) |
source |
XlaOp |
T की कैटगरी, जिसमें स्कैटर की जाने वाली वैल्यू भी शामिल हैं |
init_value |
XlaOp |
आउटपुट ऐरे की शुरुआती वैल्यू के लिए, T टाइप की स्केलर वैल्यू |
scatter |
XlaComputation |
T, T -> T टाइप का बाइनरी कैलकुलेशन, ताकि हर स्कैटर सोर्स एलिमेंट को उसके डेस्टिनेशन एलिमेंट के साथ लागू किया जा सके |
नीचे दिए गए उदाहरण में, SelectAndScatter
का इस्तेमाल करने के उदाहरण दिए गए हैं. इसमें select
फ़ंक्शन, अपने पैरामीटर के बीच सबसे बड़ी वैल्यू का हिसाब लगाता है. ध्यान दें कि जब विंडो ओवरलैप होती हैं, जैसा कि नीचे दी गई इमेज (2) में दिखाया गया है, तब अलग-अलग विंडो से, operand
कलेक्शन के इंडेक्स को कई बार चुना जा सकता है. इस इमेज में, सबसे ऊपर मौजूद दोनों विंडो (नीली और लाल) में वैल्यू 9 वाला एलिमेंट चुना गया है. साथ ही, बाइनरी जोड़ने वाला scatter
फ़ंक्शन, वैल्यू 8 (2 + 6) वाला आउटपुट एलिमेंट दिखाता है.
scatter
फ़ंक्शन का आकलन करने का क्रम मनमुताबिक हो सकता है और यह तय नहीं होता. इसलिए, scatter
फ़ंक्शन फिर से जोड़ने के लिए बहुत ज़्यादा
संवेदनशील नहीं होना चाहिए. ज़्यादा जानकारी के लिए, Reduce
के संदर्भ में, असोसिएटिविटी के बारे में चर्चा देखें.
भेजें
XlaBuilder::Send
भी देखें.
Send(operand, channel_handle)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
भेजा जाने वाला डेटा (T टाइप का कलेक्शन) |
channel_handle |
ChannelHandle |
हर भेजने/पाने वाले पेयर के लिए यूनीक आइडेंटिफ़ायर |
यह दिए गए ऑपरेंड डेटा को ऐसे Recv
निर्देश में भेजता है,
जिसमें उसी चैनल का हैंडल शेयर होता है. कोई डेटा नहीं दिखाता है.
Recv
ऑपरेशन की तरह ही, Send
का क्लाइंट एपीआई भी सिंक्रोनस कम्यूनिकेशन दिखाता है. एसिंक्रोनस डेटा ट्रांसफ़र को चालू करने के लिए, इसे एचएलओ (दो एचएलओ) निर्देशों (Send
और SendDone
) में बांटा जाता है. HloInstruction::CreateSend
और HloInstruction::CreateSendDone
भी देखें.
Send(HloInstruction operand, int64 channel_id)
ऑपरेंड को उसी चैनल आईडी से, Recv
निर्देश के ज़रिए असाइन किए गए रिसॉर्स में एसिंक्रोनस ट्रांसफ़र करता है. यह एक कॉन्टेक्स्ट दिखाता है. इस कॉन्टेक्स्ट को SendDone
के नीचे दिए गए निर्देश की मदद से, डेटा ट्रांसफ़र के पूरा होने का इंतज़ार करने के लिए इस्तेमाल किया जाता है. कॉन्टेक्स्ट, {operand (shape), request identifier
(U32)} का ट्यूपल होता है. इसका इस्तेमाल सिर्फ़ SendDone
निर्देश से किया जा सकता है.
SendDone(HloInstruction context)
Send
निर्देश से बनाया गया संदर्भ डेटा ट्रांसफ़र के पूरा होने का इंतज़ार करता है. निर्देश कोई डेटा नहीं दिखाता.
चैनल के लिए निर्देशों को शेड्यूल करने का तरीका
हर चैनल (Recv
, RecvDone
,
Send
, SendDone
) के लिए, चार निर्देशों को लागू करने का क्रम यहां दिया गया है.
Recv
,Send
से पहले होता हैSend
,RecvDone
से पहले होता हैRecv
,RecvDone
से पहले होता हैSend
,SendDone
से पहले होता है
जब बैकएंड कंपाइलर हर कंप्यूटेशन के लिए लीनियर शेड्यूल जनरेट करते हैं, जो चैनल के निर्देशों के ज़रिए कम्यूनिकेशन करता है, तो कंप्यूटेशन का साइकल नहीं होना चाहिए. उदाहरण के लिए, नीचे दिए गए शेड्यूल की वजह से डेडलॉक हो जाते हैं.
स्लाइस
XlaBuilder::Slice
भी देखें.
स्लाइस करने से, इनपुट कलेक्शन से एक सब-कलेक्शन निकाला जाता है. सब-कलेक्शन उसी रैंक की है जिसमें इनपुट शामिल है. साथ ही, इसमें वैल्यू, इनपुट कैटगरी में बाउंडिंग बॉक्स के अंदर होती हैं. यहां बाउंडिंग बॉक्स के डाइमेंशन और इंडेक्स को, स्लाइस ऑपरेशन के लिए तर्क के तौर पर दिया जाता है.
Slice(operand, start_indices, limit_indices, strides)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
operand |
XlaOp |
T टाइप का N डाइमेंशन वाला अरे |
start_indices |
ArraySlice<int64> |
N पूर्णांकों की सूची, जिसमें हर डाइमेंशन के लिए स्लाइस के शुरुआती इंडेक्स शामिल होते हैं. वैल्यू, शून्य से ज़्यादा या उसके बराबर होनी चाहिए. |
limit_indices |
ArraySlice<int64> |
हर डाइमेंशन के स्लाइस के लिए, आखिरी इंडेक्स (खास तौर पर) वाले N पूर्णांकों की सूची. हर वैल्यू, डाइमेंशन के लिए चुनी गई start_indices वैल्यू से ज़्यादा या उसके बराबर होनी चाहिए. साथ ही, यह डाइमेंशन के साइज़ से कम या उसके बराबर होनी चाहिए. |
strides |
ArraySlice<int64> |
N पूर्णांकों की सूची, जो स्लाइस की इनपुट स्ट्राइड का पता लगाती है. स्लाइस, डाइमेंशन d में हर strides[d] एलिमेंट को चुनता है. |
1-डाइमेंशन वाला उदाहरण:
let a = {0.0, 1.0, 2.0, 3.0, 4.0}
Slice(a, {2}, {4}) produces:
{2.0, 3.0}
दो डाइमेंशन वाला उदाहरण:
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} }
क्रम से लगाएं
XlaBuilder::Sort
भी देखें.
Sort(operands, comparator, dimension, is_stable)
तर्क | टाइप | सिमैंटिक |
---|---|---|
operands |
ArraySlice<XlaOp> |
क्रम से लगाने के लिए ऑपरेंड. |
comparator |
XlaComputation |
इस्तेमाल की जाने वाली तुलना करने वाली कंप्यूटेशन. |
dimension |
int64 |
वह डाइमेंशन जिसके हिसाब से क्रम में लगाना है. |
is_stable |
bool |
क्या स्थिर क्रम से लगाने की सुविधा का इस्तेमाल करना है. |
अगर सिर्फ़ एक ऑपरेंड दिया जाता है, तो:
अगर ऑपरेंड एक रैंक वाला टेंसर (ऐरे) है, तो नतीजा क्रम से लगाया गया ऐरे होता है. अगर आपको ऐरे को बढ़ते क्रम में लगाना है, तो तुलना करने वाले फ़ंक्शन को कम से कम की तुलना करनी चाहिए. असल में, ऐरे को क्रम से लगाने के बाद, यह
i, j
के साथ सभी इंडेक्स पोज़िशन के लिएi < j
रखता है, जोcomparator(value[i], value[j]) = comparator(value[j], value[i]) = false
याcomparator(value[i], value[j]) = true
हो सकता है.अगर ऑपरेंड की रैंक ज़्यादा है, तो ऑपरेंड को दिए गए डाइमेंशन के हिसाब से क्रम में लगाया जाता है. उदाहरण के लिए, रैंक-2 टेंसर (मैट्रिक्स) के लिए,
0
की डाइमेंशन वैल्यू हर कॉलम को अलग से क्रम से लगाएगी और1
की डाइमेंशन वैल्यू हर लाइन को अलग से क्रम से लगाएगी. अगर कोई डाइमेंशन नंबर नहीं दिया गया है, तो डिफ़ॉल्ट रूप से आखिरी डाइमेंशन चुना जाता है. जिस डाइमेंशन को क्रम से लगाया गया है उसके लिए, रैंक-1 के मामले में क्रम से लगाने का वही तरीका लागू होता है.
अगर n > 1
ऑपरेंड दिए गए हैं, तो:
सभी
n
ऑपरेंड, एक जैसे डाइमेंशन वाले टेंसर होने चाहिए. टेंसर के एलिमेंट टाइप अलग-अलग हो सकते हैं.सभी ऑपरेंड को एक साथ क्रम से लगाया जाता है, न कि अलग-अलग. सैद्धांतिक रूप से ऑपरेंड को ट्यूपल माना जाता है. इंडेक्स पोज़िशन
i
औरj
पर मौजूद हर ऑपरेंड के एलिमेंट को स्वैप करने की ज़रूरत है या नहीं, यह जांचने के लिए तुलना करने वाले फ़ंक्शन को2 * n
स्केलर पैरामीटर के साथ कॉल किया जाता है. इसमें पैरामीटर2 * k
,k-th
ऑपरेंड की पोज़िशनi
पर मौजूद वैल्यू से मेल खाता है और पैरामीटर2 * k + 1
,k-th
ऑपरेंड की पोज़िशनj
पर मौजूद वैल्यू से मेल खाता है. आम तौर पर, तुलना करने वाला टूल,2 * k
और2 * k + 1
पैरामीटर की तुलना एक-दूसरे से करेगा. साथ ही, पैरामीटर पेयर का इस्तेमाल टाई ब्रेकर के तौर पर कर सकता है.इसका नतीजा एक ट्यूपल होता है, जिसमें ऑपरेंड को क्रम से लगाया जाता है (जैसा कि ऊपर दिए गए डाइमेंशन के साथ). ट्यूपल का
i-th
ऑपरेंड, Sort केi-th
ऑपरेंड से मेल खाता है.
उदाहरण के लिए, अगर तीन ऑपरेंड operand0 = [3, 1]
,
operand1 = [42, 50]
, operand2 = [-3.0, 1.1]
हैं और तुलना करने वाला ऑपरेटर, operand0
की वैल्यू की तुलना सिर्फ़ कम से कम के साथ करता है, तो क्रम से लगाने का आउटपुट टुपल ([1, 3], [50, 42], [1.1, -3.0])
होगा.
अगर is_stable
को 'सही है' पर सेट किया गया है, तो क्रम के स्थिर रहने की गारंटी होती है. इसका मतलब है कि अगर ऐसे एलिमेंट हैं जिन्हें तुलना करने वाले के हिसाब से बराबर माना जाता है, तो मिलती-जुलती वैल्यू के मिलते-जुलते क्रम को सुरक्षित रखा जाता है. दो एलिमेंट e1
और e2
,
अगर comparator(e1, e2) = comparator(e2, e1) = false
हैं, तो ही बराबर हैं. डिफ़ॉल्ट रूप से, is_stable
को 'गलत' पर सेट किया जाता है.
ट्रांसपोज़ करना
tf.reshape
से जुड़ी कार्रवाई भी देखें.
Transpose(operand)
तर्क | टाइप | सिमैंटिक |
---|---|---|
operand |
XlaOp |
ट्रांसपोज़ किया जाने वाला ऑपरेंड. |
permutation |
ArraySlice<int64> |
डाइमेंशन को बदलने का तरीका. |
ऑपरेंड डाइमेंशन को दिए गए क्रम में बदलता है, इसलिए
∀ i . 0 ≤ i < rank ⇒ input_dimensions[permutation[i]] = output_dimensions[i]
.
यह फिर से शेप जैसा ही है.
TriangularSolve
XlaBuilder::TriangularSolve
भी देखें.
फ़ॉरवर्ड या बैक-सबस्टिट्यूशन की मदद से, रैखिक समीकरणों की ऐसी प्रणाली हल करती है जिसमें लाेवर या अपर ट्रैंगल फ़ॉर्म में कोएफ़िशिएंट मैट्रिक्स हों. लीडिंग डाइमेंशन के साथ ब्रॉडकास्ट करते हुए, यह रूटीन a
और b
के हिसाब से x
वैरिएबल के लिए, किसी एक मैट्रिक्स सिस्टम op(a) * x =
b
या x * op(a) = b
का समाधान करता है, जहां op(a)
या तो op(a) = a
या op(a) = Transpose(a)
या op(a) = Conj(Transpose(a))
है.
TriangularSolve(a, b, left_side, lower, unit_diagonal, transpose_a)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
a |
XlaOp |
[..., M, M] आकार वाला, कॉम्प्लेक्स या फ़्लोटिंग-पॉइंट टाइप का रैंक > 2 ऐरे. |
b |
XlaOp |
अगर left_side सही है, तो [..., M, K] आकार के साथ, एक ही टाइप का रैंक > 2 कलेक्शन. अगर ऐसा नहीं है, तो [..., K, M] . |
left_side |
bool |
बताता है कि फ़ॉर्म के सिस्टम को हल करना है op(a) * x = b (true ) या x * op(a) = b (false ). |
lower |
bool |
a के ऊपरी या निचले त्रिभुज का इस्तेमाल करना है. |
unit_diagonal |
bool |
अगर true , तो a के डायगनल एलिमेंट को 1 माना जाता है और उन्हें ऐक्सेस नहीं किया जा सकता. |
transpose_a |
Transpose |
a को ऐसे ही इस्तेमाल करना है, ट्रांसपोज़ करना है या उसका कॉंजुगेट ट्रांसपोज़ लेना है. |
इनपुट डेटा को सिर्फ़ a
के निचले/ऊपरी त्रिकोण से पढ़ा जाता है. यह lower
की वैल्यू पर निर्भर करता है. दूसरे त्रिभुज की वैल्यू नज़रअंदाज़ कर दी जाती हैं. आउटपुट डेटा, उसी ट्राएंगल में दिखाया जाता है. दूसरे ट्राएंगल में मौजूद वैल्यू, लागू करने के तरीके के हिसाब से तय होती हैं और वे कुछ भी हो सकती हैं.
अगर a
और b
की रैंक दो से ज़्यादा है, तो उन्हें मैट्रिक के बैच के तौर पर माना जाता है. इसमें, दो छोटे डाइमेंशन को छोड़कर सभी डाइमेंशन, बैच डाइमेंशन होते हैं. a
और
b
में बराबर बैच डाइमेंशन होने चाहिए.
टपल
XlaBuilder::Tuple
भी देखें.
एक टपल, जिसमें डेटा हैंडल की अलग-अलग संख्या होती है. हर हैंडल का अपना आकार होता है.
यह C++ में मौजूद std::tuple
के जैसा है. सैद्धांतिक तौर पर:
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);
ट्यूपल को GetTupleElement
ऑपरेशन की मदद से, अलग-अलग एलिमेंट में बांटा जा सकता है (ऐक्सेस किया जा सकता है).
हालांकि
XlaBuilder::While
भी देखें.
While(condition, body, init)
तर्क | टाइप | सिमैंटिक्स |
---|---|---|
condition |
XlaComputation |
T -> PRED टाइप का XlaComputation, जो 'लूप' खत्म होने की स्थिति के बारे में बताता है. |
body |
XlaComputation |
T -> T टाइप का XlaComputation, जो लूप के मुख्य हिस्से को तय करता है. |
init |
T |
condition और body पैरामीटर की शुरुआती वैल्यू. |
यह तब तक body
को क्रम से लागू करता रहता है, जब तक condition
काम नहीं करता. यह आम तौर पर होने वाली प्रोसेस जैसा ही है.
बात कुछ और भाषाओं में की जाती है. हालांकि, ये अंतर और
पाबंदियों के बारे में नहीं हैं.
While
नोड,T
टाइप की वैल्यू दिखाता है. यह वैल्यू,body
के आखिरी एक्ज़ीक्यूशन का नतीजा होती है.T
टाइप का आकार स्टैटिक तरीके से तय किया जाता है और यह सभी बार-बार एक जैसा होना चाहिए.
कैलकुलेशन के T पैरामीटर, पहले दोहराए जाने वाले चरण में init
वैल्यू से शुरू किए जाते हैं. इसके बाद, हर दोहराए जाने वाले चरण में, ये पैरामीटर body
से नए नतीजे पर अपने-आप अपडेट हो जाते हैं.
While
नोड का एक मुख्य इस्तेमाल उदाहरण यह है कि न्यूरल नेटवर्क में ट्रेनिंग को बार-बार लागू करना. नीचे, कैलकुलेशन दिखाने वाले ग्राफ़ के साथ आसान बना हुआ स्यूडोकोड दिखाया गया है. कोड while_test.cc
में देखा जा सकता है.
इस उदाहरण में मौजूद T
टाइप एक Tuple
है. इसमें इटरेशन की गिनती के लिए int32
और अक्युमिलेटर के लिए vector[10]
है. 1,000 बार दोहराए जाने पर, लुूप एक कॉन्स्टेंट वेक्टर को इकट्ठा करने वाले फ़ंक्शन में जोड़ता रहता है.
// 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};
}