From 0253a97755976b6706f7fe4adad80b0d1d2296c5 Mon Sep 17 00:00:00 2001 From: "Donald Anthony Pellegrino Jr., Ph.D." Date: Sun, 27 Jul 2025 09:10:48 -0400 Subject: [PATCH 1/4] Add OpenBSD support and update llama.cpp to 0aedae00 for granitehybrid support --- llama-cpp-sys-2/build.rs | 14 ++++++++++++-- llama-cpp-sys-2/llama.cpp | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/llama-cpp-sys-2/build.rs b/llama-cpp-sys-2/build.rs index 8bfdd567..61a1a96a 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"); + } _ => (), } } @@ -393,7 +400,7 @@ fn main() { // 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"); @@ -482,6 +489,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 From 1b7ef2efdef9424646284f10e04bb9dc3e7a0c3f Mon Sep 17 00:00:00 2001 From: "Donald Anthony Pellegrino Jr., Ph.D." Date: Sun, 27 Jul 2025 20:09:58 +0000 Subject: [PATCH 2/4] Add ROCm/HIP support for AMD GPUs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add hip feature flag to Cargo.toml files - Configure HIP build in build.rs with ROCm path detection - Set up HIP compiler and library paths - Add support for multiple AMD GPU architectures including gfx942 (MI300X) - Configure proper linking with HIP runtime libraries (amdhip64, rocblas, hipblas) - Add -fPIC flags for position-independent code - Remove unnecessary GCC/cmath workaround (users should install libstdc++-dev) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- llama-cpp-2/Cargo.toml | 1 + llama-cpp-sys-2/Cargo.toml | 1 + llama-cpp-sys-2/build.rs | 62 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+) 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 61a1a96a..012d84ba 100644 --- a/llama-cpp-sys-2/build.rs +++ b/llama-cpp-sys-2/build.rs @@ -397,6 +397,52 @@ 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 } + }) + .unwrap_or_else(|| "/opt/rocm".to_string()); + + 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"); + } + // 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. @@ -463,6 +509,22 @@ fn main() { } } + // HIP (ROCm) + if cfg!(feature = "hip") { + // Link HIP runtime libraries + println!("cargo:rustc-link-lib=amdhip64"); + println!("cargo:rustc-link-lib=rocblas"); + println!("cargo:rustc-link-lib=hipblas"); + + // Add ROCm library path + if let Ok(rocm_path) = env::var("ROCM_PATH") { + println!("cargo:rustc-link-search=native={}/lib", rocm_path); + } else { + println!("cargo:rustc-link-search=native=/opt/rocm/lib"); + println!("cargo:rustc-link-search=native=/opt/rocm-6.4.1/lib"); + } + } + // Link libraries let llama_libs_kind = if build_shared_libs { "dylib" } else { "static" }; let llama_libs = extract_lib_names(&out_dir, build_shared_libs); From 040d2b1548172b5d63e5c0ddacb8366cf4bdb4bd Mon Sep 17 00:00:00 2001 From: "Donald Anthony Pellegrino Jr., Ph.D." Date: Sun, 27 Jul 2025 20:33:53 +0000 Subject: [PATCH 3/4] Make ROCm path detection version-agnostic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove hardcoded ROCm version (6.4.1) from library search paths - Dynamically detect versioned ROCm installations in /opt/rocm-* - Prioritize ROCM_PATH environment variable if set - Automatically find all ROCm installations regardless of version - Makes the build more robust across different ROCm releases 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- llama-cpp-sys-2/build.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/llama-cpp-sys-2/build.rs b/llama-cpp-sys-2/build.rs index 012d84ba..0f630ee9 100644 --- a/llama-cpp-sys-2/build.rs +++ b/llama-cpp-sys-2/build.rs @@ -517,11 +517,26 @@ fn main() { println!("cargo:rustc-link-lib=hipblas"); // Add ROCm library path + // First try ROCM_PATH environment variable if let Ok(rocm_path) = env::var("ROCM_PATH") { println!("cargo:rustc-link-search=native={}/lib", rocm_path); } else { + // Try common ROCm installation paths println!("cargo:rustc-link-search=native=/opt/rocm/lib"); - println!("cargo:rustc-link-search=native=/opt/rocm-6.4.1/lib"); + + // Also check for versioned installations by looking for directories + if let Ok(entries) = std::fs::read_dir("/opt") { + for entry in entries.flatten() { + let path = entry.path(); + if let Some(name) = path.file_name() { + if name.to_string_lossy().starts_with("rocm-") { + if path.join("lib").exists() { + println!("cargo:rustc-link-search=native={}/lib", path.display()); + } + } + } + } + } } } From cb8fd47923369f96bad3bcfb6ba35e6db2b2277f Mon Sep 17 00:00:00 2001 From: "Donald Anthony Pellegrino Jr., Ph.D." Date: Sun, 27 Jul 2025 21:06:30 +0000 Subject: [PATCH 4/4] Simplify ROCm detection to only use hipconfig and environment variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove filesystem searching for ROCm installations - Only use hipconfig or ROCM_PATH environment variable - Fail with clear error if ROCm cannot be found - Consolidate HIP configuration into single code block - Follow best practice of explicit configuration over discovery This ensures the build only uses explicitly configured resources rather than searching the filesystem for installations. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- llama-cpp-sys-2/build.rs | 39 ++++++++------------------------------- 1 file changed, 8 insertions(+), 31 deletions(-) diff --git a/llama-cpp-sys-2/build.rs b/llama-cpp-sys-2/build.rs index 0f630ee9..1cdd17fa 100644 --- a/llama-cpp-sys-2/build.rs +++ b/llama-cpp-sys-2/build.rs @@ -409,7 +409,8 @@ fn main() { let path = String::from_utf8_lossy(&output.stdout).trim().to_string(); if !path.is_empty() { Some(path) } else { None } }) - .unwrap_or_else(|| "/opt/rocm".to_string()); + .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") @@ -441,6 +442,12 @@ fn main() { 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 @@ -509,36 +516,6 @@ fn main() { } } - // HIP (ROCm) - if cfg!(feature = "hip") { - // Link HIP runtime libraries - println!("cargo:rustc-link-lib=amdhip64"); - println!("cargo:rustc-link-lib=rocblas"); - println!("cargo:rustc-link-lib=hipblas"); - - // Add ROCm library path - // First try ROCM_PATH environment variable - if let Ok(rocm_path) = env::var("ROCM_PATH") { - println!("cargo:rustc-link-search=native={}/lib", rocm_path); - } else { - // Try common ROCm installation paths - println!("cargo:rustc-link-search=native=/opt/rocm/lib"); - - // Also check for versioned installations by looking for directories - if let Ok(entries) = std::fs::read_dir("/opt") { - for entry in entries.flatten() { - let path = entry.path(); - if let Some(name) = path.file_name() { - if name.to_string_lossy().starts_with("rocm-") { - if path.join("lib").exists() { - println!("cargo:rustc-link-search=native={}/lib", path.display()); - } - } - } - } - } - } - } // Link libraries let llama_libs_kind = if build_shared_libs { "dylib" } else { "static" };