From e785540a368e74a86722523d58f9db277177b364 Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Fri, 4 Mar 2022 19:51:52 -0800 Subject: [PATCH 01/16] Refactor out Env interface from CompilerEnv --- compiler_gym/envs/BUILD | 12 +++ compiler_gym/envs/CMakeLists.txt | 13 +++ compiler_gym/envs/__init__.py | 2 + compiler_gym/envs/compiler_env.py | 87 +++++-------------- compiler_gym/envs/env.py | 121 +++++++++++++++++++++++++++ compiler_gym/wrappers/commandline.py | 18 ++++ compiler_gym/wrappers/core.py | 47 ++++++++--- 7 files changed, 219 insertions(+), 81 deletions(-) create mode 100644 compiler_gym/envs/env.py diff --git a/compiler_gym/envs/BUILD b/compiler_gym/envs/BUILD index 89a3d1312..c4867c11b 100644 --- a/compiler_gym/envs/BUILD +++ b/compiler_gym/envs/BUILD @@ -21,6 +21,7 @@ py_library( srcs = ["compiler_env.py"], visibility = ["//compiler_gym:__subpackages__"], deps = [ + ":env", "//compiler_gym:compiler_env_state", "//compiler_gym:validation_result", "//compiler_gym/datasets", @@ -31,3 +32,14 @@ py_library( "//compiler_gym/views", ], ) + +py_library( + name = "env", + srcs = ["env.py"], + visibility = ["//compiler_gym:__subpackages__"], + deps = [ + "//compiler_gym/spaces", + "//compiler_gym/util", + "//compiler_gym/views", + ], +) diff --git a/compiler_gym/envs/CMakeLists.txt b/compiler_gym/envs/CMakeLists.txt index 15a1f64ca..352a407fe 100644 --- a/compiler_gym/envs/CMakeLists.txt +++ b/compiler_gym/envs/CMakeLists.txt @@ -24,6 +24,7 @@ cg_py_library( SRCS "compiler_env.py" DEPS + ::env_py compiler_gym::compiler_env_state compiler_gym::datasets::datasets compiler_gym::service::service @@ -34,3 +35,15 @@ cg_py_library( compiler_gym::views::views PUBLIC ) + +cg_py_library( + NAME + env_py + SRCS + "env.py" + DEPS + compiler_gym::spaces::spaces + compiler_gym::util::util + compiler_gym::views::views + PUBLIC +) diff --git a/compiler_gym/envs/__init__.py b/compiler_gym/envs/__init__.py index 33dd765e8..a84943d83 100644 --- a/compiler_gym/envs/__init__.py +++ b/compiler_gym/envs/__init__.py @@ -3,6 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from compiler_gym.envs.compiler_env import CompilerEnv +from compiler_gym.envs.env import Env from compiler_gym.envs.gcc import GccEnv from compiler_gym.envs.llvm.llvm_env import LlvmEnv from compiler_gym.envs.loop_tool.loop_tool_env import LoopToolEnv @@ -11,6 +12,7 @@ __all__ = [ "COMPILER_GYM_ENVS", "CompilerEnv", + "Env", "GccEnv", "LlvmEnv", "LoopToolEnv", diff --git a/compiler_gym/envs/compiler_env.py b/compiler_gym/envs/compiler_env.py index 9d3c5a2ed..8934387d3 100644 --- a/compiler_gym/envs/compiler_env.py +++ b/compiler_gym/envs/compiler_env.py @@ -2,7 +2,7 @@ # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -"""This module defines the OpenAI gym interface for compilers.""" + import logging import numbers import warnings @@ -13,7 +13,6 @@ from time import time from typing import Any, Dict, Iterable, List, Optional, Tuple, Union -import gym import numpy as np from deprecated.sphinx import deprecated from gym.spaces import Space @@ -21,6 +20,7 @@ from compiler_gym.compiler_env_state import CompilerEnvState from compiler_gym.datasets import Benchmark, Dataset, Datasets from compiler_gym.datasets.uri import BenchmarkUri +from compiler_gym.envs.env import Env from compiler_gym.service import ( CompilerGymServiceConnection, ConnectionOpts, @@ -81,7 +81,7 @@ def _wrapped_step( raise -class CompilerEnv(gym.Env): +class CompilerEnv(Env): """An OpenAI gym environment for compiler optimizations. The easiest way to create a CompilerGym environment is to call @@ -324,11 +324,21 @@ def __init__( self.actions: List[ActionType] = [] # Initialize the default observation/reward spaces. - self.observation_space_spec: Optional[ObservationSpaceSpec] = None + self.observation_space_spec = None self.reward_space_spec: Optional[Reward] = None self.observation_space = observation_space self.reward_space = reward_space + @property + def observation_space_spec(self) -> ObservationSpaceSpec: + return self._observation_space_spec + + @observation_space_spec.setter + def observation_space_spec( + self, observation_space_spec: Optional[ObservationSpaceSpec] + ): + self._observation_space_spec = observation_space_spec + @property @deprecated( version="0.2.1", @@ -559,29 +569,6 @@ def _init_kwargs(self) -> Dict[str, Any]: } def fork(self) -> "CompilerEnv": - """Fork a new environment with exactly the same state. - - This creates a duplicate environment instance with the current state. - The new environment is entirely independently of the source environment. - The user must call :meth:`close() ` - on the original and new environments. - - If not already in an episode, :meth:`reset() - ` is called. - - Example usage: - - >>> env = gym.make("llvm-v0") - >>> env.reset() - # ... use env - >>> new_env = env.fork() - >>> new_env.state == env.state - True - >>> new_env.step(1) == env.step(1) - True - - :return: A new environment instance. - """ if not self.in_episode: actions = self.actions.copy() self.reset() @@ -1026,7 +1013,7 @@ def raw_step( return observations, rewards, reply.end_of_session, info - def step( # pylint: disable=arguments-differ + def step( self, action: ActionType, observation_spaces: Optional[Iterable[Union[str, ObservationSpaceSpec]]] = None, @@ -1034,26 +1021,8 @@ def step( # pylint: disable=arguments-differ observations: Optional[Iterable[Union[str, ObservationSpaceSpec]]] = None, rewards: Optional[Iterable[Union[str, Reward]]] = None, ) -> StepType: - """Take a step. - - :param action: An action. - - :param observation_spaces: A list of observation spaces to compute - observations from. If provided, this changes the :code:`observation` - element of the return tuple to be a list of observations from the - requested spaces. The default :code:`env.observation_space` is not - returned. - - :param reward_spaces: A list of reward spaces to compute rewards from. If - provided, this changes the :code:`reward` element of the return - tuple to be a list of rewards from the requested spaces. The default - :code:`env.reward_space` is not returned. - - :return: A tuple of observation, reward, done, and info. Observation and - reward are None if default observation/reward is not set. - - :raises SessionNotFound: If :meth:`reset() - ` has not been called. + """:raises SessionNotFound: If :meth:`reset() + ` has not been called. """ if isinstance(action, IterableType): warnings.warn( @@ -1092,26 +1061,8 @@ def multistep( observations: Optional[Iterable[Union[str, ObservationSpaceSpec]]] = None, rewards: Optional[Iterable[Union[str, Reward]]] = None, ): - """Take a sequence of steps and return the final observation and reward. - - :param action: A sequence of actions to apply in order. - - :param observation_spaces: A list of observation spaces to compute - observations from. If provided, this changes the :code:`observation` - element of the return tuple to be a list of observations from the - requested spaces. The default :code:`env.observation_space` is not - returned. - - :param reward_spaces: A list of reward spaces to compute rewards from. If - provided, this changes the :code:`reward` element of the return - tuple to be a list of rewards from the requested spaces. The default - :code:`env.reward_space` is not returned. - - :return: A tuple of observation, reward, done, and info. Observation and - reward are None if default observation/reward is not set. - - :raises SessionNotFound: If :meth:`reset() - ` has not been called. + """:raises SessionNotFound: If :meth:`reset() + ` has not been called. """ if observations is not None: warnings.warn( diff --git a/compiler_gym/envs/env.py b/compiler_gym/envs/env.py new file mode 100644 index 000000000..d287163e2 --- /dev/null +++ b/compiler_gym/envs/env.py @@ -0,0 +1,121 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. +"""This module defines the OpenAI gym interface for compilers.""" +from abc import ABC, abstractmethod +from typing import Iterable, Optional, Union + +import gym + +from compiler_gym.spaces import Reward +from compiler_gym.util.gym_type_hints import ActionType, ObservationType, StepType +from compiler_gym.views import ObservationSpaceSpec + + +class Env(gym.Env, ABC): + @property + @abstractmethod + def observation_space_spec(self) -> ObservationSpaceSpec: + raise NotImplementedError("abstract method") + + @observation_space_spec.setter + @abstractmethod + def observation_space_spec( + self, observation_space_spec: Optional[ObservationSpaceSpec] + ): + raise NotImplementedError("abstract method") + + @abstractmethod + def fork(self) -> "Env": + """Fork a new environment with exactly the same state. + + This creates a duplicate environment instance with the current state. + The new environment is entirely independently of the source environment. + The user must call :meth:`close() ` + on the original and new environments. + + If not already in an episode, :meth:`reset() + ` is called. + + Example usage: + + >>> env = gym.make("llvm-v0") + >>> env.reset() + # ... use env + >>> new_env = env.fork() + >>> new_env.state == env.state + True + >>> new_env.step(1) == env.step(1) + True + + :return: A new environment instance. + """ + raise NotImplementedError("abstract method") + + @abstractmethod + def reset( # pylint: disable=arguments-differ + self, *args, **kwargs + ) -> Optional[ObservationType]: + """Reset the environment state. + + This method must be called before :func:`step()`. + """ + raise NotImplementedError("abstract method") + + @abstractmethod + def step( + self, + action: ActionType, + observation_spaces: Optional[Iterable[Union[str, ObservationSpaceSpec]]] = None, + reward_spaces: Optional[Iterable[Union[str, Reward]]] = None, + observations: Optional[Iterable[Union[str, ObservationSpaceSpec]]] = None, + rewards: Optional[Iterable[Union[str, Reward]]] = None, + ) -> StepType: + """Take a step. + + :param action: An action. + + :param observation_spaces: A list of observation spaces to compute + observations from. If provided, this changes the :code:`observation` + element of the return tuple to be a list of observations from the + requested spaces. The default :code:`env.observation_space` is not + returned. + + :param reward_spaces: A list of reward spaces to compute rewards from. If + provided, this changes the :code:`reward` element of the return + tuple to be a list of rewards from the requested spaces. The default + :code:`env.reward_space` is not returned. + + :return: A tuple of observation, reward, done, and info. Observation and + reward are None if default observation/reward is not set. + """ + raise NotImplementedError("abstract method") + + def multistep( + self, + actions: Iterable[ActionType], + observation_spaces: Optional[Iterable[Union[str, ObservationSpaceSpec]]] = None, + reward_spaces: Optional[Iterable[Union[str, Reward]]] = None, + observations: Optional[Iterable[Union[str, ObservationSpaceSpec]]] = None, + rewards: Optional[Iterable[Union[str, Reward]]] = None, + ): + """Take a sequence of steps and return the final observation and reward. + + :param action: A sequence of actions to apply in order. + + :param observation_spaces: A list of observation spaces to compute + observations from. If provided, this changes the :code:`observation` + element of the return tuple to be a list of observations from the + requested spaces. The default :code:`env.observation_space` is not + returned. + + :param reward_spaces: A list of reward spaces to compute rewards from. If + provided, this changes the :code:`reward` element of the return + tuple to be a list of rewards from the requested spaces. The default + :code:`env.reward_space` is not returned. + + :return: A tuple of observation, reward, done, and info. Observation and + reward are None if default observation/reward is not set. + """ + raise NotImplementedError("abstract method") diff --git a/compiler_gym/wrappers/commandline.py b/compiler_gym/wrappers/commandline.py index 21a2e2fc9..976b339e5 100644 --- a/compiler_gym/wrappers/commandline.py +++ b/compiler_gym/wrappers/commandline.py @@ -5,6 +5,8 @@ from collections.abc import Iterable as IterableType from typing import Dict, Iterable, List, Optional, Union +from gym import Space + from compiler_gym.envs import CompilerEnv from compiler_gym.spaces import Commandline, CommandlineFlag, Reward from compiler_gym.util.gym_type_hints import ActionType, StepType @@ -91,6 +93,14 @@ def multistep( return observation, reward, done, info + @property + def action_space(self) -> Space: + return self._action_space + + @action_space.setter + def action_space(self, action_space: Space): + self._action_space = action_space + class ConstrainedCommandline(ActionWrapper): """Constrains a Commandline action space to a subset of the original space's @@ -157,3 +167,11 @@ def fork(self) -> "ConstrainedCommandline": return ConstrainedCommandline( env=self.env.fork(), flags=self._flags, name=self.action_space.name ) + + @property + def action_space(self) -> Space: + return self._action_space + + @action_space.setter + def action_space(self, action_space: Space): + self._action_space = action_space diff --git a/compiler_gym/wrappers/core.py b/compiler_gym/wrappers/core.py index 62b0c679d..405f04c7b 100644 --- a/compiler_gym/wrappers/core.py +++ b/compiler_gym/wrappers/core.py @@ -4,18 +4,19 @@ # LICENSE file in the root directory of this source tree. import warnings from collections.abc import Iterable as IterableType -from typing import Iterable, List, Optional, Union +from typing import Any, Iterable, List, Optional, Tuple, Union -import gym +from gym import Wrapper +from gym.spaces import Space -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import Env from compiler_gym.spaces.reward import Reward from compiler_gym.util.gym_type_hints import ActionType, ObservationType from compiler_gym.views import ObservationSpaceSpec -class CompilerEnvWrapper(gym.Wrapper): - """Wraps a :class:`CompilerEnv ` environment +class CompilerEnvWrapper(Env, Wrapper): + """Wraps a :class:`CompilerEnv ` environment to allow a modular transformation. This class is the base class for all wrappers. This class must be used @@ -23,7 +24,7 @@ class CompilerEnvWrapper(gym.Wrapper): such as the :code:`fork()` method. """ - def __init__(self, env: CompilerEnv): # pylint: disable=super-init-not-called + def __init__(self, env: Env): # pylint: disable=super-init-not-called """Constructor. :param env: The environment to wrap. @@ -36,14 +37,11 @@ def __init__(self, env: CompilerEnv): # pylint: disable=super-init-not-called # CompilerEnv class is a property with a custom setter. Instead we set # the observation_space_spec directly. self.env = env - self.action_space = self.env.action_space - self.reward_range = self.env.reward_range - self.metadata = self.env.metadata - def reset(self, *args, **kwargs) -> ObservationType: + def reset(self, *args, **kwargs) -> Optional[ObservationType]: return self.env.reset(*args, **kwargs) - def fork(self) -> CompilerEnv: + def fork(self) -> Env: return type(self)(env=self.env.fork()) def step( # pylint: disable=arguments-differ @@ -115,10 +113,17 @@ def multistep( reward_spaces=reward_spaces, ) + @property + def reward_range(self) -> Tuple[float, float]: + return self.env.reward_range + + @reward_range.setter + def reward_range(self, value: Tuple[float, float]): + self.env.reward_range = value + @property def observation_space(self): - if self.env.observation_space_spec: - return self.env.observation_space_spec.space + return self.env.observation_space @observation_space.setter def observation_space( @@ -144,6 +149,22 @@ def reward_space(self) -> Optional[Reward]: def reward_space(self, reward_space: Optional[Union[str, Reward]]) -> None: self.env.reward_space = reward_space + @property + def action_space(self) -> Space: + return self.env.action_space + + @action_space.setter + def action_space(self, action_space: Optional[str]): + self.env.action_space = action_space + + @property + def spec(self) -> Any: + return self.env.spec + + @spec.setter + def spec(self, value: Any): + self.env.spec = value + class ActionWrapper(CompilerEnvWrapper): """Wraps a :class:`CompilerEnv ` environment From ecf42fbe497da22a4bcc0e907fd28ca7b3ba0681 Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Tue, 22 Mar 2022 11:47:27 -0700 Subject: [PATCH 02/16] Rename CompilerEnv to ClientServiceCompilerEnv --- benchmarks/bench_test.py | 10 +- compiler_gym/BUILD | 2 +- compiler_gym/CMakeLists.txt | 2 +- compiler_gym/__init__.py | 6 +- compiler_gym/bin/manual_env.py | 4 +- compiler_gym/bin/service.py | 4 +- compiler_gym/datasets/benchmark.py | 28 +++--- compiler_gym/envs/BUILD | 6 +- compiler_gym/envs/CMakeLists.txt | 6 +- compiler_gym/envs/__init__.py | 4 +- ..._env.py => client_service_compiler_env.py} | 92 +++++++++---------- compiler_gym/envs/gcc/BUILD | 2 +- compiler_gym/envs/gcc/CMakeLists.txt | 2 +- compiler_gym/envs/gcc/datasets/csmith.py | 2 +- compiler_gym/envs/gcc/gcc_env.py | 6 +- compiler_gym/envs/llvm/BUILD | 2 +- compiler_gym/envs/llvm/CMakeLists.txt | 2 +- compiler_gym/envs/llvm/datasets/csmith.py | 2 +- .../envs/llvm/datasets/llvm_stress.py | 2 +- compiler_gym/envs/llvm/llvm_benchmark.py | 2 +- compiler_gym/envs/llvm/llvm_env.py | 14 +-- compiler_gym/envs/loop_tool/BUILD | 2 +- compiler_gym/envs/loop_tool/CMakeLists.txt | 2 +- compiler_gym/envs/loop_tool/loop_tool_env.py | 4 +- compiler_gym/leaderboard/llvm_instcount.py | 2 +- compiler_gym/random_replay.py | 10 +- compiler_gym/random_search.py | 24 +++-- compiler_gym/service/compilation_session.py | 2 +- compiler_gym/service/connection.py | 4 +- compiler_gym/util/debug_util.py | 2 +- compiler_gym/util/flags/env_from_flags.py | 8 +- compiler_gym/validate.py | 8 +- compiler_gym/validation_error.py | 2 +- compiler_gym/views/observation_space_spec.py | 4 +- .../example_compiler_gym_service/__init__.py | 4 +- .../demo_without_bazel.py | 2 +- .../example_compiler_gym_service/env_tests.py | 44 ++++----- .../example_unrolling_service/__init__.py | 2 +- .../example_unrolling_service/env_tests.py | 42 ++++----- .../example_without_bazel.py | 2 +- examples/gcc_autotuning/tune.py | 8 +- .../llvm_autotuning/autotuners/__init__.py | 10 +- .../llvm_autotuning/autotuners/nevergrad_.py | 4 +- .../llvm_autotuning/autotuners/opentuner_.py | 4 +- .../llvm_autotuning/autotuners/random_.py | 4 +- examples/llvm_rl/model/benchmarks.py | 12 +-- examples/llvm_rl/model/environment.py | 10 +- examples/llvm_rl/model/inference_result.py | 8 +- examples/llvm_rl/model/testing.py | 8 +- examples/llvm_rl/model/training.py | 8 +- examples/llvm_rl/model/validation.py | 8 +- examples/llvm_rl/wrappers.py | 8 +- .../loop_optimizations_service/__init__.py | 2 +- .../loop_optimizations_service/env_tests.py | 48 +++++----- .../example_without_bazel.py | 2 +- examples/op_benchmarks.py | 2 +- .../llvm_instcount/e_greedy/e_greedy.py | 8 +- .../llvm_instcount/random_search/README.md | 2 +- tests/compiler_env_test.py | 2 +- tests/env_copy_test.py | 4 +- tests/llvm/all_actions_single_step_test.py | 4 +- tests/llvm/autophase_test.py | 4 +- ...esh_environment_observation_reward_test.py | 4 +- tests/llvm/llvm_benchmark_test.py | 6 +- tests/llvm/llvm_env_test.py | 4 +- tests/llvm/observation_spaces_test.py | 2 +- tests/llvm/service_connection_test.py | 6 +- tests/llvm/threading_test.py | 4 +- 68 files changed, 295 insertions(+), 271 deletions(-) rename compiler_gym/envs/{compiler_env.py => client_service_compiler_env.py} (93%) diff --git a/benchmarks/bench_test.py b/benchmarks/bench_test.py index 3947b0071..3819a00c8 100644 --- a/benchmarks/bench_test.py +++ b/benchmarks/bench_test.py @@ -21,7 +21,7 @@ import pytest import examples.example_compiler_gym_service as dummy -from compiler_gym.envs import CompilerEnv, LlvmEnv, llvm +from compiler_gym.envs import ClientServiceCompilerEnv, LlvmEnv, llvm from compiler_gym.service import CompilerGymServiceConnection from tests.pytest_plugins.llvm import OBSERVATION_SPACE_NAMES, REWARD_SPACE_NAMES from tests.test_main import main @@ -39,7 +39,7 @@ def env_id(request) -> str: params=["llvm-v0", "example-cc-v0", "example-py-v0"], ids=["llvm", "dummy-cc", "dummy-py"], ) -def env(request) -> CompilerEnv: +def env(request) -> ClientServiceCompilerEnv: yield request.param @@ -56,8 +56,8 @@ def test_make_local(benchmark, env_id): "args", [ (llvm.LLVM_SERVICE_BINARY, LlvmEnv), - (dummy.EXAMPLE_CC_SERVICE_BINARY, CompilerEnv), - (dummy.EXAMPLE_PY_SERVICE_BINARY, CompilerEnv), + (dummy.EXAMPLE_CC_SERVICE_BINARY, ClientServiceCompilerEnv), + (dummy.EXAMPLE_PY_SERVICE_BINARY, ClientServiceCompilerEnv), ], ids=["llvm", "dummy-cc", "dummy-py"], ) @@ -80,7 +80,7 @@ def test_make_service(benchmark, args): ], ids=["llvm;fast-benchmark", "llvm;slow-benchmark", "dummy-cc", "dummy-py"], ) -def test_reset(benchmark, make_env: CompilerEnv): +def test_reset(benchmark, make_env: ClientServiceCompilerEnv): with make_env() as env: benchmark(env.reset) diff --git a/compiler_gym/BUILD b/compiler_gym/BUILD index b12e5bb2f..14c8cad55 100644 --- a/compiler_gym/BUILD +++ b/compiler_gym/BUILD @@ -67,7 +67,7 @@ py_library( deps = [ ":validation_error", ":validation_result", - "//compiler_gym/envs:compiler_env", + "//compiler_gym/envs:client_service_compiler_env", "//compiler_gym/spaces", "//compiler_gym/util", ], diff --git a/compiler_gym/CMakeLists.txt b/compiler_gym/CMakeLists.txt index 59634c514..736cb955c 100644 --- a/compiler_gym/CMakeLists.txt +++ b/compiler_gym/CMakeLists.txt @@ -71,7 +71,7 @@ cg_py_library( DEPS ::validation_error ::validation_result - compiler_gym::envs::compiler_env + compiler_gym::envs::client_service_compiler_env compiler_gym::spaces::spaces compiler_gym::util::util PUBLIC diff --git a/compiler_gym/__init__.py b/compiler_gym/__init__.py index 087f344e3..9cea377fa 100644 --- a/compiler_gym/__init__.py +++ b/compiler_gym/__init__.py @@ -4,7 +4,7 @@ # LICENSE file in the root directory of this source tree. """CompilerGym is a set of compiler optimization environments for reinforcement learning. -After importing this module, the :class:`CompilerGym environments ` +After importing this module, the :class:`CompilerGym environments ` will be available through the :code:`gym.make(...)` interface: >>> import gym @@ -34,7 +34,7 @@ CompilerEnvStateReader, CompilerEnvStateWriter, ) -from compiler_gym.envs import COMPILER_GYM_ENVS, CompilerEnv +from compiler_gym.envs import COMPILER_GYM_ENVS, ClientServiceCompilerEnv from compiler_gym.random_search import random_search from compiler_gym.util.debug_util import ( get_debug_level, @@ -58,7 +58,7 @@ "cache_path", "COMPILER_GYM_ENVS", "make", - "CompilerEnv", + "ClientServiceCompilerEnv", "CompilerEnvState", "CompilerEnvStateWriter", "CompilerEnvStateReader", diff --git a/compiler_gym/bin/manual_env.py b/compiler_gym/bin/manual_env.py index d90a689ed..30117da4e 100644 --- a/compiler_gym/bin/manual_env.py +++ b/compiler_gym/bin/manual_env.py @@ -228,7 +228,7 @@ from absl import app, flags -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.util.flags.benchmark_from_flags import benchmark_from_flags from compiler_gym.util.flags.env_from_flags import env_from_flags from compiler_gym.util.shell_format import emph @@ -277,7 +277,7 @@ class CompilerGymShell(cmd.Cmd): Type help or ? for more information. The 'tutorial' command will give a step by step guide.""" - def __init__(self, env: CompilerEnv): + def __init__(self, env: ClientServiceCompilerEnv): """Initialise with an environment. :param env: The environment to run. """ diff --git a/compiler_gym/bin/service.py b/compiler_gym/bin/service.py index cf4c10c38..9fbdc8ad6 100644 --- a/compiler_gym/bin/service.py +++ b/compiler_gym/bin/service.py @@ -103,7 +103,7 @@ from absl import app, flags from compiler_gym.datasets import Dataset -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.service.connection import ConnectionOpts from compiler_gym.spaces import Commandline, NamedDiscrete from compiler_gym.util.flags.env_from_flags import env_from_flags @@ -190,7 +190,7 @@ def summarize_datasets(datasets: Iterable[Dataset]) -> str: ) -def print_service_capabilities(env: CompilerEnv): +def print_service_capabilities(env: ClientServiceCompilerEnv): """Discover and print the capabilities of a CompilerGym service. :param env: An environment. diff --git a/compiler_gym/datasets/benchmark.py b/compiler_gym/datasets/benchmark.py index 6bfab49a1..84dcc0726 100644 --- a/compiler_gym/datasets/benchmark.py +++ b/compiler_gym/datasets/benchmark.py @@ -13,10 +13,12 @@ from compiler_gym.util.decorators import memoized_property from compiler_gym.validation_error import ValidationError -# A validation callback is a function that takes a single CompilerEnv instance +# A validation callback is a function that takes a single ClientServiceCompilerEnv instance # as its argument and returns an iterable sequence of zero or more # ValidationError tuples. -ValidationCallback = Callable[["CompilerEnv"], Iterable[ValidationError]] # noqa: F821 +ValidationCallback = Callable[ + ["ClientServiceCompilerEnv"], Iterable[ValidationError] # noqa: F821 +] class BenchmarkSource(NamedTuple): @@ -42,8 +44,8 @@ def __repr__(self) -> str: class Benchmark: """A benchmark represents a particular program that is being compiled. - A benchmark is a program that can be used by a :class:`CompilerEnv - ` as a program to optimize. A benchmark + A benchmark is a program that can be used by a :class:`ClientServiceCompilerEnv + ` as a program to optimize. A benchmark comprises the data that is fed into the compiler, identified by a URI. Benchmarks are not normally instantiated directly. Instead, benchmarks are @@ -72,9 +74,9 @@ class Benchmark: instances. The benchmark for an environment can be set during :meth:`env.reset() - `. The currently active benchmark can + `. The currently active benchmark can be queried using :attr:`env.benchmark - `: + `: >>> env = gym.make("llvm-v0") >>> env.reset(benchmark="benchmark://cbench-v1/crc32") @@ -150,7 +152,9 @@ def is_validatable(self) -> bool: """ return self._validation_callbacks != [] - def validate(self, env: "CompilerEnv") -> List[ValidationError]: # noqa: F821 + def validate( + self, env: "ClientServiceCompilerEnv" # noqa: F821 + ) -> List[ValidationError]: """Run the validation callbacks and return any errors. If no errors are returned, validation has succeeded: @@ -175,7 +179,7 @@ def validate(self, env: "CompilerEnv") -> List[ValidationError]: # noqa: F821 >>> benchmark.validate(env) == list(benchmark.ivalidate(env)) True - :param env: The :class:`CompilerEnv ` + :param env: The :class:`ClientServiceCompilerEnv ` instance that is being validated. :return: A list of zero or more :class:`ValidationError @@ -184,13 +188,15 @@ def validate(self, env: "CompilerEnv") -> List[ValidationError]: # noqa: F821 """ return list(self.ivalidate(env)) - def ivalidate(self, env: "CompilerEnv") -> Iterable[ValidationError]: # noqa: F821 + def ivalidate( + self, env: "ClientServiceCompilerEnv" # noqa: F821 + ) -> Iterable[ValidationError]: """Run the validation callbacks and return a generator of errors. This is an asynchronous version of :meth:`validate() ` that returns immediately. - :parameter env: A :class:`CompilerEnv ` + :parameter env: A :class:`ClientServiceCompilerEnv ` instance to validate. :return: A generator of :class:`ValidationError @@ -231,7 +237,7 @@ def add_validation_callback( :meth:`validate() `. :param validation_callback: A callback that accepts a single - :class:`CompilerEnv ` argument and + :class:`ClientServiceCompilerEnv ` argument and returns an iterable sequence of zero or more :class:`ValidationError ` tuples. Validation callbacks must be thread safe and must not modify the environment. diff --git a/compiler_gym/envs/BUILD b/compiler_gym/envs/BUILD index c4867c11b..45b4d3719 100644 --- a/compiler_gym/envs/BUILD +++ b/compiler_gym/envs/BUILD @@ -9,7 +9,7 @@ py_library( srcs = ["__init__.py"], visibility = ["//visibility:public"], deps = [ - ":compiler_env", + ":client_service_compiler_env", "//compiler_gym/envs/gcc", "//compiler_gym/envs/llvm", "//compiler_gym/envs/loop_tool", @@ -17,8 +17,8 @@ py_library( ) py_library( - name = "compiler_env", - srcs = ["compiler_env.py"], + name = "client_service_compiler_env", + srcs = ["client_service_compiler_env.py"], visibility = ["//compiler_gym:__subpackages__"], deps = [ ":env", diff --git a/compiler_gym/envs/CMakeLists.txt b/compiler_gym/envs/CMakeLists.txt index 352a407fe..4992b365a 100644 --- a/compiler_gym/envs/CMakeLists.txt +++ b/compiler_gym/envs/CMakeLists.txt @@ -11,7 +11,7 @@ cg_py_library( SRCS "__init__.py" DEPS - ::compiler_env + ::client_service_compiler_env compiler_gym::envs::gcc::gcc compiler_gym::envs::llvm::llvm compiler_gym::envs::loop_tool::loop_tool @@ -20,9 +20,9 @@ cg_py_library( cg_py_library( NAME - compiler_env + client_service_compiler_env SRCS - "compiler_env.py" + "client_service_compiler_env.py" DEPS ::env_py compiler_gym::compiler_env_state diff --git a/compiler_gym/envs/__init__.py b/compiler_gym/envs/__init__.py index a84943d83..8cca3f2d0 100644 --- a/compiler_gym/envs/__init__.py +++ b/compiler_gym/envs/__init__.py @@ -2,7 +2,7 @@ # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -from compiler_gym.envs.compiler_env import CompilerEnv +from compiler_gym.envs.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.envs.env import Env from compiler_gym.envs.gcc import GccEnv from compiler_gym.envs.llvm.llvm_env import LlvmEnv @@ -11,7 +11,7 @@ __all__ = [ "COMPILER_GYM_ENVS", - "CompilerEnv", + "ClientServiceCompilerEnv", "Env", "GccEnv", "LlvmEnv", diff --git a/compiler_gym/envs/compiler_env.py b/compiler_gym/envs/client_service_compiler_env.py similarity index 93% rename from compiler_gym/envs/compiler_env.py rename to compiler_gym/envs/client_service_compiler_env.py index 8934387d3..e3b9492e0 100644 --- a/compiler_gym/envs/compiler_env.py +++ b/compiler_gym/envs/client_service_compiler_env.py @@ -64,7 +64,7 @@ logger = logging.getLogger(__name__) # NOTE(cummins): This is only required to prevent a name conflict with the now -# deprecated CompilerEnv.logger attribute. This can be removed once the logger +# deprecated ClientServiceCompilerEnv.logger attribute. This can be removed once the logger # attribute is removed, scheduled for release 0.2.3. _logger = logger @@ -81,7 +81,7 @@ def _wrapped_step( raise -class CompilerEnv(Env): +class ClientServiceCompilerEnv(Env): """An OpenAI gym environment for compiler optimizations. The easiest way to create a CompilerGym environment is to call @@ -96,7 +96,7 @@ class CompilerEnv(Env): connecting to a running compiler service at :code:`localhost:8080` (see :doc:`this document ` for more details): - >>> env = CompilerEnv( + >>> env = ClientServiceCompilerEnv( ... service="localhost:8080", ... observation_space="features", ... reward_space="runtime", @@ -145,7 +145,7 @@ class CompilerEnv(Env): :vartype reward: compiler_gym.views.RewardView - :ivar episode_reward: If :func:`CompilerEnv.reward_space + :ivar episode_reward: If :func:`ClientServiceCompilerEnv.reward_space ` is set, this value is the sum of all rewards for the current episode. @@ -193,7 +193,7 @@ def __init__( `. If not provided, :func:`step()` returns :code:`None` for the observation value. Can be set later using :meth:`env.observation_space - `. For available + `. For available spaces, see :class:`env.observation.spaces `. @@ -202,7 +202,7 @@ def __init__( `. If not provided, :func:`step()` returns :code:`None` for the reward value. Can be set later using :meth:`env.reward_space - `. For available spaces, + `. For available spaces, see :class:`env.reward.spaces `. :param action_space: The name of the action space to use. If not @@ -228,9 +228,9 @@ def __init__( # in release 0.2.3. if logger: warnings.warn( - "The `logger` argument is deprecated on CompilerEnv.__init__() " - "and will be removed in a future release. All CompilerEnv " - "instances share a logger named compiler_gym.envs.compiler_env", + "The `logger` argument is deprecated on ClientServiceCompilerEnv.__init__() " + "and will be removed in a future release. All ClientServiceCompilerEnv " + "instances share a logger named compiler_gym.envs.client_service_compiler_env", DeprecationWarning, ) @@ -290,7 +290,7 @@ def __init__( self._benchmark_in_use = self._next_benchmark except StopIteration: # StopIteration raised on next(self.datasets.benchmarks()) if there - # are no benchmarks available. This is to allow CompilerEnv to be + # are no benchmarks available. This is to allow ClientServiceCompilerEnv to be # used without any datasets by setting a benchmark before/during the # first reset() call. pass @@ -343,8 +343,8 @@ def observation_space_spec( @deprecated( version="0.2.1", reason=( - "The `CompilerEnv.logger` attribute is deprecated. All CompilerEnv " - "instances share a logger named compiler_gym.envs.compiler_env" + "The `ClientServiceCompilerEnv.logger` attribute is deprecated. All ClientServiceCompilerEnv " + "instances share a logger named compiler_gym.envs.client_service_compiler_env" ), ) def logger(self): @@ -370,15 +370,15 @@ def compiler_version(self) -> str: return self.versions.compiler_version def commandline(self) -> str: - """Interface for :class:`CompilerEnv ` + """Interface for :class:`ClientServiceCompilerEnv ` subclasses to provide an equivalent commandline invocation to the current environment state. See also :meth:`commandline_to_actions() - `. + `. - Calling this method on a :class:`CompilerEnv - ` instance raises + Calling this method on a :class:`ClientServiceCompilerEnv + ` instance raises :code:`NotImplementedError`. :return: A string commandline invocation. @@ -386,15 +386,15 @@ def commandline(self) -> str: raise NotImplementedError("abstract method") def commandline_to_actions(self, commandline: str) -> List[ActionType]: - """Interface for :class:`CompilerEnv ` + """Interface for :class:`ClientServiceCompilerEnv ` subclasses to convert from a commandline invocation to a sequence of actions. See also :meth:`commandline() - `. + `. - Calling this method on a :class:`CompilerEnv - ` instance raises + Calling this method on a :class:`ClientServiceCompilerEnv + ` instance raises :code:`NotImplementedError`. :return: A list of actions. @@ -404,7 +404,7 @@ def commandline_to_actions(self, commandline: str) -> List[ActionType]: @property def episode_walltime(self) -> float: """Return the amount of time in seconds since the last call to - :meth:`reset() `. + :meth:`reset() `. """ return time() - self.episode_start_time @@ -454,7 +454,7 @@ def benchmark(self) -> Benchmark: .. note:: Setting a new benchmark has no effect until - :func:`env.reset() ` is called. + :func:`env.reset() ` is called. """ return self._benchmark_in_use @@ -568,7 +568,7 @@ def _init_kwargs(self) -> Dict[str, Any]: "service": self._service_endpoint, } - def fork(self) -> "CompilerEnv": + def fork(self) -> "ClientServiceCompilerEnv": if not self.in_episode: actions = self.actions.copy() self.reset() @@ -642,7 +642,7 @@ def close(self): underlying compiler (see :ref:`compiler_gym.service ` for details). This means it is important to call :meth:`env.close() - ` after use to free up + ` after use to free up resources and prevent orphan subprocesses or files. We recommend using the :code:`with`-statement pattern for creating environments: @@ -651,7 +651,7 @@ def close(self): ... # use env how you like This removes the need to call :meth:`env.close() - ` yourself. + ` yourself. """ # Try and close out the episode, but errors are okay. close_service = True @@ -891,14 +891,14 @@ def raw_step( and rewards are lists. :raises SessionNotFound: If :meth:`reset() - ` has not been called. + ` has not been called. .. warning:: Don't call this method directly, use :meth:`step() - ` or :meth:`multistep() - ` instead. The - :meth:`raw_step() ` method is an + ` or :meth:`multistep() + ` instead. The + :meth:`raw_step() ` method is an implementation detail. """ if not self.in_episode: @@ -1022,12 +1022,12 @@ def step( rewards: Optional[Iterable[Union[str, Reward]]] = None, ) -> StepType: """:raises SessionNotFound: If :meth:`reset() - ` has not been called. + ` has not been called. """ if isinstance(action, IterableType): warnings.warn( - "Argument `action` of CompilerEnv.step no longer accepts a list " - " of actions. Please use CompilerEnv.multistep instead", + "Argument `action` of ClientServiceCompilerEnv.step no longer accepts a list " + " of actions. Please use ClientServiceCompilerEnv.multistep instead", category=DeprecationWarning, ) return self.multistep( @@ -1039,14 +1039,14 @@ def step( ) if observations is not None: warnings.warn( - "Argument `observations` of CompilerEnv.step has been " + "Argument `observations` of ClientServiceCompilerEnv.step has been " "renamed `observation_spaces`. Please update your code", category=DeprecationWarning, ) observation_spaces = observations if rewards is not None: warnings.warn( - "Argument `rewards` of CompilerEnv.step has been renamed " + "Argument `rewards` of ClientServiceCompilerEnv.step has been renamed " "`reward_spaces`. Please update your code", category=DeprecationWarning, ) @@ -1062,18 +1062,18 @@ def multistep( rewards: Optional[Iterable[Union[str, Reward]]] = None, ): """:raises SessionNotFound: If :meth:`reset() - ` has not been called. + ` has not been called. """ if observations is not None: warnings.warn( - "Argument `observations` of CompilerEnv.multistep has been " + "Argument `observations` of ClientServiceCompilerEnv.multistep has been " "renamed `observation_spaces`. Please update your code", category=DeprecationWarning, ) observation_spaces = observations if rewards is not None: warnings.warn( - "Argument `rewards` of CompilerEnv.multistep has been renamed " + "Argument `rewards` of ClientServiceCompilerEnv.multistep has been renamed " "`reward_spaces`. Please update your code", category=DeprecationWarning, ) @@ -1132,7 +1132,7 @@ def render( ) -> Optional[str]: """Render the environment. - CompilerEnv instances support two render modes: "human", which prints + ClientServiceCompilerEnv instances support two render modes: "human", which prints the current environment state to the terminal and return nothing; and "ansi", which returns a string representation of the current environment state. @@ -1170,7 +1170,7 @@ def _reward_view_type(self): def apply(self, state: CompilerEnvState) -> None: # noqa """Replay this state on the given an environment. - :param env: A :class:`CompilerEnv ` + :param env: A :class:`ClientServiceCompilerEnv ` instance. :raises ValueError: If this state cannot be applied. @@ -1307,7 +1307,7 @@ def validate(self, state: Optional[CompilerEnvState] = None) -> ValidationResult def send_param(self, key: str, value: str) -> str: """Send a single parameter to the compiler service. - See :meth:`send_params() ` + See :meth:`send_params() ` for more information. :param key: The parameter key. @@ -1317,7 +1317,7 @@ def send_param(self, key: str, value: str) -> str: :return: The response from the compiler service. :raises SessionNotFound: If called before :meth:`reset() - `. + `. """ return self.send_params((key, value))[0] @@ -1332,7 +1332,7 @@ def send_params(self, *params: Iterable[Tuple[str, str]]) -> List[str]: for a specific compiler service to see what parameters, if any, are supported. - Must have called :meth:`reset() ` + Must have called :meth:`reset() ` first. :param params: A list of parameters, where each parameter is a @@ -1341,7 +1341,7 @@ def send_params(self, *params: Iterable[Tuple[str, str]]) -> List[str]: :return: A list of string responses, one per parameter. :raises SessionNotFound: If called before :meth:`reset() - `. + `. """ if not self.in_episode: raise SessionNotFound("Must call reset() before send_params()") @@ -1362,11 +1362,11 @@ def send_params(self, *params: Iterable[Tuple[str, str]]) -> List[str]: return list(reply.reply) - def __copy__(self) -> "CompilerEnv": + def __copy__(self) -> "ClientServiceCompilerEnv": raise TypeError( - "CompilerEnv instances do not support shallow copies. Use deepcopy()" + "ClientServiceCompilerEnv instances do not support shallow copies. Use deepcopy()" ) - def __deepcopy__(self, memo) -> "CompilerEnv": + def __deepcopy__(self, memo) -> "ClientServiceCompilerEnv": del memo # unused return self.fork() diff --git a/compiler_gym/envs/gcc/BUILD b/compiler_gym/envs/gcc/BUILD index 70fa575fa..b8df99ff8 100644 --- a/compiler_gym/envs/gcc/BUILD +++ b/compiler_gym/envs/gcc/BUILD @@ -17,7 +17,7 @@ py_library( ], visibility = ["//visibility:public"], deps = [ - "//compiler_gym/envs:compiler_env", + "//compiler_gym/envs:client_service_compiler_env", "//compiler_gym/envs/gcc/datasets", "//compiler_gym/service", "//compiler_gym/service/runtime", # Implicit dependency of service. diff --git a/compiler_gym/envs/gcc/CMakeLists.txt b/compiler_gym/envs/gcc/CMakeLists.txt index 301315d1b..7146c14de 100644 --- a/compiler_gym/envs/gcc/CMakeLists.txt +++ b/compiler_gym/envs/gcc/CMakeLists.txt @@ -16,7 +16,7 @@ cg_py_library( DATA compiler_gym::envs::gcc::service::service DEPS - compiler_gym::envs::compiler_env + compiler_gym::envs::client_service_compiler_env compiler_gym::envs::gcc::datasets::datasets compiler_gym::service::service compiler_gym::service::runtime::runtime diff --git a/compiler_gym/envs/gcc/datasets/csmith.py b/compiler_gym/envs/gcc/datasets/csmith.py index 681a6a3a5..04a1726fc 100644 --- a/compiler_gym/envs/gcc/datasets/csmith.py +++ b/compiler_gym/envs/gcc/datasets/csmith.py @@ -81,7 +81,7 @@ class CsmithDataset(Dataset): Note that Csmith is a tool that is used to find errors in compilers. As such, there is a higher likelihood that the benchmark cannot be used for an environment and that :meth:`env.reset() - ` will raise :class:`BenchmarkInitError + ` will raise :class:`BenchmarkInitError `. """ diff --git a/compiler_gym/envs/gcc/gcc_env.py b/compiler_gym/envs/gcc/gcc_env.py index efffa14c8..65e70a09a 100644 --- a/compiler_gym/envs/gcc/gcc_env.py +++ b/compiler_gym/envs/gcc/gcc_env.py @@ -10,7 +10,7 @@ from typing import Any, Dict, List, Optional, Union from compiler_gym.datasets import Benchmark -from compiler_gym.envs.compiler_env import CompilerEnv +from compiler_gym.envs.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.envs.gcc.datasets import get_gcc_datasets from compiler_gym.envs.gcc.gcc import Gcc, GccSpec from compiler_gym.envs.gcc.gcc_rewards import AsmSizeReward, ObjSizeReward @@ -22,8 +22,8 @@ DEFAULT_GCC: str = "docker:gcc:11.2.0" -class GccEnv(CompilerEnv): - """A specialized CompilerEnv for GCC. +class GccEnv(ClientServiceCompilerEnv): + """A specialized ClientServiceCompilerEnv for GCC. This class exposes the optimization space of GCC's command line flags as an environment for reinforcement learning. For further details, see the diff --git a/compiler_gym/envs/llvm/BUILD b/compiler_gym/envs/llvm/BUILD index 513ecc926..b7d6fa091 100644 --- a/compiler_gym/envs/llvm/BUILD +++ b/compiler_gym/envs/llvm/BUILD @@ -48,7 +48,7 @@ py_library( ":llvm_benchmark", ":llvm_rewards", "//compiler_gym/datasets", - "//compiler_gym/envs:compiler_env", + "//compiler_gym/envs:client_service_compiler_env", "//compiler_gym/envs/llvm/datasets", "//compiler_gym/spaces", "//compiler_gym/third_party/autophase", diff --git a/compiler_gym/envs/llvm/CMakeLists.txt b/compiler_gym/envs/llvm/CMakeLists.txt index 009e95912..346248937 100644 --- a/compiler_gym/envs/llvm/CMakeLists.txt +++ b/compiler_gym/envs/llvm/CMakeLists.txt @@ -50,7 +50,7 @@ cg_py_library( ::llvm_benchmark ::llvm_rewards compiler_gym::datasets::datasets - compiler_gym::envs::compiler_env + compiler_gym::envs::client_service_compiler_env compiler_gym::envs::llvm::datasets::datasets compiler_gym::spaces::spaces compiler_gym::third_party::autophase::autophase diff --git a/compiler_gym/envs/llvm/datasets/csmith.py b/compiler_gym/envs/llvm/datasets/csmith.py index 54c8815da..f22d87f13 100644 --- a/compiler_gym/envs/llvm/datasets/csmith.py +++ b/compiler_gym/envs/llvm/datasets/csmith.py @@ -89,7 +89,7 @@ class CsmithDataset(Dataset): Note that Csmith is a tool that is used to find errors in compilers. As such, there is a higher likelihood that the benchmark cannot be used for an environment and that :meth:`env.reset() - ` will raise :class:`BenchmarkInitError + ` will raise :class:`BenchmarkInitError `. """ diff --git a/compiler_gym/envs/llvm/datasets/llvm_stress.py b/compiler_gym/envs/llvm/datasets/llvm_stress.py index daa0985ac..38fd09232 100644 --- a/compiler_gym/envs/llvm/datasets/llvm_stress.py +++ b/compiler_gym/envs/llvm/datasets/llvm_stress.py @@ -32,7 +32,7 @@ class LlvmStressDataset(Dataset): Note that llvm-stress is a tool that is used to find errors in LLVM. As such, there is a higher likelihood that the benchmark cannot be used for an environment and that :meth:`env.reset() - ` will raise + ` will raise :class:`BenchmarkInitError `. """ diff --git a/compiler_gym/envs/llvm/llvm_benchmark.py b/compiler_gym/envs/llvm/llvm_benchmark.py index 115b5db52..83dae7e07 100644 --- a/compiler_gym/envs/llvm/llvm_benchmark.py +++ b/compiler_gym/envs/llvm/llvm_benchmark.py @@ -230,7 +230,7 @@ def make_benchmark( You must ensure that any :code:`.bc` and :code:`.ll` files are compatible with the LLVM version used by CompilerGym, which can be reported using :func:`env.compiler_version - `. + `. E.g. for single-source C/C++ programs, you can pass the path of the source file: diff --git a/compiler_gym/envs/llvm/llvm_env.py b/compiler_gym/envs/llvm/llvm_env.py index c8b5b9c45..168c8c570 100644 --- a/compiler_gym/envs/llvm/llvm_env.py +++ b/compiler_gym/envs/llvm/llvm_env.py @@ -2,7 +2,7 @@ # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -"""Extensions to the CompilerEnv environment for LLVM.""" +"""Extensions to the ClientServiceCompilerEnv environment for LLVM.""" import os import shutil from pathlib import Path @@ -11,7 +11,7 @@ import numpy as np from compiler_gym.datasets import Benchmark, BenchmarkInitError, Dataset -from compiler_gym.envs.compiler_env import CompilerEnv +from compiler_gym.envs.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.envs.llvm.datasets import get_llvm_datasets from compiler_gym.envs.llvm.llvm_benchmark import ClangInvocation, make_benchmark from compiler_gym.envs.llvm.llvm_rewards import ( @@ -45,11 +45,11 @@ def _get_llvm_datasets(site_data_base: Optional[Path] = None) -> Iterable[Datase return get_llvm_datasets(site_data_base=site_data_base) -class LlvmEnv(CompilerEnv): - """A specialized CompilerEnv for LLVM. +class LlvmEnv(ClientServiceCompilerEnv): + """A specialized ClientServiceCompilerEnv for LLVM. - This extends the default :class:`CompilerEnv - ` environment, adding extra LLVM + This extends the default :class:`ClientServiceCompilerEnv + ` environment, adding extra LLVM functionality. Specifically, the actions use the :class:`CommandlineFlag ` space, which is a type of :code:`Discrete` space that provides additional documentation about each @@ -378,7 +378,7 @@ def make_benchmark( You must ensure that any :code:`.bc` and :code:`.ll` files are compatible with the LLVM version used by CompilerGym, which can be reported using :func:`env.compiler_version - `. + `. E.g. for single-source C/C++ programs, you can pass the path of the source file: diff --git a/compiler_gym/envs/loop_tool/BUILD b/compiler_gym/envs/loop_tool/BUILD index 037afa63f..c7345c47b 100644 --- a/compiler_gym/envs/loop_tool/BUILD +++ b/compiler_gym/envs/loop_tool/BUILD @@ -13,7 +13,7 @@ py_library( data = ["//compiler_gym/envs/loop_tool/service"], visibility = ["//visibility:public"], deps = [ - "//compiler_gym/envs:compiler_env", + "//compiler_gym/envs:client_service_compiler_env", "//compiler_gym/service", "//compiler_gym/service/proto", "//compiler_gym/service/runtime", diff --git a/compiler_gym/envs/loop_tool/CMakeLists.txt b/compiler_gym/envs/loop_tool/CMakeLists.txt index 1b707400f..abbcb3f83 100644 --- a/compiler_gym/envs/loop_tool/CMakeLists.txt +++ b/compiler_gym/envs/loop_tool/CMakeLists.txt @@ -12,7 +12,7 @@ cg_py_library( "loop_tool_env.py" DATA compiler_gym::envs::loop_tool::service::service DEPS - compiler_gym::envs::compiler_env + compiler_gym::envs::client_service_compiler_env compiler_gym::service::service compiler_gym::service::proto::proto compiler_gym::service::runtime::runtime diff --git a/compiler_gym/envs/loop_tool/loop_tool_env.py b/compiler_gym/envs/loop_tool/loop_tool_env.py index 19be8a957..089d10cff 100644 --- a/compiler_gym/envs/loop_tool/loop_tool_env.py +++ b/compiler_gym/envs/loop_tool/loop_tool_env.py @@ -2,9 +2,9 @@ # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -from compiler_gym.envs.compiler_env import CompilerEnv +from compiler_gym.envs.client_service_compiler_env import ClientServiceCompilerEnv -class LoopToolEnv(CompilerEnv): +class LoopToolEnv(ClientServiceCompilerEnv): def commandline(self): return ",".join(str(x) for x in self.actions) diff --git a/compiler_gym/leaderboard/llvm_instcount.py b/compiler_gym/leaderboard/llvm_instcount.py index 7a9c079a0..3702cfab4 100644 --- a/compiler_gym/leaderboard/llvm_instcount.py +++ b/compiler_gym/leaderboard/llvm_instcount.py @@ -166,7 +166,7 @@ def eval_llvm_instcount_policy(policy: Policy) -> None: The role of your policy is to perform a sequence of actions on the supplied environment so as to maximize cumulative reward. By default, no observation space is set on the environment, so :meth:`env.step() - ` will return :code:`None` for the + ` will return :code:`None` for the observation. You may set a new observation space: >>> env.observation_space = "InstCount" # Set a new space for env.step() diff --git a/compiler_gym/random_replay.py b/compiler_gym/random_replay.py index 81be67ba2..08871c7c1 100644 --- a/compiler_gym/random_replay.py +++ b/compiler_gym/random_replay.py @@ -8,7 +8,7 @@ from deprecated import deprecated -from compiler_gym.envs.compiler_env import CompilerEnv +from compiler_gym.envs.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.random_search import replay_actions as replay_actions_ from compiler_gym.random_search import ( replay_actions_from_logs as replay_actions_from_logs_, @@ -16,7 +16,9 @@ @deprecated(version="0.2.1", reason="Use env.step(action) instead") -def replay_actions(env: CompilerEnv, action_names: List[str], outdir: Path): +def replay_actions( + env: ClientServiceCompilerEnv, action_names: List[str], outdir: Path +): return replay_actions_(env, action_names, outdir) @@ -24,5 +26,7 @@ def replay_actions(env: CompilerEnv, action_names: List[str], outdir: Path): version="0.2.1", reason="Use compiler_gym.random_search.replay_actions_from_logs() instead", ) -def replay_actions_from_logs(env: CompilerEnv, logdir: Path, benchmark=None) -> None: +def replay_actions_from_logs( + env: ClientServiceCompilerEnv, logdir: Path, benchmark=None +) -> None: return replay_actions_from_logs_(env, logdir, benchmark) diff --git a/compiler_gym/random_search.py b/compiler_gym/random_search.py index a81b0bdb2..f6953ba4e 100644 --- a/compiler_gym/random_search.py +++ b/compiler_gym/random_search.py @@ -13,7 +13,7 @@ import humanize -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.envs.llvm import LlvmEnv from compiler_gym.service.connection import ServiceError from compiler_gym.util import logs @@ -68,7 +68,7 @@ class RandomAgentWorker(Thread): def __init__( self, - make_env: Callable[[], CompilerEnv], + make_env: Callable[[], ClientServiceCompilerEnv], patience: int, ): super().__init__() @@ -99,14 +99,14 @@ def run(self) -> None: self._patience = self._patience or env.action_space.n self.run_one_environment(env) - def run_one_environment(self, env: CompilerEnv) -> None: + def run_one_environment(self, env: ClientServiceCompilerEnv) -> None: """Run random walks in an infinite loop. Returns if the environment ends.""" while self.should_run_one_episode: self.total_episode_count += 1 if not self.run_one_episode(env): return - def run_one_episode(self, env: CompilerEnv) -> bool: + def run_one_episode(self, env: ClientServiceCompilerEnv) -> bool: """Run a single random episode. :param env: An environment. @@ -141,18 +141,18 @@ def run_one_episode(self, env: CompilerEnv) -> bool: def random_search( - make_env: Callable[[], CompilerEnv], + make_env: Callable[[], ClientServiceCompilerEnv], outdir: Optional[Union[str, Path]] = None, total_runtime: Optional[float] = 600, patience: int = 0, nproc: int = cpu_count(), skip_done: bool = False, -) -> CompilerEnv: +) -> ClientServiceCompilerEnv: with make_env() as env: env.reset() - if not isinstance(env.unwrapped, CompilerEnv): + if not isinstance(env.unwrapped, ClientServiceCompilerEnv): raise TypeError( - f"random_search() requires CompilerEnv. Called with: {type(env).__name__}" + f"random_search() requires ClientServiceCompilerEnv. Called with: {type(env).__name__}" ) benchmark_uri = env.benchmark.uri @@ -296,7 +296,9 @@ def random_search( return env -def replay_actions(env: CompilerEnv, action_names: List[str], outdir: Path): +def replay_actions( + env: ClientServiceCompilerEnv, action_names: List[str], outdir: Path +): logs_path = outdir / logs.BEST_ACTIONS_PROGRESS_NAME start_time = time() @@ -345,7 +347,9 @@ def replay_actions(env: CompilerEnv, action_names: List[str], outdir: Path): ) -def replay_actions_from_logs(env: CompilerEnv, logdir: Path, benchmark=None) -> None: +def replay_actions_from_logs( + env: ClientServiceCompilerEnv, logdir: Path, benchmark=None +) -> None: best_actions_path = logdir / logs.BEST_ACTIONS_NAME meta_path = logdir / logs.METADATA_NAME diff --git a/compiler_gym/service/compilation_session.py b/compiler_gym/service/compilation_session.py index 0ddf5687a..de59aeaa1 100644 --- a/compiler_gym/service/compilation_session.py +++ b/compiler_gym/service/compilation_session.py @@ -93,7 +93,7 @@ def handle_session_parameter(self, key: str, value: str) -> Optional[str]: Session parameters provide a method to send ad-hoc key-value messages to a compilation session through the :meth:`env.send_session_parameter() - ` method. It us up + ` method. It us up to the client/service to agree on a common schema for encoding and decoding these parameters. diff --git a/compiler_gym/service/connection.py b/compiler_gym/service/connection.py index 8f9295781..9fa49f4a1 100644 --- a/compiler_gym/service/connection.py +++ b/compiler_gym/service/connection.py @@ -94,9 +94,9 @@ class ConnectionOpts(BaseModel): always_send_benchmark_on_reset: bool = False """Send the full benchmark program data to the compiler service on ever call - to :meth:`env.reset() `. This is more + to :meth:`env.reset() `. This is more efficient in cases where the majority of calls to - :meth:`env.reset() ` uses a different + :meth:`env.reset() ` uses a different benchmark. In case of benchmark re-use, leave this :code:`False`. """ diff --git a/compiler_gym/util/debug_util.py b/compiler_gym/util/debug_util.py index edc87db40..5e4f52bde 100644 --- a/compiler_gym/util/debug_util.py +++ b/compiler_gym/util/debug_util.py @@ -63,7 +63,7 @@ def set_debug_level(level: int) -> None: Setting the debug level affects the entire process and is not thread safe. For granular control of logging information, consider instead setting a - :code:`logging.Logger` instance on :code:`CompilerEnv.logger`. + :code:`logging.Logger` instance on :code:`ClientServiceCompilerEnv.logger`. :param level: The debugging level to use. """ diff --git a/compiler_gym/util/flags/env_from_flags.py b/compiler_gym/util/flags/env_from_flags.py index d240d6a6b..bf0cf012e 100644 --- a/compiler_gym/util/flags/env_from_flags.py +++ b/compiler_gym/util/flags/env_from_flags.py @@ -11,7 +11,7 @@ import gym from absl import app, flags -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.service import ConnectionOpts from compiler_gym.service.proto import Benchmark from compiler_gym.util.registration import COMPILER_GYM_ENVS @@ -109,7 +109,9 @@ def connection_settings_from_flags( ) -def env_from_flags(benchmark: Optional[Union[str, Benchmark]] = None) -> CompilerEnv: +def env_from_flags( + benchmark: Optional[Union[str, Benchmark]] = None +) -> ClientServiceCompilerEnv: if FLAGS.ls_env: print("\n".join(sorted(COMPILER_GYM_ENVS))) sys.exit(0) @@ -143,6 +145,6 @@ def env_from_flags(benchmark: Optional[Union[str, Benchmark]] = None) -> Compile @contextmanager def env_session_from_flags( benchmark: Optional[Union[str, Benchmark]] = None -) -> CompilerEnv: +) -> ClientServiceCompilerEnv: with env_from_flags(benchmark=benchmark) as env: yield env diff --git a/compiler_gym/validate.py b/compiler_gym/validate.py index b9ac7bb4b..0b9192930 100644 --- a/compiler_gym/validate.py +++ b/compiler_gym/validate.py @@ -8,13 +8,13 @@ from typing import Callable, Iterable, Optional from compiler_gym.compiler_env_state import CompilerEnvState -from compiler_gym.envs.compiler_env import CompilerEnv +from compiler_gym.envs.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.util import thread_pool from compiler_gym.validation_result import ValidationResult def _validate_states_worker( - make_env: Callable[[], CompilerEnv], state: CompilerEnvState + make_env: Callable[[], ClientServiceCompilerEnv], state: CompilerEnvState ) -> ValidationResult: with make_env() as env: result = env.validate(state) @@ -22,13 +22,13 @@ def _validate_states_worker( def validate_states( - make_env: Callable[[], CompilerEnv], + make_env: Callable[[], ClientServiceCompilerEnv], states: Iterable[CompilerEnvState], nproc: Optional[int] = None, inorder: bool = False, ) -> Iterable[ValidationResult]: """A parallelized implementation of - :meth:`env.validate() ` for batched + :meth:`env.validate() ` for batched validation. :param make_env: A callback which instantiates a compiler environment. diff --git a/compiler_gym/validation_error.py b/compiler_gym/validation_error.py index cbbdbf054..8a1468892 100644 --- a/compiler_gym/validation_error.py +++ b/compiler_gym/validation_error.py @@ -10,7 +10,7 @@ class ValidationError(BaseModel): """A ValidationError describes an error encountered in a call to - :meth:`env.validate() `. + :meth:`env.validate() `. """ type: str diff --git a/compiler_gym/views/observation_space_spec.py b/compiler_gym/views/observation_space_spec.py index 77b50c9fd..9377522dd 100644 --- a/compiler_gym/views/observation_space_spec.py +++ b/compiler_gym/views/observation_space_spec.py @@ -32,8 +32,8 @@ class ObservationSpaceSpec: :vartype platform_dependent: bool :ivar default_value: A default observation. This value will be returned by - :func:`CompilerEnv.step() ` if - :func:`CompilerEnv.observation_space ` + :func:`ClientServiceCompilerEnv.step() ` if + :func:`ClientServiceCompilerEnv.observation_space ` is set and the service terminates. """ diff --git a/examples/example_compiler_gym_service/__init__.py b/examples/example_compiler_gym_service/__init__.py index 8cb7ab614..60680b829 100644 --- a/examples/example_compiler_gym_service/__init__.py +++ b/examples/example_compiler_gym_service/__init__.py @@ -83,7 +83,7 @@ def benchmark_from_parsed_uri(self, uri: BenchmarkUri) -> Benchmark: # the example-v0 environment will be available to gym.make(...). register( id="example-cc-v0", - entry_point="compiler_gym.envs:CompilerEnv", + entry_point="compiler_gym.envs:ClientServiceCompilerEnv", kwargs={ "service": EXAMPLE_CC_SERVICE_BINARY, "rewards": [RuntimeReward()], @@ -93,7 +93,7 @@ def benchmark_from_parsed_uri(self, uri: BenchmarkUri) -> Benchmark: register( id="example-py-v0", - entry_point="compiler_gym.envs:CompilerEnv", + entry_point="compiler_gym.envs:ClientServiceCompilerEnv", kwargs={ "service": EXAMPLE_PY_SERVICE_BINARY, "rewards": [RuntimeReward()], diff --git a/examples/example_compiler_gym_service/demo_without_bazel.py b/examples/example_compiler_gym_service/demo_without_bazel.py index 305c2bf22..e6dc81b4e 100644 --- a/examples/example_compiler_gym_service/demo_without_bazel.py +++ b/examples/example_compiler_gym_service/demo_without_bazel.py @@ -88,7 +88,7 @@ def benchmark_from_parsed_uri(self, uri: BenchmarkUri) -> Benchmark: # Register the environment for use with gym.make(...). register( id="example-v0", - entry_point="compiler_gym.envs:CompilerEnv", + entry_point="compiler_gym.envs:ClientServiceCompilerEnv", kwargs={ "service": EXAMPLE_PY_SERVICE_BINARY, "rewards": [RuntimeReward()], diff --git a/examples/example_compiler_gym_service/env_tests.py b/examples/example_compiler_gym_service/env_tests.py index 4b2259bc7..ea44d9103 100644 --- a/examples/example_compiler_gym_service/env_tests.py +++ b/examples/example_compiler_gym_service/env_tests.py @@ -14,7 +14,7 @@ from flaky import flaky import examples.example_compiler_gym_service as example -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.service import SessionNotFound from compiler_gym.spaces import Box, NamedDiscrete, Scalar, Sequence from compiler_gym.util.commands import Popen @@ -26,7 +26,7 @@ @pytest.fixture(scope="function", params=EXAMPLE_ENVIRONMENTS) -def env(request) -> CompilerEnv: +def env(request) -> ClientServiceCompilerEnv: """Text fixture that yields an environment.""" with gym.make(request.param) as env: yield env @@ -64,12 +64,12 @@ def run(cmd): assert returncode == 1 -def test_versions(env: CompilerEnv): +def test_versions(env: ClientServiceCompilerEnv): """Tests the GetVersion() RPC endpoint.""" assert env.compiler_version == "1.0.0" -def test_action_space(env: CompilerEnv): +def test_action_space(env: ClientServiceCompilerEnv): """Test that the environment reports the service's action spaces.""" assert env.action_spaces == [ NamedDiscrete( @@ -79,7 +79,7 @@ def test_action_space(env: CompilerEnv): ] -def test_observation_spaces(env: CompilerEnv): +def test_observation_spaces(env: ClientServiceCompilerEnv): """Test that the environment reports the service's observation spaces.""" env.reset() assert env.observation.spaces.keys() == {"ir", "features", "runtime"} @@ -96,50 +96,50 @@ def test_observation_spaces(env: CompilerEnv): ) -def test_reward_spaces(env: CompilerEnv): +def test_reward_spaces(env: ClientServiceCompilerEnv): """Test that the environment reports the service's reward spaces.""" env.reset() assert env.reward.spaces.keys() == {"runtime"} -def test_step_before_reset(env: CompilerEnv): +def test_step_before_reset(env: ClientServiceCompilerEnv): """Taking a step() before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): env.step(0) -def test_observation_before_reset(env: CompilerEnv): +def test_observation_before_reset(env: ClientServiceCompilerEnv): """Taking an observation before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): _ = env.observation["ir"] -def test_reward_before_reset(env: CompilerEnv): +def test_reward_before_reset(env: ClientServiceCompilerEnv): """Taking a reward before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): _ = env.reward["runtime"] -def test_reset_invalid_benchmark(env: CompilerEnv): +def test_reset_invalid_benchmark(env: ClientServiceCompilerEnv): """Test requesting a specific benchmark.""" with pytest.raises(LookupError) as ctx: env.reset(benchmark="example-v0/foobar") assert str(ctx.value) == "Unknown program name" -def test_invalid_observation_space(env: CompilerEnv): +def test_invalid_observation_space(env: ClientServiceCompilerEnv): """Test error handling with invalid observation space.""" with pytest.raises(LookupError): env.observation_space = 100 -def test_invalid_reward_space(env: CompilerEnv): +def test_invalid_reward_space(env: ClientServiceCompilerEnv): """Test error handling with invalid reward space.""" with pytest.raises(LookupError): env.reward_space = 100 -def test_double_reset(env: CompilerEnv): +def test_double_reset(env: ClientServiceCompilerEnv): """Test that reset() can be called twice.""" env.reset() assert env.in_episode @@ -147,7 +147,7 @@ def test_double_reset(env: CompilerEnv): assert env.in_episode -def test_double_reset_with_step(env: CompilerEnv): +def test_double_reset_with_step(env: ClientServiceCompilerEnv): """Test that reset() can be called twice with a step.""" env.reset() assert env.in_episode @@ -159,7 +159,7 @@ def test_double_reset_with_step(env: CompilerEnv): assert env.in_episode -def test_Step_out_of_range(env: CompilerEnv): +def test_Step_out_of_range(env: ClientServiceCompilerEnv): """Test error handling with an invalid action.""" env.reset() with pytest.raises(ValueError) as ctx: @@ -167,7 +167,7 @@ def test_Step_out_of_range(env: CompilerEnv): assert str(ctx.value) == "Out-of-range" -def test_default_ir_observation(env: CompilerEnv): +def test_default_ir_observation(env: ClientServiceCompilerEnv): """Test default observation space.""" env.observation_space = "ir" observation = env.reset() @@ -179,7 +179,7 @@ def test_default_ir_observation(env: CompilerEnv): assert not done -def test_default_features_observation(env: CompilerEnv): +def test_default_features_observation(env: ClientServiceCompilerEnv): """Test default observation space.""" env.observation_space = "features" observation = env.reset() @@ -189,7 +189,7 @@ def test_default_features_observation(env: CompilerEnv): assert observation.tolist() == [0, 0, 0] -def test_default_reward(env: CompilerEnv): +def test_default_reward(env: ClientServiceCompilerEnv): """Test default reward space.""" env.reward_space = "runtime" env.reset() @@ -199,27 +199,27 @@ def test_default_reward(env: CompilerEnv): assert not done -def test_observations(env: CompilerEnv): +def test_observations(env: ClientServiceCompilerEnv): """Test observation spaces.""" env.reset() assert env.observation["ir"] == "Hello, world!" np.testing.assert_array_equal(env.observation["features"], [0, 0, 0]) -def test_rewards(env: CompilerEnv): +def test_rewards(env: ClientServiceCompilerEnv): """Test reward spaces.""" env.reset() assert env.reward["runtime"] == 0 -def test_benchmarks(env: CompilerEnv): +def test_benchmarks(env: ClientServiceCompilerEnv): assert list(env.datasets.benchmark_uris()) == [ "benchmark://example-v0/foo", "benchmark://example-v0/bar", ] -def test_fork(env: CompilerEnv): +def test_fork(env: ClientServiceCompilerEnv): env.reset() env.step(0) env.step(1) diff --git a/examples/example_unrolling_service/__init__.py b/examples/example_unrolling_service/__init__.py index 4686e352e..16f2f705d 100644 --- a/examples/example_unrolling_service/__init__.py +++ b/examples/example_unrolling_service/__init__.py @@ -135,7 +135,7 @@ def benchmark_from_parsed_uri(self, uri: BenchmarkUri) -> Benchmark: register( id="unrolling-py-v0", - entry_point="compiler_gym.envs:CompilerEnv", + entry_point="compiler_gym.envs:ClientServiceCompilerEnv", kwargs={ "service": UNROLLING_PY_SERVICE_BINARY, "rewards": [RuntimeReward(), SizeReward()], diff --git a/examples/example_unrolling_service/env_tests.py b/examples/example_unrolling_service/env_tests.py index fba1ec4ab..9b98a3510 100644 --- a/examples/example_unrolling_service/env_tests.py +++ b/examples/example_unrolling_service/env_tests.py @@ -12,7 +12,7 @@ import compiler_gym import examples.example_unrolling_service as unrolling_service -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.service import SessionNotFound from compiler_gym.spaces import Box, NamedDiscrete, Scalar, Sequence from compiler_gym.util.commands import Popen @@ -20,7 +20,7 @@ @pytest.fixture(scope="function") -def env() -> CompilerEnv: +def env() -> ClientServiceCompilerEnv: """Text fixture that yields an environment.""" with gym.make("unrolling-py-v0") as env_: yield env_ @@ -54,13 +54,13 @@ def run(cmd): assert returncode == 1 -def test_versions(env: CompilerEnv): +def test_versions(env: ClientServiceCompilerEnv): """Tests the GetVersion() RPC endpoint.""" assert env.version == compiler_gym.__version__ assert env.compiler_version == "1.0.0" -def test_action_space(env: CompilerEnv): +def test_action_space(env: ClientServiceCompilerEnv): """Test that the environment reports the service's action spaces.""" assert env.action_spaces == [ NamedDiscrete( @@ -74,7 +74,7 @@ def test_action_space(env: CompilerEnv): ] -def test_observation_spaces(env: CompilerEnv): +def test_observation_spaces(env: ClientServiceCompilerEnv): """Test that the environment reports the service's observation spaces.""" env.reset() assert env.observation.spaces.keys() == {"ir", "features", "runtime", "size"} @@ -95,50 +95,50 @@ def test_observation_spaces(env: CompilerEnv): ) -def test_reward_spaces(env: CompilerEnv): +def test_reward_spaces(env: ClientServiceCompilerEnv): """Test that the environment reports the service's reward spaces.""" env.reset() assert env.reward.spaces.keys() == {"runtime", "size"} -def test_step_before_reset(env: CompilerEnv): +def test_step_before_reset(env: ClientServiceCompilerEnv): """Taking a step() before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): env.step(0) -def test_observation_before_reset(env: CompilerEnv): +def test_observation_before_reset(env: ClientServiceCompilerEnv): """Taking an observation before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): _ = env.observation["ir"] -def test_reward_before_reset(env: CompilerEnv): +def test_reward_before_reset(env: ClientServiceCompilerEnv): """Taking a reward before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): _ = env.reward["runtime"] -def test_reset_invalid_benchmark(env: CompilerEnv): +def test_reset_invalid_benchmark(env: ClientServiceCompilerEnv): """Test requesting a specific benchmark.""" with pytest.raises(LookupError) as ctx: env.reset(benchmark="unrolling-v0/foobar") assert str(ctx.value) == "Unknown program name" -def test_invalid_observation_space(env: CompilerEnv): +def test_invalid_observation_space(env: ClientServiceCompilerEnv): """Test error handling with invalid observation space.""" with pytest.raises(LookupError): env.observation_space = 100 -def test_invalid_reward_space(env: CompilerEnv): +def test_invalid_reward_space(env: ClientServiceCompilerEnv): """Test error handling with invalid reward space.""" with pytest.raises(LookupError): env.reward_space = 100 -def test_double_reset(env: CompilerEnv): +def test_double_reset(env: ClientServiceCompilerEnv): """Test that reset() can be called twice.""" env.reset() assert env.in_episode @@ -146,7 +146,7 @@ def test_double_reset(env: CompilerEnv): assert env.in_episode -def test_Step_out_of_range(env: CompilerEnv): +def test_Step_out_of_range(env: ClientServiceCompilerEnv): """Test error handling with an invalid action.""" env.reset() with pytest.raises(ValueError) as ctx: @@ -154,7 +154,7 @@ def test_Step_out_of_range(env: CompilerEnv): assert str(ctx.value) == "Out-of-range" -def test_default_ir_observation(env: CompilerEnv): +def test_default_ir_observation(env: ClientServiceCompilerEnv): """Test default observation space.""" env.observation_space = "ir" observation = env.reset() @@ -166,7 +166,7 @@ def test_default_ir_observation(env: CompilerEnv): assert reward is None -def test_default_features_observation(env: CompilerEnv): +def test_default_features_observation(env: ClientServiceCompilerEnv): """Test default observation space.""" env.observation_space = "features" observation = env.reset() @@ -176,7 +176,7 @@ def test_default_features_observation(env: CompilerEnv): assert all(obs >= 0 for obs in observation.tolist()) -def test_default_reward(env: CompilerEnv): +def test_default_reward(env: ClientServiceCompilerEnv): """Test default reward space.""" env.reward_space = "runtime" env.reset() @@ -186,27 +186,27 @@ def test_default_reward(env: CompilerEnv): assert reward is not None -def test_observations(env: CompilerEnv): +def test_observations(env: ClientServiceCompilerEnv): """Test observation spaces.""" env.reset() assert len(env.observation["ir"]) > 0 np.testing.assert_array_less([-1, -1, -1], env.observation["features"]) -def test_rewards(env: CompilerEnv): +def test_rewards(env: ClientServiceCompilerEnv): """Test reward spaces.""" env.reset() assert env.reward["runtime"] is not None -def test_benchmarks(env: CompilerEnv): +def test_benchmarks(env: ClientServiceCompilerEnv): assert list(env.datasets.benchmark_uris()) == [ "benchmark://unrolling-v0/offsets1", "benchmark://unrolling-v0/conv2d", ] -def test_fork(env: CompilerEnv): +def test_fork(env: ClientServiceCompilerEnv): env.reset() env.step(0) env.step(1) diff --git a/examples/example_unrolling_service/example_without_bazel.py b/examples/example_unrolling_service/example_without_bazel.py index 67fcd7d4a..b9a32c106 100644 --- a/examples/example_unrolling_service/example_without_bazel.py +++ b/examples/example_unrolling_service/example_without_bazel.py @@ -145,7 +145,7 @@ def benchmark_from_parsed_uri(self, uri: BenchmarkUri) -> Benchmark: register( id="unrolling-py-v0", - entry_point="compiler_gym.envs:CompilerEnv", + entry_point="compiler_gym.envs:ClientServiceCompilerEnv", kwargs={ "service": UNROLLING_PY_SERVICE_BINARY, "rewards": [RuntimeReward(), SizeReward()], diff --git a/examples/gcc_autotuning/tune.py b/examples/gcc_autotuning/tune.py index b1613e06c..74d51151a 100644 --- a/examples/gcc_autotuning/tune.py +++ b/examples/gcc_autotuning/tune.py @@ -17,7 +17,7 @@ import compiler_gym.util.flags.nproc # noqa Flag definition. import compiler_gym.util.flags.output_dir # noqa Flag definition. import compiler_gym.util.flags.seed # noqa Flag definition. -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.envs.gcc import DEFAULT_GCC from compiler_gym.service import ServiceError from compiler_gym.util.executor import Executor @@ -69,7 +69,7 @@ GCC_ENV_CONSTRUCTOR_LOCK = Lock() -def random_search(env: CompilerEnv): +def random_search(env: ClientServiceCompilerEnv): best = float("inf") for _ in range(FLAGS.gcc_search_budget): env.reset() @@ -81,7 +81,7 @@ def random_search(env: CompilerEnv): return best -def hill_climb(env: CompilerEnv): +def hill_climb(env: ClientServiceCompilerEnv): best = float("inf") for _ in range(FLAGS.gcc_search_budget): with env.fork() as fkd: @@ -98,7 +98,7 @@ def hill_climb(env: CompilerEnv): return best -def genetic_algorithm(env: CompilerEnv): +def genetic_algorithm(env: ClientServiceCompilerEnv): def f(choices): env.reset() env.choices = choices = list(map(int, choices)) diff --git a/examples/llvm_autotuning/autotuners/__init__.py b/examples/llvm_autotuning/autotuners/__init__.py index 6eab0f9b9..9904c2bf9 100644 --- a/examples/llvm_autotuning/autotuners/__init__.py +++ b/examples/llvm_autotuning/autotuners/__init__.py @@ -15,7 +15,7 @@ from pydantic import BaseModel, validator from compiler_gym.compiler_env_state import CompilerEnvState -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.util.capture_output import capture_output from compiler_gym.util.runfiles_path import transient_cache_path from compiler_gym.util.temporary_working_directory import temporary_working_directory @@ -26,7 +26,7 @@ class Autotuner(BaseModel): """This class represents an instance of an autotuning algorithm. After instantiating from a config dict, instances of this class can be used - to tune CompilerEnv instances: + to tune ClientServiceCompilerEnv instances: >>> autotuner = Autotuner( algorithm="greedy", @@ -53,7 +53,7 @@ class Autotuner(BaseModel): def autotune(self): """Return the autotuner function for this algorithm. - An autotuner function takes a single CompilerEnv argument and optional + An autotuner function takes a single ClientServiceCompilerEnv argument and optional keyword configuration arguments (determined by algorithm_config) and tunes the environment, returning nothing. """ @@ -76,7 +76,9 @@ def autotune_kwargs(self) -> Dict[str, Any]: kwargs.update(self.algorithm_config) return kwargs - def __call__(self, env: CompilerEnv, seed: int = 0xCC) -> CompilerEnvState: + def __call__( + self, env: ClientServiceCompilerEnv, seed: int = 0xCC + ) -> CompilerEnvState: """Autotune the given environment. :param env: The environment to autotune. diff --git a/examples/llvm_autotuning/autotuners/nevergrad_.py b/examples/llvm_autotuning/autotuners/nevergrad_.py index bacea33d8..d700407b3 100644 --- a/examples/llvm_autotuning/autotuners/nevergrad_.py +++ b/examples/llvm_autotuning/autotuners/nevergrad_.py @@ -9,12 +9,12 @@ import nevergrad as ng from llvm_autotuning.optimization_target import OptimizationTarget -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.util.gym_type_hints import ActionType def nevergrad( - env: CompilerEnv, + env: ClientServiceCompilerEnv, optimization_target: OptimizationTarget, search_time_seconds: int, seed: int, diff --git a/examples/llvm_autotuning/autotuners/opentuner_.py b/examples/llvm_autotuning/autotuners/opentuner_.py index 9d506093b..d7dec0aa3 100644 --- a/examples/llvm_autotuning/autotuners/opentuner_.py +++ b/examples/llvm_autotuning/autotuners/opentuner_.py @@ -11,7 +11,7 @@ import numpy as np from llvm_autotuning.optimization_target import OptimizationTarget -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.envs.llvm import compute_observation from compiler_gym.service.connection import ServiceError from compiler_gym.third_party.llvm import opt_path @@ -33,7 +33,7 @@ def opentuner_ga( - env: CompilerEnv, + env: ClientServiceCompilerEnv, optimization_target: OptimizationTarget, search_time_seconds: int, seed: int, diff --git a/examples/llvm_autotuning/autotuners/random_.py b/examples/llvm_autotuning/autotuners/random_.py index 7ef575f22..feb269cd9 100644 --- a/examples/llvm_autotuning/autotuners/random_.py +++ b/examples/llvm_autotuning/autotuners/random_.py @@ -6,13 +6,13 @@ from llvm_autotuning.optimization_target import OptimizationTarget -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.random_search import random_search as lib_random_search from compiler_gym.util.runfiles_path import transient_cache_path def random( - env: CompilerEnv, + env: ClientServiceCompilerEnv, optimization_target: OptimizationTarget, search_time_seconds: int, patience: int = 350, diff --git a/examples/llvm_rl/model/benchmarks.py b/examples/llvm_rl/model/benchmarks.py index b707564e7..593e5fe22 100644 --- a/examples/llvm_rl/model/benchmarks.py +++ b/examples/llvm_rl/model/benchmarks.py @@ -8,7 +8,7 @@ from pydantic import BaseModel, Field, root_validator, validator from compiler_gym.datasets import Benchmark, BenchmarkUri -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv class Benchmarks(BaseModel): @@ -54,11 +54,11 @@ class Benchmarks(BaseModel): # === Start of public API. === - def benchmarks_iterator(self, env: CompilerEnv) -> Iterable[Benchmark]: + def benchmarks_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[Benchmark]: """Return an iterator over the benchmarks.""" return self._benchmark_iterator(env) - def benchmark_uris_iterator(self, env: CompilerEnv) -> Iterable[str]: + def benchmark_uris_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[str]: """Return an iterator over the URIs of the benchmarks.""" return self._benchmark_iterator(env, uris=True) @@ -80,7 +80,7 @@ def validate_uris(cls, value, *, values, **kwargs): return list(value) def _benchmark_iterator( - self, env: CompilerEnv, uris: bool = False + self, env: ClientServiceCompilerEnv, uris: bool = False ) -> Union[Iterable[Benchmark], Iterable[str]]: return ( self._uris_iterator(env, uris) @@ -89,7 +89,7 @@ def _benchmark_iterator( ) def _uris_iterator( - self, env: CompilerEnv, uris: bool = False + self, env: ClientServiceCompilerEnv, uris: bool = False ) -> Union[Iterable[Benchmark], Iterable[str]]: """Iterate from a URIs list.""" start = self.benchmarks_start_at @@ -105,7 +105,7 @@ def _uris_iterator( return islice((env.datasets.benchmark(u) for u in self.uris), start, start + n) def _dataset_iterator( - self, env: CompilerEnv, uris: bool = False + self, env: ClientServiceCompilerEnv, uris: bool = False ) -> Union[Iterable[Benchmark], Iterable[str]]: """Iterate from a dataset name.""" dataset = env.datasets[self.dataset] diff --git a/examples/llvm_rl/model/environment.py b/examples/llvm_rl/model/environment.py index 4bb8c8129..dc4938426 100644 --- a/examples/llvm_rl/model/environment.py +++ b/examples/llvm_rl/model/environment.py @@ -10,7 +10,7 @@ from pydantic.class_validators import root_validator import compiler_gym -from compiler_gym import CompilerEnv +from compiler_gym import ClientServiceCompilerEnv from compiler_gym.wrappers import * # noqa wrapper definitions from compiler_gym.wrappers import TimeLimit @@ -35,13 +35,13 @@ def wrapper_class(self): """Return the wrapper class type.""" return self._to_class(self.wrapper) - def wrap(self, env: CompilerEnv) -> CompilerEnv: + def wrap(self, env: ClientServiceCompilerEnv) -> ClientServiceCompilerEnv: """Wrap the given environment.""" try: return self.wrapper_class(env=env, **self.args) except TypeError as e: raise TypeError( - f"Error constructing CompilerEnv wrapper {self.wrapper_class.__name__}: {e}" + f"Error constructing ClientServiceCompilerEnv wrapper {self.wrapper_class.__name__}: {e}" ) from e # === Start of implementation details. === @@ -67,7 +67,7 @@ class Config: class Environment(BaseModel): - """Represents a CompilerEnv environment.""" + """Represents a ClientServiceCompilerEnv environment.""" id: str = Field(allow_mutation=False) """The environment ID, as passed to :code:`gym.make(...)`.""" @@ -93,7 +93,7 @@ class Environment(BaseModel): # === Start of public API. === - def make_env(self) -> CompilerEnv: + def make_env(self) -> ClientServiceCompilerEnv: """Construct a compiler environment from the given config.""" env = compiler_gym.make(self.id) if self.observation_space: diff --git a/examples/llvm_rl/model/inference_result.py b/examples/llvm_rl/model/inference_result.py index f0bac3ba5..e6da85066 100644 --- a/examples/llvm_rl/model/inference_result.py +++ b/examples/llvm_rl/model/inference_result.py @@ -12,7 +12,7 @@ from ray.rllib.agents.ppo import PPOTrainer # noqa from compiler_gym.datasets import BenchmarkUri -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.util.timer import Timer logger = logging.getLogger(__name__) @@ -44,7 +44,11 @@ class InferenceResult(BaseModel): @classmethod def from_agent( - cls, env: CompilerEnv, agent, runtime: bool = True, runtimes_count: int = 30 + cls, + env: ClientServiceCompilerEnv, + agent, + runtime: bool = True, + runtimes_count: int = 30, ): # We calculate our own reward at the end, no need for incremental # rewards during inference. diff --git a/examples/llvm_rl/model/testing.py b/examples/llvm_rl/model/testing.py index a5353ddb2..e9cfed862 100644 --- a/examples/llvm_rl/model/testing.py +++ b/examples/llvm_rl/model/testing.py @@ -10,7 +10,7 @@ from pydantic import BaseModel, Field, validator from compiler_gym.datasets import Benchmark -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from .benchmarks import Benchmarks @@ -39,13 +39,13 @@ class Testing(BaseModel): # === Start of public API. === - def benchmarks_iterator(self, env: CompilerEnv) -> Iterable[Benchmark]: + def benchmarks_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[Benchmark]: """Return an iterator over the test benchmarks.""" for _ in range(self.runs_per_benchmark): for bm in self.benchmarks: yield from bm.benchmarks_iterator(env) - def benchmark_uris_iterator(self, env: CompilerEnv) -> Iterable[str]: + def benchmark_uris_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[str]: """Return an iterator over the test benchmark URIs.""" for _ in range(self.runs_per_benchmark): for bm in self.benchmarks: @@ -62,7 +62,7 @@ class Config: def get_testing_benchmarks( - env: CompilerEnv, max_benchmarks: int = 50, seed: int = 0 + env: ClientServiceCompilerEnv, max_benchmarks: int = 50, seed: int = 0 ) -> List[str]: rng = np.random.default_rng(seed=seed) for dataset in env.datasets: diff --git a/examples/llvm_rl/model/training.py b/examples/llvm_rl/model/training.py index 6079e1f32..9948b636b 100644 --- a/examples/llvm_rl/model/training.py +++ b/examples/llvm_rl/model/training.py @@ -7,7 +7,7 @@ from pydantic import BaseModel, Field, validator from compiler_gym.datasets import Benchmark -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.wrappers import ( CycleOverBenchmarks, CycleOverBenchmarksIterator, @@ -48,17 +48,17 @@ class Training(BaseModel): # === Start of public API. === - def benchmarks_iterator(self, env: CompilerEnv) -> Iterable[Benchmark]: + def benchmarks_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[Benchmark]: """Return an iterator over the training benchmarks.""" for bm in self.benchmarks: yield from bm.benchmarks_iterator(env) - def benchmark_uris_iterator(self, env: CompilerEnv) -> Iterable[str]: + def benchmark_uris_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[str]: """Return an iterator over the training benchmark URIs.""" for bm in self.benchmarks: yield from bm.benchmark_uris_iterator(env) - def wrap_env(self, env: CompilerEnv) -> CompilerEnv: + def wrap_env(self, env: ClientServiceCompilerEnv) -> ClientServiceCompilerEnv: """Wrap an environment for use in the training loop that is configured to iterate over the training benchmarks on each call to :code:`reset()`. """ diff --git a/examples/llvm_rl/model/validation.py b/examples/llvm_rl/model/validation.py index 72c08103f..97a642445 100644 --- a/examples/llvm_rl/model/validation.py +++ b/examples/llvm_rl/model/validation.py @@ -7,7 +7,7 @@ from pydantic import BaseModel, Field, validator from compiler_gym.datasets import Benchmark -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.wrappers import CycleOverBenchmarks from .benchmarks import Benchmarks @@ -28,17 +28,17 @@ class Validation(BaseModel): # === Start of public API. === - def benchmarks_iterator(self, env: CompilerEnv) -> Iterable[Benchmark]: + def benchmarks_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[Benchmark]: """Return an iterator over the validation benchmarks.""" for bm in self.benchmarks: yield from bm.benchmarks_iterator(env) - def benchmark_uris_iterator(self, env: CompilerEnv) -> Iterable[str]: + def benchmark_uris_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[str]: """Return an iterator over the training benchmark URIs.""" for bm in self.benchmarks: yield from bm.benchmark_uris_iterator(env) - def wrap_env(self, env: CompilerEnv) -> CompilerEnv: + def wrap_env(self, env: ClientServiceCompilerEnv) -> ClientServiceCompilerEnv: """Wrap an environment for use in the training loop that is configured to iterate over the validation benchmarks on each call to :code:`reset()`. diff --git a/examples/llvm_rl/wrappers.py b/examples/llvm_rl/wrappers.py index 4a2a7e6d9..2c0b2325b 100644 --- a/examples/llvm_rl/wrappers.py +++ b/examples/llvm_rl/wrappers.py @@ -8,7 +8,7 @@ import gym import numpy as np -from compiler_gym.envs import CompilerEnv, LlvmEnv +from compiler_gym.envs import ClientServiceCompilerEnv, LlvmEnv from compiler_gym.util.gym_type_hints import ActionType from compiler_gym.wrappers import ( ConstrainedCommandline, @@ -24,7 +24,7 @@ class ClampedReward(RewardWrapper): def __init__( self, - env: CompilerEnv, + env: ClientServiceCompilerEnv, min: float = -1, max: float = 1, leakiness_factor: float = 0.001, @@ -50,7 +50,7 @@ class AutophaseNormalizedFeatures(ObservationWrapper): # The index of the "TotalInsts" feature of autophase. TotalInsts_index = 51 - def __init__(self, env: CompilerEnv): + def __init__(self, env: ClientServiceCompilerEnv): super().__init__(env=env) # Force Autophase observation space. self.env.observation_space = self.env.unwrapped.observation.spaces["Autophase"] @@ -86,7 +86,7 @@ class ConcatActionsHistogram(ObservationWrapper): steps. """ - def __init__(self, env: CompilerEnv, norm_to_episode_len: int = 0): + def __init__(self, env: ClientServiceCompilerEnv, norm_to_episode_len: int = 0): super().__init__(env=env) assert isinstance( self.observation_space, gym.spaces.Box diff --git a/examples/loop_optimizations_service/__init__.py b/examples/loop_optimizations_service/__init__.py index b6866f07b..348284a67 100644 --- a/examples/loop_optimizations_service/__init__.py +++ b/examples/loop_optimizations_service/__init__.py @@ -137,7 +137,7 @@ def benchmark_from_parsed_uri(self, uri: BenchmarkUri) -> Benchmark: register( id="loops-opt-py-v0", - entry_point="compiler_gym.envs:CompilerEnv", + entry_point="compiler_gym.envs:ClientServiceCompilerEnv", kwargs={ "service": LOOPS_OPT_PY_SERVICE_BINARY, "rewards": [RuntimeReward(), SizeReward()], diff --git a/examples/loop_optimizations_service/env_tests.py b/examples/loop_optimizations_service/env_tests.py index 2329caa4a..77d19c3b7 100644 --- a/examples/loop_optimizations_service/env_tests.py +++ b/examples/loop_optimizations_service/env_tests.py @@ -12,7 +12,7 @@ import compiler_gym import examples.loop_optimizations_service as loop_optimizations_service -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.service import SessionNotFound from compiler_gym.spaces import Dict, NamedDiscrete, Scalar, Sequence from compiler_gym.third_party.autophase import AUTOPHASE_FEATURE_NAMES @@ -20,7 +20,7 @@ @pytest.fixture(scope="function") -def env() -> CompilerEnv: +def env() -> ClientServiceCompilerEnv: """Text fixture that yields an environment.""" with gym.make("loops-opt-py-v0") as env_: yield env_ @@ -54,13 +54,13 @@ def run(cmd): assert returncode == 1 -def test_versions(env: CompilerEnv): +def test_versions(env: ClientServiceCompilerEnv): """Tests the GetVersion() RPC endpoint.""" assert env.version == compiler_gym.__version__ assert env.compiler_version == "1.0.0" -def test_action_space(env: CompilerEnv): +def test_action_space(env: ClientServiceCompilerEnv): """Test that the environment reports the service's action spaces.""" assert env.action_spaces == [ NamedDiscrete( @@ -81,7 +81,7 @@ def test_action_space(env: CompilerEnv): ] -def test_observation_spaces(env: CompilerEnv): +def test_observation_spaces(env: ClientServiceCompilerEnv): """Test that the environment reports the service's observation spaces.""" env.reset() assert env.observation.spaces.keys() == { @@ -128,50 +128,50 @@ def test_observation_spaces(env: CompilerEnv): ) -def test_reward_spaces(env: CompilerEnv): +def test_reward_spaces(env: ClientServiceCompilerEnv): """Test that the environment reports the service's reward spaces.""" env.reset() assert env.reward.spaces.keys() == {"runtime", "size"} -def test_step_before_reset(env: CompilerEnv): +def test_step_before_reset(env: ClientServiceCompilerEnv): """Taking a step() before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): env.step(0) -def test_observation_before_reset(env: CompilerEnv): +def test_observation_before_reset(env: ClientServiceCompilerEnv): """Taking an observation before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): _ = env.observation["ir"] -def test_reward_before_reset(env: CompilerEnv): +def test_reward_before_reset(env: ClientServiceCompilerEnv): """Taking a reward before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): _ = env.reward["runtime"] -def test_reset_invalid_benchmark(env: CompilerEnv): +def test_reset_invalid_benchmark(env: ClientServiceCompilerEnv): """Test requesting a specific benchmark.""" with pytest.raises(LookupError) as ctx: env.reset(benchmark="loops-opt-v0/foobar") assert str(ctx.value) == "Unknown program name" -def test_invalid_observation_space(env: CompilerEnv): +def test_invalid_observation_space(env: ClientServiceCompilerEnv): """Test error handling with invalid observation space.""" with pytest.raises(LookupError): env.observation_space = 100 -def test_invalid_reward_space(env: CompilerEnv): +def test_invalid_reward_space(env: ClientServiceCompilerEnv): """Test error handling with invalid reward space.""" with pytest.raises(LookupError): env.reward_space = 100 -def test_double_reset(env: CompilerEnv): +def test_double_reset(env: ClientServiceCompilerEnv): """Test that reset() can be called twice.""" env.reset() assert env.in_episode @@ -179,7 +179,7 @@ def test_double_reset(env: CompilerEnv): assert env.in_episode -def test_Step_out_of_range(env: CompilerEnv): +def test_Step_out_of_range(env: ClientServiceCompilerEnv): """Test error handling with an invalid action.""" env.reset() with pytest.raises(ValueError) as ctx: @@ -187,7 +187,7 @@ def test_Step_out_of_range(env: CompilerEnv): assert str(ctx.value) == "Out-of-range" -def test_default_ir_observation(env: CompilerEnv): +def test_default_ir_observation(env: ClientServiceCompilerEnv): """Test default IR observation space.""" env.observation_space = "ir" observation = env.reset() @@ -199,7 +199,7 @@ def test_default_ir_observation(env: CompilerEnv): assert reward is None -def test_default_inst2vec_observation(env: CompilerEnv): +def test_default_inst2vec_observation(env: ClientServiceCompilerEnv): """Test default inst2vec observation space.""" env.observation_space = "Inst2vec" observation = env.reset() @@ -209,7 +209,7 @@ def test_default_inst2vec_observation(env: CompilerEnv): assert all(obs >= 0 for obs in observation.tolist()) -def test_default_autophase_observation(env: CompilerEnv): +def test_default_autophase_observation(env: ClientServiceCompilerEnv): """Test default autophase observation space.""" env.observation_space = "Autophase" observation = env.reset() @@ -219,7 +219,7 @@ def test_default_autophase_observation(env: CompilerEnv): assert all(obs >= 0 for obs in observation.tolist()) -def test_default_autophase_dict_observation(env: CompilerEnv): +def test_default_autophase_dict_observation(env: ClientServiceCompilerEnv): """Test default autophase dict observation space.""" env.observation_space = "AutophaseDict" observation = env.reset() @@ -229,7 +229,7 @@ def test_default_autophase_dict_observation(env: CompilerEnv): assert all(obs >= 0 for obs in observation.values()) -def test_default_programl_observation(env: CompilerEnv): +def test_default_programl_observation(env: ClientServiceCompilerEnv): """Test default observation space.""" env.observation_space = "Programl" observation = env.reset() @@ -241,7 +241,7 @@ def test_default_programl_observation(env: CompilerEnv): assert reward is None -def test_default_reward(env: CompilerEnv): +def test_default_reward(env: ClientServiceCompilerEnv): """Test default reward space.""" env.reward_space = "runtime" env.reset() @@ -251,7 +251,7 @@ def test_default_reward(env: CompilerEnv): assert reward is not None -def test_observations(env: CompilerEnv): +def test_observations(env: ClientServiceCompilerEnv): """Test observation spaces.""" env.reset() assert len(env.observation["ir"]) > 0 @@ -260,13 +260,13 @@ def test_observations(env: CompilerEnv): assert len(env.observation["Programl"]) > 0 -def test_rewards(env: CompilerEnv): +def test_rewards(env: ClientServiceCompilerEnv): """Test reward spaces.""" env.reset() assert env.reward["runtime"] is not None -def test_benchmarks(env: CompilerEnv): +def test_benchmarks(env: ClientServiceCompilerEnv): assert list(env.datasets.benchmark_uris()) == [ "benchmark://loops-opt-v0/add", "benchmark://loops-opt-v0/offsets1", @@ -274,7 +274,7 @@ def test_benchmarks(env: CompilerEnv): ] -def test_fork(env: CompilerEnv): +def test_fork(env: ClientServiceCompilerEnv): env.reset() env.step(0) env.step(1) diff --git a/examples/loop_optimizations_service/example_without_bazel.py b/examples/loop_optimizations_service/example_without_bazel.py index bcfa04d97..f8e5bcf97 100644 --- a/examples/loop_optimizations_service/example_without_bazel.py +++ b/examples/loop_optimizations_service/example_without_bazel.py @@ -147,7 +147,7 @@ def benchmark_from_parsed_uri(self, uri: BenchmarkUri) -> Benchmark: register( id="loops-opt-py-v0", - entry_point="compiler_gym.envs:CompilerEnv", + entry_point="compiler_gym.envs:ClientServiceCompilerEnv", kwargs={ "service": LOOPS_OPT_PY_SERVICE_BINARY, "rewards": [RuntimeReward(), SizeReward()], diff --git a/examples/op_benchmarks.py b/examples/op_benchmarks.py index 1d63d04d8..27e363ac1 100644 --- a/examples/op_benchmarks.py +++ b/examples/op_benchmarks.py @@ -29,7 +29,7 @@ import compiler_gym from compiler_gym.datasets import BenchmarkInitError -from compiler_gym.envs.compiler_env import CompilerEnv +from compiler_gym.envs.client_service_compiler_env import CompilerEnv from compiler_gym.util.executor import Executor from compiler_gym.util.logging import init_logging from compiler_gym.util.runfiles_path import create_user_logs_dir diff --git a/leaderboard/llvm_instcount/e_greedy/e_greedy.py b/leaderboard/llvm_instcount/e_greedy/e_greedy.py index a61f015e8..e18cd3138 100644 --- a/leaderboard/llvm_instcount/e_greedy/e_greedy.py +++ b/leaderboard/llvm_instcount/e_greedy/e_greedy.py @@ -10,7 +10,7 @@ from absl import flags -from compiler_gym.envs import CompilerEnv, LlvmEnv +from compiler_gym.envs import ClientServiceCompilerEnv, LlvmEnv from compiler_gym.leaderboard.llvm_instcount import eval_llvm_instcount_policy flags.DEFINE_float( @@ -27,10 +27,12 @@ class RewardAction(NamedTuple): action: int -def select_best_action(env: CompilerEnv, executor: ThreadPoolExecutor) -> RewardAction: +def select_best_action( + env: ClientServiceCompilerEnv, executor: ThreadPoolExecutor +) -> RewardAction: """Determine the best action by trying all possible options and ranking them.""" - def eval_action(fkd: CompilerEnv, action: int) -> RewardAction: + def eval_action(fkd: ClientServiceCompilerEnv, action: int) -> RewardAction: """Evaluate the given action.""" try: _, reward, _, _ = fkd.step(action) diff --git a/leaderboard/llvm_instcount/random_search/README.md b/leaderboard/llvm_instcount/random_search/README.md index 101cf514b..679bb64eb 100644 --- a/leaderboard/llvm_instcount/random_search/README.md +++ b/leaderboard/llvm_instcount/random_search/README.md @@ -56,7 +56,7 @@ elapsed. Pseudo-code for this search is: ```c++ -float search_with_patience(CompilerEnv env, int patience, int search_time) { +float search_with_patience(ClientServiceCompilerEnv env, int patience, int search_time) { float best_reward = -INFINITY; int end_time = time() + search_time; while (time() < end_time) { diff --git a/tests/compiler_env_test.py b/tests/compiler_env_test.py index 15845961c..1a7636c37 100644 --- a/tests/compiler_env_test.py +++ b/tests/compiler_env_test.py @@ -36,7 +36,7 @@ def test_benchmark_set_in_reset(env: LlvmEnv): def test_logger_is_deprecated(env: LlvmEnv): with pytest.deprecated_call( - match="The `CompilerEnv.logger` attribute is deprecated" + match="The `ClientServiceCompilerEnv.logger` attribute is deprecated" ): env.logger diff --git a/tests/env_copy_test.py b/tests/env_copy_test.py index 25b6ed0cc..1ba3c05f2 100644 --- a/tests/env_copy_test.py +++ b/tests/env_copy_test.py @@ -2,7 +2,7 @@ # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -"""Tests for the copy() and deepcopy() operators on CompilerEnv.""" +"""Tests for the copy() and deepcopy() operators on ClientServiceCompilerEnv.""" from copy import copy, deepcopy import pytest @@ -17,7 +17,7 @@ def test_forbidden_shallow_copy(env: LlvmEnv): """Test that shallow copy operator is explicitly forbidden.""" with pytest.raises( TypeError, - match=r"^CompilerEnv instances do not support shallow copies. Use deepcopy\(\)", + match=r"^ClientServiceCompilerEnv instances do not support shallow copies. Use deepcopy\(\)", ): copy(env) diff --git a/tests/llvm/all_actions_single_step_test.py b/tests/llvm/all_actions_single_step_test.py index 33bfe3ca5..662036d83 100644 --- a/tests/llvm/all_actions_single_step_test.py +++ b/tests/llvm/all_actions_single_step_test.py @@ -6,7 +6,7 @@ import numpy as np -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.service.connection import ServiceError from compiler_gym.third_party.autophase import AUTOPHASE_FEATURE_DIM from tests.test_main import main @@ -14,7 +14,7 @@ pytest_plugins = ["tests.pytest_plugins.llvm"] -def test_step(env: CompilerEnv, action_name: str): +def test_step(env: ClientServiceCompilerEnv, action_name: str): """Run each action on a single benchmark.""" env.reward_space = "IrInstructionCount" env.observation_space = "Autophase" diff --git a/tests/llvm/autophase_test.py b/tests/llvm/autophase_test.py index a466a2957..b557f47f8 100644 --- a/tests/llvm/autophase_test.py +++ b/tests/llvm/autophase_test.py @@ -3,13 +3,13 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. """Integrations tests for the LLVM CompilerGym environments.""" -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from tests.test_main import main pytest_plugins = ["tests.pytest_plugins.llvm"] -def test_autophase_crc32_feature_vector(env: CompilerEnv): +def test_autophase_crc32_feature_vector(env: ClientServiceCompilerEnv): env.reset(benchmark="cbench-v1/crc32") print(env.benchmark) # For debugging in case of error. features = env.observation["AutophaseDict"] diff --git a/tests/llvm/fresh_environment_observation_reward_test.py b/tests/llvm/fresh_environment_observation_reward_test.py index e9c140000..cdf265238 100644 --- a/tests/llvm/fresh_environment_observation_reward_test.py +++ b/tests/llvm/fresh_environment_observation_reward_test.py @@ -8,7 +8,7 @@ import pytest from flaky import flaky -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from tests.test_main import main pytest_plugins = ["tests.pytest_plugins.llvm"] @@ -19,7 +19,7 @@ reason="github.com/facebookresearch/CompilerGym/issues/459", ) @flaky # Runtime can timeout -def test_step(env: CompilerEnv, observation_space: str, reward_space: str): +def test_step(env: ClientServiceCompilerEnv, observation_space: str, reward_space: str): """Request every combination of observation and reward in a fresh environment.""" env.reward_space = None env.observation_space = None diff --git a/tests/llvm/llvm_benchmark_test.py b/tests/llvm/llvm_benchmark_test.py index 337ab13c5..d569ba381 100644 --- a/tests/llvm/llvm_benchmark_test.py +++ b/tests/llvm/llvm_benchmark_test.py @@ -9,7 +9,7 @@ import pytest from compiler_gym.datasets import Benchmark -from compiler_gym.envs import CompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.envs.llvm import llvm_benchmark from compiler_gym.service.proto import Benchmark as BenchmarkProto from compiler_gym.service.proto import File @@ -19,7 +19,7 @@ pytest_plugins = ["tests.pytest_plugins.llvm"] -def test_add_benchmark_invalid_scheme(env: CompilerEnv): +def test_add_benchmark_invalid_scheme(env: ClientServiceCompilerEnv): with pytest.raises(ValueError) as ctx: env.reset( benchmark=Benchmark( @@ -34,7 +34,7 @@ def test_add_benchmark_invalid_scheme(env: CompilerEnv): ) -def test_add_benchmark_invalid_path(env: CompilerEnv): +def test_add_benchmark_invalid_path(env: ClientServiceCompilerEnv): with tempfile.TemporaryDirectory() as d: tmp = Path(d) / "not_a_file" with pytest.raises(FileNotFoundError) as ctx: diff --git a/tests/llvm/llvm_env_test.py b/tests/llvm/llvm_env_test.py index 36fe74bba..34322ffd9 100644 --- a/tests/llvm/llvm_env_test.py +++ b/tests/llvm/llvm_env_test.py @@ -17,7 +17,7 @@ CompilerEnvStateReader, CompilerEnvStateWriter, ) -from compiler_gym.envs import CompilerEnv, llvm +from compiler_gym.envs import ClientServiceCompilerEnv, llvm from compiler_gym.envs.llvm.llvm_env import LlvmEnv from compiler_gym.service import ServiceError from compiler_gym.service.connection import CompilerGymServiceConnection @@ -28,7 +28,7 @@ @pytest.fixture(scope="function", params=["local", "service"]) -def env(request) -> CompilerEnv: +def env(request) -> ClientServiceCompilerEnv: """Create an LLVM environment.""" if request.param == "local": with gym.make("llvm-v0") as env: diff --git a/tests/llvm/observation_spaces_test.py b/tests/llvm/observation_spaces_test.py index 865623787..c0a4692ec 100644 --- a/tests/llvm/observation_spaces_test.py +++ b/tests/llvm/observation_spaces_test.py @@ -1422,7 +1422,7 @@ def test_is_buildable_observation_space_not_buildable(env: LlvmEnv): def test_add_derived_space(env: LlvmEnv): env.reset() with pytest.deprecated_call( - match="Use the derived_observation_spaces argument to CompilerEnv constructor." + match="Use the derived_observation_spaces argument to ClientServiceCompilerEnv constructor." ): env.observation.add_derived_space( id="IrLen", diff --git a/tests/llvm/service_connection_test.py b/tests/llvm/service_connection_test.py index 54b7d2d8d..1206c1016 100644 --- a/tests/llvm/service_connection_test.py +++ b/tests/llvm/service_connection_test.py @@ -8,7 +8,7 @@ import pytest import compiler_gym # noqa Register environments. -from compiler_gym.envs import CompilerEnv, llvm +from compiler_gym.envs import ClientServiceCompilerEnv, llvm from compiler_gym.envs.llvm.llvm_env import LlvmEnv from compiler_gym.service import ServiceError from compiler_gym.service.connection import CompilerGymServiceConnection @@ -19,7 +19,7 @@ @pytest.fixture(scope="function", params=["local", "service"]) -def env(request) -> CompilerEnv: +def env(request) -> ClientServiceCompilerEnv: # Redefine fixture to test both gym.make(...) and unmanaged service # connections. if request.param == "local": @@ -34,7 +34,7 @@ def env(request) -> CompilerEnv: service.close() -def test_service_env_dies_reset(env: CompilerEnv): +def test_service_env_dies_reset(env: ClientServiceCompilerEnv): env.observation_space = "Autophase" env.reward_space = "IrInstructionCount" env.reset("cbench-v1/crc32") diff --git a/tests/llvm/threading_test.py b/tests/llvm/threading_test.py index a347ffc6d..e7df23315 100644 --- a/tests/llvm/threading_test.py +++ b/tests/llvm/threading_test.py @@ -9,7 +9,7 @@ import gym from flaky import flaky -from compiler_gym import CompilerEnv +from compiler_gym import ClientServiceCompilerEnv from compiler_gym.util.gym_type_hints import ActionType from tests.test_main import main @@ -39,7 +39,7 @@ def run(self) -> None: class ThreadedWorkerWithEnv(Thread): """Create an environment and run through a set of actions in a background thread.""" - def __init__(self, env: CompilerEnv, actions: List[ActionType]): + def __init__(self, env: ClientServiceCompilerEnv, actions: List[ActionType]): super().__init__() self.done = False self.env = env From 4a79017f291bd3f053f18ba7f2918ff214c18d52 Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Tue, 22 Mar 2022 11:59:54 -0700 Subject: [PATCH 03/16] Rename Env to CompilerEnv --- compiler_gym/envs/BUILD | 6 +++--- compiler_gym/envs/CMakeLists.txt | 2 +- compiler_gym/envs/__init__.py | 4 ++-- compiler_gym/envs/client_service_compiler_env.py | 4 ++-- compiler_gym/envs/{env.py => compiler_env.py} | 6 +++--- compiler_gym/wrappers/core.py | 10 +++++----- 6 files changed, 16 insertions(+), 16 deletions(-) rename compiler_gym/envs/{env.py => compiler_env.py} (97%) diff --git a/compiler_gym/envs/BUILD b/compiler_gym/envs/BUILD index 45b4d3719..0c85f0910 100644 --- a/compiler_gym/envs/BUILD +++ b/compiler_gym/envs/BUILD @@ -21,7 +21,7 @@ py_library( srcs = ["client_service_compiler_env.py"], visibility = ["//compiler_gym:__subpackages__"], deps = [ - ":env", + ":compiler_env", "//compiler_gym:compiler_env_state", "//compiler_gym:validation_result", "//compiler_gym/datasets", @@ -34,8 +34,8 @@ py_library( ) py_library( - name = "env", - srcs = ["env.py"], + name = "compiler_env", + srcs = ["compiler_env.py"], visibility = ["//compiler_gym:__subpackages__"], deps = [ "//compiler_gym/spaces", diff --git a/compiler_gym/envs/CMakeLists.txt b/compiler_gym/envs/CMakeLists.txt index 4992b365a..591054737 100644 --- a/compiler_gym/envs/CMakeLists.txt +++ b/compiler_gym/envs/CMakeLists.txt @@ -40,7 +40,7 @@ cg_py_library( NAME env_py SRCS - "env.py" + "compiler_env.py" DEPS compiler_gym::spaces::spaces compiler_gym::util::util diff --git a/compiler_gym/envs/__init__.py b/compiler_gym/envs/__init__.py index 8cca3f2d0..292433647 100644 --- a/compiler_gym/envs/__init__.py +++ b/compiler_gym/envs/__init__.py @@ -3,7 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. from compiler_gym.envs.client_service_compiler_env import ClientServiceCompilerEnv -from compiler_gym.envs.env import Env +from compiler_gym.envs.compiler_env import CompilerEnv from compiler_gym.envs.gcc import GccEnv from compiler_gym.envs.llvm.llvm_env import LlvmEnv from compiler_gym.envs.loop_tool.loop_tool_env import LoopToolEnv @@ -12,7 +12,7 @@ __all__ = [ "COMPILER_GYM_ENVS", "ClientServiceCompilerEnv", - "Env", + "CompilerEnv", "GccEnv", "LlvmEnv", "LoopToolEnv", diff --git a/compiler_gym/envs/client_service_compiler_env.py b/compiler_gym/envs/client_service_compiler_env.py index e3b9492e0..655ccd559 100644 --- a/compiler_gym/envs/client_service_compiler_env.py +++ b/compiler_gym/envs/client_service_compiler_env.py @@ -20,7 +20,7 @@ from compiler_gym.compiler_env_state import CompilerEnvState from compiler_gym.datasets import Benchmark, Dataset, Datasets from compiler_gym.datasets.uri import BenchmarkUri -from compiler_gym.envs.env import Env +from compiler_gym.envs.compiler_env import CompilerEnv from compiler_gym.service import ( CompilerGymServiceConnection, ConnectionOpts, @@ -81,7 +81,7 @@ def _wrapped_step( raise -class ClientServiceCompilerEnv(Env): +class ClientServiceCompilerEnv(CompilerEnv): """An OpenAI gym environment for compiler optimizations. The easiest way to create a CompilerGym environment is to call diff --git a/compiler_gym/envs/env.py b/compiler_gym/envs/compiler_env.py similarity index 97% rename from compiler_gym/envs/env.py rename to compiler_gym/envs/compiler_env.py index d287163e2..e78513cde 100644 --- a/compiler_gym/envs/env.py +++ b/compiler_gym/envs/compiler_env.py @@ -13,7 +13,7 @@ from compiler_gym.views import ObservationSpaceSpec -class Env(gym.Env, ABC): +class CompilerEnv(gym.Env, ABC): @property @abstractmethod def observation_space_spec(self) -> ObservationSpaceSpec: @@ -27,7 +27,7 @@ def observation_space_spec( raise NotImplementedError("abstract method") @abstractmethod - def fork(self) -> "Env": + def fork(self) -> "CompilerEnv": """Fork a new environment with exactly the same state. This creates a duplicate environment instance with the current state. @@ -36,7 +36,7 @@ def fork(self) -> "Env": on the original and new environments. If not already in an episode, :meth:`reset() - ` is called. + ` is called. Example usage: diff --git a/compiler_gym/wrappers/core.py b/compiler_gym/wrappers/core.py index 405f04c7b..4134b71ad 100644 --- a/compiler_gym/wrappers/core.py +++ b/compiler_gym/wrappers/core.py @@ -9,14 +9,14 @@ from gym import Wrapper from gym.spaces import Space -from compiler_gym.envs import Env +from compiler_gym.envs import CompilerEnv from compiler_gym.spaces.reward import Reward from compiler_gym.util.gym_type_hints import ActionType, ObservationType from compiler_gym.views import ObservationSpaceSpec -class CompilerEnvWrapper(Env, Wrapper): - """Wraps a :class:`CompilerEnv ` environment +class CompilerEnvWrapper(CompilerEnv, Wrapper): + """Wraps a :class:`CompilerEnv ` environment to allow a modular transformation. This class is the base class for all wrappers. This class must be used @@ -24,7 +24,7 @@ class CompilerEnvWrapper(Env, Wrapper): such as the :code:`fork()` method. """ - def __init__(self, env: Env): # pylint: disable=super-init-not-called + def __init__(self, env: CompilerEnv): # pylint: disable=super-init-not-called """Constructor. :param env: The environment to wrap. @@ -41,7 +41,7 @@ def __init__(self, env: Env): # pylint: disable=super-init-not-called def reset(self, *args, **kwargs) -> Optional[ObservationType]: return self.env.reset(*args, **kwargs) - def fork(self) -> Env: + def fork(self) -> CompilerEnv: return type(self)(env=self.env.fork()) def step( # pylint: disable=arguments-differ From 1e6595ea335f95284a1112b48d2b4a0fbc457ffc Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Wed, 23 Mar 2022 12:53:55 -0700 Subject: [PATCH 04/16] Extend CompilerEnv interface --- .../envs/client_service_compiler_env.py | 131 +++++------- compiler_gym/envs/compiler_env.py | 191 +++++++++++++++++- compiler_gym/wrappers/core.py | 65 +++++- 3 files changed, 297 insertions(+), 90 deletions(-) diff --git a/compiler_gym/envs/client_service_compiler_env.py b/compiler_gym/envs/client_service_compiler_env.py index 655ccd559..5020b55fc 100644 --- a/compiler_gym/envs/client_service_compiler_env.py +++ b/compiler_gym/envs/client_service_compiler_env.py @@ -247,7 +247,7 @@ def __init__( endpoint=self._service_endpoint, opts=self._connection_settings, ) - self.datasets = Datasets(datasets or []) + self._datasets = Datasets(datasets or []) self.action_space_name = action_space @@ -319,13 +319,13 @@ def __init__( # Mutable state initialized in reset(). self.reward_range: Tuple[float, float] = (-np.inf, np.inf) - self.episode_reward: Optional[float] = None + self.episode_reward = None self.episode_start_time: float = time() - self.actions: List[ActionType] = [] + self._actions: List[ActionType] = [] # Initialize the default observation/reward spaces. self.observation_space_spec = None - self.reward_space_spec: Optional[Reward] = None + self.reward_space_spec = None self.observation_space = observation_space self.reward_space = reward_space @@ -339,6 +339,42 @@ def observation_space_spec( ): self._observation_space_spec = observation_space_spec + @property + def reward_space_spec(self) -> Optional[Reward]: + return self._reward_space_spec + + @reward_space_spec.setter + def reward_space_spec(self, val: Optional[Reward]): + self._reward_space_spec = val + + @property + def benchmark(self) -> Benchmark: + return self._benchmark + + @benchmark.setter + def benchmark(self, benchmark: Optional[Union[str, Benchmark, BenchmarkUri]]): + self._benchmark = benchmark + + @property + def datasets(self) -> Iterable[Dataset]: + return self._datasets + + @datasets.setter + def datasets(self, datasets: Iterable[Dataset]): + self._datastes = datasets + + @property + def episode_reward(self) -> Optional[float]: + return self._episode_reward + + @episode_reward.setter + def episode_reward(self, episode_reward: Optional[float]): + self._episode_reward = episode_reward + + @property + def actions(self) -> List[ActionType]: + return self._actions + @property @deprecated( version="0.2.1", @@ -370,47 +406,25 @@ def compiler_version(self) -> str: return self.versions.compiler_version def commandline(self) -> str: - """Interface for :class:`ClientServiceCompilerEnv ` - subclasses to provide an equivalent commandline invocation to the - current environment state. - - See also :meth:`commandline_to_actions() - `. - - Calling this method on a :class:`ClientServiceCompilerEnv + """Calling this method on a :class:`ClientServiceCompilerEnv ` instance raises :code:`NotImplementedError`. - - :return: A string commandline invocation. """ raise NotImplementedError("abstract method") def commandline_to_actions(self, commandline: str) -> List[ActionType]: - """Interface for :class:`ClientServiceCompilerEnv ` - subclasses to convert from a commandline invocation to a sequence of - actions. - - See also :meth:`commandline() - `. - - Calling this method on a :class:`ClientServiceCompilerEnv + """Calling this method on a :class:`ClientServiceCompilerEnv ` instance raises :code:`NotImplementedError`. - - :return: A list of actions. """ raise NotImplementedError("abstract method") @property def episode_walltime(self) -> float: - """Return the amount of time in seconds since the last call to - :meth:`reset() `. - """ return time() - self.episode_start_time @property def state(self) -> CompilerEnvState: - """The tuple representation of the current environment state.""" return CompilerEnvState( benchmark=str(self.benchmark) if self.benchmark else None, reward=self.episode_reward, @@ -420,13 +434,6 @@ def state(self) -> CompilerEnvState: @property def action_space(self) -> Space: - """The current action space. - - :getter: Get the current action space. - :setter: Set the action space to use. Must be an entry in - :code:`action_spaces`. If :code:`None`, the default action space is - selected. - """ return self._action_space @action_space.setter @@ -441,21 +448,6 @@ def action_space(self, action_space: Optional[str]): @property def benchmark(self) -> Benchmark: - """Get or set the benchmark to use. - - :getter: Get :class:`Benchmark ` that - is currently in use. - - :setter: Set the benchmark to use. Either a :class:`Benchmark - ` instance, or the URI of a - benchmark as in :meth:`env.datasets.benchmark_uris() - `. - - .. note:: - - Setting a new benchmark has no effect until - :func:`env.reset() ` is called. - """ return self._benchmark_in_use @benchmark.setter @@ -482,13 +474,6 @@ def benchmark(self, benchmark: Union[str, Benchmark, BenchmarkUri]): @property def reward_space(self) -> Optional[Reward]: - """The default reward space that is used to return a reward value from - :func:`~step()`. - - :getter: Returns a :class:`Reward `, - or :code:`None` if not set. - :setter: Set the default reward space. - """ return self.reward_space_spec @reward_space.setter @@ -520,22 +505,10 @@ def reward_space(self, reward_space: Optional[Union[str, Reward]]) -> None: @property def in_episode(self) -> bool: - """Whether the service is ready for :func:`step` to be called, - i.e. :func:`reset` has been called and :func:`close` has not. - - :return: :code:`True` if in an episode, else :code:`False`. - """ return self._session_id is not None @property def observation_space(self) -> Optional[Space]: - """The observation space that is used to return an observation value in - :func:`~step()`. - - :getter: Returns the underlying observation space, or :code:`None` if - not set. - :setter: Set the default observation space. - """ if self.observation_space_spec: return self.observation_space_spec.space @@ -625,7 +598,7 @@ def fork(self) -> "ClientServiceCompilerEnv": # Copy over the mutable episode state. new_env.episode_reward = self.episode_reward new_env.episode_start_time = self.episode_start_time - new_env.actions = self.actions.copy() + new_env._actions = self.actions.copy() return new_env @@ -851,7 +824,7 @@ def _call_with_error( self.observation.session_id = reply.session_id self.reward.get_cost = self.observation.__getitem__ self.episode_start_time = time() - self.actions = [] + self._actions = [] # If the action space has changed, update it. if reply.HasField("new_action_space"): @@ -919,7 +892,7 @@ def raw_step( } # Record the actions. - self.actions += actions + self._actions += actions # Send the request to the backend service. request = StepRequest( @@ -1168,13 +1141,6 @@ def _reward_view_type(self): return RewardView def apply(self, state: CompilerEnvState) -> None: # noqa - """Replay this state on the given an environment. - - :param env: A :class:`ClientServiceCompilerEnv ` - instance. - - :raises ValueError: If this state cannot be applied. - """ if not self.in_episode: self.reset(benchmark=state.benchmark) @@ -1203,13 +1169,6 @@ def apply(self, state: CompilerEnvState) -> None: # noqa ) def validate(self, state: Optional[CompilerEnvState] = None) -> ValidationResult: - """Validate an environment's state. - - :param state: A state to environment. If not provided, the current state - is validated. - - :returns: A :class:`ValidationResult `. - """ if state: self.reset(benchmark=state.benchmark) in_place = False diff --git a/compiler_gym/envs/compiler_env.py b/compiler_gym/envs/compiler_env.py index e78513cde..28e4e8732 100644 --- a/compiler_gym/envs/compiler_env.py +++ b/compiler_gym/envs/compiler_env.py @@ -4,12 +4,16 @@ # LICENSE file in the root directory of this source tree. """This module defines the OpenAI gym interface for compilers.""" from abc import ABC, abstractmethod -from typing import Iterable, Optional, Union +from typing import Iterable, List, Optional, Union import gym +from gym.spaces import Space +from compiler_gym.compiler_env_state import CompilerEnvState +from compiler_gym.datasets import Benchmark, BenchmarkUri, Dataset from compiler_gym.spaces import Reward from compiler_gym.util.gym_type_hints import ActionType, ObservationType, StepType +from compiler_gym.validation_result import ValidationResult from compiler_gym.views import ObservationSpaceSpec @@ -26,6 +30,143 @@ def observation_space_spec( ): raise NotImplementedError("abstract method") + @property + @abstractmethod + def reward_space_spec(self) -> Optional[Reward]: + raise NotImplementedError("abstract method") + + @reward_space_spec.setter + @abstractmethod + def reward_space_spec(self, val: Optional[Reward]): + raise NotImplementedError("abstract method") + + @property + @abstractmethod + def benchmark(self) -> Benchmark: + """Get or set the benchmark to use. + + :getter: Get :class:`Benchmark ` that + is currently in use. + + :setter: Set the benchmark to use. Either a :class:`Benchmark + ` instance, or the URI of a + benchmark as in :meth:`env.datasets.benchmark_uris() + `. + + .. note:: + + Setting a new benchmark has no effect until + :func:`env.reset() ` is called. + """ + raise NotImplementedError("abstract method") + + @benchmark.setter + @abstractmethod + def benchmark(self, benchmark: Optional[Union[str, Benchmark, BenchmarkUri]]): + raise NotImplementedError("abstract method") + + @property + @abstractmethod + def datasets(self) -> Iterable[Dataset]: + raise NotImplementedError("abstract method") + + @datasets.setter + @abstractmethod + def datasets(self, datasets: Iterable[Dataset]): + raise NotImplementedError("abstract method") + + @property + @abstractmethod + def episode_walltime(self) -> float: + """Return the amount of time in seconds since the last call to + :meth:`reset() `. + """ + raise NotImplementedError("abstract method") + + @property + @abstractmethod + def in_episode(self) -> bool: + """Whether the service is ready for :func:`step` to be called, + i.e. :func:`reset` has been called and :func:`close` has not. + + :return: :code:`True` if in an episode, else :code:`False`. + """ + raise NotImplementedError("abstract method") + + @property + @abstractmethod + def episode_reward(self) -> Optional[float]: + raise NotImplementedError("abstract method") + + @episode_reward.setter + @abstractmethod + def episode_reward(self, episode_reward: Optional[float]): + raise NotImplementedError("abstract method") + + @property + @abstractmethod + def actions(self) -> List[ActionType]: + raise NotImplementedError("abstract method") + + @property + @abstractmethod + def state(self) -> CompilerEnvState: + """The tuple representation of the current environment state.""" + raise NotImplementedError("abstract method") + + @property + @abstractmethod + def action_space(self) -> Space: + """The current action space. + + :getter: Get the current action space. + :setter: Set the action space to use. Must be an entry in + :code:`action_spaces`. If :code:`None`, the default action space is + selected. + """ + raise NotImplementedError("abstract method") + + @action_space.setter + @abstractmethod + def action_space(self, action_space: Optional[str]): + raise NotImplementedError("abstract method") + + @property + @abstractmethod + def reward_space(self) -> Optional[Reward]: + """The default reward space that is used to return a reward value from + :func:`~step()`. + + :getter: Returns a :class:`Reward `, + or :code:`None` if not set. + :setter: Set the default reward space. + """ + raise NotImplementedError("abstract method") + + @reward_space.setter + @abstractmethod + def reward_space(self, reward_space: Optional[Union[str, Reward]]) -> None: + raise NotImplementedError("abstract method") + + @property + @abstractmethod + def observation_space(self) -> Optional[Space]: + """The observation space that is used to return an observation value in + :func:`~step()`. + + :getter: Returns the underlying observation space, or :code:`None` if + not set. + :setter: Set the default observation space. + """ + raise NotImplementedError("abstract method") + + @observation_space.setter + @abstractmethod + def observation_space( + self, observation_space: Optional[Union[str, ObservationSpaceSpec]] + ) -> None: + raise NotImplementedError("abstract method") + @abstractmethod def fork(self) -> "CompilerEnv": """Fork a new environment with exactly the same state. @@ -119,3 +260,51 @@ def multistep( reward are None if default observation/reward is not set. """ raise NotImplementedError("abstract method") + + @abstractmethod + def commandline(self) -> str: + """Interface for :class:`ClientServiceCompilerEnv ` + subclasses to provide an equivalent commandline invocation to the + current environment state. + + See also :meth:`commandline_to_actions() + `. + + :return: A string commandline invocation. + """ + raise NotImplementedError("abstract method") + + @abstractmethod + def commandline_to_actions(self, commandline: str) -> List[ActionType]: + """Interface for :class:`ClientServiceCompilerEnv ` + subclasses to convert from a commandline invocation to a sequence of + actions. + + See also :meth:`commandline() + `. + + :return: A list of actions. + """ + raise NotImplementedError("abstract method") + + @abstractmethod + def apply(self, state: CompilerEnvState) -> None: # noqa + """Replay this state on the given environment. + + :param state: A :class:`CompilerEnvState ` + instance. + + :raises ValueError: If this state cannot be applied. + """ + raise NotImplementedError("abstract method") + + @abstractmethod + def validate(self, state: Optional[CompilerEnvState] = None) -> ValidationResult: + """Validate an environment's state. + + :param state: A state to environment. If not provided, the current state + is validated. + + :returns: A :class:`ValidationResult `. + """ + raise NotImplementedError("abstract method") diff --git a/compiler_gym/wrappers/core.py b/compiler_gym/wrappers/core.py index 4134b71ad..74550f967 100644 --- a/compiler_gym/wrappers/core.py +++ b/compiler_gym/wrappers/core.py @@ -9,9 +9,12 @@ from gym import Wrapper from gym.spaces import Space +from compiler_gym.compiler_env_state import CompilerEnvState +from compiler_gym.datasets import Benchmark, BenchmarkUri, Dataset from compiler_gym.envs import CompilerEnv from compiler_gym.spaces.reward import Reward from compiler_gym.util.gym_type_hints import ActionType, ObservationType +from compiler_gym.validation_result import ValidationResult from compiler_gym.views import ObservationSpaceSpec @@ -141,6 +144,14 @@ def observation_space_spec( ) -> None: self.env.observation_space_spec = observation_space_spec + @property + def reward_space_spec(self) -> Optional[Reward]: + return self.env.reward_space_spec + + @reward_space_spec.setter + def reward_space_spec(self, val: Optional[Reward]): + self.env.reward_space_spec = val + @property def reward_space(self) -> Optional[Reward]: return self.env.reward_space @@ -161,9 +172,57 @@ def action_space(self, action_space: Optional[str]): def spec(self) -> Any: return self.env.spec - @spec.setter - def spec(self, value: Any): - self.env.spec = value + @property + def benchmark(self) -> Benchmark: + return self.env.benchmark + + @benchmark.setter + def benchmark(self, benchmark: Optional[Union[str, Benchmark, BenchmarkUri]]): + self.env.benchmark = benchmark + + @property + def datasets(self) -> Iterable[Dataset]: + return self.env.datasets + + @datasets.setter + def datasets(self, datasets: Iterable[Dataset]): + self.env.datasets = datasets + + @property + def episode_walltime(self) -> float: + return self.env.episode_walltime + + @property + def in_episode(self) -> bool: + return self.env.in_episode + + @property + def episode_reward(self) -> Optional[float]: + return self.env.episode_reward + + @episode_reward.setter + def episode_reward(self, episode_reward: Optional[float]): + self.env.episode_reward = episode_reward + + @property + def actions(self) -> List[ActionType]: + return self.env.actions + + @property + def state(self) -> CompilerEnvState: + return self.env.state + + def commandline(self) -> str: + return self.env.commandline() + + def commandline_to_actions(self, commandline: str) -> List[ActionType]: + return self.env.commandline_to_actions(commandline) + + def apply(self, state: CompilerEnvState) -> None: # noqa + self.env.apply(state) + + def validate(self, state: Optional[CompilerEnvState] = None) -> ValidationResult: + return self.env.validate(state) class ActionWrapper(CompilerEnvWrapper): From d667d7f893a4726cb22cef8750e4511d814ae748 Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Wed, 23 Mar 2022 14:29:59 -0700 Subject: [PATCH 05/16] Rename back some occurrences of ClientServiceCompilerEnv to CompilerEnv --- benchmarks/bench_test.py | 10 ++-- compiler_gym/__init__.py | 6 +-- compiler_gym/bin/manual_env.py | 4 +- compiler_gym/datasets/benchmark.py | 28 +++++------ compiler_gym/envs/compiler_env.py | 6 +-- compiler_gym/envs/gcc/datasets/csmith.py | 2 +- compiler_gym/envs/llvm/datasets/csmith.py | 2 +- .../envs/llvm/datasets/llvm_stress.py | 2 +- compiler_gym/leaderboard/llvm_instcount.py | 2 +- compiler_gym/random_replay.py | 10 ++-- compiler_gym/random_search.py | 24 ++++------ compiler_gym/service/connection.py | 4 +- compiler_gym/util/flags/env_from_flags.py | 8 ++-- compiler_gym/validate.py | 8 ++-- compiler_gym/validation_error.py | 2 +- compiler_gym/views/observation_space_spec.py | 4 +- .../example_compiler_gym_service/env_tests.py | 44 +++++++++--------- .../example_unrolling_service/env_tests.py | 42 ++++++++--------- examples/gcc_autotuning/tune.py | 8 ++-- .../llvm_autotuning/autotuners/__init__.py | 10 ++-- .../llvm_autotuning/autotuners/nevergrad_.py | 4 +- .../llvm_autotuning/autotuners/random_.py | 4 +- examples/llvm_rl/model/benchmarks.py | 12 ++--- examples/llvm_rl/model/environment.py | 10 ++-- examples/llvm_rl/model/testing.py | 8 ++-- examples/llvm_rl/model/training.py | 8 ++-- examples/llvm_rl/model/validation.py | 8 ++-- examples/llvm_rl/wrappers.py | 8 ++-- .../loop_optimizations_service/env_tests.py | 46 +++++++++---------- .../llvm_instcount/e_greedy/e_greedy.py | 8 ++-- tests/llvm/all_actions_single_step_test.py | 4 +- tests/llvm/autophase_test.py | 4 +- ...esh_environment_observation_reward_test.py | 4 +- tests/llvm/llvm_benchmark_test.py | 6 +-- tests/llvm/llvm_env_test.py | 4 +- tests/llvm/observation_spaces_test.py | 2 +- tests/llvm/threading_test.py | 4 +- 37 files changed, 175 insertions(+), 195 deletions(-) diff --git a/benchmarks/bench_test.py b/benchmarks/bench_test.py index 3819a00c8..3947b0071 100644 --- a/benchmarks/bench_test.py +++ b/benchmarks/bench_test.py @@ -21,7 +21,7 @@ import pytest import examples.example_compiler_gym_service as dummy -from compiler_gym.envs import ClientServiceCompilerEnv, LlvmEnv, llvm +from compiler_gym.envs import CompilerEnv, LlvmEnv, llvm from compiler_gym.service import CompilerGymServiceConnection from tests.pytest_plugins.llvm import OBSERVATION_SPACE_NAMES, REWARD_SPACE_NAMES from tests.test_main import main @@ -39,7 +39,7 @@ def env_id(request) -> str: params=["llvm-v0", "example-cc-v0", "example-py-v0"], ids=["llvm", "dummy-cc", "dummy-py"], ) -def env(request) -> ClientServiceCompilerEnv: +def env(request) -> CompilerEnv: yield request.param @@ -56,8 +56,8 @@ def test_make_local(benchmark, env_id): "args", [ (llvm.LLVM_SERVICE_BINARY, LlvmEnv), - (dummy.EXAMPLE_CC_SERVICE_BINARY, ClientServiceCompilerEnv), - (dummy.EXAMPLE_PY_SERVICE_BINARY, ClientServiceCompilerEnv), + (dummy.EXAMPLE_CC_SERVICE_BINARY, CompilerEnv), + (dummy.EXAMPLE_PY_SERVICE_BINARY, CompilerEnv), ], ids=["llvm", "dummy-cc", "dummy-py"], ) @@ -80,7 +80,7 @@ def test_make_service(benchmark, args): ], ids=["llvm;fast-benchmark", "llvm;slow-benchmark", "dummy-cc", "dummy-py"], ) -def test_reset(benchmark, make_env: ClientServiceCompilerEnv): +def test_reset(benchmark, make_env: CompilerEnv): with make_env() as env: benchmark(env.reset) diff --git a/compiler_gym/__init__.py b/compiler_gym/__init__.py index 9cea377fa..087f344e3 100644 --- a/compiler_gym/__init__.py +++ b/compiler_gym/__init__.py @@ -4,7 +4,7 @@ # LICENSE file in the root directory of this source tree. """CompilerGym is a set of compiler optimization environments for reinforcement learning. -After importing this module, the :class:`CompilerGym environments ` +After importing this module, the :class:`CompilerGym environments ` will be available through the :code:`gym.make(...)` interface: >>> import gym @@ -34,7 +34,7 @@ CompilerEnvStateReader, CompilerEnvStateWriter, ) -from compiler_gym.envs import COMPILER_GYM_ENVS, ClientServiceCompilerEnv +from compiler_gym.envs import COMPILER_GYM_ENVS, CompilerEnv from compiler_gym.random_search import random_search from compiler_gym.util.debug_util import ( get_debug_level, @@ -58,7 +58,7 @@ "cache_path", "COMPILER_GYM_ENVS", "make", - "ClientServiceCompilerEnv", + "CompilerEnv", "CompilerEnvState", "CompilerEnvStateWriter", "CompilerEnvStateReader", diff --git a/compiler_gym/bin/manual_env.py b/compiler_gym/bin/manual_env.py index 30117da4e..d90a689ed 100644 --- a/compiler_gym/bin/manual_env.py +++ b/compiler_gym/bin/manual_env.py @@ -228,7 +228,7 @@ from absl import app, flags -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.util.flags.benchmark_from_flags import benchmark_from_flags from compiler_gym.util.flags.env_from_flags import env_from_flags from compiler_gym.util.shell_format import emph @@ -277,7 +277,7 @@ class CompilerGymShell(cmd.Cmd): Type help or ? for more information. The 'tutorial' command will give a step by step guide.""" - def __init__(self, env: ClientServiceCompilerEnv): + def __init__(self, env: CompilerEnv): """Initialise with an environment. :param env: The environment to run. """ diff --git a/compiler_gym/datasets/benchmark.py b/compiler_gym/datasets/benchmark.py index 84dcc0726..6bfab49a1 100644 --- a/compiler_gym/datasets/benchmark.py +++ b/compiler_gym/datasets/benchmark.py @@ -13,12 +13,10 @@ from compiler_gym.util.decorators import memoized_property from compiler_gym.validation_error import ValidationError -# A validation callback is a function that takes a single ClientServiceCompilerEnv instance +# A validation callback is a function that takes a single CompilerEnv instance # as its argument and returns an iterable sequence of zero or more # ValidationError tuples. -ValidationCallback = Callable[ - ["ClientServiceCompilerEnv"], Iterable[ValidationError] # noqa: F821 -] +ValidationCallback = Callable[["CompilerEnv"], Iterable[ValidationError]] # noqa: F821 class BenchmarkSource(NamedTuple): @@ -44,8 +42,8 @@ def __repr__(self) -> str: class Benchmark: """A benchmark represents a particular program that is being compiled. - A benchmark is a program that can be used by a :class:`ClientServiceCompilerEnv - ` as a program to optimize. A benchmark + A benchmark is a program that can be used by a :class:`CompilerEnv + ` as a program to optimize. A benchmark comprises the data that is fed into the compiler, identified by a URI. Benchmarks are not normally instantiated directly. Instead, benchmarks are @@ -74,9 +72,9 @@ class Benchmark: instances. The benchmark for an environment can be set during :meth:`env.reset() - `. The currently active benchmark can + `. The currently active benchmark can be queried using :attr:`env.benchmark - `: + `: >>> env = gym.make("llvm-v0") >>> env.reset(benchmark="benchmark://cbench-v1/crc32") @@ -152,9 +150,7 @@ def is_validatable(self) -> bool: """ return self._validation_callbacks != [] - def validate( - self, env: "ClientServiceCompilerEnv" # noqa: F821 - ) -> List[ValidationError]: + def validate(self, env: "CompilerEnv") -> List[ValidationError]: # noqa: F821 """Run the validation callbacks and return any errors. If no errors are returned, validation has succeeded: @@ -179,7 +175,7 @@ def validate( >>> benchmark.validate(env) == list(benchmark.ivalidate(env)) True - :param env: The :class:`ClientServiceCompilerEnv ` + :param env: The :class:`CompilerEnv ` instance that is being validated. :return: A list of zero or more :class:`ValidationError @@ -188,15 +184,13 @@ def validate( """ return list(self.ivalidate(env)) - def ivalidate( - self, env: "ClientServiceCompilerEnv" # noqa: F821 - ) -> Iterable[ValidationError]: + def ivalidate(self, env: "CompilerEnv") -> Iterable[ValidationError]: # noqa: F821 """Run the validation callbacks and return a generator of errors. This is an asynchronous version of :meth:`validate() ` that returns immediately. - :parameter env: A :class:`ClientServiceCompilerEnv ` + :parameter env: A :class:`CompilerEnv ` instance to validate. :return: A generator of :class:`ValidationError @@ -237,7 +231,7 @@ def add_validation_callback( :meth:`validate() `. :param validation_callback: A callback that accepts a single - :class:`ClientServiceCompilerEnv ` argument and + :class:`CompilerEnv ` argument and returns an iterable sequence of zero or more :class:`ValidationError ` tuples. Validation callbacks must be thread safe and must not modify the environment. diff --git a/compiler_gym/envs/compiler_env.py b/compiler_gym/envs/compiler_env.py index 28e4e8732..117e73615 100644 --- a/compiler_gym/envs/compiler_env.py +++ b/compiler_gym/envs/compiler_env.py @@ -263,7 +263,7 @@ def multistep( @abstractmethod def commandline(self) -> str: - """Interface for :class:`ClientServiceCompilerEnv ` + """Interface for :class:`CompilerEnv ` subclasses to provide an equivalent commandline invocation to the current environment state. @@ -276,12 +276,12 @@ def commandline(self) -> str: @abstractmethod def commandline_to_actions(self, commandline: str) -> List[ActionType]: - """Interface for :class:`ClientServiceCompilerEnv ` + """Interface for :class:`CompilerEnv ` subclasses to convert from a commandline invocation to a sequence of actions. See also :meth:`commandline() - `. + `. :return: A list of actions. """ diff --git a/compiler_gym/envs/gcc/datasets/csmith.py b/compiler_gym/envs/gcc/datasets/csmith.py index 04a1726fc..681a6a3a5 100644 --- a/compiler_gym/envs/gcc/datasets/csmith.py +++ b/compiler_gym/envs/gcc/datasets/csmith.py @@ -81,7 +81,7 @@ class CsmithDataset(Dataset): Note that Csmith is a tool that is used to find errors in compilers. As such, there is a higher likelihood that the benchmark cannot be used for an environment and that :meth:`env.reset() - ` will raise :class:`BenchmarkInitError + ` will raise :class:`BenchmarkInitError `. """ diff --git a/compiler_gym/envs/llvm/datasets/csmith.py b/compiler_gym/envs/llvm/datasets/csmith.py index f22d87f13..54c8815da 100644 --- a/compiler_gym/envs/llvm/datasets/csmith.py +++ b/compiler_gym/envs/llvm/datasets/csmith.py @@ -89,7 +89,7 @@ class CsmithDataset(Dataset): Note that Csmith is a tool that is used to find errors in compilers. As such, there is a higher likelihood that the benchmark cannot be used for an environment and that :meth:`env.reset() - ` will raise :class:`BenchmarkInitError + ` will raise :class:`BenchmarkInitError `. """ diff --git a/compiler_gym/envs/llvm/datasets/llvm_stress.py b/compiler_gym/envs/llvm/datasets/llvm_stress.py index 38fd09232..daa0985ac 100644 --- a/compiler_gym/envs/llvm/datasets/llvm_stress.py +++ b/compiler_gym/envs/llvm/datasets/llvm_stress.py @@ -32,7 +32,7 @@ class LlvmStressDataset(Dataset): Note that llvm-stress is a tool that is used to find errors in LLVM. As such, there is a higher likelihood that the benchmark cannot be used for an environment and that :meth:`env.reset() - ` will raise + ` will raise :class:`BenchmarkInitError `. """ diff --git a/compiler_gym/leaderboard/llvm_instcount.py b/compiler_gym/leaderboard/llvm_instcount.py index 3702cfab4..7a9c079a0 100644 --- a/compiler_gym/leaderboard/llvm_instcount.py +++ b/compiler_gym/leaderboard/llvm_instcount.py @@ -166,7 +166,7 @@ def eval_llvm_instcount_policy(policy: Policy) -> None: The role of your policy is to perform a sequence of actions on the supplied environment so as to maximize cumulative reward. By default, no observation space is set on the environment, so :meth:`env.step() - ` will return :code:`None` for the + ` will return :code:`None` for the observation. You may set a new observation space: >>> env.observation_space = "InstCount" # Set a new space for env.step() diff --git a/compiler_gym/random_replay.py b/compiler_gym/random_replay.py index 08871c7c1..b342e1be2 100644 --- a/compiler_gym/random_replay.py +++ b/compiler_gym/random_replay.py @@ -8,7 +8,7 @@ from deprecated import deprecated -from compiler_gym.envs.client_service_compiler_env import ClientServiceCompilerEnv +from compiler_gym.envs.client_service_compiler_env import CompilerEnv from compiler_gym.random_search import replay_actions as replay_actions_ from compiler_gym.random_search import ( replay_actions_from_logs as replay_actions_from_logs_, @@ -16,9 +16,7 @@ @deprecated(version="0.2.1", reason="Use env.step(action) instead") -def replay_actions( - env: ClientServiceCompilerEnv, action_names: List[str], outdir: Path -): +def replay_actions(env: CompilerEnv, action_names: List[str], outdir: Path): return replay_actions_(env, action_names, outdir) @@ -26,7 +24,5 @@ def replay_actions( version="0.2.1", reason="Use compiler_gym.random_search.replay_actions_from_logs() instead", ) -def replay_actions_from_logs( - env: ClientServiceCompilerEnv, logdir: Path, benchmark=None -) -> None: +def replay_actions_from_logs(env: CompilerEnv, logdir: Path, benchmark=None) -> None: return replay_actions_from_logs_(env, logdir, benchmark) diff --git a/compiler_gym/random_search.py b/compiler_gym/random_search.py index f6953ba4e..a81b0bdb2 100644 --- a/compiler_gym/random_search.py +++ b/compiler_gym/random_search.py @@ -13,7 +13,7 @@ import humanize -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.envs.llvm import LlvmEnv from compiler_gym.service.connection import ServiceError from compiler_gym.util import logs @@ -68,7 +68,7 @@ class RandomAgentWorker(Thread): def __init__( self, - make_env: Callable[[], ClientServiceCompilerEnv], + make_env: Callable[[], CompilerEnv], patience: int, ): super().__init__() @@ -99,14 +99,14 @@ def run(self) -> None: self._patience = self._patience or env.action_space.n self.run_one_environment(env) - def run_one_environment(self, env: ClientServiceCompilerEnv) -> None: + def run_one_environment(self, env: CompilerEnv) -> None: """Run random walks in an infinite loop. Returns if the environment ends.""" while self.should_run_one_episode: self.total_episode_count += 1 if not self.run_one_episode(env): return - def run_one_episode(self, env: ClientServiceCompilerEnv) -> bool: + def run_one_episode(self, env: CompilerEnv) -> bool: """Run a single random episode. :param env: An environment. @@ -141,18 +141,18 @@ def run_one_episode(self, env: ClientServiceCompilerEnv) -> bool: def random_search( - make_env: Callable[[], ClientServiceCompilerEnv], + make_env: Callable[[], CompilerEnv], outdir: Optional[Union[str, Path]] = None, total_runtime: Optional[float] = 600, patience: int = 0, nproc: int = cpu_count(), skip_done: bool = False, -) -> ClientServiceCompilerEnv: +) -> CompilerEnv: with make_env() as env: env.reset() - if not isinstance(env.unwrapped, ClientServiceCompilerEnv): + if not isinstance(env.unwrapped, CompilerEnv): raise TypeError( - f"random_search() requires ClientServiceCompilerEnv. Called with: {type(env).__name__}" + f"random_search() requires CompilerEnv. Called with: {type(env).__name__}" ) benchmark_uri = env.benchmark.uri @@ -296,9 +296,7 @@ def random_search( return env -def replay_actions( - env: ClientServiceCompilerEnv, action_names: List[str], outdir: Path -): +def replay_actions(env: CompilerEnv, action_names: List[str], outdir: Path): logs_path = outdir / logs.BEST_ACTIONS_PROGRESS_NAME start_time = time() @@ -347,9 +345,7 @@ def replay_actions( ) -def replay_actions_from_logs( - env: ClientServiceCompilerEnv, logdir: Path, benchmark=None -) -> None: +def replay_actions_from_logs(env: CompilerEnv, logdir: Path, benchmark=None) -> None: best_actions_path = logdir / logs.BEST_ACTIONS_NAME meta_path = logdir / logs.METADATA_NAME diff --git a/compiler_gym/service/connection.py b/compiler_gym/service/connection.py index 9fa49f4a1..8f9295781 100644 --- a/compiler_gym/service/connection.py +++ b/compiler_gym/service/connection.py @@ -94,9 +94,9 @@ class ConnectionOpts(BaseModel): always_send_benchmark_on_reset: bool = False """Send the full benchmark program data to the compiler service on ever call - to :meth:`env.reset() `. This is more + to :meth:`env.reset() `. This is more efficient in cases where the majority of calls to - :meth:`env.reset() ` uses a different + :meth:`env.reset() ` uses a different benchmark. In case of benchmark re-use, leave this :code:`False`. """ diff --git a/compiler_gym/util/flags/env_from_flags.py b/compiler_gym/util/flags/env_from_flags.py index bf0cf012e..d240d6a6b 100644 --- a/compiler_gym/util/flags/env_from_flags.py +++ b/compiler_gym/util/flags/env_from_flags.py @@ -11,7 +11,7 @@ import gym from absl import app, flags -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.service import ConnectionOpts from compiler_gym.service.proto import Benchmark from compiler_gym.util.registration import COMPILER_GYM_ENVS @@ -109,9 +109,7 @@ def connection_settings_from_flags( ) -def env_from_flags( - benchmark: Optional[Union[str, Benchmark]] = None -) -> ClientServiceCompilerEnv: +def env_from_flags(benchmark: Optional[Union[str, Benchmark]] = None) -> CompilerEnv: if FLAGS.ls_env: print("\n".join(sorted(COMPILER_GYM_ENVS))) sys.exit(0) @@ -145,6 +143,6 @@ def env_from_flags( @contextmanager def env_session_from_flags( benchmark: Optional[Union[str, Benchmark]] = None -) -> ClientServiceCompilerEnv: +) -> CompilerEnv: with env_from_flags(benchmark=benchmark) as env: yield env diff --git a/compiler_gym/validate.py b/compiler_gym/validate.py index 0b9192930..5f897ffb9 100644 --- a/compiler_gym/validate.py +++ b/compiler_gym/validate.py @@ -8,13 +8,13 @@ from typing import Callable, Iterable, Optional from compiler_gym.compiler_env_state import CompilerEnvState -from compiler_gym.envs.client_service_compiler_env import ClientServiceCompilerEnv +from compiler_gym.envs.client_service_compiler_env import CompilerEnv from compiler_gym.util import thread_pool from compiler_gym.validation_result import ValidationResult def _validate_states_worker( - make_env: Callable[[], ClientServiceCompilerEnv], state: CompilerEnvState + make_env: Callable[[], CompilerEnv], state: CompilerEnvState ) -> ValidationResult: with make_env() as env: result = env.validate(state) @@ -22,13 +22,13 @@ def _validate_states_worker( def validate_states( - make_env: Callable[[], ClientServiceCompilerEnv], + make_env: Callable[[], CompilerEnv], states: Iterable[CompilerEnvState], nproc: Optional[int] = None, inorder: bool = False, ) -> Iterable[ValidationResult]: """A parallelized implementation of - :meth:`env.validate() ` for batched + :meth:`env.validate() ` for batched validation. :param make_env: A callback which instantiates a compiler environment. diff --git a/compiler_gym/validation_error.py b/compiler_gym/validation_error.py index 8a1468892..cbbdbf054 100644 --- a/compiler_gym/validation_error.py +++ b/compiler_gym/validation_error.py @@ -10,7 +10,7 @@ class ValidationError(BaseModel): """A ValidationError describes an error encountered in a call to - :meth:`env.validate() `. + :meth:`env.validate() `. """ type: str diff --git a/compiler_gym/views/observation_space_spec.py b/compiler_gym/views/observation_space_spec.py index 9377522dd..77b50c9fd 100644 --- a/compiler_gym/views/observation_space_spec.py +++ b/compiler_gym/views/observation_space_spec.py @@ -32,8 +32,8 @@ class ObservationSpaceSpec: :vartype platform_dependent: bool :ivar default_value: A default observation. This value will be returned by - :func:`ClientServiceCompilerEnv.step() ` if - :func:`ClientServiceCompilerEnv.observation_space ` + :func:`CompilerEnv.step() ` if + :func:`CompilerEnv.observation_space ` is set and the service terminates. """ diff --git a/examples/example_compiler_gym_service/env_tests.py b/examples/example_compiler_gym_service/env_tests.py index ea44d9103..4b2259bc7 100644 --- a/examples/example_compiler_gym_service/env_tests.py +++ b/examples/example_compiler_gym_service/env_tests.py @@ -14,7 +14,7 @@ from flaky import flaky import examples.example_compiler_gym_service as example -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.service import SessionNotFound from compiler_gym.spaces import Box, NamedDiscrete, Scalar, Sequence from compiler_gym.util.commands import Popen @@ -26,7 +26,7 @@ @pytest.fixture(scope="function", params=EXAMPLE_ENVIRONMENTS) -def env(request) -> ClientServiceCompilerEnv: +def env(request) -> CompilerEnv: """Text fixture that yields an environment.""" with gym.make(request.param) as env: yield env @@ -64,12 +64,12 @@ def run(cmd): assert returncode == 1 -def test_versions(env: ClientServiceCompilerEnv): +def test_versions(env: CompilerEnv): """Tests the GetVersion() RPC endpoint.""" assert env.compiler_version == "1.0.0" -def test_action_space(env: ClientServiceCompilerEnv): +def test_action_space(env: CompilerEnv): """Test that the environment reports the service's action spaces.""" assert env.action_spaces == [ NamedDiscrete( @@ -79,7 +79,7 @@ def test_action_space(env: ClientServiceCompilerEnv): ] -def test_observation_spaces(env: ClientServiceCompilerEnv): +def test_observation_spaces(env: CompilerEnv): """Test that the environment reports the service's observation spaces.""" env.reset() assert env.observation.spaces.keys() == {"ir", "features", "runtime"} @@ -96,50 +96,50 @@ def test_observation_spaces(env: ClientServiceCompilerEnv): ) -def test_reward_spaces(env: ClientServiceCompilerEnv): +def test_reward_spaces(env: CompilerEnv): """Test that the environment reports the service's reward spaces.""" env.reset() assert env.reward.spaces.keys() == {"runtime"} -def test_step_before_reset(env: ClientServiceCompilerEnv): +def test_step_before_reset(env: CompilerEnv): """Taking a step() before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): env.step(0) -def test_observation_before_reset(env: ClientServiceCompilerEnv): +def test_observation_before_reset(env: CompilerEnv): """Taking an observation before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): _ = env.observation["ir"] -def test_reward_before_reset(env: ClientServiceCompilerEnv): +def test_reward_before_reset(env: CompilerEnv): """Taking a reward before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): _ = env.reward["runtime"] -def test_reset_invalid_benchmark(env: ClientServiceCompilerEnv): +def test_reset_invalid_benchmark(env: CompilerEnv): """Test requesting a specific benchmark.""" with pytest.raises(LookupError) as ctx: env.reset(benchmark="example-v0/foobar") assert str(ctx.value) == "Unknown program name" -def test_invalid_observation_space(env: ClientServiceCompilerEnv): +def test_invalid_observation_space(env: CompilerEnv): """Test error handling with invalid observation space.""" with pytest.raises(LookupError): env.observation_space = 100 -def test_invalid_reward_space(env: ClientServiceCompilerEnv): +def test_invalid_reward_space(env: CompilerEnv): """Test error handling with invalid reward space.""" with pytest.raises(LookupError): env.reward_space = 100 -def test_double_reset(env: ClientServiceCompilerEnv): +def test_double_reset(env: CompilerEnv): """Test that reset() can be called twice.""" env.reset() assert env.in_episode @@ -147,7 +147,7 @@ def test_double_reset(env: ClientServiceCompilerEnv): assert env.in_episode -def test_double_reset_with_step(env: ClientServiceCompilerEnv): +def test_double_reset_with_step(env: CompilerEnv): """Test that reset() can be called twice with a step.""" env.reset() assert env.in_episode @@ -159,7 +159,7 @@ def test_double_reset_with_step(env: ClientServiceCompilerEnv): assert env.in_episode -def test_Step_out_of_range(env: ClientServiceCompilerEnv): +def test_Step_out_of_range(env: CompilerEnv): """Test error handling with an invalid action.""" env.reset() with pytest.raises(ValueError) as ctx: @@ -167,7 +167,7 @@ def test_Step_out_of_range(env: ClientServiceCompilerEnv): assert str(ctx.value) == "Out-of-range" -def test_default_ir_observation(env: ClientServiceCompilerEnv): +def test_default_ir_observation(env: CompilerEnv): """Test default observation space.""" env.observation_space = "ir" observation = env.reset() @@ -179,7 +179,7 @@ def test_default_ir_observation(env: ClientServiceCompilerEnv): assert not done -def test_default_features_observation(env: ClientServiceCompilerEnv): +def test_default_features_observation(env: CompilerEnv): """Test default observation space.""" env.observation_space = "features" observation = env.reset() @@ -189,7 +189,7 @@ def test_default_features_observation(env: ClientServiceCompilerEnv): assert observation.tolist() == [0, 0, 0] -def test_default_reward(env: ClientServiceCompilerEnv): +def test_default_reward(env: CompilerEnv): """Test default reward space.""" env.reward_space = "runtime" env.reset() @@ -199,27 +199,27 @@ def test_default_reward(env: ClientServiceCompilerEnv): assert not done -def test_observations(env: ClientServiceCompilerEnv): +def test_observations(env: CompilerEnv): """Test observation spaces.""" env.reset() assert env.observation["ir"] == "Hello, world!" np.testing.assert_array_equal(env.observation["features"], [0, 0, 0]) -def test_rewards(env: ClientServiceCompilerEnv): +def test_rewards(env: CompilerEnv): """Test reward spaces.""" env.reset() assert env.reward["runtime"] == 0 -def test_benchmarks(env: ClientServiceCompilerEnv): +def test_benchmarks(env: CompilerEnv): assert list(env.datasets.benchmark_uris()) == [ "benchmark://example-v0/foo", "benchmark://example-v0/bar", ] -def test_fork(env: ClientServiceCompilerEnv): +def test_fork(env: CompilerEnv): env.reset() env.step(0) env.step(1) diff --git a/examples/example_unrolling_service/env_tests.py b/examples/example_unrolling_service/env_tests.py index 9b98a3510..fba1ec4ab 100644 --- a/examples/example_unrolling_service/env_tests.py +++ b/examples/example_unrolling_service/env_tests.py @@ -12,7 +12,7 @@ import compiler_gym import examples.example_unrolling_service as unrolling_service -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.service import SessionNotFound from compiler_gym.spaces import Box, NamedDiscrete, Scalar, Sequence from compiler_gym.util.commands import Popen @@ -20,7 +20,7 @@ @pytest.fixture(scope="function") -def env() -> ClientServiceCompilerEnv: +def env() -> CompilerEnv: """Text fixture that yields an environment.""" with gym.make("unrolling-py-v0") as env_: yield env_ @@ -54,13 +54,13 @@ def run(cmd): assert returncode == 1 -def test_versions(env: ClientServiceCompilerEnv): +def test_versions(env: CompilerEnv): """Tests the GetVersion() RPC endpoint.""" assert env.version == compiler_gym.__version__ assert env.compiler_version == "1.0.0" -def test_action_space(env: ClientServiceCompilerEnv): +def test_action_space(env: CompilerEnv): """Test that the environment reports the service's action spaces.""" assert env.action_spaces == [ NamedDiscrete( @@ -74,7 +74,7 @@ def test_action_space(env: ClientServiceCompilerEnv): ] -def test_observation_spaces(env: ClientServiceCompilerEnv): +def test_observation_spaces(env: CompilerEnv): """Test that the environment reports the service's observation spaces.""" env.reset() assert env.observation.spaces.keys() == {"ir", "features", "runtime", "size"} @@ -95,50 +95,50 @@ def test_observation_spaces(env: ClientServiceCompilerEnv): ) -def test_reward_spaces(env: ClientServiceCompilerEnv): +def test_reward_spaces(env: CompilerEnv): """Test that the environment reports the service's reward spaces.""" env.reset() assert env.reward.spaces.keys() == {"runtime", "size"} -def test_step_before_reset(env: ClientServiceCompilerEnv): +def test_step_before_reset(env: CompilerEnv): """Taking a step() before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): env.step(0) -def test_observation_before_reset(env: ClientServiceCompilerEnv): +def test_observation_before_reset(env: CompilerEnv): """Taking an observation before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): _ = env.observation["ir"] -def test_reward_before_reset(env: ClientServiceCompilerEnv): +def test_reward_before_reset(env: CompilerEnv): """Taking a reward before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): _ = env.reward["runtime"] -def test_reset_invalid_benchmark(env: ClientServiceCompilerEnv): +def test_reset_invalid_benchmark(env: CompilerEnv): """Test requesting a specific benchmark.""" with pytest.raises(LookupError) as ctx: env.reset(benchmark="unrolling-v0/foobar") assert str(ctx.value) == "Unknown program name" -def test_invalid_observation_space(env: ClientServiceCompilerEnv): +def test_invalid_observation_space(env: CompilerEnv): """Test error handling with invalid observation space.""" with pytest.raises(LookupError): env.observation_space = 100 -def test_invalid_reward_space(env: ClientServiceCompilerEnv): +def test_invalid_reward_space(env: CompilerEnv): """Test error handling with invalid reward space.""" with pytest.raises(LookupError): env.reward_space = 100 -def test_double_reset(env: ClientServiceCompilerEnv): +def test_double_reset(env: CompilerEnv): """Test that reset() can be called twice.""" env.reset() assert env.in_episode @@ -146,7 +146,7 @@ def test_double_reset(env: ClientServiceCompilerEnv): assert env.in_episode -def test_Step_out_of_range(env: ClientServiceCompilerEnv): +def test_Step_out_of_range(env: CompilerEnv): """Test error handling with an invalid action.""" env.reset() with pytest.raises(ValueError) as ctx: @@ -154,7 +154,7 @@ def test_Step_out_of_range(env: ClientServiceCompilerEnv): assert str(ctx.value) == "Out-of-range" -def test_default_ir_observation(env: ClientServiceCompilerEnv): +def test_default_ir_observation(env: CompilerEnv): """Test default observation space.""" env.observation_space = "ir" observation = env.reset() @@ -166,7 +166,7 @@ def test_default_ir_observation(env: ClientServiceCompilerEnv): assert reward is None -def test_default_features_observation(env: ClientServiceCompilerEnv): +def test_default_features_observation(env: CompilerEnv): """Test default observation space.""" env.observation_space = "features" observation = env.reset() @@ -176,7 +176,7 @@ def test_default_features_observation(env: ClientServiceCompilerEnv): assert all(obs >= 0 for obs in observation.tolist()) -def test_default_reward(env: ClientServiceCompilerEnv): +def test_default_reward(env: CompilerEnv): """Test default reward space.""" env.reward_space = "runtime" env.reset() @@ -186,27 +186,27 @@ def test_default_reward(env: ClientServiceCompilerEnv): assert reward is not None -def test_observations(env: ClientServiceCompilerEnv): +def test_observations(env: CompilerEnv): """Test observation spaces.""" env.reset() assert len(env.observation["ir"]) > 0 np.testing.assert_array_less([-1, -1, -1], env.observation["features"]) -def test_rewards(env: ClientServiceCompilerEnv): +def test_rewards(env: CompilerEnv): """Test reward spaces.""" env.reset() assert env.reward["runtime"] is not None -def test_benchmarks(env: ClientServiceCompilerEnv): +def test_benchmarks(env: CompilerEnv): assert list(env.datasets.benchmark_uris()) == [ "benchmark://unrolling-v0/offsets1", "benchmark://unrolling-v0/conv2d", ] -def test_fork(env: ClientServiceCompilerEnv): +def test_fork(env: CompilerEnv): env.reset() env.step(0) env.step(1) diff --git a/examples/gcc_autotuning/tune.py b/examples/gcc_autotuning/tune.py index 74d51151a..b1613e06c 100644 --- a/examples/gcc_autotuning/tune.py +++ b/examples/gcc_autotuning/tune.py @@ -17,7 +17,7 @@ import compiler_gym.util.flags.nproc # noqa Flag definition. import compiler_gym.util.flags.output_dir # noqa Flag definition. import compiler_gym.util.flags.seed # noqa Flag definition. -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.envs.gcc import DEFAULT_GCC from compiler_gym.service import ServiceError from compiler_gym.util.executor import Executor @@ -69,7 +69,7 @@ GCC_ENV_CONSTRUCTOR_LOCK = Lock() -def random_search(env: ClientServiceCompilerEnv): +def random_search(env: CompilerEnv): best = float("inf") for _ in range(FLAGS.gcc_search_budget): env.reset() @@ -81,7 +81,7 @@ def random_search(env: ClientServiceCompilerEnv): return best -def hill_climb(env: ClientServiceCompilerEnv): +def hill_climb(env: CompilerEnv): best = float("inf") for _ in range(FLAGS.gcc_search_budget): with env.fork() as fkd: @@ -98,7 +98,7 @@ def hill_climb(env: ClientServiceCompilerEnv): return best -def genetic_algorithm(env: ClientServiceCompilerEnv): +def genetic_algorithm(env: CompilerEnv): def f(choices): env.reset() env.choices = choices = list(map(int, choices)) diff --git a/examples/llvm_autotuning/autotuners/__init__.py b/examples/llvm_autotuning/autotuners/__init__.py index 9904c2bf9..6eab0f9b9 100644 --- a/examples/llvm_autotuning/autotuners/__init__.py +++ b/examples/llvm_autotuning/autotuners/__init__.py @@ -15,7 +15,7 @@ from pydantic import BaseModel, validator from compiler_gym.compiler_env_state import CompilerEnvState -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.util.capture_output import capture_output from compiler_gym.util.runfiles_path import transient_cache_path from compiler_gym.util.temporary_working_directory import temporary_working_directory @@ -26,7 +26,7 @@ class Autotuner(BaseModel): """This class represents an instance of an autotuning algorithm. After instantiating from a config dict, instances of this class can be used - to tune ClientServiceCompilerEnv instances: + to tune CompilerEnv instances: >>> autotuner = Autotuner( algorithm="greedy", @@ -53,7 +53,7 @@ class Autotuner(BaseModel): def autotune(self): """Return the autotuner function for this algorithm. - An autotuner function takes a single ClientServiceCompilerEnv argument and optional + An autotuner function takes a single CompilerEnv argument and optional keyword configuration arguments (determined by algorithm_config) and tunes the environment, returning nothing. """ @@ -76,9 +76,7 @@ def autotune_kwargs(self) -> Dict[str, Any]: kwargs.update(self.algorithm_config) return kwargs - def __call__( - self, env: ClientServiceCompilerEnv, seed: int = 0xCC - ) -> CompilerEnvState: + def __call__(self, env: CompilerEnv, seed: int = 0xCC) -> CompilerEnvState: """Autotune the given environment. :param env: The environment to autotune. diff --git a/examples/llvm_autotuning/autotuners/nevergrad_.py b/examples/llvm_autotuning/autotuners/nevergrad_.py index d700407b3..bacea33d8 100644 --- a/examples/llvm_autotuning/autotuners/nevergrad_.py +++ b/examples/llvm_autotuning/autotuners/nevergrad_.py @@ -9,12 +9,12 @@ import nevergrad as ng from llvm_autotuning.optimization_target import OptimizationTarget -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.util.gym_type_hints import ActionType def nevergrad( - env: ClientServiceCompilerEnv, + env: CompilerEnv, optimization_target: OptimizationTarget, search_time_seconds: int, seed: int, diff --git a/examples/llvm_autotuning/autotuners/random_.py b/examples/llvm_autotuning/autotuners/random_.py index feb269cd9..7ef575f22 100644 --- a/examples/llvm_autotuning/autotuners/random_.py +++ b/examples/llvm_autotuning/autotuners/random_.py @@ -6,13 +6,13 @@ from llvm_autotuning.optimization_target import OptimizationTarget -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.random_search import random_search as lib_random_search from compiler_gym.util.runfiles_path import transient_cache_path def random( - env: ClientServiceCompilerEnv, + env: CompilerEnv, optimization_target: OptimizationTarget, search_time_seconds: int, patience: int = 350, diff --git a/examples/llvm_rl/model/benchmarks.py b/examples/llvm_rl/model/benchmarks.py index 593e5fe22..b707564e7 100644 --- a/examples/llvm_rl/model/benchmarks.py +++ b/examples/llvm_rl/model/benchmarks.py @@ -8,7 +8,7 @@ from pydantic import BaseModel, Field, root_validator, validator from compiler_gym.datasets import Benchmark, BenchmarkUri -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv class Benchmarks(BaseModel): @@ -54,11 +54,11 @@ class Benchmarks(BaseModel): # === Start of public API. === - def benchmarks_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[Benchmark]: + def benchmarks_iterator(self, env: CompilerEnv) -> Iterable[Benchmark]: """Return an iterator over the benchmarks.""" return self._benchmark_iterator(env) - def benchmark_uris_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[str]: + def benchmark_uris_iterator(self, env: CompilerEnv) -> Iterable[str]: """Return an iterator over the URIs of the benchmarks.""" return self._benchmark_iterator(env, uris=True) @@ -80,7 +80,7 @@ def validate_uris(cls, value, *, values, **kwargs): return list(value) def _benchmark_iterator( - self, env: ClientServiceCompilerEnv, uris: bool = False + self, env: CompilerEnv, uris: bool = False ) -> Union[Iterable[Benchmark], Iterable[str]]: return ( self._uris_iterator(env, uris) @@ -89,7 +89,7 @@ def _benchmark_iterator( ) def _uris_iterator( - self, env: ClientServiceCompilerEnv, uris: bool = False + self, env: CompilerEnv, uris: bool = False ) -> Union[Iterable[Benchmark], Iterable[str]]: """Iterate from a URIs list.""" start = self.benchmarks_start_at @@ -105,7 +105,7 @@ def _uris_iterator( return islice((env.datasets.benchmark(u) for u in self.uris), start, start + n) def _dataset_iterator( - self, env: ClientServiceCompilerEnv, uris: bool = False + self, env: CompilerEnv, uris: bool = False ) -> Union[Iterable[Benchmark], Iterable[str]]: """Iterate from a dataset name.""" dataset = env.datasets[self.dataset] diff --git a/examples/llvm_rl/model/environment.py b/examples/llvm_rl/model/environment.py index dc4938426..4bb8c8129 100644 --- a/examples/llvm_rl/model/environment.py +++ b/examples/llvm_rl/model/environment.py @@ -10,7 +10,7 @@ from pydantic.class_validators import root_validator import compiler_gym -from compiler_gym import ClientServiceCompilerEnv +from compiler_gym import CompilerEnv from compiler_gym.wrappers import * # noqa wrapper definitions from compiler_gym.wrappers import TimeLimit @@ -35,13 +35,13 @@ def wrapper_class(self): """Return the wrapper class type.""" return self._to_class(self.wrapper) - def wrap(self, env: ClientServiceCompilerEnv) -> ClientServiceCompilerEnv: + def wrap(self, env: CompilerEnv) -> CompilerEnv: """Wrap the given environment.""" try: return self.wrapper_class(env=env, **self.args) except TypeError as e: raise TypeError( - f"Error constructing ClientServiceCompilerEnv wrapper {self.wrapper_class.__name__}: {e}" + f"Error constructing CompilerEnv wrapper {self.wrapper_class.__name__}: {e}" ) from e # === Start of implementation details. === @@ -67,7 +67,7 @@ class Config: class Environment(BaseModel): - """Represents a ClientServiceCompilerEnv environment.""" + """Represents a CompilerEnv environment.""" id: str = Field(allow_mutation=False) """The environment ID, as passed to :code:`gym.make(...)`.""" @@ -93,7 +93,7 @@ class Environment(BaseModel): # === Start of public API. === - def make_env(self) -> ClientServiceCompilerEnv: + def make_env(self) -> CompilerEnv: """Construct a compiler environment from the given config.""" env = compiler_gym.make(self.id) if self.observation_space: diff --git a/examples/llvm_rl/model/testing.py b/examples/llvm_rl/model/testing.py index e9cfed862..a5353ddb2 100644 --- a/examples/llvm_rl/model/testing.py +++ b/examples/llvm_rl/model/testing.py @@ -10,7 +10,7 @@ from pydantic import BaseModel, Field, validator from compiler_gym.datasets import Benchmark -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from .benchmarks import Benchmarks @@ -39,13 +39,13 @@ class Testing(BaseModel): # === Start of public API. === - def benchmarks_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[Benchmark]: + def benchmarks_iterator(self, env: CompilerEnv) -> Iterable[Benchmark]: """Return an iterator over the test benchmarks.""" for _ in range(self.runs_per_benchmark): for bm in self.benchmarks: yield from bm.benchmarks_iterator(env) - def benchmark_uris_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[str]: + def benchmark_uris_iterator(self, env: CompilerEnv) -> Iterable[str]: """Return an iterator over the test benchmark URIs.""" for _ in range(self.runs_per_benchmark): for bm in self.benchmarks: @@ -62,7 +62,7 @@ class Config: def get_testing_benchmarks( - env: ClientServiceCompilerEnv, max_benchmarks: int = 50, seed: int = 0 + env: CompilerEnv, max_benchmarks: int = 50, seed: int = 0 ) -> List[str]: rng = np.random.default_rng(seed=seed) for dataset in env.datasets: diff --git a/examples/llvm_rl/model/training.py b/examples/llvm_rl/model/training.py index 9948b636b..6079e1f32 100644 --- a/examples/llvm_rl/model/training.py +++ b/examples/llvm_rl/model/training.py @@ -7,7 +7,7 @@ from pydantic import BaseModel, Field, validator from compiler_gym.datasets import Benchmark -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.wrappers import ( CycleOverBenchmarks, CycleOverBenchmarksIterator, @@ -48,17 +48,17 @@ class Training(BaseModel): # === Start of public API. === - def benchmarks_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[Benchmark]: + def benchmarks_iterator(self, env: CompilerEnv) -> Iterable[Benchmark]: """Return an iterator over the training benchmarks.""" for bm in self.benchmarks: yield from bm.benchmarks_iterator(env) - def benchmark_uris_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[str]: + def benchmark_uris_iterator(self, env: CompilerEnv) -> Iterable[str]: """Return an iterator over the training benchmark URIs.""" for bm in self.benchmarks: yield from bm.benchmark_uris_iterator(env) - def wrap_env(self, env: ClientServiceCompilerEnv) -> ClientServiceCompilerEnv: + def wrap_env(self, env: CompilerEnv) -> CompilerEnv: """Wrap an environment for use in the training loop that is configured to iterate over the training benchmarks on each call to :code:`reset()`. """ diff --git a/examples/llvm_rl/model/validation.py b/examples/llvm_rl/model/validation.py index 97a642445..72c08103f 100644 --- a/examples/llvm_rl/model/validation.py +++ b/examples/llvm_rl/model/validation.py @@ -7,7 +7,7 @@ from pydantic import BaseModel, Field, validator from compiler_gym.datasets import Benchmark -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.wrappers import CycleOverBenchmarks from .benchmarks import Benchmarks @@ -28,17 +28,17 @@ class Validation(BaseModel): # === Start of public API. === - def benchmarks_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[Benchmark]: + def benchmarks_iterator(self, env: CompilerEnv) -> Iterable[Benchmark]: """Return an iterator over the validation benchmarks.""" for bm in self.benchmarks: yield from bm.benchmarks_iterator(env) - def benchmark_uris_iterator(self, env: ClientServiceCompilerEnv) -> Iterable[str]: + def benchmark_uris_iterator(self, env: CompilerEnv) -> Iterable[str]: """Return an iterator over the training benchmark URIs.""" for bm in self.benchmarks: yield from bm.benchmark_uris_iterator(env) - def wrap_env(self, env: ClientServiceCompilerEnv) -> ClientServiceCompilerEnv: + def wrap_env(self, env: CompilerEnv) -> CompilerEnv: """Wrap an environment for use in the training loop that is configured to iterate over the validation benchmarks on each call to :code:`reset()`. diff --git a/examples/llvm_rl/wrappers.py b/examples/llvm_rl/wrappers.py index 2c0b2325b..4a2a7e6d9 100644 --- a/examples/llvm_rl/wrappers.py +++ b/examples/llvm_rl/wrappers.py @@ -8,7 +8,7 @@ import gym import numpy as np -from compiler_gym.envs import ClientServiceCompilerEnv, LlvmEnv +from compiler_gym.envs import CompilerEnv, LlvmEnv from compiler_gym.util.gym_type_hints import ActionType from compiler_gym.wrappers import ( ConstrainedCommandline, @@ -24,7 +24,7 @@ class ClampedReward(RewardWrapper): def __init__( self, - env: ClientServiceCompilerEnv, + env: CompilerEnv, min: float = -1, max: float = 1, leakiness_factor: float = 0.001, @@ -50,7 +50,7 @@ class AutophaseNormalizedFeatures(ObservationWrapper): # The index of the "TotalInsts" feature of autophase. TotalInsts_index = 51 - def __init__(self, env: ClientServiceCompilerEnv): + def __init__(self, env: CompilerEnv): super().__init__(env=env) # Force Autophase observation space. self.env.observation_space = self.env.unwrapped.observation.spaces["Autophase"] @@ -86,7 +86,7 @@ class ConcatActionsHistogram(ObservationWrapper): steps. """ - def __init__(self, env: ClientServiceCompilerEnv, norm_to_episode_len: int = 0): + def __init__(self, env: CompilerEnv, norm_to_episode_len: int = 0): super().__init__(env=env) assert isinstance( self.observation_space, gym.spaces.Box diff --git a/examples/loop_optimizations_service/env_tests.py b/examples/loop_optimizations_service/env_tests.py index 77d19c3b7..8b4aacadd 100644 --- a/examples/loop_optimizations_service/env_tests.py +++ b/examples/loop_optimizations_service/env_tests.py @@ -12,7 +12,7 @@ import compiler_gym import examples.loop_optimizations_service as loop_optimizations_service -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import ClientServiceCompilerEnv, CompilerEnv from compiler_gym.service import SessionNotFound from compiler_gym.spaces import Dict, NamedDiscrete, Scalar, Sequence from compiler_gym.third_party.autophase import AUTOPHASE_FEATURE_NAMES @@ -20,7 +20,7 @@ @pytest.fixture(scope="function") -def env() -> ClientServiceCompilerEnv: +def env() -> CompilerEnv: """Text fixture that yields an environment.""" with gym.make("loops-opt-py-v0") as env_: yield env_ @@ -60,7 +60,7 @@ def test_versions(env: ClientServiceCompilerEnv): assert env.compiler_version == "1.0.0" -def test_action_space(env: ClientServiceCompilerEnv): +def test_action_space(env: CompilerEnv): """Test that the environment reports the service's action spaces.""" assert env.action_spaces == [ NamedDiscrete( @@ -81,7 +81,7 @@ def test_action_space(env: ClientServiceCompilerEnv): ] -def test_observation_spaces(env: ClientServiceCompilerEnv): +def test_observation_spaces(env: CompilerEnv): """Test that the environment reports the service's observation spaces.""" env.reset() assert env.observation.spaces.keys() == { @@ -128,50 +128,50 @@ def test_observation_spaces(env: ClientServiceCompilerEnv): ) -def test_reward_spaces(env: ClientServiceCompilerEnv): +def test_reward_spaces(env: CompilerEnv): """Test that the environment reports the service's reward spaces.""" env.reset() assert env.reward.spaces.keys() == {"runtime", "size"} -def test_step_before_reset(env: ClientServiceCompilerEnv): +def test_step_before_reset(env: CompilerEnv): """Taking a step() before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): env.step(0) -def test_observation_before_reset(env: ClientServiceCompilerEnv): +def test_observation_before_reset(env: CompilerEnv): """Taking an observation before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): _ = env.observation["ir"] -def test_reward_before_reset(env: ClientServiceCompilerEnv): +def test_reward_before_reset(env: CompilerEnv): """Taking a reward before reset() is illegal.""" with pytest.raises(SessionNotFound, match=r"Must call reset\(\) before step\(\)"): _ = env.reward["runtime"] -def test_reset_invalid_benchmark(env: ClientServiceCompilerEnv): +def test_reset_invalid_benchmark(env: CompilerEnv): """Test requesting a specific benchmark.""" with pytest.raises(LookupError) as ctx: env.reset(benchmark="loops-opt-v0/foobar") assert str(ctx.value) == "Unknown program name" -def test_invalid_observation_space(env: ClientServiceCompilerEnv): +def test_invalid_observation_space(env: CompilerEnv): """Test error handling with invalid observation space.""" with pytest.raises(LookupError): env.observation_space = 100 -def test_invalid_reward_space(env: ClientServiceCompilerEnv): +def test_invalid_reward_space(env: CompilerEnv): """Test error handling with invalid reward space.""" with pytest.raises(LookupError): env.reward_space = 100 -def test_double_reset(env: ClientServiceCompilerEnv): +def test_double_reset(env: CompilerEnv): """Test that reset() can be called twice.""" env.reset() assert env.in_episode @@ -179,7 +179,7 @@ def test_double_reset(env: ClientServiceCompilerEnv): assert env.in_episode -def test_Step_out_of_range(env: ClientServiceCompilerEnv): +def test_Step_out_of_range(env: CompilerEnv): """Test error handling with an invalid action.""" env.reset() with pytest.raises(ValueError) as ctx: @@ -187,7 +187,7 @@ def test_Step_out_of_range(env: ClientServiceCompilerEnv): assert str(ctx.value) == "Out-of-range" -def test_default_ir_observation(env: ClientServiceCompilerEnv): +def test_default_ir_observation(env: CompilerEnv): """Test default IR observation space.""" env.observation_space = "ir" observation = env.reset() @@ -199,7 +199,7 @@ def test_default_ir_observation(env: ClientServiceCompilerEnv): assert reward is None -def test_default_inst2vec_observation(env: ClientServiceCompilerEnv): +def test_default_inst2vec_observation(env: CompilerEnv): """Test default inst2vec observation space.""" env.observation_space = "Inst2vec" observation = env.reset() @@ -209,7 +209,7 @@ def test_default_inst2vec_observation(env: ClientServiceCompilerEnv): assert all(obs >= 0 for obs in observation.tolist()) -def test_default_autophase_observation(env: ClientServiceCompilerEnv): +def test_default_autophase_observation(env: CompilerEnv): """Test default autophase observation space.""" env.observation_space = "Autophase" observation = env.reset() @@ -219,7 +219,7 @@ def test_default_autophase_observation(env: ClientServiceCompilerEnv): assert all(obs >= 0 for obs in observation.tolist()) -def test_default_autophase_dict_observation(env: ClientServiceCompilerEnv): +def test_default_autophase_dict_observation(env: CompilerEnv): """Test default autophase dict observation space.""" env.observation_space = "AutophaseDict" observation = env.reset() @@ -229,7 +229,7 @@ def test_default_autophase_dict_observation(env: ClientServiceCompilerEnv): assert all(obs >= 0 for obs in observation.values()) -def test_default_programl_observation(env: ClientServiceCompilerEnv): +def test_default_programl_observation(env: CompilerEnv): """Test default observation space.""" env.observation_space = "Programl" observation = env.reset() @@ -241,7 +241,7 @@ def test_default_programl_observation(env: ClientServiceCompilerEnv): assert reward is None -def test_default_reward(env: ClientServiceCompilerEnv): +def test_default_reward(env: CompilerEnv): """Test default reward space.""" env.reward_space = "runtime" env.reset() @@ -251,7 +251,7 @@ def test_default_reward(env: ClientServiceCompilerEnv): assert reward is not None -def test_observations(env: ClientServiceCompilerEnv): +def test_observations(env: CompilerEnv): """Test observation spaces.""" env.reset() assert len(env.observation["ir"]) > 0 @@ -260,13 +260,13 @@ def test_observations(env: ClientServiceCompilerEnv): assert len(env.observation["Programl"]) > 0 -def test_rewards(env: ClientServiceCompilerEnv): +def test_rewards(env: CompilerEnv): """Test reward spaces.""" env.reset() assert env.reward["runtime"] is not None -def test_benchmarks(env: ClientServiceCompilerEnv): +def test_benchmarks(env: CompilerEnv): assert list(env.datasets.benchmark_uris()) == [ "benchmark://loops-opt-v0/add", "benchmark://loops-opt-v0/offsets1", @@ -274,7 +274,7 @@ def test_benchmarks(env: ClientServiceCompilerEnv): ] -def test_fork(env: ClientServiceCompilerEnv): +def test_fork(env: CompilerEnv): env.reset() env.step(0) env.step(1) diff --git a/leaderboard/llvm_instcount/e_greedy/e_greedy.py b/leaderboard/llvm_instcount/e_greedy/e_greedy.py index e18cd3138..a61f015e8 100644 --- a/leaderboard/llvm_instcount/e_greedy/e_greedy.py +++ b/leaderboard/llvm_instcount/e_greedy/e_greedy.py @@ -10,7 +10,7 @@ from absl import flags -from compiler_gym.envs import ClientServiceCompilerEnv, LlvmEnv +from compiler_gym.envs import CompilerEnv, LlvmEnv from compiler_gym.leaderboard.llvm_instcount import eval_llvm_instcount_policy flags.DEFINE_float( @@ -27,12 +27,10 @@ class RewardAction(NamedTuple): action: int -def select_best_action( - env: ClientServiceCompilerEnv, executor: ThreadPoolExecutor -) -> RewardAction: +def select_best_action(env: CompilerEnv, executor: ThreadPoolExecutor) -> RewardAction: """Determine the best action by trying all possible options and ranking them.""" - def eval_action(fkd: ClientServiceCompilerEnv, action: int) -> RewardAction: + def eval_action(fkd: CompilerEnv, action: int) -> RewardAction: """Evaluate the given action.""" try: _, reward, _, _ = fkd.step(action) diff --git a/tests/llvm/all_actions_single_step_test.py b/tests/llvm/all_actions_single_step_test.py index 662036d83..33bfe3ca5 100644 --- a/tests/llvm/all_actions_single_step_test.py +++ b/tests/llvm/all_actions_single_step_test.py @@ -6,7 +6,7 @@ import numpy as np -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.service.connection import ServiceError from compiler_gym.third_party.autophase import AUTOPHASE_FEATURE_DIM from tests.test_main import main @@ -14,7 +14,7 @@ pytest_plugins = ["tests.pytest_plugins.llvm"] -def test_step(env: ClientServiceCompilerEnv, action_name: str): +def test_step(env: CompilerEnv, action_name: str): """Run each action on a single benchmark.""" env.reward_space = "IrInstructionCount" env.observation_space = "Autophase" diff --git a/tests/llvm/autophase_test.py b/tests/llvm/autophase_test.py index b557f47f8..a466a2957 100644 --- a/tests/llvm/autophase_test.py +++ b/tests/llvm/autophase_test.py @@ -3,13 +3,13 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. """Integrations tests for the LLVM CompilerGym environments.""" -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from tests.test_main import main pytest_plugins = ["tests.pytest_plugins.llvm"] -def test_autophase_crc32_feature_vector(env: ClientServiceCompilerEnv): +def test_autophase_crc32_feature_vector(env: CompilerEnv): env.reset(benchmark="cbench-v1/crc32") print(env.benchmark) # For debugging in case of error. features = env.observation["AutophaseDict"] diff --git a/tests/llvm/fresh_environment_observation_reward_test.py b/tests/llvm/fresh_environment_observation_reward_test.py index cdf265238..e9c140000 100644 --- a/tests/llvm/fresh_environment_observation_reward_test.py +++ b/tests/llvm/fresh_environment_observation_reward_test.py @@ -8,7 +8,7 @@ import pytest from flaky import flaky -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from tests.test_main import main pytest_plugins = ["tests.pytest_plugins.llvm"] @@ -19,7 +19,7 @@ reason="github.com/facebookresearch/CompilerGym/issues/459", ) @flaky # Runtime can timeout -def test_step(env: ClientServiceCompilerEnv, observation_space: str, reward_space: str): +def test_step(env: CompilerEnv, observation_space: str, reward_space: str): """Request every combination of observation and reward in a fresh environment.""" env.reward_space = None env.observation_space = None diff --git a/tests/llvm/llvm_benchmark_test.py b/tests/llvm/llvm_benchmark_test.py index d569ba381..337ab13c5 100644 --- a/tests/llvm/llvm_benchmark_test.py +++ b/tests/llvm/llvm_benchmark_test.py @@ -9,7 +9,7 @@ import pytest from compiler_gym.datasets import Benchmark -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.envs.llvm import llvm_benchmark from compiler_gym.service.proto import Benchmark as BenchmarkProto from compiler_gym.service.proto import File @@ -19,7 +19,7 @@ pytest_plugins = ["tests.pytest_plugins.llvm"] -def test_add_benchmark_invalid_scheme(env: ClientServiceCompilerEnv): +def test_add_benchmark_invalid_scheme(env: CompilerEnv): with pytest.raises(ValueError) as ctx: env.reset( benchmark=Benchmark( @@ -34,7 +34,7 @@ def test_add_benchmark_invalid_scheme(env: ClientServiceCompilerEnv): ) -def test_add_benchmark_invalid_path(env: ClientServiceCompilerEnv): +def test_add_benchmark_invalid_path(env: CompilerEnv): with tempfile.TemporaryDirectory() as d: tmp = Path(d) / "not_a_file" with pytest.raises(FileNotFoundError) as ctx: diff --git a/tests/llvm/llvm_env_test.py b/tests/llvm/llvm_env_test.py index 34322ffd9..36fe74bba 100644 --- a/tests/llvm/llvm_env_test.py +++ b/tests/llvm/llvm_env_test.py @@ -17,7 +17,7 @@ CompilerEnvStateReader, CompilerEnvStateWriter, ) -from compiler_gym.envs import ClientServiceCompilerEnv, llvm +from compiler_gym.envs import CompilerEnv, llvm from compiler_gym.envs.llvm.llvm_env import LlvmEnv from compiler_gym.service import ServiceError from compiler_gym.service.connection import CompilerGymServiceConnection @@ -28,7 +28,7 @@ @pytest.fixture(scope="function", params=["local", "service"]) -def env(request) -> ClientServiceCompilerEnv: +def env(request) -> CompilerEnv: """Create an LLVM environment.""" if request.param == "local": with gym.make("llvm-v0") as env: diff --git a/tests/llvm/observation_spaces_test.py b/tests/llvm/observation_spaces_test.py index c0a4692ec..865623787 100644 --- a/tests/llvm/observation_spaces_test.py +++ b/tests/llvm/observation_spaces_test.py @@ -1422,7 +1422,7 @@ def test_is_buildable_observation_space_not_buildable(env: LlvmEnv): def test_add_derived_space(env: LlvmEnv): env.reset() with pytest.deprecated_call( - match="Use the derived_observation_spaces argument to ClientServiceCompilerEnv constructor." + match="Use the derived_observation_spaces argument to CompilerEnv constructor." ): env.observation.add_derived_space( id="IrLen", diff --git a/tests/llvm/threading_test.py b/tests/llvm/threading_test.py index e7df23315..a347ffc6d 100644 --- a/tests/llvm/threading_test.py +++ b/tests/llvm/threading_test.py @@ -9,7 +9,7 @@ import gym from flaky import flaky -from compiler_gym import ClientServiceCompilerEnv +from compiler_gym import CompilerEnv from compiler_gym.util.gym_type_hints import ActionType from tests.test_main import main @@ -39,7 +39,7 @@ def run(self) -> None: class ThreadedWorkerWithEnv(Thread): """Create an environment and run through a set of actions in a background thread.""" - def __init__(self, env: ClientServiceCompilerEnv, actions: List[ActionType]): + def __init__(self, env: CompilerEnv, actions: List[ActionType]): super().__init__() self.done = False self.env = env From f760d426c5b49ef705e33777051e520228b235f6 Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Wed, 23 Mar 2022 17:47:07 -0700 Subject: [PATCH 06/16] Move ClientServiceCompilerEnv to service --- benchmarks/bench_test.py | 5 ++-- compiler_gym/BUILD | 2 +- compiler_gym/CMakeLists.txt | 2 +- compiler_gym/bin/service.py | 2 +- compiler_gym/envs/BUILD | 20 +++------------ compiler_gym/envs/CMakeLists.txt | 25 ++++--------------- compiler_gym/envs/__init__.py | 2 -- compiler_gym/envs/compiler_env.py | 2 +- compiler_gym/envs/gcc/BUILD | 2 +- compiler_gym/envs/gcc/CMakeLists.txt | 2 +- compiler_gym/envs/gcc/gcc_env.py | 2 +- compiler_gym/envs/llvm/BUILD | 2 +- compiler_gym/envs/llvm/CMakeLists.txt | 2 +- compiler_gym/envs/llvm/llvm_env.py | 2 +- compiler_gym/envs/loop_tool/BUILD | 2 +- compiler_gym/envs/loop_tool/CMakeLists.txt | 2 +- compiler_gym/envs/loop_tool/loop_tool_env.py | 2 +- compiler_gym/random_replay.py | 2 +- compiler_gym/service/BUILD | 20 +++++++++++++++ compiler_gym/service/CMakeLists.txt | 20 +++++++++++++++ .../client_service_compiler_env.py | 4 +-- compiler_gym/spaces/BUILD | 1 - compiler_gym/spaces/CMakeLists.txt | 1 - compiler_gym/validate.py | 2 +- .../example_compiler_gym_service/__init__.py | 4 +-- .../demo_without_bazel.py | 2 +- .../example_unrolling_service/__init__.py | 2 +- .../example_without_bazel.py | 2 +- .../llvm_autotuning/autotuners/opentuner_.py | 2 +- examples/llvm_rl/model/inference_result.py | 2 +- .../loop_optimizations_service/__init__.py | 2 +- .../loop_optimizations_service/env_tests.py | 3 ++- .../example_without_bazel.py | 2 +- examples/op_benchmarks.py | 2 +- tests/llvm/service_connection_test.py | 3 ++- 35 files changed, 82 insertions(+), 72 deletions(-) rename compiler_gym/{envs => service}/client_service_compiler_env.py (99%) diff --git a/benchmarks/bench_test.py b/benchmarks/bench_test.py index 3947b0071..497f73e53 100644 --- a/benchmarks/bench_test.py +++ b/benchmarks/bench_test.py @@ -23,6 +23,7 @@ import examples.example_compiler_gym_service as dummy from compiler_gym.envs import CompilerEnv, LlvmEnv, llvm from compiler_gym.service import CompilerGymServiceConnection +from compiler_gym.service.client_service_compiler_env import ClientServiceCompilerEnv from tests.pytest_plugins.llvm import OBSERVATION_SPACE_NAMES, REWARD_SPACE_NAMES from tests.test_main import main @@ -56,8 +57,8 @@ def test_make_local(benchmark, env_id): "args", [ (llvm.LLVM_SERVICE_BINARY, LlvmEnv), - (dummy.EXAMPLE_CC_SERVICE_BINARY, CompilerEnv), - (dummy.EXAMPLE_PY_SERVICE_BINARY, CompilerEnv), + (dummy.EXAMPLE_CC_SERVICE_BINARY, ClientServiceCompilerEnv), + (dummy.EXAMPLE_PY_SERVICE_BINARY, ClientServiceCompilerEnv), ], ids=["llvm", "dummy-cc", "dummy-py"], ) diff --git a/compiler_gym/BUILD b/compiler_gym/BUILD index 14c8cad55..0564b7343 100644 --- a/compiler_gym/BUILD +++ b/compiler_gym/BUILD @@ -67,7 +67,7 @@ py_library( deps = [ ":validation_error", ":validation_result", - "//compiler_gym/envs:client_service_compiler_env", + "//compiler_gym/service:client_service_compiler_env", "//compiler_gym/spaces", "//compiler_gym/util", ], diff --git a/compiler_gym/CMakeLists.txt b/compiler_gym/CMakeLists.txt index 736cb955c..83e115523 100644 --- a/compiler_gym/CMakeLists.txt +++ b/compiler_gym/CMakeLists.txt @@ -71,7 +71,7 @@ cg_py_library( DEPS ::validation_error ::validation_result - compiler_gym::envs::client_service_compiler_env + compiler_gym::service::client_service_compiler_env compiler_gym::spaces::spaces compiler_gym::util::util PUBLIC diff --git a/compiler_gym/bin/service.py b/compiler_gym/bin/service.py index 9fbdc8ad6..8474c9af9 100644 --- a/compiler_gym/bin/service.py +++ b/compiler_gym/bin/service.py @@ -103,7 +103,7 @@ from absl import app, flags from compiler_gym.datasets import Dataset -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.service.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.service.connection import ConnectionOpts from compiler_gym.spaces import Commandline, NamedDiscrete from compiler_gym.util.flags.env_from_flags import env_from_flags diff --git a/compiler_gym/envs/BUILD b/compiler_gym/envs/BUILD index 0c85f0910..525d52a69 100644 --- a/compiler_gym/envs/BUILD +++ b/compiler_gym/envs/BUILD @@ -9,7 +9,7 @@ py_library( srcs = ["__init__.py"], visibility = ["//visibility:public"], deps = [ - ":client_service_compiler_env", + ":compiler_env", "//compiler_gym/envs/gcc", "//compiler_gym/envs/llvm", "//compiler_gym/envs/loop_tool", @@ -17,27 +17,13 @@ py_library( ) py_library( - name = "client_service_compiler_env", - srcs = ["client_service_compiler_env.py"], + name = "compiler_env", + srcs = ["compiler_env.py"], visibility = ["//compiler_gym:__subpackages__"], deps = [ - ":compiler_env", "//compiler_gym:compiler_env_state", "//compiler_gym:validation_result", "//compiler_gym/datasets", - "//compiler_gym/service", - "//compiler_gym/service/proto", - "//compiler_gym/spaces", - "//compiler_gym/util", - "//compiler_gym/views", - ], -) - -py_library( - name = "compiler_env", - srcs = ["compiler_env.py"], - visibility = ["//compiler_gym:__subpackages__"], - deps = [ "//compiler_gym/spaces", "//compiler_gym/util", "//compiler_gym/views", diff --git a/compiler_gym/envs/CMakeLists.txt b/compiler_gym/envs/CMakeLists.txt index 591054737..1962603e5 100644 --- a/compiler_gym/envs/CMakeLists.txt +++ b/compiler_gym/envs/CMakeLists.txt @@ -11,7 +11,7 @@ cg_py_library( SRCS "__init__.py" DEPS - ::client_service_compiler_env + ::compiler_env compiler_gym::envs::gcc::gcc compiler_gym::envs::llvm::llvm compiler_gym::envs::loop_tool::loop_tool @@ -20,30 +20,15 @@ cg_py_library( cg_py_library( NAME - client_service_compiler_env - SRCS - "client_service_compiler_env.py" - DEPS - ::env_py - compiler_gym::compiler_env_state - compiler_gym::datasets::datasets - compiler_gym::service::service - compiler_gym::service::proto::proto - compiler_gym::spaces::spaces - compiler_gym::util::util - compiler_gym::validation_result - compiler_gym::views::views - PUBLIC -) - -cg_py_library( - NAME - env_py + compiler_env SRCS "compiler_env.py" DEPS compiler_gym::spaces::spaces compiler_gym::util::util compiler_gym::views::views + compiler_gym::compiler_env_state + compiler_gym::validation_result + compiler_gym::datasets::datasets PUBLIC ) diff --git a/compiler_gym/envs/__init__.py b/compiler_gym/envs/__init__.py index 292433647..33dd765e8 100644 --- a/compiler_gym/envs/__init__.py +++ b/compiler_gym/envs/__init__.py @@ -2,7 +2,6 @@ # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -from compiler_gym.envs.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.envs.compiler_env import CompilerEnv from compiler_gym.envs.gcc import GccEnv from compiler_gym.envs.llvm.llvm_env import LlvmEnv @@ -11,7 +10,6 @@ __all__ = [ "COMPILER_GYM_ENVS", - "ClientServiceCompilerEnv", "CompilerEnv", "GccEnv", "LlvmEnv", diff --git a/compiler_gym/envs/compiler_env.py b/compiler_gym/envs/compiler_env.py index 117e73615..763f3c7e5 100644 --- a/compiler_gym/envs/compiler_env.py +++ b/compiler_gym/envs/compiler_env.py @@ -79,7 +79,7 @@ def datasets(self, datasets: Iterable[Dataset]): @abstractmethod def episode_walltime(self) -> float: """Return the amount of time in seconds since the last call to - :meth:`reset() `. + :meth:`reset() `. """ raise NotImplementedError("abstract method") diff --git a/compiler_gym/envs/gcc/BUILD b/compiler_gym/envs/gcc/BUILD index b8df99ff8..f6727ce44 100644 --- a/compiler_gym/envs/gcc/BUILD +++ b/compiler_gym/envs/gcc/BUILD @@ -17,9 +17,9 @@ py_library( ], visibility = ["//visibility:public"], deps = [ - "//compiler_gym/envs:client_service_compiler_env", "//compiler_gym/envs/gcc/datasets", "//compiler_gym/service", + "//compiler_gym/service:client_service_compiler_env", "//compiler_gym/service/runtime", # Implicit dependency of service. "//compiler_gym/util", ], diff --git a/compiler_gym/envs/gcc/CMakeLists.txt b/compiler_gym/envs/gcc/CMakeLists.txt index 7146c14de..386bd1d08 100644 --- a/compiler_gym/envs/gcc/CMakeLists.txt +++ b/compiler_gym/envs/gcc/CMakeLists.txt @@ -16,7 +16,7 @@ cg_py_library( DATA compiler_gym::envs::gcc::service::service DEPS - compiler_gym::envs::client_service_compiler_env + compiler_gym::service::client_service_compiler_env compiler_gym::envs::gcc::datasets::datasets compiler_gym::service::service compiler_gym::service::runtime::runtime diff --git a/compiler_gym/envs/gcc/gcc_env.py b/compiler_gym/envs/gcc/gcc_env.py index 65e70a09a..993f1155b 100644 --- a/compiler_gym/envs/gcc/gcc_env.py +++ b/compiler_gym/envs/gcc/gcc_env.py @@ -10,11 +10,11 @@ from typing import Any, Dict, List, Optional, Union from compiler_gym.datasets import Benchmark -from compiler_gym.envs.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.envs.gcc.datasets import get_gcc_datasets from compiler_gym.envs.gcc.gcc import Gcc, GccSpec from compiler_gym.envs.gcc.gcc_rewards import AsmSizeReward, ObjSizeReward from compiler_gym.service import ConnectionOpts +from compiler_gym.service.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.util.decorators import memoized_property from compiler_gym.util.gym_type_hints import ObservationType diff --git a/compiler_gym/envs/llvm/BUILD b/compiler_gym/envs/llvm/BUILD index b7d6fa091..7bf5b1096 100644 --- a/compiler_gym/envs/llvm/BUILD +++ b/compiler_gym/envs/llvm/BUILD @@ -48,8 +48,8 @@ py_library( ":llvm_benchmark", ":llvm_rewards", "//compiler_gym/datasets", - "//compiler_gym/envs:client_service_compiler_env", "//compiler_gym/envs/llvm/datasets", + "//compiler_gym/service:client_service_compiler_env", "//compiler_gym/spaces", "//compiler_gym/third_party/autophase", "//compiler_gym/third_party/inst2vec", diff --git a/compiler_gym/envs/llvm/CMakeLists.txt b/compiler_gym/envs/llvm/CMakeLists.txt index 346248937..5d04526ee 100644 --- a/compiler_gym/envs/llvm/CMakeLists.txt +++ b/compiler_gym/envs/llvm/CMakeLists.txt @@ -50,7 +50,7 @@ cg_py_library( ::llvm_benchmark ::llvm_rewards compiler_gym::datasets::datasets - compiler_gym::envs::client_service_compiler_env + compiler_gym::service::client_service_compiler_env compiler_gym::envs::llvm::datasets::datasets compiler_gym::spaces::spaces compiler_gym::third_party::autophase::autophase diff --git a/compiler_gym/envs/llvm/llvm_env.py b/compiler_gym/envs/llvm/llvm_env.py index 168c8c570..a9d291a1a 100644 --- a/compiler_gym/envs/llvm/llvm_env.py +++ b/compiler_gym/envs/llvm/llvm_env.py @@ -11,7 +11,6 @@ import numpy as np from compiler_gym.datasets import Benchmark, BenchmarkInitError, Dataset -from compiler_gym.envs.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.envs.llvm.datasets import get_llvm_datasets from compiler_gym.envs.llvm.llvm_benchmark import ClangInvocation, make_benchmark from compiler_gym.envs.llvm.llvm_rewards import ( @@ -19,6 +18,7 @@ CostFunctionReward, NormalizedReward, ) +from compiler_gym.service.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.spaces import Box, Commandline from compiler_gym.spaces import Dict as DictSpace from compiler_gym.spaces import Scalar, Sequence diff --git a/compiler_gym/envs/loop_tool/BUILD b/compiler_gym/envs/loop_tool/BUILD index c7345c47b..61ad772e9 100644 --- a/compiler_gym/envs/loop_tool/BUILD +++ b/compiler_gym/envs/loop_tool/BUILD @@ -13,8 +13,8 @@ py_library( data = ["//compiler_gym/envs/loop_tool/service"], visibility = ["//visibility:public"], deps = [ - "//compiler_gym/envs:client_service_compiler_env", "//compiler_gym/service", + "//compiler_gym/service:client_service_compiler_env", "//compiler_gym/service/proto", "//compiler_gym/service/runtime", ], diff --git a/compiler_gym/envs/loop_tool/CMakeLists.txt b/compiler_gym/envs/loop_tool/CMakeLists.txt index abbcb3f83..f04f82442 100644 --- a/compiler_gym/envs/loop_tool/CMakeLists.txt +++ b/compiler_gym/envs/loop_tool/CMakeLists.txt @@ -12,7 +12,7 @@ cg_py_library( "loop_tool_env.py" DATA compiler_gym::envs::loop_tool::service::service DEPS - compiler_gym::envs::client_service_compiler_env + compiler_gym::service::client_service_compiler_env compiler_gym::service::service compiler_gym::service::proto::proto compiler_gym::service::runtime::runtime diff --git a/compiler_gym/envs/loop_tool/loop_tool_env.py b/compiler_gym/envs/loop_tool/loop_tool_env.py index 089d10cff..e21d04208 100644 --- a/compiler_gym/envs/loop_tool/loop_tool_env.py +++ b/compiler_gym/envs/loop_tool/loop_tool_env.py @@ -2,7 +2,7 @@ # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. -from compiler_gym.envs.client_service_compiler_env import ClientServiceCompilerEnv +from compiler_gym.service.client_service_compiler_env import ClientServiceCompilerEnv class LoopToolEnv(ClientServiceCompilerEnv): diff --git a/compiler_gym/random_replay.py b/compiler_gym/random_replay.py index b342e1be2..3e5f86d8c 100644 --- a/compiler_gym/random_replay.py +++ b/compiler_gym/random_replay.py @@ -8,7 +8,7 @@ from deprecated import deprecated -from compiler_gym.envs.client_service_compiler_env import CompilerEnv +from compiler_gym import CompilerEnv from compiler_gym.random_search import replay_actions as replay_actions_ from compiler_gym.random_search import ( replay_actions_from_logs as replay_actions_from_logs_, diff --git a/compiler_gym/service/BUILD b/compiler_gym/service/BUILD index 280d508eb..32c1722e3 100644 --- a/compiler_gym/service/BUILD +++ b/compiler_gym/service/BUILD @@ -12,6 +12,8 @@ py_library( deps = [ ":compilation_session", ":connection", + # TODO: add this after circular dependencies are resolved + # ":client_service_compiler_env", "//compiler_gym/service/proto", ], ) @@ -46,3 +48,21 @@ py_library( "//compiler_gym/util", ], ) + +py_library( + name = "client_service_compiler_env", + srcs = ["client_service_compiler_env.py"], + visibility = ["//compiler_gym:__subpackages__"], + deps = [ + ":compilation_session", + ":connection", + "//compiler_gym:compiler_env_state", + "//compiler_gym:validation_result", + "//compiler_gym/datasets", + "//compiler_gym/envs:compiler_env", + "//compiler_gym/service/proto", + "//compiler_gym/spaces", + "//compiler_gym/util", + "//compiler_gym/views", + ], +) diff --git a/compiler_gym/service/CMakeLists.txt b/compiler_gym/service/CMakeLists.txt index 9ad17ae9c..060a46376 100644 --- a/compiler_gym/service/CMakeLists.txt +++ b/compiler_gym/service/CMakeLists.txt @@ -13,6 +13,8 @@ cg_py_library( DEPS ::compilation_session ::connection + # TODO: add this after circular dependencies are resolved + #::client_service_compiler_env compiler_gym::service::proto::proto PUBLIC ) @@ -52,3 +54,21 @@ cg_py_library( compiler_gym::util::util PUBLIC ) + +cg_py_library( + NAME + client_service_compiler_env + SRCS + "client_service_compiler_env.py" + DEPS + compiler_gym::envs::compiler_env + compiler_gym::compiler_env_state + compiler_gym::datasets::datasets + compiler_gym::service::service + compiler_gym::service::proto::proto + compiler_gym::spaces::spaces + compiler_gym::util::util + compiler_gym::validation_result + compiler_gym::views::views + PUBLIC +) diff --git a/compiler_gym/envs/client_service_compiler_env.py b/compiler_gym/service/client_service_compiler_env.py similarity index 99% rename from compiler_gym/envs/client_service_compiler_env.py rename to compiler_gym/service/client_service_compiler_env.py index 5020b55fc..ff9b92d70 100644 --- a/compiler_gym/envs/client_service_compiler_env.py +++ b/compiler_gym/service/client_service_compiler_env.py @@ -230,7 +230,7 @@ def __init__( warnings.warn( "The `logger` argument is deprecated on ClientServiceCompilerEnv.__init__() " "and will be removed in a future release. All ClientServiceCompilerEnv " - "instances share a logger named compiler_gym.envs.client_service_compiler_env", + "instances share a logger named compiler_gym.service.client_service_compiler_env", DeprecationWarning, ) @@ -380,7 +380,7 @@ def actions(self) -> List[ActionType]: version="0.2.1", reason=( "The `ClientServiceCompilerEnv.logger` attribute is deprecated. All ClientServiceCompilerEnv " - "instances share a logger named compiler_gym.envs.client_service_compiler_env" + "instances share a logger named compiler_gym.service.client_service_compiler_env" ), ) def logger(self): diff --git a/compiler_gym/spaces/BUILD b/compiler_gym/spaces/BUILD index 0a77e981b..683272c17 100644 --- a/compiler_gym/spaces/BUILD +++ b/compiler_gym/spaces/BUILD @@ -69,7 +69,6 @@ py_library( srcs = ["reward.py"], deps = [ ":scalar", - "//compiler_gym/service", "//compiler_gym/util", ], ) diff --git a/compiler_gym/spaces/CMakeLists.txt b/compiler_gym/spaces/CMakeLists.txt index 763a996b6..6bba6af76 100644 --- a/compiler_gym/spaces/CMakeLists.txt +++ b/compiler_gym/spaces/CMakeLists.txt @@ -71,7 +71,6 @@ cg_py_library( "reward.py" DEPS ::scalar - compiler_gym::service::service compiler_gym::util::util PUBLIC ) diff --git a/compiler_gym/validate.py b/compiler_gym/validate.py index 5f897ffb9..b9ac7bb4b 100644 --- a/compiler_gym/validate.py +++ b/compiler_gym/validate.py @@ -8,7 +8,7 @@ from typing import Callable, Iterable, Optional from compiler_gym.compiler_env_state import CompilerEnvState -from compiler_gym.envs.client_service_compiler_env import CompilerEnv +from compiler_gym.envs.compiler_env import CompilerEnv from compiler_gym.util import thread_pool from compiler_gym.validation_result import ValidationResult diff --git a/examples/example_compiler_gym_service/__init__.py b/examples/example_compiler_gym_service/__init__.py index 60680b829..546cea3d4 100644 --- a/examples/example_compiler_gym_service/__init__.py +++ b/examples/example_compiler_gym_service/__init__.py @@ -83,7 +83,7 @@ def benchmark_from_parsed_uri(self, uri: BenchmarkUri) -> Benchmark: # the example-v0 environment will be available to gym.make(...). register( id="example-cc-v0", - entry_point="compiler_gym.envs:ClientServiceCompilerEnv", + entry_point="compiler_gym.service.client_service_compiler_env:ClientServiceCompilerEnv", kwargs={ "service": EXAMPLE_CC_SERVICE_BINARY, "rewards": [RuntimeReward()], @@ -93,7 +93,7 @@ def benchmark_from_parsed_uri(self, uri: BenchmarkUri) -> Benchmark: register( id="example-py-v0", - entry_point="compiler_gym.envs:ClientServiceCompilerEnv", + entry_point="compiler_gym.service.client_service_compiler_env:ClientServiceCompilerEnv", kwargs={ "service": EXAMPLE_PY_SERVICE_BINARY, "rewards": [RuntimeReward()], diff --git a/examples/example_compiler_gym_service/demo_without_bazel.py b/examples/example_compiler_gym_service/demo_without_bazel.py index e6dc81b4e..64dcf320a 100644 --- a/examples/example_compiler_gym_service/demo_without_bazel.py +++ b/examples/example_compiler_gym_service/demo_without_bazel.py @@ -88,7 +88,7 @@ def benchmark_from_parsed_uri(self, uri: BenchmarkUri) -> Benchmark: # Register the environment for use with gym.make(...). register( id="example-v0", - entry_point="compiler_gym.envs:ClientServiceCompilerEnv", + entry_point="compiler_gym.service.client_service_compiler_env:ClientServiceCompilerEnv", kwargs={ "service": EXAMPLE_PY_SERVICE_BINARY, "rewards": [RuntimeReward()], diff --git a/examples/example_unrolling_service/__init__.py b/examples/example_unrolling_service/__init__.py index 16f2f705d..409d405c1 100644 --- a/examples/example_unrolling_service/__init__.py +++ b/examples/example_unrolling_service/__init__.py @@ -135,7 +135,7 @@ def benchmark_from_parsed_uri(self, uri: BenchmarkUri) -> Benchmark: register( id="unrolling-py-v0", - entry_point="compiler_gym.envs:ClientServiceCompilerEnv", + entry_point="compiler_gym.service.client_service_compiler_env:ClientServiceCompilerEnv", kwargs={ "service": UNROLLING_PY_SERVICE_BINARY, "rewards": [RuntimeReward(), SizeReward()], diff --git a/examples/example_unrolling_service/example_without_bazel.py b/examples/example_unrolling_service/example_without_bazel.py index b9a32c106..d07dae288 100644 --- a/examples/example_unrolling_service/example_without_bazel.py +++ b/examples/example_unrolling_service/example_without_bazel.py @@ -145,7 +145,7 @@ def benchmark_from_parsed_uri(self, uri: BenchmarkUri) -> Benchmark: register( id="unrolling-py-v0", - entry_point="compiler_gym.envs:ClientServiceCompilerEnv", + entry_point="compiler_gym.service.client_service_compiler_env:ClientServiceCompilerEnv", kwargs={ "service": UNROLLING_PY_SERVICE_BINARY, "rewards": [RuntimeReward(), SizeReward()], diff --git a/examples/llvm_autotuning/autotuners/opentuner_.py b/examples/llvm_autotuning/autotuners/opentuner_.py index d7dec0aa3..932169ddb 100644 --- a/examples/llvm_autotuning/autotuners/opentuner_.py +++ b/examples/llvm_autotuning/autotuners/opentuner_.py @@ -11,8 +11,8 @@ import numpy as np from llvm_autotuning.optimization_target import OptimizationTarget -from compiler_gym.envs import ClientServiceCompilerEnv from compiler_gym.envs.llvm import compute_observation +from compiler_gym.service.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.service.connection import ServiceError from compiler_gym.third_party.llvm import opt_path from compiler_gym.util.runfiles_path import transient_cache_path diff --git a/examples/llvm_rl/model/inference_result.py b/examples/llvm_rl/model/inference_result.py index e6da85066..8e2c651cb 100644 --- a/examples/llvm_rl/model/inference_result.py +++ b/examples/llvm_rl/model/inference_result.py @@ -12,7 +12,7 @@ from ray.rllib.agents.ppo import PPOTrainer # noqa from compiler_gym.datasets import BenchmarkUri -from compiler_gym.envs import ClientServiceCompilerEnv +from compiler_gym.service.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.util.timer import Timer logger = logging.getLogger(__name__) diff --git a/examples/loop_optimizations_service/__init__.py b/examples/loop_optimizations_service/__init__.py index 348284a67..9e60c49d1 100644 --- a/examples/loop_optimizations_service/__init__.py +++ b/examples/loop_optimizations_service/__init__.py @@ -137,7 +137,7 @@ def benchmark_from_parsed_uri(self, uri: BenchmarkUri) -> Benchmark: register( id="loops-opt-py-v0", - entry_point="compiler_gym.envs:ClientServiceCompilerEnv", + entry_point="compiler_gym.service.client_service_compiler_env:ClientServiceCompilerEnv", kwargs={ "service": LOOPS_OPT_PY_SERVICE_BINARY, "rewards": [RuntimeReward(), SizeReward()], diff --git a/examples/loop_optimizations_service/env_tests.py b/examples/loop_optimizations_service/env_tests.py index 8b4aacadd..376cb00bb 100644 --- a/examples/loop_optimizations_service/env_tests.py +++ b/examples/loop_optimizations_service/env_tests.py @@ -12,8 +12,9 @@ import compiler_gym import examples.loop_optimizations_service as loop_optimizations_service -from compiler_gym.envs import ClientServiceCompilerEnv, CompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.service import SessionNotFound +from compiler_gym.service.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.spaces import Dict, NamedDiscrete, Scalar, Sequence from compiler_gym.third_party.autophase import AUTOPHASE_FEATURE_NAMES from tests.test_main import main diff --git a/examples/loop_optimizations_service/example_without_bazel.py b/examples/loop_optimizations_service/example_without_bazel.py index f8e5bcf97..c1edfe0c9 100644 --- a/examples/loop_optimizations_service/example_without_bazel.py +++ b/examples/loop_optimizations_service/example_without_bazel.py @@ -147,7 +147,7 @@ def benchmark_from_parsed_uri(self, uri: BenchmarkUri) -> Benchmark: register( id="loops-opt-py-v0", - entry_point="compiler_gym.envs:ClientServiceCompilerEnv", + entry_point="compiler_gym.service.client_service_compiler_env:ClientServiceCompilerEnv", kwargs={ "service": LOOPS_OPT_PY_SERVICE_BINARY, "rewards": [RuntimeReward(), SizeReward()], diff --git a/examples/op_benchmarks.py b/examples/op_benchmarks.py index 27e363ac1..819e6358d 100644 --- a/examples/op_benchmarks.py +++ b/examples/op_benchmarks.py @@ -28,8 +28,8 @@ from tabulate import tabulate import compiler_gym +from compiler_gym import CompilerEnv from compiler_gym.datasets import BenchmarkInitError -from compiler_gym.envs.client_service_compiler_env import CompilerEnv from compiler_gym.util.executor import Executor from compiler_gym.util.logging import init_logging from compiler_gym.util.runfiles_path import create_user_logs_dir diff --git a/tests/llvm/service_connection_test.py b/tests/llvm/service_connection_test.py index 1206c1016..0ae2e22bb 100644 --- a/tests/llvm/service_connection_test.py +++ b/tests/llvm/service_connection_test.py @@ -8,9 +8,10 @@ import pytest import compiler_gym # noqa Register environments. -from compiler_gym.envs import ClientServiceCompilerEnv, llvm +from compiler_gym.envs import llvm from compiler_gym.envs.llvm.llvm_env import LlvmEnv from compiler_gym.service import ServiceError +from compiler_gym.service.client_service_compiler_env import ClientServiceCompilerEnv from compiler_gym.service.connection import CompilerGymServiceConnection from compiler_gym.third_party.autophase import AUTOPHASE_FEATURE_DIM from tests.test_main import main From 621cace4ce1d78ba21b8b21683e4a1ddd61834ad Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Wed, 23 Mar 2022 18:21:59 -0700 Subject: [PATCH 07/16] Edit documentation for CompilerEnv and ClientServiceCompilerEnv --- compiler_gym/envs/compiler_env.py | 37 ++++++++++++++++++ .../service/client_service_compiler_env.py | 38 ++----------------- 2 files changed, 40 insertions(+), 35 deletions(-) diff --git a/compiler_gym/envs/compiler_env.py b/compiler_gym/envs/compiler_env.py index 763f3c7e5..af9ce4f6c 100644 --- a/compiler_gym/envs/compiler_env.py +++ b/compiler_gym/envs/compiler_env.py @@ -18,6 +18,42 @@ class CompilerEnv(gym.Env, ABC): + """An OpenAI gym environment for compiler optimizations. + + The easiest way to create a CompilerGym environment is to call + :code:`gym.make()` on one of the registered environments: + + >>> env = gym.make("llvm-v0") + + See :code:`compiler_gym.COMPILER_GYM_ENVS` for a list of registered + environment names. + + Alternatively, an environment can be constructed directly, such as by + connecting to a running compiler service at :code:`localhost:8080` (see + :doc:`this document ` for more details): + + >>> env = ClientServiceCompilerEnv( + ... service="localhost:8080", + ... observation_space="features", + ... reward_space="runtime", + ... rewards=[env_reward_spaces], + ... ) + + Once constructed, an environment can be used in exactly the same way as a + regular :code:`gym.Env`, e.g. + + >>> observation = env.reset() + >>> cumulative_reward = 0 + >>> for i in range(100): + >>> action = env.action_space.sample() + >>> observation, reward, done, info = env.step(action) + >>> cumulative_reward += reward + >>> if done: + >>> break + >>> print(f"Reward after {i} steps: {cumulative_reward}") + Reward after 100 steps: -0.32123 + """ + @property @abstractmethod def observation_space_spec(self) -> ObservationSpaceSpec: @@ -233,6 +269,7 @@ def step( """ raise NotImplementedError("abstract method") + @abstractmethod def multistep( self, actions: Iterable[ActionType], diff --git a/compiler_gym/service/client_service_compiler_env.py b/compiler_gym/service/client_service_compiler_env.py index ff9b92d70..51be66f58 100644 --- a/compiler_gym/service/client_service_compiler_env.py +++ b/compiler_gym/service/client_service_compiler_env.py @@ -2,7 +2,8 @@ # # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. - +"""Contains an implementation of the :class:`CompilerEnv` +interface as a gRPC client service.""" import logging import numbers import warnings @@ -82,40 +83,7 @@ def _wrapped_step( class ClientServiceCompilerEnv(CompilerEnv): - """An OpenAI gym environment for compiler optimizations. - - The easiest way to create a CompilerGym environment is to call - :code:`gym.make()` on one of the registered environments: - - >>> env = gym.make("llvm-v0") - - See :code:`compiler_gym.COMPILER_GYM_ENVS` for a list of registered - environment names. - - Alternatively, an environment can be constructed directly, such as by - connecting to a running compiler service at :code:`localhost:8080` (see - :doc:`this document ` for more details): - - >>> env = ClientServiceCompilerEnv( - ... service="localhost:8080", - ... observation_space="features", - ... reward_space="runtime", - ... rewards=[env_reward_spaces], - ... ) - - Once constructed, an environment can be used in exactly the same way as a - regular :code:`gym.Env`, e.g. - - >>> observation = env.reset() - >>> cumulative_reward = 0 - >>> for i in range(100): - >>> action = env.action_space.sample() - >>> observation, reward, done, info = env.step(action) - >>> cumulative_reward += reward - >>> if done: - >>> break - >>> print(f"Reward after {i} steps: {cumulative_reward}") - Reward after 100 steps: -0.32123 + """Implementation using gRPC for a client-server communication. :ivar service: A connection to the underlying compiler service. From 2acd700df477a284e67128df2220722c9dfadd72 Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Thu, 24 Mar 2022 08:24:35 -0700 Subject: [PATCH 08/16] Remove duplicate benchmark property from ClientServiceCompilerEnv --- compiler_gym/service/client_service_compiler_env.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/compiler_gym/service/client_service_compiler_env.py b/compiler_gym/service/client_service_compiler_env.py index 51be66f58..6e88cd8af 100644 --- a/compiler_gym/service/client_service_compiler_env.py +++ b/compiler_gym/service/client_service_compiler_env.py @@ -315,14 +315,6 @@ def reward_space_spec(self) -> Optional[Reward]: def reward_space_spec(self, val: Optional[Reward]): self._reward_space_spec = val - @property - def benchmark(self) -> Benchmark: - return self._benchmark - - @benchmark.setter - def benchmark(self, benchmark: Optional[Union[str, Benchmark, BenchmarkUri]]): - self._benchmark = benchmark - @property def datasets(self) -> Iterable[Dataset]: return self._datasets From 2b041d61368c2e06e2523e6448cb3d335e3e3680 Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Fri, 25 Mar 2022 08:53:22 -0700 Subject: [PATCH 09/16] Add missing methods to CompilerEnv --- compiler_gym/envs/compiler_env.py | 73 ++++++++++++++++++- compiler_gym/random_replay.py | 2 +- .../service/client_service_compiler_env.py | 24 ++++++ compiler_gym/wrappers/core.py | 61 ++++++++++++++-- tests/wrappers/core_wrappers_test.py | 50 +++++++++---- 5 files changed, 186 insertions(+), 24 deletions(-) diff --git a/compiler_gym/envs/compiler_env.py b/compiler_gym/envs/compiler_env.py index af9ce4f6c..7f6874612 100644 --- a/compiler_gym/envs/compiler_env.py +++ b/compiler_gym/envs/compiler_env.py @@ -7,6 +7,7 @@ from typing import Iterable, List, Optional, Union import gym +from deprecated.sphinx import deprecated from gym.spaces import Space from compiler_gym.compiler_env_state import CompilerEnvState @@ -14,7 +15,7 @@ from compiler_gym.spaces import Reward from compiler_gym.util.gym_type_hints import ActionType, ObservationType, StepType from compiler_gym.validation_result import ValidationResult -from compiler_gym.views import ObservationSpaceSpec +from compiler_gym.views import ObservationSpaceSpec, ObservationView, RewardView class CompilerEnv(gym.Env, ABC): @@ -144,6 +145,26 @@ def episode_reward(self, episode_reward: Optional[float]): def actions(self) -> List[ActionType]: raise NotImplementedError("abstract method") + @property + @abstractmethod + @deprecated( + version="0.2.1", + ) + def logger(self): + raise NotImplementedError("abstract method") + + @property + @abstractmethod + def version(self) -> str: + """The version string of the compiler service.""" + raise NotImplementedError("abstract method") + + @property + @abstractmethod + def compiler_version(self) -> str: + """The version string of the underlying compiler that this service supports.""" + raise NotImplementedError("abstract method") + @property @abstractmethod def state(self) -> CompilerEnvState: @@ -167,6 +188,17 @@ def action_space(self) -> Space: def action_space(self, action_space: Optional[str]): raise NotImplementedError("abstract method") + @property + @abstractmethod + def action_spaces(self) -> List[str]: + """A list of supported action space names.""" + raise NotImplementedError("abstract method") + + @action_spaces.setter + @abstractmethod + def action_spaces(self, action_spaces: List[str]): + raise NotImplementedError("abstract method") + @property @abstractmethod def reward_space(self) -> Optional[Reward]: @@ -203,6 +235,32 @@ def observation_space( ) -> None: raise NotImplementedError("abstract method") + @property + @abstractmethod + def observation(self) -> ObservationView: + """A view of the available observation spaces that permits + on-demand computation of observations. + """ + raise NotImplementedError("abstract method") + + @observation.setter + @abstractmethod + def observation(self, observation: ObservationView) -> None: + raise NotImplementedError("abstract method") + + @property + @abstractmethod + def reward(self) -> RewardView: + """A view of the available reward spaces that permits on-demand + computation of rewards. + """ + raise NotImplementedError("abstract method") + + @reward.setter + @abstractmethod + def reward(self, reward: RewardView) -> None: + raise NotImplementedError("abstract method") + @abstractmethod def fork(self) -> "CompilerEnv": """Fork a new environment with exactly the same state. @@ -298,6 +356,19 @@ def multistep( """ raise NotImplementedError("abstract method") + @abstractmethod + def render( + self, + mode="human", + ) -> Optional[str]: + """Render the environment. + + :param mode: The render mode to use. + :raises TypeError: If a default observation space is not set, or if the + requested render mode does not exist. + """ + raise NotImplementedError("abstract method") + @abstractmethod def commandline(self) -> str: """Interface for :class:`CompilerEnv ` diff --git a/compiler_gym/random_replay.py b/compiler_gym/random_replay.py index 3e5f86d8c..81be67ba2 100644 --- a/compiler_gym/random_replay.py +++ b/compiler_gym/random_replay.py @@ -8,7 +8,7 @@ from deprecated import deprecated -from compiler_gym import CompilerEnv +from compiler_gym.envs.compiler_env import CompilerEnv from compiler_gym.random_search import replay_actions as replay_actions_ from compiler_gym.random_search import ( replay_actions_from_logs as replay_actions_from_logs_, diff --git a/compiler_gym/service/client_service_compiler_env.py b/compiler_gym/service/client_service_compiler_env.py index 6e88cd8af..0bd449d1e 100644 --- a/compiler_gym/service/client_service_compiler_env.py +++ b/compiler_gym/service/client_service_compiler_env.py @@ -307,6 +307,14 @@ def observation_space_spec( ): self._observation_space_spec = observation_space_spec + @property + def observation(self) -> ObservationView: + return self._observation + + @observation.setter + def observation(self, observation: ObservationView) -> None: + self._observation = observation + @property def reward_space_spec(self) -> Optional[Reward]: return self._reward_space_spec @@ -406,6 +414,14 @@ def action_space(self, action_space: Optional[str]): ) self._action_space: NamedDiscrete = self.action_spaces[index] + @property + def action_spaces(self) -> List[str]: + return self._action_spaces + + @action_spaces.setter + def action_spaces(self, action_spaces: List[str]): + self._action_spaces = action_spaces + @property def benchmark(self) -> Benchmark: return self._benchmark_in_use @@ -463,6 +479,14 @@ def reward_space(self, reward_space: Optional[Union[str, Reward]]) -> None: self.reward_space_spec = None self.reward_range = (-np.inf, np.inf) + @property + def reward(self) -> RewardView: + return self._reward + + @reward.setter + def reward(self, reward: RewardView) -> None: + self._reward = reward + @property def in_episode(self) -> bool: return self._session_id is not None diff --git a/compiler_gym/wrappers/core.py b/compiler_gym/wrappers/core.py index 74550f967..5ce4ef1a2 100644 --- a/compiler_gym/wrappers/core.py +++ b/compiler_gym/wrappers/core.py @@ -3,6 +3,7 @@ # This source code is licensed under the MIT license found in the # LICENSE file in the root directory of this source tree. import warnings +from abc import ABC, abstractmethod from collections.abc import Iterable as IterableType from typing import Any, Iterable, List, Optional, Tuple, Union @@ -15,7 +16,7 @@ from compiler_gym.spaces.reward import Reward from compiler_gym.util.gym_type_hints import ActionType, ObservationType from compiler_gym.validation_result import ValidationResult -from compiler_gym.views import ObservationSpaceSpec +from compiler_gym.views import ObservationSpaceSpec, ObservationView, RewardView class CompilerEnvWrapper(CompilerEnv, Wrapper): @@ -116,6 +117,12 @@ def multistep( reward_spaces=reward_spaces, ) + def render( + self, + mode="human", + ) -> Optional[str]: + return self.env.render(mode) + @property def reward_range(self) -> Tuple[float, float]: return self.env.reward_range @@ -134,6 +141,14 @@ def observation_space( ) -> None: self.env.observation_space = observation_space + @property + def observation(self) -> ObservationView: + return self.env.observation + + @observation.setter + def observation(self, observation: ObservationView) -> None: + self.env.observation = observation + @property def observation_space_spec(self): return self.env.observation_space_spec @@ -160,6 +175,14 @@ def reward_space(self) -> Optional[Reward]: def reward_space(self, reward_space: Optional[Union[str, Reward]]) -> None: self.env.reward_space = reward_space + @property + def reward(self) -> RewardView: + return self.env.reward + + @reward.setter + def reward(self, reward: RewardView) -> None: + self.env.reward = reward + @property def action_space(self) -> Space: return self.env.action_space @@ -168,6 +191,14 @@ def action_space(self) -> Space: def action_space(self, action_space: Optional[str]): self.env.action_space = action_space + @property + def action_spaces(self) -> List[str]: + return self.env.action_spaces + + @action_spaces.setter + def action_spaces(self, action_spaces: List[str]): + self.env.action_spaces = action_spaces + @property def spec(self) -> Any: return self.env.spec @@ -208,6 +239,18 @@ def episode_reward(self, episode_reward: Optional[float]): def actions(self) -> List[ActionType]: return self.env.actions + @property + def logger(self): + return self.env.logger + + @property + def version(self) -> str: + return self.env.version + + @property + def compiler_version(self) -> str: + return self.env.compiler_version + @property def state(self) -> CompilerEnvState: return self.env.state @@ -255,14 +298,14 @@ def reverse_action(self, action: ActionType) -> ActionType: raise NotImplementedError -class ObservationWrapper(CompilerEnvWrapper): +class ObservationWrapper(CompilerEnvWrapper, ABC): """Wraps a :class:`CompilerEnv ` environment to allow an observation space transformation. """ def reset(self, *args, **kwargs): observation = self.env.reset(*args, **kwargs) - return self.observation(observation) + return self.convert_observation(observation) def multistep( self, @@ -280,14 +323,15 @@ def multistep( rewards=rewards, ) - return self.observation(observation), reward, done, info + return self.convert_observation(observation), reward, done, info - def observation(self, observation): + @abstractmethod + def convert_observation(self, observation): """Translate an observation to the new space.""" raise NotImplementedError -class RewardWrapper(CompilerEnvWrapper): +class RewardWrapper(CompilerEnvWrapper, ABC): """Wraps a :class:`CompilerEnv ` environment to allow an reward space transformation. """ @@ -319,10 +363,11 @@ def multistep( # the base reward returns NaN or an invalid type. if reward is not None and self.episode_reward is not None: self.unwrapped.episode_reward -= reward - reward = self.reward(reward) + reward = self.convert_reward(reward) self.unwrapped.episode_reward += reward return observation, reward, done, info - def reward(self, reward): + @abstractmethod + def convert_reward(self, reward): """Translate a reward to the new space.""" raise NotImplementedError diff --git a/tests/wrappers/core_wrappers_test.py b/tests/wrappers/core_wrappers_test.py index bcaffa42f..a13dcd8a1 100644 --- a/tests/wrappers/core_wrappers_test.py +++ b/tests/wrappers/core_wrappers_test.py @@ -18,9 +18,30 @@ pytest_plugins = ["tests.pytest_plugins.llvm"] +class ObservationDummyWrapper(ObservationWrapper): + def __init__(self, env): + super().__init__(env) + + def convert_observation(self, observation): + return observation + + +class RewardDummyWrapper(RewardWrapper): + def __init__(self, env): + super().__init__(env) + + def convert_reward(self, reward): + return reward + + @pytest.fixture( scope="module", - params=[ActionWrapper, CompilerEnvWrapper, ObservationWrapper, RewardWrapper], + params=[ + ActionWrapper, + CompilerEnvWrapper, + ObservationDummyWrapper, + RewardDummyWrapper, + ], ) def wrapper_type(request): """A test fixture that yields one of the CompilerGym wrapper types.""" @@ -101,13 +122,13 @@ def test_wrapped_step_custom_args(env: LlvmEnv, wrapper_type): """Test passing the custom CompilerGym step() keyword arguments.""" class MyWrapper(wrapper_type): - def observation(self, observation): + def convert_observation(self, observation): return observation # pass thru def action(self, action): return action # pass thru - def reward(self, reward): + def convert_reward(self, reward): return reward env = MyWrapper(env) @@ -130,7 +151,7 @@ def test_wrapped_benchmark(env: LlvmEnv, wrapper_type): """Test that benchmark property has expected values.""" class MyWrapper(wrapper_type): - def observation(self, observation): + def convert_observation(self, observation): return observation # pass thru env.observation_space = "Ir" @@ -150,7 +171,7 @@ def test_wrapped_set_benchmark(env: LlvmEnv, wrapper_type): """Test that the benchmark attribute can be set on wrapped classes.""" class MyWrapper(wrapper_type): - def observation(self, observation): + def convert_observation(self, observation): return observation # pass thru env = MyWrapper(env) @@ -168,7 +189,7 @@ def observation(self, observation): def test_wrapped_env_in_episode(env: LlvmEnv, wrapper_type): class MyWrapper(wrapper_type): - def observation(self, observation): + def convert_observation(self, observation): return observation env = MyWrapper(env) @@ -187,7 +208,7 @@ def __init__(self, env: LlvmEnv): self.env.observation_space = "Autophase" self.env.reward_space = "IrInstructionCount" - def observation(self, observation): + def convert_observation(self, observation): return observation # pass thru env = MyWrapper(env) @@ -203,9 +224,12 @@ def test_wrapped_env_change_spaces(env: LlvmEnv, wrapper_type): """Test changing the observation and reward spaces on a wrapped environment.""" class MyWrapper(wrapper_type): - def observation(self, observation): + def convert_observation(self, observation): return observation # pass thru + def convert_reward(self, reward): + return reward # pass thru + env = MyWrapper(env) env.observation_space = "Autophase" @@ -243,7 +267,7 @@ def __init__(self, env): super().__init__(env) self.observation_space = "Ir" - def observation(self, observation): + def convert_observation(self, observation): return len(observation) env = MyWrapper(env) @@ -255,15 +279,13 @@ def observation(self, observation): def test_wrapped_observation_missing_definition(env: LlvmEnv): - - env = ObservationWrapper(env) - with pytest.raises(NotImplementedError): - env.reset() + with pytest.raises(TypeError): + env = ObservationWrapper(env) def test_wrapped_reward(env: LlvmEnv): class MyWrapper(RewardWrapper): - def reward(self, reward): + def convert_reward(self, reward): return -5 env.reward_space = "IrInstructionCount" From b7f0ac0f9ecb8e08906472352708360beb7ffced Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Fri, 25 Mar 2022 12:12:12 -0700 Subject: [PATCH 10/16] Rename in a few places ClientServiceCompilerEnv to CompilerEnv --- compiler_gym/bin/service.py | 4 ++-- compiler_gym/envs/llvm/llvm_benchmark.py | 2 +- compiler_gym/util/debug_util.py | 2 +- leaderboard/llvm_instcount/random_search/README.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler_gym/bin/service.py b/compiler_gym/bin/service.py index 8474c9af9..cf4c10c38 100644 --- a/compiler_gym/bin/service.py +++ b/compiler_gym/bin/service.py @@ -103,7 +103,7 @@ from absl import app, flags from compiler_gym.datasets import Dataset -from compiler_gym.service.client_service_compiler_env import ClientServiceCompilerEnv +from compiler_gym.envs import CompilerEnv from compiler_gym.service.connection import ConnectionOpts from compiler_gym.spaces import Commandline, NamedDiscrete from compiler_gym.util.flags.env_from_flags import env_from_flags @@ -190,7 +190,7 @@ def summarize_datasets(datasets: Iterable[Dataset]) -> str: ) -def print_service_capabilities(env: ClientServiceCompilerEnv): +def print_service_capabilities(env: CompilerEnv): """Discover and print the capabilities of a CompilerGym service. :param env: An environment. diff --git a/compiler_gym/envs/llvm/llvm_benchmark.py b/compiler_gym/envs/llvm/llvm_benchmark.py index 83dae7e07..115b5db52 100644 --- a/compiler_gym/envs/llvm/llvm_benchmark.py +++ b/compiler_gym/envs/llvm/llvm_benchmark.py @@ -230,7 +230,7 @@ def make_benchmark( You must ensure that any :code:`.bc` and :code:`.ll` files are compatible with the LLVM version used by CompilerGym, which can be reported using :func:`env.compiler_version - `. + `. E.g. for single-source C/C++ programs, you can pass the path of the source file: diff --git a/compiler_gym/util/debug_util.py b/compiler_gym/util/debug_util.py index 5e4f52bde..edc87db40 100644 --- a/compiler_gym/util/debug_util.py +++ b/compiler_gym/util/debug_util.py @@ -63,7 +63,7 @@ def set_debug_level(level: int) -> None: Setting the debug level affects the entire process and is not thread safe. For granular control of logging information, consider instead setting a - :code:`logging.Logger` instance on :code:`ClientServiceCompilerEnv.logger`. + :code:`logging.Logger` instance on :code:`CompilerEnv.logger`. :param level: The debugging level to use. """ diff --git a/leaderboard/llvm_instcount/random_search/README.md b/leaderboard/llvm_instcount/random_search/README.md index 679bb64eb..101cf514b 100644 --- a/leaderboard/llvm_instcount/random_search/README.md +++ b/leaderboard/llvm_instcount/random_search/README.md @@ -56,7 +56,7 @@ elapsed. Pseudo-code for this search is: ```c++ -float search_with_patience(ClientServiceCompilerEnv env, int patience, int search_time) { +float search_with_patience(CompilerEnv env, int patience, int search_time) { float best_reward = -INFINITY; int end_time = time() + search_time; while (time() < end_time) { From 33a17cc40627f95925240401b0feaa8a7779abc3 Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Fri, 25 Mar 2022 12:22:50 -0700 Subject: [PATCH 11/16] Add ClientServiceCompilerEnv to documentation --- docs/source/compiler_gym/service.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/source/compiler_gym/service.rst b/docs/source/compiler_gym/service.rst index bdb8635b8..32c93026d 100644 --- a/docs/source/compiler_gym/service.rst +++ b/docs/source/compiler_gym/service.rst @@ -14,6 +14,15 @@ client and service is managed by the :class:`CompilerGymServiceConnection :local: +ClientServiceCompilerEnv +------------------------ + +.. autoclass:: ClientServiceCompilerEnv + :members: + + .. automethod:: __init__ + + The CompilationSession Interface -------------------------------- From 4715691c332485133d45da8b0c06acd15890c981 Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Fri, 25 Mar 2022 12:29:01 -0700 Subject: [PATCH 12/16] Remove comments of some members in ClientServiceCompilerEnv --- compiler_gym/envs/compiler_env.py | 4 ++++ .../service/client_service_compiler_env.py | 24 ------------------- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/compiler_gym/envs/compiler_env.py b/compiler_gym/envs/compiler_env.py index 7f6874612..9fcdc5924 100644 --- a/compiler_gym/envs/compiler_env.py +++ b/compiler_gym/envs/compiler_env.py @@ -133,6 +133,10 @@ def in_episode(self) -> bool: @property @abstractmethod def episode_reward(self) -> Optional[float]: + """If :func:`CompilerEnv.reward_space + ` is set, this value is the + sum of all rewards for the current episode. + """ raise NotImplementedError("abstract method") @episode_reward.setter diff --git a/compiler_gym/service/client_service_compiler_env.py b/compiler_gym/service/client_service_compiler_env.py index 0bd449d1e..9b1db32e3 100644 --- a/compiler_gym/service/client_service_compiler_env.py +++ b/compiler_gym/service/client_service_compiler_env.py @@ -89,35 +89,11 @@ class ClientServiceCompilerEnv(CompilerEnv): :vartype service: compiler_gym.service.CompilerGymServiceConnection - :ivar action_spaces: A list of supported action space names. - - :vartype action_spaces: List[str] - - :ivar actions: The list of actions that have been performed since the - previous call to :func:`reset`. - - :vartype actions: List[ActionType] :ivar reward_range: A tuple indicating the range of reward values. Default range is (-inf, +inf). :vartype reward_range: Tuple[float, float] - - :ivar observation: A view of the available observation spaces that permits - on-demand computation of observations. - - :vartype observation: compiler_gym.views.ObservationView - - :ivar reward: A view of the available reward spaces that permits on-demand - computation of rewards. - - :vartype reward: compiler_gym.views.RewardView - - :ivar episode_reward: If :func:`ClientServiceCompilerEnv.reward_space - ` is set, this value is the - sum of all rewards for the current episode. - - :vartype episode_reward: float """ def __init__( From 64f3ef205d30b87406680b46fa242f9cc7642c93 Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Fri, 25 Mar 2022 12:43:39 -0700 Subject: [PATCH 13/16] Add expected warning in test_wrapped_set_benchmark --- tests/wrappers/core_wrappers_test.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/wrappers/core_wrappers_test.py b/tests/wrappers/core_wrappers_test.py index a13dcd8a1..252b7c8d8 100644 --- a/tests/wrappers/core_wrappers_test.py +++ b/tests/wrappers/core_wrappers_test.py @@ -4,6 +4,7 @@ # LICENSE file in the root directory of this source tree. """Unit tests for //compiler_gym/wrappers.""" import pytest +from pytest import warns from compiler_gym.datasets import Datasets from compiler_gym.envs.llvm import LlvmEnv @@ -182,7 +183,11 @@ def convert_observation(self, observation): assert env.benchmark == "benchmark://cbench-v1/dijkstra" # Repeat again for a different benchmark. - env.benchmark = "benchmark://cbench-v1/crc32" + with warns( + UserWarning, + match=r"Changing the benchmark has no effect until reset\(\) is called", + ): + env.benchmark = "benchmark://cbench-v1/crc32" env.reset() assert env.benchmark == "benchmark://cbench-v1/crc32" From 4230f9f3beef3d37574954e5bdfe1bf35bb7c942 Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Fri, 25 Mar 2022 18:38:15 -0700 Subject: [PATCH 14/16] Use convert_observation in ConcatActionsHistogram --- examples/llvm_rl/wrappers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/llvm_rl/wrappers.py b/examples/llvm_rl/wrappers.py index 4a2a7e6d9..d1807aa0f 100644 --- a/examples/llvm_rl/wrappers.py +++ b/examples/llvm_rl/wrappers.py @@ -137,7 +137,7 @@ def multistep( self.histogram[a] += self.increment return super().multistep(actions, **kwargs) - def observation(self, observation): + def convert_observation(self, observation): return np.concatenate((observation, self.histogram)).astype( self.env.observation_space.dtype ) From 165b3853e42eaf768d3fc0f09a8a8028b429b226 Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Mon, 28 Mar 2022 09:04:11 -0700 Subject: [PATCH 15/16] Add reference to PR in a comment about circular dependency --- compiler_gym/service/BUILD | 3 ++- compiler_gym/service/CMakeLists.txt | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/compiler_gym/service/BUILD b/compiler_gym/service/BUILD index 32c1722e3..7a93a7d38 100644 --- a/compiler_gym/service/BUILD +++ b/compiler_gym/service/BUILD @@ -12,7 +12,8 @@ py_library( deps = [ ":compilation_session", ":connection", - # TODO: add this after circular dependencies are resolved + # TODO(github.com/facebookresearch/CompilerGym/pull/633): + # add this after circular dependencies are resolved # ":client_service_compiler_env", "//compiler_gym/service/proto", ], diff --git a/compiler_gym/service/CMakeLists.txt b/compiler_gym/service/CMakeLists.txt index 060a46376..dc2791760 100644 --- a/compiler_gym/service/CMakeLists.txt +++ b/compiler_gym/service/CMakeLists.txt @@ -13,7 +13,8 @@ cg_py_library( DEPS ::compilation_session ::connection - # TODO: add this after circular dependencies are resolved + # TODO(github.com/facebookresearch/CompilerGym/pull/633): + # add this after circular dependencies are resolved #::client_service_compiler_env compiler_gym::service::proto::proto PUBLIC From 3b9518ad7eefe723c05f04e533431c56fab4ad1c Mon Sep 17 00:00:00 2001 From: Boian Petkantchin Date: Mon, 28 Mar 2022 09:05:45 -0700 Subject: [PATCH 16/16] Fix implementation of inheritace from ObservationWrapper and RewardWrapper --- examples/llvm_rl/wrappers.py | 4 ++-- tests/wrappers/core_wrappers_test.py | 19 ++++++++----------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/examples/llvm_rl/wrappers.py b/examples/llvm_rl/wrappers.py index d1807aa0f..3fdf8825d 100644 --- a/examples/llvm_rl/wrappers.py +++ b/examples/llvm_rl/wrappers.py @@ -34,7 +34,7 @@ def __init__( self.max = max self.leakiness_factor = leakiness_factor - def reward(self, reward: float) -> float: + def convert_reward(self, reward: float) -> float: if reward > self.max: return self.max + (reward - self.max) * self.leakiness_factor elif reward < self.min: @@ -65,7 +65,7 @@ def __init__(self, env: CompilerEnv): dtype=np.float32, ) - def observation(self, observation): + def convert_observation(self, observation): if observation[self.TotalInsts_index] <= 0: return np.zeros(observation.shape, dtype=np.float32) return np.clip( diff --git a/tests/wrappers/core_wrappers_test.py b/tests/wrappers/core_wrappers_test.py index 252b7c8d8..ca493996f 100644 --- a/tests/wrappers/core_wrappers_test.py +++ b/tests/wrappers/core_wrappers_test.py @@ -8,18 +8,15 @@ from compiler_gym.datasets import Datasets from compiler_gym.envs.llvm import LlvmEnv -from compiler_gym.wrappers import ( - ActionWrapper, - CompilerEnvWrapper, - ObservationWrapper, - RewardWrapper, -) +from compiler_gym.wrappers import ActionWrapper, CompilerEnvWrapper +from compiler_gym.wrappers import ObservationWrapper as CoreObservationWrapper +from compiler_gym.wrappers import RewardWrapper as CoreRewardWrapper from tests.test_main import main pytest_plugins = ["tests.pytest_plugins.llvm"] -class ObservationDummyWrapper(ObservationWrapper): +class ObservationWrapper(CoreObservationWrapper): def __init__(self, env): super().__init__(env) @@ -27,7 +24,7 @@ def convert_observation(self, observation): return observation -class RewardDummyWrapper(RewardWrapper): +class RewardWrapper(CoreRewardWrapper): def __init__(self, env): super().__init__(env) @@ -40,8 +37,8 @@ def convert_reward(self, reward): params=[ ActionWrapper, CompilerEnvWrapper, - ObservationDummyWrapper, - RewardDummyWrapper, + ObservationWrapper, + RewardWrapper, ], ) def wrapper_type(request): @@ -285,7 +282,7 @@ def convert_observation(self, observation): def test_wrapped_observation_missing_definition(env: LlvmEnv): with pytest.raises(TypeError): - env = ObservationWrapper(env) + env = CoreObservationWrapper(env) def test_wrapped_reward(env: LlvmEnv):