StableHLO को मूल रूप से एमएचएलओ भाषा से बूटस्ट्रैप किया गया था. साथ ही, इसने टाइप अनुमान के एमएचएलओ को लागू किया था. लागू करने की प्रोग्रेस को status.md में ट्रैक किया जाता है.
नीचे दिए गए दिशा-निर्देशों का मकसद, StableHLO ऑपरेशन के लिए अच्छी क्वालिटी की पुष्टि करने वाले और आकार फ़ंक्शन लागू करना है.
प्रस्ताव
ये प्रपोज़ल, मौजूदा तरीकों को फिर से लागू करने और बड़े स्तर तक कवरेज हासिल करने तक, नए ऑपरेशन हासिल करने पर लागू होते हैं.
(P1) सही जानकारी के सोर्स के तौर पर, StableHLO स्पेसिफ़िकेशन का इस्तेमाल करें
StableHLO ऑपरेशन के सभी पुष्टि करने वालों और शेप फ़ंक्शन के लिए, spec सबसे सही सोर्स है. हर ऑप के मौजूदा पुष्टि करने वाले और आकार फ़ंक्शन को फिर से देखना ज़रूरी है, ताकि निर्देशों का पूरी तरह से पालन किया जा सके. ध्यान दें कि खास जानकारी से जुड़े दस्तावेज़ में बदलाव होते रहते हैं. ऐसे मामलों में जहां ऑपरेटर की खास जानकारी उपलब्ध न हो, वहां XLA को लागू करने के तरीके का इस्तेमाल, सच्चाई के सोर्स के तौर पर किया जाना चाहिए. इसमें xla/service/shape_inference.cc और xla/service/hlo_verifier.cc भी शामिल हैं. एक्सएलए को लागू करने में, बिना किसी सीमा के डायनेमिज़्म शामिल नहीं हैं. इसलिए, डॉमिनिज़्म के लिए आरएफ़सी उपलब्ध होने तक, हम सामान्य नियमों को लागू करेंगे.
(P2) ओडीएस का पूरा फ़ायदा लें
ओडीएस फ़ाइलें (जैसे कि StablehloOps.td), हर ऑपरेंड/एट्रिब्यूट/नतीजे के लिए traits और टाइप तय करती हैं और पुष्टि करेंगी. इसलिए, उन प्रॉपर्टी के लिए पुष्टि करने वाले टूल या आकार फ़ंक्शन में पुष्टि करने के लिए किसी कोड की ज़रूरत नहीं होती जो ओडीएस से पहले से ही गारंटी वाली होती हैं. अगर पुष्टि करने वाले कोड को ओडीएस के साथ डुप्लीकेट किया गया है, तो उसे हटा दें, क्योंकि उसे कभी ट्रिगर नहीं किया जाएगा.
क्या हमें ओडीएस से, कंस्ट्रेंट के लिए टेस्ट जोड़ने की ज़रूरत है? कृपया टेस्टिंग से जुड़े दिशा-निर्देश बनाएं देखें.
(P3) पुष्टि करने वालों और आकार फ़ंक्शन में पुष्टि करने के कोड को बनाए रखना
दोनों:
- पुष्टि करने वाले:
Op::verify()
ने लागू किया और - आकार फ़ंक्शन:
Op::inferReturnTypes()
याOp::inferReturnTypeComponents
जैसेInferTypeOpInterface
की मदद से लागू किए जाते हैं
में ऑपरेंड/एट्रिब्यूट/नतीजों की जांच करने के लिए पुष्टि कोड हो सकता है. शुरुआती स्प्लिट इस तरह हो सकता है: पुष्टि करने वाले टूल को ऑपरेंड/एट्रिब्यूट की जांच करने दें. इसके बाद, शेप फ़ंक्शन को सिर्फ़ अनुमानित नतीजों के टाइप का हिसाब लगाने दें और असली नतीजों के टाइप के साथ काम करने की जांच करने दें. हालांकि, असल में इस स्प्लिट में कुछ समस्याएं हैं:
- आकार फ़ंक्शन को, पुष्टि करने वाले को कॉल किए बिना, अपने-आप जनरेट होने वाले
build()
फ़ंक्शन से कॉल किया जा सकता है. इसलिए, मिलते-जुलते इनपुट की पुष्टि शेप फ़ंक्शन में भी की जानी चाहिए. - डुप्लीकेट कोड: उदाहरण के लिए, पुष्टि करने वाले टूल में हम ऑपरेटर पर कुछ प्रोसेस करते हैं और फिर बीच के लेवल पर मिलने वाले कुछ नतीजों की पुष्टि करते हैं. फिर आकार में दिए गए फ़ंक्शन बीच के ये नतीजे आखिरी नतीजों का पता लगाने में मदद करते हैं. इन इंटरमीडिएट नतीजों की दो बार गिनती होती है.
- रखरखाव का बोझ: किसी ऑप की पुष्टि करना दो अलग-अलग तरीकों में होता है.
इसका समाधान इस तरह से है:
बिना क्षेत्र वाले ज़्यादातर ऑपरेशन के लिए (जैसे कि
PadOp
): पुष्टि करने वाले सभी कोड को शेप फ़ंक्शन में डालने की कोशिश करें और पुष्टि करने वाले सभी फ़ंक्शन को पूरी तरह खारिज करें. जिन मामलों में, रिटर्न टाइप का अनुमान न लगा पाने की वजह से ऐसा करना मुमकिन नहीं है (जैसे किReshapeOp
याBroadcastInDimOp
के साथ), वहां पुष्टि करने के लिए ज़रूरी लॉजिक शामिल करें. आम तौर पर, अनुमान लगाए जा सकने वाले ऑपरेशन, जैसे किAddOp
को और पुष्टि करने के लिए, अब भी पुष्टि करने वाले टूल की ज़रूरत पड़ सकती है. ऐसा इसलिए होता है, क्योंकि वे उपलब्ध कराए गए रिटर्न टाइप से जुड़ी पाबंदियों की पुष्टि कर रहे होते हैं, जिसे टाइप/आकार अनुमान के तरीकों से ऐक्सेस नहीं किया जा सकता.क्षेत्रों के साथ ऑपरेशन के लिए (जैसे कि
ReduceOp/IfOp
; पूरी सूची यहां है): अपने-आप जनरेट होने वाले बिल्डर, क्षेत्रों को पैरामीटर के तौर पर नहीं लेते हैं. इसलिए, अगर इन बिल्डर में टाइप अनुमान शामिल है, तो आकार फ़ंक्शन को खाली क्षेत्रों के साथ कॉल किया जाएगा (यह उदाहरण देखें).अगर टाइप अनुमान (जैसे कि
ReduceOp
) के लिए, क्षेत्रों की ज़रूरत नहीं है, तो शेप फ़ंक्शन के बजाय, इलाके से जुड़े पुष्टि करने वाले लॉजिक को पुष्टि करने वाले तरीके में रखें. अगर ज़रूरी हो, तो किसी कोड का डुप्लीकेट बनाएं.अगर टाइप अनुमान (
IfOp/CaseOp/MapOp
) के लिए क्षेत्रों की ज़रूरत है, तो इसके अलावा आकार फ़ंक्शन को इस बात की पुष्टि करनी होगी कि क्षेत्र खाली नहीं हैं. हालांकि, हो सकता है कि ओडीएस, पहले से ही ओपी डेफ़िनिशन में इसके मौजूद होने की गारंटी दे.
(P4) टेस्टिंग से जुड़े दिशा-निर्देश तय करना
क्या हमें पुष्टि करने के लिए उन टेस्ट को जोड़ना या उनका रखरखाव करना होगा जो ओडीएस की मदद से कवर किए गए हैं?
हमारे पास ऐसा नहीं है. टेस्ट, पुष्टि करने वाले और आकार के फ़ंक्शन पर फ़ोकस करना चाहिए, जबकि ओडीएस में किए जाने वाले बदलावों को इस विकल्प पर फिर से गौर करना चाहिए.
हालांकि, जो चीज़ें मौजूद नहीं हैं उनके बारे में सावधानी बरतें: उदाहरण के लिए, अगर ऑप में
एट्रिब्यूट SameOperandsAndResultShape
है, जो सिर्फ़ आकार की जांच करता है,
लेकिन एलिमेंट टाइप की नहीं, तो एलिमेंट टाइप के ऑपरेंड/नतीजों की पुष्टि के लिए अब भी
टेस्ट की ज़रूरत होती है.
हम पुष्टि करने वाले लोगों और टाइप के अनुमान के लिए, टेस्ट कहां करते हैं?
ops_stablehlo.mlir में ऑपरेशन के पॉज़िटिव केस शामिल होते हैं. साथ ही, इसमें (कम से कम) पुष्टि की हर गड़बड़ी के लिए एक नेगेटिव टेस्ट होता है. इससे यह भी पता चलता है कि अनुमानित रिटर्न टाइप, असली नतीजे के टाइप के साथ काम करता है (जैसा नहीं है!).
infer_stablehlo.mlir, hlo_test_infer.get_return_type_components"(%x):...
के साथ लाइन में
ऑप के आकार फ़ंक्शन की मौजूदगी की पुष्टि करता है और यह जांच करता है कि
तय किया गया टाइप, उम्मीद के मुताबिक मेल खाता है या नहीं. आम तौर पर, हर ऑपर्च्यूनिटी के लिए एक पॉज़िटिव टेस्ट.
क्या करें
किसी ऑपरेटर की पुष्टि करने वाले और/या आकार फ़ंक्शन को लागू करते समय या उसे फिर से लागू करते समय:
सभी पॉज़िटिव केस और नेगेटिव केस को ops_stablehlo.mlir में डालें.
इंटरफ़ेस की जांच करने के लिए, infer_stablehlo.mlir में एक पॉज़िटिव टेस्ट जोड़ें.
(ज़रूरी नहीं) अगर कोई ऑपर्च्यूनिटी मुश्किल है और उसमें कई टेस्ट शामिल हो सकते हैं, तो उसी फ़ोल्डर में
verify_<op_name>.mlir
याverify_<your_topic>.mlir
नाम की अलग-अलग टेस्ट फ़ाइल जोड़ें.