Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[service] Add a CompilationSession abstract base class. #261

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions compiler_gym/service/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,40 @@
# This source code is licensed under the MIT license found in the
# LICENSE file in the root directory of this source tree.
load("@rules_python//python:defs.bzl", "py_library")
load("@rules_cc//cc:defs.bzl", "cc_library")

py_library(
name = "service",
srcs = ["__init__.py"],
visibility = ["//visibility:public"],
deps = [
":compilation_session",
":connection",
"//compiler_gym/service/proto",
],
)

py_library(
name = "compilation_session",
srcs = ["compilation_session.py"],
visibility = ["//visibility:public"],
deps = [
"//compiler_gym/service/proto",
],
)

cc_library(
name = "CompilationSession",
srcs = ["CompilationSession.cc"],
hdrs = ["CompilationSession.h"],
visibility = ["//visibility:public"],
deps = [
"//compiler_gym/service/proto:compiler_gym_service_cc",
"@boost//:filesystem",
"@com_github_grpc_grpc//:grpc++",
],
)

py_library(
name = "connection",
srcs = ["connection.py"],
Expand Down
26 changes: 26 additions & 0 deletions compiler_gym/service/CompilationSession.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// 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.
#include "compiler_gym/service/CompilationSession.h"

using grpc::Status;
using grpc::StatusCode;

namespace compiler_gym {

std::string CompilationSession::getCompilerVersion() const { return ""; }

Status CompilationSession::init(CompilationSession* other) {
return Status(StatusCode::UNIMPLEMENTED, "CompilationSession::init() not implemented");
}

Status CompilationSession::endOfStep(bool actionHadNoEffect, bool& endOfEpisode,
std::optional<ActionSpace>& newActionSpace) {
return Status::OK;
}

CompilationSession::CompilationSession(const boost::filesystem::path& workingDirectory)
: workingDirectory_(workingDirectory) {}

} // namespace compiler_gym
85 changes: 85 additions & 0 deletions compiler_gym/service/CompilationSession.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// 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.
#pragma once

#include <grpcpp/grpcpp.h>

#include <optional>
#include <vector>

#include "boost/filesystem.hpp"
#include "compiler_gym/service/proto/compiler_gym_service.pb.h"

namespace compiler_gym {

// 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
// createAndRunCompilationService() and parametrize it with your class type:
//
// #include "compiler_gym/service/CompilationSession.h"
// #include "compiler_gym/service/runtime/Runtime.h"
//
// using namespace compiler_gym;
//
// class MyCompilationSession final : public CompilationSession { ... }
//
// int main(int argc, char** argv) {
// runtime::createAndRunCompilationService<MyCompilationSession>();
// }
//
class CompilationSession {
public:
// Get the compiler version.
virtual std::string getCompilerVersion() const;

// A list of action spaces describing the capabilities of the compiler.
virtual std::vector<ActionSpace> getActionSpaces() const = 0;

// A list of feature vectors that this compiler provides.
virtual std::vector<ObservationSpace> getObservationSpaces() const = 0;

// Start a CompilationSession. This will be called after construction and
// before applyAction() or computeObservation(). This will only be called
// once.
[[nodiscard]] virtual grpc::Status init(const ActionSpace& actionSpace,
const Benchmark& benchmark) = 0;

// Initialize the state from another CompilerSession. This will be called
// after construction and before applyAction() or computeObservation(). This
// will only be called once.
[[nodiscard]] virtual grpc::Status init(CompilationSession* other);

// Apply an action.
[[nodiscard]] virtual grpc::Status applyAction(const Action& action, bool& endOfEpisode,
std::optional<ActionSpace>& newActionSpace,
bool& actionHadNoEffect) = 0;

// Compute an observation.
[[nodiscard]] virtual grpc::Status computeObservation(const ObservationSpace& observationSpace,
Observation& observation) = 0;

// Optional. This will be called after all applyAction() and
// computeObservation() in a step. Use this method if you would like to
// perform post-transform validation of compiler state.
[[nodiscard]] virtual grpc::Status endOfStep(bool actionHadNoEffect, bool& endOfEpisode,
std::optional<ActionSpace>& newActionSpace);

CompilationSession(const boost::filesystem::path& workingDirectory);

virtual ~CompilationSession() = default;

protected:
// Get the working directory, which is a local filesystem directory that this
// CompilationSession can use to store temporary files such as build
// artifacts.
inline const boost::filesystem::path& workingDirectory() { return workingDirectory_; }

private:
const boost::filesystem::path workingDirectory_;
};

} // namespace compiler_gym
2 changes: 2 additions & 0 deletions compiler_gym/service/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +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.service.compilation_session import CompilationSession
from compiler_gym.service.connection import (
CompilerGymServiceConnection,
ConnectionOpts,
Expand All @@ -15,6 +16,7 @@

__all__ = [
"CompilerGymServiceConnection",
"CompilationSession",
"ConnectionOpts",
"ServiceError",
"ServiceInitError",
Expand Down
90 changes: 90 additions & 0 deletions compiler_gym/service/compilation_session.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# 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.
from pathlib import Path
from typing import List, Optional, Tuple

from compiler_gym.service.proto import (
Action,
ActionSpace,
Benchmark,
Observation,
ObservationSpace,
)


class CompilationSession:
"""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
:func:`create_and_run_compiler_service
<compiler_gym.service.runtime.create_and_run_compiler_service>` and pass in
your class type:

.. code-block:: python

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)
"""

compiler_version: str = ""
"""The compiler version."""

action_spaces: List[ActionSpace] = []
"""A list of action spaces describing the capabilities of the compiler."""

observation_spaces: List[ObservationSpace] = []
"""A list of feature vectors that this compiler provides."""

def __init__(
self, working_dir: Path, action_space: ActionSpace, benchmark: Benchmark
):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious: why doesn't this return a status like the c++ code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't use exceptions in C++ (FWIW I don't have particularly strong opinions on the matter), the CompilationSession constructor in C++ is a safe default, and any of the three methods that can fail (init, compute feature, run action) return Status.

For Python, exceptions are fine and all of the runtime logic that interacts with CompilationSession will catch exceptions and set the relevant RPC error code

"""Start a CompilationSession.

Subclasses should initialize the parent class first.

:param working_dir: A directory on the local filesystem that can be used
to store temporary files such as build artifacts.

:param action_space: The action space to use.

:param benchmark: The benchmark to use.
"""
del action_space # Subclasses must use this.
del benchmark # Subclasses must use this.
self.working_dir = working_dir

def apply_action(self, action: Action) -> Tuple[bool, Optional[ActionSpace], bool]:
"""Apply an action.

:param action: The action to apply.

:return: A tuple: :code:`(end_of_session, new_action_space,
action_had_no_effect)`.
"""
raise NotImplementedError

def get_observation(self, observation_space: ObservationSpace) -> Observation:
"""Compute an observation.

:param observation_space: The observation space.

:return: An observation.
"""
raise NotImplementedError

def fork(self) -> "CompilationSession":
"""Optional. Create a copy of current session state.

:return: A new CopmilationSession with the same state.
"""
# No need to override this if you are not adding support to fork().
raise NotImplementedError("CompilationSession.fork() not supported")
6 changes: 6 additions & 0 deletions docs/source/compiler_gym/service.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ client and service is managed by the :class:`CompilerGymServiceConnection
.. contents:: Document contents:
:local:

.. autoclass:: CompilationSession
:members:

.. automethod:: __init__


The connection object
---------------------

Expand Down
2 changes: 1 addition & 1 deletion requirements_pre_commit.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
black==19.10b0
isort==4.3.21
pre-commit>=2.9.0
pre-commit>=2.12.1