compiler_gym.service
The compiler_gym.service
module provides a client/service implementation
of the CompilerEnv
interface. Services
provide an interface for manipulating compiler behavior. Clients are Python
frontend objects that provide a reinforcement learning abstraction on top of the
service. Communication between the service and client is done using RPC. The connection between the client and service is managed by the
CompilerGymServiceConnection
object.
Document contents:
The CompilationSession Interface
- class compiler_gym.service.CompilationSession(working_dir: Path, action_space: ActionSpace, benchmark: Benchmark)[source]
Base class for encapsulating an incremental compilation session.
To add support for a new compiler, subclass from this base and provide implementations of the abstract methods, then call
create_and_run_compiler_service
and pass in your class type:from compiler_gym.service import CompilationSession from compiler_gym.service import runtime class MyCompilationSession(CompilationSession): ... if __name__ == "__main__": runtime.create_and_run_compiler_service(MyCompilationSession)
- __init__(working_dir: Path, action_space: ActionSpace, benchmark: Benchmark)[source]
Start a CompilationSession.
Subclasses should initialize the parent class first.
- Parameters
working_dir – A directory on the local filesystem that can be used to store temporary files such as build artifacts.
action_space – The action space to use.
benchmark – The benchmark to use.
- action_spaces: List[ActionSpace] = []
A list of action spaces describing the capabilities of the compiler.
- apply_action(action: Event) Tuple[bool, Optional[ActionSpace], bool] [source]
Apply an action.
- Parameters
action – The action to apply.
- Returns
A tuple: :code:`(end_of_session, new_action_space,
action_had_no_effect)`.
- compiler_version: str = ''
The compiler version.
- fork() CompilationSession [source]
Create a copy of current session state.
Implementing this method is optional.
- Returns
A new CompilationSession with the same state.
- get_observation(observation_space: ObservationSpace) Event [source]
Compute an observation.
- Parameters
observation_space – The observation space.
- Returns
An observation.
- handle_session_parameter(key: str, value: str) Optional[str] [source]
Handle a session parameter send by the frontend.
Session parameters provide a method to send ad-hoc key-value messages to a compilation session through the
env.send_session_parameter()
method. It us up to the client/service to agree on a common schema for encoding and decoding these parameters.Implementing this method is optional.
- Parameters
key – The parameter key.
value – The parameter value.
- Returns
A string response message if the parameter was understood. Else
None
to indicate that the message could not be interpretted.
- observation_spaces: List[ObservationSpace] = []
A list of feature vectors that this compiler provides.
ClientServiceCompilerEnv
- class compiler_gym.service.client_service_compiler_env.ClientServiceCompilerEnv(service: Union[str, Path], rewards: Optional[List[Reward]] = None, datasets: Optional[Iterable[Dataset]] = None, benchmark: Optional[Union[str, Benchmark]] = None, observation_space: Optional[Union[str, ObservationSpaceSpec]] = None, reward_space: Optional[Union[str, Reward]] = None, action_space: Optional[str] = None, derived_observation_spaces: Optional[List[Dict[str, Any]]] = None, service_message_converters: Optional[ServiceMessageConverters] = None, connection_settings: Optional[ConnectionOpts] = None, service_connection: Optional[CompilerGymServiceConnection] = None)[source]
Implementation of
CompilerEnv
using gRPC for client-server communication.- Variables
service (compiler_gym.service.CompilerGymServiceConnection) – A connection to the underlying compiler service.
- __init__(service: Union[str, Path], rewards: Optional[List[Reward]] = None, datasets: Optional[Iterable[Dataset]] = None, benchmark: Optional[Union[str, Benchmark]] = None, observation_space: Optional[Union[str, ObservationSpaceSpec]] = None, reward_space: Optional[Union[str, Reward]] = None, action_space: Optional[str] = None, derived_observation_spaces: Optional[List[Dict[str, Any]]] = None, service_message_converters: Optional[ServiceMessageConverters] = None, connection_settings: Optional[ConnectionOpts] = None, service_connection: Optional[CompilerGymServiceConnection] = None)[source]
Construct and initialize a CompilerGym environment.
In normal use you should use
gym.make(...)
rather than calling the constructor directly.- Parameters
service – The hostname and port of a service that implements the CompilerGym service interface, or the path of a binary file which provides the CompilerGym service interface when executed. See compiler_gym.service for details.
rewards – The reward spaces that this environment supports. Rewards are typically calculated based on observations generated by the service. See
Reward
for details.benchmark – The benchmark to use for this environment. Either a URI string, or a
Benchmark
instance. If not provided, the first benchmark as returned bynext(env.datasets.benchmarks())
will be used as the default.observation_space – Compute and return observations at each
step()
from this space. Accepts a string name or anObservationSpaceSpec
. If not provided,step()
returnsNone
for the observation value. Can be set later usingenv.observation_space
. For available spaces, seeenv.observation.spaces
.reward_space – Compute and return reward at each
step()
from this space. Accepts a string name or aReward
. If not provided,step()
returnsNone
for the reward value. Can be set later usingenv.reward_space
. For available spaces, seeenv.reward.spaces
.action_space – The name of the action space to use. If not specified, the default action space for this compiler is used.
derived_observation_spaces – An optional list of arguments to be passed to
env.observation.add_derived_space()
.service_message_converters – Custom converters for action spaces and actions.
connection_settings – The settings used to establish a connection with the remote service.
service_connection – An existing compiler gym service connection to use.
- Raises
FileNotFoundError – If service is a path to a file that is not found.
TimeoutError – If the compiler service fails to initialize within the parameters provided in
connection_settings
.
- property action_space: ActionSpace
The current action space.
- Getter
Get the current action space.
- Setter
Set the action space to use. Must be an entry in
action_spaces
. IfNone
, the default action space is selected.
- property action_spaces: List[str]
A list of supported action space names.
- apply(state: CompilerEnvState) None [source]
Replay this state on the given environment.
- Parameters
state – A
CompilerEnvState
instance.- Raises
ValueError – If this state cannot be applied.
- property benchmark: Benchmark
Get or set the benchmark to use.
- Getter
Get
Benchmark
that is currently in use.- Setter
Set the benchmark to use. Either a
Benchmark
instance, or the URI of a benchmark as inenv.datasets.benchmark_uris()
.
Note
Setting a new benchmark has no effect until
env.reset()
is called.
- close()[source]
Close the environment.
Once closed,
reset()
must be called before the environment is used again.Note
You must make sure to call
env.close()
on a CompilerGym environment when you are done with it. This is needed to perform manual tidying up of temporary files and processes. See the FAQ for more details.
- commandline() str [source]
Calling this method on a
ClientServiceCompilerEnv
instance raisesNotImplementedError
.
- commandline_to_actions(commandline: str) List[ActionType] [source]
Calling this method on a
ClientServiceCompilerEnv
instance raisesNotImplementedError
.
- property compiler_version: str
The version string of the underlying compiler that this service supports.
- property episode_reward: Optional[float]
CompilerEnv.reward_space <compiler_gym.envs.CompilerGym.reward_space> is set, this value is the sum of all rewards for the current episode.
- Type
If
- Type
func
- property episode_walltime: float
Return the amount of time in seconds since the last call to
reset()
.
- fork() ClientServiceCompilerEnv [source]
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
close()
on the original and new environments.If not already in an episode,
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
Note
The client/service implementation of CompilerGym means that the forked and base environments share a common backend resource. This means that if either of them crash, such as due to a compiler assertion, both environments must be reset.
- Returns
A new environment instance.
- property in_episode: bool
Whether the service is ready for
step()
to be called, i.e.reset()
has been called andclose()
has not.- Returns
True
if in an episode, elseFalse
.
- multistep(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, timeout: float = 300)[source]
- Raises
SessionNotFound – If :meth:`reset()
<compiler_gym.envs.ClientServiceCompilerEnv.reset>` has not been called.
- property observation: ObservationView
A view of the available observation spaces that permits on-demand computation of observations.
- property observation_space: Optional[Space]
The observation space that is used to return an observation value in
step()
.- Getter
Returns the underlying observation space, or
None
if not set.- Setter
Set the default observation space.
- raw_step(actions: Iterable[ActionType], observation_spaces: List[ObservationSpaceSpec], reward_spaces: List[Reward], timeout: float = 300) Tuple[Optional[Union[ObservationType, List[ObservationType]]], Optional[Union[float, List[float]]], bool, Dict[str, Any]] [source]
Take a step.
- Parameters
actions – A list of actions to be applied.
observations – A list of observations spaces to compute observations from. These are evaluated after the actions are applied.
rewards – A list of reward spaces to compute rewards from. These are evaluated after the actions are applied.
- Returns
A tuple of observations, rewards, done, and info. Observations and rewards are lists.
- Raises
SessionNotFound – If
reset()
has not been called.
Warning
Don’t call this method directly, use
step()
ormultistep()
instead. Theraw_step()
method is an implementation detail.
- render(mode='human') Optional[str] [source]
Render the environment.
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.
- Parameters
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.
- reset(benchmark: Optional[Union[str, Benchmark]] = None, action_space: Optional[str] = None, reward_space: Union[OptionalArgumentValue, str, Reward] = OptionalArgumentValue.UNCHANGED, observation_space: Union[OptionalArgumentValue, str, ObservationSpaceSpec] = OptionalArgumentValue.UNCHANGED, timeout: float = 300) Optional[ObservationType] [source]
Reset the environment state.
This method must be called before
step()
.- Parameters
benchmark – The name of the benchmark to use. If provided, it overrides any value that was set during
__init__()
, and becomes subsequent calls toreset()
will use this benchmark. If no benchmark is provided, and no benchmark was provided to__init___()
, the service will randomly select a benchmark to use.action_space – The name of the action space to use. If provided, it overrides any value that set during
__init__()
, and subsequent calls toreset()
will use this action space. If no action space is provided, the default action space is used.observation_space – Compute and return observations at each
step()
from this space. Accepts a string name or anObservationSpaceSpec
. IfNone
,step()
returnsNone
for the observation value. IfOptionalArgumentValue.UNCHANGED
(the default value), the observation space remains unchanged from the previous episode. For available spaces, seeenv.observation.spaces
.reward_space – Compute and return reward at each
step()
from this space. Accepts a string name or aReward
. IfNone
,step()
returnsNone
for the reward value. IfOptionalArgumentValue.UNCHANGED
(the default value), the observation space remains unchanged from the previous episode. For available spaces, seeenv.reward.spaces
.timeout – The maximum number of seconds to wait for reset to succeed.
- Returns
The initial observation.
- Raises
BenchmarkInitError – If the benchmark is invalid. This can happen if the benchmark contains code that the compiler does not support, or because of some internal error within the compiler. In this case, another benchmark must be used.
TypeError – If no benchmark has been set, and the environment does not have a default benchmark to select from.
- property reward: RewardView
A view of the available reward spaces that permits on-demand computation of rewards.
- property reward_range: Tuple[float, float]
A tuple indicating the range of reward values.
Default range is (-inf, +inf).
- property reward_space: Optional[Reward]
The default reward space that is used to return a reward value from
step()
.- Getter
Returns a
Reward
, orNone
if not set.- Setter
Set the default reward space.
- send_param(key: str, value: str, resend_on_reset: bool = False) str [source]
Send a single <key, value> parameter to the compiler service.
See
send_params()
for more information.- Parameters
key – The parameter key.
value – The parameter value.
resend_on_reset – Whether to resend this parameter to the compiler service on
reset()
.
- Returns
The response from the compiler service.
- Raises
SessionNotFound – If called before
reset()
.
- send_params(*params: Iterable[Tuple[str, str]], resend_on_reset: bool = False) List[str] [source]
Send a list of <key, value> parameters to the compiler service.
This provides a mechanism to send messages to the backend compilation session in a way that doesn’t conform to the normal communication pattern. This can be useful for things like configuring runtime debugging settings, or applying “meta actions” to the compiler that are not exposed in the compiler’s action space. Consult the documentation for a specific compiler service to see what parameters, if any, are supported.
Must have called
reset()
first.- Parameters
params – A list of parameters, where each parameter is a
(key, value)
tuple.resend_on_reset – Whether to resend this parameter to the compiler service on
reset()
.
- Returns
A list of string responses, one per parameter.
- Raises
SessionNotFound – If called before
reset()
.
- property state: CompilerEnvState
The tuple representation of the current environment state.
- step(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, timeout: float = 300) Tuple[Optional[Union[ObservationType, List[ObservationType]]], Optional[Union[float, List[float]]], bool, Dict[str, Any]] [source]
- Raises
SessionNotFound – If :meth:`reset()
<compiler_gym.envs.ClientServiceCompilerEnv.reset>` has not been called.
- validate(state: Optional[CompilerEnvState] = None) ValidationResult [source]
Validate an environment’s state.
- Parameters
state – A state to environment. If not provided, the current state is validated.
- Returns
- property version: str
The version string of the compiler service.
- property versions: GetVersionReply
Get the version numbers from the compiler service.
- class compiler_gym.service.client_service_compiler_env.ServiceMessageConverters(action_space_converter: Optional[Callable[[ActionSpace], Space]] = None, action_converter: Optional[Callable[[Any], Event]] = None)[source]
Allows for customization of conversion to/from gRPC messages for the
ClientServiceCompilerEnv
.Supports conversion customizations:
compiler_gym.service.proto.ActionSpace
->gym.spaces.Space
.compiler_gym.util.gym_type_hints.ActionType
->compiler_gym.service.proto.Event
.
The connection object
- class compiler_gym.service.CompilerGymServiceConnection(endpoint: Union[str, Path], opts: Optional[ConnectionOpts] = None)[source]
A connection to a compiler gym service.
There are two types of service connections: managed and unmanaged. The type of connection is determined by the endpoint. If a “host:port” URL is provided, an unmanaged connection is created. If the path of a file is provided, a managed connection is used. The difference between a managed and unmanaged connection is that with a managed connection, the lifecycle of the service if controlled by the client connection. That is, when a managed connection is created, a service subprocess is started by executing the specified path. When the connection is closed, the subprocess is terminated. With an unmanaged connection, if the service fails is goes offline, the client will fail.
This class provides a common abstraction between the two types of connection, and provides a call method for invoking remote procedures on the service.
Example usage of an unmanaged service connection:
# Connect to a service running on localhost:8080. The user must # started a process running on port 8080. connection = CompilerGymServiceConnection("localhost:8080") # Invoke an RPC method. connection(connection.stub.StartSession, StartSessionRequest()) # Close the connection. The service running on port 8080 is # left running. connection.close()
Example usage of a managed service connection:
# Start a subprocess using the binary located at /path/to/my/service. connection = CompilerGymServiceConnection(Path("/path/to/my/service")) # Invoke an RPC method. connection(connection.stub.StartSession, StartSessionRequest()) # Close the connection. The subprocess is terminated. connection.close()
- Variables
stub – A CompilerGymServiceStub that can be used as the first argument to
__call__()
to specify an RPC method to call.action_spaces – A list of action spaces provided by the service.
observation_spaces – A list of observation spaces provided by the service.
- __init__(endpoint: Union[str, Path], opts: Optional[ConnectionOpts] = None)[source]
Constructor.
- Parameters
endpoint – The connection endpoint. Either the URL of a service, e.g. “localhost:8080”, or the path of a local service binary.
opts – The connection options.
- Raises
ValueError – If the provided options are invalid.
FileNotFoundError – In case opts.local_service_binary is not found.
TimeoutError – In case the service failed to start within opts.init_max_seconds seconds.
- __call__(stub_method: StubMethod, request: Request, timeout: Optional[float] = 300, max_retries: Optional[int] = None, retry_wait_seconds: Optional[float] = None, retry_wait_backoff_exponent: Optional[float] = None) Reply [source]
Invoke an RPC method on the service and return its response. All RPC methods accept a single request message, and respond with a response message.
Example usage:
connection = CompilerGymServiceConnection("localhost:8080") request = compiler_gym.service.proto.GetSpacesRequest() reply = connection(connection.stub.GetSpaces, request)
In the above example, the GetSpaces RPC method is invoked on a connection, yielding a GetSpacesReply message.
- Parameters
stub_method – An RPC method attribute on CompilerGymServiceStub.
request – A request message.
timeout – The maximum number of seconds to await a reply.
max_retries – The maximum number of failed attempts to communicate with the RPC service before raising an error. Retries are made only for communication errors. Failures from other causes such as error signals raised by the service are not retried.
retry_wait_seconds – The number of seconds to wait between successive attempts to communicate with the RPC service.
retry_wait_backoff_exponent – The exponential backoff scaling between successive attempts to communicate with the RPC service.
- Raises
ValueError – If the service responds with an error indicating an invalid argument.
NotImplementedError – If the service responds with an error indicating that the requested functionality is not implemented.
FileNotFoundError – If the service responds with an error indicating that a requested resource was not found.
OSError – If the service responds with an error indicating that it ran out of resources.
TypeError – If the provided request parameter is of incorrect type or cannot be serialized, or if the service responds with an error indicating that a precondition failed.
TimeoutError – If the service failed to respond to the query within the specified timeout.
ServiceTransportError – If the client failed to communicate with the service.
ServiceIsClosed – If the connection to the service is closed.
ServiceError – If the service raised an error not covered by any of the above conditions.
- Returns
A reply message.
- property closed: bool
Whether the connection is closed.
Configuring the connection
The ConnectionOpts
object is used
to configure the options used for managing a service connection.
- class compiler_gym.service.ConnectionOpts(*, rpc_max_retries: int = 5, retry_wait_seconds: float = 0.1, retry_wait_backoff_exponent: float = 1.5, init_max_seconds: float = 30, init_max_attempts: int = 5, local_service_port_init_max_seconds: float = 30, local_service_exit_max_seconds: float = 30, rpc_init_max_seconds: float = 3, always_send_benchmark_on_reset: bool = False, script_args: List[str] = [], script_env: Dict[str, str] = {})[source]
The options used to configure a connection to a service.
- always_send_benchmark_on_reset: bool
Send the full benchmark program data to the compiler service on ever call to
env.reset()
. This is more efficient in cases where the majority of calls toenv.reset()
uses a different benchmark. In case of benchmark re-use, leave thisFalse
.
- init_max_attempts: int
The maximum number of attempts to make to establish a connection to the service before failing.
- init_max_seconds: float
The maximum number of seconds to spend attempting to establish a connection to the service before failing.
- local_service_exit_max_seconds: float
The maximum number of seconds to wait for a local service to terminate on close.
- local_service_port_init_max_seconds: float
The maximum number of seconds to wait for a local service to write the port.txt file.
- retry_wait_backoff_exponent: float
The exponential backoff scaling between successive attempts to communicate with the RPC service.
- retry_wait_seconds: float
The number of seconds to wait between successive attempts to communicate with the RPC service.
- rpc_init_max_seconds: float
The maximum number of seconds to wait for an RPC connection to establish.
- rpc_max_retries: int
The maximum number of failed attempts to communicate with the RPC service before raising an error. Retries are made only for communication errors. Failures from other causes such as error signals raised by the service are not retried.
- script_args: List[str]
If the service is started from a local script, this set of args is used on the command line. No effect when used for existing sockets.
- script_env: Dict[str, str]
If the service is started from a local script, this set of env vars is used on the command line. No effect when used for existing sockets.
Exceptions
In general, errors raised by the service are converted to the equivalent builtin
exception type, e.g., ValueError for invalid method arguments, and
FileNotFound for resource errors. However, some error cases are not well
covered by the builtin exception hierarchy. For those cases, we define custom
exception types, all inheriting from a base ServiceError
class:
- exception compiler_gym.service.EnvironmentNotSupported[source]
Error raised if the runtime requirements for an environment are not met on the current system.
- exception compiler_gym.service.ServiceInitError[source]
Error raised if the service fails to initialize.
- exception compiler_gym.service.ServiceTransportError[source]
Error that is raised if communication with the service fails.