Week 4 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 4 spec.
How to use this
Run python tools/test.py --compiler PATH --week 4 -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/normalize_4096 | render | end doesn't close its range final version not followed loads never move into loops render elementwise at 0 render expand zero render load at offset 0 render loop starts at 1 render loop uses <= render reduce reversed render skips rangeify render store loop short | |
render/normalize_stage_4096 | render | end doesn't close its range final version not followed loads never move into loops render elementwise at 0 render expand zero render load at offset 0 render loop starts at 1 render loop uses <= render reduce reversed render skips rangeify render stage reads x[0] render store loop short | |
render/r_add_f32_2048 | render | elementwise add of two large f32 vectors | end doesn't close its range final version not followed render elementwise at 0 render load at offset 0 render loop starts at 1 render skips rangeify render store loop short |
render/r_cast_f32_i32_1024 | render | f32 to i32 casts in range, truncating | end doesn't close its range final version not followed render elementwise at 0 render load at offset 0 render loop starts at 1 render skips rangeify render store loop short |
render/r_cast_i32_f32_1024 | render | i32 to f32 rounds to nearest-even for big values | end doesn't close its range final version not followed render elementwise at 0 render load at offset 0 render loop starts at 1 render skips rangeify render store loop short |
render/r_chained_reduce_1024 | render | subtract the max, then scale by the inverse sum of squares | end doesn't close its range final version not followed loads never move into loops render elementwise at 0 render expand zero render load at offset 0 render loop starts at 1 render loop uses <= render skips rangeify render store loop short |
render/r_copy_4096 | render | a plain 4096-element copy (load, then store): still has to be a loop to fit in 20 KB | end doesn't close its range final version not followed no size threshold render load at offset 0 render loop starts at 1 render skips rangeify render store loop short |
render/r_differences_2047 | render | adjacent differences from two overlapping views of one buffer | C nested offsets lost end doesn't close its range final version not followed render elementwise at 0 render expand zero render load at offset 0 render loop starts at 1 render skips rangeify render store loop short |
render/r_divmod_1024 | render | C-style div and mod with negatives and -1 divisors (UB-free) | end doesn't close its range final version not followed render elementwise at 0 render load at offset 0 render loop starts at 1 render skips rangeify render store loop short |
render/r_dot_4096 | render | a 4096-wide dot product | end doesn't close its range final version not followed loads never move into loops render elementwise at 0 render load at offset 0 render loop starts at 1 render loop uses <= render reduce reversed render skips rangeify |
render/r_expand_dtypes_1024 | render | expand i32, f32 and bool scalars into buffers | end doesn't close its range final version not followed render expand zero render loop starts at 1 render skips rangeify render store loop short |
render/r_index_computed | render | index into a computed vector at a loaded, masked index | final version not followed render elementwise at 0 render load at offset 0 render skips rangeify |
render/r_inplace_scale_by_sum | render | scale a vector in place by its own sum: every element must use the sum of the old contents | end doesn't close its range final version not followed loads never move into loops render elementwise at 0 render expand zero render load at offset 0 render loop starts at 1 render loop uses <= render skips rangeify render stage reads x[0] render store loop short |
render/r_max_specials_1024 | render | elementwise max with nan, signed zeros and infinities | C max ignores -0.0 C max ignores nan end doesn't close its range final version not followed render elementwise at 0 render load at offset 0 render loop starts at 1 render skips rangeify render store loop short |
render/r_mean_variance_2048 | render | mean and variance of 2048 values, written to two slots | C float literals 6 digits end doesn't close its range final version not followed loads never move into loops render elementwise at 0 render expand zero render load at offset 0 render loop starts at 1 render loop uses <= render reduce reversed render skips rangeify |
render/r_mul_i32_wrap_1024 | render | i32 elementwise mul wraps per element, in a loop | C plain signed add end doesn't close its range final version not followed render elementwise at 0 render load at offset 0 render loop starts at 1 render skips rangeify render store loop short |
render/r_recip_1024 | render | recip per element, signed zeros included | end doesn't close its range final version not followed render elementwise at 0 render load at offset 0 render loop starts at 1 render skips rangeify render store loop short |
render/r_reduce_add_i32_4096 | render | a 4096-wide i32 sum wraps | C plain signed add end doesn't close its range final version not followed loads never move into loops render load at offset 0 render loop starts at 1 render loop uses <= render skips rangeify |
render/r_reduce_add_order_4096 | render | a 4096-wide f32 sum whose bits depend on folding left to right | end doesn't close its range final version not followed loads never move into loops render load at offset 0 render loop starts at 1 render loop uses <= render reduce reversed render skips rangeify |
render/r_reduce_in_hand_loop | render | a reduce result feeding a hand-written week 3 loop | end doesn't close its range final version not followed loads never move into loops render load at offset 0 render loop starts at 1 render loop uses <= stores under ends unsequenced |
render/r_reduce_max_nan_2048 | render | max with a nan in the middle is nan. Without the nan it is the true max | C max ignores nan end doesn't close its range final version not followed loads never move into loops render load at offset 0 render skips rangeify |
render/r_reduce_max_signed_zero | render | max over only signed zeros gives +0.0 if any +0.0 is present | C max ignores -0.0 end doesn't close its range loads never move into loops render load at offset 0 render skips rangeify |
render/r_reduce_mul_i32_1024 | render | i32 product of 1024 values wraps at every step | end doesn't close its range loads never move into loops render skips rangeify |
render/r_reduce_single | render | a one-element reduce is a zero-trip loop after the first element | end doesn't close its range final version not followed render reduce from zero render skips rangeify |
render/r_relu_4096 | render | relu by cmplt and where, 4096 wide | C cmplt as <= C where swapped end doesn't close its range final version not followed render elementwise at 0 render load at offset 0 render skips rangeify render store loop short |
render/r_shl_1024 | render | shl per element wraps | C plain signed add end doesn't close its range final version not followed render elementwise at 0 render load at offset 0 render loop starts at 1 render loop uses <= render skips rangeify render store loop short |
render/r_stage_scalar | render | stage on a scalar is just that scalar | end doesn't close its range final version not followed loads never move into loops render load at offset 0 render loop starts at 1 render loop uses <= render skips rangeify |
render/r_stage_twice_4096 | render | a staged vector read by two reduces and a store | end doesn't close its range final version not followed loads never move into loops render elementwise at 0 render expand zero render load at offset 0 render loop starts at 1 render loop uses <= render reduce reversed render skips rangeify render stage reads x[0] render store loop short |
render/r_two_outputs_2048 | render | one loaded vector feeding two outputs | end doesn't close its range final version not followed render elementwise at 0 render load at offset 0 render loop starts at 1 render skips rangeify render store loop short |
render/r_used_twice_2048 | render | a squared vector used in a reduce and elementwise, recomputed | end doesn't close its range final version not followed loads never move into loops render elementwise at 0 render expand zero render load at offset 0 render loop starts at 1 render loop uses <= render reduce reversed render skips rangeify render store loop short |
render/r_used_twice_stage_2048 | render | a squared vector used in a reduce and elementwise, materialized with stage | end doesn't close its range final version not followed loads never move into loops render elementwise at 0 render expand zero render load at offset 0 render loop starts at 1 render loop uses <= render reduce reversed render skips rangeify render stage reads x[0] render store loop short |
render/r_view_slices_1500 | render | rank-1 views at an offset: copy b[3..1502] + 1 into c[1..1500] | C nested offsets lost end doesn't close its range final version not followed render elementwise at 0 render expand zero render load at offset 0 render loop starts at 1 render skips rangeify render store loop short |
render/r_where_i32_2048 | render | clamp i32 to [-100, 100] with where | C where swapped end doesn't close its range final version not followed render elementwise at 0 render expand zero render load at offset 0 render loop starts at 1 render skips rangeify render store loop short |
render/r_xor_bool_1024 | render | bool xor into a bool buffer | end doesn't close its range final version not followed render elementwise at 0 render load at offset 0 render loop starts at 1 render loop uses <= render skips rangeify |
run/add_i32_vec | run: pass | elementwise i32 add on rank-1 values | elementwise uses x[0] |
run/add_i32_wrap_vec | run: pass | elementwise add wraps per element | add doesn't wrap elementwise uses x[0] |
run/cast_vec | run: pass | cast works per element | bool->num always 1 elementwise uses x[0] f32->i32 rounds i32->f32 not rounded |
run/chained_reduce | run: pass | max, then a sum of squares of x - max | elementwise uses x[0] expand scalar is zero |
run/cmplt_where_vec | run: pass | cmplt gives a bool vector, and where selects per element | NaN != NaN in assert cmplt is <= elementwise uses x[0] expand scalar is zero where branches swapped |
run/div_mod_vec | run: pass | C-style div and mod per element, INT_MIN / -1 wraps | div floors like Python elementwise uses x[0] mod uses Python % |
run/dot | run: pass | a dot product is reduce(mul(x, y)) | elementwise uses x[0] f32 ops not rounded |
run/err_div_zero_vec | run: invalid | one zero divisor in a vector is a runtime error | div by zero returns 0 elementwise uses x[0] |
run/err_expand_grows_non1_axis | run: invalid | expand only grows size-1 axes: a size-2 axis cannot become size 3 (a scalar or same-rank value is fine from week 5) | expand grows non-1 axes |
run/err_expand_no_shape | run: invalid | expand needs shape=[n] | none recorded |
run/err_expand_zero | run: invalid | shape=[0] isn't a shape | none recorded |
run/err_missing_expand | run: invalid | no implicit broadcasting: a scalar must be expanded first | implicit broadcast allowed |
run/err_rank1_open_range | run: invalid | a rank-1 value can't depend on an open range | shaped on open range ok |
run/err_reduce_bad_op | run: invalid | reduce op must be add, mul or max | none recorded |
run/err_reduce_bool | run: invalid | reduce works on i32 or f32 only | reduce on bool |
run/err_reduce_no_op | run: invalid | reduce needs op= | none recorded |
run/err_reduce_scalar | run: invalid | reduce takes a rank-1 value | reduce takes scalars |
run/err_shape_mismatch | run: invalid | elementwise ops need equal shapes | implicit broadcast allowed |
run/err_where_scalar_cond | run: invalid | where needs its condition in the same shape as its branches | implicit broadcast allowed |
run/expand_dtypes | run: pass | expand broadcasts a scalar of any dtype | expand scalar is zero recip 0 ignores sign |
run/fail_vec | run: assert_fail | a computed vector that doesn't match | none recorded |
run/index_computed_vec | run: pass | index into a computed rank-1 value | elementwise uses x[0] |
run/inloop_after_not_output | run: pass | an after inside a loop is local to an iteration, not an output: no top-level after builds on %b, so %b's output is unchanged | evaluates everything in-loop afters are outputs |
run/load_view_rank1 | run: pass | load a [k] view, add an expanded scalar, store into another buffer's view | elementwise uses x[0] evaluates everything expand scalar is zero load ignores the offset rank-1 store writes one |
run/max_f32_nan_vec | run: pass | elementwise max: nan wins, -0.0 vs 0.0 gives +0.0 | NaN != NaN in assert elementwise uses x[0] f32 consts not rounded max ignores NaN |
run/mean_variance | run: pass | mean, then variance from the deviations | elementwise uses x[0] expand scalar is zero |
run/mul_add_f32_vec | run: pass | f32 elementwise ops round after every op | elementwise uses x[0] f32 consts not rounded f32 ops not rounded |
run/normalize_small | run: pass | x / sum(x): x is used twice, once inside the reduce and once after | elementwise uses x[0] expand scalar is zero f32 ops not rounded |
run/normalize_small_stage | run: pass | the same with stage: identical results | elementwise uses x[0] expand scalar is zero f32 ops not rounded stage zeroes |
run/recip_vec | run: pass | recip per element, including signed zeros | elementwise uses x[0] recip 0 ignores sign |
run/reduce_add_f32_order | run: pass | reduce add folds left to right from x[0]; right to left would give 0.0 | f32 ops not rounded fold right to left |
run/reduce_add_i32_wrap | run: pass | reduce add on i32 wraps at each step | add doesn't wrap |
run/reduce_add_negzero | run: pass | a fold that starts from x[0] keeps -0.0; starting from 0.0 would lose the sign | fold from zero recip 0 ignores sign |
run/reduce_in_hand_loop | run: pass | a reduce result (no open ranges) used inside a week 3 loop | end doesn't close its range evaluates everything loop runs one extra time stores under ends unsequenced |
run/reduce_max_i32 | run: pass | reduce max of negatives | fold from zero reduce op ignored |
run/reduce_max_nan | run: pass | reduce max: any nan makes the result nan | NaN != NaN in assert fold skips nan max ignores NaN |
run/reduce_max_signed_zero | run: pass | reduce max of -0.0 and 0.0 is +0.0 | fold from zero recip 0 ignores sign |
run/reduce_mul_f32 | run: pass | reduce mul on f32 rounds after every step (and overflows to inf) | f32 ops not rounded fold from zero reduce op ignored |
run/reduce_mul_i32_wrap | run: pass | reduce mul on i32 wraps at each step | mul doesn't wrap reduce op ignored |
run/reduce_of_expand | run: pass | reducing an expanded scalar | expand scalar is zero f32 ops not rounded |
run/reduce_single | run: pass | a one-element reduce is that element | none recorded |
run/shl_vec | run: pass | shl per element wraps | elementwise uses x[0] shl doesn't wrap |
run/stage_identity | run: pass | stage doesn't change the value, rank 1 or scalar | NaN != NaN in assert stage zeroes |
run/xor_vec | run: pass | xor on bool and i32 vectors | elementwise uses x[0] xor bool is equality |