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 Joblib Launcher for parallel execution (multi-process and multi-threaded) #392

Merged
merged 53 commits into from Feb 12, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
3e83d0e
Add Parallel Launcher
jan-matthis Jan 31, 2020
f5d2986
Renamed to JoblibLauncher
jan-matthis Feb 2, 2020
6b5061c
moved lint to be first nox test
omry Feb 2, 2020
619a23f
pin master to OmegaConf 2.0.0rc4 until Structured configs branch lands
omry Feb 2, 2020
0ca221e
Implementing changes from first review
jan-matthis Feb 3, 2020
8e94d38
Using default config in test
jan-matthis Feb 3, 2020
263882a
Two test cases in task_launcher_cfg
jan-matthis Feb 3, 2020
17ff451
Add joblib to third_party
jan-matthis Feb 3, 2020
d2847a3
Fix SearchPath
jan-matthis Feb 3, 2020
dc0295c
Modify testcase 2 to have no defaults
jan-matthis Feb 3, 2020
6ffd77e
Changes after review round 2
jan-matthis Feb 4, 2020
d16cbb6
Rename plugin with hydra prefix
jan-matthis Feb 5, 2020
b284b68
Add news entry
jan-matthis Feb 5, 2020
af6d7ab
Change handling of Singleton state
jan-matthis Feb 5, 2020
5949bf9
None to null, add comments
jan-matthis Feb 5, 2020
4a9921a
Update README with comments on options
jan-matthis Feb 5, 2020
81a2616
Remove unused import
jan-matthis Feb 5, 2020
61a1f9a
Change folder name
jan-matthis Feb 5, 2020
2ebdc3e
Additional renaming for consistency with hydra_colorlog
jan-matthis Feb 5, 2020
0deaeb3
Newline
jan-matthis Feb 5, 2020
3b0d50c
Remove timestamps
jan-matthis Feb 5, 2020
6b01866
Add link to example
jan-matthis Feb 5, 2020
f77ac3f
Moving config.yaml to same folder as my_app.py for consistency with h…
jan-matthis Feb 5, 2020
4ada0ac
Add assertions for runs, fix job.id
jan-matthis Feb 5, 2020
69ebde8
Comments before variables
jan-matthis Feb 5, 2020
65ec255
Add no_output_timeout to linux and win tests
jan-matthis Feb 5, 2020
b4f0d41
Use default config for thread-based test
jan-matthis Feb 5, 2020
832ece5
Fix flake8
jan-matthis Feb 5, 2020
152d76c
Set no_output_timeout to 30m for mac and win
jan-matthis Feb 6, 2020
2e6c930
Add comments to tests
jan-matthis Feb 6, 2020
e2f29d8
Remove extra line
jan-matthis Feb 7, 2020
ac4e41f
Small docstring fix
jan-matthis Feb 7, 2020
2483955
Move configure_log up
jan-matthis Feb 8, 2020
8622db0
Remove configure_log, it is called inside of run_job
jan-matthis Feb 8, 2020
23fb20c
Rename HydraJoblibLauncher to JoblibLauncher
jan-matthis Feb 11, 2020
f38b342
Imports
jan-matthis Feb 12, 2020
7170eef
Add website
jan-matthis Feb 12, 2020
766f864
Disable thread-based test
jan-matthis Feb 12, 2020
3d43f6e
Add note about adding new pages
jan-matthis Feb 12, 2020
af70c54
Move website page
jan-matthis Feb 12, 2020
d226762
README.md as a pointer to website
jan-matthis Feb 12, 2020
74eb284
Reduce n_jobs to 2 (trying to debug CircleCI failures)
jan-matthis Feb 12, 2020
96744ec
Sort imports
jan-matthis Feb 12, 2020
d86c242
Sort imports
jan-matthis Feb 12, 2020
3b9cc8a
Restore IntegrationTest, limit TestSuite
jan-matthis Feb 12, 2020
d341d1d
Remove n_jobs limit again
jan-matthis Feb 12, 2020
1d10c9b
Revert to original tests; exclude windows
jan-matthis Feb 12, 2020
febcf68
Formatting
jan-matthis Feb 12, 2020
4a421f7
Mypy fix
jan-matthis Feb 12, 2020
9f92a1c
Add type ignore to decorator
jan-matthis Feb 12, 2020
b810010
updated description in intro
omry Feb 3, 2020
65b3517
Fix typos
nzw0301 Feb 7, 2020
7f2e75a
Work around CircleCI test coverage issue (#413)
omry Feb 12, 2020
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
28 changes: 19 additions & 9 deletions .circleci/config.yml
Expand Up @@ -15,7 +15,7 @@ jobs:
~/miniconda3/bin/conda init bash
- run:
name: "Testing Hydra"
no_output_timeout: 60m
no_output_timeout: 30m
command: |
export NOX_PYTHON_VERSIONS=3.6
~/miniconda3/bin/conda create -n hydra python=3.6 -q -y
Expand All @@ -35,7 +35,7 @@ jobs:
~/miniconda3/bin/conda init bash
- run:
name: "Testing Hydra"
no_output_timeout: 60m
no_output_timeout: 30m
command: |
export NOX_PYTHON_VERSIONS=3.7
~/miniconda3/bin/conda create -n hydra python=3.7 -q -y
Expand All @@ -55,7 +55,7 @@ jobs:
~/miniconda3/bin/conda init bash
- run:
name: "Testing Hydra"
no_output_timeout: 60m
no_output_timeout: 30m
command: |
export NOX_PYTHON_VERSIONS=3.8
~/miniconda3/bin/conda create -n hydra python=3.8 -q -y
Expand All @@ -66,13 +66,17 @@ jobs:
# Linux
py36_linux:
docker:
- image: circleci/python:3.6
# - image: circleci/python:3.6
# Temporary workaround around 3.6 image
- image: circleci/python@sha256:19a446501d3e0ca273ed3161eeca3780dadbc9e3f3a788c8fd2bc92f5ed9bed0
omry marked this conversation as resolved.
Show resolved Hide resolved
steps:
- checkout
- run: sudo apt-get install -y expect
- run: echo 'export NOX_PYTHON_VERSIONS=3.6' >> $BASH_ENV
- run: sudo pip install nox
- run: nox
- run:
name: "Testing Hydra"
command: nox

py37_linux:
docker:
Expand All @@ -82,7 +86,9 @@ jobs:
- run: sudo apt-get install -y expect
- run: echo 'export NOX_PYTHON_VERSIONS=3.7' >> $BASH_ENV
- run: sudo pip install nox
- run: nox
- run:
name: "Testing Hydra"
command: nox

py38_linux:
docker:
Expand All @@ -92,7 +98,9 @@ jobs:
- run: sudo apt-get install -y expect
- run: echo 'export NOX_PYTHON_VERSIONS=3.8' >> $BASH_ENV
- run: sudo pip install nox
- run: nox
- run:
name: "Testing Hydra"
command: nox

# windows
py36_win:
Expand All @@ -111,6 +119,7 @@ jobs:
conda run -n hydra pip install nox
- run:
name: Testing Hydra
no_output_timeout: 30m
command: |
$env:NOX_PYTHON_VERSIONS=3.6
$env:PYTHONIOENCODING="utf_8"
Expand All @@ -134,14 +143,15 @@ jobs:
conda run -n hydra pip install nox
- run:
name: Testing Hydra
no_output_timeout: 30m
command: |
$env:NOX_PYTHON_VERSIONS=3.7
$env:PYTHONIOENCODING="utf_8"
conda activate hydra
nox
exit $LASTEXITCODE

# TODO: test re-enable in a few months
# TODO: Test later, for now low priority
# py38_win:
# executor: win/default
# steps:
Expand Down Expand Up @@ -212,7 +222,7 @@ workflows:
# windows
- py36_win
- py37_win
# - py38_win
# - py38_win
- deploy-website:
filters:
branches:
Expand Down
3 changes: 2 additions & 1 deletion .coveragerc
Expand Up @@ -11,4 +11,5 @@ exclude_lines =
raise NotImplementedError
raise TypeError
@deprecated
assert False
assert False

2 changes: 1 addition & 1 deletion .isort.cfg
Expand Up @@ -5,5 +5,5 @@ force_grid_wrap=0
use_parentheses=True
line_length=88
ensure_newline_before_comments=True
known_third_party=omegaconf,ray,pytest,typing_extensions
known_third_party=joblib,omegaconf,ray,pytest,typing_extensions
known_first_party=hydra,hydra_plugins
1 change: 1 addition & 0 deletions news/392.plugin
@@ -0,0 +1 @@
Add Joblib Launcher plugin.
54 changes: 27 additions & 27 deletions noxfile.py
Expand Up @@ -75,6 +75,33 @@ def test_example_app(session, install_cmd):
)


