XLA डेवलपमेंट का वर्कफ़्लो आम तौर पर HLO IR पर आधारित होता है. यह कंपाइलर को दिए गए, अलग-अलग फ़ंक्शनल कंप्यूटेशन को दिखाता है. XLA में कई कमांड लाइन टूल (नीचे दिए गए हैं) शामिल होते हैं. ये HLO का इस्तेमाल करते हैं और इसे चलाते हैं या कंपाइल करने के इंटरमीडिएट स्टेज की जानकारी देते हैं. ऐसे टूल का इस्तेमाल, तेज़ी से compile->modify->runइटरेशन साइकल के लिए बहुत ज़रूरी है. ऐसा इसलिए, क्योंकि एचएलओ को विज़ुअलाइज़ किया जा सकता है और इसमें बदलाव किया जा सकता है. साथ ही, इसे बार-बार बदलना और चलाना, अक्सर XLA की परफ़ॉर्मेंस या व्यवहार को समझने और उसे ठीक करने का सबसे तेज़ तरीका होता है.
XLA के साथ कंपाइल किए जा रहे प्रोग्राम के लिए, एचएलओ पाने का सबसे आसान तरीका आम तौर पर XLA_FLAGS एनवायरमेंट वैरिएबल का इस्तेमाल करना होता है:
$ XLA_FLAGS=--xla_dump_to=/tmp/myfolder ./myprogram-entry-point
यह फ़ोल्डर, ऑप्टिमाइज़ेशन से पहले की सभी HLO फ़ाइलों को सेव करता है. साथ ही, इसमें कई अन्य काम की चीज़ें भी होती हैं.
[run_hlo_module] एचएलओ मॉड्यूल चलाना
bazel run //xla/tools:run_hlo_module -- [flags] <filename>
यह टूल run_hlo_module, प्री-ऑप्टिमाइज़ेशन एचएलओ पर काम करता है. साथ ही, डिफ़ॉल्ट रूप से बंडल कंपाइल करता है, उन्हें चलाता है, और रेफ़रंस इंटरप्रेटर के साथ तुलना करता है. उदाहरण के लिए, किसी इनपुट फ़ाइल को NVIDIA GPU पर चलाने और उसकी जांच करने के लिए, आम तौर पर इस कमांड का इस्तेमाल किया जाता है:
computation.hlo
run_hlo_module --platform=CUDA --reference_platform=Interpreter computation.hlo
एक से ज़्यादा HLO मॉड्यूल चलाना
run_hlo_module के लिए, एक से ज़्यादा एचएलओ मॉड्यूल के साथ इनवोकेशन की सुविधा उपलब्ध है. किसी डायरेक्ट्री से सभी एचएलओ मॉड्यूल चलाने के लिए:
bazel run //xla/tools:run_hlo_module -- [flags] /dump/*before_optimizations*
[multihost_hlo_runner] Run HLO Modules With SPMD Support
# Note: Binary name is `hlo_runner_main`.
bazel run //xla/tools/multihost_hlo_runner:hlo_runner_main -- [flags] <filename>
मल्टीहोस्ट एचएलओ रनर भी इसी तरह का टूल है. हालांकि, इसमें एसपीएमडी का इस्तेमाल किया जा सकता है. इसमें क्रॉस होस्ट कम्यूनिकेशन भी शामिल है. ज़्यादा जानकारी के लिए, एक से ज़्यादा होस्ट वाले एचएलओ रनर देखें.
एसपीएमडी की सुविधा के साथ एक से ज़्यादा एचएलओ मॉड्यूल चलाना
run_hlo_module की तरह, multihost_hlo_runner में भी एक साथ कई मॉड्यूल इस्तेमाल किए जा सकते हैं.
bazel run //xla/tools/multihost_hlo_runner:hlo_runner_main -- [flags] /dump/*before_optimizations*
[hlo-opt] कंपाइल एचएलओ मॉड्यूल
bazel run //xla/tools:hlo-opt -- --platform=[gpu|cpu|...] [more flags] <filename>
कंपाइलर की गड़बड़ी ठीक करते समय या उसके काम करने के तरीके को समझते समय, अक्सर यह जानना ज़रूरी होता है कि किसी दिए गए HLO या StableHLO इनपुट के लिए, पाइपलाइन (चाहे वह HLO, ऑप्टिमाइज़ किया गया HLO, TritonIR या LLVM हो) के किसी खास पॉइंट पर, किसी खास हार्डवेयर के लिए एक्सपैंशन क्या है.
hlo-opt कई आउटपुट स्टेज के साथ काम करता है: जैसे, PTX, ऑप्टिमाइज़ेशन के बाद HLO, ऑप्टिमाइज़ेशन से पहले LLVM IR या TritonIR. सपोर्ट किए गए चरणों का सटीक सेट, प्लैटफ़ॉर्म पर निर्भर करता है.उदाहरण के लिए, PTX सिर्फ़ NVIDIA के लिए है. इसे --list-stages कमांड का इस्तेमाल करके देखा जा सकता है:
hlo-opt --platform=CUDA --list-stages
buffer-assignment
hlo
hlo-backend
html
llvm
llvm-after-optimizations
llvm-before-optimizations
ptx
स्टेज चुनने के बाद, उपयोगकर्ता किसी दिए गए प्लैटफ़ॉर्म के लिए, किसी स्ट्रीम में कन्वर्ज़न का नतीजा लिख सकता है:
hlo-opt --platform=cpu --stage=hlo input.hlo
इससे डंप को stdout पर प्रिंट किया जाएगा. अगर -o तय किया गया था, तो डंप को दी गई फ़ाइल में प्रिंट किया जाएगा.
जीपीयू के लिए डिवाइस के बिना कंपाइल करना
डिवाइस के बिना कंपाइल करने के लिए, जीपीयू का ऐक्सेस ज़रूरी नहीं है. डिवाइस के बिना कंपाइल करने की सुविधा, उन चरणों के लिए कमांड लाइन (--xla_gpu_target_config_filename) पर जीपीयू स्पेसिफ़िकेशन तय करने का तरीका उपलब्ध कराती है जहां जीपीयू का ऐक्सेस ज़रूरी होता है. इससे जीपीयू डिवाइस की ज़रूरत खत्म हो जाती है.
उदाहरण: जीपीयू डिवाइस का ऐक्सेस न होने पर PTX आउटपुट:
hlo-opt --platform=CUDA --stage=llvm --xla_gpu_target_config_filename=/xla/tools/hlo_opt/gpu_specs/a100_pcie_80.txtpb input.hlo
लोकप्रिय जीपीयू के स्पेसिफ़िकेशन, कंपाइलर के साथ शिप किए जाते हैं. साथ ही, दी गई फ़ाइल, device_description.proto का स्ट्रिंग सीरियलाइज़ेशन है:
gpu_device_info {
cuda_compute_capability {
major: 8
minor: 0
}
threads_per_block_limit: 1024
threads_per_warp: 32
shared_memory_per_block: 127152
shared_memory_per_core: 65536
threads_per_core_limit: 2048
core_count: 6192
fpus_per_core: 64
block_dim_limit_x: 2147483647
block_dim_limit_y: 65535
block_dim_limit_z: 65535
memory_bandwidth: 2039000000000
l2_cache_size: 4194304
clock_rate_ghz: 1.1105
device_memory_size: 79050250240
}
platform_name: "CUDA"
जीपीयू की ज़्यादा जानकारी /xla/tools/hlo_opt/gpu_specs पर उपलब्ध है
ऑटोट्यूनिंग
कभी-कभी कंपाइलेशन में, कंपाइलेशन --stage के आधार पर ऑटो ट्यूनिंग शामिल हो सकती है.
बिना डिवाइस के कंपाइल करने की सुविधा का इस्तेमाल करने के लिए, उपयोगकर्ता को
ऑटोट्यूनिंग की सुविधा बंद करनी होगी. इसके लिए, --xla_gpu_autotune_level=0
या
पहले से मौजूद ऑटोट्यूनिंग के नतीजे लोड करने होंगे. इसके लिए, --xla_gpu_load_autotune_results_from=<filename> (--xla_gpu_dump_autotune_results_to=<filename> से मिले) का इस्तेमाल करना होगा.
hlo-opt --platform=CUDA --stage=llvm --xla_gpu_target_config_filename=gpu_specs/a100_pcie_80.txtpb --xla_gpu_load_autotune_results_from=results.textpb input.hlo
ऑटोट्यून फ़ाइल, autotune_results.proto का टेक्स्ट सीरियलाइज़ेशन है. इसका उदाहरण यहां दिया गया है:
version: 3
results {
device: "CUDA: 8.0, Cores: 108, GPU clock: 1.41 GHz, Memory bandwidth: 1555 GB/s, L2 cache: 40 MB"
hlo: "{\n tmp_0 = f16[1,16,17,3]{3,2,1,0} parameter(0)\n tmp_1 = f16[16,51]{1,0} bitcast(f16[1,16,17,3]{3,2,1,0} tmp_0)\n tmp_2 = s8[16,17,3]{2,1,0} parameter(1)\n tmp_3 = s8[51,16]{0,1} bitcast(s8[16,17,3]{2,1,0} tmp_2)\n tmp_4 = f16[51,16]{0,1} convert(s8[51,16]{0,1} tmp_3)\n tmp_5 = f16[16,16]{1,0} dot(f16[16,51]{1,0} tmp_1, f16[51,16]{0,1} tmp_4), lhs_contracting_dims={1}, rhs_contracting_dims={0}\n ROOT tmp_6 = f16[1,16,16]{2,1,0} bitcast(f16[16,16]{1,0} tmp_5)\n}"
result {
run_time {
nanos: 31744
}
triton {
block_m: 32
block_n: 32
block_k: 32
split_k: 1
num_stages: 1
num_warps: 4
}
}
}
ऑटोट्यूनिंग डेटाबेस को XLA_FLAGS=--xla_gpu_dump_autotune_results_to=<myfile.pbtxt> का इस्तेमाल करके क्रम से लगाया जा सकता है
[hlo-opt] एचएलओ पास डेवलपमेंट और डीबगिंग
# If you are working with hardware independent passes from the
# `xla/hlo/transforms/` directory, prefer light-weight version
# of the `hlo-opt` tool with fewer dependencies:
bazel run //xla/hlo/tools:hlo-opt -- [flags] <filename>
# Otherwise, for hardware independent and CPU, GPU passes use
# the same binary from "Compile HLO Modules" section above:
bazel run //xla/tools:hlo-opt -- [flags] <filename>
hlo-opt टूल की मदद से, किसी पास को अलग से एक्ज़ीक्यूट किया जा सकता है. इसके लिए, दिए गए प्लैटफ़ॉर्म के कंपाइलेशन स्टेज की ज़रूरत नहीं होती. इस आइसोलेशन से, इनपुट एचएलओ मॉड्यूल पर पास को तुरंत चलाने और गड़बड़ियों की असल वजह का पता लगाने में मदद मिलती है.
hlo-opt --passes=schedule-aware-collective-cse input.hlo
hlo-opt टूल में भी DebugOptions XLA_FLAGS का इस्तेमाल किया जा सकता है.
hlo-opt --passes=schedule-aware-collective-cse
--xla_gpu_experimental_collective_cse_distance_threshold=20 input.hlo
पास का नाम स्ट्रिंग पाने के लिए, --list-passes विकल्प का इस्तेमाल करें.
hlo-opt --list-passes
उपयोगकर्ता, --passes विकल्प में एक से ज़्यादा पास तय करके, अपनी पसंद के मुताबिक कस्टम पाइपलाइन बना सकते हैं.
hlo-opt --passes=pass1,pass2,pass3 input.hlo
नए HLO पास को डेवलप करने में मदद करना
- सबसे पहले, अपना पास लिखें.
नए पास को
hlo-optटूल पास रजिस्ट्री में रजिस्टर करें.RegisterPass<FooPass>(FooPassInputOptions)पास के टाइप के आधार पर, रजिस्ट्रेशन के लिए इनमें से कोई एक जगह चुनें:
opt_lib.ccहार्डवेयर पर निर्भर न रहने वाले पास.
cpu_opt.ccसीपीयू के हिसाब से पास.
gpu_opt.ccजीपीयू के हिसाब से पास.
compiled_opt.ccसीपीयू, जीपीयू, और एक्सपीयू के लिए सामान्य पास.
बिल्ड डिपेंडेंसी जोड़ना न भूलें.पास के रजिस्ट्रेशन को अपने पीआर(उदाहरण) में शामिल करें, ताकि पास का इस्तेमाल सभी
hlo-optउपयोगकर्ता कर सकें.hlo-optटूल को फिर से बनाएं.--list-passesविकल्प का इस्तेमाल करके, पास के रजिस्ट्रेशन की पुष्टि करें. इसके बाद, पास चलाने के लिए--passesविकल्प का इस्तेमाल करें.$ hlo-opt --passes=foo-pass input.hloक्या आपको पास के लिए यूनिट टेस्ट लिखनी हैं? ज़्यादा जानकारी के लिए, https://openxla.org/xla/test_hlo_passes पर जाएं.
रनटाइम मेज़रमेंट पास करें
बड़े मॉडल के लिए, पूरे कंपाइलेशन को पूरा होने में कुछ मिनट लग सकते हैं. इससे परफ़ॉर्मेंस में मामूली गिरावट का पता लगाना मुश्किल हो जाता है. इसके उलट, hlo-opt का इस्तेमाल करके अलग-अलग पास चलाने से, परफ़ॉर्मेंस को सटीक तरीके से मेज़र किया जा सकता है. साथ ही, कोड में हुए नए बदलावों की वजह से, एक्ज़ीक्यूशन टाइम में हुई थोड़ी सी बढ़ोतरी का भी आसानी से पता लगाया जा सकता है.
time hlo-opt --passes=reduce-window-rewriter,scatter_simplifier
--xla_reduce_window_rewrite_base_length=128 input.hlo
[hlo-opt] Convert HLO Module Formats
# Use the light weight version of the `hlo-opt` tool.
bazel run //xla/hlo/tools:hlo-opt -- [flags] <filename>
HLO Text -> HLO Proto को बदलें
hlo-opt --emit-proto input.hlo
HLO Proto या HLO Proto Binary -> HLO Text में बदलें
hlo-opt input.pbtxt or input.pb
[ptx-opt] कंपाइलर LLVM मॉड्यूल से PTX तक
यह टूल, LLVMIR ऑप्टिमाइज़ेशन पाइपलाइन को चलाएगा. इसके बाद, CompileToPtx को कॉल करेगा.
bazel run //xla/hlo/tools/ptx-opt -- --arch=9.0 <filename>
यह टूल, हर पाथ के बाद LLVMIR को डंप भी कर सकता है.
bazel run //xla/hlo/tools/ptx-opt -- --arch=9.0 --xla_dump_to=<path> --xla_gpu_dump_llvmir <filename>
[isolate_hlo] समस्या पैदा करने वाले एचएलओ निर्देशों की पहचान करना
अगर आपके पास बहुत बड़ा एचएलओ डंप है और आपको लगता है कि एचएलओ मॉड्यूल में मौजूद किसी खास निर्देश या सेक्शन की वजह से क्रैश हो रहा है, तो isolate_hlo टूल का इस्तेमाल किया जा सकता है.
यह टूल, एक HLO निर्देश (और उसके ज़रूरी कॉन्टेक्स्ट) को एक नए और छोटे HLO मॉड्यूल में बदलता है. यह कंपाइलर-लेवल पर कम से कम जानकारी वाला रिप्रोड्यूसर बनाने में बहुत मददगार है.
- दस्तावेज़ और सोर्स:
isolate_hloटूल, OpenXLA रिपॉज़िटरी में उपलब्ध है. XLA के सोर्स कोड मेंxla/toolsडायरेक्ट्री देखें. इस्तेमाल करने का तरीका: XLA सोर्स ट्री से टूल बनाएं. आम तौर पर, इसमें इनपुट HLO मॉड्यूल फ़ाइल (टेक्स्ट या प्रोटो), निकालने के लिए निर्देश का नाम, और आउटपुट फ़ाइल का पाथ लगता है.
# Example usage after building XLA: # ./build/tools/isolate_hlo --input=module.hlo --instruction_name=fusion.123 \ # --output=isolated_fusion.123.hlo --input_format=txt --output_format=long_txtखास फ़्लैग और फ़ॉर्मैट के विकल्पों के लिए, टूल के सहायता मैसेज (
--help) देखें.