Week 2 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 2 spec.

How to use this

Run python tools/test.py --compiler PATH --week 2 -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/alloc_read_before_writerenderreading an alloc before any store sees zerosC alloc not zeroed
C rank-1 store one elem
final version not followed
render/alloc_scratchrendera local alloc holds an intermediate, and it starts as zerosfinal version not followed
render/alloc_two_distinctrendertwo same-size allocs are separate arraysC alloc not zeroed
C rank-1 store one elem
allocs share storage
final version not followed
render/asserts_ignoredrenderrender ignores asserts and statements the outputs don't needfinal version not followed
render/bool_opsrenderbool xor, where on bools, and bool to i32C where swapped
final version not followed
render/call_inlinedrendercalls render inline: the body runs on loaded argsC rank-1 store one elem
final version not followed
render/call_nested_closedrendera nested call's body keeps its own param 0 when inlinedfinal version not followed
top-down inline enters bodies
render/casts_to_i32_and_boolrenderf32 to i32 truncates, and anything to bool is != 0, nan includedC cast to i32 rounds
C rank-1 store one elem
final version not followed
render/copy_scalarrenderthe smallest kernel: one load, one storefinal version not followed
render/dynamic_offset_boolrendera bool-derived offset picks one of two elementsfinal version not followed
render/dynamic_offset_storerenderstore at a masked loaded offsetfinal version not followed
render/f32_chainrendera longer f32 chain where every intermediate roundsfinal version not followed
render/f32_exact_literalsrenderf32 constants need every digit: 1/3 and the largest finite f32 must come out exactC float literals 6 digits
C rank-1 store one elem
final version not followed
render/f32_from_i32_castrenderi32 to f32 rounds to nearest even, and bool to f32 is 0 or 1C cast to i32 rounds
final version not followed
render/f32_maxrendermax with nan on either side and both signed-zero ordersC max ignores -0.0
C max ignores nan
final version not followed
render/f32_reciprenderrecip of zeros, infinities and a value that roundsfinal version not followed
render/f32_roundingrenderevery f32 op rounds; -ffp-contract=off keeps a*b+c from fusingfinal version not followed
render/f32_signed_zerorender-0.0 survives where it should and doesn't where it shouldn'tfinal version not followed
render/f32_specialsrendernan and inf arithmeticfinal version not followed
render/f32_where_cmpltrendercmplt with nan is false, and where picks a branchC cmplt as <=
C where swapped
final version not followed
render/i32_add_wraprenderi32 add wraps, and in C that has to go through uint32_tC plain signed add
final version not followed
render/i32_div_mod_intminrenderINT_MIN / -1 and INT_MIN % -1 are UB in C; the kernel must not trapC div without -1 guard
C mod without -1 guard
final version not followed
render/i32_div_mod_truncrenderC division truncates toward zero, and mod takes the dividend's signfinal version not followed
render/i32_max_cmp_xorrendermax, xor and a cmplt-driven where on i32 edgesC where swapped
final version not followed
render/i32_mul_wraprenderi32 mul wraps without UBC plain signed add
final version not followed
render/i32_shl_wraprendershl into the sign bit and past itC plain signed add
final version not followed
render/load_whole_indexrenderload a whole buffer and index itC rank-1 store one elem
final version not followed
render/mixed_dtypesrenderthree buffers of different dtypes in one kernelfinal version not followed
loads not before stores
render/nested_view_offsetsrendershrink of shrink: offsets add in the C tooC nested offsets lost
C rank-1 load no offset
C rank-1 store one elem
final version not followed
render/old_version_late_userenderan old-version load whose value is used two stores laterfinal version not followed
loads not before stores
render/rank1_copyrenderload a [3] view and store it into another buffer's [3] viewC rank-1 load no offset
C rank-1 store one elem
final version not followed
render/rmw_chainrenderthree increments of the same elementC plain signed add
final version not followed
render/special_data_copyrenderspecial float data copies through bit for bitC rank-1 store one elem
final version not followed
render/stack_index_dynamicrenderindex a stack with a loaded indexC rank-1 store one elem
final version not followed
render/store_whole_bufferrenderstore a rank-1 value into a whole bufferC rank-1 store one elem
final version not followed
render/swap_schedulerenderswap: the second store uses a load of the original version, so loads must be scheduled firstfinal version not followed
loads not before stores
render/unwritten_bufferrendera buffer the kernel never writes keeps its datafinal version not followed
run/alloc_distinctrun: passtwo allocs of the same size are different memoryalloc not zeroed
evaluates everything
run/alloc_scratchrun: passalloc is local scratch that starts as zerosalloc not zeroed
evaluates everything
run/bounds_bool_offsetrun: passa bool cast to i32 is in [0, 1], so it can index a 2-element bufferevaluates everything
load ignores the offset
run/bounds_const_arith_offsetrun: passconstant arithmetic offsets have exact boundsevaluates everything
load ignores the offset
run/bounds_last_windowrun: passa [k] view that ends exactly at the end is in boundsevaluates everything
load ignores the offset
run/bounds_masked_offsetrun: passa loaded index masked with max and mod is provably in [0, 3]evaluates everything
load ignores the offset
run/buf_boolrun: passbool buffers hold true/falseevaluates everything
load ignores the offset
xor bool is equality
run/buf_chain3run: passthree stores in a row, each into the previous versionevaluates everything
run/buf_data_loadrun: passdata= gives a buffer its initial contents, and a scalar view loads one elementevaluates everything
load ignores the offset
run/buf_f32_roundingrun: passf32 data rounds like f32 literals, and stays f32 through memoryevaluates everything
f32 consts not rounded
f32 ops not rounded
load ignores the offset
run/buf_old_versionrun: passa load of the old version still sees the old value, even if written after the store in the fileevaluates everything
load ignores the offset
run/buf_rmwrun: passread, modify, write backevaluates everything
run/buf_store_afterrun: passafter names the version with the store appliedevaluates everything
load ignores the offset
run/buf_versions_differrun: passevery version keeps its own contentsevaluates everything
run/buf_zerosrun: passwithout data=, a buffer starts as zeros of its dtypeevaluates everything
run/copy_between_buffersrun: passload from one buffer, store into anotherevaluates everything
load ignores the offset
rank-1 store writes one
run/err_after_not_storerun: invalidthe second operand of after must be a storenone recorded
run/err_after_on_viewrun: invalidafter takes a whole buffer version, not a viewnone recorded
run/err_after_stale_versionrun: invalidafter names an older version of the right buffer: still wrongafter version unchecked
run/err_after_wrong_versionrun: invalidafter must name the version the store writes intoafter version unchecked
run/err_alloc_slotrun: invalidalloc has no slot: it isn't an inputunknown attributes ignored
run/err_bounds_mask_too_widerun: invalidmasking to [0, 4] doesn't fit a scalar view in a 4-element bufferbounds off by one
bounds unchecked
run/err_bounds_mod_negativerun: invalidmod alone keeps the sign, so the offset could be negativebounds allow negative
bounds unchecked
mod bounds ignore sign
run/err_bounds_negativerun: invalidnegative offsets are out of boundsbounds allow negative
bounds unchecked
run/err_bounds_nestedrun: invalida nested view must fit its parent view, not just the bufferbounds off by one
bounds unchecked
nested view vs storage
run/err_bounds_past_endrun: invalidelements 3 and 4 of a 4-element buffer: 4 is past the endbounds off by one
bounds unchecked
run/err_bounds_raw_loadedrun: invalida raw loaded index could be anything, so the view can't be proven in boundsbounds unchecked
run/err_bounds_scalar_at_nrun: invalidelement 4 of a 4-element buffer doesn't existbounds off by one
bounds unchecked
run/err_bounds_unusedrun: invalidbounds are checked statically, even for a view nothing usesbounds unchecked
run/err_buffer_no_dtyperun: invalida buffer needs dtype=none recorded
run/err_buffer_no_slotrun: invalidbuffer needs slot=none recorded
run/err_buffer_size_zerorun: invalida buffer has at least one elementnone recorded
run/err_data_dtyperun: invaliddata values must be literals of the buffer's dtypedata dtype unchecked
run/err_data_lengthrun: invaliddata= must give exactly n valuesdata length unchecked
run/err_duplicate_slotrun: invalidslots are uniqueduplicate slots ok
run/err_duplicate_slot_identicalrun: invalidtwo identical buffer statements are still two buffers sharing a slotduplicate slots ok
identical buffers merge
run/err_load_valuerun: invalidload reads memory, not a valuenone recorded
run/err_mem_alu_operandrun: invalidmemory isn't a value: load it firstnone recorded
run/err_mem_assertrun: invalidassert compares values, not memorymemory as ALU operand ok
run/err_mem_call_argrun: invalidmemory can't be passed to a callnone recorded
run/err_mem_in_call_bodyrun: invalidmemory can't be used inside a call bodymemory in call body ok
run/err_mem_stackrun: invalidmemory can't be stackedmemory as ALU operand ok
run/err_offset_f32run: invalidoffsets are i32none recorded
run/err_old_version_needed_laterun: invalidthe offset of a load from the old version depends on the new version: no order worksloads not before stores
no ordering cycle check
run/err_shrink_no_shaperun: invalidshrink needs shape=none recorded
run/err_store_dtyperun: invalidthe stored value must have the view's dtypestore type unchecked
run/err_store_into_valuerun: invalidstore writes into memory, not into a valuenone recorded
run/err_store_shaperun: invalidthe stored value must have the view's shapestore type unchecked
run/err_two_stores_one_versionrun: invalidtwo stores into the same version are unorderedtwo stores per version
run/err_two_stores_unsequenced_secondrun: invalida second store into a version is invalid even if only one is sequencednone recorded
run/err_unsequenced_storerun: invalida store no after sequences has no effect, so it's an errorunsequenced store ok
run/err_view_alu_operandrun: invalida view isn't a value eithermemory as ALU operand ok
run/fail_memory_assertrun: assert_faila failing assert on a loaded valueevaluates everything
run/load_after_values_in_callrun: passloaded values (not memory) can be call argsevaluates everything
run/loaded_div_zerorun: invalida runtime error in a value an assert depends on: dividing by a loaded zerodiv by zero returns 0
run/special_float_datarun: passdata can hold nan, inf, -inf and -0.0-0.0 != 0.0 in assert
NaN != NaN in assert
evaluates everything
load ignores the offset
recip 0 ignores sign
run/swaprun: passswap two elements: both loads read the original versionevaluates everything
load ignores the offset
loads not before stores
run/unread_store_okrun: passa sequenced store that no assert reads is fineevaluates everything
run/view_rank1_loadrun: passshape=[k] views k elements starting at the offsetevaluates everything
load ignores the offset
run/view_rank1_storerun: passstore a rank-1 value into a [k] viewevaluates everything
rank-1 store writes one
run/view_shrink_of_shrinkrun: passoffsets add: shrink 1 then shrink 2 lands on element 3evaluates everything
load ignores the offset
shrink offsets don't add
run/view_shrink_of_shrink_storerun: passa store through a nested view writes the right elementevaluates everything
shrink offsets don't add
run/view_whole_load_indexrun: passload a whole buffer, then index the rank-1 valueevaluates everything