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

Running huge test suites on Windows causes [WinError 206] The filename or extension is too long #485

Closed
michaelosthege opened this issue Jun 20, 2021 · 2 comments
Labels
Windows wontfix This will not be worked on

Comments

@michaelosthege
Copy link
Contributor

michaelosthege commented Jun 20, 2021

Description

When running large test suites such as test_distributions.py from PyMC3, the following error can appear:

FileNotFoundError: [WinError 206] The filename or extension is too long: 'c:\\miniconda\\envs\\pymc3-dev-py38\\library\\mingw-w64\\bin'

It originates from cmodule.py", line 294, in dlimport.

Full traceback
================================== FAILURES ===================================
____________________ test_orderedlogistic_dimensions[(1,)] ____________________

shape = (1,)

    @pytest.mark.parametrize("shape", [tuple(), (1,), (3, 1), (3, 2)], ids=str)
    def test_orderedlogistic_dimensions(shape):
        # Test for issue #3535
        loge = np.log10(np.exp(1))
        size = 7
        p = np.ones(shape + (10,)) / 10
        cutpoints = np.tile(logit(np.linspace(0, 1, 11)[1:-1]), shape + (1,))
        obs = np.random.randint(0, 2, size=(size,) + shape)
        with Model():
            ol = OrderedLogistic(
                "ol",
                eta=np.zeros(shape),
                cutpoints=cutpoints,
                observed=obs,
            )
            c = Categorical(
                "c",
                p=p,
                observed=obs,
            )
>       ologp = logpt_sum(ol, np.ones_like(obs)).eval() * loge

