// 🚀 대규모 100만 노드(1024x1024) 병렬 복잡계 엔진 (src/parallel_engine.rs) use rayon::prelude::*; use rand::Rng; #[derive(Copy, Clone, Debug, PartialEq)] #[repr(u8)] pub enum PhaseState { HyperInhibition = 0, StandardInhibition = 1, SubInhibition = 2, NegQuiescent = 3, PosQuiescent = 4, SubExcitation = 5, StandardExcitation = 6, HyperExcitation = 7, } impl PhaseState { #[inline(always)] pub fn value(&self) -> f32 { match self { PhaseState::HyperInhibition => -2.0, PhaseState::StandardInhibition => -1.0, PhaseState::SubInhibition => -0.5, PhaseState::NegQuiescent => -0.01, PhaseState::PosQuiescent => 0.01, PhaseState::SubExcitation => 0.5, PhaseState::StandardExcitation => 1.0, PhaseState::HyperExcitation => 2.0, } } #[inline(always)] pub fn from_energy(e: f32) -> Self { if e <= -1.5 { PhaseState::HyperInhibition } else if e <= -0.75 { PhaseState::StandardInhibition } else if e <= -0.25 { PhaseState::SubInhibition } else if e <= 0.0 { PhaseState::NegQuiescent } else if e <= 0.25 { PhaseState::PosQuiescent } else if e <= 0.75 { PhaseState::SubExcitation } else if e <= 1.5 { PhaseState::StandardExcitation } else { PhaseState::HyperExcitation } } } pub struct LargeScaleEngine { pub size: usize, pub bedrock: Vec, pub topsoil: Vec, } impl LargeScaleEngine { pub fn new(size: usize) -> Self { let mut rng = rand::thread_rng(); let total_nodes = size * size; let bedrock: Vec = (0..total_nodes).map(|_| rng.gen_range(-0.5..0.5)).collect(); let topsoil: Vec = (0..total_nodes).map(|_| PhaseState::from_energy(rng.gen_range(-2.0..2.0))).collect(); LargeScaleEngine { size, bedrock, topsoil } } /// Rayon 멀티스레드 병렬 상태 전이 (100만 노드 분할 처리) pub fn step_parallel(&mut self) -> f32 { let size = self.size; let prev_topsoil = &self.topsoil; let bedrock = &self.bedrock; // 청크(Row) 단위 멀티스레드 병렬 갱신 let (next_topsoil, total_energy): (Vec, f32) = (0..size) .into_par_iter() .map(|y| { let mut row_states = Vec::with_capacity(size); let mut row_energy = 0.0f32; let s = size as i32; for x in 0..size { let idx = y * size + x; let up_idx = ((y as i32 - 1 + s) % s * s + x as i32) as usize; let down_idx = ((y as i32 + 1) % s * s + x as i32) as usize; let left_idx = (y as i32 * s + (x as i32 - 1 + s) % s) as usize; let right_idx = (y as i32 * s + (x as i32 + 1) % s) as usize; let neighbor_e = ( prev_topsoil[up_idx].value() + prev_topsoil[down_idx].value() + prev_topsoil[left_idx].value() + prev_topsoil[right_idx].value() ) * 0.25; let local_field = neighbor_e + bedrock[idx]; row_states.push(PhaseState::from_energy(local_field)); row_energy += local_field.abs(); } (row_states, row_energy) }) .reduce( || (Vec::with_capacity(size * size), 0.0f32), |mut acc, (row_states, row_e)| { acc.0.extend(row_states); acc.1 += row_e; acc }, ); self.topsoil = next_topsoil; total_energy / (size * size) as f32 } }