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 reusable pool for backend services. #583

Open
wants to merge 41 commits into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
7a35872
[service] Make ConnectionOpts hashable.
ChrisCummins Feb 20, 2022
dda3b61
[datasets] Add a note about installing LLVM runtime data.
ChrisCummins Feb 20, 2022
07973f3
[tests] Add a new corner case test for forked environments.
ChrisCummins Feb 20, 2022
dcd7708
[service] Add a reusable pool of service connections.
ChrisCummins Feb 19, 2022
0bb97b1
Hardening patch for shutdown errors.
ChrisCummins Feb 23, 2022
781727f
[gcc] Fix connection property setter.
ChrisCummins Feb 23, 2022
bdada20
[tests] Update tests.
ChrisCummins Feb 23, 2022
4304d51
[service] Make ConnectionOpts mutable again.
ChrisCummins Feb 23, 2022
37bda6c
[service] Fix race in destructor.
ChrisCummins Feb 23, 2022
3e11bb1
[service] Fix unmanaged service pool.
ChrisCummins Feb 23, 2022
15b6248
Test fixes from new connection pool.
ChrisCummins Mar 3, 2022
a2a3123
Fix typo in docstring.
ChrisCummins Mar 3, 2022
c104632
Add a type annotation for env._service_pool.
ChrisCummins Mar 3, 2022
3a7b745
Clarify docstring.
ChrisCummins Mar 3, 2022
2010f38
Docstring improvements.
ChrisCummins Mar 3, 2022
63d3bd8
Refactor env.action_space.flags.index(x) to env.action_space[x].
ChrisCummins Mar 3, 2022
eeef55f
[tests] Increase timeout on validation test.
ChrisCummins Mar 3, 2022
91c38ef
Documentation improvements.
ChrisCummins Mar 3, 2022
623a23d
[tests] Add test case for forked environment scope.
ChrisCummins Mar 3, 2022
35cbd5b
[benchmarks] Merge init benchmarks and add GCC + loop_tool.
ChrisCummins Mar 3, 2022
826b5c4
[tests] Increase timeouts for validation tests.
ChrisCummins Mar 3, 2022
a7207a6
[gcc] Add post-install steps to docker install instructions.
ChrisCummins Mar 3, 2022
de7db62
[gcc] Move the thread lock on constructor into core library.
ChrisCummins Mar 7, 2022
adad70c
[service] Add a base class for the connection pool.
ChrisCummins Mar 7, 2022
b1781ea
[service] Tweak logging messages.
ChrisCummins Mar 7, 2022
9ec10e1
[gcc] Disable service connection pool for GCC.
ChrisCummins Mar 7, 2022
8c8ba2f
[tests] Better GCC fixture enumeration.
ChrisCummins Mar 7, 2022
9c6e9fe
[examples] Fix missing return code.
ChrisCummins Mar 7, 2022
09188f7
[service] Defend against logging error on close().
ChrisCummins Mar 7, 2022
aedcb00
Rebase fixes for service pool PR.
ChrisCummins Apr 19, 2022
0674661
Run pre-commit formatters on sources.
ChrisCummins Apr 21, 2022
712276f
[tests] Add missing maxsize to lru_cache.
ChrisCummins Apr 19, 2022
c1f89eb
Fix cmake dependency name.
ChrisCummins Apr 19, 2022
077b3bf
Add missing cmake dependencies.
ChrisCummins Apr 19, 2022
31a9430
Auto-formatted sources.
ChrisCummins Apr 19, 2022
8735fce
Update tests to add ConnectionOpts argument.
ChrisCummins Apr 19, 2022
7228951
Bump timeout on GCC smoke test to 10 min.
ChrisCummins Apr 19, 2022
fa2b50e
[ci] Remove redundant comment.
ChrisCummins Apr 19, 2022
b6bb7fb
Tidy up build dependencies.
ChrisCummins Apr 19, 2022
884fa10
Remove unused import.
ChrisCummins Apr 19, 2022
8847e93
Merge connection_pool target to fix CMake build.
ChrisCummins Apr 19, 2022
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
1 change: 0 additions & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ jobs:
else
wget https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz -O ~/llvm.tar.xz
fi
# TODO(cummins): Remove 'v' debugging flag:
mkdir ~/llvm && tar xvf ~/llvm.tar.xz --strip-components 1 -C ~/llvm
rm ~/llvm.tar.xz
echo "Unpacked, testing for expected file:"
Expand Down
13 changes: 7 additions & 6 deletions benchmarks/bench_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
import gym
import pytest

