टाइप का अनुमान

StableHLO को मूल रूप से एमएचएलओ भाषा से बूटस्ट्रैप किया गया था और इसने टाइप अनुमान के एमएचएलओ को लागू करने की प्रक्रिया को इनहेरिट किया. लागू होने की स्थिति को status.md में ट्रैक किया जाता है.

नीचे दिए गए दिशा-निर्देशों का मकसद यह पक्का करना है कि StableHLO ऑपरेशन के लिए, अच्छी क्वालिटी की पुष्टि करने वाले और आकार देने वाले फ़ंक्शन लागू किए जाएं.

प्रस्ताव

ये प्रस्ताव, लागू किए गए मौजूदा तरीकों को फिर से लागू करने और व्यापक कवरेज तक नए ऑपरेशन हासिल करने पर लागू होते हैं.

(P1) StableHLO स्पेसिफ़िकेशन का इस्तेमाल, सच्चाई के सोर्स के तौर पर करना

StableHLO ऑपरेशन के सभी पुष्टि करने वाले और आकार फ़ंक्शन के लिए, spec ही सबसे सही जानकारी है. हर ऑपरेटर के मौजूदा पुष्टि करने वाले और आकार फ़ंक्शन को फिर से देखना होगा, ताकि निर्देशों को पूरी तरह से अलाइन किया जा सके. ध्यान दें कि स्पेसिफ़िकेशन से जुड़े दस्तावेज़ में बदलाव होते रहते हैं. ऐसे मामलों में जहां ऑपर्च्यूनिटी की खास जानकारी उपलब्ध न हो, XLA लागू करने के तरीके का इस्तेमाल सही जानकारी के तौर पर किया जाना चाहिए. इसमें xla/service/shape_inference.cc और xla/service/hlo_verifier.cc शामिल हैं. XLA लागू करने में, अनबाउंड डायनेमिज़्म शामिल नहीं है. इसलिए, बिना दायरे वाली गतिविधि के लिए, हम डाइनैमिक तौर पर आरएफ़सी उपलब्ध होने तक सामान्य सेंसेटिव का इस्तेमाल करेंगे.

(P2) ODS का पूरा फ़ायदा पाएं

ODS फ़ाइलें (जैसे StablehloOps.td) हर ऑपरेंड/एट्रिब्यूट/नतीजे के लिए विशेषता और टाइप के साथ ऑपरेशन को परिभाषित करती हैं और पुष्टि करेंगी. इसलिए, पहले से ही ओडीएस की मदद से गारंटी देने वाले प्रॉपर्टी के पुष्टि करने वाले या आकार फ़ंक्शन में, पुष्टि करने के लिए किसी कोड की ज़रूरत नहीं होती. अगर ODS के साथ डुप्लीकेट कोड बनाया गया है, तो पुष्टि करने का कोड हटा दें. ऐसा करना कभी भी ट्रिगर नहीं होगा.

क्या हमें ODS से, कंस्ट्रेंट के लिए टेस्ट जोड़ने की ज़रूरत है? कृपया जांच करने के दिशा-निर्देश बनाएं देखें.

(P3) पुष्टि करने वाले टूल और आकार वाले फ़ंक्शन में, पुष्टि करने के कोड को बनाए रखना

दोनों:

  • पुष्टि करने वाले: Op::verify() ने लागू किया, और
  • आकार फ़ंक्शन: Op::inferReturnTypes() या Op::inferReturnTypeComponents जैसे InferTypeOpInterface की मदद से लागू किया जाता है

में ऑपरेंड/एट्रिब्यूट/नतीजे देखने के लिए पुष्टि करने वाला कोड हो सकता है. शुरुआती स्प्लिट इस तरह हो सकता है: पुष्टि करने वाले लोगों को ऑपरेंड/एट्रिब्यूट की जांच करने दें. इसके बाद, आकार फ़ंक्शन को सिर्फ़ अनुमानित नतीजों के टाइप कैलकुलेट करने दें और यह पता करने दें कि असल नतीजों के टाइप के साथ काम करता है या नहीं. हालांकि, असल में इस विभाजन में कुछ समस्याएं हैं:

  • आकार फ़ंक्शन को, पुष्टि करने वाले को कॉल किए बिना, अपने-आप जनरेट हुए build() फ़ंक्शन से कॉल किया जा सकता है. इसलिए, संबंधित इनपुट का आकार फ़ंक्शन में भी पुष्टि किया जाना ज़रूरी है.
  • डुप्लीकेट कोड: उदाहरण के लिए, पुष्टि करने वाले टूल में हम कुछ प्रोसेस करते हैं. इसके बाद, बीच के लेवल पर मिले कुछ नतीजों की पुष्टि करते हैं. फिर आकार में दिए गए फ़ंक्शन इन इंटरमीडिएट नतीजे आखिरी नतीजों का अनुमान लगाने के लिए उपयोगी होते हैं. इन इंटरमीडिएट नतीजों की गिनती दो बार करनी पड़ती है.
  • रखरखाव का बोझ: ऑपरेटर की पुष्टि दो अलग-अलग तरीकों से की जाती है.

