Skip to content

Commit

Permalink
Merge pull request #41 from rdnfn/dev/general
Browse files Browse the repository at this point in the history
v0.4.1
  • Loading branch information
rdnfn authored Mar 30, 2022
2 parents 27fdc4f + 74c08e8 commit eae5ce2
Show file tree
Hide file tree
Showing 26 changed files with 258 additions and 140 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -117,5 +117,5 @@ wandb/
docs/generated/

#beobench
beobench_results/
beobench_results*
notebooks/archive
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/psf/black
rev: 21.9b0
rev: 22.3.0
hooks:
- id: black
language_version: python3.9
Expand Down
8 changes: 8 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@
History
=======

0.4.1 (2022-03-30)
------------------

* Feature: enable package extras to be given in development mode
* Feature: add support for arm64/aarch64-based development by forcing experiment containers to run as amd64 containers on those systems (#32)
* Fix: add gym to extended package requirements


0.4.0 (2022-03-28)
------------------

Expand Down
5 changes: 3 additions & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ include README.rst
include PYPI_README.rst

recursive-include tests *
recursive-exclude * __pycache__
recursive-exclude * *.py[co]

recursive-include beobench/experiment/definitions *
recursive-exclude beobench/experiment/definitions/archive/ *

recursive-exclude docs *.rst conf.py Makefile make.bat *.jpg *.png *.gif
recursive-exclude * __pycache__
recursive-exclude * *.py[co]
2 changes: 1 addition & 1 deletion beobench/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

__author__ = """rdnfn"""
__email__ = "-"
__version__ = "0.4.0"
__version__ = "0.4.1"

from beobench.utils import restart
from beobench.experiment.scheduler import run
2 changes: 1 addition & 1 deletion beobench/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def cli():
)
@click.option(
"--local-dir",
default="./beobench_results/ray_results",
default="./beobench_results",
help="Local directory to write results to.",
type=click.Path(exists=False, file_okay=False, dir_okay=True),
)
Expand Down
23 changes: 19 additions & 4 deletions beobench/data/configs/rewex01.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,38 @@
# Run with the command
# beobench run -c beobench/experiment/definitions/rewex01.yaml -d . --use-gpu --docker-shm-size 28gb

# Some of the descriptions of RLlib config values are taken from
# https://docs.ray.io/en/latest/rllib/rllib-training.html

# agent config
agent:
origin: rllib # either path to agent script or name of agent library (rllib)
config: # given to ray.tune.run() as arguments (since rllib set before)
run_or_experiment: PPO
stop:
timesteps_total: 400000
timesteps_total: 35040
config:
lr: 0.005
lr: 0.0005
model:
fcnet_activation: relu
fcnet_hiddens: [256,256,256,256]
post_fcnet_activation: tanh
batch_mode: complete_episodes
gamma: 0.999
horizon: 1000
metrics_smoothing_episodes: 5
# Number of steps after which the episode is forced to terminate. Defaults
# to `env.spec.max_episode_steps` (if present) for Gym envs.
horizon: 96
# Calculate rewards but don't reset the environment when the horizon is
# hit. This allows value estimation and RNN state to span across logical
# episodes denoted by horizon. This only has an effect if horizon != inf.
soft_horizon: True
# Number of timesteps collected for each SGD round. This defines the size
# of each SGD epoch.
train_batch_size: 94 # single day of 15min steps
# Total SGD batch size across all devices for SGD. This defines the
# minibatch size within each epoch.
sgd_minibatch_size: 24
metrics_smoothing_episodes: 1
framework: torch
log_level: "WARNING"
num_workers: 1 # this is required for energym to work (can fail silently otherwise)
Expand Down
2 changes: 1 addition & 1 deletion beobench/data/configs/rewex01_test01.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# REWEX Experiment 01
# Run with the command
# beobench run -c beobench/data/configs/rewex01_test01.yaml -d . --use-gpu --docker-shm-size 28gb
# beobench run -c beobench/data/configs/rewex01_test01.yaml -d .[extended] --use-gpu --docker-shm-size 28gb

