diff --git a/llama-cpp-2/Cargo.toml b/llama-cpp-2/Cargo.toml index ab46dae9..7a262161 100644 --- a/llama-cpp-2/Cargo.toml +++ b/llama-cpp-2/Cargo.toml @@ -25,6 +25,7 @@ cuda-no-vmm = ["cuda", "llama-cpp-sys-2/cuda-no-vmm"] metal = ["llama-cpp-sys-2/metal"] dynamic-link = ["llama-cpp-sys-2/dynamic-link"] vulkan = ["llama-cpp-sys-2/vulkan"] +hip = ["llama-cpp-sys-2/hip"] native = ["llama-cpp-sys-2/native"] openmp = ["llama-cpp-sys-2/openmp"] sampler = [] diff --git a/llama-cpp-sys-2/Cargo.toml b/llama-cpp-sys-2/Cargo.toml index 39458bcd..003b7327 100644 --- a/llama-cpp-sys-2/Cargo.toml +++ b/llama-cpp-sys-2/Cargo.toml @@ -74,6 +74,7 @@ cuda-no-vmm = ["cuda"] metal = [] dynamic-link = [] vulkan = [] +hip = [] native = [] openmp = [] # Only has an impact on Android. diff --git a/llama-cpp-sys-2/build.rs b/llama-cpp-sys-2/build.rs index 8bfdd567..1cdd17fa 100644 --- a/llama-cpp-sys-2/build.rs +++ b/llama-cpp-sys-2/build.rs @@ -20,6 +20,7 @@ enum TargetOs { Apple(AppleVariant), Linux, Android, + OpenBSD, } macro_rules! debug_log { @@ -49,6 +50,8 @@ fn parse_target_os() -> Result<(TargetOs, String), String> { Ok((TargetOs::Android, target)) } else if target.contains("linux") { Ok((TargetOs::Linux, target)) + } else if target.contains("openbsd") { + Ok((TargetOs::OpenBSD, target)) } else { Err(target) } @@ -343,7 +346,7 @@ fn main() { } } - if matches!(target_os, TargetOs::Linux) + if (matches!(target_os, TargetOs::Linux) || matches!(target_os, TargetOs::OpenBSD)) && target_triple.contains("aarch64") && !env::var(format!("CARGO_FEATURE_{}", "native".to_uppercase())).is_ok() { @@ -378,6 +381,10 @@ fn main() { TargetOs::Linux => { println!("cargo:rustc-link-lib=vulkan"); } + TargetOs::OpenBSD => { + println!("cargo:rustc-link-search=/usr/local/lib"); + println!("cargo:rustc-link-lib=vulkan"); + } _ => (), } } @@ -390,10 +397,63 @@ fn main() { } } + if cfg!(feature = "hip") { + config.define("GGML_HIP", "ON"); + + // Get HIP paths using hipconfig + let hip_path = Command::new("hipconfig") + .arg("-R") + .output() + .ok() + .and_then(|output| { + let path = String::from_utf8_lossy(&output.stdout).trim().to_string(); + if !path.is_empty() { Some(path) } else { None } + }) + .or_else(|| env::var("ROCM_PATH").ok()) + .expect("Failed to find ROCm installation. Please ensure hipconfig is in PATH or set ROCM_PATH environment variable."); + + let hip_clang_path = Command::new("hipconfig") + .arg("-l") + .output() + .ok() + .and_then(|output| { + let path = String::from_utf8_lossy(&output.stdout).trim().to_string(); + if !path.is_empty() { Some(path) } else { None } + }) + .unwrap_or_else(|| format!("{}/lib/llvm/bin", hip_path)); + + // Set environment variables as per llama.cpp documentation + env::set_var("HIPCXX", format!("{}/clang++", hip_clang_path)); + env::set_var("HIP_PATH", &hip_path); + + // Allow user to specify GPU architecture via environment variable + if let Ok(targets) = env::var("AMDGPU_TARGETS") { + config.define("AMDGPU_TARGETS", targets); + } else { + // Default to common AMD GPU architectures if not specified + // Including gfx942 for MI300X + config.define("AMDGPU_TARGETS", "gfx906;gfx908;gfx90a;gfx942;gfx1030;gfx1100"); + } + + // Help CMake find the HIP compiler by setting CMAKE_HIP_COMPILER + config.define("CMAKE_HIP_COMPILER", format!("{}/clang++", hip_clang_path)); + + // Add position-independent code flags for HIP compilation + config.define("CMAKE_HIP_FLAGS", "-fPIC"); + config.cflag("-fPIC"); + config.cxxflag("-fPIC"); + + // Link HIP runtime libraries and add library path + println!("cargo:rustc-link-lib=amdhip64"); + println!("cargo:rustc-link-lib=rocblas"); + println!("cargo:rustc-link-lib=hipblas"); + println!("cargo:rustc-link-search=native={}/lib", hip_path); + } + // Android doesn't have OpenMP support AFAICT and openmp is a default feature. Do this here // rather than modifying the defaults in Cargo.toml just in case someone enables the OpenMP feature // and tries to build for Android anyway. - if cfg!(feature = "openmp") && !matches!(target_os, TargetOs::Android) { + if cfg!(feature = "openmp") && !matches!(target_os, TargetOs::Android) && !matches!(target_os, TargetOs::OpenBSD) { config.define("GGML_OPENMP", "ON"); } else { config.define("GGML_OPENMP", "OFF"); @@ -456,6 +516,7 @@ fn main() { } } + // Link libraries let llama_libs_kind = if build_shared_libs { "dylib" } else { "static" }; let llama_libs = extract_lib_names(&out_dir, build_shared_libs); @@ -482,6 +543,9 @@ fn main() { TargetOs::Linux => { println!("cargo:rustc-link-lib=dylib=stdc++"); } + TargetOs::OpenBSD => { + println!("cargo:rustc-link-lib=dylib=c++"); + } TargetOs::Apple(variant) => { println!("cargo:rustc-link-lib=framework=Foundation"); println!("cargo:rustc-link-lib=framework=Metal"); diff --git a/llama-cpp-sys-2/llama.cpp b/llama-cpp-sys-2/llama.cpp index e434e691..0aedae00 160000 --- a/llama-cpp-sys-2/llama.cpp +++ b/llama-cpp-sys-2/llama.cpp @@ -1 +1 @@ -Subproject commit e434e69183fd9e1031f4445002083178c331a28b +Subproject commit 0aedae00e6fb48680324a5ac5da9cba0e35de6b5