Week 7 test guide
A test failed and you don't know why? Find it here: what it checks, and the plausible bugs that are known to fail it. Then read the matching part of the week 7 spec.
How to use this
Run python tools/test.py --compiler PATH --week 7 -v, copy the failing test's name, and search below. "Bugs known to fail it" lists mistakes that were planted in the reference compiler and caught by this test, so one of them is a good first guess. It's not a complete list, and the debugging guide covers what to do when none fit.
| test | kind | what it checks | bugs known to fail it |
|---|---|---|---|
render/r_gemm_tiled_12x24x7 | render | a 12x24 by 7 GEMM: thread over 4-row blocks, a 4x8 private tile, upcast loops. Same bits as matmul. | upcast unrolls one copy short |
render/r_gemm_tiled_4x8x2 | render | a 4x8 by 2 GEMM: thread over 4-row blocks, a 4x8 private tile, upcast loops. Same bits as matmul. | upcast unrolls one copy short |
render/r_gemm_tiled_8x16x5 | render | a 8x16 by 5 GEMM: thread over 4-row blocks, a 4x8 private tile, upcast loops. Same bits as matmul. | upcast unrolls one copy short |
render/r_thread_captures_values | render | the outlined body needs values computed outside it: a scale loaded before the loop, and the outer range | none recorded |
render/r_thread_inside_loop | render | a thread loop inside a plain loop, rendered | none recorded |
render/r_thread_private_alloc | render | private allocs: each call of the outlined body starts from zeros | render private allocs shared thread rendered as a plain loop |
render/r_thread_rowsum | render | a thread loop rendered: the harness runs it with uir_parallel_for | none recorded |
render/r_thread_zero_trips | render | zero iterations: the buffer is untouched | none recorded |
render/r_upcast_sum_order | render | an unrolled f32 sum keeps its order | upcast unrolls one copy short |
render/s_gemm_768_threads | render, speed 0.5 | thread loops alone (no upcast): at least half the reference's speed | render private allocs shared thread rendered as a plain loop |
render/s_gemm_768_threads_and_upcast | render, speed 0.5 | the full schedule: at least half the reference's speed. Ignoring the thread axis is about 8 times too slow. | render private allocs shared thread rendered as a plain loop upcast rendered as a plain loop upcast unrolls one copy short |
render/s_gemm_768_upcast | render, speed 0.65 | one thread, upcast tile only: at least 0.65 of the reference's speed. Rendering upcast loops as plain loops is too slow. | upcast rendered as a plain loop upcast unrolls one copy short |
run/axis_loop_is_default | run: pass | axis=loop is the same as no axis at all | none recorded |
run/axis_thread_same_result | run: pass | a thread loop computes exactly what a plain loop does | none recorded |
run/axis_thread_wrong_value | run: assert_fail | and a wrong expected value still fails | none recorded |
run/axis_upcast_same_order | run: pass | upcast unrolls but keeps the order: the f32 sum (with 1e8 and -1e8 in it) has the same bits | none recorded |
run/err_axis_unknown | run: invalid | axis is loop, upcast or thread | none recorded |
run/err_thread_alloc_shared | run: invalid | an alloc that is also used after the loop is shared, so writing its element 0 from every iteration races | none recorded |
run/err_thread_load_neighbor | run: invalid | a load of memory the loop writes must stay in its own slice too: reading o[r + 1] races with iteration r + 1 | thread loads unchecked |
run/err_thread_mixed_strides | run: invalid | each access alone stays in a slice, o[2r] then o[r], but iteration 2 writes o[2] and so does iteration 1: one stride per buffer | mixed strides allowed |
run/err_thread_nested | run: invalid | a thread loop inside another thread loop, even when each access rule holds (the outer loop runs once) | nested thread loops allowed |
run/err_thread_store_negative | run: invalid | the rest of the offset may not go below the slice: 4r - 1 | none recorded |
run/err_thread_store_not_literal_stride | run: invalid | the stride must be a literal | none recorded |
run/err_thread_store_overlap | run: invalid | o[2r + j] with j up to 3 reaches the next iteration's slice | none recorded |
run/err_thread_store_r_twice | run: invalid | r may appear in one term only | none recorded |
run/err_thread_store_shared | run: invalid | every iteration writes o[j]: a race | none recorded |
run/err_thread_vector_store_overflows | run: invalid | a 2-element store at 4r + j, j up to 3, spills into the next slice | thread slice ignores the access size |
run/err_upcast_not_literal | run: invalid | an upcast bound is a literal: the loop is copied that many times | upcast bound unchecked |
run/err_upcast_too_big | run: invalid | upcast bounds go up to 32 | upcast bound unchecked |
run/err_upcast_zero | run: invalid | an upcast bound is at least 1 | upcast bound unchecked |
run/loop_alloc_carries_over | run: pass | the same program as a plain loop carries the alloc across iterations: running sums | none recorded |
run/thread_alloc_indexed_by_r | run: pass | a shared alloc is fine when each iteration writes its own element | none recorded |
run/thread_inside_loop | run: pass | a thread loop inside a plain loop: each pass of the outer loop runs it again | none recorded |
run/thread_private_alloc_fresh | run: pass | an alloc used only inside a thread loop starts at zero in every iteration: out[r] = 0 + r | private allocs never reset |
run/thread_private_alloc_not_cumulative | run: assert_fail | so a thread loop does not give running sums | private allocs never reset |
run/thread_reads_any_input | run: pass | memory the loop never writes may be read anywhere: each iteration sums all of x | none recorded |
run/thread_store_own_slice | run: pass | iteration r writes o[4r + j], j in [0, 3]: its own slice | none recorded |
run/thread_store_stride_first | run: pass | the literal may come first: mul 4 r | none recorded |
run/thread_zero_trips | run: pass | a thread loop that runs zero times is fine | none recorded |
run/upcast_bound_32 | run: pass | 32 is allowed | none recorded |
run/upcast_inside_thread | run: pass | upcast loops inside a thread loop, writing o[4r + u] | none recorded |