-
Notifications
You must be signed in to change notification settings - Fork 234
Set GMT_SESSION_NAME to a unique name on Windows for multiprocessing support #2938
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
Changes from all commits
12383e1
07ae8f1
236f874
04646ad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,10 @@ | ||
| """ | ||
| Test the session management modules. | ||
| """ | ||
| import multiprocessing as mp | ||
| import os | ||
| from importlib import reload | ||
| from pathlib import Path | ||
|
|
||
| import pytest | ||
| from pygmt.clib import Session | ||
|
|
@@ -57,3 +60,29 @@ def test_gmt_compat_6_is_applied(capsys): | |
| # Make sure no global "gmt.conf" in the current directory | ||
| assert not os.path.exists("gmt.conf") | ||
| begin() # Restart the global session | ||
|
|
||
|
|
||
| def _gmt_func_wrapper(figname): | ||
| """ | ||
| A wrapper for running PyGMT scripts with multiprocessing. | ||
|
|
||
| Currently, we have to import pygmt and reload it in each process. Workaround from | ||
| https://github.com/GenericMappingTools/pygmt/issues/217#issuecomment-754774875. | ||
| """ | ||
| import pygmt | ||
|
|
||
| reload(pygmt) | ||
| fig = pygmt.Figure() | ||
| fig.basemap(region=[10, 70, -3, 8], projection="X8c/6c", frame="afg") | ||
| fig.savefig(figname) | ||
|
|
||
|
|
||
| def test_session_multiprocessing(): | ||
| """ | ||
| Make sure that multiprocessing is supported if pygmt is re-imported. | ||
| """ | ||
| prefix = "test_session_multiprocessing" | ||
| with mp.Pool(2) as p: | ||
| p.map(_gmt_func_wrapper, [f"{prefix}-1.png", f"{prefix}-2.png"]) | ||
| Path(f"{prefix}-1.png").unlink() | ||
| Path(f"{prefix}-2.png").unlink() | ||
|
Comment on lines
+86
to
+88
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should probably use GMTTempFile or a try-except block to remove the files automatically, even if the multiprocessing function fails.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Likely not necessary here. If anything wrong happens, the two PNG files won't be generated, and |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I thought this should best be handled upstream in GMT, but then I saw the note from https://github.com/GenericMappingTools/gmt/blob/104bcdbafd13eb96260b445910ce3587a362dbc0/src/gmt_api.c#L1050-L1057:
Would setting a unique
GMT_SESSION_NAMEhere in PyGMT result in any issues then? I couldn't rungit blameon those lines to find out more context.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This note (https://docs.generic-mapping-tools.org/dev/begin.html#note-on-unix-shells) is also useful. So, the key point for how GMT modern mode works is having a unique and invariable value so that GMT modules know where to find the session directory and the historical information. The value can be either the constant PPID or a number manually set by
GMT_SESSION_NAME.All tests still pass, so I believe it has no side effects.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, but maybe we should check if
GMT_SESSION_NAMEis set by the user first before overriding it. Something like this maybe (untested):Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Users should NEVER set
GMT_SESSION_NAMEas a global environment variable. Even if they setGMT_SESSION_NAME, we should override it in PyGMT, otherwise multiprocessing won't work.Here are steps to understand why
GMT_SESSION_NAMEshould be overridden. Open a terminal, define the variable:and run
gmt begin. Then you'll see the session directory~/.gmt/sessions/gmt_session.123456/; all information will be saved in this directory. So, if a globalGMT_SESSION_NAMEis set, processes will write information and output to the same directory, leading to crashes.