Chi Hierarchical Instructions: Reusable Compiler Infrastructure for Visual Computing Mingkuan Xu Taichi Graphics Tsinghua University Apr 24, 2021 2 Extract CHI from Taichi 3 CHI Extract CHI from Taichi 4 CHI Extract CHI from Taichi 5 CHI
"Chi Hierarchical Instructions: Reusable Compiler" is the property of its rightful owner. Permission is granted to
download and print the materials on this website for personal, non-commercial use only, and to display it
on your personal computer provided you do not modify the materials and that you retain all copyright
notices contained in the materials. By downloading content from our website, you accept the terms of this
agreement.
Presentation Transcript
01
Chi Hierarchical Instructions:Reusable Compiler Infrastructure for Visual Computing Mingkuan Xu
Taichi Graphics & Tsinghua University
Apr 24, 2021 2<br>
02
Extract CHI from Taichi 3 CHI<br>
03
Extract CHI from Taichi 4 CHI<br>
04
Extract CHI from Taichi 5 CHI Any Frontend IR Builder<br>
05
Why CHI? Portability
High performance
Taichi features:
Sparse programming
Differentiable programming
Quantization
… 6 No need of pybind11 No need of Python frontend Standardization<br>
06
Statements 7<br>
07
IR Builder An interface to generate CHI IR conveniently
Example: generate 40 + 2: 8 auto block = std::make_unique<Block>();
auto func = []() {};
auto kernel = std::make_unique<Kernel>( get_current_program(), func, "fake_kernel");
block->kernel = kernel.get();
auto *lhs = block->push_back<ConstStmt>( TypedConstant(40));
auto *rhs = block->push_back<ConstStmt>( TypedConstant(2));
auto *add = block->push_back<BinaryOpStmt>( BinaryOpType::add, lhs, rhs); Before IRBuilder builder;
auto *lhs = builder.get_int32(40);
auto *rhs = builder.get_int32(2);
auto *add = builder.create_add(lhs, rhs); After<br>
08
Loop guards “Chi Hierarchical Instructions”
Handle insertion points automatically
WYSIWYG 9 IRBuilder builder;
auto *zero = builder.get_int32(0);
auto *ten = builder.get_int32(10);
auto *loop = builder.create_range_for(zero, ten);
{
auto _ = builder.get_loop_guard(loop);
auto *index = builder.get_loop_index(loop, 0);
}
auto *ret = builder.create_return(zero); kernel {
<i32> $0 = const [0]
<i32> $1 = const [10]
$2 : for in range($0, $1) {
$3 = loop $2 index 0
}
$4 : kernel return $0
}<br>
09
Interaction with C++ arrays Example: a[1] = a[0];
Declare kernel arguments & run on backends! 10 auto *arg = builder.create_arg_load(/*arg_id=*/0, get_data_type<int>(), /*is_ptr=*/true);
auto *zero = builder.get_int32(0);
auto *one = builder.get_int32(1);
auto *a0 = builder.create_global_load(builder.create_external_ptr(arg, {zero}));
builder.create_global_store(builder.create_external_ptr(arg, {one}), a0); auto ker = std::make_unique<Kernel>(prog, builder.extract_ir());
ker->insert_arg(get_data_type<int>(), /*is_external_array=*/true); // int *
auto launch_ctx = ker->make_launch_context();
launch_ctx.set_arg_external_array(/*arg_id=*/0, (uint64)a, size); // int a[size];
(*ker)(launch_ctx); // run!<br>
Analysis manager Atomic demotion for bit struct stores needs to gather all uniquely accessed bit structs.
Gather uniquely accessed bit structs must be before lower access since the latter will corrupt some information for aliasing analysis.
Atomic demotion for bit struct stores must be after lower access since bit struct stores are generated from the lowered accesses for now. 13 Information?<br>
13
Pass manager? Customize compilation passes
Use function interface (instead of class in LLVM/TVM/SPIR-V/…)for passes (functions)
Summary Standardize CHI IR
Generate CHI IR: IR Builder
Pass analysis information across passes: Analysis manager
Customize compilation passes: call functions directly
Towards a portable and high-performance compiler infrastructure for visual computing! 15<br>