@nox.session
def lint(session):
session.install("--upgrade", "setuptools", "pip")
# needed for isort to properly identify pytest as third party
session.install("pytest")
session.install(
"mypy",
"flake8",
"flake8-copyright",
"git+git://github.com/timothycrosley/isort.git@c54b3dd4620f9b3e7ac127c583ecb029fb90f1b7",
)
session.run("pip", "install", "-e", ".", silent=SILENT)
session.run("flake8", "--config", ".circleci/flake8_py3.cfg")

session.install("black")
# if this fails you need to format your code with black
session.run("black", "--check", ".")

session.run("isort", "--check", ".")

# Mypy
session.run("mypy", ".", "--strict")
# Mypy for plugins
for plugin in get_all_plugins():
session.run("mypy", os.path.join("plugins", plugin["path"]), "--strict")


@nox.session(python=PYTHON_VERSIONS)
@nox.parametrize(
"install_cmd",
Expand Down Expand Up @@ -189,33 +216,6 @@ def coverage(session):
session.run("coverage", "erase")


@nox.session
def lint(session):
session.install("--upgrade", "setuptools", "pip")
# needed for isort to properly identify pytest as third party
session.install("pytest")
session.install(
"mypy",
"flake8",
"flake8-copyright",
"git+git://github.com/timothycrosley/isort.git@c54b3dd4620f9b3e7ac127c583ecb029fb90f1b7",
)
session.run("pip", "install", "-e", ".", silent=SILENT)
session.run("flake8", "--config", ".circleci/flake8_py3.cfg")

session.install("black")
# if this fails you need to format your code with black
session.run("black", "--check", ".")

session.run("isort", "--check", ".")

# Mypy
session.run("mypy", ".", "--strict")
# Mypy for plugins
for plugin in get_all_plugins():
session.run("mypy", os.path.join("plugins", plugin["path"]), "--strict")


@nox.session(python=PYTHON_VERSIONS)
def test_jupyter_notebook(session):
versions = copy.copy(DEFAULT_PYTHON_VERSIONS)
Expand Down
3 changes: 3 additions & 0 deletions plugins/hydra_joblib_launcher/MANIFEST.in
@@ -0,0 +1,3 @@
global-exclude *.pyc
global-exclude __pycache__
recursive-include hydra_plugins/* *.yaml
2 changes: 2 additions & 0 deletions plugins/hydra_joblib_launcher/README.md
@@ -0,0 +1,2 @@
# Hydra Joblib Launcher
See [website](https://hydra.cc/docs/plugins/joblib_launcher) for more information
Copy link
Collaborator

Choose a reason for hiding this comment

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

Until 1.0.0 is released, the url will be:

https://hydra.cc/docs/next/plugins/joblib_launcher

4 changes: 4 additions & 0 deletions plugins/hydra_joblib_launcher/example/config.yaml
@@ -0,0 +1,4 @@
defaults:
- hydra/launcher: joblib

task: 1
19 changes: 19 additions & 0 deletions plugins/hydra_joblib_launcher/example/my_app.py
@@ -0,0 +1,19 @@
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
import logging
import os
import time

import hydra

log = logging.getLogger(__name__)


@hydra.main(config_path="config.yaml")
def my_app(cfg):
log.info(f"Process ID {os.getpid()} executing task {cfg.task} ...")

time.sleep(1)


if __name__ == "__main__":
my_app()
3 changes: 3 additions & 0 deletions plugins/hydra_joblib_launcher/hydra_plugins/__init__.py
@@ -0,0 +1,3 @@
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
# type: ignore
__path__ = __import__("pkgutil").extend_path(__path__, __name__)
@@ -0,0 +1,4 @@
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
from .joblib_launcher import JoblibLauncher

__all__ = ["JoblibLauncher"]
@@ -0,0 +1 @@
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
@@ -0,0 +1,39 @@
hydra:
launcher:
class: hydra_plugins.hydra_joblib_launcher.JoblibLauncher
params:
joblib: ${hydra.joblib}

joblib:
# maximum number of concurrently running jobs. if -1, all CPUs are used
n_jobs: -1

# allows to hard-code backend, otherwise inferred based on prefer and require
backend: null

# processes or threads, soft hint to choose backend
prefer: processes

# null or sharedmem, sharedmem will select thread-based backend
require: null

# if greater than zero, prints progress messages
verbose: 0

# timeout limit for each task
timeout: null

# number of batches to be pre-dispatched
pre_dispatch: 2*n_jobs

# number of atomic tasks to dispatch at once to each worker
batch_size: auto

# folder used for memmapping large arrays for sharing memory with workers
temp_folder: null

# thresholds size of arrays that triggers automated memmapping
max_nbytes: 1M

# memmapping mode for numpy arrays passed to workers
mmap_mode: r