Week 8 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 8 spec.
How to use this
Run python tools/test.py --compiler PATH --week 8 -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/c_block_shared_fresh | cuda | shared memory starts at zero in every block, so the kernel must zero it | render private allocs shared |
render/c_err_alloc_in_two_kernels | cuda: invalid | an alloc used by two global loops isn't any one block's shared memory, so it has nowhere to live on the GPU | none recorded |
render/c_err_kernel_uses_outer_loop | cuda: invalid | a global loop inside a plain loop uses the plain loop's index, which only the CPU knows | none recorded |
render/c_err_thread_loop | cuda: invalid | a week 7 thread loop runs on CPU threads: render-cuda wants global and local loops | none recorded |
render/c_err_work_outside_kernel | cuda: invalid | a load at the top level would run on the CPU: render-cuda needs every bit of work inside a kernel | none recorded |
render/c_gemm_row_strips | cuda | a GEMM with one block per strip of rows, looping over column tiles inside | render private allocs shared |
render/c_gemm_tile_per_block | cuda | the textbook GEMM: a block per 4x4 tile of C, shared A and B tiles, one accumulator per thread | render private allocs shared |
render/c_reverse_shared | cuda | two phases through shared memory: without __syncthreads between them, threads read before others write | cuda no barrier between phases render private allocs shared |
render/c_reverse_shared_1024 | cuda | the reversal with 1024-thread blocks: on a real GPU, 32 warps make a missing __syncthreads show | cuda no barrier between phases |
render/c_scale | cuda | one thread per element: blockIdx and threadIdx | none recorded |
render/c_shared_dirty_then_fresh | cuda | kernel 1 fills shared memory with 7s. Kernel 2 must still see its own shared memory start at zero, so the kernel has to zero it | cuda shared memory not zeroed |
render/c_tiles_2d_layout | cuda | a 2D grid of blocks, written through div and mod | none recorded |
render/c_two_kernels | cuda | two kernels in a row: the second reads what the first wrote | none recorded |
render/c_zero_blocks | cuda | a grid of zero blocks: nothing runs, nothing breaks | none recorded |
render/r_gemm_tile_per_block_cpu | render | the same GPU program rendered for the CPU: global as threads, local as loops | render private allocs shared |
render/r_reverse_shared_cpu | render | phases on the CPU are just consecutive loops | none recorded |
render/s_cuda_gemm_512 | cuda, speed 0.5 | a 512x512 GEMM on the GPU: at least half the reference kernel's speed. Without a GPU it only has to build. | cuda local loops run in one thread cuda no barrier between phases cuda shared memory not zeroed render private allocs shared |
run/block_shared_starts_at_zero | run: pass | shared memory used only in one global loop starts at zero in every block: o = b + t | none recorded |
run/digits_just_apart | run: pass | o[3b + t] with t up to 2 is fine: 3 is more than 2 | none recorded |
run/err_block_layouts_differ | run: invalid | one buffer written with two different block layouts | block layouts may differ |
run/err_blocks_write_one_place | run: invalid | the block index is missing from the offset: every block writes o[t] | parallel index may be missing |
run/err_coefficient_not_literal | run: invalid | block offsets use literal coefficients | none recorded |
run/err_digits_exactly_touch | run: invalid | o[2b + t] with t up to 2: block 1 thread 0 and block 0 thread 2 both write o[2]. The coefficient 2 must be more than 2, not equal. | digits may touch |
run/err_local_nested | run: invalid | a local loop inside another local loop | none recorded |
run/err_local_not_literal | run: invalid | the block size is a literal | none recorded |
run/err_local_outside_global | run: invalid | a local loop runs inside a block, so it needs a global loop around it | local outside global allowed |
run/err_local_sizes_differ | run: invalid | all local loops in one kernel are the same block: one size | block sizes may differ |
run/err_local_too_big | run: invalid | a block has at most 1024 threads | none recorded |
run/err_same_phase_neighbor | run: invalid | reading sh[t + 1] in the same phase that writes sh: thread t + 1 may not have written it yet | phase loads unchecked |
run/err_store_outside_local | run: invalid | a store in a block but outside any local loop would run on every thread of the block | store outside local allowed |
run/err_thread_in_global | run: invalid | CPU threads inside a GPU block | none recorded |
run/err_threads_write_one_cell | run: invalid | every thread of the block writes sh[0]: a race | parallel index may be missing |
run/err_tiles_2d_overlap | run: invalid | by*4 + bx*2 + ty*2 + tx: bx and ty share a coefficient, so blocks overlap | none recorded |
run/global_local_same_result | run: pass | two blocks of four threads compute exactly what plain loops do | none recorded |
run/global_local_wrong_value | run: assert_fail | and a wrong value still fails | none recorded |
run/later_phase_reads_anywhere | run: pass | a later phase may read any shared element an earlier phase wrote: reverse each block of 4 | none recorded |
run/local_bound_1024 | run: pass | 1024 threads is allowed | none recorded |
run/plain_loop_alloc_carries_over | run: pass | the same program as plain loops carries the alloc from b = 0 into b = 1 | none recorded |
run/tiles_2d_layout | run: pass | a 4x4 matrix as 2x2 blocks of 2x2 threads: by*8 + bx*2 + ty*4 + tx, a unique mixed-radix number | none recorded |