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

Issues with multiprocessing #242

Closed
twsl opened this issue Dec 23, 2021 · 5 comments
Closed

Issues with multiprocessing #242

twsl opened this issue Dec 23, 2021 · 5 comments

Comments

@twsl
Copy link

twsl commented Dec 23, 2021

I am having issues with multiprocessing triggering this error message:

raise ValueError("Internal error - config has not been correctly loaded. Please report")

Here is a minimal example to recreate the issue.

from pytest_cases import parametrize_with_cases
from torch.multiprocessing import Pool, set_start_method

from functools import partial


class TestCases:
    def case_1(self):
        return 2, 4

    def case_2(self):
        return 3, 9


def f(a, b, t):
    if t:
        assert a ** 2 == b
    else:
        assert not (a ** 2 == b)


@parametrize_with_cases("x,y", cases=TestCases)
def test_f_xy(x, y):

    # set_start_method("spawn")
    pool = Pool(processes=2)
    pool.starmap(partial(f), [(x, y, False), (x, y, True)])

Is multiprocessing not supported?

@twsl
Copy link
Author

twsl commented Dec 26, 2021

Added an example to recreate the issue. When running the test it just keep retrying.

@smarie
Copy link
Owner

smarie commented Jan 3, 2022

Thanks @twsl ! Multiprocessing should definitely supported, if it is supported by pytest.

As a workaround I guess that you can put the multiprocessing code in a separate module (for example the conftest.py or another file in the tests folder). That should prevent pytest-cases to be loaded several times in parallel.

I'll have a look one of these days

@smarie
Copy link
Owner

smarie commented Jan 7, 2022

I was able to reproduce the issue.
First, we can check that it works with pytest:

from multiprocessing import Pool

import pytest
from functools import partial

def f(a, b, t):
    if t:
        assert a ** 2 == b
    else:
        assert not (a ** 2 == b)

@pytest.mark.parametrize("x,y", [(2, 4), (3, 9)])
def test_f_xy(x, y):
    pool = Pool(processes=2)
    pool.starmap(partial(f), [(x, y, False), (x, y, True)])

Running it yields to the two tests failing as expected, and it completes correctly.

While the following hangs as you point out:

from pytest_cases import parametrize_with_cases
from multiprocessing import Pool

from functools import partial


class TestCases:
    def case_1(self):
        return 2, 4

    def case_2(self):
        return 3, 9

def f(a, b, t):
    if t:
        assert a ** 2 == b
    else:
        assert not (a ** 2 == b)

@parametrize_with_cases("x,y", cases=TestCases)
def test_f_xy(x, y):
    pool = Pool(processes=2)
    pool.starmap(partial(f), [(x, y, False), (x, y, True)])

@smarie
Copy link
Owner

smarie commented Jan 7, 2022

Apparently we can detect if a process is the main process using this:

try:
    from multiprocessing import parent_process
except ImportError:
    from multiprocessing import current_process
    from multiprocessing.process import _MainProcess

    def is_main_process():
        return isinstance(current_process(), _MainProcess)
else:
    def is_main_process():
        return parent_process() is None

We could therefore use this to only raise the ValueError if not is_main_process.
See https://stackoverflow.com/questions/30790660/python-multiprocessing-name-of-the-main-process

However if we spawn a single process like below, then is_main_process seems to return True

p = Process(target=partial(f), args=(x, y, True))
p.start()
p.join()

So this workaround is not satisfaying. I will therefore simply comment the error-raising line, hoping that it will not make harder to debug a future situation where the config is None.

@smarie smarie closed this as completed in aa69d7c Jan 7, 2022
@smarie
Copy link
Owner

smarie commented Jan 7, 2022

Should be fixed in 3.6.8. let me know !

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

No branches or pull requests

2 participants