Exemplo n.º 1
0
def solve_chen_greedy(g: DFGraph,
                      segment_mem_B: int,
                      use_actuation_points: bool = True):
    with Timer("solve_chen_greedy") as timer_solve:
        C = g.articulation_points if use_actuation_points else g.v
        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 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_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,
    )
Exemplo n.º 4
0
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,
    )
Exemplo n.º 5
0
def solve_chen_sqrtn(g: DFGraph,
                     use_actuation_points: bool = True) -> ScheduledResult:
    with Timer("solve_chen_sqrtn") as timer_solve:
        C = g.articulation_points if use_actuation_points else g.v
        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,
    )
Exemplo n.º 6
0
def solve_checkmate_cvxpy(
    g, budget, rounding_thresholds=(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9), solver_override=None, verbose=True
):
    lpsolver = ILPSolverCVXPY(g, int(0.9 * budget))  # rounding threshold
    try:
        r, s, u, free_e = lpsolver.solve(solver_override=solver_override, verbose=verbose)
        lp_feasible = True
    except ValueError as e:
        logging.exception(e)
        r, s, u, free_e = (None, None, None, None)
        lp_feasible = False
    schedule, aux_data, min_threshold = None, None, None
    if lp_feasible:  # round the solution
        for threshold in rounding_thresholds:
            s_ = (s >= threshold).astype(np.int)
            r_ = solve_r_opt(g, s_)
            schedule_, aux_data_ = schedule_from_rs(g, r_, s_)
            if aux_data_.activation_ram <= budget and (aux_data is None or aux_data_.cpu <= aux_data.cpu):
                aux_data = aux_data_
                schedule = schedule_
                min_threshold = threshold
    solve_strategy = (
        SolveStrategy.APPROX_DET_ROUND_LP_05_THRESH
        if len(rounding_thresholds) == 1
        else SolveStrategy.APPROX_DET_ROUND_LP_SWEEP
    )
    return ScheduledResult(
        solve_strategy=solve_strategy,
        solver_budget=budget,
        feasible=lp_feasible and aux_data is not None,
        schedule=schedule,
        schedule_aux_data=aux_data,
        solve_time_s=lpsolver.solve_time,
        ilp_aux_data=ILPAuxData(
            U=u,
            Free_E=free_e,
            ilp_approx=False,
            ilp_time_limit=None,
            ilp_eps_noise=0.0,
            ilp_num_constraints=lpsolver.num_vars,
            ilp_num_variables=lpsolver.num_constraints,
            approx_deterministic_round_threshold=min_threshold,
        ),
    )
Exemplo n.º 7
0
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.articulation_points))
    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
Exemplo n.º 8
0
def solve_approx_lp_deterministic_sweep(
    g: DFGraph,
    budget: int,
    seed_s: Optional[np.ndarray] = None,
    approx=True,
    time_limit: Optional[int] = None,
    write_log_file: Optional[PathLike] = None,
    print_to_console=True,
    write_model_file: Optional[PathLike] = None,
    eps_noise=0.01,
    solver_cores=os.cpu_count(),
    thresholds=(0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9),
    imposed_schedule: ImposedSchedule = ImposedSchedule.FULL_SCHEDULE,
    allow_return_infeasible_schedule=False,
):
    param_dict = {
        "LogToConsole": 1 if print_to_console else 0,
        "LogFile": str(write_log_file) if write_log_file is not None else "",
        "Threads": solver_cores,
        "TimeLimit": math.inf if time_limit is None else time_limit,
        "OptimalityTol": 1e-2 if approx else 1e-4,
        "IntFeasTol": 1e-3 if approx else 1e-5,
        "Presolve": 2,
        "StartNodeLimit": 10000000,
    }
    lpsolver = ILPSolverGurobi(
        g,
        int(0.9 * budget),  # hack to get values under the budget
        gurobi_params=param_dict,
        seed_s=seed_s,
        integral=False,
        solve_r=False,
        eps_noise=eps_noise,
        imposed_schedule=imposed_schedule,
        write_model_file=write_model_file,
    )
    lpsolver.build_model()
    try:
        r, s, u, free_e = lpsolver.solve()
        lp_feasible = True
    except ValueError as e:
        logging.exception(e)
        r, s, u, free_e = (None, None, None, None)
        lp_feasible = False
    schedule, aux_data, min_threshold = None, None, None
    if lp_feasible:  # round the solution
        for threshold in thresholds:
            s_ = (s >= threshold).astype(np.int)
            r_ = solve_r_opt(g, s_)
            schedule_, aux_data_ = schedule_from_rs(g, r_, s_)
            if (allow_return_infeasible_schedule and aux_data is None) or (
                    aux_data_.activation_ram <= budget and
                (aux_data is None or aux_data_.cpu <= aux_data.cpu)):
                aux_data = aux_data_
                schedule = schedule_
                min_threshold = threshold
    return ScheduledResult(
        solve_strategy=SolveStrategy.APPROX_DET_ROUND_LP_SWEEP,
        solver_budget=budget,
        feasible=lp_feasible and aux_data is not None,
        schedule=schedule,
        schedule_aux_data=aux_data,
        solve_time_s=lpsolver.solve_time,
        ilp_aux_data=ILPAuxData(
            U=u,
            Free_E=free_e,
            ilp_approx=approx,
            ilp_time_limit=time_limit,
            ilp_eps_noise=eps_noise,
            ilp_num_constraints=lpsolver.m.numConstrs,
            ilp_num_variables=lpsolver.m.numVars,
            approx_deterministic_round_threshold=min_threshold,
        ),
    )
