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

Add docs publishing pipeline and switch back to poetry #28

Merged
merged 30 commits into from
Apr 5, 2022
Merged
Show file tree
Hide file tree
Changes from 21 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
18 changes: 18 additions & 0 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
common: &common
plugins:
- EmbarkStudios/k8s#1.2.10:
service-account-name: monorepo-ci
image: gcr.io/embark-shared/ml/monorepo-controller@sha256:aad8ab820105ea1c0dea9dad53b1d1853b92eee93a4a7e3663fe0b265806fa8c
default-secret-name: buildkite-k8s-plugin
always-pull: true

agents:
cluster: builds-fi-2
queue: monorepo-ci
size: small

steps:
- label: 📚 Publish docs
command: bash .buildkite/publish-docs.sh

<< : *common
39 changes: 39 additions & 0 deletions .buildkite/publish-docs.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
set -eo pipefail

echo --- Installing dependencies

apt-get update \
&& apt-get install --no-install-recommends -y \
curl \
build-essential

export PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=off \
PIP_DISABLE_PIP_VERSION_CHECK=on \
PIP_DEFAULT_TIMEOUT=100 \
POETRY_VERSION=1.2.0b1 \
POETRY_HOME="/tmp/poetry" \
POETRY_VIRTUALENVS_IN_PROJECT=true \
POETRY_NO_INTERACTION=1 \

pip install poetry==1.2.0b1
poetry install
poetry env info --path


echo --- Initializing gcloud

curl https://sdk.cloud.google.com > install.sh && \
bash install.sh --disable-prompts 2>&1 && \
/root/google-cloud-sdk/install.sh --path-update true --usage-reporting false --quiet

if [ -f '/root/google-cloud-sdk/path.bash.inc' ]; then . '/root/google-cloud-sdk/path.bash.inc'; fi
gcloud config set account monorepo-ci@embark-builds.iam.gserviceaccount.com

echo --- Building docs
pushd docs
poetry env info --path
make deploy
gsutil rsync -r ./_build/dirhtml gs://embark-static/emote-docs
popd
13 changes: 11 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
__pycache__/
# Editor polution
.vscode
.dir-locals.el

# General python junk
__pycache__/
*.egg-info
*.onnx
.coverage

# CI/CD/Tooling
docs/_build
docs/generated
docs/coverage.rst

