Skip to content

Commit

Permalink
Merge pull request #572 from mit-ll-responsible-ai/explanation
Browse files Browse the repository at this point in the history
Improve docs
  • Loading branch information
rsokl authored Nov 8, 2023
2 parents 43948b1 + 22247e5 commit 6b81770
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 43 deletions.
32 changes: 16 additions & 16 deletions docs/source/api_reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,22 @@ Storing Configs
wrapper.default_to_config


**************************************
Creating and Launching Jobs with Hydra
**************************************

hydra-zen provides users the ability to launch a Hydra job via a
Python function instead of from a commandline interface.

.. currentmodule:: hydra_zen

.. autosummary::
:toctree: generated/

zen
launch
wrapper.Zen


Instantiating and Resolving Configs
***********************************
Expand Down Expand Up @@ -111,22 +127,6 @@ hydra_zen.typing
DataclassOptions
ZenConvert

**************************************
Creating and Launching Jobs with Hydra
**************************************

hydra-zen provides users the ability to launch a Hydra job via a
Python function instead of from a commandline interface.

.. currentmodule:: hydra_zen

.. autosummary::
:toctree: generated/

launch
zen
wrapper.Zen


.. _valid-types:

Expand Down
6 changes: 3 additions & 3 deletions docs/source/how_to/configuring_experiments.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ The application can then be executed using:
Creating Configurations for Particular "Experiments"
====================================================

Suppose that we frequently want to run our application using the following two configurations (which we will refer to as `aplite` and `nglite`, respectively)
Suppose that we frequently want to run our application using the following two configurations, which we will refer to as `aplite` and `nglite`, respectively.

.. code-block:: console
:caption: Manually running the so-called `aplite` configuration
Expand Down Expand Up @@ -131,7 +131,7 @@ Our objective is to be able run these experiments more concisely, as:

.. code-block:: console
$ python my_app.py +experiment=<aglite or nginx>
$ python my_app.py +experiment=<aplite or nglite>
To do this we implement new experiment configurations that:
Expand Down Expand Up @@ -182,7 +182,7 @@ Now the configuration for either "experiment" can be specified by-name from the

.. tab-set::

.. tab-item:: aplit
.. tab-item:: aplite

.. code-block:: console
:caption: 4 Running the `aplite` experiment
Expand Down
75 changes: 62 additions & 13 deletions docs/source/tutorials/add_cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,43 +18,56 @@ Add a Command Line Interface to Our Application
In this tutorial we will update our project so that it can be configured and launched
from a command line interface (CLI), using Hydra.

In the last section of the tutorial, we

- Defined a task function
- Created a config for that task function
- Ran the task function via `hydra_zen.launch(Config, task_function, overrides=<...>)`

In this section, we need to add our config to Hydra's config-store; this enables Hydra to generate a CLI from this config.

Modifying Our Project
=====================

Open ``my_app.py`` in your editor. We will make the following modifications to it:

1. Use :func:`hydra_zen.store` (`docs <https://mit-ll-responsible-ai.github.io/hydra-zen/generated/hydra_zen.ZenStore.html#hydra_zen.ZenStore>`_) to generate for our task function and to store it in Hydra's global config store.
1. Use :class:`hydra_zen.ZenStore` to store our config locally.
2. Add a ``__main__`` clause to our ``my_app.py`` script so that the script runs our task function.
3. Use :func:`hydra_zen.zen` to wrap the task function and to generate the CLI.
3. Within ``__main__`` populate Hydra's global config store so that Hydra can generate a CLI using our configs.
4. Use :func:`hydra_zen.zen` to wrap the task function and to generate the CLI.

Modify your script to match this:

