提交 eb552eef authored 作者: lucianopaz's avatar lucianopaz 提交者: Luciano Paz

Add guardrails for cxx -print-search-dirs failure

上级 2bb847cf
...@@ -2731,6 +2731,15 @@ def default_blas_ldflags(): ...@@ -2731,6 +2731,15 @@ def default_blas_ldflags():
shell=True, shell=True,
) )
(stdout, stderr) = p.communicate(input=b"") (stdout, stderr) = p.communicate(input=b"")
if p.returncode != 0:
warnings.warn(
"Pytensor cxx failed to communicate its search dirs. As a consequence, "
"it might not be possible to automatically determine the blas link flags to use.\n"
f"Command that was run: {config.cxx} -print-search-dirs\n"
f"Output printed to stderr: {stderr.decode(sys.stderr.encoding)}"
)
return []
maybe_lib_dirs = [ maybe_lib_dirs = [
[pathlib.Path(p).resolve() for p in line[len("libraries: =") :].split(":")] [pathlib.Path(p).resolve() for p in line[len("libraries: =") :].split(":")]
for line in stdout.decode(sys.stdout.encoding).splitlines() for line in stdout.decode(sys.stdout.encoding).splitlines()
......
...@@ -6,6 +6,7 @@ deterministic based on the input type and the op. ...@@ -6,6 +6,7 @@ deterministic based on the input type and the op.
""" """
import multiprocessing import multiprocessing
import os import os
import re
import sys import sys
import tempfile import tempfile
from unittest.mock import MagicMock, patch from unittest.mock import MagicMock, patch
...@@ -207,23 +208,51 @@ def cxx_search_dirs(blas_libs, mock_system): ...@@ -207,23 +208,51 @@ def cxx_search_dirs(blas_libs, mock_system):
yield f"libraries: ={d}".encode(sys.stdout.encoding), flags yield f"libraries: ={d}".encode(sys.stdout.encoding), flags
@pytest.fixture(
scope="function", params=[False, True], ids=["Working_CXX", "Broken_CXX"]
)
def cxx_search_dirs_status(request):
return request.param
@patch("pytensor.link.c.cmodule.std_lib_dirs", return_value=[]) @patch("pytensor.link.c.cmodule.std_lib_dirs", return_value=[])
@patch("pytensor.link.c.cmodule.check_mkl_openmp", return_value=None) @patch("pytensor.link.c.cmodule.check_mkl_openmp", return_value=None)
def test_default_blas_ldflags( def test_default_blas_ldflags(
mock_std_lib_dirs, mock_check_mkl_openmp, cxx_search_dirs mock_std_lib_dirs, mock_check_mkl_openmp, cxx_search_dirs, cxx_search_dirs_status
): ):
cxx_search_dirs, expected_blas_ldflags = cxx_search_dirs cxx_search_dirs, expected_blas_ldflags = cxx_search_dirs
mock_process = MagicMock() mock_process = MagicMock()
mock_process.communicate = lambda *args, **kwargs: (cxx_search_dirs, None) if cxx_search_dirs_status:
error_message = ""
mock_process.communicate = lambda *args, **kwargs: (cxx_search_dirs, b"")
mock_process.returncode = 0
else:
error_message = "Unsupported argument -print-search-dirs"
error_message_bytes = error_message.encode(sys.stderr.encoding)
mock_process.communicate = lambda *args, **kwargs: (b"", error_message_bytes)
mock_process.returncode = 1
with patch("pytensor.link.c.cmodule.subprocess_Popen", return_value=mock_process): with patch("pytensor.link.c.cmodule.subprocess_Popen", return_value=mock_process):
with patch.object( with patch.object(
pytensor.link.c.cmodule.GCC_compiler, pytensor.link.c.cmodule.GCC_compiler,
"try_compile_tmp", "try_compile_tmp",
return_value=(True, True), return_value=(True, True),
): ):
if cxx_search_dirs_status:
assert set(default_blas_ldflags().split(" ")) == set( assert set(default_blas_ldflags().split(" ")) == set(
expected_blas_ldflags.split(" ") expected_blas_ldflags.split(" ")
) )
else:
expected_warning = re.escape(
"Pytensor cxx failed to communicate its search dirs. As a consequence, "
"it might not be possible to automatically determine the blas link flags to use.\n"
f"Command that was run: {config.cxx} -print-search-dirs\n"
f"Output printed to stderr: {error_message}"
)
with pytest.warns(
UserWarning,
match=expected_warning,
):
assert default_blas_ldflags() == ""
def test_default_blas_ldflags_no_cxx(): def test_default_blas_ldflags_no_cxx():
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论