Exemplo n.º 9
0
def solve_approx_lp_randomized(
        g: DFGraph,
        budget: int,
        seed_s: Optional[np.ndarray] = None,
        approx=True,
        time_limit: Optional[int] = None,
        write_log_file: Optional[PathLike] = None,
        print_to_console=True,
        write_model_file: Optional[PathLike] = None,
        eps_noise=0.01,
        solver_cores=os.cpu_count(),
        num_rounds=100,
        return_rounds=False,
):
    """Randomized rounding of LP relaxation
    
    Args:
        g: 
        budget: 
        seed_s: 
        approx: 
        time_limit: 
        write_log_file: 
        print_to_console: 
        write_model_file: 
        eps_noise:
        solver_cores:
        num_rounds: 
        return_rounds: If True, return tuple (ScheduledResult, rounding_statistics)
    """
    param_dict = {
        "LogToConsole": 1 if print_to_console else 0,
        "LogFile": str(write_log_file) if write_log_file is not None else "",
        "Threads": solver_cores,
        "TimeLimit": math.inf if time_limit is None else time_limit,
        "OptimalityTol": 1e-2 if approx else 1e-4,
        "IntFeasTol": 1e-3 if approx else 1e-5,
        "Presolve": 2,
        "StartNodeLimit": 10000000,
    }
    lpsolver = ILPSolverGurobi(
        g,
        int(0.9 * budget),  # hack to get values under the budget
        gurobi_params=param_dict,
        seed_s=seed_s,
        solve_r=False,
        integral=False,
        eps_noise=eps_noise,
        write_model_file=write_model_file,
    )
    lpsolver.build_model()
    try:
        r, s, u, free_e = lpsolver.solve()
        lp_feasible = True
    except ValueError as e:
        logging.exception(e)
        r, s, u, free_e = (None, None, None, None)
        lp_feasible = False

    best_solution = (float("inf"), None, None)
    rounding_cpus = []
    rounding_activation_rams = []
    rounding_in_budgets = []
    if lp_feasible:  # round the solution
        for i in range(num_rounds):
            s_ = (np.random.rand(*s.shape) <= s).astype(np.int32)
            r_ = solve_r_opt(g, s_)
            schedule, aux_data = schedule_from_rs(g, r_, s_)

            rounding_cpus.append(aux_data.cpu)
            rounding_activation_rams.append(aux_data.activation_ram)
            rounding_in_budgets.append(aux_data.activation_ram <= budget)

            if aux_data.activation_ram <= budget and (
                    best_solution[2] is None
                    or aux_data.cpu <= best_solution[0]):
                best_solution = (aux_data.cpu, schedule, aux_data)

            if (i + 1) % 1 == 0:
                print(
                    f"Rounded relaxation argmin {i+1} / num_rounds times, best cost {best_solution[0]}"
                )
    schedule, aux_data = best_solution[1], best_solution[2]

    scheduled_result = ScheduledResult(
        solve_strategy=SolveStrategy.APPROX_RANDOMIZED_ROUND,
        solver_budget=budget,
        feasible=lp_feasible,
        schedule=schedule,
        schedule_aux_data=aux_data,
        solve_time_s=lpsolver.solve_time,
        ilp_aux_data=ILPAuxData(
            U=u,
            Free_E=free_e,
            ilp_approx=approx,
            ilp_time_limit=time_limit,
            ilp_eps_noise=eps_noise,
            ilp_num_constraints=lpsolver.m.numConstrs,
            ilp_num_variables=lpsolver.m.numVars,
            approx_deterministic_round_threshold=None,
        ),
    )
    if return_rounds:
        return (
            scheduled_result,
            {
                "cpu": rounding_cpus,
                "activation_ram": rounding_activation_rams,
                "in_budget": rounding_in_budgets
            },
        )
    return scheduled_result
Exemplo n.º 10
0
    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("Infeasible ILP seed at budget {:.2E}".format(
                        self.budget))
                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(
                "Model status is {} (not infeasible), but solCount is {}".
                format(self.m.status, self.m.solCount))

        Rout = np.zeros((T, T),
                        dtype=checkmate.core.utils.solver_common.SOLVER_DTYPE
                        if self.integral else np.float)
        Sout = np.zeros((T, T),
                        dtype=checkmate.core.utils.solver_common.SOLVER_DTYPE
                        if self.integral else np.float)
        Uout = np.zeros((T, T),
                        dtype=checkmate.core.utils.solver_common.SOLVER_DTYPE
                        if self.integral else np.float)
        Free_Eout = np.zeros(
            (T, len(self.g.edge_list)),
            dtype=checkmate.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