Skip to main content

ik_llama_cpp_2/model/
meta.rs

1//! Model metadata + dimension accessors.
2//!
3//! Mirrors the `llama-cpp-2` anchor's metadata/dim accessors on `LlamaModel`,
4//! adapted to ik's C API. ik exposes no head-count accessor (`llama_n_head` /
5//! `llama_model_n_head` are absent), so that getter is omitted.
6
7use std::os::raw::c_char;
8
9use ik_llama_cpp_sys as sys;
10
11use crate::model::LlamaModel;
12
13/// Read a C string produced by an `snprintf`-style FFI getter using the
14/// two-call size-then-fill pattern. Returns `None` if the getter reports the
15/// item is absent (negative return) or the bytes are not valid UTF-8.
16fn read_ffi_string<F: Fn(*mut c_char, usize) -> i32>(fill: F) -> Option<String> {
17    // Probe the required length (snprintf semantics: null buf, size 0).
18    let needed = fill(std::ptr::null_mut(), 0);
19    if needed < 0 {
20        return None;
21    }
22    let cap = needed as usize + 1;
23    let mut buf = vec![0u8; cap];
24    let written = fill(buf.as_mut_ptr().cast::<c_char>(), cap);
25    if written < 0 {
26        return None;
27    }
28    buf.truncate(written as usize);
29    String::from_utf8(buf).ok()
30}
31
32impl LlamaModel {
33    /// Value of a metadata key (e.g. `"general.architecture"`), or `None` if absent.
34    #[must_use]
35    pub fn meta_val_str(&self, key: &str) -> Option<String> {
36        let c_key = std::ffi::CString::new(key).ok()?;
37        let model = self.model.as_ptr();
38        // SAFETY: valid model + NUL-terminated key; buf/size honored by the getter.
39        read_ffi_string(|buf, size| unsafe {
40            sys::llama_model_meta_val_str(model, c_key.as_ptr(), buf, size)
41        })
42    }
43
44    /// Number of metadata key-value pairs.
45    #[must_use]
46    pub fn meta_count(&self) -> i32 {
47        unsafe { sys::llama_model_meta_count(self.model.as_ptr()) }
48    }
49
50    /// Metadata key name at `index`, or `None` if out of range.
51    #[must_use]
52    pub fn meta_key_by_index(&self, index: i32) -> Option<String> {
53        let model = self.model.as_ptr();
54        // SAFETY: valid model; buf/size honored by the getter.
55        read_ffi_string(|buf, size| unsafe {
56            sys::llama_model_meta_key_by_index(model, index, buf, size)
57        })
58    }
59
60    /// Metadata value at `index`, or `None` if out of range.
61    #[must_use]
62    pub fn meta_val_str_by_index(&self, index: i32) -> Option<String> {
63        let model = self.model.as_ptr();
64        // SAFETY: valid model; buf/size honored by the getter.
65        read_ffi_string(|buf, size| unsafe {
66            sys::llama_model_meta_val_str_by_index(model, index, buf, size)
67        })
68    }
69
70    /// Human-readable model description.
71    #[must_use]
72    pub fn desc(&self) -> String {
73        let model = self.model.as_ptr();
74        // SAFETY: valid model; buf/size honored by the getter.
75        read_ffi_string(|buf, size| unsafe { sys::llama_model_desc(model, buf, size) })
76            .unwrap_or_default()
77    }
78
79    /// Total model size in bytes.
80    #[must_use]
81    pub fn size(&self) -> u64 {
82        unsafe { sys::llama_model_size(self.model.as_ptr()) }
83    }
84
85    /// Total number of parameters.
86    #[must_use]
87    pub fn n_params(&self) -> u64 {
88        unsafe { sys::llama_model_n_params(self.model.as_ptr()) }
89    }
90
91    /// Training context length.
92    #[must_use]
93    pub fn n_ctx_train(&self) -> i32 {
94        unsafe { sys::llama_n_ctx_train(self.model.as_ptr()) }
95    }
96
97    /// Embedding dimension.
98    #[must_use]
99    pub fn n_embd(&self) -> i32 {
100        unsafe { sys::llama_model_n_embd(self.model.as_ptr()) }
101    }
102
103    /// Number of layers.
104    #[must_use]
105    pub fn n_layer(&self) -> i32 {
106        unsafe { sys::llama_n_layer(self.model.as_ptr()) }
107    }
108
109    /// RoPE type (raw `llama_rope_type`).
110    #[must_use]
111    pub fn rope_type(&self) -> sys::llama_rope_type {
112        unsafe { sys::llama_rope_type(self.model.as_ptr()) }
113    }
114}