Sequential Quantum Gate Decomposer  v1.9.6
Powerful decomposition of general unitarias into one- and two-qubit gates gates
find_numpy_blas_dir.py
Go to the documentation of this file.
1 #!/usr/bin/env python3
2 """
3 Utility script invoked from CMake to locate the BLAS directory used by NumPy.
4 
5 The script mirrors the previous inline CMake/Python logic by trying the more
6 recent NumPy APIs first, then falling back to older mechanisms, finally
7 defaulting to the standard ``../lib`` location inside the NumPy installation.
8 It prints the detected directory to stdout.
9 """
10 
11 from __future__ import annotations
12 
13 import os
14 import sys
15 from pathlib import Path
16 
17 
18 def _try_new_api(numpy_module) -> str | None:
19  """Attempt to locate BLAS directory using newer NumPy internals."""
20  try:
21  # Import triggers newer API availability check (NumPy >= 1.21)
22  from numpy._core._multiarray_umath import __cpu_features__ # noqa: F401
23  except Exception:
24  return None
25 
26  numpy_dir = Path(numpy_module.__file__).resolve().parent
27  candidates = [
28  numpy_dir / ".." / "lib",
29  numpy_dir / ".." / ".." / "lib",
30  Path("/usr/lib"),
31  Path("/usr/local/lib"),
32  ]
33 
34  for path in candidates:
35  abs_path = path.resolve()
36  if abs_path.exists():
37  return str(abs_path)
38  return None
39 
40 
41 def _try_config_api(numpy_module) -> str | None:
42  """Fallback to NumPy's configuration metadata."""
43  try:
44  blas_info = numpy_module.__config__.get_info("blas_opt_info")
45  except Exception:
46  return None
47 
48  libs = blas_info.get("library_dirs", []) if isinstance(blas_info, dict) else []
49  if libs:
50  return os.path.abspath(libs[0])
51  return None
52 
53 
54 def _default_path(numpy_module) -> str:
55  """Final fallback: assume BLAS resides in ../lib next to NumPy."""
56  numpy_dir = Path(numpy_module.__file__).resolve().parent
57  return str((numpy_dir / ".." / "lib").resolve())
58 
59 
60 def main() -> int:
61  try:
62  import numpy # type: ignore
63  except Exception as exc: # pragma: no cover - guard for CMake invocation
64  print(f"Failed to import numpy: {exc}", file=sys.stderr)
65  return 1
66 
67  for resolver in (_try_new_api, _try_config_api):
68  try:
69  result = resolver(numpy)
70  except Exception:
71  result = None
72  if result:
73  print(result)
74  return 0
75 
76  # Last resort
77  print(_default_path(numpy))
78  return 0
79 
80 
81 if __name__ == "__main__":
82  raise SystemExit(main())
83 
def _try_new_api(numpy_module)
def _default_path(numpy_module)
def _try_config_api(numpy_module)