XLA-Tools verwenden

Im Mittelpunkt des XLA-Entwicklungsworkflows HLO IR, was eine isolierte Funktionseinheit darstellt dem Compiler übergebene Berechnung. XLA bietet mehrere Befehlszeilentools (siehe unten), die HLO verbrauchen und entweder ausführen oder ein in der Zwischenkompilierungsphase. Der Einsatz solcher Tools ist für eine schnelle compile->modify->run-Iterationszyklus, da HLO sowohl visualisiert und iterativ geändert und ausgeführt wird, ist oft der schnellste Weg, die Leistung oder das Verhalten von XLA zu verstehen und zu beheben.

Die einfachste Möglichkeit, das HLO für ein mit XLA kompiliertes Programm zu erhalten, ist wird in der Regel die Umgebungsvariable XLA_FLAGS verwendet:

$ XLA_FLAGS=--xla_dump_to=/tmp/myfolder ./myprogram-entry-point

das alle HLO-Dateien vor der Optimierung im angegebenen Ordner speichert, zusammen mit mit vielen anderen nützlichen Artefakten.

Laufende HLO-Snippets: run_hlo_module

Das Tool run_hlo_module wird auf HLO vor der Optimierung ausgeführt und ist standardmäßig Pakete mit dem Referenzinterpreter kompilieren, ausführen und vergleichen Implementierung. Der übliche Aufruf zum Ausführen einer Eingabedatei computation.hlo auf einer NVIDIA-GPU und überprüft sie auf ihre Richtigkeit:

$ run_hlo_module --platform=CUDA --reference_platform=Interpreter computation.hlo

Wie bei allen Tools kann --help verwendet werden, um die vollständige Liste der Optionen abzurufen.

HLO-Snippets mit SPMD-Unterstützung ausführen: multihost_hlo_runner

Multihost HLO Runner ist ein sehr ähnliches Tool, unterstützt jedoch SPMD, einschließlich hostübergreifender Kommunikation. Weitere Informationen finden Sie unter Multi-Host HLO Runner (HLO-Runner mit mehreren Hosts).

Multi-HLO-Wiedergabe

Aufrufe mit mehreren Modulen werden sowohl für run_hlo_module als auch hlo_runner_main: Dies ist oft praktisch, um alle Module in einem Dump wiederzugeben. Verzeichnis:

$ hlo_runner_main /dump/*before_optimizations*

Laufende Pässe/Phasen der HLO-Kompilierung: hlo-opt

Bei der Fehlerbehebung oder beim Verständnis der Funktionsweise des Compilers ist dies oft nützlich. um die Erweiterung für eine bestimmte Hardware an einem bestimmten Punkt im (HLO, optimiertes HLO, TritonIR oder LLVM) für ein bestimmtes (stabiles) HLO Eingabe.

hlo-opt unterstützt mehrere Ausgabephasen: PTX, HLO nach Optimierungen, LLVM IR vor Optimierungen oder TritonIR. Der genaue Satz unterstützter Phasen hängt von der Plattform ab (z.B. ist PTX NVIDIA-spezifisch) und kann mit den Befehl --list-stages:

$ hlo-opt --platform=CUDA --list-stages
hlo
llvm
ptx

Nach der Auswahl einer Phase kann der Nutzer das Ergebnis der Conversion für eine einer bestimmten Plattform einem bestimmten Stream zu:

$ hlo-opt myinput.hlo --platform=CUDA --stage=llvm

wodurch der Dump nach stdout ausgegeben wird (oder in eine bestimmte Datei, wenn -o angegeben wurde).

Gerätelose Nutzung

Für den Großteil der Kompilierung ist kein Zugriff auf eine GPU erforderlich. Außerdem wird durch Angabe eines GPU-Spezifikation in der Befehlszeile, die wir erhalten können, z.B. PTX-Ausgabe ohne Zugriff auf Beschleuniger:

$ hlo-opt  --platform=CUDA --stage=llvm  --xla_gpu_target_config_filename=(pwd)/tools/data/gpu_specs/a100_pcie_80.txtpb input.hlo

Spezifikationen für beliebte GPUs werden mit dem Compiler geliefert. Die bereitgestellte Datei wird String-Serialisierung von 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"

Bei der gerätelosen Kompilierung können Probleme auftreten, wenn eine automatische Abstimmung erforderlich ist. Glücklicherweise können wir diese auch in der Befehlszeile angeben:

$ 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

Die Autotune-Datei ist die Textserialisierung von autotune_results.proto mit Beispiel wie folgt aus:

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
    }
  }
}

Die Autotuning-Datenbank kann mit XLA_FLAGS=--xla_gpu_dump_autotune_results_t=<myfile.pbtxt>

Einzelnen Compiler-Pass ausführen

Die Flags von XLA_FLAGS werden ebenfalls unterstützt, sodass das Tool zum Testen einer einzelnen Karte / eines einzelnen Tickets:

$ hlo-opt --platform=CUDA --stage=hlo --xla-hlo-enable-passes-only=algebraic_simplifer input.hlo