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

How to use this

Run python tools/test.py --compiler PATH --week 1 -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
run/basic_addrun: passthe syllabus examplenone recorded
run/basic_chainrun: passnames refer to earlier statementsnone recorded
run/call_basicrun: passthe spec's first call exampleevaluates everything
run/call_closed_bodyrun: passsubstitution must not go inside a nested call's body: inner's param 0 is NOT outer's param 0evaluates everything
nested body sees outer env
run/call_compositionrun: passf(f(x)) built from callsevaluates everything
global memo across calls
nested body sees outer env
run/call_extra_argsrun: passextra args are ignorednone recorded
run/call_f32_boolrun: passparams of other dtypesglobal memo across calls
where branches swapped
run/call_memo_per_callrun: passthe same body called with different args gives different results (memoize per call, not globally)global memo across calls
run/call_no_paramsrun: passa body with no params is just a valuenone recorded
run/call_rank1_paramrun: passa param can be rank 1none recorded
run/call_runtime_error_insiderun: invalida runtime error inside a call body is still a runtime errordiv by zero returns 0
run/call_shared_param_noderun: passtwo functions that use the same param node (hash consed) still mean different thingsnone recorded
run/call_spec_inner_outerrun: passthe spec's closed-body examplenone recorded
run/call_two_paramsrun: passarg i binds param inone recorded
run/cast_basicrun: passcast rules from the specbool->num always 1
f32->i32 rounds
i32->f32 not rounded
run/cast_i32_edgesrun: passthe largest f32 below 2^31 still fits in i32i32->f32 not rounded
run/cmplt_basicrun: passcmplt is strict less-than and returns boolcmplt is <=
run/cmplt_nan_zerorun: passany NaN compare is false; -0.0 is not less than 0.0cmplt is <=
run/comments_whitespacerun: passcomments, blank lines, and extra spacesnone recorded
run/const_dtyperun: passconst with an explicit dtypenone recorded
run/dag_sharing_300run: pass300 levels of doubling: a tree walk is 2^300 steps, a memoized DAG walk is 300add doesn't wrap
no memoization
run/dag_sharing_mixrun: passevery level uses the previous one twice, so it needs memoizationno memoization
run/empty_programrun: passa program with no asserts trivially passesnone recorded
run/err_alu_rank1run: invalidALU ops only take scalarsimplicit broadcast allowed
run/err_arityrun: invalidadd takes exactly two operandsnone recorded
run/err_assert_shaperun: invalidassert needs matching shapesnone recorded
run/err_attr_before_operandrun: invalidoperands come before attributesattributes before operands
run/err_attr_duplicaterun: invalidan attribute can be given onceduplicate attributes allowed
run/err_attr_unknownrun: invalidadd takes no attributes. Unknown attributes are errors, not ignoredunknown attributes ignored
run/err_call_missing_argrun: invalidevery param in the body needs an argmissing args not checked
run/err_call_missing_arg_unusedrun: invalidarg checks are static: this call is never evaluated, but it's still a type errormissing args not checked
run/err_call_shape_mismatchrun: invalidarg shape must match the paramarg types not checked
run/err_call_type_mismatchrun: invalidarg dtype must match the paramarg types not checked
run/err_call_type_unusedrun: invalidarg dtype checks are static tooarg types not checked
run/err_call_void_bodyrun: invalida void body can't be calledvoid operands allowed
run/err_cast_big_i32run: invalid2^31 doesn't fit in i32f32->i32 no range check
run/err_cast_inf_i32run: invalidinf can't become an i32none recorded
run/err_cast_nan_i32run: invalidNaN can't become an i32none recorded
run/err_div_zerorun: invaliddiv by zero is a runtime errordiv by zero returns 0
run/err_index_f32run: invalidthe index must be i32none recorded
run/err_index_negrun: invalidnegative indexindex allows negative
run/err_index_oobrun: invalidindex past the endnone recorded
run/err_int_too_bigrun: invalidinteger literals must fit in i32int literals unbounded
run/err_literal_hexrun: invalidno hex literalsnone recorded
run/err_literal_infinityrun: invalidthe word is inf, not infinityloose float literals
run/err_literal_plusrun: invalida literal can't start with +none recorded
run/err_literal_underscorerun: invalidno digit separatorsnone recorded
run/err_mod_zerorun: invalidmod by zero is a runtime errordiv by zero returns 0
run/err_param_outside_callrun: invalida param evaluated outside any call is a runtime errorparam outside call is 0
run/err_param_two_typesrun: invalidone slot can't be two types inside one bodynone recorded
run/err_param_two_types_brun: invalidsame as err_param_two_types with the uses in the other order: check every use, not just the first or lastparam slot types unchecked
run/err_param_two_types_uncalledrun: invalidone slot used with two types is a static error even if the body is never calledparam slot types unchecked
slot types checked on call only
run/err_parserun: invalida line that isn't a statementnone recorded
run/err_redefinerun: invalida name can be defined onceredefinition allowed
run/err_shape_rank2run: invalidweek 1 shapes are [k] with one k >= 1none recorded
run/err_shape_zerorun: invalida shape of [0] isn't allowed in week 1none recorded
run/err_shl_32run: invalidshift amounts outside [0, 31] are runtime errorsshl allows 32
run/err_shl_negrun: invalidshift amounts outside [0, 31] are runtime errorsnone recorded
run/err_stack_mixedrun: invalidstack operands must share a dtypestack dtypes unchecked
run/err_stack_mixed_shapesrun: invalidstack operands must share one shape (stacking vectors is fine from week 5; mixing shapes never is)none recorded
run/err_type_assertrun: invalidassert needs matching dtypesnone recorded
run/err_type_bool_addrun: invalidadd is not defined on boolnone recorded
run/err_type_cast_voidrun: invalidyou can't cast to voidnone recorded
run/err_type_cmplt_boolrun: invalidcmplt is defined on numbers onlynone recorded
run/err_type_div_f32run: invaliddiv is i32 onlynone recorded
run/err_type_mixrun: invalidno implicit conversion between i32 and f32implicit dtype mixing
run/err_type_recip_i32run: invalidrecip is f32 onlynone recorded
run/err_type_staticrun: invalidtype errors are static: this bad line is never evaluated, but the program is still invalidimplicit dtype mixing
run/err_type_void_operandrun: invalidan assert's value (void) can't be an operandvoid operands allowed
run/err_type_where_branchesrun: invalidwhere branches must have the same dtypenone recorded
run/err_type_where_condrun: invalidwhere needs a bool conditionnone recorded
run/err_type_xor_f32run: invalidxor is not defined on f32none recorded
run/err_undefinedrun: invalidnames must be defined before usenone recorded
run/err_unknown_oprun: invalidunknown opnone recorded
run/err_use_before_defrun: invalidnames must be defined above their first usenone recorded
run/err_where_strictrun: invalidwhere is strict: an error in the untaken branch is still an errornone recorded
run/error_before_failrun: invalidan error in an earlier assert wins over a later failureasserts in reverse order
run/f32_assert_equalityrun: passassert compares f32 by value, and NaN counts as equal to NaN-0.0 != 0.0 in assert
NaN != NaN in assert
run/f32_literalsrun: passfloat literal formsf32 consts not rounded
run/f32_nan_sourcesrun: passinf - inf and inf * 0 are NaNNaN != NaN in assert
run/f32_overflowrun: passf32 overflow goes to inff32 ops not rounded
run/f32_product_roundsrun: passevery op rounds to f32, so 3 * (1/3) is exactly 1 but 1/3 is not 0.333333333cmplt is <=
f32 consts not rounded
f32 ops not rounded
run/f32_reciprun: passrecip, including signed zero and infrecip 0 ignores sign
run/f32_rounding_steprun: passf32 has 24 bits of mantissa: 2^24 + 1 rounds back to 2^24f32 ops not rounded
run/f32_signed_zero_visiblerun: pass-0.0 and 0.0 compare equal but recip tells them apartrecip 0 ignores sign
run/f32_tenthsrun: passin f32, 0.1 + 0.2 rounds to exactly 0.3 (unlike f64)f32 consts not rounded
run/fail_basicrun: assert_faila failing assert exits 1 and names itselfnone recorded
run/fail_before_errorrun: assert_failasserts run in file order, so this fails before the later div by zero is reachedasserts in reverse order
run/fail_first_in_orderrun: assert_failreport the first failing assert in file orderasserts in reverse order
run/fail_then_static_errorrun: invalidtype checking happens before any assert runs, so a later type error beats an earlier failing assertimplicit dtype mixing
run/hash_consing_same_noderun: passidentical statements are one node. Nothing observable changes, but the program must still worknone recorded
run/i32_div_intminrun: passINT_MIN / -1 wraps to INT_MIN, and INT_MIN mod -1 is 0none recorded
run/i32_div_truncrun: passdiv truncates toward zero, like C (not floor like Python)div floors like Python
run/i32_mod_signrun: passmod takes the sign of the dividend, like Cdiv floors like Python
mod uses Python %
run/i32_shlrun: passshl wrapsshl doesn't wrap
run/i32_wrap_addrun: passi32 add wraps around (two's complement)add doesn't wrap
run/i32_wrap_mulrun: passi32 mul keeps the low 32 bitsmul doesn't wrap
run/lazy_unused_runtime_errorrun: passruntime errors only matter if an assert depends on themnone recorded
run/literal_float_formsrun: pass1., .5, -.5, 1E5 and 1e+5 are all float literalsnone recorded
run/literal_float_out_of_rangerun: passa float literal too big for f32 rounds to inf, and one too small rounds to 0none recorded
run/max_basicrun: passmax on i32 and f32none recorded
run/max_nanrun: passmax propagates NaN from either sideNaN != NaN in assert
max ignores NaN
run/max_signed_zerorun: passmax(-0.0, 0.0) is +0.0 in either order, and recip tells the zeros apartmax(-0.0, 0.0) order-dependent
run/stack_assertrun: passassert compares rank-1 values elementwisenone recorded
run/stack_assert_failrun: assert_failone element differsnone recorded
run/stack_f32_boolrun: passstack works for any dtype-0.0 != 0.0 in assert
run/stack_indexrun: passstack builds a rank-1 value, index reads itnone recorded
run/where_basicrun: passwhere picks a branchwhere branches swapped
run/xor_i32_boolrun: passxor is bitwise on i32 and logical on boolxor bool is equality
simplify/add_negzero_f32simplify, max_ops=0x + -0.0 IS x on f32, for every x including -0.0 and nannone recorded
simplify/add_zerosimplify, max_ops=0x + 0 -> x on i32none recorded
simplify/bounds_cmpltsimplify, max_ops=0max(x, 0) mod 8 is in [0, 7], so it is always < 8none recorded
simplify/bounds_cmplt_falsesimplify, max_ops=0max(x, 0) is never < 0none recorded
simplify/bounds_div_elimsimplify, max_ops=0a value in [0, 7] div 8 is 0none recorded
simplify/bounds_maxsimplify, max_ops=0max(b, 5) where b is in [0, 1] is 5none recorded
simplify/bounds_mod_elimsimplify, max_ops=1a value in [0, 1] mod 4 is itselfnone recorded
simplify/call_inlinesimplify, max_ops=0inline the call, then simplify through itno call inlining
simplify/cast_samesimplify, max_ops=0a cast to the same dtype is a no-opnone recorded
simplify/chain_of_identitiessimplify, max_ops=0a pile of no-opsnone recorded
simplify/cmplt_selfsimplify, max_ops=0x < x -> false (also true for f32: nan < nan is false)none recorded
simplify/const_foldsimplify, max_ops=1fold the constant partnone recorded
simplify/div_mul_boundedsimplify, max_ops=1(b * 2) / 2 -> b when bounds prove b * 2 can't wrapdiv elim off by one
no hash consing
simplify/index_stacksimplify, max_ops=0index of a stack with a const index picks the elementnone recorded
simplify/mul_one_f32simplify, max_ops=0x * 1.0 -> x is exact on f32, even for nan and -0.0none recorded
simplify/mul_zero_i32simplify, max_ops=0x * 0 -> 0 on i32none recorded
simplify/reassoc_i32simplify, max_ops=1(1 + x) + 2 -> x + 3: i32 is a ring mod 2^32, so reassociation is safe even with wraparoundno const-right canonicalize
simplify/shared_subexprsimplify, max_ops=2hash consing: (x*x) + (x*x) is two ops, not threeno hash consing
simplify/trap_add_zero_f32simplify, max_ops=1TRAP: x + 0.0 is NOT x on f32: -0.0 + 0.0 is +0.0, and the grader compares bit patternsi32 rules applied to f32
x + 0.0 -> x on f32
simplify/trap_bounds_edgesimplify, max_ops=3TRAP: a value in [0, 7] is not always < 7cmplt bounds off by one
simplify/trap_bounds_wrapsimplify, max_ops=3TRAP: max(x, 0) + 1 wraps to INT_MIN when x = INT_MAX, so it CAN be < 0bounds clamp instead of wrap
simplify/trap_div_elim_edgesimplify, max_ops=3TRAP: a value in [0, 7] div 7 is not always 0div elim off by one
simplify/trap_div_mul_wrapsimplify, max_ops=2TRAP: (x * 2) / 2 is NOT x on i32 (2^30 * 2 wraps)(x*c)/c ignores wrap
simplify/trap_f32_reassocsimplify, max_ops=2TRAP: (x + 1e8) - 1e8 is NOT x on f32 (1.0 + 1e8 rounds to 1e8)i32 rules applied to f32
simplify/trap_minus_one_lesssimplify, max_ops=2TRAP: x - 1 < x is false at INT_MIN (it wraps to INT_MAX)none recorded
simplify/trap_mod_negativesimplify, max_ops=3TRAP: x mod 8 can be negative (sign follows x), so this can't foldmod bounds ignore sign
simplify/trap_mul_zero_f32simplify, max_ops=1TRAP: x * 0.0 is NOT 0.0 on f32 (nan * 0 = nan, inf * 0 = nan)i32 rules applied to f32
x*0 -> 0 on f32
simplify/trap_nested_callsimplify, max_ops=1TRAP: inline correctly. The param 0 of inner is bound by outer's call, not by out's argsno call inlining
top-down inline enters bodies
simplify/trap_xor_two_boolssimplify, max_ops=1TRAP: xor of two different params can't foldnone recorded
simplify/where_const_condsimplify, max_ops=0the condition folds, then the where doesnone recorded
simplify/where_samesimplify, max_ops=0where c x x -> xnone recorded
simplify/xor_selfsimplify, max_ops=0x ^ x -> 0none recorded
simplify/zero_addsimplify, max_ops=00 + x -> x: put consts on the right firstno const-right canonicalize