# agent config
agent:
Expand Down
19 changes: 19 additions & 0 deletions beobench/data/configs/rewex01_test02.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# REWEX Experiment 02
# Run with the command
# beobench run -c beobench/data/configs/rewex01_test02.yaml -d .[extended] --use-gpu --docker-shm-size 28gb

# agent config
agent:
origin: beobench/data/agents/random_agent.py # either path to agent script or name of agent library (rllib)
# environment config
env:
name: MixedUseFanFCU-v0
gym: energym
config:
days: 365
energym_environment: MixedUseFanFCU-v0
gym_kwargs:
max_episode_length: 35040
normalize: true
step_period: 15
weather: GRC_A_Athens
52 changes: 38 additions & 14 deletions beobench/experiment/containers.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

import subprocess
import os
import pathlib
import shutil

# To enable compatiblity with Python<=3.6 (e.g. for sinergym dockerfile)
try:
Expand All @@ -16,8 +18,9 @@
def build_experiment_container(
build_context: str,
use_no_cache: bool = False,
version="latest",
enable_rllib=False,
local_dir: pathlib.Path = None,
version: str = "latest",
enable_rllib: bool = False,
) -> None:
"""Build experiment container from beobench/integrations/boptest/Dockerfile.
Expand All @@ -27,26 +30,49 @@ def build_experiment_container(
of existing beobench integration (e.g. `boptest`). See the official docs
https://docs.docker.com/engine/reference/commandline/build/ for more info.
use_no_cache (bool, optional): wether to use cache in build. Defaults to False.
version (str, optional): version to add to container tag. Defaults to "latest".
enable_rllib (bool, optional): whether to install rllib. Defaults to False.
"""

# Flags are shared between gym image build and gym_and_beobench image build
flags = []

# Using buildx to enable platform-specific builds
build_commands = ["docker", "buildx", "build"]

# On arm64 machines force experiment containers to be amd64
# This is only useful for development purposes.
# (example: M1 macbooks)
if os.uname().machine in ["arm64", "aarch64"]:
flags += ["--platform", "linux/amd64"]

if use_no_cache:
flags.append("--no-cache")

# pylint: disable=invalid-name
AVAILABLE_INTEGRATIONS = [
"boptest",
"sinergym",
"energym",
] # pylint: disable=invalid-name
]

