ik_llama_cpp_2/token/
data_array.rs1use std::ptr;
3
4use ik_llama_cpp_sys as sys;
5
6use crate::context::LlamaContext;
7use crate::token::data::LlamaTokenData;
8use crate::token::LlamaToken;
9
10#[derive(Debug, Clone, PartialEq)]
13pub struct LlamaTokenDataArray {
14 pub data: Vec<LlamaTokenData>,
16 pub selected: Option<usize>,
18 pub sorted: bool,
20}
21
22impl LlamaTokenDataArray {
23 #[must_use]
26 pub fn new(data: Vec<LlamaTokenData>, sorted: bool) -> Self {
27 Self {
28 data,
29 selected: None,
30 sorted,
31 }
32 }
33
34 pub fn from_iter<T>(data: T, sorted: bool) -> LlamaTokenDataArray
36 where
37 T: IntoIterator<Item = LlamaTokenData>,
38 {
39 Self::new(data.into_iter().collect(), sorted)
40 }
41
42 #[must_use]
45 pub fn from_logits(logits: &[f32]) -> Self {
46 let data = logits
47 .iter()
48 .enumerate()
49 .map(|(i, &logit)| LlamaTokenData::new(LlamaToken(i as sys::llama_token), logit, 0.0))
50 .collect();
51 Self::new(data, false)
52 }
53
54 #[must_use]
56 pub fn selected_token(&self) -> Option<LlamaToken> {
57 self.data.get(self.selected?).map(LlamaTokenData::id)
58 }
59
60 pub fn apply_repetition_penalties(
67 &mut self,
68 ctx: &mut LlamaContext,
69 last_tokens: &[LlamaToken],
70 penalty_repeat: f32,
71 penalty_freq: f32,
72 penalty_present: f32,
73 ) {
74 let raw: Vec<sys::llama_token> = last_tokens.iter().map(|t| t.0).collect();
75 let ctx_ptr = ctx.as_ptr();
76 unsafe {
79 self.modify_as_c_llama_token_data_array(|c| {
80 sys::llama_sample_repetition_penalties(
81 ctx_ptr,
82 c,
83 raw.as_ptr(),
84 raw.len(),
85 penalty_repeat,
86 penalty_freq,
87 penalty_present,
88 );
89 });
90 }
91 }
92
93 pub(crate) fn as_c(&mut self) -> sys::llama_token_data_array {
100 sys::llama_token_data_array {
101 data: self.data.as_mut_ptr().cast::<sys::llama_token_data>(),
102 size: self.data.len(),
103 selected: self.selected.and_then(|s| s.try_into().ok()).unwrap_or(-1),
104 sorted: self.sorted,
105 }
106 }
107
108 pub(crate) unsafe fn modify_as_c_llama_token_data_array<T>(
116 &mut self,
117 modify: impl FnOnce(&mut sys::llama_token_data_array) -> T,
118 ) -> T {
119 let data = self.data.as_mut_ptr().cast::<sys::llama_token_data>();
120 let mut c = sys::llama_token_data_array {
121 data,
122 size: self.data.len(),
123 selected: self.selected.and_then(|s| s.try_into().ok()).unwrap_or(-1),
124 sorted: self.sorted,
125 };
126
127 let result = modify(&mut c);
128
129 assert!(
130 c.size <= self.data.capacity(),
131 "sampler returned an array larger than the candidate buffer capacity"
132 );
133 if !ptr::eq(c.data, data) {
134 ptr::copy(c.data, data, c.size);
135 }
136 self.data.set_len(c.size);
138 self.sorted = c.sorted;
139 self.selected = c.selected.try_into().ok().filter(|&s| s < self.data.len());
140 result
141 }
142}