1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
//! an rusty equivalent of `llama_token_data`.
use crate::token::data::LlamaTokenData;
/// a safe wrapper around `llama_token_data_array`.
#[derive(Debug, Clone, PartialEq)]
#[allow(clippy::module_name_repetitions)]
pub struct LlamaTokenDataArray {
/// the underlying data
pub data: Vec<LlamaTokenData>,
/// is the data sorted?
pub sorted: bool,
}
impl LlamaTokenDataArray {
/// Create a new `LlamaTokenDataArray` from a vector and weather or not the data is sorted.
///
/// ```
/// # use llama_cpp_2::token::data::LlamaTokenData;
/// # use llama_cpp_2::token::data_array::LlamaTokenDataArray;
/// # use llama_cpp_2::token::LlamaToken;
/// let array = LlamaTokenDataArray::new(vec![
/// LlamaTokenData::new(LlamaToken(0), 0.0, 0.0),
/// LlamaTokenData::new(LlamaToken(1), 0.1, 0.1)
/// ], false);
/// assert_eq!(array.data.len(), 2);
/// assert_eq!(array.sorted, false);
/// ```
#[must_use]
pub fn new(data: Vec<LlamaTokenData>, sorted: bool) -> Self {
Self { data, sorted }
}
/// Create a new `LlamaTokenDataArray` from an iterator and weather or not the data is sorted.
/// ```
/// # use llama_cpp_2::token::data::LlamaTokenData;
/// # use llama_cpp_2::token::data_array::LlamaTokenDataArray;
/// # use llama_cpp_2::token::LlamaToken;
/// let array = LlamaTokenDataArray::from_iter([
/// LlamaTokenData::new(LlamaToken(0), 0.0, 0.0),
/// LlamaTokenData::new(LlamaToken(1), 0.1, 0.1)
/// ], false);
/// assert_eq!(array.data.len(), 2);
/// assert_eq!(array.sorted, false);
pub fn from_iter<T>(data: T, sorted: bool) -> LlamaTokenDataArray
where
T: IntoIterator<Item = LlamaTokenData>,
{
Self::new(data.into_iter().collect(), sorted)
}
}
impl LlamaTokenDataArray {
/// Modify the underlying data as a `llama_token_data_array`. and reconstruct the `LlamaTokenDataArray`.
///
/// # Panics
///
/// Panics if some of the safety conditions are not met. (we cannot check all of them at runtime so breaking them is UB)
///
/// SAFETY:
/// [modify] cannot change the data pointer.
/// if the data is not sorted, sorted must be false.
/// the size of the data can only decrease (i.e you cannot add new elements).
pub(crate) unsafe fn modify_as_c_llama_token_data_array(
&mut self,
modify: impl FnOnce(&mut llama_cpp_sys_2::llama_token_data_array),
) {
let size = self.data.len();
let data = self.data.as_mut_ptr().cast();
let mut c_llama_token_data_array = llama_cpp_sys_2::llama_token_data_array {
data,
size,
sorted: self.sorted,
};
modify(&mut c_llama_token_data_array);
assert!(
std::ptr::eq(data, c_llama_token_data_array.data),
"data pointer changed"
);
assert!(c_llama_token_data_array.size <= size, "size increased");
self.data.set_len(c_llama_token_data_array.size);
self.sorted = c_llama_token_data_array.sorted;
}
}