Repository navigation
Expand file tree
/
Copy pathjit_diagnostics.py
More file actions
executable file
·197 lines (169 loc) · 6.63 KB
/
Copy pathjit_diagnostics.py
File metadata and controls
executable file
·197 lines (169 loc) · 6.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#!/usr/bin/env python
"""Print JIT diagnostic information for debugging compiler configuration.
Run with: python scripts/jit_diagnostics.py
This prints the GraphBLAS JIT configuration, available compilers, sysconfig
values, and attempts a JIT compilation to verify everything works.
"""
import os
import pathlib
import shutil
import sys
import sysconfig
import time
def main():
print("=" * 60)
print("JIT Diagnostics")
print("=" * 60)
print("\n--- Platform ---")
print(f"sys.platform: {sys.platform}")
print(f"Python: {sys.version}")
print("\n--- Environment ---")
conda = os.environ.get("CONDA_PREFIX", "")
print(f"CONDA_PREFIX: {conda or 'NOT SET'}")
print(f"GITHUB_ACTIONS: {os.environ.get('GITHUB_ACTIONS', 'NOT SET')}")
print("\n--- sysconfig ---")
for key in ["CC", "CXX", "CFLAGS", "LDFLAGS", "LIBS"]:
val = sysconfig.get_config_var(key)
if val and len(str(val)) > 100:
val = str(val)[:100] + "..."
print(f" {key}: {val}")
print(f" include: {sysconfig.get_path('include')}")
print("\n--- Compiler search ---")
candidates = ["cc", "gcc", "clang"]
if sys.platform == "linux":
candidates.append("x86_64-conda-linux-gnu-cc")
elif sys.platform == "darwin":
candidates.extend(
[
"x86_64-apple-darwin13.4.0-clang",
"arm64-apple-darwin20.0.0-clang",
]
)
for name in candidates:
which = shutil.which(name)
conda_path = pathlib.Path(conda) / "bin" / name if conda else None
conda_exists = conda_path.exists() if conda_path else False
print(f" {name}: which={which}, conda={'yes' if conda_exists else 'no'}")
# SuiteSparse built with MSVC (Windows) compiles only through cmake.
print(f" cmake: which={shutil.which('cmake')}")
# Import graphblas
try:
import graphblas as gb
gb.init("suitesparse")
except Exception as e:
print(f"\nERROR: Could not initialize graphblas: {e}")
return 1
from graphblas.core.ss import _IS_SSGB7
if _IS_SSGB7:
print("\nSuiteSparse:GraphBLAS 7.x: JIT not available")
return 0
print("\n--- GraphBLAS JIT settings after graphblas init ---")
for key in [
"jit_c_control",
"jit_use_cmake",
"jit_c_compiler_name",
"jit_c_compiler_flags",
"jit_c_linker_flags",
"jit_c_libraries",
"jit_c_cmake_libs",
"jit_cache_path",
]:
val = gb.ss.config[key]
if isinstance(val, str) and len(val) > 120:
val = val[:120] + "..."
print(f" {key}: {val}")
# Check if default compiler exists
jit_cc = gb.ss.config["jit_c_compiler_name"]
print("\n--- Compiler path analysis ---")
print(f" Default compiler: {jit_cc}")
print(f" Exists? {pathlib.Path(jit_cc).exists()}")
cc_basename = pathlib.Path(jit_cc).name
if conda:
local_cc = pathlib.Path(conda) / "bin" / cc_basename
print(f" Conda equivalent: {local_cc}")
print(f" Exists? {local_cc.exists()}")
fallback_cc = pathlib.Path(conda) / "bin" / "cc"
print(f" Fallback (cc): {fallback_cc}")
print(f" Exists? {fallback_cc.exists()}")
# Check for problematic flags
flags = gb.ss.config["jit_c_compiler_flags"]
import re
if isysroot := re.search(r"-isysroot\s+(\S+)", flags):
path = isysroot.group(1)
print(f"\n -isysroot: {path}")
print(f" Exists? {pathlib.Path(path).exists()}")
fdebug = re.findall(r"-fdebug-prefix-map=(\S+)", flags)
for d in fdebug:
print(f" -fdebug-prefix-map: {d}")
# Try the fix
print("\n--- Attempting gb.ss.fix_jit_config ---")
result = gb.ss.fix_jit_config()
descs = {True: "working", False: "probe failed", None: "no compiler found to repair from"}
desc = descs[result]
print(f" Result: {result} ({desc})")
if result is True:
print(f" Compiler: {gb.ss.config['jit_c_compiler_name']}")
flags_after = gb.ss.config["jit_c_compiler_flags"]
if len(flags_after) > 120:
flags_after = flags_after[:120] + "..."
print(f" Flags: {flags_after}")
# Try JIT compilation
print("\n--- JIT compilation test ---")
if gb.ss.config["jit_c_control"] == "off":
print(" SKIPPED (JIT is off)")
else:
try:
from graphblas import dtypes
prev_burble = gb.ss.config["burble"]
gb.ss.config["burble"] = True
start = time.perf_counter()
dtype = dtypes.ss.register_new(
"jit_diag_test",
"typedef struct { int val ; } jit_diag_test ;",
)
seconds = time.perf_counter() - start
gb.ss.config["burble"] = prev_burble
print(f" SUCCESS: registered type '{dtype.name}' in {seconds:.2f} s")
except Exception as e:
print(f" FAILED: {type(e).__name__}: {e}")
try:
err_log = gb.ss.config["jit_error_log"]
if err_log:
print(f" JIT error log: {err_log[:500]}")
except Exception:
pass
# What GRAPHBLAS_JIT_C_CONTROL=on does at init: it probes the compiler, or
# cmake where SuiteSparse compiles with it, and falls back to 'run'. A probe
# compiled through cmake times about the least a new kernel costs there.
print("\n--- jit_c_control 'on', as init sets it ---", flush=True)
from graphblas.core.ss import jit_config
probe_seconds = []
probe_jit = jit_config._probe_jit
def timed_probe(cfg):
start = time.perf_counter()
try:
return probe_jit(cfg)
finally:
probe_seconds.append(time.perf_counter() - start)
jit_config._probe_jit = timed_probe
prev_burble = gb.ss.config["burble"]
gb.ss.config["burble"] = True
try:
jit_config._set_jit_c_control_at_init("on")
finally:
gb.ss.config["burble"] = prev_burble
jit_config._probe_jit = probe_jit
print(f" Result: {gb.ss.config['jit_c_control']}")
via = "cmake" if gb.ss.config["jit_use_cmake"] else "the C compiler"
if probe_seconds:
print(f" Probe through {via}: {probe_seconds[0]:.2f} s (compile, or load if cached)")
else:
print(f" No probe: {via} not found, the cache not writable, or SuiteSparse has no JIT")
# Print final JIT state
print("\n--- Final JIT state ---")
print(f" jit_c_control: {gb.ss.config['jit_c_control']}")
print(f" jit_c_compiler_name: {gb.ss.config['jit_c_compiler_name']}")
print(f"\n{'=' * 60}")
return 0
if __name__ == "__main__":
raise SystemExit(main())