Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to run l2rpn_neurips_2020_track1_small using Rllib integration code #196

Closed
rrhossain opened this issue Apr 20, 2021 · 3 comments
Closed
Labels
bug Something isn't working

Comments

@rrhossain
Copy link

rrhossain commented Apr 20, 2021

Environment

  • Grid2op version: 1.5.1
  • System: ubuntu 20.04 / MAC Os`
  • Additional system information

Bug description

The code is working for l2rpn-sandbox but it is producing error for l2rpn-neurips-track-1-small environment.

Code snippet

import gym
import ray
import gym
import numpy as np
class MyEnv(gym.Env):
    def __init__(self, env_config):
        import grid2op
        from grid2op.gym_compat import GymEnv
        from grid2op.gym_compat import ScalerAttrConverter, ContinuousToDiscreteConverter, MultiToTupleConverter
        # 1. create the grid2op environment
        if not "env_name" in env_config:
            raise RuntimeError("The configuration for RLLIB should provide the env name")
        nm_env = env_config["env_name"]
        del env_config["env_name"]
        self.env_glop = grid2op.make(nm_env, **env_config)

        # 2. create the gym environment
        self.env_gym = GymEnv(self.env_glop)
        obs_gym = self.env_gym.reset()

        # 3. (optional) customize it (see section above for more information)
        ## customize action space
        self.env_gym.action_space = self.env_gym.action_space.ignore_attr("set_bus").ignore_attr("set_line_status")
        self.env_gym.action_space = self.env_gym.action_space.reencode_space("redispatch",
                                                                             ContinuousToDiscreteConverter(nb_bins=11)
                                                                             )
        self.env_gym.action_space = self.env_gym.action_space.reencode_space("change_bus", MultiToTupleConverter())
        self.env_gym.action_space = self.env_gym.action_space.reencode_space("change_line_status",
                                                                             MultiToTupleConverter())
        self.env_gym.action_space = self.env_gym.action_space.reencode_space("redispatch", MultiToTupleConverter())
        ## customize observation space
        ob_space = self.env_gym.observation_space
        ob_space = ob_space.keep_only_attr(["rho", "gen_p", "load_p", "topo_vect", "actual_dispatch"])
        ob_space = ob_space.reencode_space("actual_dispatch",
                                           ScalerAttrConverter(substract=0.,
                                                               divide=self.env_glop.gen_pmax
                                                               )
                                           )
        ob_space = ob_space.reencode_space("gen_p",
                                           ScalerAttrConverter(substract=0.,
                                                               divide=self.env_glop.gen_pmax
                                                               )
                                           )
        ob_space = ob_space.reencode_space("load_p",
                                           ScalerAttrConverter(substract=obs_gym["load_p"],
                                                               divide=0.5 * obs_gym["load_p"]
                                                               )
                                           )
        self.env_gym.observation_space = ob_space

        # 4. specific to rllib
        self.action_space = self.env_gym.action_space
        self.observation_space = self.env_gym.observation_space
        self.step_count = 0

    def reset(self):
        obs = self.env_gym.reset()
        self.step_count = 0
        #print(obs)
        return obs
    def step(self, action):
        self.step_count += 1
        print(self.step_count)
        obs, reward, done, info = self.env_gym.step(action)
        return obs, reward, done, info

nb_step_train = 1
if nb_step_train:  # remember: don't forge to change this number to perform an actual training !
    from ray.rllib.agents import ppo  # import the type of agents
    # fist initialize ray
    ray.init()
    try:
        # then define a "trainer"
        trainer = ppo.PPOTrainer(env=MyEnv, config={
            "env_config": {"env_name":"l2rpn_neurips_2020_track1_small"},  # config to pass to env class
        })
        # and then train it for a given number of iteration
        for step in range(nb_step_train):
            trainer.train()
    finally:   
        # shutdown ray
        ray.shutdown()

The output of the code snippet above (in colab):


RayTaskError(ValueError): ray::RolloutWorker.par_iter_next() (pid=378, ip=172.28.0.2)
  File "python/ray/_raylet.pyx", line 480, in ray._raylet.execute_task
  File "python/ray/_raylet.pyx", line 432, in ray._raylet.execute_task.function_executor
  File "/usr/local/lib/python3.7/dist-packages/ray/util/iter.py", line 1152, in par_iter_next
    return next(self.local_it)
  File "/usr/local/lib/python3.7/dist-packages/ray/rllib/evaluation/rollout_worker.py", line 327, in gen_rollouts
    yield self.sample()
  File "/usr/local/lib/python3.7/dist-packages/ray/rllib/evaluation/rollout_worker.py", line 662, in sample
    batches = [self.input_reader.next()]
  File "/usr/local/lib/python3.7/dist-packages/ray/rllib/evaluation/sampler.py", line 95, in next
    batches = [self.get_data()]
  File "/usr/local/lib/python3.7/dist-packages/ray/rllib/evaluation/sampler.py", line 224, in get_data
    item = next(self.rollout_provider)
  File "/usr/local/lib/python3.7/dist-packages/ray/rllib/evaluation/sampler.py", line 620, in _env_runner
    sample_collector=sample_collector,
  File "/usr/local/lib/python3.7/dist-packages/ray/rllib/evaluation/sampler.py", line 1056, in _process_observations_w_trajectory_view_api
    policy_id).transform(raw_obs)
  File "/usr/local/lib/python3.7/dist-packages/ray/rllib/models/preprocessors.py", line 257, in transform
    self.check_shape(observation)
  File "/usr/local/lib/python3.7/dist-packages/ray/rllib/models/preprocessors.py", line 68, in check_shape
    observation, self._obs_space)
ValueError: ('Observation ({}) outside given space ({})!', OrderedDict([('actual_dispatch', array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,
       0., 0., 0., 0., 0.], dtype=float32)), ('gen_p', array([0.        , 0.14583334, 0.        , 0.5376    , 0.        ,
       0.13690476, 0.        , 0.        , 0.13988096, 0.        ,
       0.        , 0.        , 0.        , 0.        , 0.        ,
       0.        , 0.        , 0.10416667, 0.        , 0.9975    ,
       0.        , 0.0872582 ], dtype=float32)), ('load_p', array([-8.33333358e-02,  1.27543859e+01, -3.14843726e+00, -4.91228588e-02,
       -7.84314200e-02,  2.70270016e-02,  4.51001197e-01, -7.63358772e-02,
       -8.42104480e-02, -7.90961310e-02, -2.31212564e-02, -7.31706619e-02,
       -5.47945984e-02, -5.57769537e-02, -4.65115122e-02,  0.00000000e+00,
       -6.25000373e-02, -2.98508592e-02,  0.00000000e+00,  2.59741265e-02,
       -5.12821227e-02,  2.12766770e-02, -4.38757129e-02,  1.45455096e-02,
       -1.45278079e-02, -3.63636017e-02,  7.14286715e-02,  1.03358915e-02,
        8.95522386e-02,  4.81927246e-02, -1.76759213e-02,  1.11111533e-02,
        1.00000061e-01, -5.28445065e-01,  3.00833374e-01,  7.76839375e-01,
       -7.07498193e-01], dtype=float32)), ('rho', array([0.49652272, 0.42036632, 0.12563582, 0.22375877, 0.54946697,
       0.08844228, 0.05907034, 0.10975129, 0.13002895, 0.14068729,
       0.17318982, 0.6956544 , 0.38796344, 0.67179894, 0.22992906,
       0.25189328, 0.15049867, 0.09095841, 0.35627988, 0.35627988,
       0.36776555, 0.27249542, 0.6269728 , 0.62393713, 0.3464659 ,
       0.35879263, 0.22755426, 0.35994047, 0.36117986, 0.12019955,
       0.03638522, 0.2805753 , 0.5809281 , 0.6191531 , 0.5243356 ,
       0.60382956, 0.35834518, 0.35867074, 0.3580954 , 0.6681824 ,
       0.3441911 , 0.6081861 , 0.34460714, 0.18246886, 0.10307808,
       0.46778303, 0.47179568, 0.45407027, 0.30089107, 0.30089107,
       0.34481782, 0.3182735 , 0.35940355, 0.21895139, 0.19766088,
       0.63653564, 0.46778303, 0.4566811 , 0.64398617], dtype=float32)), ('topo_vect', array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1], dtype=int32))]), Dict(actual_dispatch:Box(-1.0, 1.0, (22,), float32), gen_p:Box(0.0, 1.2000000476837158, (22,), float32), load_p:Box(-inf, inf, (37,), float32), rho:Box(0.0, inf, (59,), float32), topo_vect:Box(-1, 2, (177,), int32)))

The output of the code snippet above (in local machine)

Traceback (most recent call last):
  File "rllib_ppo.py", line 76, in <module>
    "env_config": {"env_name":"l2rpn_neurips_2020_track1_small"},  # config to pass to env class
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/rllib/agents/trainer_template.py", line 107, in __init__
    Trainer.__init__(self, config, env, logger_creator)
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/rllib/agents/trainer.py", line 486, in __init__
    super().__init__(config, logger_creator)
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/tune/trainable.py", line 97, in __init__
    self.setup(copy.deepcopy(self.config))
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/rllib/agents/trainer.py", line 654, in setup
    self._init(self.config, self.env_creator)
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/rllib/agents/trainer_template.py", line 139, in _init
    num_workers=self.config["num_workers"])
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/rllib/agents/trainer.py", line 731, in _make_workers
    logdir=self.logdir)
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/rllib/evaluation/worker_set.py", line 81, in __init__
    lambda p, pid: (pid, p.observation_space, p.action_space)))
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/_private/client_mode_hook.py", line 47, in wrapper
    return func(*args, **kwargs)
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/worker.py", line 1449, in get
    object_refs, timeout=timeout)
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/worker.py", line 320, in get_objects
    object_refs), debugger_breakpoint
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/worker.py", line 282, in deserialize_objects
    return context.deserialize_objects(data_metadata_pairs, object_refs)
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/serialization.py", line 245, in deserialize_objects
    self._deserialize_object(data, metadata, object_ref))
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/serialization.py", line 192, in _deserialize_object
    return self._deserialize_msgpack_data(data, metadata_fields)
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/serialization.py", line 170, in _deserialize_msgpack_data
    python_objects = self._deserialize_pickle5_data(pickle5_data)
  File "/home/hossain/project-env/lib/python3.7/site-packages/ray/serialization.py", line 158, in _deserialize_pickle5_data
    obj = pickle.loads(in_band, buffers=buffers)
**AttributeError: Can't get attribute 'ActionSpace_l2rpn_neurips_2020_track1_small' on <module 'grid2op.Space.GridObjects' from '/home/hossain/project-env/lib/python3.7/site-packages/grid2op/Space/GridObjects.py'>**

@rrhossain rrhossain added the bug Something isn't working label Apr 20, 2021
@rrhossain rrhossain changed the title Unable to run l2rpn_neurips_2020_track1_small using Rllib integration Unable to run l2rpn_neurips_2020_track1_small using Rllib integration code Apr 20, 2021
@BDonnot
Copy link
Collaborator

BDonnot commented Apr 23, 2021

Hello,

I will have a look at the first error. It seems that the upper / lower bound of the observation space are too tight. I will try to reproduce it and fix it asap. With the provided error, it does not seem to be an issue though (i mean: the observation given appears to be in the observation space, so this might - i say might- be a ray / rllib or a gym error and not a grid2op error)

For the second one, I am aware that multiprocessing does not work well on macos / windows due to internal working of this package.
Basically, it the fact that is does not work is a combination of :

  • ray (to rely on multiprocessing)
  • windows to not implement "fork" (which is a linux that allows to copy process)
  • the implementation of multiprocessing on macOs / windows that does some hidden stuff not working really well in some cases (see example bellow)
  • grid2op that heavily relies on dynamically defined classes (for performance reasons)

There is for now little i can do about it unfortunately. It works fine on linux based machine and on macos with python 3.6 or 3.7 i believe. They "broke" it starting from python 3.8 on macOs if i recall correctly.

There might be a good chance that this code works if you run it outside a jupyter notebook though (running multiprocessing in jupyter notebook on MacOs and Windows never works pretty much, see eg https://stackoverflow.com/questions/23641475/multiprocessing-working-in-python-but-not-in-ipython/23641560#23641560 for a more detailed explanation)

@BDonnot
Copy link
Collaborator

BDonnot commented Apr 26, 2021

Hi,

The issue with the "obs not in obs space" (or something like that) is indeed due to :

  • some internal consideration of the "powergrid solver"
  • an error due to the "scaler" in the case of loads.

You can fix them with:

class MyEnv(gym.Env):
    def __init__(self, env_config):
        import grid2op
        from grid2op.gym_compat import GymEnv
        from grid2op.gym_compat import ScalerAttrConverter, ContinuousToDiscreteConverter, MultiToTupleConverter
        from lightsim2grid import LightSimBackend
        # 1. create the grid2op environment
        if not "env_name" in env_config:
            raise RuntimeError("The configuration for RLLIB should provide the env name")
        nm_env = env_config["env_name"]
        del env_config["env_name"]
        self.env_glop = grid2op.make(nm_env, backend=LightSimBackend(), **env_config)
        self.env_glop.deactivate_forecast()

        # 2. create the gym environment
        self.env_gym = GymEnv(self.env_glop)
        obs_gym = self.env_gym.reset()

        # 3. (optional) customize it (see section above for more information)
        ## customize action space
        self.env_gym.action_space = self.env_gym.action_space.ignore_attr("set_bus").ignore_attr("set_line_status")
        self.env_gym.action_space = self.env_gym.action_space.reencode_space("redispatch",
                                                                             ContinuousToDiscreteConverter(nb_bins=11)
                                                                             )
        self.env_gym.action_space = self.env_gym.action_space.reencode_space("change_bus", MultiToTupleConverter())
        self.env_gym.action_space = self.env_gym.action_space.reencode_space("change_line_status",
                                                                             MultiToTupleConverter())
        self.env_gym.action_space = self.env_gym.action_space.reencode_space("redispatch", MultiToTupleConverter())
        ## customize observation space
        ob_space = self.env_gym.observation_space
        ob_space = ob_space.keep_only_attr(["rho", "gen_p", "load_p", "topo_vect", "actual_dispatch"])
        if True:
            ob_space = ob_space.reencode_space("actual_dispatch",
                                               ScalerAttrConverter(substract=0.,
                                                                   divide=self.env_glop.gen_pmax
                                                                   )
                                               )
            ob_space = ob_space.reencode_space("gen_p",
                                               ScalerAttrConverter(substract=0.,
                                                                   divide=self.env_glop.gen_pmax
                                                                   )
                                               )
            ob_space = ob_space.reencode_space("load_p",
                                               ScalerAttrConverter(substract=obs_gym["load_p"],
                                                                   divide=0.5 * obs_gym["load_p"]
                                                                   )
                                               )
        self.env_gym.observation_space = ob_space

        # 4. specific to rllib
        self.action_space = self.env_gym.action_space
        self.observation_space = self.env_gym.observation_space
        self.step_count = 0

        self.observation_space["gen_p"].low[:] = -np.inf
        self.observation_space["gen_p"].high[:] = np.inf
        self.observation_space["load_p"].low[:] = -np.inf
        self.observation_space["load_p"].high[:] = np.inf

    def reset(self):
        obs = self.env_gym.reset()
        self.step_count = 0
        return obs

    def step(self, action):
        self.step_count += 1
        obs, reward, done, info = self.env_gym.step(action)
        return obs, reward, done, info

A fix (partial for the first issue) will come soon. The "complete" fix for the issue is to put -np.inf and np.inf as a permanent
fix for "gen_p" but i don' really like to do that as the "pathological cases" are really just "pathological"

@BDonnot
Copy link
Collaborator

BDonnot commented May 10, 2021

Code is working on linux now

@BDonnot BDonnot closed this as completed May 10, 2021
BDonnot added a commit that referenced this issue Jun 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants