Spaces:
Running on Zero
Running on Zero
| import importlib | |
| import warnings | |
| warnings.filterwarnings('ignore') | |
| import gymnasium as gym | |
| from envs.wrappers.vectorized_multitask import make_vectorized_multitask_env | |
| from envs.wrappers.render import Render | |
| # Every domain used to be imported eagerly here, which means one missing | |
| # dependency took down *all* tasks rather than just its own -- painful on any | |
| # partial install, and fatal when deploying (a hosted demo cannot install a | |
| # Vulkan ICD for ManiSkill, but should still serve the other nine domains). | |
| # Each domain is now loaded behind a guard, generalising the pattern that was | |
| # already used for Atari: on failure the name binds to a stub that raises the | |
| # original error, but only if that domain's task is actually requested. | |
| # `AVAILABLE_DOMAINS` lets a caller filter its task list up front instead. | |
| # | |
| # The guard catches Exception, not just ImportError, because these domains fail | |
| # in more ways than a missing module: a native renderer with no GL/Vulkan | |
| # context available typically raises RuntimeError or OSError at import time. | |
| _IMPORT_ERRORS = {} | |
| AVAILABLE_DOMAINS = set() | |
| def _load_domain(module, domains, hint): | |
| """Return envs.<module>.make_env, or a stub explaining why it is unavailable.""" | |
| try: | |
| fn = importlib.import_module(f'envs.{module}').make_env | |
| except Exception as err: | |
| _IMPORT_ERRORS[module] = err | |
| def _unavailable(cfg, _m=module, _h=hint, _e=err): | |
| raise ImportError( | |
| f'The {_m} domain is not available in this installation ({_h}). ' | |
| f'Original import error: {type(_e).__name__}: {_e}' | |
| ) | |
| return _unavailable | |
| AVAILABLE_DOMAINS.update(domains) | |
| return fn | |
| make_dm_control_env = _load_domain( | |
| 'dmcontrol', ('dmcontrol', 'dmcontrol-ext'), 'needs dm-control and a headless MuJoCo GL backend, e.g. MUJOCO_GL=egl') | |
| make_maniskill_env = _load_domain( | |
| 'maniskill', ('maniskill',), 'needs mani_skill, and SAPIEN requires a Vulkan ICD') | |
| make_metaworld_env = _load_domain( | |
| 'metaworld', ('metaworld',), 'needs the metaworld fork and a headless MuJoCo GL backend') | |
| make_mujoco_env = _load_domain( | |
| 'mujoco', ('mujoco',), 'needs mujoco and a headless GL backend') | |
| make_box2d_env = _load_domain( | |
| 'box2d', ('box2d',), 'needs box2d-py (built with swig) and pygame') | |
| make_robodesk_env = _load_domain( | |
| 'robodesk', ('robodesk',), 'needs robodesk and a headless MuJoCo GL backend') | |
| make_ogbench_env = _load_domain( | |
| 'ogbench', ('ogbench',), 'needs ogbench and a headless MuJoCo GL backend') | |
| make_pygame_env = _load_domain( | |
| 'pygame', ('pygame',), 'needs pygame; set SDL_VIDEODRIVER=dummy when headless') | |
| make_atari_env = _load_domain( | |
| 'atari', ('atari',), 'needs ale_py>=0.10 for continuous-action Atari') | |
| def unavailable_domains(): | |
| """Map of domain module -> the exception that stopped it importing.""" | |
| return dict(_IMPORT_ERRORS) | |
| def make_env(cfg): | |
| """ | |
| Make an environment for world-model experiments. | |
| """ | |
| gym.logger.set_level(40) | |
| if not cfg.child_env: | |
| env = make_vectorized_multitask_env(cfg, make_env) | |
| else: | |
| env = None | |
| for fn in [ | |
| make_dm_control_env, make_maniskill_env, make_metaworld_env, | |
| make_mujoco_env, make_box2d_env, make_robodesk_env, | |
| make_ogbench_env, make_pygame_env, make_atari_env, | |
| ]: | |
| try: | |
| env = fn(cfg) | |
| break | |
| except ValueError as e: | |
| if 'Unknown task' in str(e): | |
| continue | |
| else: | |
| raise e | |
| if env is None: | |
| raise ValueError(f'Failed to make environment "{cfg.task}": please verify that dependencies are installed and that the task exists.') | |
| assert cfg.num_envs == 1 or cfg.get('obs', 'state') == 'state', \ | |
| 'Vectorized environments only support state observations.' | |
| if cfg.save_video and cfg.get('num_demos', 0) > 0: | |
| env = Render(env, cfg) | |
| print(f'[Rank {cfg.rank}] Created env for task {cfg.task}') | |
| try: # Dict | |
| cfg.obs_shape = {k: v.shape for k, v in env.observation_space.spaces.items()} | |
| except: # Box | |
| cfg.obs_shape = {cfg.get('obs', 'state'): env.observation_space.shape} | |
| cfg.action_dim = env.action_space.shape[0] | |
| cfg.episode_length = env.max_episode_steps | |
| return env | |