import examples.example_compiler_gym_service as dummy
import examples.example_compiler_gym_service # noqa Environment import.
import examples.example_compiler_gym_service as dummy # noqa Environment import.
from compiler_gym.envs import CompilerEnv, LlvmEnv, llvm
from compiler_gym.service import CompilerGymServiceConnection
from compiler_gym.service import CompilerGymServiceConnection, ConnectionOpts
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
Expand All @@ -46,10 +47,10 @@ def env(request) -> CompilerEnv:

@pytest.mark.parametrize(
"env_id",
["llvm-v0", "example-cc-v0", "example-py-v0"],
ids=["llvm", "dummy-cc", "dummy-py"],
["llvm-v0", "example-cc-v0", "example-py-v0", "loop_tool-v0"],
ids=["llvm", "dummy-cc", "dummy-py", "loop_tool"],
)
def test_make_local(benchmark, env_id):
def test_make_env(benchmark, env_id):
benchmark(lambda: gym.make(env_id).close())


Expand All @@ -64,7 +65,7 @@ def test_make_local(benchmark, env_id):
)
def test_make_service(benchmark, args):
service_binary, env_class = args
service = CompilerGymServiceConnection(service_binary)
service = CompilerGymServiceConnection(service_binary, ConnectionOpts())
try:
benchmark(lambda: env_class(service=service.connection.url).close())
finally:
Expand Down
4 changes: 3 additions & 1 deletion compiler_gym/bin/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,9 @@ def main(argv):

