2
2
import re
3
3
import os
4
4
from collections import namedtuple
5
+ from shutil import which
5
6
6
7
from numba .core .config import IS_WIN32
7
8
from numba .misc .findlib import find_lib , find_file
10
11
_env_path_tuple = namedtuple ('_env_path_tuple' , ['by' , 'info' ])
11
12
12
13
14
+ def find_executable (name , bindirs = None ):
15
+ # This should probably go into numba.misc.findlib
16
+ if bindirs is None :
17
+ return which (name ) # Check the path if we've been given no directories.
18
+
19
+ if isinstance (bindirs , str ):
20
+ bindirs = [bindirs ,]
21
+ else :
22
+ bindirs = list (bindirs )
23
+ files = []
24
+ for bdir in bindirs :
25
+ try :
26
+ entries = os .listdir (bdir )
27
+ except FileNotFoundError :
28
+ continue
29
+ candidates = [os .path .join (bdir , ent ) for ent in entries if name == ent ]
30
+ files .extend ([c for c in candidates if os .path .isfile (c )])
31
+ return files
32
+
33
+
13
34
def _find_valid_path (options ):
14
35
"""Find valid path from *options*, which is a list of 2-tuple of
15
36
(name, path). Return first pair where *path* is not None.
@@ -52,6 +73,18 @@ def _get_nvvm_path_decision():
52
73
return by , path
53
74
54
75
76
+ def _get_nvdisasm_path_decision ():
77
+ options = [
78
+ ('Conda environment' , get_conda_ctk ()),
79
+ ('Conda environment (NVIDIA package)' , get_nvidia_nvdisasm_ctk ()),
80
+ ('CUDA_HOME' , get_cuda_home ('bin' )),
81
+ ('System' , get_system_ctk ('bin' )),
82
+ ('Path' , None ),
83
+ ]
84
+ by , path = _find_valid_path (options )
85
+ return by , path
86
+
87
+
55
88
def _get_libdevice_paths ():
56
89
by , libdir = _get_libdevice_path_decision ()
57
90
# Search for pattern
@@ -161,6 +194,29 @@ def get_nvidia_nvvm_ctk():
161
194
return os .path .dirname (max (paths ))
162
195
163
196
197
+ def get_nvidia_nvdisasm_ctk ():
198
+ """Return path to directory containing the nvdisasm executable.
199
+ """
200
+ is_conda_env = os .path .exists (os .path .join (sys .prefix , 'conda-meta' ))
201
+ if not is_conda_env :
202
+ return
203
+
204
+ # Assume the existence of nvdisasm in the conda env implies that a CUDA
205
+ # toolkit conda package is installed.
206
+
207
+ # Try the location used on Linux and the Windows 11.x packages
208
+ bindir = os .path .join (sys .prefix , 'bin' )
209
+ if not os .path .exists (bindir ) or not os .path .isdir (bindir ):
210
+ return
211
+
212
+ paths = find_executable ('nvdisasm' , bindir )
213
+ if not paths :
214
+ return
215
+
216
+ # Use the directory name of the max path
217
+ return os .path .dirname (max (paths ))
218
+
219
+
164
220
def get_nvidia_libdevice_ctk ():
165
221
"""Return path to directory containing the libdevice library.
166
222
"""
@@ -220,6 +276,13 @@ def _get_nvvm_path():
220
276
return _env_path_tuple (by , path )
221
277
222
278
279
+ def _get_nvdisasm_path ():
280
+ by , path = _get_nvdisasm_path_decision ()
281
+ candidates = find_executable ('nvdisasm' , path )
282
+ path = max (candidates ) if candidates else None
283
+ return _env_path_tuple (by , path )
284
+
285
+
223
286
def get_cuda_paths ():
224
287
"""Returns a dictionary mapping component names to a 2-tuple
225
288
of (source_variable, info).
@@ -238,9 +301,10 @@ def get_cuda_paths():
238
301
# Not in cache
239
302
d = {
240
303
'nvvm' : _get_nvvm_path (),
304
+ 'nvdisasm' : _get_nvdisasm_path (),
241
305
'libdevice' : _get_libdevice_paths (),
242
306
'cudalib_dir' : _get_cudalib_dir (),
243
- 'static_cudalib_dir' : _get_static_cudalib_dir (),
307
+ 'static_cudalib_dir' : _get_static_cudalib_dir ()
244
308
}
245
309
# Cache result
246
310
get_cuda_paths ._cached_result = d
0 commit comments