Skip to content

Commit b380c1d

Browse files
authored
Refactor initialization logic to allow for automatic detection in Fedora (#788)
1 parent 53fb762 commit b380c1d

File tree

4 files changed

+102
-24
lines changed

4 files changed

+102
-24
lines changed

docs/src/index.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@ Pkg.add("AMDGPU")
4848
!!! note "On Windows AMD Software"
4949
Adrenalin Edition contains HIP library itself, while ROCm provides support for other functionality.
5050

51+
!!! note "On Fedora ROCm packages"
52+
Although not included in the AMD's list of supported Linux distributions,
53+
Fedora provides its own ROCM packages.
54+
```
55+
sudo dnf install rocminfo rccl-devel rocblas-devel rocfft-devel rocsparse-devel rocsolver-devel rocrand-devel roctracer-devel miopen-devel rocm-hip-devel
56+
```
57+
However, the libraries are not installed in the usual location (under
58+
`/opt/rocm`) so for `AMDGPU` to find them you must set an environment variable.
59+
```
60+
export ROCM_PATH=/usr/lib64
61+
```
62+
5163
## Test
5264

5365
To ensure that everything works, you can run the test suite:

docs/src/install_tips.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,10 @@ Depending on your GPU model and the functionality you want to use, you may have
3535
to force the GPU architecture by setting the `HSA_OVERRIDE_GFX_VERSION`
3636
variable to a compatible version.
3737

38+
You may also have more than one type of GPU, for example a dedicated AMD GPU and an integrated one.
39+
In that case use `rocminfo` to find which device they are and setting `HIP_VISIBLE_DEVICES` to the specific device you want to use.
40+
Otherwise the runtime may crash if it sees two different architectures.
41+
3842
## Extra Setup Details
3943

4044
List of additional steps that may be needed to take to ensure everything is working:

src/discovery/discovery.jl

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,18 +44,20 @@ function _hip_runtime_version()
4444
VersionNumber(major, minor, patch)
4545
end
4646

47+
global rel_libdir::String = ""
48+
global libhsaruntime::String = ""
49+
global lld_path::String = ""
50+
global lld_artifact::Bool = false
51+
global libhip::String = ""
52+
global libdevice_libs::String = ""
53+
global librocblas::String = ""
54+
global librocsparse::String = ""
55+
global librocsolver::String = ""
56+
global librocrand::String = ""
57+
global librocfft::String = ""
58+
global libMIOpen_path::String = ""
59+
4760
function __init__()
48-
global libhsaruntime = ""
49-
global lld_path = ""
50-
global lld_artifact = ""
51-
global libhip = ""
52-
global libdevice_libs = ""
53-
global librocblas = ""
54-
global librocsparse = ""
55-
global librocsolver = ""
56-
global librocrand = ""
57-
global librocfft = ""
58-
global libMIOpen_path = ""
5961

6062
if Sys.islinux() && isdir("/sys/class/kfd/kfd/topology/nodes/")
6163
for node_id in readdir("/sys/class/kfd/kfd/topology/nodes/")

src/discovery/utils.jl

Lines changed: 73 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,36 @@
1-
"""
2-
Find root ROCm directory.
3-
"""
1+
# use amdhip as query for a valid rocm_path
2+
function check_rocm_path(path::String)
3+
libname = (Sys.islinux() ? "libamdhip64" : "amdhip64") * "." * dlext
4+
path2 = path
5+
isfile(joinpath(path2, libname)) && @goto success
6+
path2 = joinpath(path, "lib")
7+
isfile(joinpath(path2, libname)) && @goto success
8+
path2 = joinpath(path, "bin")
9+
isfile(joinpath(path2, libname)) && @goto success
10+
path2 = joinpath(path, "lib64")
11+
isfile(joinpath(path2, libname)) && @goto success
12+
return ""
13+
@label success
14+
@assert isdir(path2)
15+
return path2
16+
end
17+
18+
# Find root ROCm directory.
419
function find_roc_path()::String
520
env_dir = get(ENV, "ROCM_PATH", "")
6-
isdir(env_dir) && return env_dir
21+
isdir(env_dir) && check_rocm_path(env_dir) != "" && return env_dir
722

823
if Sys.islinux()
9-
isdir("/opt/rocm") && return "/opt/rocm" # shim for Ubuntu rocm packages.
24+
hipconfig = Sys.which("hipconfig")
25+
if !isnothing(hipconfig)
26+
rocm_path = read(`$hipconfig --rocmpath`, String)
27+
rocm_path = check_rocm_path(rocm_path)
28+
isdir(rocm_path) && return rocm_path
29+
end
30+
rocm_path = check_rocm_path("/opt/rocm")
31+
isdir(rocm_path) && return rocm_path
32+
rocm_path = check_rocm_path("/usr")
33+
isdir(rocm_path) && return rocm_path
1034
elseif Sys.iswindows()
1135
disk_dir = dirname(dirname(homedir())) # Disk C root directory.
1236
rocm_dir = joinpath(disk_dir, "Program Files", "AMD", "ROCm")
@@ -24,22 +48,52 @@ function find_roc_path()::String
2448
return ""
2549
end
2650

51+
# use hip.bc as query for a valid device libs dir
52+
function check_device_libs(path::String)
53+
if isdir(path)
54+
file_path = joinpath(path, "hip" * ".bc")
55+
if !ispath(file_path)
56+
file_path = joinpath(path, "hip"* ".amdgcn.bc")
57+
if !ispath(file_path)
58+
# failed to find matching bitcode file
59+
return ""
60+
end
61+
end
62+
return path
63+
else
64+
return ""
65+
end
66+
end
67+
2768
function find_device_libs(rocm_path::String)::String
2869
env_dir = get(ENV, "ROCM_PATH", "")
2970
if isdir(env_dir)
3071
path = joinpath(env_dir, "amdgcn", "bitcode")
72+
path = check_device_libs(path)
3173
isdir(path) && return path
3274
end
33-
3475
# Might be set by tools like Spack or the user
3576
hip_devlibs_path = get(ENV, "HIP_DEVICE_LIB_PATH", "")
3677
hip_devlibs_path !== "" && return hip_devlibs_path
3778
devlibs_path = get(ENV, "DEVICE_LIB_PATH", "")
3879
devlibs_path !== "" && return devlibs_path
39-
80+
# Try using hipconfig to find the device libraries.
4081
# Try the canonical location.
4182
canonical_dir = joinpath(rocm_path, "amdgcn", "bitcode")
83+
canonical_dir = check_device_libs(canonical_dir)
4284
isdir(canonical_dir) && return canonical_dir
85+
# Fedora might put it in a weird place
86+
hipconfig = Sys.which("hipconfig")
87+
if !isnothing(hipconfig)
88+
clang_path = read(`$hipconfig --hipclangpath`, String)
89+
lib_path = joinpath(clang_path ,".." , "lib","clang")
90+
if isdir(lib_path)
91+
lib_path = joinpath(lib_path, only(readdir(lib_path)))
92+
lib_path = joinpath(lib_path, "amdgcn", "bitcode")
93+
lib_path = check_device_libs(lib_path)
94+
isdir(lib_path) && return lib_path
95+
end
96+
end
4397
return ""
4498
end
4599

@@ -52,21 +106,27 @@ function find_rocm_library(libs::Vector; rocm_path::String, ext::String = dlext)
52106
end
53107

54108
function find_rocm_library(lib::String; rocm_path::String, ext::String = dlext)::String
55-
libdir = joinpath(rocm_path, Sys.islinux() ? "lib" : "bin")
56-
isdir(libdir) || return ""
57-
109+
libdir = joinpath(rocm_path, rel_libdir)
110+
@assert isdir(libdir)
58111
for file in readdir(libdir; join=true)
59112
fname = basename(file)
60-
matched = startswith(fname, lib) && endswith(fname, ext)
113+
matched = startswith(fname, lib) && contains(fname, ext)
61114
matched && return file
62115
end
63116
return ""
64117
end
65118

66119
function find_ld_lld(rocm_path::String)::String
67120
lld_name = "ld.lld" * (Sys.iswindows() ? ".exe" : "")
68-
for subdir in (joinpath("llvm", "bin"), "bin")
69-
exp_ld_path = joinpath(rocm_path, subdir, lld_name)
121+
122+
dirs = (joinpath(rocm_path,"llvm", "bin"), joinpath(rocm_path,"bin"))
123+
hipconfig = Sys.which("hipconfig")
124+
if !isnothing(hipconfig)
125+
clang_path = read(`$hipconfig --hipclangpath`, String)
126+
dirs = (dirs ..., clang_path)
127+
end
128+
for dir in dirs
129+
exp_ld_path = joinpath(dir, lld_name)
70130
ispath(exp_ld_path) || continue
71131
try
72132
tmpfile = tempname(;cleanup=false)

0 commit comments

Comments
 (0)