.. code-block:: python
:caption: Contents of my_app.py:
from hydra_zen import store, zen
from hydra_zen import builds, zen, ZenStore
# 1) `hydra_zen.store generates a config for our task function
# and stores it locally under the entry-name "my_app"
@store(name="my_app")
# The same task function as before
def task_function(player1: str, player2: str):
# write the log with the names
with open("player_log.txt", "w") as f:
f.write("Game session log:\n")
f.write(f"Player 1: {player1}\n" f"Player 2: {player2}")
return player1, player2
# 2) Executing `python my_app.py [...]` will run our task function
Config = builds(task_function, populate_full_signature=True)
# 1) Create a local config store and store our config
store = ZenStore()
store(Config, name="my_app")
# 2) Adding our __main__ clause to our script.
# Executing `python my_app.py [...]` will generate a CLI for our running
# our task function
if __name__ == "__main__":
# 3) We need to add the configs from our local store to Hydra's
# global config store
# global config store
store.add_to_hydra_store()
# 4) Our zen-wrapped task function is used to generate
# the CLI, and to specify which config we want to use
# to configure the app by default
# 4) hydra_main generates a CLI based off of the config
# stored under the name "my_app", and will run
# `task_function`
zen(task_function).hydra_main(config_name="my_app",
version_base="1.1",
config_path=None,
Expand Down Expand Up @@ -135,6 +148,42 @@ Voilà! As demonstrated, our simple application can now be configured and launch
command line. It should be noted that we can still launch our app from a Python
console, using :func:`~hydra_zen.launch`, as we did :ref:`in the previous tutorial <launch-basic-app>`.


Streamlining Our Code
=====================

:class:`hydra_zen.ZenStore` has :ref:`auto-config capabilities <store-autoconf>` and it
can be used as a decorator. This enables us to both create and store a config for our task function in a single line.

.. code-block:: python
:caption: Streamlined version of my_app.py:
from hydra_zen import zen, ZenStore
store = ZenStore()
@store(name="my_app")
def task_function(player1: str, player2: str):
with open("player_log.txt", "w") as f:
f.write("Game session log:\n")
f.write(f"Player 1: {player1}\n" f"Player 2: {player2}")
return player1, player2
if __name__ == "__main__":
store.add_to_hydra_store()
zen(task_function).hydra_main(config_name="my_app",
version_base="1.1",
config_path=None,
)
Here, applying ``@store("my_app")`` to ``task_function`` is equivalent to

.. code-block:: python
store(builds(task_function, populate_full_signature=True), name="my_app")
Reference Documentation
=======================
Want a deeper understanding of how hydra-zen and Hydra work?
Expand Down
20 changes: 15 additions & 5 deletions docs/source/tutorials/basic_app.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ Create and Launch a Basic Application with Hydra
================================================

In this tutorial we will create a basic application that we can configure and launch
using Hydra. Although this project will be trivial, we will be introduced to the
using Hydra, within a Python program (the next section of the tutorial will introduce a
CLI). Although this project will be trivial, we will be introduced to the
overarching design that is used for any Hydra-based project, as well to the
core functionality provided by hydra-zen.

Expand Down Expand Up @@ -71,6 +72,9 @@ Hydra-based application:
1. A "config", which defines the configurable interface of our application.
2. A task function, which accepts the populated config, and whose body specifies the code that will be executed when our application is launched.

We will then use `hydra_zen.launch(Config, task_function, overrides=<...>)` to
configure and run our task-function from within a python program.

Once we create this typical Hydra app, we will iterate on it and simplify things by using how hydra-zen's :func:`hydra_zen.zen` wrapper.

Writing the Application
Expand All @@ -87,6 +91,9 @@ this file.
from hydra_zen import make_config, instantiate
Config = make_config("player1", "player2")
# A dataclass-type with fields
# - player1: Any
# - player2: Any
def task_function(cfg):
# cfg: Config
Expand Down Expand Up @@ -232,8 +239,6 @@ In the final section, let's see how we can simplify some of our code using speci
Simplifying Things with :func:`hydra_zen.zen`
---------------------------------------------

.. note:: This part of the tutorial requires ``hydra-zen v0.9.0`` or later to be installed.

We can simplify our task function, removing Hydra-specific logic from it, by using :func:`hydra_zen.zen`.

Let's update our task function in `my_app.py` to be a simple function whose signature determines the fields that will be extracted and instantiated from our config.
Expand All @@ -254,9 +259,14 @@ Then we can use :func:`hydra_zen.builds`, instead of :func:`hydra_zen.make_confi
return player1, player2
# auto-populates the fields of our configs based on the signature of
# `task_function`
Config = builds(new_task_function, populate_full_signature=True)
# `builds` auto-populates the fields of our config based on the
# signature of `task_function`
#
# `Config` is dataclass-type whose fields are
# - player1: str
# - player2: str
# - _target_: str = "my_app.task_function"
Wrapping this function as
Expand Down
6 changes: 0 additions & 6 deletions docs/source/tutorials/config_groups.rst
Original file line number Diff line number Diff line change
Expand Up @@ -201,13 +201,7 @@ over. Modify your ``my_app.py`` script to match the following code.
if __name__ == "__main__":
# We need to add the configs from our local store to Hydra's
# global config store
store.add_to_hydra_store()
# Our zen-wrapped task function is used to generate
# the CLI, and to specify which config we want to use
# to configure the app by default
zen(task_function).hydra_main(config_name="my_app",
version_base="1.1",
config_path=".",
Expand Down

0 comments on commit 6b81770

Please sign in to comment.