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

FIX-#4564: Workaround import issues in Ray: auto-import pandas on python start if env var is set #4603

Merged
merged 18 commits into from
Jul 7, 2022

Conversation

vnlitvinov
Copy link
Collaborator

@vnlitvinov vnlitvinov commented Jun 24, 2022

What do these changes do?

Based on what I found in #4564 (comment), I think the real root cause of #4564 (and other similar issues with inability to import pandas) is the Python bug https://bugs.python.org/issue38884, which rises from the fact that they seem to have dropped the idea of the import lock in Python 3.3+.

This PR aims to workaround that by doing the following:

  1. Create special .pth file to be shipped which, when package is installed, is placed under site-packages automatically and, when processed by Python interpreter, imports pandas if special environment variable is set
  2. Change setup.py so this special file is part of both source and binary distributions
  3. Initialize Ray so it sets this environment variable on each worker
  4. Check Ray configuration if Ray was pre-initialized and warn the user to set the variables if they don't match
  • commit message follows format outlined here
  • passes flake8 modin/ asv_bench/benchmarks scripts/doc_checker.py
  • passes black --check modin/ asv_bench/benchmarks scripts/doc_checker.py
  • signed commit with git commit -s
  • Resolves BUG: ray 1.13 breaks CI, including test_binary and test_pickle, with circular import #4564
  • tests added and passing
  • module layout described at docs/development/architecture.rst is up-to-date
  • added (Issue Number: PR title (PR Number)) and github username to release notes for next major release

Signed-off-by: Vasily Litvinov <fam1ly.n4me@yandex.ru>
Signed-off-by: Vasily Litvinov <fam1ly.n4me@yandex.ru>
Signed-off-by: Vasily Litvinov <fam1ly.n4me@yandex.ru>
Signed-off-by: Vasily Litvinov <fam1ly.n4me@yandex.ru>
@vnlitvinov vnlitvinov requested a review from a team as a code owner June 24, 2022 13:10
Signed-off-by: Vasily Litvinov <fam1ly.n4me@yandex.ru>
@vnlitvinov vnlitvinov changed the title Workaround import issues in Ray: auto-import pandas on python start if env var is set FIX-#4564: Workaround import issues in Ray: auto-import pandas on python start if env var is set (#4603) Jun 24, 2022
@vnlitvinov vnlitvinov changed the title FIX-#4564: Workaround import issues in Ray: auto-import pandas on python start if env var is set (#4603) FIX-#4564: Workaround import issues in Ray: auto-import pandas on python start if env var is set Jun 24, 2022
@codecov
Copy link

codecov bot commented Jun 24, 2022

Codecov Report

Merging #4603 (01682b0) into master (7181569) will increase coverage by 3.13%.
The diff coverage is 100.00%.

@@            Coverage Diff             @@
##           master    #4603      +/-   ##
==========================================
+ Coverage   86.56%   89.69%   +3.13%     
==========================================
  Files         230      231       +1     
  Lines       18470    18734     +264     
==========================================
+ Hits        15988    16803     +815     
+ Misses       2482     1931     -551     
Impacted Files Coverage Δ
modin/utils.py 93.66% <ø> (+13.93%) ⬆️
modin/config/envvars.py 89.10% <100.00%> (+3.46%) ⬆️
modin/core/execution/ray/common/utils.py 95.23% <100.00%> (-1.64%) ⬇️
modin/experimental/batch/test/test_pipeline.py 100.00% <0.00%> (ø)
modin/pandas/base.py 95.30% <0.00%> (+0.08%) ⬆️
...mentations/pandas_on_ray/partitioning/partition.py 93.57% <0.00%> (+1.83%) ⬆️
...tations/pandas_on_python/partitioning/partition.py 93.75% <0.00%> (+2.08%) ⬆️
...entations/pandas_on_dask/partitioning/partition.py 91.46% <0.00%> (+2.43%) ⬆️
modin/pandas/__init__.py 69.69% <0.00%> (+3.03%) ⬆️
... and 15 more

📣 Codecov can now indicate which changes are the most critical in Pull Requests. Learn more

Copy link
Collaborator

@devin-petersohn devin-petersohn left a comment

Choose a reason for hiding this comment

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