if build_context in AVAILABLE_INTEGRATIONS:
image_name = f"beobench_{build_context}"
integration_name = build_context
build_context = (
f"https://github.com/rdnfn/"
f"beobench_contrib.git#main:gyms/{build_context}"

# TODO: remove tmp git dir once buildkit version in docker cli updated
tmp_git_dir = (local_dir / "tmp" / "beobench_contrib").absolute()
subprocess.check_call(
[
"git",
"clone",
"https://github.com/rdnfn/beobench_contrib.git",
tmp_git_dir,
]
)

build_context = str(tmp_git_dir / "gyms" / integration_name)

print(
(
f"Recognised integration named {integration_name}: using build"
Expand All @@ -64,17 +90,14 @@ def build_experiment_container(

# Part 1: build base experiment image
args = [
"docker",
"build",
*build_commands,
"-t",
base_image_tag,
"-f",
"Dockerfile", # change to non-default name
*flags,
build_context,
]
env = os.environ.copy()
env["DOCKER_BUILDKIT"] = "0"
print("Running command: " + " ".join(args))
subprocess.check_call(
args,
env=env, # this enables accessing dockerfile in subdir
Expand All @@ -92,14 +115,13 @@ def build_experiment_container(
# Which extras to install beobench container
# e.g. using pip install beobench[extras]
if enable_rllib:
beobench_extras = '"extended,rllib"'
beobench_extras = "extended,rllib"
else:
beobench_extras = "extended"
# Load dockerfile into pipe
with subprocess.Popen(["cat", complete_dockerfile], stdout=subprocess.PIPE) as proc:
beobench_build_args = [
"docker",
"build",
*build_commands,
"-t",
complete_image_tag,
"-f",
Expand All @@ -118,6 +140,8 @@ def build_experiment_container(
env=env, # this enables accessing dockerfile in subdir
)

# TODO: remove tmp git dir once buildkit version in docker cli updated
shutil.rmtree(tmp_git_dir)
print("Experiment gym image build finished.")

return complete_image_tag
Expand Down
2 changes: 1 addition & 1 deletion beobench/experiment/dockerfiles/Dockerfile.experiment
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ ARG GYM_IMAGE
FROM ${GYM_IMAGE}

# install beobench
ARG EXTRAS="extended, rllib"
ARG EXTRAS="extended,rllib"
RUN pip3 --disable-pip-version-check --no-cache-dir install "beobench[${EXTRAS}]"

# add env creator
Expand Down
27 changes: 20 additions & 7 deletions beobench/experiment/scheduler.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
"""Module to schedule experiments."""

from cgitb import enable
import os
import uuid
import subprocess
Expand Down Expand Up @@ -56,7 +55,7 @@ def run(
overwrites any env set in experiment file. Defaults to None.
local_dir (str, optional): Directory to write experiment files to. This argument
is equivalent to the `local_dir` argument in `tune.run()`. Defaults to
`"./beobench_results/ray_results"`.
`"./beobench_results"`.
wandb_project (str, optional): Name of wandb project. Defaults to
"initial_experiments".
wandb_entity (str, optional): Name of wandb entity. Defaults to "beobench".
Expand Down Expand Up @@ -86,7 +85,7 @@ def run(
# Create a definition of experiment from inputs
if experiment_file is not None:
warnings.warn(
"The experiment_file argmunent has been replaced by config",
"The experiment_file argument has been replaced by config",
DeprecationWarning,
)
if agent_file is not None:
Expand Down Expand Up @@ -125,19 +124,22 @@ def run(
# build and run experiments in docker container

### part 1: build docker images
# Ensure local_dir exists, and create otherwise
local_dir_path = pathlib.Path(local_dir)
local_dir_path.mkdir(parents=True, exist_ok=True)

enable_rllib = config["agent"]["origin"] == "rllib"
image_tag = beobench.experiment.containers.build_experiment_container(
build_context=config["env"]["gym"],
use_no_cache=use_no_cache,
enable_rllib=enable_rllib,
local_dir=local_dir_path,
)

### part 2: create args and run command in docker container
docker_flags = []

# Ensure local_dir exists, and create otherwise
local_dir_path = pathlib.Path(local_dir)
local_dir_path.mkdir(parents=True, exist_ok=True)
### create path to store ray results at
ray_path_abs = str((local_dir_path / "ray_results").absolute())

# Save config to local dir and add mount flag for config
Expand Down Expand Up @@ -216,6 +218,17 @@ def run(
if "https" in dev_path:
cmd_list_in_container.append(f"pip install {dev_path}")
else:
if "[" in dev_path:
dev_paths = dev_path.split("[")
if len(dev_paths) > 2:
raise ValueError(
f"Dev path does not appear compatible: {dev_path}"
)
dev_path = dev_paths[0]
dev_extras = "[" + dev_paths[1]
else:
dev_extras = ""

# mount local beobench repo
dev_path = pathlib.Path(dev_path)
dev_abs = dev_path.absolute()
Expand All @@ -228,7 +241,7 @@ def run(
f"cp -r {dev_path_on_docker}_mount {dev_path_on_docker}"
)
cmd_list_in_container.append(
f"python -m pip install {dev_path_on_docker}"
f"python -m pip install {dev_path_on_docker}{dev_extras}"
)

cmd_in_container = " && ".join(cmd_list_in_container)
Expand Down
3 changes: 2 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
"sphinx.ext.viewcode",
"sphinx.ext.autosummary",
"sphinx_tabs.tabs",
"myst_parser",
# "myst_parser",
# "m2r2",
]

# Add any paths that contain templates here, relative to this directory.
Expand Down
Loading

0 comments on commit eae5ce2

Please sign in to comment.