|
| 1 | +#!/home/donnotben/Documents/lightsim2grid/venv_ls/bin/python3 |
| 2 | + |
1 | 3 | #!/bin/python3 |
| 4 | +import pickle |
| 5 | +import time |
| 6 | + |
| 7 | +from kiwisolver import Solver |
2 | 8 | import grid2op |
3 | 9 | from lightsim2grid import LightSimBackend |
| 10 | +from lightsim2grid.solver import SolverType |
4 | 11 | import warnings |
| 12 | +import pandapower as pp |
| 13 | +import numpy as np |
5 | 14 |
|
6 | 15 | # usage: |
7 | 16 | # perf record ./test_profile.py |
8 | 17 | # perf report |
9 | | -env_name = "l2rpn_neurips_2020_track2_small" |
10 | | -with warnings.catch_warnings(): |
11 | | - warnings.filterwarnings("ignore") |
12 | | - env_tmp = grid2op.make(env_name) |
| 18 | +# env_name = "l2rpn_neurips_2020_track2_small" |
| 19 | + |
| 20 | +from benchmark_grid_size import ( |
| 21 | + get_loads_gens, |
| 22 | + make_grid2op_env |
| 23 | +) |
| 24 | +prng = np.random.default_rng(42) |
| 25 | + |
| 26 | +CASE_NAME = "case9241pegase.json" |
| 27 | +NB_TS = 10 |
13 | 28 |
|
14 | | - param = env_tmp.parameters |
15 | | - param.NO_OVERFLOW_DISCONNECTION = True |
16 | | - env = grid2op.make(env_name, backend=LightSimBackend(), param=param) |
17 | 29 |
|
| 30 | +def my_grid2op_env(case_name, nb_ts, prng): |
| 31 | + with warnings.catch_warnings(): |
| 32 | + warnings.filterwarnings("ignore") |
| 33 | + # env_tmp = grid2op.make(env_name) |
| 34 | + |
| 35 | + # load the case file |
| 36 | + case = pp.from_json(case_name) |
| 37 | + pp.runpp(case) # for slack |
| 38 | + load_p_init = 1.0 * case.load["p_mw"].values |
| 39 | + load_q_init = 1.0 * case.load["q_mvar"].values |
| 40 | + gen_p_init = 1.0 * case.gen["p_mw"].values |
| 41 | + sgen_p_init = 1.0 * case.sgen["p_mw"].values |
| 42 | + load_p, load_q, gen_p, sgen_p = get_loads_gens(load_p_init, load_q_init, gen_p_init, sgen_p_init, prng) |
18 | 43 |
|
19 | | -def make_steps(env, nb=1000): |
| 44 | + slack_gens = np.zeros((nb_ts, case.ext_grid.shape[0])) |
| 45 | + if "res_ext_grid" in case: |
| 46 | + slack_gens += np.tile(case.res_ext_grid["p_mw"].values.reshape(1,-1), (nb_ts, 1)) |
| 47 | + gen_p_g2op = np.concatenate((gen_p, slack_gens), axis=1) |
| 48 | + env = make_grid2op_env(case, |
| 49 | + case_name, |
| 50 | + load_p, |
| 51 | + load_q, |
| 52 | + gen_p_g2op, |
| 53 | + sgen_p) |
| 54 | + |
| 55 | + # param = env_tmp.parameters |
| 56 | + # param.NO_OVERFLOW_DISCONNECTION = True |
| 57 | + # env = grid2op.make(env_name, backend=LightSimBackend(), param=param) |
| 58 | + env.reset(seed=0, options={"time serie id": 0}) |
| 59 | + env.backend._timer_preproc = 0 |
| 60 | + env.backend._timer_solver = 0 |
| 61 | + |
| 62 | + with open(f"gridmodel_{case_name}.pickle", "wb") as f: |
| 63 | + pickle.dump(obj=env.backend._grid, file=f) |
| 64 | + return env |
| 65 | + |
| 66 | + |
| 67 | +def make_steps_glop(env, nb=NB_TS, reset_algo=False): |
20 | 68 | for i in range(nb): |
| 69 | + if reset_algo: |
| 70 | + env.backend._grid.tell_solver_need_reset() |
21 | 71 | _ = env.step(env.action_space()) |
| 72 | + print(f"Total time: {env.backend._timer_preproc + env.backend._timer_solver}") |
| 73 | + |
22 | 74 |
|
| 75 | +def main_glop(): |
| 76 | + env = my_grid2op_env(CASE_NAME, NB_TS, prng) |
| 77 | + make_steps_glop(env, NB_TS, reset_algo=True) |
| 78 | + |
23 | 79 |
|
| 80 | +def main_gridmodel(case_name=CASE_NAME, nb_ts=NB_TS, reset_algo=True, solver_used=SolverType.KLU): |
| 81 | + time_ls = 0. |
| 82 | + ls_timer_Fx = 0. |
| 83 | + ls_timer_solve = 0. |
| 84 | + ls_timer_initialize = 0. |
| 85 | + ls_timer_check = 0. |
| 86 | + ls_timer_dSbus = 0. |
| 87 | + ls_timer_fillJ = 0. |
| 88 | + ls_timer_Va_Vm = 0. |
| 89 | + ls_timer_pre_proc = 0. |
| 90 | + ls_timer_total_nr = 0. |
| 91 | + |
| 92 | + with open(f"gridmodel_{case_name}.pickle", "rb") as f: |
| 93 | + ls_grid = pickle.load(f) |
| 94 | + ls_grid.change_solver(solver_used) |
| 95 | + v_init = ls_grid.dc_pf(np.ones(ls_grid.get_bus_vn_kv().shape[0], dtype=complex) * 1.04, 1, 0.1) |
| 96 | + for _ in range(nb_ts): |
| 97 | + if reset_algo: |
| 98 | + ls_grid.tell_solver_need_reset() |
| 99 | + beg_ls = time.perf_counter() |
| 100 | + V = ls_grid.ac_pf(v_init, 10, 1e-6) |
| 101 | + end_ls = time.perf_counter() |
| 102 | + time_ls += end_ls - beg_ls |
| 103 | + if V.shape[0] == 0: |
| 104 | + raise RuntimeError("Divergence") |
| 105 | + |
| 106 | + (timer_Fx_, timer_solve_, timer_initialize_, |
| 107 | + timer_check_, timer_dSbus_, timer_fillJ_, |
| 108 | + timer_Va_Vm_, timer_pre_proc_, timer_total_nr_ |
| 109 | + ) = ls_grid.get_solver().get_timers_jacobian() |
| 110 | + ls_grid.unset_changes() # tell lightsim2grid that the state of the grid is consistent |
| 111 | + ls_timer_Fx += timer_Fx_ |
| 112 | + ls_timer_solve += timer_solve_ |
| 113 | + ls_timer_initialize += timer_initialize_ |
| 114 | + ls_timer_check += timer_check_ |
| 115 | + ls_timer_dSbus += timer_dSbus_ |
| 116 | + ls_timer_fillJ += timer_fillJ_ |
| 117 | + ls_timer_Va_Vm += timer_Va_Vm_ |
| 118 | + ls_timer_pre_proc += timer_pre_proc_ |
| 119 | + ls_timer_total_nr += timer_total_nr_ |
| 120 | + print(f"Solver used: {solver_used}") |
| 121 | + print(f"Nb iter: {nb_ts}") |
| 122 | + print(f"Do reset each step: {reset_algo}") |
| 123 | + print("--------------------------------------") |
| 124 | + print("Detailed lightsim2grid timings: ") |
| 125 | + print(f"Total time {time_ls * 1000.:.2e}ms => {time_ls / nb_ts * 1e3:.2e} ms/pf | {nb_ts / time_ls:.0f} pf /s") |
| 126 | + print(f"Total time spent in the solver: {1e3 * ls_timer_total_nr:.2e} ms ({100. * ls_timer_total_nr / time_ls:.0f}% of total time spent in lightsim2grid)") |
| 127 | + print(f"\t Time to pre process Ybus, Sbus etc.: {1e3 * ls_timer_pre_proc:.2e} ms ({100. * ls_timer_pre_proc / ls_timer_total_nr:.0f} % of time in solver)") |
| 128 | + print(f"\t Time to initialize linear solver {1e3 * ls_timer_initialize:.2e} ms ({100. * ls_timer_initialize / ls_timer_total_nr:.0f} % of time in solver)") |
| 129 | + print(f"\t Time to compute dS/dV {1e3 * ls_timer_dSbus : .2e} ms ({100. * ls_timer_dSbus / ls_timer_total_nr:.0f} % of time in solver)") |
| 130 | + print(f"\t Time to fill the Jacobian {1e3 * ls_timer_fillJ:.2e} ms ({100. * ls_timer_fillJ / ls_timer_total_nr:.0f} % of time in solver)") |
| 131 | + print(f"\t Time to solve the Jacobian linear system: {1e3 * ls_timer_solve:.2e} ms ({100. * ls_timer_solve / ls_timer_total_nr:.0f} % of time in solver)") |
| 132 | + print(f"\t Time to update Va and Vm {1e3*ls_timer_Va_Vm:.2e} ms ({100. * ls_timer_Va_Vm / ls_timer_total_nr:.0f} % of time in solver)") |
| 133 | + print(f"\t Time to evaluate p,q mismmatch at each bus {1e3*ls_timer_Fx:.2e} ms ({100. * ls_timer_Fx / ls_timer_total_nr:.0f} % of time in solver)") |
| 134 | + print(f"\t Time to evaluate cvg criteria {1e3*ls_timer_check:.2e} ms ({100. * ls_timer_check / ls_timer_total_nr:.0f} % of time in solver)") |
| 135 | + print("--------------------------------------\n") |
| 136 | + |
| 137 | + |
24 | 138 | if __name__ == "__main__": |
25 | | - make_steps(env, nb=1000) |
| 139 | + # my_grid2op_env(case_name, nb_ts, prng) |
| 140 | + main_gridmodel(CASE_NAME, NB_TS, reset_algo=True, solver_used=SolverType.KLUSingleSlack) |
0 commit comments