From 329c0191cc5ce9623c46cfab6ae0bc20747a389a Mon Sep 17 00:00:00 2001 From: Derek Christ Date: Sun, 24 Dec 2023 11:27:32 +0100 Subject: [PATCH] Example: add two matrices --- pim-os/src/main.rs | 46 ++++++++--------- pim-os/src/pim.rs | 2 +- pim-os/src/pim/array.rs | 65 +++++++++++++++---------- pim-os/src/pim/kernel.rs | 8 +-- pim-os/src/pim/state.rs | 2 +- pim-os/src/pim/{matrix.rs => vector.rs} | 4 +- 6 files changed, 65 insertions(+), 62 deletions(-) rename pim-os/src/pim/{matrix.rs => vector.rs} (97%) diff --git a/pim-os/src/main.rs b/pim-os/src/main.rs index b1052d9..6593e47 100644 --- a/pim-os/src/main.rs +++ b/pim-os/src/main.rs @@ -14,8 +14,8 @@ use nalgebra::Matrix; use pim::{ array::{PimMatrixArena, PimRegion, PimStorage}, kernel::TEST_KERNEL, - matrix::{F16x1, F16x16}, state::PimState, + vector::{F16x1, F16x16}, }; use pim_isa::BankMode; use uart::Uart0; @@ -30,21 +30,18 @@ pub extern "C" fn entry() -> ! { let mut uart = Uart0; let mut pim_state = PimState::new(&TEST_KERNEL); - let pim_matrix_arena = RefCell::new(PimMatrixArena([[F16x16::default(); 8]; 8])); + let pim_matrix_arena0 = RefCell::new(PimMatrixArena([[F16x16::default(); 8]; 8])); + let pim_matrix_arena1 = RefCell::new(PimMatrixArena([[F16x16::default(); 8]; 8])); let pim_storage0 = PimStorage { - arena: &pim_matrix_arena, + arena: &pim_matrix_arena0, index: 0, }; let pim_storage1 = PimStorage { - arena: &pim_matrix_arena, - index: 1, - }; - let pim_storage2 = PimStorage { - arena: &pim_matrix_arena, - index: 2, + arena: &pim_matrix_arena1, + index: 0, }; + let mut matrix0 = Matrix::from_data(pim_storage0); - let matrix1 = Matrix::from_data(pim_storage1); matrix0.fill_column(0, F16x1(f16::ZERO)); matrix0.fill_column(1, F16x1(f16::ONE)); matrix0.fill_column(2, F16x1(f16::PI)); @@ -54,36 +51,31 @@ pub extern "C" fn entry() -> ! { matrix0.fill_column(6, F16x1(f16::LN_2)); matrix0.fill_column(7, F16x1(f16::LN_10)); - writeln!( - &mut uart, - "Cache Lines: {}\nRows: {}", - PimMatrixArena::<8, 8>::OCCUPIED_CACHE_LINES, - PimMatrixArena::<8, 8>::OCCUPIED_ROWS - ) - .unwrap(); - writeln!(&mut uart, "{matrix0} * 2\n=").unwrap(); + let mut matrix1 = Matrix::from_data(pim_storage1); + matrix1.fill_lower_triangle(F16x1(f16::ONE), 0); + + writeln!(&mut uart, "{matrix0} + {matrix1}\n=").unwrap(); // Invalidate and flush array just in case - pim_matrix_arena.borrow_mut().invalidate_flush(); - // dummy_array.invalidate_flush(); + pim_matrix_arena0.borrow_mut().invalidate_flush(); + pim_matrix_arena1.borrow_mut().invalidate_flush(); barrier::dsb(barrier::SY); pim_state.set_bank_mode(BankMode::PimAllBank); - pim_matrix_arena - .borrow_mut() + pim_matrix_arena0 + .borrow() .execute_instruction_read_dual_bank(); - pim_matrix_arena - .borrow_mut() + pim_matrix_arena1 + .borrow() .execute_instruction_read_dual_bank(); - pim_matrix_arena + pim_matrix_arena0 .borrow_mut() .execute_instruction_write_dual_bank(); pim_state.set_bank_mode(BankMode::SingleBank); - pim_matrix_arena.borrow_mut().invalidate(); + pim_matrix_arena0.borrow_mut().invalidate(); barrier::dsb(barrier::SY); - // writeln!(&mut uart, "{matrix0}+{matrix1}").unwrap(); writeln!(&mut uart, "{matrix0}").unwrap(); m5ops::exit(); diff --git a/pim-os/src/pim.rs b/pim-os/src/pim.rs index 5d5d47a..58ee855 100644 --- a/pim-os/src/pim.rs +++ b/pim-os/src/pim.rs @@ -1,5 +1,5 @@ pub mod array; pub mod config; pub mod kernel; -pub mod matrix; +pub mod vector; pub mod state; diff --git a/pim-os/src/pim/array.rs b/pim-os/src/pim/array.rs index 3628684..06555ca 100644 --- a/pim-os/src/pim/array.rs +++ b/pim-os/src/pim/array.rs @@ -1,4 +1,4 @@ -use super::matrix::{F16x1, F16x16}; +use super::vector::{F16x1, F16x16}; use aarch64_cpu::asm::barrier; use core::{arch::asm, cell::RefCell}; use half::f16; @@ -17,15 +17,15 @@ impl PimRegion for PimMatrixArena { const OCCUPIED_ROWS: usize = Self::OCCUPIED_CACHE_LINES / NUMBER_OF_BANKS; fn bank_ptr(&self, bank_index: usize) -> *const f16 { - unsafe { (self.0.as_ptr() as *const F16x16).offset(bank_index as _) as *const f16 } + unsafe { (self.0.as_ptr() as *const F16x16).add(bank_index) as *const f16 } } fn bank_ptr_mut(&mut self, bank_index: usize) -> *mut f16 { - unsafe { (self.0.as_mut_ptr() as *mut F16x16).offset(bank_index as _) as *mut f16 } + unsafe { (self.0.as_mut_ptr() as *mut F16x16).add(bank_index) as *mut f16 } } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct PimStorage<'a, const R: usize, const C: usize> { pub arena: &'a RefCell>, pub index: usize, @@ -38,9 +38,7 @@ unsafe impl<'a, const R: usize, const C: usize> RawStorage, Cons type CStride = Dyn; fn ptr(&self) -> *const F16x1 { - unsafe { - (&self.arena.borrow().0[0][0] as *const F16x16 as *const F16x1).offset(self.index as _) - } + unsafe { (&self.arena.borrow().0[0][0] as *const F16x16 as *const F16x1).add(self.index) } } fn shape(&self) -> (Const, Const) { @@ -65,8 +63,7 @@ unsafe impl<'a, const R: usize, const C: usize> RawStorageMut, C { fn ptr_mut(&mut self) -> *mut F16x1 { unsafe { - (&mut self.arena.borrow_mut().0[0][0] as *mut F16x16 as *mut F16x1) - .offset(self.index as _) + (&mut self.arena.borrow_mut().0[0][0] as *mut F16x16 as *mut F16x1).add(self.index) } } @@ -83,15 +80,17 @@ pub trait PimRegion { fn bank_ptr_mut(&mut self, bank_index: usize) -> *mut f16; fn execute_instruction_read_single_bank(&self) { - if !cfg!(feature = "cacheless") { - self.invalidate_bank(EVEN_BANK_INDEX); + for i in (0..Self::OCCUPIED_ROWS).map(|i| i * NUMBER_OF_BANKS) { + if !cfg!(feature = "cacheless") { + self.invalidate_bank(EVEN_BANK_INDEX + i); + barrier::dsb(barrier::SY); + } + + // Read from first bank + self.read_data_bank(EVEN_BANK_INDEX + i); + barrier::dsb(barrier::SY); } - - // Read from first bank - self.read_data_bank(EVEN_BANK_INDEX); - - barrier::dsb(barrier::SY); } fn execute_instruction_read_dual_bank(&self) { @@ -113,25 +112,32 @@ pub trait PimRegion { fn read_data_bank(&self, bank_index: usize) { let bank = self.bank_ptr(bank_index); + + // For some reason, this is needed... + use core::fmt::Write; + write!(&mut crate::uart::Uart0 {}, "").unwrap(); + unsafe { core::ptr::read_volatile(bank); } } fn execute_instruction_write_single_bank(&mut self) { - if !cfg!(feature = "cacheless") { - self.preload_zero(); + for i in (0..Self::OCCUPIED_ROWS).map(|i| i * NUMBER_OF_BANKS) { + if !cfg!(feature = "cacheless") { + self.preload_zero_bank(EVEN_BANK_INDEX + i); + barrier::dsb(barrier::SY); + } + + // Write to first bank + self.write_data_bank(EVEN_BANK_INDEX + i); + + if !cfg!(feature = "cacheless") { + self.invalidate_flush_bank(EVEN_BANK_INDEX + i); + } + barrier::dsb(barrier::SY); } - - // Write to first bank - self.write_data_bank(EVEN_BANK_INDEX); - - if !cfg!(feature = "cacheless") { - self.invalidate_flush_bank(EVEN_BANK_INDEX); - } - - barrier::dsb(barrier::SY); } fn execute_instruction_write_dual_bank(&mut self) { @@ -157,6 +163,11 @@ pub trait PimRegion { fn write_data_bank(&mut self, bank_index: usize) { let bank = self.bank_ptr_mut(bank_index); + + // For some reason, this is needed... + use core::fmt::Write; + write!(&mut crate::uart::Uart0 {}, "").unwrap(); + unsafe { core::ptr::write_volatile(bank, Default::default()); } diff --git a/pim-os/src/pim/kernel.rs b/pim-os/src/pim/kernel.rs index bc79c5f..e770ea6 100644 --- a/pim-os/src/pim/kernel.rs +++ b/pim-os/src/pim/kernel.rs @@ -18,25 +18,25 @@ pub const TEST_KERNEL: Kernel = Kernel([ dst: File::GrfB { index: 1 }, }, Instruction::ADD { - src0: File::GrfA { index: 0 }, + src0: File::Bank, src1: File::GrfA { index: 0 }, dst: File::GrfA { index: 0 }, aam: false, }, Instruction::ADD { - src0: File::GrfB { index: 0 }, + src0: File::Bank, src1: File::GrfB { index: 0 }, dst: File::GrfB { index: 0 }, aam: false, }, Instruction::ADD { - src0: File::GrfA { index: 1 }, + src0: File::Bank, src1: File::GrfA { index: 1 }, dst: File::GrfA { index: 1 }, aam: false, }, Instruction::ADD { - src0: File::GrfB { index: 1 }, + src0: File::Bank, src1: File::GrfB { index: 1 }, dst: File::GrfB { index: 1 }, aam: false, diff --git a/pim-os/src/pim/state.rs b/pim-os/src/pim/state.rs index faed842..61f86b8 100644 --- a/pim-os/src/pim/state.rs +++ b/pim-os/src/pim/state.rs @@ -28,7 +28,7 @@ impl PimState { } self.writer.write( - serde_json_core::to_string::(&PimConfig { + serde_json_core::to_string::(&PimConfig { kernel: self.kernel.clone(), bank_mode, }) diff --git a/pim-os/src/pim/matrix.rs b/pim-os/src/pim/vector.rs similarity index 97% rename from pim-os/src/pim/matrix.rs rename to pim-os/src/pim/vector.rs index 36db7b5..78c5299 100644 --- a/pim-os/src/pim/matrix.rs +++ b/pim-os/src/pim/vector.rs @@ -8,13 +8,13 @@ pub struct F16x1(pub f16); impl core::fmt::Debug for F16x1 { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - Ok(self.0.fmt(f)?) + self.0.fmt(f) } } impl core::fmt::Display for F16x1 { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - Ok(self.0.fmt(f)?) + self.0.fmt(f) } }