use std::sync::atomic::{AtomicBool, Ordering};
use llama_crab_sys as sys;
use crate::error::{LlamaError, Result};
static INITIALIZED: AtomicBool = AtomicBool::new(false);
#[derive(Debug)]
pub struct LlamaBackend {
_private: (),
}
impl LlamaBackend {
pub fn init() -> Result<Self> {
unsafe {
sys::llama_backend_init();
}
INITIALIZED.store(true, Ordering::SeqCst);
Ok(Self { _private: () })
}
pub fn init_numa(strategy: NumaStrategy) -> Result<Self> {
let raw: sys::ggml_numa_strategy = strategy.into();
unsafe {
sys::llama_numa_init(raw);
}
INITIALIZED.store(true, Ordering::SeqCst);
Ok(Self { _private: () })
}
#[must_use]
pub fn supports_gpu_offload() -> bool {
unsafe { sys::llama_supports_gpu_offload() }
}
#[must_use]
pub fn supports_mmap() -> bool {
unsafe { sys::llama_supports_mmap() }
}
#[must_use]
pub fn supports_mlock() -> bool {
unsafe { sys::llama_supports_mlock() }
}
#[must_use]
pub fn supports_rpc() -> bool {
unsafe { sys::llama_supports_rpc() }
}
}
impl Drop for LlamaBackend {
fn drop(&mut self) {
unsafe {
sys::llama_backend_free();
}
INITIALIZED.store(false, Ordering::SeqCst);
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum NumaStrategy {
Disabled,
Distribute,
Isolate,
NumaCtl,
Mirror,
Count,
}
impl From<NumaStrategy> for sys::ggml_numa_strategy {
fn from(s: NumaStrategy) -> Self {
match s {
NumaStrategy::Disabled => Self::GGML_NUMA_STRATEGY_DISABLED,
NumaStrategy::Distribute => Self::GGML_NUMA_STRATEGY_DISTRIBUTE,
NumaStrategy::Isolate => Self::GGML_NUMA_STRATEGY_ISOLATE,
NumaStrategy::NumaCtl => Self::GGML_NUMA_STRATEGY_NUMACTL,
NumaStrategy::Mirror => Self::GGML_NUMA_STRATEGY_MIRROR,
NumaStrategy::Count => Self::GGML_NUMA_STRATEGY_COUNT,
}
}
}
impl TryFrom<sys::ggml_numa_strategy> for NumaStrategy {
type Error = LlamaError;
fn try_from(v: sys::ggml_numa_strategy) -> Result<Self> {
Ok(match v {
sys::ggml_numa_strategy::GGML_NUMA_STRATEGY_DISABLED => Self::Disabled,
sys::ggml_numa_strategy::GGML_NUMA_STRATEGY_DISTRIBUTE => Self::Distribute,
sys::ggml_numa_strategy::GGML_NUMA_STRATEGY_ISOLATE => Self::Isolate,
sys::ggml_numa_strategy::GGML_NUMA_STRATEGY_NUMACTL => Self::NumaCtl,
sys::ggml_numa_strategy::GGML_NUMA_STRATEGY_MIRROR => Self::Mirror,
sys::ggml_numa_strategy::GGML_NUMA_STRATEGY_COUNT => Self::Count,
})
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn numa_roundtrip() {
for s in [
NumaStrategy::Disabled,
NumaStrategy::Distribute,
NumaStrategy::Isolate,
NumaStrategy::NumaCtl,
NumaStrategy::Mirror,
NumaStrategy::Count,
] {
let raw: sys::ggml_numa_strategy = s.into();
let back = NumaStrategy::try_from(raw).unwrap();
assert_eq!(s, back);
}
}
}