ऑपरेशन सिमैंटिक

यहां 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 एक सामूहिक ऑपरेशन है, जो सभी कोर से सभी कोर पर डेटा भेजता है. इसमें दो चरण होते हैं:

  1. स्कैटर फ़ेज़. हर कोर पर, ऑपरेंड को split_dimensions के साथ split_count ब्लॉक में बांटा जाता है और ब्लॉक सभी कोर में भेजे जाते हैं. उदाहरण के लिए, ith ब्लॉक को ith कोर पर भेजा जाता है.
  2. इकट्ठा करने का चरण. हर कोर, मिले ब्लॉक को 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 XlaOps का क्रम आर्बिट्रेरी टाइप के 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 XlaOps का क्रम किसी भी टाइप के 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) में से कोई एक होAtan2Complex

तर्क टाइप सिमैंटिक
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 के साथ आउटपुट कलेक्शन के सीमाओं का हिसाब इस तरह लगाया जाता है:

  1. अगर 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] है).

  2. अगर 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 की गिनती इस तरह से की जाती है:

  1. मान लें कि G = { Out[k] for k in batch_dims }. G का इस्तेमाल करके, वैक्टर S को इस तरह काटें कि S[i] = start_indices[Combine(G, i)] हो. यहां Combine(A, b), A में index_vector_dim पोज़िशन पर b डालता है. ध्यान दें कि G के खाली होने पर भी, यह अच्छी तरह से तय किया गया है: अगर G खाली है, तो S = start_indices.

  2. start_index_map की मदद से S को अलग-अलग करके, S का इस्तेमाल करके operand में Sin का शुरुआती इंडेक्स बनाएं. ज़्यादा सटीक रूप से:

    1. Sin[start_index_map[k]] = S[k], अगर k < start_index_map.size.

    2. Sin[_] = 0 नहीं तो.

  3. collapsed_slice_dims सेट के हिसाब से, Out में ऑफ़सेट डाइमेंशन के इंडेक्स को स्कैटर करके, operand में Oin इंडेक्स बनाएं. ज़्यादा सटीक रूप से:

    1. अगर k < offset_dims.size है, तो Oin[remapped_offset_dims(k)] = Out[offset_dims[k]] (remapped_offset_dims की जानकारी नीचे दी गई है).

    2. Oin[_] = 0 नहीं तो.

  4. In, Oin + Sin है, जहां एलिमेंट के हिसाब से + का मतलब है.

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, {01, 13, 24, 35} है.

अगर 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,O0,O1] को आउटपुट शेप में इंडेक्स के तौर पर लेता है और इसे इनपुट कलेक्शन के एलिमेंट पर इस तरह मैप करता है:

हम सबसे पहले G का इस्तेमाल करके, इकट्ठा किए गए इंडेक्स के कलेक्शन से एक (X,Y) वेक्टर चुनते हैं. आउटपुट ऐरे में इंडेक्स [G,O0,O1] पर मौजूद एलिमेंट, इनपुट ऐरे में इंडेक्स [X+O0,Y+O1] पर मौजूद एलिमेंट होता है.

slice_sizes, [8,6] है. इससे O0 और O1 की रेंज तय होती है. साथ ही, इससे स्लाइस के बाउंड तय होते हैं.

यह इकट्ठा करने की कार्रवाई एक बैच डाइनैमिक स्लाइस के तौर पर काम करती है, जिसमें G बैच डाइमेंशन के तौर पर काम करता है.

इकट्ठा किए गए इंडेक्स, कई डाइमेंशन वाले हो सकते हैं. उदाहरण के लिए, ऊपर दिए गए उदाहरण का ज़्यादा सामान्य वर्शन, [4,5,2] आकार के "इकट्ठा इंडेक्स" कलेक्शन का इस्तेमाल करके, इंडेक्स को इस तरह से ट्रांसलेट करेगा:

यह फिर से बैच डाइमेंशन के तौर पर, बैच डाइनैमिक स्लाइस G0 और G1 के तौर पर काम करता है. स्लाइस का साइज़ अब भी [8,6] है.

