def solve(self): T = self.g.size with self.profiler('Gurobi model optimization', extra_data={ 'T': str(T), 'budget': str(self.budget) }): with Timer("ILPSolve") as solve_ilp: self.m.optimize() self.solve_time = solve_ilp.elapsed infeasible = (self.m.status == GRB.INFEASIBLE) try: _ = self.R[0, 0].X _ = self.S[0, 0].X _ = self.U[0, 0].X _ = self.batch_size.X except AttributeError as e: infeasible = True if infeasible: raise ValueError( "Infeasible model, check constraints carefully. Insufficient memory?" ) Rout = np.zeros((T, T), dtype=SOLVER_DTYPE) Sout = np.zeros((T, T), dtype=SOLVER_DTYPE) Uout = np.zeros((T, T), dtype=SOLVER_DTYPE) Free_Eout = np.zeros((T, len(self.g.edge_list)), dtype=SOLVER_DTYPE) batch_size = self.batch_size.X try: for t in range(T): for i in range(T): Rout[t][i] = int(self.R[t, i].X) Sout[t][i] = int(self.S[t, i].X) Uout[t][i] = self.U[t, i].X * self.ram_gcd for e in range(len(self.g.edge_list)): Free_Eout[t][e] = int(self.Free_E[t, e].X) except AttributeError as e: logging.exception(e) return None, None, None, None Rout = solve_r_opt(self.g, Sout) # prune R using optimal recomputation solver ilp_aux_data = ILPAuxData(U=Uout, Free_E=Free_Eout, ilp_approx=False, ilp_time_limit=0, ilp_eps_noise=0, ilp_num_constraints=self.m.numConstrs, ilp_num_variables=self.m.numVars) schedule, aux_data = schedule_from_rs(self.g, Rout, Sout) return ScheduledResult(solve_strategy=SolveStrategy.OPTIMAL_ILP_GC, solver_budget=self.budget, feasible=True, schedule=schedule, schedule_aux_data=aux_data, solve_time_s=self.solve_time, ilp_aux_data=ilp_aux_data), batch_size
def solve_checkpoint_last_node(g: DFGraph): """Checkpoint only one node between stages""" with Timer('solve_checkpoint_last_node') as timer_solve: s = np.zeros((g.size, g.size), dtype=SOLVER_DTYPE) np.fill_diagonal(s[1:], 1) r = solve_r_opt(g, s) schedule, aux_data = schedule_from_rs(g, r, s) return ScheduledResult(solve_strategy=SolveStrategy.CHECKPOINT_LAST_NODE, solver_budget=0, feasible=True, schedule=schedule, schedule_aux_data=aux_data, solve_time_s=timer_solve.elapsed)
def solve_checkpoint_all(g: DFGraph): with Timer('solve_checkpoint_all') as timer_solve: s = gen_s_matrix_fixed_checkpoints(g, g.vfwd) r = solve_r_opt(g, s) schedule, aux_data = schedule_from_rs(g, r, s) return ScheduledResult( solve_strategy=SolveStrategy.CHECKPOINT_ALL, solver_budget=0, feasible=True, schedule=schedule, schedule_aux_data=aux_data, solve_time_s=timer_solve.elapsed )
def solve_chen_sqrtn(g: DFGraph, use_actuation_points: bool) -> ScheduledResult: with Timer('solve_chen_sqrtn') as timer_solve: C = g.checkpoint_set if use_actuation_points else g.checkpoint_set_all k = int(math.sqrt(len(C))) checkpoints = [v for idx, v in enumerate(C) if (idx + 1) % k == 0] S = gen_s_matrix_fixed_checkpoints(g, set(checkpoints)) R = solve_r_opt(g, S) schedule, aux_data = schedule_from_rs(g, R, S) return ScheduledResult( solve_strategy=SolveStrategy.CHEN_SQRTN if use_actuation_points else SolveStrategy.CHEN_SQRTN_NOAP, solver_budget=0, feasible=True, schedule=schedule, schedule_aux_data=aux_data, solve_time_s=timer_solve.elapsed )
def _solve_griewank_to_rs(g: DFGraph, budget: int): S = np.zeros((g.size, g.size), dtype=np.int32) S = setup_implied_s_backwards(g, S) np.fill_diagonal(S[1:], 1) ap_points = list(sorted(g.checkpoint_set)) metaTfwd = len(ap_points) ap_points = ap_points + [ g.forward_to_backward(p) for p in reversed(ap_points) ] meta_to_real_v = { ap_points.index(ap_point): ap_point for ap_point in ap_points } try: regranges_all = _load_griewank(metaTfwd) except Exception as e: logging.exception(e) return None, None if regranges_all is None: return None, None max_budget = max(regranges_all["budget"]) regranges = regranges_all[regranges_all["budget"] == min( budget, max_budget)] if len(regranges.index) < 1: return None, None def map_time(_t: int) -> int: return min(meta_to_real_v.get(_t, np.inf), g.size) for index, reg_range in regranges.iterrows(): for t in range(map_time(reg_range['timestart']), map_time(reg_range['timeend'] + 1)): if reg_range['nodeid'] > 0: S[t, meta_to_real_v[reg_range['nodeid']]] = 1 R = solve_r_opt(g, S) return R, S
def solve_chen_greedy(g: DFGraph, segment_mem_B: int, use_actuation_points: bool): with Timer('solve_chen_greedy') as timer_solve: C = g.checkpoint_set if use_actuation_points else g.checkpoint_set_all temp = 0 x = 0 checkpoints = set() for v in g.topological_order_fwd: temp += g.cost_ram[v] if v in C and temp > segment_mem_B: x += g.cost_ram[v] temp = 0 checkpoints.add(v) S = gen_s_matrix_fixed_checkpoints(g, checkpoints) R = solve_r_opt(g, S) schedule, aux_data = schedule_from_rs(g, R, S) return ScheduledResult( solve_strategy=SolveStrategy.CHEN_GREEDY if use_actuation_points else SolveStrategy.CHEN_GREEDY_NOAP, solver_budget=segment_mem_B, feasible=True, schedule=schedule, schedule_aux_data=aux_data, solve_time_s=timer_solve.elapsed )
def solve(self): T = self.g.size with Timer('Gurobi model optimization', extra_data={ 'T': str(T), 'budget': str(self.budget) }): if self.seed_s is not None: self.m.Params.TimeLimit = self.GRB_CONSTRAINED_PRESOLVE_TIME_LIMIT self.m.optimize() if self.m.status == GRB.INFEASIBLE: print(f"Infeasible ILP seed at budget {self.budget:.2E}") self.m.remove(self.init_constraints) self.m.Params.TimeLimit = self.gurobi_params.get('TimeLimit', 0) self.m.message("\n\nRestarting solve\n\n") with Timer("ILPSolve") as solve_ilp: self.m.optimize() self.solve_time = solve_ilp.elapsed infeasible = (self.m.status == GRB.INFEASIBLE) if infeasible: raise ValueError( "Infeasible model, check constraints carefully. Insufficient memory?" ) if self.m.solCount < 1: raise ValueError( f"Model status is {self.m.status} (not infeasible), but solCount is {self.m.solCount}" ) Rout = np.zeros((T, T), dtype=remat.core.utils.solver_common.SOLVER_DTYPE if self.integral else np.float) Sout = np.zeros((T, T), dtype=remat.core.utils.solver_common.SOLVER_DTYPE if self.integral else np.float) Uout = np.zeros((T, T), dtype=remat.core.utils.solver_common.SOLVER_DTYPE if self.integral else np.float) Free_Eout = np.zeros((T, len(self.g.edge_list)), dtype=remat.core.utils.solver_common.SOLVER_DTYPE) solver_dtype_cast = int if self.integral else float try: for t in range(T): for i in range(T): try: Rout[t][i] = solver_dtype_cast(self.R[t, i].X) except (AttributeError, TypeError) as e: Rout[t][i] = solver_dtype_cast(self.R[t, i]) try: Sout[t][i] = solver_dtype_cast(self.S[t, i]) except (AttributeError, TypeError) as e: Sout[t][i] = solver_dtype_cast(self.S[t, i].X) try: Uout[t][i] = self.U[t, i].X * self.ram_gcd except (AttributeError, TypeError) as e: Uout[t][i] = self.U[t, i] * self.ram_gcd for e in range(len(self.g.edge_list)): try: Free_Eout[t][e] = solver_dtype_cast(self.Free_E[t, e].X) except (AttributeError, TypeError) as e: Free_Eout[t][e] = solver_dtype_cast(self.Free_E[t, e]) except AttributeError as e: logging.exception(e) return None, None, None, None # prune R using closed-form solver if self.solve_r and self.integral: Rout = solve_r_opt(self.g, Sout) return Rout, Sout, Uout, Free_Eout