# Program outputs
*.onnx
runs/**
9 changes: 7 additions & 2 deletions docs/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SPHINXOPTS ?=
SPHINXBUILD ?= poetry run sphinx-build
SOURCEDIR = .
BUILDDIR = _build

Expand All @@ -18,3 +18,8 @@ help:
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

deploy:
@$(SPHINXBUILD) -M coverage "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
cp "$(BUILDDIR)/coverage/python.txt" "$(SOURCEDIR)/coverage.rst"
@$(SPHINXBUILD) -M dirhtml "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
32 changes: 32 additions & 0 deletions docs/_templates/autosummary/class.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{{ objname | escape | underline}}

.. currentmodule:: {{ module }}

.. autoclass:: {{ objname }}
:members:
:show-inheritance:
:inherited-members:

{% block methods %}
.. automethod:: __init__

{% if methods %}
.. rubric:: {{ _('Methods') }}

.. autosummary::
{% for item in methods %}
~{{ name }}.{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}

{% block attributes %}
{% if attributes %}
.. rubric:: {{ _('Attributes') }}

.. autosummary::
{% for item in attributes %}
~{{ name }}.{{ item }}
{%- endfor %}
{% endif %}
{% endblock %}
54 changes: 54 additions & 0 deletions docs/callback.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
emote.callback
==============

.. currentmodule:: emote.callback
.. automodule:: emote.callback

In this module you'll find the callback framework used by Emote. Those
who have used FastAI before will recognize it, as it's heavily
inspired by that system - but adapted for RL and our use-cases.

The `Callback` interface
########################

The callback is the core interface used to hook into the Emote framework. You can think of these as events - when the training loop starts, we'll invoke `begin_training` on all callback objects. Then we'll start a new cycle, and call :meth:`Callback.begin_cycle`.

All in all, the flow of callbacks is like this:

.. graphviz::

digraph foo {
rankdir=LR;
node [shape=rectangle,style="rounded"]

newrank=true;
{ rank=same; begin_cycle; begin_batch; }
{ rank=same; end_batch; end_cycle; }

begin_training;
subgraph cluster_cycle {
label = "while cycles left"
begin_cycle;

subgraph cluster_batch {
label = "while batches left";
begin_batch;
backward;
end_batch;
}
end_cycle;
}
end_training;

begin_training -> begin_cycle -> begin_batch -> backward -> end_batch;

end_batch -> begin_batch [constraint=no];
end_cycle -> begin_cycle [constraint=no];

end_batch -> end_cycle [style=dashed]
end_cycle -> end_training [style=dashed]
}

.. autoclass:: Callback
:members:
:member-order: bysource
7 changes: 7 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,15 @@
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx.ext.autosummary",
"sphinx.ext.autodoc",
"sphinx.ext.coverage",
"sphinx.ext.graphviz",
"sphinx_autodoc_typehints",
]

#autodoc_mock_imports = ["dataclasses"]

# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]

Expand All @@ -43,6 +49,7 @@
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]

add_module_names = False

# -- Options for HTML output -------------------------------------------------

Expand Down
5 changes: 5 additions & 0 deletions docs/coverage.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Undocumented Python objects
===========================

To generate this file, run `make deploy`! Do not check it in.

6 changes: 6 additions & 0 deletions docs/emote.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
emote
======

.. automodule:: emote
.. currentmodule:: emote

24 changes: 19 additions & 5 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,31 @@ sense that we could easily swap the algorithm we used and how data was collected
but also in the sense that the different parts of various algorithms could be reused
to build other algorithms.

.. automodule:: emote


.. toctree::
:maxdepth: 2
:caption: Contents:
:caption: Design
:hidden:

.. automodule:: emote
:members:
self

.. toctree::
:maxdepth: 6
:caption: API Documentation
:hidden:

Indices and tables
==================
emote
memory
callback

.. toctree::
:caption: Extras
:hidden:

Undocumented code <coverage.rst>

* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
117 changes: 117 additions & 0 deletions docs/memory.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
emote.memory
============

.. currentmodule:: emote.memory
.. automodule:: emote.memory

This module contains all the major building blocks for our memory
implementation. The memory was developed in the same time period as
`DeepMind's Reverb <https://www.deepmind.com/open-source/reverb>`_, and shares
naming with it, which in turn is borrowing from databases. What is not
alike Reverb is that we do not have the RateSamplers (but it can be
added). We also do not share data between ArrayTables.

The goal of the memory is to provide a unified interface for all types of
machine learning tasks. This is achieved by focusing on configuration and
pluggability over code-driven functionality.

Currently, there are three main points of customization:

* Shape and type of data
* Insertion, sampling, and eviction
* Data transformation and generation

High-level parts
----------------

ArrayTable
##########

A table is a datastructure containing a specific type of data that shares the same high-level structure.

.. autosummary::
:toctree: generated

Table

Columns and Virtual Columns
######

A column is a storage for a specific type of data where each item is
the same shape and type. A virtual column is like a column, but it
references another column and does data synthesization or modification
w.r.t that. For example, dones and masks are synthetic data based only
on indices.

.. autosummary::
:toctree: generated

column.Column
column.TagColumn
column.VirtualColumn

Adaptors
########

Adaptors are another approach to virtual column but are more suited for
transforming the whole batch, such as scaling for reshaping specific
datas. Since this step occurs when the data has already been converted to
tensors, the full power of Tensorflow is available here and gradients will be
correctly tracked.

.. autosummary::
:toctree: generated

adaptors.DictObsAdaptor
adaptors.KeyScaleAdaptor
adaptors.KeyCastAdaptor
adaptors.KeyScaleAdaptor
adaptors.TerminalAdaptor

Strategies, Samplers and Ejectors
#################################

Strategies are based on the delegate pattern, where we can inject implementation
details through objects instead of using inheritance. Strategies define the API
for sampling and ejection from memories, and are queried from the table upon
sampling and insertion.

Samplers and Ejectors track the data (but do not own it!). They are used by the
table for sampling and ejection based on the policy they implement. Currently we
have Fifo and Uniform samplers and ejectors, but one could have prioritized
samplers/ejectors, etc.

.. topic:: Bases

.. autosummary::
:toctree: generated

strategy.Strategy
strategy.SampleStrategy
strategy.EjectionStrategy

fifo_strategy.FifoStrategyBase
uniform_strategy.UniformStrategyBase

.. topic:: Samplers

.. autosummary::
:toctree: generated

fifo_strategy.FifoSampleStrategy
uniform_strategy.UniformSampleStrategy


.. topic:: Samplers

.. autosummary::
:toctree: generated

fifo_strategy.FifoEjectionStrategy
uniform_strategy.UniformEjectionStrategy


.. contents:: emote.memory
:depth: 3
:local:
:backlinks: top
3 changes: 3 additions & 0 deletions emote/callback.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,12 @@ def __init__(self, cycle=0):
self.cycle = cycle

def begin_training(self, *args, **kwargs):
'''Called when training starts, both from scratch and when restoring
from a checkpoint.'''
pass

def begin_cycle(self, *args, **kwargs):
'''Called at the start of each cycle.'''
pass

def begin_batch(self, *args, **kwargs):
Expand Down
Loading