कैटगरी: कंपाइल टाइम: मोज़ेक अनप्रूवन मेमोरी ऐक्सेस अलाइनमेंट
यह गड़बड़ी तब होती है, जब कंपाइलर मेमोरी ऐक्सेस करने की किसी कार्रवाई (जैसे कि vector.load, vector.store, tpu.load या tpu.store) का विश्लेषण करता है. साथ ही, वह यह पुष्टि नहीं कर पाता कि किसी डाइमेंशन के लिए इस्तेमाल किया गया डाइनैमिक इंडेक्स, ज़रूरी टाइलिंग साइज़ का मल्टीपल है.
गड़बड़ी के मैसेज के उदाहरण:
INTERNAL: Mosaic failed to compile TPU kernel: cannot statically prove that index in dimension 1 is a multiple of 128
at location: ...
The MLIR operation involved:
%14372 = "vector.load"(%14371, %93, %14363) : (memref<4x256xf32, #tpu.memory_space<vmem>>, index, index) -> vector<1x32xf32>
XLA बैकएंड: टीपीयू
खास जानकारी
जब आपका कर्नल किसी वेक्टर को लोड या सेव करता है, तो मेमोरी का पता (बेस पॉइंटर और डाइनैमिक इंडेक्स से कैलकुलेट किया गया) हार्डवेयर पर वेक्टर के टाइलिंग साइज़ के साथ अलाइन होना चाहिए. उदाहरण के लिए, अगर किसी डाइमेंशन को 128 एलिमेंट से टाइल किया गया है, तो उसे ऐक्सेस करने के लिए इस्तेमाल किया गया डाइनैमिक इंडेक्स 0, 128, 256 वगैरह होना चाहिए. ध्यान दें कि कई कार्रवाइयों (जैसे, वेक्टर लोड और स्टोर) के लिए, स्टैटिक इंडेक्स की ऐसी कोई ज़रूरत नहीं होती.
कंपाइलर, स्टैटिक विश्लेषण का इस्तेमाल करके इस ज़रूरी शर्त को लागू करता है. यह इंडेक्स वैरिएबल के इतिहास का पता लगाता है.इसके लिए, यह उन अंकगणितीय कार्रवाइयों का इस्तेमाल करता है जिनकी वजह से इंडेक्स वैरिएबल बना है. जैसे, गुणा करना, जोड़ना. अगर कंपाइलर, कंपाइल करने के समय यह पक्का नहीं कर पाता कि नतीजे के तौर पर मिलने वाली वैल्यू हमेशा टाइलिंग साइज़ से भाग दी जा सकेगी, तो वह यह गड़बड़ी दिखाता है.
कंपाइलर, "अलाइनमेंट की पुष्टि हो चुकी है" और "अलाइनमेंट की जानकारी नहीं है" को एक जैसा मानता है.
इसलिए, अगर आपने ऐसे इंडेक्स का इस्तेमाल किया है जो गणित के हिसाब से गलत है (जैसे,
i * 128 + 32) का इस्तेमाल किया जाता है, तो कंपाइलर वही गड़बड़ी दिखाएगा.
इसलिए, यह गड़बड़ी तब हो सकती है, जब
- मेमोरी को ऐक्सेस करने के लिए, रनटाइम वैरिएबल (डाइनैमिक इंडेक्स) का इस्तेमाल किया जाता है.
- इंडेक्स कैलकुलेशन का लॉजिक इतना जटिल है कि कंपाइलर उसका विश्लेषण नहीं कर सकता.
- यह इंडेक्स गणित के हिसाब से सही है, लेकिन कोड में इसका कोई सबूत नहीं है.
- स्टैटिक विश्लेषण से "पुष्टि की गई गड़बड़ी" का पता चलता है.
डीबग करना
इस गड़बड़ी को ठीक करने के लिए, आपके पास ये विकल्प हैं:
1. साफ़ तौर पर अलाइनमेंट की पुष्टि करना
अगर आपको पता है कि आपका इंडेक्स मान्य है, लेकिन कंपाइलर इसे साबित नहीं कर सकता, तो tpu.assume_multiple ऑपरेशन का इस्तेमाल करें. यह कंपाइलर से किया गया एक वादा है कि वैल्यू को किसी खास फ़ैक्टर से भाग दिया जा सकता है.
2. अलाइन किए गए लोड और घुमाने की सुविधा का इस्तेमाल करना
अगर जान-बूझकर अलाइनमेंट नहीं किया गया है, तो अलाइन न किए गए छोटे वेक्टर सेगमेंट को लोड करने के बजाय:
- बड़ी और पूरी तरह से अलाइन की गई टाइल लोड करें. इसके बाद, वैल्यू को डाइनैमिक तौर पर घुमाएं, ताकि मनचाहे डेटा को सही जगह पर ले जाया जा सके. ऐसा इसलिए, क्योंकि डाइनैमिक स्टार्ट इंडेक्स वाले वेक्टर स्लाइस काम नहीं करते. या
- टेंसर को फिर से आकार दें या पैड करें, ताकि डेटा इंडेक्स 0 से शुरू हो और ऐक्सेस के बीच का स्ट्राइड, हार्डवेयर अलाइनमेंट से मेल खाए.
- उदाहरण: अगर आपने ऑफ़सेट 1 से शुरू करके, 32 साइज़ के चंक पर बार-बार काम किया है, तो आपके ऑफ़सेट 1, 33, 65... होंगे (अलाइन नहीं किया गया).
- ठीक करें: डेटा को नए टेंसर में फिर से पैक करें. इसमें पहला हिस्सा 0 पर है और डाइमेंशन को 128 तक पैड किया गया है. आपके ऑफ़सेट 0, 128, 256... हो जाते हैं, जो अलाइनमेंट की ज़रूरी शर्त को पूरा करते हैं.
इन तरीकों में ज़्यादा मेमोरी का इस्तेमाल होता है. हालांकि, इनसे अक्सर कर्नल लॉजिक आसान हो जाता है और मैन्युअल अलाइनमेंट असर्शन की ज़रूरत नहीं पड़ती.