This looks pretty good, although it introduces minor friction for users who want to get started and initialize Ray themselves. Probably need extra documentation or something because we recommend users to start the engine themselves.

Can you add runtime env to an already running Ray cluster?

Copy link
Contributor

@prutskov prutskov left a comment

Choose a reason for hiding this comment

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

How does it work in the case I didn't install modin? Suppose, I'm working in modin-root folder.

@vnlitvinov
Copy link
Collaborator Author

Can you add runtime env to an already running Ray cluster?

You can set runtime env even on per-task basis, but in this case it won't have any particular effect as the interpreter in each worker has already been initialized.

As for docs... I'm open for suggestions on where to put things.

How does it work in the case I didn't install modin? Suppose, I'm working in modin-root folder.

Obviously, it won't have the workaround effect, but TBH this isn't the main use case, plus I personally never saw this issue locally. If someone is really bothered by this issue, one could pip install . to enable the workaround.

Signed-off-by: Vasily Litvinov <fam1ly.n4me@yandex.ru>
@vnlitvinov
Copy link
Collaborator Author

For hinting the users on how to initialize Ray, this is how current (in this PR) warning look like:

>>> import modin.pandas as pd
UserWarning: The pandas version installed 1.4.2 does not match the supported pandas version in Modin 1.4.3. This may cause undesired side effects!
>>> df=pd.DataFrame({})
UserWarning: Ray execution environment not yet initialized. Initializing...
To remove this warning, run the following python code before doing dataframe operations:

    import ray
    ray.init(runtime_env={'env_vars': {'__MODIN_AUTOIMPORT_PANDAS_WORKAROUND__': '1'}})

UserWarning: Distributing <class 'dict'> object. This may take some time.

@Garra1980
Copy link
Collaborator

Whoa, poor user, so many extra info...

@vnlitvinov
Copy link
Collaborator Author

It was like this for quite a while, but before this PR it simply stated ray.init() without parameters:

UserWarning: The pandas version installed 1.4.2 does not match the supported pandas version in Modin 1.4.3. This may cause undesired side effects!
UserWarning: Ray execution environment not yet initialized. Initializing...
To remove this warning, run the following python code before doing dataframe operations:

    import ray
    ray.init()

UserWarning: Distributing <class 'dict'> object. This may take some time.

modin-autoimport-pandas.pth Outdated Show resolved Hide resolved
modin/core/execution/ray/common/utils.py Outdated Show resolved Hide resolved
modin/core/execution/ray/common/utils.py Show resolved Hide resolved
@YarShev
Copy link
Collaborator

YarShev commented Jun 27, 2022

What do you think if we leave the warning as is (just import ray; ray.init()) when initializing Ray by users themselves, and put a paragraph regarding race condition in the troubleshooting page?

@vnlitvinov
Copy link
Collaborator Author

I don't think adding a little bit of info in our warning would make any harm, but I think it would harm user's experience when they would receive some spurious failures until they would realize that there is a troubleshooting guide on that...