इसका समाधान इस प्रकार है:

  1. बिना इलाके वाली ज़्यादातर ऑपरेशन के लिए (जैसे कि PadOp): पुष्टि करने वाले सभी कोड को शेप फ़ंक्शन में डालें और पुष्टि करने वाले सभी टूल को पूरी तरह खारिज कर दें.

  2. क्षेत्र वाले ऑपरेशन के लिए (जैसे कि ReduceOp/IfOp; पूरी सूची यहां दी गई है): अपने-आप जनरेट होने वाले बिल्डर, रीजन को पैरामीटर के तौर पर नहीं लेते हैं. इसलिए, अगर ये बिल्डर, टाइप अनुमान को शामिल करते हैं, तो आकार फ़ंक्शन को खाली क्षेत्रों के साथ कॉल किया जाएगा (यह उदाहरण देखें).

    1. अगर टाइप के अनुमान (जैसे कि ReduceOp) के लिए क्षेत्रों की ज़रूरत नहीं है, तो आकार के फ़ंक्शन के बजाय, इलाके से जुड़े पुष्टि करने के लॉजिक को पुष्टि करने वाले टूल में रखें. अगर ज़रूरी हो, तो कुछ कोड के डुप्लीकेट बनाएं.

    2. अगर टाइप अनुमान (IfOp/CaseOp/MapOp) के लिए क्षेत्रों की ज़रूरत है, तो इसके अलावा आकार फ़ंक्शन को इस बात की पुष्टि करनी होगी कि क्षेत्र साफ़ तौर पर खाली नहीं हैं. भले ही, ओडीएस पहले से ही ओपी डेफ़िनिशन में इसके मौजूद होने की गारंटी दे सकता है.

(P4) जांच से जुड़े दिशा-निर्देश तय करें

क्या हमें ODS से कवर किए गए पुष्टि के लिए, टेस्ट जोड़ने/रखने की ज़रूरत है?

हमारे पास नहीं है. टेस्ट का फ़ोकस, पुष्टि करने वाले लोगों और आकार के फ़ंक्शन पर होना चाहिए, जबकि ओडीएस में किए जाने वाले बदलावों को इस ऑपर्च्यूनिटी पर फिर से गौर करना चाहिए.

हालांकि, मौजूद न होने वाले हिस्सों के बारे में सावधानी बरतें: उदाहरण के लिए, अगर ऑपरेटर में trait SameOperandsAndResultShape है, जो सिर्फ़ आकार की जांच करता है, न कि एलिमेंट टाइप की, तो एलिमेंट टाइप/नतीजों की पुष्टि के लिए अब भी जांच की ज़रूरत है.

हम पुष्टि करने वाले और टाइप के अनुमान के लिए टेस्ट कहां लगाते हैं?

ops_stablehlo.mlir इसमें ऑपरेशन के पॉज़िटिव केस शामिल होते हैं और पुष्टि की हर गड़बड़ी के लिए, कम से कम एक नेगेटिव टेस्ट होता है. इससे यह भी पता चलता है कि अनुमानित रिटर्न टाइप, असली नतीजे के टाइप के साथ काम करता है (जैसा कि नहीं है!).

infer_stablehlo.mlir hlo_test_infer.get_return_type_components"(%x):... की मदद से, लाइन के हिसाब से ऑपरेटर के आकार फ़ंक्शन के मौजूद होने की पुष्टि करता है. साथ ही, यह जांच करता है कि फ़र्ड टाइप, उम्मीद के मुताबिक मेल खाता है या नहीं. आम तौर पर, हर ऑपर्च्यूनिटी के लिए एक पॉज़िटिव टेस्ट.

आपको क्या करना होगा

किसी ऑपरेटर के पुष्टि करने वाले और/या आकार फ़ंक्शन को लागू करते समय या फिर से विज़िट करते समय:

  1. सभी पॉज़िटिव केस और नेगेटिव केस को ops_stablehlo.mlir में डालें.

  2. इंटरफ़ेस की जांच करने के लिए, infer_stablehlo.mlir में एक पॉज़िटिव टेस्ट जोड़ें.

  3. (ज़रूरी नहीं) अगर कोई ऑपरेटर जटिल है और उसमें कई टेस्ट शामिल हो सकते हैं, तो उसी फ़ोल्डर में verify_<op_name>.mlir या verify_<your_topic>.mlir नाम की अलग टेस्ट फ़ाइल जोड़ें.