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.

testkindwhat it checksbugs known to fail it
render/normalize_4096renderend 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_4096renderend 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_2048renderelementwise add of two large f32 vectorsend 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_1024renderf32 to i32 casts in range, truncatingend 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_1024renderi32 to f32 rounds to nearest-even for big valuesend 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_1024rendersubtract the max, then scale by the inverse sum of squaresend 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_4096rendera plain 4096-element copy (load, then store): still has to be a loop to fit in 20 KBend 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_2047renderadjacent differences from two overlapping views of one bufferC 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_1024renderC-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_4096rendera 4096-wide dot productend 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_1024renderexpand i32, f32 and bool scalars into buffersend 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_computedrenderindex into a computed vector at a loaded, masked indexfinal version not followed
render elementwise at 0
render load at offset 0
render skips rangeify
render/r_inplace_scale_by_sumrenderscale a vector in place by its own sum: every element must use the sum of the old contentsend 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_1024renderelementwise max with nan, signed zeros and infinitiesC 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_2048rendermean and variance of 2048 values, written to two slotsC 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_1024renderi32 elementwise mul wraps per element, in a loopC 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_1024renderrecip per element, signed zeros includedend 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_4096rendera 4096-wide i32 sum wrapsC 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_4096rendera 4096-wide f32 sum whose bits depend on folding left to rightend 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_looprendera reduce result feeding a hand-written week 3 loopend 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_2048rendermax with a nan in the middle is nan. Without the nan it is the true maxC 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_zerorendermax over only signed zeros gives +0.0 if any +0.0 is presentC 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_1024renderi32 product of 1024 values wraps at every stepend doesn't close its range
loads never move into loops
render skips rangeify
render/r_reduce_singlerendera one-element reduce is a zero-trip loop after the first elementend doesn't close its range
final version not followed
render reduce from zero
render skips rangeify
render/r_relu_4096renderrelu by cmplt and where, 4096 wideC 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_1024rendershl per element wrapsC 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_scalarrenderstage on a scalar is just that scalarend 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_4096rendera staged vector read by two reduces and a storeend 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_2048renderone loaded vector feeding two outputsend 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_2048rendera squared vector used in a reduce and elementwise, recomputedend 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_2048rendera squared vector used in a reduce and elementwise, materialized with stageend 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_1500renderrank-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_2048renderclamp i32 to [-100, 100] with whereC 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_1024renderbool xor into a bool bufferend 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_vecrun: passelementwise i32 add on rank-1 valueselementwise uses x[0]
run/add_i32_wrap_vecrun: passelementwise add wraps per elementadd doesn't wrap
elementwise uses x[0]
run/cast_vecrun: passcast works per elementbool->num always 1
elementwise uses x[0]
f32->i32 rounds
i32->f32 not rounded
run/chained_reducerun: passmax, then a sum of squares of x - maxelementwise uses x[0]
expand scalar is zero
run/cmplt_where_vecrun: passcmplt gives a bool vector, and where selects per elementNaN != NaN in assert
cmplt is <=
elementwise uses x[0]
expand scalar is zero
where branches swapped
run/div_mod_vecrun: passC-style div and mod per element, INT_MIN / -1 wrapsdiv floors like Python
elementwise uses x[0]
mod uses Python %
run/dotrun: passa dot product is reduce(mul(x, y))elementwise uses x[0]
f32 ops not rounded
run/err_div_zero_vecrun: invalidone zero divisor in a vector is a runtime errordiv by zero returns 0
elementwise uses x[0]
run/err_expand_grows_non1_axisrun: invalidexpand 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_shaperun: invalidexpand needs shape=[n]none recorded
run/err_expand_zerorun: invalidshape=[0] isn't a shapenone recorded
run/err_missing_expandrun: invalidno implicit broadcasting: a scalar must be expanded firstimplicit broadcast allowed
run/err_rank1_open_rangerun: invalida rank-1 value can't depend on an open rangeshaped on open range ok
run/err_reduce_bad_oprun: invalidreduce op must be add, mul or maxnone recorded
run/err_reduce_boolrun: invalidreduce works on i32 or f32 onlyreduce on bool
run/err_reduce_no_oprun: invalidreduce needs op=none recorded
run/err_reduce_scalarrun: invalidreduce takes a rank-1 valuereduce takes scalars
run/err_shape_mismatchrun: invalidelementwise ops need equal shapesimplicit broadcast allowed
run/err_where_scalar_condrun: invalidwhere needs its condition in the same shape as its branchesimplicit broadcast allowed
run/expand_dtypesrun: passexpand broadcasts a scalar of any dtypeexpand scalar is zero
recip 0 ignores sign
run/fail_vecrun: assert_faila computed vector that doesn't matchnone recorded
run/index_computed_vecrun: passindex into a computed rank-1 valueelementwise uses x[0]
run/inloop_after_not_outputrun: passan after inside a loop is local to an iteration, not an output: no top-level after builds on %b, so %b's output is unchangedevaluates everything
in-loop afters are outputs
run/load_view_rank1run: passload a [k] view, add an expanded scalar, store into another buffer's viewelementwise uses x[0]
evaluates everything
expand scalar is zero
load ignores the offset
rank-1 store writes one
run/max_f32_nan_vecrun: passelementwise max: nan wins, -0.0 vs 0.0 gives +0.0NaN != NaN in assert
elementwise uses x[0]
f32 consts not rounded
max ignores NaN
run/mean_variancerun: passmean, then variance from the deviationselementwise uses x[0]
expand scalar is zero
run/mul_add_f32_vecrun: passf32 elementwise ops round after every opelementwise uses x[0]
f32 consts not rounded
f32 ops not rounded
run/normalize_smallrun: passx / sum(x): x is used twice, once inside the reduce and once afterelementwise uses x[0]
expand scalar is zero
f32 ops not rounded
run/normalize_small_stagerun: passthe same with stage: identical resultselementwise uses x[0]
expand scalar is zero
f32 ops not rounded
stage zeroes
run/recip_vecrun: passrecip per element, including signed zeroselementwise uses x[0]
recip 0 ignores sign
run/reduce_add_f32_orderrun: passreduce add folds left to right from x[0]; right to left would give 0.0f32 ops not rounded
fold right to left
run/reduce_add_i32_wraprun: passreduce add on i32 wraps at each stepadd doesn't wrap
run/reduce_add_negzerorun: passa fold that starts from x[0] keeps -0.0; starting from 0.0 would lose the signfold from zero
recip 0 ignores sign
run/reduce_in_hand_looprun: passa reduce result (no open ranges) used inside a week 3 loopend doesn't close its range
evaluates everything
loop runs one extra time
stores under ends unsequenced
run/reduce_max_i32run: passreduce max of negativesfold from zero
reduce op ignored
run/reduce_max_nanrun: passreduce max: any nan makes the result nanNaN != NaN in assert
fold skips nan
max ignores NaN
run/reduce_max_signed_zerorun: passreduce max of -0.0 and 0.0 is +0.0fold from zero
recip 0 ignores sign
run/reduce_mul_f32run: passreduce 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_wraprun: passreduce mul on i32 wraps at each stepmul doesn't wrap
reduce op ignored
run/reduce_of_expandrun: passreducing an expanded scalarexpand scalar is zero
f32 ops not rounded
run/reduce_singlerun: passa one-element reduce is that elementnone recorded
run/shl_vecrun: passshl per element wrapselementwise uses x[0]
shl doesn't wrap
run/stage_identityrun: passstage doesn't change the value, rank 1 or scalarNaN != NaN in assert
stage zeroes
run/xor_vecrun: passxor on bool and i32 vectorselementwise uses x[0]
xor bool is equality