use std::{
env::{self, var, VarError},
path::PathBuf,
};
const DEFAULT_OPENCL_PATH: &str = "/usr";
pub fn include_hip() {
if env::var("DOCS_RS").is_err() && !cfg!(doc) {
let paths = find_hip_root_dirs();
if paths.is_empty() {
panic!("Could not find a hip installation");
}
for path in paths {
println!("cargo:rustc-link-search=native={}/lib", path.display());
}
println!("cargo:rustc-link-lib=dylib=amdhip64");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-env-changed=CUDA_LIBRARY_PATH");
println!("cargo:rerun-if-env-changed=CUDA_ROOT");
println!("cargo:rerun-if-env-changed=CUDA_PATH");
println!("cargo:rerun-if-env-changed=CUDA_TOOLKIT_ROOT_DIR");
println!("cargo:rerun-if-env-changed=HIP_PATH");
println!("cargo:rerun-if-env-changed=HCC_ROCCLR_HOME");
println!("cargo:rerun-if-env-changed=HSA_PATH");
println!("cargo:rerun-if-env-changed=ROCM_PATH");
}
}
pub fn read_env() -> Vec<PathBuf> {
let split_char = if cfg!(target_os = "windows") {
";"
} else {
":"
};
match var("OPENCL_LIBRARY_PATH") {
Ok(path) => {
path.split(split_char)
.map(PathBuf::from)
.filter(|pb| pb.exists())
.collect()
}
Err(VarError::NotPresent) => DEFAULT_OPENCL_PATH
.split(split_char)
.map(PathBuf::from)
.filter(|pb| pb.exists())
.collect(),
Err(e @ VarError::NotUnicode(_)) => panic!("{}: HIP_PATH: {}", env!("CARGO_PKG_NAME"), e),
}
}
pub fn find_hip_root_dirs() -> Vec<PathBuf> {
let mut candidates = read_env();
candidates.push(PathBuf::from("/opt/cuda"));
candidates.push(PathBuf::from("/opt/cuda/targets/x86_64-linux"));
candidates.push(PathBuf::from("/opt/rocm"));
candidates.push(PathBuf::from("/opt/rocm/opencl"));
candidates.push(PathBuf::from("/usr"));
let mut valid_paths = vec![];
for base in &candidates {
let header = base.join("include/CL/cl.h");
let lib = PathBuf::from(base).join("lib");
if lib.is_dir() && header.is_file() {
valid_paths.push(base.clone());
}
}
valid_paths
}