XLA में डेटा इकट्ठा करने की प्रक्रिया में, ऊपर बताए गए अनौपचारिक सिमेंटिक्स को इन तरीकों से सामान्य बनाया गया है:

  1. हम कॉन्फ़िगर कर सकते हैं कि आउटपुट आकार में कौनसे डाइमेंशन, ऑफ़सेट डाइमेंशन हैं. (आखिरी उदाहरण में, वे डाइमेंशन O0, O1 हैं). आउटपुट बैच डाइमेंशन (पिछले उदाहरण में G0, G1 वाले डाइमेंशन), ऐसे आउटपुट डाइमेंशन होते हैं जो ऑफ़सेट डाइमेंशन नहीं होते.

  2. आउटपुट आकार में साफ़ तौर पर मौजूद आउटपुट ऑफ़सेट डाइमेंशन की संख्या, इनपुट रैंक से कम हो सकती है. इन "मिसिंग" डाइमेंशन का साइज़ 1 होना चाहिए. इन्हें collapsed_slice_dims के तौर पर साफ़ तौर पर सूची में शामिल किया गया है. इनका स्लाइस साइज़ 1 है. इसलिए, इनके लिए सिर्फ़ 0 इंडेक्स मान्य है. साथ ही, इन्हें हटाने से कोई समस्या नहीं होती.

  3. "सूची इकट्ठा करें" श्रेणी (पिछले उदाहरण में (X, Y)) से निकाले गए स्लाइस में, इनपुट अरे की रैंक से कम एलिमेंट हो सकते हैं. साथ ही, साफ़ तौर पर मैप करने से यह तय होता है कि इंडेक्स को, इनपुट से मिलती-जुलती रैंक कैसे करना चाहिए.

आखिरी उदाहरण के तौर पर, हम tf.gather_nd को लागू करने के लिए (2) और (3) का इस्तेमाल करते हैं:

G0 और G1 का इस्तेमाल, इंडेक्स इकट्ठा करने वाले कलेक्शन से, स्टार्टिंग इंडेक्स को अलग करने के लिए किया जाता है. हालांकि, स्टार्टिंग इंडेक्स में सिर्फ़ एक एलिमेंट, X होता है. इसी तरह, O0 वैल्यू वाला सिर्फ़ एक आउटपुट ऑफ़सेट इंडेक्स है. हालांकि, इनपुट कलेक्शन में इंडेक्स के तौर पर इस्तेमाल किए जाने से पहले, इन्हें "इकट्ठा करने के लिए इंडेक्स मैपिंग" (औपचारिक ब्यौरे में start_index_map) और "ऑफ़सेट मैपिंग" (औपचारिक ब्यौरे में remapped_offset_dims) के हिसाब से [X,0] और [0,O0] में बड़ा किया जाता है. इन दोनों को जोड़ने पर [X,O0] बनता है. दूसरे शब्दों में, आउटपुट इंडेक्स [G0,G1,O0] को इनपुट इंडेक्स [GatherIndices[G0,G1,0],O0] पर मैप किया जाता है. इससे हमें 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 XlaOps का क्रम 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 के लिए उपलब्ध वैल्यू:

स्कैटर

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 का हिसाब इस तरह लगाया जाता है:

  1. मान लें कि G = { U[k] for k in update_scatter_dims }. G का इस्तेमाल करके, scatter_indices कलेक्शन में इंडेक्स वेक्टर S को खोजें, ताकि S[i] = scatter_indices[Combine(G, i)] हो. यहां Combine(A, b), A में index_vector_dim पोज़िशन पर b को डालता है.
  2. scatter_dims_to_operand_dims मैप की मदद से S को स्कैटर करके S का इस्तेमाल करके, operand में Sin इंडेक्स बनाएं. ज़्यादा औपचारिक तौर पर:
    1. Sin[scatter_dims_to_operand_dims[k]] = S[k], अगर k < scatter_dims_to_operand_dims.size.
    2. Sin[_] = 0, अगर ऐसा नहीं है.
  3. Win इंडेक्स को हर operands ऐरे में बनाएं. इसके लिए, inserted_window_dims के हिसाब से U में update_window_dims पर इंडेक्स को अलग-अलग जगह पर डालें. फ़ॉर्मल तरीके से:
    1. Win[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 {01, 13, 24, 35} है.
    2. Win[_] = 0 नहीं तो.
  4. I, Win + Sin है. यहां + का मतलब एलिमेंट के हिसाब से जोड़ना है.

खास जानकारी में, स्कैटर ऑपरेशन को इस तरह परिभाषित किया जा सकता है.

  • 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, आउटपुट ऐरे में चुने गए हर इंडेक्स पर लागू होता है. इसमें दो स्केलर पैरामीटर होते हैं:

  1. आउटपुट कलेक्शन में चुने गए इंडेक्स की मौजूदा वैल्यू
  2. चुने गए इंडेक्स पर लागू होने वाली 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};
}