pymc3\tests\test_distributions.py:2891: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\graph\basic.py:550: in eval
    self._fn_cache[inputs] = function(inputs, self)
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\compile\function\__init__.py:337: in function
    fn = pfunc(
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\compile\function\pfunc.py:524: in pfunc
    return orig_function(
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\compile\function\types.py:1983: in orig_function
    fn = m.create(defaults)
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\compile\function\types.py:1838: in create
    _fn, _i, _o = self.linker.make_thunk(
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\basic.py:282: in make_thunk
    return self.make_all(
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\vm.py:1133: in make_all
    node.op.make_thunk(node, storage_map, compute_map, [], impl=impl)
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\graph\op.py:659: in make_thunk
    return self.make_c_thunk(node, storage_map, compute_map, no_recycling)
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\graph\op.py:625: in make_c_thunk
    outputs = cl.make_thunk(
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\c\basic.py:1204: in make_thunk
    cthunk, module, in_storage, out_storage, error_storage = self.__compile__(
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\c\basic.py:1139: in __compile__
    thunk, module = self.cthunk_factory(
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\c\basic.py:1635: in cthunk_factory
    module = get_module_cache().module_from_key(key=key, lnk=self)
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\c\cmodule.py:1198: in module_from_key
    module = lnk.compile_cmodule(location)
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\c\basic.py:1544: in compile_cmodule
    module = c_compiler.compile_str(
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\c\cmodule.py:2564: in compile_str
    return dlimport(lib_filename)
C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\c\cmodule.py:294: in dlimport
    os.add_dll_directory(os.path.dirname(gcc_path))
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

path = 'c:\\miniconda\\envs\\pymc3-dev-py38\\library\\mingw-w64\\bin'

    def add_dll_directory(path):
        """Add a path to the DLL search path.
    
        This search path is used when resolving dependencies for imported
        extension modules (the module itself is resolved through sys.path),
        and also by ctypes.
    
        Remove the directory by calling close() on the returned object or
        using it in a with statement.
        """
        import nt
>       cookie = nt._add_dll_directory(path)
E       FileNotFoundError: [WinError 206] The filename or extension is too long: 'c:\\miniconda\\envs\\pymc3-dev-py38\\library\\mingw-w64\\bin'

C:\Miniconda\envs\pymc3-dev-py38\lib\os.py:1109: FileNotFoundError
---------------------------- Captured stderr call -----------------------------
ERROR (aesara.link.c.cmodule): [WinError 206] The filename or extension is too long: 'c:\\miniconda\\envs\\pymc3-dev-py38\\library\\mingw-w64\\bin'
ERROR (aesara.graph.opt): Optimization failure due to: constant_folding
ERROR (aesara.graph.opt): node: All{1}(TensorConstant{(1, 10) of True})
ERROR (aesara.graph.opt): TRACEBACK:
ERROR (aesara.graph.opt): Traceback (most recent call last):
  File "C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\graph\opt.py", line 2014, in process_node
    replacements = lopt.transform(fgraph, node)
  File "C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\graph\opt.py", line 1187, in transform
    return self.fn(*args, **kwargs)
  File "C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\tensor\basic_opt.py", line 4355, in constant_folding
    thunk = node.op.make_thunk(node, storage_map, compute_map, no_recycling=[])
  File "C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\graph\op.py", line 659, in make_thunk
    return self.make_c_thunk(node, storage_map, compute_map, no_recycling)
  File "C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\graph\op.py", line 625, in make_c_thunk
    outputs = cl.make_thunk(
  File "C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\c\basic.py", line 1204, in make_thunk
    cthunk, module, in_storage, out_storage, error_storage = self.__compile__(
  File "C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\c\basic.py", line 1139, in __compile__
    thunk, module = self.cthunk_factory(
  File "C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\c\basic.py", line 1635, in cthunk_factory
    module = get_module_cache().module_from_key(key=key, lnk=self)
  File "C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\c\cmodule.py", line 1198, in module_from_key
    module = lnk.compile_cmodule(location)
  File "C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\c\basic.py", line 1544, in compile_cmodule
    module = c_compiler.compile_str(
  File "C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\c\cmodule.py", line 2564, in compile_str
    return dlimport(lib_filename)
  File "C:\Miniconda\envs\pymc3-dev-py38\lib\site-packages\aesara\link\c\cmodule.py", line 294, in dlimport
    os.add_dll_directory(os.path.dirname(gcc_path))
  File "C:\Miniconda\envs\pymc3-dev-py38\lib\os.py", line 1109, in add_dll_directory
    cookie = nt._add_dll_directory(path)
FileNotFoundError: [WinError 206] The filename or extension is too long: 'c:\\miniconda\\envs\\pymc3-dev-py38\\library\\mingw-w64\\bin'

The first thing one finds when researching solutions are problems with git bash not supporting long file paths.
But this error appears only when the entire tests file is run, and the path shown in the error message is clearly not too long.

When run individually these tests pass!

My best guess is that the PATH has a maximum length that is exceeded by the add_dll_directory operation when its executed over and over again in the test suite.

Not sure if there's an easy solution by removing DLL directories again?
Otherwise we can mark this as won't fix. I just wanted to make sure it's documented.

Versions and main components

  • Aesara version: 2.0.11
  • Python version: 3.8
  • Operating system: Windows, Windows in Docker
@michaelosthege
Copy link
Contributor Author

ping @brandonwillard it looks like I no longer have permissions to set issue labels

michaelosthege added a commit to michaelosthege/pymc that referenced this issue Jun 20, 2021
But don't run tests_distributions.py on Windows because it runs into aesara-devs/aesara#485
@brandonwillard brandonwillard added Windows wontfix This will not be worked on labels Jun 21, 2021
@brandonwillard
Copy link
Member

This appears to be an issue specific to Python's os.add_dll_directory and/or Windows, and not an issue with Aesara, so I'm going to close this for now.

If you have a reason to believe that Aesara is doing something it shouldn't be doing with those paths (e.g. adding too many, adding ones that aren't needed, etc.), then, please, open an issue for that; one containing an illustration of the bad path(s) in an MWE.

twiecki pushed a commit to pymc-devs/pymc that referenced this issue Jun 23, 2021
* Analyze included/excluded test files based on YAML job matrix

Compared to the previous regex-based approach, this can distinguish by OS and floatX setting, allowing for more informative outputs.

* Merge Windows workflow with pytest workflow

Closes #4517

* Run more Windows tests and use cmd shell

But don't run tests_distributions.py on Windows because it runs into aesara-devs/aesara#485
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Windows wontfix This will not be worked on
Projects
None yet
Development

No branches or pull requests

2 participants