Quy trình phát triển XLA thường tập trung vào
HLO IR, biểu thị chức năng tách biệt
tính toán được cung cấp cho trình biên dịch. XLA đi kèm với nhiều công cụ dòng lệnh
(được mô tả bên dưới) sử dụng HLO và chạy nó hoặc cung cấp
giai đoạn biên dịch trung gian. Việc sử dụng các công cụ này là vô giá đối với
Chu kỳ lặp lại compile->modify->run
, vì HLO vừa có thể trực quan vừa
dễ xâm nhập cũng như thay đổi và chạy lặp đi lặp lại thường là cách nhanh nhất để
hiểu và khắc phục hiệu suất hoặc hành vi của XLA.
Cách dễ nhất để có được HLO cho một chương trình được biên dịch bằng XLA là
thường sử dụng biến môi trường XLA_FLAGS
:
$ XLA_FLAGS=--xla_dump_to=/tmp/myfolder ./myprogram-entry-point
kho lưu trữ tất cả tệp HLO trước khi tối ưu hoá trong thư mục được chỉ định, cùng với cùng nhiều cấu phần phần mềm hữu ích khác.
Đoạn mã HLO đang chạy: run_hlo_module
Công cụ run_hlo_module
hoạt động dựa trên HLO trước khi tối ưu hoá và theo mặc định
biên dịch, chạy và so sánh gói với trình phiên dịch tham chiếu
trong quá trình triển khai. Ví dụ: lệnh gọi thông thường để chạy tệp đầu vào
computation.hlo
trên GPU NVIDIA và kiểm tra tính chính xác của GPU là:
$ run_hlo_module --platform=CUDA --reference_platform=Interpreter computation.hlo
Tương tự như với tất cả các công cụ, bạn có thể sử dụng --help
để lấy danh sách đầy đủ các tuỳ chọn.
Chạy đoạn mã HLO có hỗ trợ SPMD: multihost_hlo_runner
Trình chạy HLO của Multihost là một công cụ rất tương tự, nhưng kèm theo cảnh báo là công cụ này hỗ trợ SPMD, bao gồm cả giao tiếp giữa nhiều máy chủ. Xem Trình chạy HLO nhiều máy chủ để biết thông tin chi tiết.
Phát lại nhiều HLO
Lệnh gọi qua nhiều mô-đun được hỗ trợ cho cả run_hlo_module
và
hlo_runner_main
, thường thuận tiện để phát lại tất cả các mô-đun trong một tệp kết xuất
thư mục:
$ hlo_runner_main /dump/*before_optimizations*
Chạy/các giai đoạn trong quá trình biên dịch HLO: hlo-opt
Khi gỡ lỗi hoặc hiểu hoạt động của trình biên dịch, mã này thường hữu ích để có được mở rộng cho một phần cứng cụ thể tại một điểm cụ thể trong quy trình (có thể là HLO, HLO được tối ưu hoá, TritonIR hoặc LLVM), cho một HLO (Ổn định) nhất định đầu vào.
hlo-opt
hỗ trợ nhiều giai đoạn đầu ra: có thể là PTX, HLO sau khi tối ưu hoá,
LLVM IR trước khi tối ưu hoá, hoặc TritonIR. Tập hợp chính xác các giai đoạn được hỗ trợ
phụ thuộc vào nền tảng (ví dụ: PTX dành riêng cho NVIDIA) và có thể được xem bằng
lệnh --list-stages:
$ hlo-opt --platform=CUDA --list-stages
hlo
llvm
ptx
Sau khi chọn một giai đoạn, người dùng có thể viết kết quả chuyển đổi cho nền tảng cụ thể đến một luồng nhất định:
$ hlo-opt myinput.hlo --platform=CUDA --stage=llvm
Thao tác này sẽ in kết xuất sang stdout (hoặc tới một tệp nhất định nếu -o
được chỉ định).
Mức sử dụng thiết bị không phải thiết bị
Không cần quyền truy cập vào GPU trong hầu hết quá trình biên dịch và bằng cách chỉ định Thông số GPU trên dòng lệnh mà chúng ta có thể nhận được, ví dụ: Đầu ra PTX mà không cần truy cập vào trình tăng tốc:
$ hlo-opt --platform=CUDA --stage=llvm --xla_gpu_target_config_filename=(pwd)/tools/data/gpu_specs/a100_pcie_80.txtpb input.hlo
Thông số kỹ thuật cho các GPU phổ biến được gửi cùng với trình biên dịch và tệp được cung cấp là
chuyển đổi tuần tự chuỗi của 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"
Quá trình biên dịch không có thiết bị có thể gặp sự cố nếu cần phải tự động điều chỉnh. Thật may mắn, chúng tôi cũng có thể cung cấp những mã đó trên dòng lệnh:
$ 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
Tệp autotune là một chuỗi văn bản chuyển đổi tuần tự của autotune_results.proto
, với
ví dụ như sau:
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
}
}
}
Cơ sở dữ liệu tự động điều chỉnh có thể được chuyển đổi tuần tự bằng
XLA_FLAGS=--xla_gpu_dump_autotune_results_t=<myfile.pbtxt>
Chạy một Trình biên dịch Pass (single Compiler Pass)
Các cờ từ XLA_FLAGS
cũng được hỗ trợ, vì vậy, bạn có thể sử dụng công cụ này để kiểm thử
chạy một lượt truyền:
$ hlo-opt --platform=CUDA --stage=hlo --xla-hlo-enable-passes-only=algebraic_simplifer input.hlo