2025, Sep 26 03:34
NumPy के _multiarray_umath shared मॉड्यूल को स्रोत तक ट्रेस करें
जानें NumPy के _multiarray_umath .so को Meson introspect से स्रोत तक ट्रेस करना: concatenate/inner कहाँ परिभाषित हैं, कौन-सी C/CPP व जनरेटेड फाइलें शामिल हैं
NumPy के कोर में झांकते समय जब concatenate या inner जैसी फ़ंक्शनों के लिए साधारण Python फ़ाइल नहीं मिलती, तो यह लगभग हर उपयोगकर्ता के लिए एक परिचित पड़ाव होता है। वजह सीधी है: ये फ़ंक्शन .py नहीं, बल्कि .so के रूप में आने वाले संकलित shared मॉड्यूल को कॉल करते हैं। वह फ़ाइल क्या है, वह कहाँ से आती है और उसे स्रोत तक कैसे ट्रेस किया जाए—यह समझ लेने से NumPy के आंतरिक हिस्सों को पढ़ना और डिबग करना काफी कम रहस्यमय हो जाता है।
गड़बड़ी कहाँ से शुरू होती है
numpy/_core/multiarray.py में आपको कोर API एक सामान्य-से relative import के जरिए सजाए और जोड़े हुए दिखेंगे। लेकिन उसके पास कोई _multiarray_umath.py मौजूद नहीं है। इसकी जगह, NumPy numpy/_core के भीतर _multiarray_umath.cpython-313-x86_64-linux-gnu.so नाम का एक बाइनरी इंस्टॉल करता है। यही .so वास्तव में from . import _multiarray_umath के द्वारा इम्पोर्ट किया जाने वाला मॉड्यूल है।
ऐसा सबसे छोटा कोड जो बाइंडिंग दिखा दे
आप यह पक्का कर सकते हैं कि Python एक बाइनरी shared मॉड्यूल इम्पोर्ट कर रहा है और वह कहाँ स्थित है। तर्क सादा है: मॉड्यूल इम्पोर्ट करें और उसकी मेटाडेटा जाँच लें।
import importlib
ua_handle = importlib.import_module('numpy._core._multiarray_umath')
print(type(ua_handle).__name__)
print(getattr(ua_handle, '__file__', 'no-file-attr'))
यह दिखाता है कि इम्पोर्ट एक shared मॉड्यूल (.so) पर सुलझता है और numpy/_core के भीतर उसका डिस्क-पथ क्या है।
.so वास्तव में क्या है
यह .so एक shared मॉड्यूल है, जिसे numpy/_core/src में फैली करीब सौ C और C++ स्रोत फ़ाइलों से संकलित किया गया है—जिनमें multiarray और umath जैसी उप-डायरेक्टरियाँ भी शामिल हैं। इनमें से कुछ स्रोत फाइलें जनरेटेड C फाइलें होती हैं, हाथ से लिखी हुई नहीं। पूरा बिल्ड NumPy की Meson कॉन्फ़िगरेशन से परिभाषित और नियंत्रित होता है।
यह ठीक-ठीक कैसे बनता है, यह कैसे देखें
समझने का सबसे सीधा तरीका है कि NumPy को स्रोत से बिल्ड करें और फिर Meson के जरिए बिल्ड ग्राफ का इंट्रोस्पेक्ट करें। कॉन्फ़िगर करने के बाद आप शीर्ष-स्तरीय टार्गेट्स का मशीन-पठनीय विवरण निकाल सकते हैं:
meson introspect --targets -i build/ > targets.json
targets.json में _multiarray_umath टार्गेट खोजें। वहाँ एक प्रविष्टि मिलेगी जो बताती है कि यह एक shared मॉड्यूल है, यह कहाँ परिभाषित है, कहाँ इंस्टॉल होता है, और इसमें कौन-सी स्रोत तथा जनरेटेड स्रोत फ़ाइलें शामिल हैं। एक प्रतिनिधि अंश इस तरह दिखेगा:
{
  "name": "_multiarray_umath.cpython-313-x86_64-linux-gnu",
  "type": "shared module",
  "defined_in": "/home/user/numpy/numpy/_core/meson.build",
  "filename": [
    "/home/user/numpy/build/numpy/_core/_multiarray_umath.cpython-313-x86_64-linux-gnu.so"
  ],
  "target_sources": [
    {
      "language": "c",
      "sources": [
        "/home/user/numpy/numpy/_core/src/multiarray/arrayobject.c",
        "/home/user/numpy/numpy/_core/src/multiarray/multiarraymodule.c",
        "/home/user/numpy/numpy/_core/src/umath/umathmodule.c"
      ],
      "generated_sources": [
        "/home/user/numpy/build/numpy/_core/_multiarray_umath.cpython-313-x86_64-linux-gnu.so.p/arraytypes.c",
        "/home/user/numpy/build/numpy/_core/_multiarray_umath.cpython-313-x86_64-linux-gnu.so.p/einsum.c"
      ]
    },
    {
      "language": "cpp",
      "sources": [
        "/home/user/numpy/numpy/_core/src/umath/clip.cpp",
        "/home/user/numpy/numpy/_core/src/umath/string_ufuncs.cpp"
      ]
    }
  ],
  "dependencies": ["openblas", "python-3.13"],
  "install_filename": [
    "/usr/lib/python3.13/site-packages/numpy/_core/_multiarray_umath.cpython-313-x86_64-linux-gnu.so"
  ]
}
इससे दो बातें साफ़ हो जाती हैं। पहली, मॉड्यूल numpy/_core/meson.build में परिभाषित है। दूसरी, हाथ से लिखी C/C++ फाइलों के साथ-साथ इसमें generated_sources के तहत सूचीबद्ध जनरेटेड C फाइलें भी शामिल हैं। ये जनरेटेड फाइलें आम तौर पर .c.src टेम्पलेट्स से आती हैं। हालांकि, Meson का introspection यहाँ उनके generation स्टेप के विवरण नहीं दिखाता।
ट्री में स्रोतों को ट्रेस करना
यदि आप संबंधित कोड देखना चाहते हैं, तो सीधे numpy/_core/src पर जाएँ। इसी डायरेक्टरी में वे C और C++ इम्प्लीमेंटेशन हैं जो आपके द्वारा इम्पोर्ट किए जाने वाले shared मॉड्यूल में संकलित होते हैं। यहाँ multiarray और umath जैसी उप-डायरेक्टरियाँ मिलेंगी। Python लेयर में vstack जैसे Python शिम्स ढूँढना आसान है, पर concatenate या inner को C लेयर तक फॉलो करने का मतलब इन C/C++ स्रोतों को पढ़ना है—और कुछ जगहों पर बिल्ड के दौरान जनरेट हुई C फाइलों को भी।
समाधान का रास्ता: इंट्रोस्पेक्ट करें और Meson की परिभाषाएँ पढ़ें
व्यावहारिक वर्कफ़्लो यही है: NumPy को स्रोत से बिल्ड करें और ऊपर दिखाए अनुसार Meson से बिल्ड का इंट्रोस्पेक्ट करें। फिर _multiarray_umath मॉड्यूल कैसे बना है, इसका सटीक विवरण पाने के लिए उसे घोषित करने वाले Meson नियम पढ़ें। मॉड्यूल का बिल्ड-वर्णन NumPy की Meson कॉन्फ़िगरेशन में ही रहता है और बताता है कि कौन-सी स्रोत और जनरेटेड फाइलें साथ में बंडल होती हैं और वे कैसे संकलित की जाती हैं। इसे यहाँ देख सकते हैं: numpy/_core/meson.build.
यह मेंटेनर्स और उन्नत उपयोगकर्ताओं के लिए क्यों मायने रखता है
यह समझना कि NumPy की कोर API एक बड़े संकलित shared मॉड्यूल के ऊपर पतली Python परतें हैं, यह स्पष्ट कर देता है कि प्रदर्शन-महत्वपूर्ण कार्यों के लिए आपको शुद्ध Python बॉडी क्यों नहीं मिलती। साथ ही यह भी साफ़ हो जाता है कि व्यवहार का ऑडिट करना हो, लो-लेवल समस्याएँ डिबग करनी हों, CPU फीचर फ्लैग्स को समझना हो, या यह देखना हो कि जनरेटेड कोड अंतिम बाइनरी में कैसे शामिल होता है—तो कहाँ देखना चाहिए। Meson का introspection आउटपुट इम्पोर्ट होने योग्य .so से उसके स्रोतों, कंपाइलर फ्लैग्स और लिंक निर्भरताओं तक पहुँचने का भरोसेमंद नक्शा देता है।
समापन
यदि किसी कोर NumPy फ़ंक्शन की .py फ़ाइल नहीं मिल रही, तो मान लें कि वह numpy/_core में मौजूद किसी shared मॉड्यूल से समर्थित है। Python में इम्पोर्ट और पथ की पुष्टि करें, फिर स्रोत से बिल्ड करें और meson introspect --targets -i build/ चलाकर ठीक-ठीक किन स्रोतों और जनरेटेड स्रोतों से _multiarray_umath बनता है, यह सूचीबद्ध कर लें। संदेह होने पर numpy/_core/meson.build खोलें और परिभाषाएँ देखें। यह तरीका आपको उसी पर टिकाए रखता है जो वास्तव में संकलित और इंस्टॉल होता है, और उच्च-स्तरीय API से उसके नीचे की C और C++ इम्प्लीमेंटेशनों तक बिना अटकलों के पहुँचने में मदद करता है।
यह लेख StackOverflow पर प्रश्न (लेखक: user90189) और Nick ODell के उत्तर पर आधारित है।