Signed-off-by: Vasily Litvinov <fam1ly.n4me@yandex.ru>
@@ -138,17 +87,16 @@ def initialize_ray(
include_dashboard=False,
ignore_reinit_error=True,
_redis_password=redis_password,
**extra_init_kw,
Copy link
Contributor

@prutskov prutskov Jun 27, 2022

Choose a reason for hiding this comment

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

Did you check this case? I can't find that extra parameters could be provided in case of existing cluster https://github.com/ray-project/ray/blob/master/python/ray/_private/worker.py#L1400-L1412

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I hadn't, but apparently extra ones would just get ignored, and, if in the future we'll add more arguments than runtime_env it would be useful.

As for the runtime environment being different, there is a code later on checking the variables. It should give a warning to the user.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I hadn't, but apparently extra ones would just get ignored, and, if in the future we'll add more arguments than runtime_env it would be useful.

Can you elaborate why it would be useful?

As for the runtime environment being different, there is a code later on checking the variables. It should give a warning to the user.

What the code do you mean?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Can you elaborate why it would be useful?

This creates one central place to add more arguments to ray.init() instead of copy-pasting them in several different places.

What the code do you mean?

else: # ray is already initialized, check runtime env config
env_vars = ray.get_runtime_context().runtime_env.get("env_vars", {})
for varname, varvalue in extra_init_kw["runtime_env"]["env_vars"].items():
if str(env_vars.get(varname, "")) != str(varvalue):
ErrorMessage.single_warning(
"If initialising Ray yourself, please ensure its runtime env "
+ f"sets environment variable {varname} to {varvalue}"
)

Copy link
Collaborator

Choose a reason for hiding this comment

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

We don't hit this branch in case of cluster init.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Huh?.. we either call ray.init() or hit this else: branch.

We hit ray.init() at line 84 (under if cluster:) or at line 158 (in else branch of that if cluster).

Copy link
Collaborator

Choose a reason for hiding this comment

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

I was just wondering if we should check the runtime environment after ray.init() in case Modin itself initializes Ray? Because of this.

Did you check this case? I can't find that extra parameters could be provided in case of existing cluster https://github.com/ray-project/ray/blob/master/python/ray/_private/worker.py#L1400-L1412

I hadn't, but apparently extra ones would just get ignored

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

good point!

modin/core/execution/ray/common/utils.py Outdated Show resolved Hide resolved
setup.py Outdated Show resolved Hide resolved
@YarShev
Copy link
Collaborator

YarShev commented Jun 27, 2022

As for docs... I'm open for suggestions on where to put things.

What about modin.config - https://modin.readthedocs.io/en/stable/flow/modin/config.html?

@YarShev
Copy link
Collaborator

YarShev commented Jul 4, 2022

@vnlitvinov, that is fine to me. Please also take into account my previous comments, which are unresolved.

Copy link
Collaborator

@devin-petersohn devin-petersohn left a comment

Choose a reason for hiding this comment

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

@vnlitvinov looks great! There are a couple of comments here about cluster-related handling.

Copy link
Collaborator

@RehanSD RehanSD left a comment

Choose a reason for hiding this comment

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

Left a quick change as well as a question

modin/core/execution/ray/common/utils.py Outdated Show resolved Hide resolved
)
ray.worker.global_worker.run_function_on_all_workers(_import_pandas)
else: # ray is already initialized, check runtime env config
env_vars = ray.get_runtime_context().runtime_env.get("env_vars", {})
Copy link
Collaborator

Choose a reason for hiding this comment

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

This only checks that the head nodes env vars are set correctly, right? Don't we need to set the environment variable on all of the workers/nodes, and if so, shouldn't we be checking that the env vars are set correctly on all of the workers? We could probably do that using the ray function that runs on all workers.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No, .runtime_env is the thing which tells Ray which environment variables to set for its workers. It should set these variables for the workers automatically.

vnlitvinov and others added 3 commits July 7, 2022 16:53
Co-authored-by: Rehan Sohail Durrani <rdurrani@berkeley.edu>
Signed-off-by: Vasily Litvinov <fam1ly.n4me@yandex.ru>
Signed-off-by: Vasily Litvinov <fam1ly.n4me@yandex.ru>
@YarShev
Copy link
Collaborator

YarShev commented Jul 7, 2022

@vnlitvinov, build docs job failed because of AttributeError: partially initialized module 'pandas' has no attribute 'core' (most likely due to a circular import). Do you think why that happened?

@vnlitvinov
Copy link
Collaborator Author

Huh, when I look at the CI of the last commit (887a5f4) docs are built fine. Am I missing things?

@YarShev
Copy link
Collaborator

YarShev commented Jul 7, 2022

@vnlitvinov
Copy link
Collaborator Author

Thanks. I've missed an empty line after .. code-block:: thingy, which broke sphinx. Fixed.

Signed-off-by: Vasily Litvinov <fam1ly.n4me@yandex.ru>
Copy link
Collaborator

@YarShev YarShev left a comment

Choose a reason for hiding this comment

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

@vnlitvinov, LGTM, thanks!

@YarShev YarShev merged commit 05933a5 into modin-project:master Jul 7, 2022
@Garra1980
Copy link
Collaborator

So green light for python 3.10 support? :)

@vnlitvinov vnlitvinov deleted the workaround-ray-imports branch July 8, 2022 15:46
@vnlitvinov
Copy link
Collaborator Author

Technically yes, though note that Ray still does not have published 1.13 in conda-forge...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BUG: ray 1.13 breaks CI, including test_binary and test_pickle, with circular import
7 participants