Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ executors:
jobs:
test:
executor: grid2op-executor
resource_class: medium+
resource_class: large
parallelism: 4
steps:
- checkout
Expand Down
59 changes: 58 additions & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -311,11 +311,68 @@ jobs:
- name: Test the automatic generation of classes in the env folder
run: |
python -m unittest grid2op/tests/automatic_classes.py -v -f

detailed_topology:
name: Test detailed topology on ${{ matrix.config.name }}
runs-on: ${{ matrix.config.os }}
strategy:
matrix:
config:
# - {
# name: darwin,
# os: macos-latest,
# }
# - {
# name: windows,
# os: windows-2019,
# }
- {
name: ubuntu,
os: ubuntu-latest,
}
python:
- {
name: cp39,
version: '3.9',
}
- {
name: cp313,
version: '3.13',
}

steps:

- name: Checkout sources
uses: actions/checkout@v3
with:
submodules: true

- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: ${{ matrix.python.version }}

- name: Install Python dependencies
run: |
python -m pip install --upgrade pip wheel setuptools gymnasium build

- name: Build wheel
run: python -m build --wheel .

- name: Install wheel
shell: bash
run: |
python -m pip install dist/*.whl --user
pip freeze

- name: Test the working of the detailed topo representation
run: |
python -m unittest grid2op/tests/indep_test_detailed_topo_extended.py -f

package:
name: Test install
runs-on: ubuntu-latest
needs: [manylinux_build, macos_windows_build, auto_class_in_file]
needs: [manylinux_build, macos_windows_build, auto_class_in_file, detailed_topology]

steps:
- name: Download wheels
Expand Down
10 changes: 10 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,17 @@ getting_started/venv_310_ray/
grid2op/tests/venv_test_autoclass/
test_eduardo.py
grid2op/tests/failed_test*
grid2op/tests/ampl_from_iidm.py
grid2op/tests/do_I_repeat.txt
grid2op/tests/parse_res35_working.txt
grid2op/tests/parse_res_35 (copie).txt
grid2op/tests/parse_res_35.txt
grid2op/tests/res_algo_topo_35.txt
grid2op/tests/test_topo_ampl/
grid2op/tests/test_topo_ampl2/
venv_312
venv_*
grid2op/tests/internal_*.pickle
grid2op_test_issue_discord.ipynb
grid2op_test_issue_discord_orig.ipynb
grid_bug_pp3.json
Expand Down
23 changes: 20 additions & 3 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,19 @@ Native multi agents support:
- add detachment
- add change_bus / set_bus

[1.13.0] - DETAILED TOPO
---------------------------
- [FIXED] some issues with gym classes
- [IMPROVED] the serialization of class definition
when using "automatic_classes" or "experimental_read_from_local_dir"
- [IMPROVED] when using gym MultiDiscrete as an action space,
if the dimension is 0 (for one of the MultiDiscrete) then it is now
removed from the action space (for example, if your environment does not
contain storage unit, the corresponding MultiDiscrete will have one less
dimension, because you cannot act on storage unit.)
- [IMPROVED] classes for action and observation classes are now easier to
initialize (added the `finalize_class_definition` classmethod)

[1.12.2] - 2025-10-xx
----------------------
- [FIXED] an issue preventing to change the way
Expand Down Expand Up @@ -296,9 +309,13 @@ Native multi agents support:

[1.10.4] - 2024-10-14
-------------------------
- [FIXED] an issue in the backend: if the backend failed to be
- [FIXED] an issue in the backend: if the backend failed to be copied
created the `_grid` attribute was set to `None` and not set back to
its original value in the copied backend.
- [FIXED] the `self.skip_if_needed()` was missing for one of the test suite.
- [FIXED] the correct `AmbiguousAction` is now raised when grid2op does not understand
what an action should be doing (an incorrect `IllegalAction` used to be sent)
- [FIXED] a test in `test_ActionProperties` did not test the correct property
- [FIXED] an error in the descirption of the `educ_case14_storage` environment
(wrong sign for the slack generator)
- [FIXED] the environment would not load in case of an incorrect "layout.json"
Expand All @@ -311,6 +328,7 @@ Native multi agents support:
in the readme)
- [ADDED] numpy 2 support (now that pandapower allows it)
- [IMPROVED] error message when forecasts are not correctly set-up
- [IMPROVED] an error message when loading a grid with forecasts


[1.10.3] - 2024-07-12
Expand Down Expand Up @@ -381,7 +399,6 @@ Native multi agents support:
processes (using `fork` at least), see `ep_data.make_serializable`
- [IMPROVED] chronix2grid tests are now done independantly on the CI


[1.10.2] - 2024-05-27
-------------------------
- [BREAKING] the `runner.run_one_episode` now returns an extra argument (first position):
Expand Down Expand Up @@ -1168,7 +1185,7 @@ Native multi agents support:
- [ADDED]: function to retrieve the maximum duration of the current episode.
- [ADDED]: a new kind of opponent that is able to attack at "more random" times with "more random" duration.
See the `GeometricOpponent`.
- [IMPROVED]: on windows at least, grid2op does not work with gym < 0.17.2 Checks are performed in order to make sure
- [IMPROVED]: on windows at least, grid2op does not work with `gym < 0.17.2` Checks are performed in order to make sure
the installed open ai gym package meets this requirement (see issue
`Issue#185 <https://github.com/Grid2Op/grid2op/issues/185>`_ )
- [IMPROVED] the seed of openAI gym for composed action space (see issue `https://github.com/openai/gym/issues/2166`):
Expand Down
135 changes: 135 additions & 0 deletions _profiling/profiler_switch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# Copyright (c) 2019-2020, RTE (https://www.rte-france.com)
# See AUTHORS.txt
# This Source Code Form is subject to the terms of the Mozilla Public License, version 2.0.
# If a copy of the Mozilla Public License, version 2.0 was not distributed with this file,
# you can obtain one at http://mozilla.org/MPL/2.0/.
# SPDX-License-Identifier: MPL-2.0
# This file is part of Grid2Op, Grid2Op a testbed platform to model sequential decision making in power systems.

"""
This file should be used to assess the performance of grid2op in "runner" mode: the loading time are not studied,
neither are the import times.

Data are loaded only once, when the environment is "done" the programm stops.

This corresponds to the situation: you have a trained agent, you want to assess its performance using the runner
"""

import os

from grid2op import make
from grid2op.Action import CompleteAction
from grid2op.Space import AddDetailedTopoIEEE
from grid2op.Parameters import Parameters
from grid2op.Agent import BaseAgent
from grid2op.Rules import AlwaysLegal
from grid2op.Backend import PandaPowerBackend
import cProfile

from utils_benchmark import run_env, str2bool

try:
from lightsim2grid import LightSimBackend
light_sim_avail = True
except ImportError:
light_sim_avail = False

ENV_NAME = "rte_case5_example"
ENV_NAME = "rte_case14_realistic"
MAX_TS = 1000
RANDOM_SWITCH_AGENT = False # do not change this
# for profiling it has no impact.


class RandomBusSwitchAgent(BaseAgent):
def act(self, observation, reward, done=False):
sub_id = self.space_prng.randint(type(self.action_space).n_sub)
new_position = self.space_prng.choice([-1, 1], size=1)
return self.action_space({"set_switch": [(sub_id, new_position)]})


class RandomElSwitchAgent(BaseAgent):
def act(self, observation, reward, done = False):
if observation.current_step <= 1:
# deactivate the connector between busbars
res = self.action_space({"set_switch": [(sub_id, -1)
for sub_id in range(type(self.action_space).n_sub)]})
else:
res = self.action_space()

do_act = self.space_prng.choice([0, 1], size=1, p = [0.95, 0.05])
if not do_act:
return res

n_switch = type(self.action_space).detailed_topo_desc.switches.shape[0]
switch_id = self.space_prng.randint(type(self.action_space).n_sub,
n_switch,
size=1)
new_position = self.space_prng.choice([-1, 1], size=1)
res.update({"set_switch": [(switch_id, new_position)]})
return res

def main(max_ts, name, use_lightsim=False, test_env=True):
param = Parameters()
if use_lightsim:
if light_sim_avail:
class ThisBackendClass(AddDetailedTopoIEEE, LightSimBackend):
pass
else:
raise RuntimeError("LightSimBackend not available")
else:
class ThisBackendClass(AddDetailedTopoIEEE, PandaPowerBackend):
pass

backend = ThisBackendClass()

param.init_from_dict(
{"NO_OVERFLOW_DISCONNECTION": True,
"STOP_EP_IF_GEN_BREAK_CONSTRAINTS": False,
"ENV_DOES_REDISPATCHING": False})

env_klu = make(name,
backend=backend,
param=param,
gamerules_class=AlwaysLegal,
test=test_env,
action_class=CompleteAction)
assert type(env_klu).detailed_topo_desc is not None
agent = RandomBusSwitchAgent(action_space=env_klu.action_space)
if RANDOM_SWITCH_AGENT:
agent = RandomElSwitchAgent(action_space=env_klu.action_space)
agent.seed(4)

cp = cProfile.Profile()
cp.enable()
nb_ts_klu, *_, time_step = run_env(env_klu, max_ts, agent)
cp.disable()
print(f'Time for {nb_ts_klu} steps: {time_step} => {time_step / nb_ts_klu} s/step or {nb_ts_klu / time_step:.3e} step / s')
nm_f, ext = os.path.splitext(__file__)
nm_out = "{}_{}_{}.prof".format(nm_f, "lightsim" if use_ls else "pp", name)
cp.dump_stats(nm_out)
print("You can view profiling results with:\n\tsnakeviz {}".format(nm_out))


if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(description='Benchmark pyKLU and Pandapower Backend for an agent that takes every '
'topological action possible')
parser.add_argument('--name', default=ENV_NAME, type=str,
help='Environment name to be used for the benchmark.')
parser.add_argument('--number', type=int, default=MAX_TS,
help='Maximum number of time steps for which the benchamark will be run.')
parser.add_argument("--use_ls", type=str2bool, nargs='?',
const=True, default=False,
help="Use the LightSim2Grid Backend.")
parser.add_argument("--no_test", type=str2bool, nargs='?',
const=True, default=False,
help="Do not use a test environment for the profiling (default to False: meaning you use a test env)")

args = parser.parse_args()

max_ts = int(args.number)
name = str(args.name)
use_ls = args.use_ls
test_env = not args.no_test
main(max_ts, name, use_lightsim=use_ls, test_env=test_env)
6 changes: 4 additions & 2 deletions _profiling/utils_benchmark.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import numpy as np
from tqdm import tqdm
import argparse
from grid2op.Environment import Environment
from grid2op.Agent import AgentWithConverter
from grid2op.Converter import IdToAct

Expand Down Expand Up @@ -179,12 +180,12 @@ def print_res(env_klu, env_pp,
print("Absolute value of the difference for gen_q: {}".format(np.max(np.abs(gen_q_klu - gen_q_pp))))


def run_env(env, max_ts, agent):
def run_env(env: Environment, max_ts, agent):
nb_rows = min(env.chronics_handler.max_timestep(), max_ts)
aor = np.zeros((nb_rows, env.n_line))
gen_p = np.zeros((nb_rows, env.n_gen))
gen_q = np.zeros((nb_rows, env.n_gen))
obs = env.get_obs()
obs = env.get_obs(_do_copy=False)
done = False
reward = env.reward_range[0]
nb_ts = 0
Expand All @@ -196,6 +197,7 @@ def run_env(env, max_ts, agent):
act = agent.act(obs, reward, done)
beg_step = time.perf_counter()
obs, reward, done, info = env.step(act)
assert not info["is_ambiguous"], info["exception"]
time_step += time.perf_counter() - beg_step
aor[nb_ts, :] = obs.a_or
gen_p[nb_ts, :] = obs.prod_p
Expand Down
50 changes: 50 additions & 0 deletions docs/detailed_topology.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
.. _detailed-topology-modeling-module:

Dive into the detailed topology "modeling" in grid2op
===================================================================

.. warning::
Work in progress

What is a "detailed" topology in grid2op
-----------------------------------------

.. warning::
Work in progress


- Concept of connectivity nodes
- Switches
- Processing of the switches to "original topoolgy"
-

Impact in grid2op
------------------

.. warning::
Work in progress

- new action
- new observation

.. danger::
Be carefull with convertion fo / from switches !!!

Why did we add it ?
--------------------

.. warning::
Work in progress

What features are actually implemented ?
-----------------------------------------

.. warning::
Work in progress


Pros and cons of using it ?
---------------------------------
.. warning::
Work in progress

1 change: 1 addition & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ graph.
modeled_elements
grid_graph
topology
detailed_topology

Environments
---------------
Expand Down
Loading
Loading