def test_gt_mem_f(): lib = load_bundle( """ .funcsig sig = (double uptr<double>) -> (int<64>) .funcdef test_gt_mem_f <sig> { entry(<double> x <uptr<double>> ptr): y = LOAD PTR <double> ptr cond = FOGT <double> x y BRANCH2 cond ret1() ret0() ret1(): RET <int<64>> 1 ret0(): RET <int<64>> 0 } """, "test_gt_mem_f") zero = ctypes.c_double(0) ptr = ctypes.addressof(zero) cmp_gt_zero = get_function(lib.test_gt_mem_f, [ctypes.c_double, ctypes.c_voidp], ctypes.c_int64) assert (cmp_gt_zero(ctypes.c_double(1), ptr) == 1) assert (cmp_gt_zero(ctypes.c_double(0), ptr) == 0) assert (cmp_gt_zero(ctypes.c_double(-1), ptr) == 0)
def test_gt_mem_r(): lib = load_bundle( """ .funcsig sig = (int<64> uptr<int<64>>) -> (int<64>) .funcdef test_gt_mem_r <sig> { entry(<int<64>> x <uptr<int<64>>> ptr): y = LOAD PTR <int<64>> ptr cond = SGT <int<64>> x y BRANCH2 cond ret1() ret0() ret1(): RET <int<64>> 1 ret0(): RET <int<64>> 0 } """, "test_gt_mem_r") zero = ctypes.c_int64(0) ptr = ctypes.addressof(zero) cmp_gt_zero = get_function(lib.test_gt_mem_r, [ctypes.c_int64, ctypes.c_int64], ctypes.c_int64) assert (cmp_gt_zero(ctypes.c_int64(1), ptr) == 1) assert (cmp_gt_zero(ctypes.c_int64(0), ptr) == 0) assert (cmp_gt_zero(ctypes.c_int64(-1), ptr) == 0)
def test_gt_r_mem(): lib = load_bundle( """ .funcsig sig = (uptr<int<64>> int<64>) -> (int<64>) .funcdef test_gt_r_mem <sig> { entry(<uptr<int<64>>> ptr <int<64>> y): x = LOAD PTR <int<64>> ptr cond = SGT <int<64>> x y BRANCH2 cond ret1() ret0() ret1(): RET <int<64>> 1 ret0(): RET <int<64>> 0 } """, "test_gt_r_mem") zero = ctypes.c_int64(0) ptr = ctypes.addressof(zero) cmp_gt_zero = get_function(lib.test_gt_r_mem, [ctypes.c_int64, ctypes.c_int64], ctypes.c_int64) assert (cmp_gt_zero(ptr, ctypes.c_int64(1)) == 0) assert (cmp_gt_zero(ptr, ctypes.c_int64(0)) == 0) assert (cmp_gt_zero(ptr, ctypes.c_int64(-1)) == 1)
def test_gt_f_mem(): lib = load_bundle( """ .funcsig sig = (uptr<double> double) -> (int<64>) .funcdef test_gt_f_mem <sig> { entry(<uptr<double>> ptr <double> y): x = LOAD PTR <double> ptr cond = FOGT <double> x y BRANCH2 cond ret1() ret0() ret1(): RET <int<64>> 1 ret0(): RET <int<64>> 0 } """, "test_gt_f_mem") zero = ctypes.c_double(0) ptr = ctypes.addressof(zero) cmp_gt_zero = get_function(lib.test_gt_f_mem, [ctypes.c_voidp, ctypes.c_double], ctypes.c_int64) assert (cmp_gt_zero(ptr, ctypes.c_double(1)) == 0) assert (cmp_gt_zero(ptr, ctypes.c_double(0)) == 0) assert (cmp_gt_zero(ptr, ctypes.c_double(-1)) == 1)
def test_nest_loop(): lib = load_bundle( """ .funcdef nest_loop<(int<64>) -> (int<64>)> { entry(<int<64>> n): BRANCH outer_header(n <int<64>> 0 <int<64>> 0) outer_header(<int<64>> n <int<64>> i <int<64>> sum): outer_cond = SLT <int<64>> i n BRANCH2 outer_cond outer_body(n i sum) exit(sum) outer_body(<int<64>> n <int<64>> i <int<64>> sum): BRANCH inner_header(n i <int<64>> 0 sum) outer_step(<int<64>> n <int<64>> i <int<64>> sum): i2 = ADD <int<64>> i <int<64>> 1 BRANCH outer_header(n i2 sum) inner_header(<int<64>> n <int<64>> i <int<64>> j <int<64>> sum): inner_cond = SLT <int<64>> j i BRANCH2 inner_cond inner_body(n i j sum) outer_step(n i sum) inner_body(<int<64>> n <int<64>> i <int<64>> j <int<64>> sum): sum2 = ADD <int<64>> sum j j2 = ADD <int<64>> j <int<64>> 1 BRANCH inner_header(n i j2 sum2) exit(<int<64>> sum): RET sum } """, "nest_loop") nest_loop = get_function(lib.nest_loop, [ctypes.c_int64], ctypes.c_int64) assert (nest_loop(100) == 161700)
def test_from_ref_imm(): lib = load_bundle(""" .funcdef tr64_from_tag <(int<6>)->(tagref64)> { entry(<int<6>> tag): res = COMMINST uvm.tr64.from_ref(<ref<void>>NULL tag) RET res }""", "tr64_from_tag"); # type: ctypes.CDLL tr64_from_tag = get_function(lib.tr64_from_tag, [ctypes.c_uint8], ctypes.c_uint64); assert(tr64_from_tag(0x00) == 0x7ff0000000000002); assert(tr64_from_tag(0x3f) == 0x7fff800000000006);
def test_to_ref(): lib = load_bundle(""" .funcdef tr64_to_ref <(tagref64)->(ref<void>)> { entry(<tagref64> tr): res = COMMINST uvm.tr64.to_ref(tr) RET res } """, "tr64_to_ref"); # type: ctypes.CDLL tr64_to_ref = get_function(lib.tr64_to_ref, [ctypes.c_uint64], ctypes.c_void_p); assert(tr64_to_ref(0x7ff0555555555552) == 0x555555555550); assert(tr64_to_ref(0xfff02aaaaaaaaaaa) == 0xffffaaaaaaaaaaa8);
def test_is_ref(): lib = load_bundle(""" .funcdef tr64_is_ref <(tagref64)->(int<1>)> { entry(<tagref64> tr): res = COMMINST uvm.tr64.is_ref (tr) RET res } """, "tr64_is_ref"); # type: ctypes.CDLL tr64_is_ref = get_function(lib.tr64_is_ref, [ctypes.c_uint64], ctypes.c_bool); assert(tr64_is_ref(0x7ff0000000000002)); assert(tr64_is_ref(0xfff0000000000002)); assert(tr64_is_ref(0xfffffffffffffffe));
def test_div2(): lib = load_bundle( """ .funcdef div2<(int<64>) -> (int<64>)> { entry(<int<64>> x): res = UDIV <int<64>> x <int<64>> 2 RET res } """, "div2") div2 = get_function(lib.div2, [ctypes.c_uint64], ctypes.c_uint64) assert (div2(6) == 3)
def test_div(): lib = load_bundle( """ .funcdef div<(int<64> int<64>) -> (int<64>)> { entry(<int<64>> x <int<64>> y): res = UDIV <int<64>> x y RET res } """, "div") div = get_function(lib.div, [ctypes.c_uint64], ctypes.c_uint64) assert (div(6, 2) == 3)
def test_from_int(): lib = load_bundle(""" .funcdef tr64_from_int <(int<52>)->(tagref64)> { entry(<int<52>> val): res = COMMINST uvm.tr64.from_int(val) RET res } """, "tr64_from_int"); # type: ctypes.CDLL tr64_from_int = get_function(lib.tr64_from_int, [ctypes.c_uint64], ctypes.c_uint64); assert(tr64_from_int(0x0000000000000) == 0x7ff0000000000001); assert(tr64_from_int(0xfffffffffffff) == 0xffffffffffffffff); assert(tr64_from_int(0x5555555555555) == 0x7ffaaaaaaaaaaaab); assert(tr64_from_int(0xaaaaaaaaaaaaa) == 0xfff5555555555555);
def test_from_ref(): lib = load_bundle(""" .funcdef tr64_from_ref <(ref<void> int<6>)->(tagref64)> { entry(<ref<void>>%ref <int<6>> tag): res = COMMINST uvm.tr64.from_ref(%ref tag) RET res } """, "tr64_from_ref"); # type: ctypes.CDLL tr64_from_ref = get_function(lib.tr64_from_ref, [ctypes.c_void_p, ctypes.c_uint8], ctypes.c_uint64); assert(tr64_from_ref(0x000000000000, 0x00) == 0x7ff0000000000002); assert(tr64_from_ref(0x7ffffffffff8, 0x00) == 0x7ff07ffffffffffa); assert(tr64_from_ref(0xfffffffffffffff8, 0x00) == 0xfff07ffffffffffa); assert(tr64_from_ref(0x000000000000, 0x3f) == 0x7fff800000000006);
def test_sdiv2(): lib = load_bundle( """ .funcdef sdiv2<(int<64>) -> (int<64>)> { entry(<int<64>> x): res = SDIV <int<64>> x <int<64>> 2 RET res } """, "sdiv2") sdiv2 = get_function(lib.sdiv2, [ctypes.c_int64], ctypes.c_int64) assert (sdiv2(ctypes.c_int64(6)) == 3) assert (sdiv2(ctypes.c_int64(-6)) == -3)
def test_mul2(): lib = load_bundle( """ .funcdef mul2<(int<64>) -> (int<64>)> { entry(<int<64>> x): res = MUL <int<64>> x <int<64>> 2 RET res } """, "mul2") mul2 = get_function(lib.mul2, [ctypes.c_int64], ctypes.c_int64) assert (mul2(3) == 6) assert (mul2(-3) == -6)
def test_to_tag(): lib = load_bundle(""" .funcdef tr64_to_tag <(tagref64)->(int<6>)> { entry(<tagref64> tr): res = COMMINST uvm.tr64.to_tag(tr) RET res } """, "tr64_to_tag"); # type: ctypes.CDLL tr64_to_tag = get_function(lib.tr64_to_tag, [ctypes.c_uint64], ctypes.c_uint8); assert(tr64_to_tag(0x7ff0555555555552) == 0); assert(tr64_to_tag(0x7fff800000000006) == 0x3f); assert(tr64_to_tag(0x7ffa800000000002) == 0x2a); assert(tr64_to_tag(0x7ff5000000000006) == 0x15);
def test_add(): lib = load_bundle( """ .funcdef test_add <(int<64> int<64>)->(int<64>)> { entry(<int<64>>a <int<64>>b): res = ADD <int<64>> a b RET res } """, "test_add") test_add = get_function(lib.test_add, [ctypes.c_int64, ctypes.c_int64], ctypes.c_int64) assert (test_add(1, 2) == 3) assert (test_add(-40, 60) == 20)
def test_to_fp(): lib = load_bundle(""" .funcdef tr64_to_fp <(tagref64)->(double)> { entry(<tagref64> tr): res = COMMINST uvm.tr64.to_fp(tr) RET res } """, "tr64_to_fp"); # type: ctypes.CDLL tr64_to_fp = get_function(lib.tr64_to_fp, [ctypes.c_uint64], ctypes.c_double); assert(tr64_to_fp(0x0000000000000000) == 0.0); assert(tr64_to_fp(0x8000000000000000) == -0.0); assert(tr64_to_fp(0x3ff0000000000000) == 1.0); assert(math.isnan(tr64_to_fp(0x7ff0000000000008)));
def test_to_int(): lib = load_bundle(""" .funcdef tr64_to_int <(tagref64)->(int<52>)> { entry(<tagref64> tr): res = COMMINST uvm.tr64.to_int(tr) RET res } """, "tr64_to_int"); # type: ctypes.CDLL tr64_to_int = get_function(lib.tr64_to_int, [ctypes.c_uint64], ctypes.c_uint64); assert(tr64_to_int(0x7ff0000000000001) == 0); assert(tr64_to_int(0xfff0000000000001) == 0x8000000000000); assert(tr64_to_int(0xfff5555555555555) == 0xaaaaaaaaaaaaa); assert(tr64_to_int(0x7ffaaaaaaaaaaaab) == 0x5555555555555);
def test_from_fp(): lib = load_bundle(""" .funcdef tr64_from_fp <(double)->(tagref64)> { entry(<double> val): res = COMMINST uvm.tr64.from_fp(val) RET res } """, "tr64_from_fp"); # type: ctypes.CDLL tr64_from_fp = get_function(lib.tr64_from_fp, [ctypes.c_double], ctypes.c_uint64); assert(tr64_from_fp(3.14) == transmute_float_to_int(3.14)); assert(tr64_from_fp(-3.14) == transmute_float_to_int(-3.14)); assert(tr64_from_fp(float("inf")) == 0x7ff0000000000000); assert(tr64_from_fp(transmute_int_to_float(0x7ff123456789abcd)) == 0x7ff0000000000008); assert(math.isnan(transmute_int_to_float(tr64_from_fp(transmute_int_to_float(0x7ff123456789abcd)))));
def test_is_fp(): lib = load_bundle(""" .funcdef tr64_is_fp <(tagref64)->(int<1>)> { entry(<tagref64> tr): res = COMMINST uvm.tr64.is_fp(tr) RET res } """, "tr64_is_fp"); # type: ctypes.CDLL tr64_is_fp = get_function(lib.tr64_is_fp, [ctypes.c_uint64], ctypes.c_bool); assert(tr64_is_fp(0x0)); assert(tr64_is_fp(0x123456789abcdef0)); assert(tr64_is_fp(0x7ff123456789abcc)); assert(tr64_is_fp(0xfffffffffffffffc)); assert(tr64_is_fp(transmute_float_to_int(3.1415927)));
def test_sdiv(): lib = load_bundle( """ .funcdef sdiv<(int<64> int<64>) -> (int<64>)> { entry(<int<64>> x <int<64>> y): res = SDIV <int<64>> x y RET res } """, "sdiv") sdiv = get_function(lib.sdiv, [ctypes.c_int64], ctypes.c_int64) assert (sdiv(ctypes.c_int64(6), ctypes.c_int64(2)) == 3) assert (sdiv(ctypes.c_int64(-6), ctypes.c_int64(2)) == -3) assert (sdiv(ctypes.c_int64(6), ctypes.c_int64(-2)) == -3) assert (sdiv(ctypes.c_int64(-6), ctypes.c_int64(-2)) == 3)
def test_mul(): lib = load_bundle( """ .funcdef mul<(int<64> int<64>) -> (int<64>)> { entry(<int<64>> x <int<64>> y): res = MUL <int<64>> x y RET res } """, "mul") mul = get_function(lib.mul, [ctypes.c_int64, ctypes.c_int64], ctypes.c_int64) assert (mul(3, 2) == 6) assert (mul(-3, 2) == -6) assert (mul(-3, -2) == 6)
def run_testcase(testcase, args): testcase = path(testcase).name config = ConfigParser() config.read(['default.cfg', 'main.cfg', args.config]) # overwrite config if provided in command line update_config(config, 'score', args.score) update_config(config, 'solve', args.solve) sc_fn = get_function('score', config) # get the scorer function run_folder = setup_run_folder(sys.argv, config) # where to save run information init_log(testcase) tear_down_streams = setup_stdstreams( run_folder) # get the teardown function log.debug(f'Running testcase {testcase}') with open('in/' + testcase + '.in') as f: inp = f.read() solve_args = {} for kv in args.solve_args.split(','): if '=' in kv: k, v = kv.split('=') solve_args[k] = v solve_args['log'] = log solve_args['testcase'] = testcase solve_args['folder'] = run_folder get_ans = get_ans_fn(config, inp) # get the solver function def run(solve_args): solve_args_orig = dict(solve_args) ans = get_ans(solve_args) # run the solver function and get the answer process(inp, ans, solve_args_orig, sc_fn) # add to best submission or not rounds = 1 if args.seed else args.iterations for i in range(rounds): seed = args.seed if args.seed else ri(0, 10**6 - 1) log.debug('seed: {:<6}, test#: {}'.format(seed, i)) sa = dict(solve_args) sa['iter'] = i sa['seed'] = seed run(sa) tear_down_streams()
def run_testcase(testcase, args): testcase = path(testcase).name config = ConfigParser() config.read(['default.cfg', 'main.cfg', args.config]) update_config(config, 'score', args.score) update_config(config, 'solve', args.solve) sc_fn = get_function('score', config) run_folder = setup_run_folder(sys.argv, config, testcase) init_log(testcase) tear_down_streams = setup_stdstreams(run_folder) log.debug('Running testcase {}'.format(testcase)) with open('in/' + testcase + '.in') as f: inp = f.read() solve_args = {} for kv in args.solve_args.split(','): if '=' in kv: k, v = kv.split('=') solve_args[k] = v solve_args['log'] = log solve_args['testcase'] = testcase solve_args['folder'] = run_folder orig_module_name = config.get('solve', 'module') solve_args['module_name'] = sanitize_module_name(orig_module_name) get_ans = get_ans_fn(config, inp) def run(solve_args): solve_args_orig = dict(solve_args) ans = get_ans(solve_args) process(inp, ans, solve_args_orig, sc_fn) rounds = 1 if args.seed else args.iterations for i in range(rounds): seed = args.seed if args.seed else ri(0, 10**6 - 1) log.debug('seed: {:<6}, test#: {}'.format(seed, i)) sa = dict(solve_args) sa['iter'] = i sa['seed'] = seed run(sa) tear_down_streams()
def test_eq_f_zero(): lib = load_bundle( """ .funcsig sig = (double) -> (int<8>) .funcdef test_eq_f_zero <sig> { entry(<double> x): cond = FOEQ <double> x <double> 0.00 d res = ZEXT <int<1> int<8>> cond RET res } """, "test_eq_f_zero") eq_zero = get_function(lib.test_eq_f_zero, [ctypes.c_double], ctypes.c_int8) assert (eq_zero(ctypes.c_double(0)) == 1) assert (eq_zero(ctypes.c_double(1)) == 0) assert (eq_zero(ctypes.c_double(-1)) == 0)
def test_gt_val_mem_r(): lib = load_bundle( """ .funcsig sig = (int<64> uptr<int<64>>) -> (int<8>) .funcdef test_gt_val_mem_r <sig> { entry(<int<64>> x <uptr<int<64>>> ptr): y = LOAD PTR <int<64>> ptr cond = SGT <int<64>> x y res = ZEXT <int<1> int<8>> cond RET res } """, "test_gt_val_mem_r") zero = ctypes.c_int64(0) ptr = ctypes.addressof(zero) cmp_gt_zero = get_function(lib.test_gt_val_mem_r, [ctypes.c_int64, ctypes.c_voidp], ctypes.c_int8) assert (cmp_gt_zero(ctypes.c_int64(1), ptr) == 1) assert (cmp_gt_zero(ctypes.c_int64(0), ptr) == 0) assert (cmp_gt_zero(ctypes.c_int64(-1), ptr) == 0)
def test_cmp_pattern2(): lib = load_bundle( """ .funcdef test_cmp_pattern2 <(int<64> int<64>) -> (int<64>)> { entry(<int<64>> x <int<64>> y): cond = EQ <int<64>> x y sum = ADD <int<64>> x y BRANCH2 cond ret_true(sum) ret_false(sum) ret_true(<int<64>> sum): RET <int<64>> 1 ret_false(<int<64>> sum): RET <int<64>> 0 } """, "test_cmp_pattern2") eq = get_function(lib.test_cmp_pattern2, [ctypes.c_int64, ctypes.c_int64], ctypes.c_int64) assert (eq(1, 1) == 1) assert (eq(1, 0) == 0)
def test_stack_args(): lib = load_bundle( """ .funcsig stack_sig = (double double double double double double double double double double)->(int<32>) .funcdef test_stack_args <stack_sig> { entry(<double>d0 <double>d1 <double>d2 <double>d3 <double>d4 <double>d5 <double>d6 <double>d7 <double> d8 <double> d9): ds0 = FMUL <double> d0 <double>0.0 d ds1 = FMUL <double> d1 <double>1.0 d ds2 = FMUL <double> d2 <double>2.0 d ds3 = FMUL <double> d3 <double>3.0 d ds4 = FMUL <double> d4 <double>4.0 d ds5 = FMUL <double> d5 <double>5.0 d ds6 = FMUL <double> d6 <double>6.0 d ds7 = FMUL <double> d7 <double>7.0 d ds8 = FMUL <double> d8 <double>8.0 d ds9 = FMUL <double> d9 <double>9.0 d s1 = FADD <double> ds0 ds1 s2 = FADD <double> s1 ds2 s3 = FADD <double> s2 ds3 s4 = FADD <double> s3 ds4 s5 = FADD <double> s4 ds5 s6 = FADD <double> s5 ds6 s7 = FADD <double> s6 ds7 s8 = FADD <double> s7 ds8 s9 = FADD <double> s8 ds9 r = FPTOSI <double int<32>> s9 RET r } """, "test_stack_args") test_stack_args = get_function(lib.test_stack_args, [ ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double, ctypes.c_double ], ctypes.c_int32) args = [0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0] assert (test_stack_args(*tuple(args)) == sum(map((lambda x: x**2), args)))
def test_alloca(): lib = load_bundle( """ .typedef type = struct<int<64> double ref<void>> .funcdef alloca <(int<64>)->(int<64>)> { entry(<int<64>>arg): a = ALLOCA <type> // Load the int field to ai_int ai_ref = GETFIELDIREF <type 0> a ai_int = LOAD <int<64>> ai_ref // Load the double field to ad_int (converting it to an int<64>) ad_ref = GETFIELDIREF <type 1> a ad = LOAD <double> ad_ref ad_int = BITCAST <double int<64>> ad // Load the ref field to ar_int (which will be '0' for a null ref, and '1' otherwise) ar_ref = GETFIELDIREF <type 2> a ar = LOAD <ref<void>> ar_ref ar_null = NE <ref<void>> ar <ref<void>>NULL ar_int = ZEXT <int<1> int<64>> ar_null // Store arg into the ALLOCA'd area STORE <type> ai_ref arg argc_int = LOAD <int<64>> ai_ref // or all the *_int values together res_0 = OR <int<64>> ai_int ad_int res_1 = OR <int<64>> res_0 ar_int res_2 = OR <int<64>> res_1 argc_int RET res_2 } """, "test_alloca") alloca = get_function(lib.alloca, [ctypes.c_int64], ctypes.c_int64) assert (alloca(-56) == -56)
def test_allocahybrid(): lib = load_bundle( """ .typedef type = hybrid<int<1> int<64>> .funcdef allocahybrid <(int<8>)->(int<64>)> { entry(<int<8>>n): a = ALLOCAHYBRID <type int<64>> n // Load the int<1> field to ai_int (as a 64-bit integer) ai_ref = GETFIELDIREF <type 0> a ai = LOAD <int<64>> ai_ref ai_int = ZEXT <int<1> int<64>> ai a_var = GETVARPARTIREF <type> a n_zero = EQ <int<8>> n <int<8>>0 // If the hybrid is non empty, sum all of it's variable elements BRANCH2 n_zero exit(ai_int) sum(a_var n ai_int) // Sum 'sum' and the n elements of pos // branch to exit with sum once finished sum(<iref<int<64>>>pos <int<8>>n <int<64>>sum): val = LOAD <int<64>> pos new_pos = SHIFTIREF <int<64> int<1>> pos <int<1>>1 new_sum = OR <int<64>> sum val new_n = SUB <int<8>> n <int<8>>1 n_zero = EQ <int<8>> n <int<8>>1 BRANCH2 n_zero exit(new_sum) sum(new_pos new_n new_sum) exit(<int<64>> sum): RET sum } """, "test_allocahybrid") allocahybrid = get_function(lib.allocahybrid, [ctypes.c_uint8], ctypes.c_uint64) assert (allocahybrid(56) == 0)