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

BUG Passes global configuration when spawning joblib jobs #17634

Merged
merged 12 commits into from
Sep 21, 2020

Conversation

thomasjpfan
Copy link
Member

@thomasjpfan thomasjpfan commented Jun 18, 2020

On master the global configuration flag would not be passed joblib jobs with a multiprocess backend:

from joblib import Parallel, delayed
from sklearn import get_config, config_context

def get_working_memory():
    return get_config()['working_memory']

with config_context(working_memory=123):
    results = Parallel(n_jobs=2)(
        delayed(get_working_memory)() for _ in range(2)
    )

results
# [1024, 1024]

XREF: joblib/joblib#1071

@rth
Copy link
Member

rth commented Jun 19, 2020

Thanks for detecting this and the issue at joblib! Let's see if there is a way to fix it on the joblib side (or maybe our config mechanism needs to be revisited). Using a parallel wrapper means that external users of joblib + scikit-learn would still run into this issue..

@adrinjalali
Copy link
Member

@rth do you have a proposal for a revised config handling?

@thomasjpfan
Copy link
Member Author

I have a "fun" proposal here: joblib/joblib#1071 (comment)

(Global config + doing things in parallel = fun)

@jnothman
Copy link
Member

We could just use os.environ to store the config?

@thomasjpfan
Copy link
Member Author

Storing them in the environment may not work: joblib/joblib#1064

@adrinjalali
Copy link
Member

Doesn't that depend on the backend? It should work as long as all those processes are on the same machine, doesn't it?

@ogrisel
Copy link
Member

ogrisel commented Jun 24, 2020

Maybe we could pass it as environment and make joblib / loky detect that environment has changed and re-spawn workers accordingly. That might be a bit expensive though.

@ogrisel
Copy link
Member

ogrisel commented Jun 24, 2020

Doesn't that depend on the backend? It should work as long as all those processes are on the same machine, doesn't it?

The threading backend should have no problem. multiprocessing + fork should work out of the box but it's broken in other ways and not available on windows.

loky and dask will need explicit config init.

@adrinjalali
Copy link
Member

I think I'm okay with this, but I'd probably move the code to fixes.py to have them all in the same place, and I think adding a linter to fail on importing joblib.delayed would be an overkill?

Copy link
Member

@jnothman jnothman left a comment

Choose a reason for hiding this comment

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

Apart from not being comfortable with the use of utils.fixes for something other than a backport, this looks great

@@ -136,13 +136,13 @@ check_files() {

if [[ "$MODIFIED_FILES" == "no_match" ]]; then
echo "No file outside sklearn/externals and doc/sphinxext has been modified"
else
# else
Copy link
Member

Choose a reason for hiding this comment

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

Is this still needed?

@thomasjpfan
Copy link
Member Author

Apart from not being comfortable with the use of utils.fixes for something other than a backport, this looks great

Should we use sklearn.utls._parallel like we had before?

@jnothman
Copy link
Member

jnothman commented Aug 27, 2020 via email

Copy link
Member

@adrinjalali adrinjalali left a comment

Choose a reason for hiding this comment

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

Apart from not being comfortable with the use of utils.fixes for something other than a backport, this looks great

This needs to be fixed in joblib upstream, and then it'll be removed, from that perspective, fixes.py is the right place for it I think.

Otherwise this LGTM. I'm happy to have it as a temporary workaround.

@@ -196,3 +200,21 @@ def _take_along_axis(arr, indices, axis):

fancy_index = tuple(fancy_index)
return arr[fancy_index]


def delayed(function, *args, **kwargs):
Copy link
Member

Choose a reason for hiding this comment

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

maybe add a comment like

remove when https://github.com/joblib/joblib/issues/1071 is fixed

?

@rth
Copy link
Member

rth commented Aug 29, 2020

This looks reasonable but would one among @lesteve @ogrisel or @tomMoral be also be able to review this, following discussion in joblib/joblib#1071?

@rth
Copy link
Member

rth commented Aug 29, 2020

Could you please also check that the vendored version of delayed, hasn't significantly changed for the supported versions of joblib?

@thomasjpfan
Copy link
Member Author

I looked at:

https://github.com/joblib/joblib/blob/19db4f58ac502a4bd01ab07aa31b2fc8756bcc3a/joblib/parallel.py#L302

from tags 0.11 to 0.16 and the function does the same thing.

After reading its implementation, we can use a simplified version in our utils.fixes for now:

def delayed(function):
    """Decorator used to capture the arguments of a function."""
    @functools.wraps(function)
    def delayed_function(*args, **kwargs):
        return _FuncWrapper(function), args, kwargs
    return delayed_function

This way we do not need to depend on a vendored version.

@cmarmo
Copy link
Member

cmarmo commented Sep 17, 2020

Hi @scikit-learn/core-devs, two approvals here: is something left? Or is it good to merge?

@adrinjalali
Copy link
Member

Since the last commit and hence the CI runs were from almost 3 weeks ago, I'm happy to merge once we do another merge with the current master. Would you mind updating @thomasjpfan ? I feel like we agreed to having this in the meantime.

@thomasjpfan
Copy link
Member Author

Merged with master and it still passes.

1 similar comment
@thomasjpfan
Copy link
Member Author

Merged with master and it still passes.

@adrinjalali
Copy link
Member

woohoo 🥳 let's do this then 👍

@adrinjalali adrinjalali merged commit 06d6f8a into scikit-learn:master Sep 21, 2020
jayzed82 pushed a commit to jayzed82/scikit-learn that referenced this pull request Oct 22, 2020
…rn#17634)

* WIP

* BUG Passes context to joblib jobs

* BUG Fix

* BUG Fix

* CLN Moves delayed into fixes

* CLN Adds linter

* REV Revert diff

* DOC Adds comment for removal

* Use a simple implementation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants