Download code/tt_bevformer/tt/kernels/scatter_k_compute.cpp from changh95/bevformer-p150: direct link, hf CLI and curl.
- Browser
- Download file 4.53 kB
-
https://huggingface.co/changh95/bevformer-p150/resolve/main/code/tt_bevformer/tt/kernels/scatter_k_compute.cpp
- Command line
-
hf download hf://changh95/bevformer-p150/code/tt_bevformer/tt/kernels/scatter_k_compute.cpp
-
curl -L -o scatter_k_compute.cpp https://huggingface.co/changh95/bevformer-p150/resolve/main/code/tt_bevformer/tt/kernels/scatter_k_compute.cpp
4.53 kB
| // SPDX-License-Identifier: Apache-2.0 | |
| // scatter_k (tt/scatter_k.py), compute. Per 32-row block (DT tiles), the steps of the stock ops in their order, each | |
| // result packed to bf16 like the stock ops' bf16 outputs (16-bit DEST, fp32 dest accumulation off, as binary_ng runs | |
| // bf16 operands): | |
| // s1 = g0 + g1, s2 = s1 + g2: the FPU add (add_tiles); | |
| // out = s2 * scale: the SFPU multiply (both operands copied to DEST, mul_binary_tile) with the scale column broadcast | |
| // over the row by the reader (binary_ng's column-broadcast fill). | |
| // Which unit each stock op used was measured against the stock ops (logs/bevformer/opt_r8/scatp_*.log): the SFPU add | |
| // rounds ties to even where the stock add does not; the FPU multiply rounds differently from the stock multiply. | |
| constexpr uint32_t DT = get_compile_time_arg_val(0); | |
| constexpr uint32_t NWORK = get_compile_time_arg_val(1); | |
| constexpr uint32_t NC = get_compile_time_arg_val(2); | |
| constexpr uint32_t GX = get_compile_time_arg_val(3); | |
| constexpr uint32_t cb_g0 = 0, cb_g1 = 1, cb_g2 = 2, cb_sc = 3, cb_s1 = 4, cb_s2 = 5, cb_out = 16; | |
| constexpr uint32_t SB = 4; // tiles per DEST batch (operand pairs: 8 of the 16-bit DEST half) | |
| static_assert(DT % SB == 0, "scatter_k: D a multiple of 128"); | |
| // s = a + b: binary_ng's FPU add of bf16 operands (add_tiles; measured: the SFPU add's RNE does not reproduce it) | |
| static inline void add_step(uint32_t a, uint32_t b, uint32_t o) { | |
| cb_wait_front(a, DT); | |
| cb_wait_front(b, DT); | |
| cb_reserve_back(o, DT); | |
| reconfig_data_format(a, b); | |
| pack_reconfig_data_format(o); | |
| add_init(a, b); | |
| for (uint32_t t0 = 0; t0 < DT; t0 += SB) { | |
| tile_regs_acquire(); | |
| for (uint32_t i = 0; i < SB; ++i) { | |
| add_tiles(a, b, t0 + i, t0 + i, i); | |
| } | |
| tile_regs_commit(); | |
| tile_regs_wait(); | |
| for (uint32_t i = 0; i < SB; ++i) { | |
| pack_tile<true>(i, o, t0 + i); | |
| } | |
| tile_regs_release(); | |
| } | |
| cb_push_back(o, DT); | |
| cb_pop_front(a, DT); | |
| cb_pop_front(b, DT); | |
| } | |
| // o = a * bcast: binary_ng's SFPU multiply (copy both to DEST, mul_binary_tile; the broadcast tile filled by the | |
| // reader; measured: the FPU multiply does not reproduce it) | |
| static inline void mul_step(uint32_t a, uint32_t b, uint32_t o) { | |
| cb_wait_front(a, DT); | |
| cb_wait_front(b, 1); | |
| cb_reserve_back(o, DT); | |
| pack_reconfig_data_format(o); | |
| for (uint32_t t0 = 0; t0 < DT; t0 += SB) { | |
| tile_regs_acquire(); | |
| reconfig_data_format_srca(a); | |
| copy_init(a); | |
| for (uint32_t i = 0; i < SB; ++i) { | |
| copy_tile(a, t0 + i, 2 * i); | |
| } | |
| reconfig_data_format_srca(b); | |
| copy_init(b); | |
| for (uint32_t i = 0; i < SB; ++i) { | |
| copy_tile(b, 0, 2 * i + 1); | |
| mul_binary_tile_init(); | |
| mul_binary_tile(2 * i, 2 * i + 1, 2 * i); | |
| } | |
| tile_regs_commit(); | |
| tile_regs_wait(); | |
| for (uint32_t i = 0; i < SB; ++i) { | |
| pack_tile<true>(2 * i, o, t0 + i); | |
| } | |
| tile_regs_release(); | |
| } | |
| cb_push_back(o, DT); | |
| cb_pop_front(a, DT); | |
| cb_pop_front(b, 1); | |
| } | |
| void kernel_main() { | |
| const uint32_t ci = get_absolute_logical_y() * GX + get_absolute_logical_x(); | |
| if (ci >= NC) { | |
| return; | |
| } | |
| const uint32_t w0 = ci * NWORK / NC; | |
| const uint32_t w1 = (ci + 1) * NWORK / NC; | |
| if (w0 >= w1) { | |
| return; | |
| } | |
| compute_kernel_hw_startup(cb_g0, cb_g1, cb_out); | |
| for (uint32_t w = w0; w < w1; ++w) { | |
| add_step(cb_g0, cb_g1, cb_out); | |
| cb_wait_front(cb_g2, DT); | |
| cb_pop_front(cb_g2, DT); | |
| cb_wait_front(cb_sc, 1); | |
| cb_pop_front(cb_sc, 1); | |
| add_step(cb_g0, cb_g1, cb_s1); | |
| add_step(cb_s1, cb_g2, cb_out); | |
| cb_wait_front(cb_sc, 1); | |
| cb_pop_front(cb_sc, 1); | |
| add_step(cb_g0, cb_g1, cb_s1); | |
| add_step(cb_s1, cb_g2, cb_s2); | |
| mul_step(cb_s2, cb_sc, cb_out); | |
| } | |
| } | |