Skip to main content

ik_llama_cpp_2/
llama_backend.rs

1//! Process-wide ik_llama.cpp backend initialization.
2
3use std::sync::atomic::{AtomicBool, Ordering};
4
5use crate::LlamaError;
6
7static INITIALIZED: AtomicBool = AtomicBool::new(false);
8
9/// RAII proof that the ik_llama.cpp backend has been initialized.
10///
11/// Initialization is a process-wide singleton (like llama.cpp itself). Hold one
12/// `LlamaBackend` for the lifetime of your models/contexts; dropping it calls
13/// `llama_backend_free`.
14#[derive(Debug)]
15pub struct LlamaBackend {
16    _private: (),
17}
18
19impl LlamaBackend {
20    /// Initialize the backend. Returns [`LlamaError::BackendAlreadyInitialized`]
21    /// if a `LlamaBackend` is already live in this process.
22    pub fn init() -> Result<Self, LlamaError> {
23        if INITIALIZED.swap(true, Ordering::SeqCst) {
24            return Err(LlamaError::BackendAlreadyInitialized);
25        }
26        // SAFETY: guarded by the atomic above; called at most once at a time.
27        unsafe { ik_llama_cpp_sys::llama_backend_init() };
28        Ok(Self { _private: () })
29    }
30}
31
32impl Drop for LlamaBackend {
33    fn drop(&mut self) {
34        // SAFETY: matches the single `llama_backend_init` above.
35        unsafe { ik_llama_cpp_sys::llama_backend_free() };
36        INITIALIZED.store(false, Ordering::SeqCst);
37    }
38}