IRLens
December 2, 2025 ยท View on GitHub
IRLens_analyze_hlo_ir.py: HLO IR execution skeleton analyzer.
This tool parses an XLA HLO module text dump, starting from ENTRY, and prints a hierarchical "execution skeleton" showing while-loops, conditionals, and selected operation types (communication ops, computation ops, or both).
It strips away non-essential ops and keeps only the control-flow structure and the relevant ops. All op_name metadata paths are printed in full.
USAGE:
IRLens_analyze_hlo_ir.py <hlo_ir_dump.txt> [options]
OPTIONS:
--op {all,communication,computation}
Select which types of operations to display.
all (default): show both communication and computation ops
communication: show only communication ops (all-gather-start, reduce-scatter-start...)
computation: show only computation ops (fusion kernels, custom-call GEMMs, etc.)
--name
Display result variable names and while loop names.
--topology
Display communication topology information such as replica_groups or
source_target_pairs.
--fusion-stats
Show detailed fusion subtypes in the statistics summary (skeleton always
shows the detailed subtype regardless).
EXAMPLES:
# Show all ops in the skeleton (default)
IRLens_analyze_hlo_ir.py hlo_ir_dump.txt
# Show only communication ops (EXTREMELY USEFUL!!!)
IRLens_analyze_hlo_ir.py hlo_ir_dump.txt --op communication
# Show only computation ops
IRLens_analyze_hlo_ir.py hlo_ir_dump.txt --op computation
# Show name and topology fields
IRLens_analyze_hlo_ir.py hlo_ir_dump.txt --name --topology
# Break down fusion ops in statistics
IRLens_analyze_hlo_ir.py hlo_ir_dump.txt --fusion-stats
DEMO
You can run the following command:
./IRLens_analyze_hlo_ir.py examples/tiny-hlo.txt
The output may look like:
ENTRY %main.123:
while i in range(10):
%outer_loop.body:
all-gather-start | f32[1024], f32[8192] | allgather_layer1 | /home/user/model.py:42
while j in range(5):
%inner_loop.body:
reduce-scatter-start | f32[8192], f32[1024] | reduce_scatter_inner | /home/user/model.py:45
all-reduce-start | f32[1024] | allreduce_inner | /home/user/model.py:47
all-reduce-start | f32[8192] | allreduce_final | /home/user/model.py:50
add | s32[] | N/A | N/A
# Total communication ops: 120
# 3 communication op categories:
# all-gather-start 10
# all-reduce-start 60
# reduce-scatter-start 50
# Total computation ops: 10
# 1 computation op categories:
# add 10
Showcase
A few real HLO IR files dumped from MaxText are provided in the examples directory. You can analyze them with the following commands:
./IRLens_analyze_hlo_ir.py examples/debug-model.bf16.dcn-dp1_dcn-pp2_ici-ep8.jit_train_step.gfx950_gpu_after_optimizations.txt --op=communication > bf16-dp1.comm.txt
./IRLens_analyze_hlo_ir.py examples/debug-model.bf16.dcn-dp2_dcn-pp2_ici-ep8.jit_train_step.gfx950_gpu_after_optimizations.txt --op=communication > bf16-dp2.comm.txt
./IRLens_analyze_hlo_ir.py examples/debug-model.fp8.dcn-dp1_dcn-pp2_ici-ep8.jit_train_step.gfx950_gpu_after_optimizations.txt --op=communication > fp8-dp1.comm.txt
./IRLens_analyze_hlo_ir.py examples/debug-model.fp8.dcn-dp2_dcn-pp2_ici-ep8.jit_train_step.gfx950_gpu_after_optimizations.txt --op=communication > fp8-dp2.comm.txt
vimdiff bf16-dp1.comm.txt bf16-dp2.comm.txt
vimdiff fp8-dp1.comm.txt fp8-dp2.comm.txt
These diffs clearly highlight the Data Parallel (DP) scaling behavior differences currently in MaxText when using Pipeline Parallelism (PP) under BF16 vs. FP8:
- With
BF16, the gradient-reductionall-reduceops are successfully hoisted out of the backward pipelining loop.

- With
FP8, theseall-reduceops remain inside the backward loop, leading to significantly higher communication overhead.
