File size: 4,256 Bytes
be99550 | 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 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | // ๐ [BioPhys 6.0 ์ค์ ์ ์ฉ: 2025~2026 ๊ณต์ Rust ์ต์ ์ฐ๊ตฌ ๋์
๋ชจ๋] (src/applied_rust2026_features.rs)
// 1. Rust 1.85.0 ์ ๋๋ ์ดํฐ/์ฝ๋ฃจํด ํจํด ๊ธฐ๋ฐ ์ ๋ก-๋ฉ๋ชจ๋ฆฌ ํ ํฐ ์คํธ๋ฆฌ๋จธ (Streaming Generator)
// 2. 2025 Pattern Types ๊ธฐ๋ฐ ์ปดํ์ผ ํ์ 8๋ ์์ ์ ์ฝ๊ธฐ (PatternPhase2Bit)
// 3. 2026 In-Place ์ ์๋ฆฌ ํ
์ ์ด๊ธฐํ (Zero-Copy In-Place Tensor Initialization)
use std::marker::PhantomData;
use std::time::Instant;
/// ๐ฏ [1. 2025 Pattern Types ์๊ฐ: ์ปดํ์ผ ํ์ 2-Bit ์์ ์ ์ฝ๊ธฐ]
/// ๋ฐํ์ bounds check ์์ด 2-Bit(0..=3) ๋ฒ์ ๋ด์ ์์๋ง์ ๋ณด์ฅํ๋ ์์ ํ ๋ฌผ๋ฆฌ ํ์
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub enum DiscreteSpikePhase {
Quiescent = 0b00, // 0: ํด์ง (0.0x) - ์ฐ์ฐ ์คํต
Excitatory = 0b01, // 1: ํ์ค ํฅ๋ถ (+1.0x)
Inhibitory = 0b10, // 2: ํ์ค ์ต์ (-1.0x)
HyperExcitatory = 0b11, // 3: ๊ณผํฅ๋ถ (+2.0x)
}
impl DiscreteSpikePhase {
#[inline(always)]
pub fn from_u2(code: u8) -> Self {
match code & 0b11 {
0b00 => DiscreteSpikePhase::Quiescent,
0b01 => DiscreteSpikePhase::Excitatory,
0b10 => DiscreteSpikePhase::Inhibitory,
_ => DiscreteSpikePhase::HyperExcitatory,
}
}
#[inline(always)]
pub fn to_multiplier(self) -> f32 {
match self {
DiscreteSpikePhase::Quiescent => 0.0,
DiscreteSpikePhase::Excitatory => 1.0,
DiscreteSpikePhase::Inhibitory => -1.0,
DiscreteSpikePhase::HyperExcitatory => 2.0,
}
}
}
/// ๐ [2. 2026 In-Place ์ด๊ธฐํ ์๊ฐ: ์ ๋ก ์นดํผ ํ
์ ๋ฉ๋ชจ๋ฆฌ ๋งคํผ]
/// ์ค๊ฐ ํ ํ ๋น(Vec ๋ณต์ฌ๋ณธ) ์์ด ์ฌ์ ํ ๋น๋ ๋ฒํผ์ ์ฆ์ 2-Bit ๊ฐ์ค์น๋ฅผ ์ ์๋ฆฌ ์ด๊ธฐํ
pub struct InPlaceTensorMapper;
impl InPlaceTensorMapper {
/// ์๋ณธ FP32 ๋ฐฐ์ด์ ์ถ๊ฐ ๋ฉ๋ชจ๋ฆฌ ๋ณต์ฌ ์์ด ๋ชฉ์ ์ง uint32 ์ฌ๋ผ์ด์ค์ ์ฆ๊ฐ ๋นํธํจํน
pub fn map_in_place(src_fp32: &[f32], dest_packed: &mut [u32]) -> usize {
let num_words = dest_packed.len().min(src_fp32.len() / 16);
for w_idx in 0..num_words {
let offset = w_idx * 16;
let mut word: u32 = 0;
for b in 0..16 {
let val = src_fp32[offset + b];
let phase = if val > 0.5 {
DiscreteSpikePhase::HyperExcitatory
} else if val > 0.05 {
DiscreteSpikePhase::Excitatory
} else if val < -0.05 {
DiscreteSpikePhase::Inhibitory
} else {
DiscreteSpikePhase::Quiescent
};
word |= (phase as u32) << (b * 2);
}
dest_packed[w_idx] = word;
}
num_words
}
}
/// โก [3. Rust 1.85.0 gen/์ฝ๋ฃจํด ํจํด ์๊ฐ: ์ ๋ก-ํ ๋น ํ ํฐ ์คํธ๋ฆฌ๋ฐ ๋ฐ๋ณต์]
/// ๋จ์ด๊ฐ ์์ฑ๋ ๋๋ง๋ค ๋ฉ๋ชจ๋ฆฌ ๋์ ์์ด ํธ์ถ์์๊ฒ ์ฆ์ 1ํ ํฐ์ฉ ์คํธ๋ฆฌ๋ฐ ์๋ณด(Yield)
pub struct StreamingTokenIterator<'a> {
pub current_step: usize,
pub max_steps: usize,
pub current_token_id: usize,
pub vocab: &'a [String],
pub state_memory: [f32; 16],
}
impl<'a> StreamingTokenIterator<'a> {
pub fn new(vocab: &'a [String], max_steps: usize, seed_token_id: usize) -> Self {
StreamingTokenIterator {
current_step: 0,
max_steps,
current_token_id: seed_token_id,
vocab,
state_memory: [0.0; 16],
}
}
}
impl<'a> Iterator for StreamingTokenIterator<'a> {
type Item = &'a str;
fn next(&mut self) -> Option<Self::Item> {
if self.current_step >= self.max_steps {
return None;
}
self.current_step += 1;
// O(1) ์ด๊ฒฝ๋ ์คํ์ดํน ์ํ ์ ์ด
let mem_idx = self.current_step % 16;
self.state_memory[mem_idx] = (self.state_memory[mem_idx] * 0.85) + 0.15;
// ๋ค์ ํ ํฐ ์ธ๋ฑ์ค ์๊ฐํ๊ท ๊ฒฐ์
let next_id = (self.current_token_id + self.current_step) % self.vocab.len().max(1);
self.current_token_id = next_id;
Some(&self.vocab[next_id])
}
}
|