def test_peephole_twoconstant_sources(): src = ''' @kernel def main(): a = 1 b = 12 c = a + b d = b - a e = a | b a = -2 b = 3 f = b & a g = a * b ''' compiler = Compiler() main_object = compiler.compile(src)[0] main_object = compiler.opt_peephole(main_object) code = [InstrAdapter(x) for x in main_object.code] pattern = ''' imm a@0,1 imm b@0,12 imm c@0,13 imm d@0,11 imm e@0,13 imm a@1,-2 imm b@1,3 imm f@0,2 imm g@0,-6 '''.strip() assert match_code(code, pattern)
def test_builtin_transfer(): ''' Test the transfer builtin functions. ''' compiler = Compiler() src = ''' @kernel def main(): a = 3 b = transferFromNorth(a) c = transferFromEast(b) d = transferFromSouth(c) e = transferFromWest(d) ''' kernel_objects= compiler.compile(src) main_object = kernel_objects[0] code = [InstrAdapter(x) for x in main_object.code] pattern = ''' imm a@0, 3 mov out, a@0 mov b@0, north mov out, b@0 mov c@0, east mov out, c@0 mov d@0, south mov out, d@0 mov d@0, west '''.strip() assert match_code(code, pattern)
def test_peephole_addorsub_zero(): ''' Test if an addition/subtraction with a zero operand is converted into a mov instr. ''' src = ''' @kernel def main(a): b = a | 0 c = a + 0 d = a - 0 e = 0 - a # unoptimised case f = 4 g = 3 h = f + g i = f - g ''' compiler = Compiler() main_object = compiler.compile(src)[0] main_object = compiler.opt_peephole(main_object) code = [InstrAdapter(x) for x in main_object.code] pattern = ''' imm tmp_0@0,0 mov b@0,a@0 imm tmp_1@0,0 mov c@0,a@0 imm tmp_2@0,0 mov d@0,a@0 imm tmp_3@0,0 sub e@0,tmp_3@0,a@0 imm f@0,4 imm g@0,3 imm h@0,7 imm i@0,1 '''.strip() assert match_code(code, pattern)
def test_simple_loop_emit(): compiler = Compiler() src = ''' @kernel def main(): b = 5 for i in range(2): b = i ''' kernel_objects= compiler.compile(src) main_object = kernel_objects[0] code = [InstrAdapter(x) for x in main_object.code] pattern = ''' imm b@0, 5 ximm tmp_0@0, 2 xlabel loop_intro_1 ximm i@0, 0 ximm inc_1@0, 1 xlabel for_2 ximm tmp_3@0, 0 xemit tmp_5@0, i@1 imm tmp_6@0, 0 xcmp i@1, tmp_3@0 xphi {EQ} tmp_8@0, i@0, i@1 xmov b@1, tmp_8@0 xadd i@1, tmp_8@0, inc_1@0 xcmp i@1, tmp_0@0 xjmp {LT} for_2 '''.strip() assert match_code(code, pattern)
def test_get2D_copy_propagation(): ''' Test the get2D builtin, this code fetches a value from a 2D buffer with boundary handling. The difference with the previous test is that it also runs the copy propagation optimiser. ''' compiler = Compiler() main_object = compiler.compile(get2D_simple_src)[0] print '\n'.join(str(InstrAdapter(x)) for x in main_object.code) main_object = compiler.opt_copy_propagation(main_object) code = [InstrAdapter(x) for x in main_object.code] pattern = ''' imm in_ptr@0, 0 imm bwidth@0, 8 imm bheight@0, 8 imm tmp_0@0, 0 lid y@0, tmp_0@0 imm tmp_1@0, 1 lid x@0, tmp_1@0 imm cg_tmp_1@0, 0 imm cg_tmp_2@0, 0 add cg_tmp_3@0, x@0, bwidth@0 cmp x@0, cg_tmp_1@0 phi {LT} cg_tmp_6@0, cg_tmp_3@0, x@0 sub cg_tmp_7@0, cg_tmp_6@0, bwidth@0 cmp x@0, bwidth@0 phi {GE} cg_tmp_8@0, cg_tmp_7@0, cg_tmp_6@0 add cg_tmp_9@0, y@0, bheight@0 cmp y@0, cg_tmp_2@0 phi {LT} cg_tmp_12@0, cg_tmp_9@0, y@0 sub cg_tmp_13@0, cg_tmp_12@0, bheight@0 cmp y@0, bheight@0 phi {GE} cg_tmp_14@0, cg_tmp_13@0, cg_tmp_12@0 mul cg_tmp_15@0, cg_tmp_14@0, bwidth@0 add cg_tmp_16@0, cg_tmp_15@0, cg_tmp_8@0 add cg_tmp_17@0, in_ptr@0, cg_tmp_16@0 memr cg_tmp_19@0, cg_tmp_17@0 mov out, cg_tmp_19@0 mov cg_tmp_20@0, west cmp x@0, cg_tmp_1@0 phi {LT} cg_tmp_21@0, cg_tmp_20@0, cg_tmp_19@0 mov out, cg_tmp_21@0 mov cg_tmp_22@0, east cmp x@0, bwidth@0 phi {GE} cg_tmp_23@0, cg_tmp_22@0, cg_tmp_21@0 mov out, cg_tmp_23@0 mov cg_tmp_24@0, north cmp y@0, cg_tmp_2@0 phi {LT} cg_tmp_25@0, cg_tmp_24@0, cg_tmp_23@0 mov out, cg_tmp_25@0 mov cg_tmp_26@0, south cmp y@0, bheight@0 phi {GE} cg_tmp_27@0, cg_tmp_26@0, cg_tmp_25@0 ''' assert match_code(code, pattern)
def test_undefined_variable_detection(): ''' Test if an undefined variable gives the correct error. ''' compiler = Compiler() src = ''' @kernel def main(a): b = 3 a += 1 c = a + d ''' try: main_object = compiler.compile(src)[0] except UndefinedVariableException, e: print str(e) return # correct execution
def test_builtin_loadwest(): compiler = Compiler() src = ''' @kernel def main(): b = loadWest() ''' kernel_objects= compiler.compile(src) main_object = kernel_objects[0] main_object = compiler.replace_phi_nodes(main_object) code = [InstrAdapter(x) for x in main_object.code] pattern = ''' mov b@0, west '''.strip() assert match_code(code, pattern)
def test_compile_add(): compiler = Compiler() src = ''' @kernel def main(): b = 4 a = b + 2 ''' kernel_objects= compiler.compile(src) main_object = kernel_objects[0] code = [InstrAdapter(x) for x in main_object.code] pattern = ''' imm b@0,4 imm tmp_0@0,2 add a@0,b@0,tmp_0@0 '''.strip() assert match_code(code, pattern)
def test_inplace_operator(): compiler = Compiler() src = ''' @kernel def main(): b = 5 b += 1 ''' kernel_objects= compiler.compile(src) main_object = kernel_objects[0] code = [InstrAdapter(x) for x in main_object.code] pattern = ''' imm b@0,5 imm tmp_0@0,1 add b@1,b@0,tmp_0@0 '''.strip() assert match_code(code, pattern)
def test_builtin_sendout(): compiler = Compiler() src = ''' @kernel def main(): a = 3 sendOut(a) ''' kernel_objects= compiler.compile(src) main_object = kernel_objects[0] main_object = compiler.replace_phi_nodes(main_object) code = [InstrAdapter(x) for x in main_object.code] pattern = ''' imm a@0, 3 mov out, a@0 '''.strip() assert match_code(code, pattern)
def test_compile_conditional(): compiler = Compiler() src = ''' @kernel def main(a): b = 3 if a > 0 else 1 return b ''' kernel_objects= compiler.compile(src) main_object = kernel_objects[0] code = [InstrAdapter(x) for x in main_object.code] pattern = ''' imm tmp_0@0,0 imm tmp_2@0,3 imm tmp_3@0,1 cmp a@0,tmp_0@0 phi {GT} b@0,tmp_2@0,tmp_3@0 mov main___return@0,b@0 '''.strip() assert match_code(code, pattern)
def test_replace_phi_nodes(): compiler = Compiler() src = ''' @kernel def main(a): b = 3 if a > 0 else 1 ''' kernel_objects= compiler.compile(src) main_object = kernel_objects[0] main_object = compiler.replace_phi_nodes(main_object) code = [InstrAdapter(x) for x in main_object.code] pattern = ''' imm tmp_0@0,0 imm tmp_2@0,3 imm tmp_3@0,1 cmp a@0,tmp_0@0 mov b@0,tmp_3@0 mov {GT} b@0,tmp_2@0 '''.strip() assert match_code(code, pattern)
def test_simple_loop_emit_noseq(): compiler = Compiler(no_sequencer=True) src = ''' @kernel def main(): b = 5 for i in range(2): b = i ''' kernel_objects= compiler.compile(src) main_object = kernel_objects[0] code = [InstrAdapter(x) for x in main_object.code] pattern = ''' imm b@0,5 imm i@0,0 mov b@1,i@0 imm i@1,1 mov b@2,i@1 '''.strip() assert match_code(code, pattern)
def test_patch_reg_arguments(): ''' Patching of arguments before run, now with registers as arguments. ''' from blip.code.BlipCompiler import Compiler, NamedValue src = ''' @kernel def main(p, q): b = p - 2 return q + b ''' compiler = Compiler() main_object = compiler.compile(src)[0] patched_object = Compiler.patch_arguments_before_run(main_object, [NamedValue('test_value@0'), 41]) code = [InstrAdapter(x) for x in patched_object.code] pattern = ''' mov p@0,test_value@0 imm q@0,41 imm tmp_0@0,2 sub b@0,p@0,tmp_0@0 add tmp_1@0,q@0,b@0 mov main___return@0,tmp_1@0 '''.strip() assert match_code(code, pattern)
def test_get2D(): ''' Test the get2D builtin, this code fetches a value from a 2D buffer with boundary handling. ''' compiler = Compiler() main_object = compiler.compile(get2D_simple_src)[0] code = [InstrAdapter(x) for x in main_object.code] pattern = ''' # initiate parameters imm in_ptr@0, 0 imm bwidth@0, 8 imm bheight@0, 8 imm tmp_0@0, 0 lid y@0, tmp_0@0 imm tmp_1@0, 1 lid x@0, tmp_1@0 # copy parameters mov cg_tmp_18@0, in_ptr@0 mov cg_tmp_4@0, x@0 mov cg_tmp_10@0, y@0 mov cg_tmp_5@0, bwidth@0 mov cg_tmp_11@0, bheight@0 # start of get2D imm cg_tmp_1@0, 0 imm cg_tmp_2@0, 0 add cg_tmp_3@0, cg_tmp_4@0, cg_tmp_5@0 # cg_tmp_3 = x + bwidth cmp cg_tmp_4@0, cg_tmp_1@0 # comp x, 0 phi {LT} cg_tmp_6@0, cg_tmp_3@0, cg_tmp_4@0 # cg_tmp_6 = phi(x < 0, cg_tmp_3, x) sub cg_tmp_7@0, cg_tmp_6@0, cg_tmp_5@0 # cg_tmp_7 = cg_tmp_6 - bwidth cmp cg_tmp_4@0, cg_tmp_5@0 # comp x, bwidth phi {GE} cg_tmp_8@0, cg_tmp_7@0, cg_tmp_6@0 # cg_tmp_4 = phi(x >= bwidth, cg_tmp_7, cg_tmp_6) add cg_tmp_9@0, cg_tmp_10@0, cg_tmp_11@0 # cg_tmp_9 = y + bheight cmp cg_tmp_10@0, cg_tmp_2@0 phi {LT} cg_tmp_12@0, cg_tmp_9@0, cg_tmp_10@0 sub cg_tmp_13@0, cg_tmp_12@0, cg_tmp_11@0 cmp cg_tmp_10@0, cg_tmp_11@0 phi {GE} cg_tmp_14@0, cg_tmp_13@0, cg_tmp_12@0 mul cg_tmp_15@0, cg_tmp_14@0, cg_tmp_5@0 add cg_tmp_16@0, cg_tmp_15@0, cg_tmp_8@0 add cg_tmp_17@0, cg_tmp_18@0, cg_tmp_16@0 memr cg_tmp_19@0, cg_tmp_17@0 mov out, cg_tmp_19@0 mov cg_tmp_20@0, west cmp cg_tmp_4@0, cg_tmp_1@0 phi {LT} cg_tmp_21@0, cg_tmp_20@0, cg_tmp_19@0 mov out, cg_tmp_21@0 mov cg_tmp_22@0, east cmp cg_tmp_4@0, cg_tmp_5@0 phi {GE} cg_tmp_23@0, cg_tmp_22@0, cg_tmp_21@0 mov out, cg_tmp_23@0 mov cg_tmp_24@0, north cmp cg_tmp_10@0, cg_tmp_2@0 phi {LT} cg_tmp_25@0, cg_tmp_24@0, cg_tmp_23@0 mov out, cg_tmp_25@0 mov cg_tmp_26@0, south cmp cg_tmp_10@0, cg_tmp_11@0 phi {GE} cg_tmp_27@0, cg_tmp_26@0, cg_tmp_25@0 mov cg_tmp_28@0, cg_tmp_27@0 mov v@0, cg_tmp_28@0 '''.strip() assert match_code(code, pattern)