if FLAGS.run_on_port:
assert FLAGS.env, "Must specify an --env to run"
settings = ConnectionOpts(script_args=["--port", str(FLAGS.run_on_port)])
settings = ConnectionOpts(
script_args=frozenset(["--port", str(FLAGS.run_on_port)])
)
with gym.make(FLAGS.env, connection_settings=settings) as env:
print(
f"=== Started a service on port {FLAGS.run_on_port}. Use C-c to terminate. ==="
Expand Down
2 changes: 1 addition & 1 deletion compiler_gym/envs/gcc/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

register(
id="gcc-v0",
entry_point="compiler_gym.envs.gcc:GccEnv",
entry_point="compiler_gym.envs.gcc.gcc_env:make",
kwargs={"service": GCC_SERVICE_BINARY},
)

Expand Down
34 changes: 32 additions & 2 deletions compiler_gym/envs/gcc/gcc_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import json
import pickle
from pathlib import Path
from threading import Lock
from typing import Any, Dict, List, Optional, Union

from compiler_gym.datasets import Benchmark
Expand All @@ -15,6 +16,7 @@
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.service.connection_pool import ServiceConnectionPoolBase
from compiler_gym.spaces import Reward
from compiler_gym.util.decorators import memoized_property
from compiler_gym.util.gym_type_hints import ObservationType, OptionalArgumentValue
Expand Down Expand Up @@ -63,9 +65,11 @@ def __init__(

:raises ServiceInitError: If the requested GCC version cannot be used.
"""
connection_settings = connection_settings or ConnectionOpts()
# Pass the executable path via an environment variable
connection_settings.script_env = {"CC": gcc_bin}
connection_settings = connection_settings or ConnectionOpts()
connection_settings.script_env = connection_settings.script_env.set(
"CC", gcc_bin
)

# Eagerly create a GCC compiler instance now because:
#
Expand All @@ -76,6 +80,13 @@ def __init__(
# initialization may time out.
Gcc(bin=gcc_bin)

# NOTE(github.com/facebookresearch/CompilerGym/pull/583): The GCC
# environment stalls on the StartSession() RPC call when service
# connection caching is enabled. I believe this has something to do with
# the runtime code generation, but have not been able to diagnose it
# yet. For now, disable service connection caching for GCC environments.
kwargs["service_pool"] = ServiceConnectionPoolBase()

super().__init__(
*args,
**kwargs,
Expand All @@ -88,6 +99,9 @@ def __init__(
)
self._timeout = timeout

def commandline_to_actions(self, commandline: str) -> List[int]:
return NotImplementedError

def reset(
self,
benchmark: Optional[Union[str, Benchmark]] = None,
Expand Down Expand Up @@ -213,3 +227,19 @@ def _init_kwargs(self) -> Dict[str, Any]:
"gcc_bin": self.gcc_spec.gcc.bin,
**super()._init_kwargs(),
}


_GCC_ENV_DOCKER_CONSTRUCTOR_LOCK = Lock()


def make(*args, gcc_bin: Union[str, Path] = DEFAULT_GCC, **kwargs):
"""Construct a GccEnv class using a lock to ensure thread exclusivity.

This is to prevent multiple threads running the docker initialization
routines simultaneously as this can cause issues with the docker API.
"""
if gcc_bin.startswith("docker:"):
with _GCC_ENV_DOCKER_CONSTRUCTOR_LOCK:
return GccEnv(*args, gcc_bin=gcc_bin, **kwargs)
else:
return GccEnv(*args, gcc_bin=gcc_bin, **kwargs)
4 changes: 4 additions & 0 deletions compiler_gym/envs/llvm/datasets/cbench.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,10 @@ def download_cBench_runtime_data() -> bool:
if (cbench_data / "unpacked").is_file():
return False
else:
logger.warning(
"Installing the cBench runtime inputs. This may take a few moments ..."
)

# Clean up any partially-extracted data directory.
if cbench_data.is_dir():
shutil.rmtree(cbench_data)
Expand Down
1 change: 1 addition & 0 deletions compiler_gym/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ absl-py>=0.10.0
deprecated>=1.2.12
docker>=4.0.0
fasteners>=0.15
frozendict>=1.0.0
grpcio>=1.32.0,<1.44.0
gym>=0.18.0,<0.21
humanize>=2.6.0
Expand Down
7 changes: 4 additions & 3 deletions compiler_gym/service/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ py_library(
name = "service",
srcs = [
"__init__.py",
"connection_pool.py",
],
visibility = ["//visibility:public"],
deps = [
":compilation_session",
":connection",
# TODO(github.com/facebookresearch/CompilerGym/pull/633):
# add this after circular dependencies are resolved
# add this after circular dependencies are resolved:
# ":client_service_compiler_env",
":compilation_session",
":connection",
":service_cache",
"//compiler_gym/errors",
"//compiler_gym/service/proto",
Expand Down
7 changes: 4 additions & 3 deletions compiler_gym/service/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ cg_py_library(
service
SRCS
"__init__.py"
"connection_pool.py"
DEPS
# TODO(github.com/facebookresearch/CompilerGym/pull/633):
# add this after circular dependencies are resolved:
# ::client_service_compiler_env
::compilation_session
::connection
# TODO(github.com/facebookresearch/CompilerGym/pull/633):
# add this after circular dependencies are resolved
#::client_service_compiler_env
::service_cache
compiler_gym::errors::errors
compiler_gym::service::proto::proto
Expand Down
4 changes: 3 additions & 1 deletion compiler_gym/service/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
ServiceTransportError,
SessionNotFound,
)
from compiler_gym.service.connection_pool import ServiceConnectionPool

__all__ = [
"CompilerGymServiceConnection",
"CompilationSession",
"CompilerGymServiceConnection",
"ConnectionOpts",
"EnvironmentNotSupported",
"ServiceConnectionPool",
"ServiceError",
"ServiceInitError",
"ServiceIsClosed",
Expand Down
Loading