def pull_temps(s: Stm, decls_out: [SDecl], exp_is_bad) -> Stm: def pull(e: Exp) -> Exp: if exp_is_bad(e): v = fresh_var(e.type) decls_out.append(SDecl(v.id, e)) return v return e if isinstance(s, SNoOp): return s if isinstance(s, SSeq): s1 = pull_temps(s.s1, decls_out, exp_is_bad) s2 = pull_temps(s.s2, decls_out, exp_is_bad) return SSeq(s1, s2) if isinstance(s, SIf): cond = pull(s.cond) s1 = pull_temps(s.then_branch, decls_out, exp_is_bad) s2 = pull_temps(s.else_branch, decls_out, exp_is_bad) return SIf(cond, s1, s2) if isinstance(s, SForEach): bag = pull(s.iter) d_tmp = [] body = pull_temps(s.body, d_tmp, exp_is_bad) to_fix, ok = partition(d_tmp, lambda d: s.id in free_vars(d.val)) decls_out.extend(ok) for d in to_fix: v = EVar(d.id).with_type(d.val.type) mt = TMap(s.id.type, v.type) m = EMakeMap2(bag, ELambda(s.id, d.val)).with_type(mt) mv = fresh_var(m.type) md = SDecl(mv.id, m) decls_out.append(md) body = subst(body, {v.id: EMapGet(mv, s.id).with_type(v.type)}) return SForEach(s.id, bag, body) if isinstance(s, SAssign): return SAssign(s.lhs, pull(s.rhs)) if isinstance(s, SCall): return SCall(s.target, s.func, tuple(pull(arg) for arg in s.args)) if isinstance(s, SMapDel): return SMapDel(s.map, pull(s.key)) if isinstance(s, SMapPut): return SMapPut(s.map, pull(s.key), pull(s.value)) if isinstance(s, SMapUpdate): key = pull(s.key) d_tmp = [] change = pull_temps(s.change, d_tmp, exp_is_bad) for d in d_tmp: if s.val_var in free_vars(d.val): decls_out.append( SDecl( d.id, subst( d.val, { s.val_var.id: EMapGet(s.map, key).with_type(s.val_var.type) }))) else: decls_out.append(d) return SMapUpdate(s.map, key, s.val_var, change) raise NotImplementedError(s)
def ESum(es, base_case=ZERO): es = [e for e in es if e != base_case] if not es: return base_case nums, nonnums = partition(es, lambda e: isinstance(e, ENum)) es = nonnums if nums: es.append(ENum(sum(n.val for n in nums)).with_type(base_case.type)) return build_balanced_binop_tree(base_case.type, "+", es)
def ESum(es): es = [e for x in es for e in break_sum(x) if e != ZERO] if not es: return ZERO nums, nonnums = partition(es, lambda e: isinstance(e, ENum)) es = nonnums if nums: es.append(ENum(sum(n.val for n in nums)).with_type(INT)) return build_balanced_tree(INT, "+", es)
def simplify_sum(e): parts = list(break_sum(e)) t, f = partition(parts, lambda p: p[0]) t = [x[1] for x in t] f = [x[1] for x in f] parts = [] for x in t: opp = find_one( f, lambda y: alpha_equivalent(strip_EStateVar(x), strip_EStateVar(y))) if opp: f.remove(opp) else: parts.append(x) parts.extend(EUnaryOp("-", x).with_type(INT) for x in f) if not parts: return ZERO res = parts[0] for i in range(1, len(parts)): res = EBinOp(res, "+", parts[i]).with_type(INT) return res
def stop_jobs(jobs): """Call request_stop() on each job and wait for them to finish. This procedure also calls .join() on each job to clean up its resources. """ jobs = list(jobs) for j in jobs: j.request_stop() while jobs: for j in jobs: j.join(timeout=1) done_jobs, jobs = partition(jobs, lambda j: j.done) for j in done_jobs: # need to do this because they might have finished AFTER the .join # timed out and BEFORE the .done check j.join() if jobs: print("Waiting on {} jobs...".format(len(jobs))) for j in jobs: print(" --> {} [pid={}]".format(j, j.pid))
def pull_temps(s: Stm, decls_out: [SDecl], exp_is_bad) -> Stm: """Remove "bad" expressions from `s`. This procedure returns a statement new_s that replaces every expression in `s` where `exp_is_bad` returns True with a fresh variable. After running, `decls_out` contains definitions for the fresh variables so that the whole statement decls_out; new_s should return the same result as `s`. """ def pull(e: Exp) -> Exp: """Pull an expression into a temporary. Creates a fresh variable for `e`, writes a declaration into `decls_out`, and returns the fresh variable. """ if exp_is_bad(e): v = fresh_var(e.type) decls_out.append(SDecl(v, e)) return v return e if isinstance(s, SNoOp): return s if isinstance(s, SSeq): s1 = pull_temps(s.s1, decls_out, exp_is_bad) s2 = pull_temps(s.s2, decls_out, exp_is_bad) return SSeq(s1, s2) if isinstance(s, SDecl): return SDecl(s.var, pull(s.val)) if isinstance(s, SIf): cond = pull(s.cond) s1 = pull_temps(s.then_branch, decls_out, exp_is_bad) s2 = pull_temps(s.else_branch, decls_out, exp_is_bad) return SIf(cond, s1, s2) if isinstance(s, SForEach): bag = pull(s.iter) d_tmp = [] body = pull_temps(s.body, d_tmp, exp_is_bad) to_fix, ok = partition(d_tmp, lambda d: s.loop_var in free_vars(d.val)) decls_out.extend(ok) for d in to_fix: v = d.var mt = TMap(s.loop_var.type, v.type) m = EMakeMap2(bag, ELambda(s.loop_var, d.val)).with_type(mt) mv = fresh_var(m.type) md = SDecl(mv, m) decls_out.append(md) body = subst(body, {v.id: EMapGet(mv, s.loop_var).with_type(v.type)}) return SForEach(s.loop_var, bag, body) if isinstance(s, SAssign): return SAssign(s.lhs, pull(s.rhs)) if isinstance(s, SCall): return SCall(s.target, s.func, tuple(pull(arg) for arg in s.args)) if isinstance(s, SMapDel): return SMapDel(s.map, pull(s.key)) if isinstance(s, SMapPut): return SMapPut(s.map, pull(s.key), pull(s.value)) if isinstance(s, SMapUpdate): key = pull(s.key) d_tmp = [] change = pull_temps(s.change, d_tmp, exp_is_bad) for d in d_tmp: if s.val_var in free_vars(d.val): decls_out.append( SDecl( d.var, subst( d.val, { s.val_var.id: EMapGet(s.map, key).with_type(s.val_var.type) }))) else: decls_out.append(d) return SMapUpdate(s.map, key, s.val_var, change) raise NotImplementedError(s)
def pull_temps(s : Stm, decls_out : [SDecl], exp_is_bad) -> Stm: """Remove "bad" expressions from `s`. This procedure returns a statement new_s that replaces every expression in `s` where `exp_is_bad` returns True with a fresh variable. After running, `decls_out` contains definitions for the fresh variables so that the whole statement decls_out; new_s should return the same result as `s`. """ def pull(e : Exp) -> Exp: """Pull an expression into a temporary. Creates a fresh variable for `e`, writes a declaration into `decls_out`, and returns the fresh variable. """ if exp_is_bad(e): v = fresh_var(e.type) decls_out.append(SDecl(v, e)) return v return e if isinstance(s, SNoOp): return s if isinstance(s, SSeq): s1 = pull_temps(s.s1, decls_out, exp_is_bad) s2 = pull_temps(s.s2, decls_out, exp_is_bad) return SSeq(s1, s2) if isinstance(s, SDecl): return SDecl(s.var, pull(s.val)) if isinstance(s, SIf): cond = pull(s.cond) s1 = pull_temps(s.then_branch, decls_out, exp_is_bad) s2 = pull_temps(s.else_branch, decls_out, exp_is_bad) return SIf(cond, s1, s2) if isinstance(s, SForEach): bag = pull(s.iter) d_tmp = [] body = pull_temps(s.body, d_tmp, exp_is_bad) to_fix, ok = partition(d_tmp, lambda d: s.loop_var in free_vars(d.val)) decls_out.extend(ok) for d in to_fix: v = d.var mt = TMap(s.loop_var.type, v.type) m = EMakeMap2(bag, ELambda(s.loop_var, d.val)).with_type(mt) mv = fresh_var(m.type) md = SDecl(mv, m) decls_out.append(md) body = subst(body, { v.id : EMapGet(mv, s.loop_var).with_type(v.type) }) return SForEach(s.loop_var, bag, body) if isinstance(s, SAssign): return SAssign(s.lhs, pull(s.rhs)) if isinstance(s, SCall): return SCall(s.target, s.func, tuple(pull(arg) for arg in s.args)) if isinstance(s, SMapDel): return SMapDel(s.map, pull(s.key)) if isinstance(s, SMapPut): return SMapPut(s.map, pull(s.key), pull(s.value)) if isinstance(s, SMapUpdate): key = pull(s.key) d_tmp = [] change = pull_temps(s.change, d_tmp, exp_is_bad) for d in d_tmp: if s.val_var in free_vars(d.val): decls_out.append(SDecl(d.var, subst(d.val, { s.val_var.id : EMapGet(s.map, key).with_type(s.val_var.type) }))) else: decls_out.append(d) return SMapUpdate(s.map, key, s.val_var, change) raise NotImplementedError(s)