There are different ways to write unit test for HLO passes. This page describes the preferred method to ensure consistency and readability.
FileCheck
with CHECK
lines interleaved
Most HLO passes can be tested using
FileCheck
tests.
Interleave CHECK
lines in input HLO module texts, and make sure to use //
CHECK
instead of ; CHECK
uniformly as the FileCheck
delimiter.
For example, you can re-write the
fusion cc_test
for a priotity_fusion
pass
as follows:
TEST_F(PriorityFusionTest, FuseBroadcastIntoBitcastConsumers) {
absl::string_view kHlo = R"(
HloModule test_module
// CHECK: ENTRY main
ENTRY main {
// CHECK-NEXT: %[[PARAM:.*]] = f32[96]{0} parameter(0)
param_0 = f32[96]{0} parameter(0)
broadcast = f32[8,96,128,7]{3,2,1,0} broadcast(param_0), dimensions={1}
bitcast.6079.2 = f32[8,24,4,128,7]{4,3,2,1,0} bitcast(broadcast)
// CHECK-NEXT: ROOT %{ {.*} } fusion(%[[PARAM]]) { {.*} }
ROOT transpose.1990.2 = f32[8,24,128,7,4]{4,3,2,1,0} transpose(bitcast.6079.2), dimensions={0,1,3,4,2}
}
)";
RunAndFilecheckHloRewrite(kHlo, std::move(priority_fusion_));
}
LIT
runner and hlo-opt
Where feasible, use LIT
runner
and hlo-opt
, and place CHECK
lines locally next to the input IR they
correspond to. Again, make sure to use // CHECK
instead of ; CHECK
as the
delimiter.
For example, some GPU tests can be written as follows:
// RUN: hlo-opt %s --platform=gpu --stage=llvm-before-optimizations --xla_gpu_target_config_filename=%S/../../../tools/hlo_opt/gpu_specs/%{GPU}.txtpb | FileCheck --check-prefixes=CHECK-%{PTX} %s
HloModule Test, is_scheduled=true
fused_computation {
param_0 = f32[100,200]{1,0} parameter(0)
ROOT b.1 = f32[200,100]{1,0} transpose(f32[100,200]{1,0} param_0), dimensions={1,0}
}
ENTRY main {
a = f32[100, 200]{1,0} parameter(0)
// CHECK-PTX: call void @llvm.nvvm.barrier0
// CHECK-GCN: call void @llvm.amdgcn.s.barrier
ROOT wrapped_b = f32[200,100]{1,0} fusion(f32[100,200]{1,0} a), kind=kInput, calls=fused_computation
}
(Don't) Graph traversal
Refrain from writing tests that travel leaf nodes of the result graph and match with expected op. These tests are tedious to write, difficult to quickly read, and more difficult to debug and fix. Use one of the above options instead.