From 9ca1a0ed9f4f9b09cfeaccce2a298d44bfde14ae Mon Sep 17 00:00:00 2001 From: NiccoloN Date: Fri, 31 Jul 2026 17:24:19 +0200 Subject: [PATCH] implement vmv in pim-simulator fix offset selection implementation to match the pim isa automatic code format for pim-simulator --- .../src/bin/pim-simulator/main.rs | 6 +- .../pim/pim-simulator/src/lib/cpu/crossbar.rs | 41 +- .../pim/pim-simulator/src/lib/cpu/mod.rs | 44 +- .../lib/instruction_set/instruction_data.rs | 15 +- .../src/lib/instruction_set/isa.rs | 50 ++- .../src/lib/instruction_set/mod.rs | 5 +- .../src/lib/memory_manager/mod.rs | 44 +- .../src/lib/memory_manager/type_traits.rs | 42 +- .../pim/pim-simulator/src/lib/pimcore.rs | 8 +- .../pim/pim-simulator/src/lib/send_recv.rs | 11 +- .../pim-simulator/src/lib/tracing/disable.rs | 98 ++--- .../pim/pim-simulator/src/lib/tracing/mod.rs | 2 - .../src/lib/tracing/profile/mod.rs | 4 +- .../lib/tracing/profile/profile_analysis.rs | 20 +- .../src/lib/tracing/profile/profile_isa.rs | 9 +- .../src/lib/tracing/trace/mod.rs | 2 - .../src/lib/tracing/trace/tracing_isa.rs | 38 +- .../pim/pim-simulator/src/lib/utility.rs | 65 +-- .../pim/pim-simulator/tests/big_mul.rs | 21 +- .../pim/pim-simulator/tests/es_runner.rs | 13 +- .../pim/pim-simulator/tests/placeholder.rs | 54 +-- .../pim/pim-simulator/tests/simd.rs | 401 +++++++++--------- .../pim/pim-simulator/tests/sync.rs | 88 ++-- 23 files changed, 584 insertions(+), 497 deletions(-) diff --git a/backend-simulators/pim/pim-simulator/src/bin/pim-simulator/main.rs b/backend-simulators/pim/pim-simulator/src/bin/pim-simulator/main.rs index 2bbe082..cf5a5ea 100644 --- a/backend-simulators/pim/pim-simulator/src/bin/pim-simulator/main.rs +++ b/backend-simulators/pim/pim-simulator/src/bin/pim-simulator/main.rs @@ -13,7 +13,7 @@ use pimcore::memory_manager::CoreMemory; use pimcore::tracing::TRACER; use serde_json::Value; use std::collections::HashMap; -use std::fs::{self, File, read_link}; +use std::fs::{self, File}; use std::io::{BufReader, Write}; use std::path::PathBuf; @@ -110,7 +110,7 @@ fn map_crossbars_to_cores<'c>( sym_link_files.sort_by_key(|&(num, _)| num); for (_, symlink) in sym_link_files { - let real_path = read_link(symlink).unwrap(); + let real_path = symlink.canonicalize().unwrap(); let path_as_str = real_path.to_str().unwrap(); assert!( global_crossbars.contains_key(path_as_str), @@ -162,6 +162,8 @@ fn get_crossbars(config: &Value, args: &Args) -> anyhow::Result Self { - Self { max_width: width, max_height: height, memory, stored_bytes:0 } + Self { + max_width: width, + max_height: height, + memory, + stored_bytes: 0, + } } pub fn width(&self) -> usize { @@ -27,27 +31,36 @@ impl Crossbar { self.stored_bytes } - pub fn execute_store(&mut self, element: &[T]) -> Result<()> where - T: MemoryStorable, { + pub fn execute_store(&mut self, element: &[T]) -> Result<()> + where + T: MemoryStorable, + { self.memory.clear(); let total_size = self.max_width * self.max_height; self.memory.set_capacity(total_size); let stored_size = std::mem::size_of_val(element); - ensure!(stored_size <= total_size, "Storing more than crossbar can handle"); - self.stored_bytes=stored_size; + ensure!( + stored_size <= total_size, + "Storing more than crossbar can handle" + ); + self.stored_bytes = stored_size; self.memory.execute_store(0, element) } - pub fn load(&self, size: usize) -> Result> where - T: MemoryStorable, { - if self.memory.get_len() < size - //|| self.stored_bytes < size + pub fn load(&self, size: usize) -> Result> + where + T: MemoryStorable, + { + if self.memory.get_len() < size + //|| self.stored_bytes < size { - bail!("Loading outside crossbar boundary [{} {}] < {}", self.stored_bytes, self.memory.get_len() , size); + bail!( + "Loading outside crossbar boundary [{} {}] < {}", + self.stored_bytes, + self.memory.get_len(), + size + ); } self.memory.load_const(0, size) } - - - } diff --git a/backend-simulators/pim/pim-simulator/src/lib/cpu/mod.rs b/backend-simulators/pim/pim-simulator/src/lib/cpu/mod.rs index 0ab2f4a..d3f2e87 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/cpu/mod.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/cpu/mod.rs @@ -1,6 +1,6 @@ use crate::utility::AddressArg; -use std::{collections::HashMap, fmt::Debug}; use anyhow::{Context, Result, ensure}; +use std::{collections::HashMap, fmt::Debug}; use crate::{ cpu::crossbar::Crossbar, @@ -10,14 +10,13 @@ use crate::{ pub mod crossbar; - #[derive(Debug, Clone)] pub struct CPU<'a> { cores: Box<[Core<'a>]>, } impl<'a> CPU<'a> { - pub fn new(num_cores: impl TryToUsize, crossbars: Vec> ) -> Self { + pub fn new(num_cores: impl TryToUsize, crossbars: Vec>) -> Self { let num_cores = num_cores.try_into().expect("num_cores can not be negative"); assert!(crossbars.len() == num_cores + 1); let mut cores = Vec::new(); @@ -30,25 +29,31 @@ impl<'a> CPU<'a> { } pub fn host<'b>(&'b mut self) -> &'b mut Core<'a> - where 'a : 'b + where + 'a: 'b, { - & mut self.cores[0] + &mut self.cores[0] } - pub fn core<'b >(&'b mut self, index: impl TryToUsize) -> &'b mut Core<'a> - where 'a : 'b + pub fn core<'b>(&'b mut self, index: impl TryToUsize) -> &'b mut Core<'a> + where + 'a: 'b, { let index = index.try_into().expect("can not be negative"); - & mut self.cores[index] + &mut self.cores[index] } pub fn num_core(&self) -> usize { self.cores.len() } - pub(crate) fn host_and_cores<'b, 'c >(&'b mut self, core: impl TryToUsize) -> (&'c mut Core<'a>, &'c mut Core<'a>) - where 'a: 'b, - 'b: 'c + pub(crate) fn host_and_cores<'b, 'c>( + &'b mut self, + core: impl TryToUsize, + ) -> (&'c mut Core<'a>, &'c mut Core<'a>) + where + 'a: 'b, + 'b: 'c, { let core = core.try_into().expect("core can not be negative"); assert_ne!( @@ -63,8 +68,12 @@ impl<'a> CPU<'a> { (host, core) } - pub fn get_multiple_cores<'b, const N: usize>(&'b mut self, indices: [usize; N]) -> [&'b mut Core<'a>; N] - where 'a : 'b + pub fn get_multiple_cores<'b, const N: usize>( + &'b mut self, + indices: [usize; N], + ) -> [&'b mut Core<'a>; N] + where + 'a: 'b, { self.cores.get_disjoint_mut(indices).unwrap() } @@ -78,7 +87,7 @@ pub struct Core<'a> { } impl<'a> Core<'a> { - fn new(crossbars : Vec<&'a Crossbar>) -> Self { + fn new(crossbars: Vec<&'a Crossbar>) -> Self { Self { crossbars, memory: CoreMemory::new(), @@ -139,7 +148,12 @@ impl<'a> Core<'a> { (memory, crossbars) } - pub fn memset(&mut self, address: impl AddressArg, size: impl TryToUsize, val: u8) -> Result<()> { + pub fn memset( + &mut self, + address: impl AddressArg, + size: impl TryToUsize, + val: u8, + ) -> Result<()> { let address = address.to_address_usize()?; let size = size.try_into().context("size can not be negative")?; self.memory.memset(address, size, val) diff --git a/backend-simulators/pim/pim-simulator/src/lib/instruction_set/instruction_data.rs b/backend-simulators/pim/pim-simulator/src/lib/instruction_set/instruction_data.rs index df94357..ac06767 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/instruction_set/instruction_data.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/instruction_set/instruction_data.rs @@ -278,9 +278,18 @@ impl InstructionDataBuilder { } fn check_sanity(&self) { - assert!(!(self.get_r2() != 0 && self.get_imm() != 0 && self.get_mbiw() != 0 && self.get_imm_core() != 0)); - assert!(!(self.get_ibiw() != 0 && self.get_offset_select() != 0 && self.get_imm_relu() != 0)); - assert!(!(self.get_obiw() != 0 && self.get_offset_value() != 0 && self.get_imm_group() != 0)); + assert!( + !(self.get_r2() != 0 + && self.get_imm() != 0 + && self.get_mbiw() != 0 + && self.get_imm_core() != 0) + ); + assert!( + !(self.get_ibiw() != 0 && self.get_offset_select() != 0 && self.get_imm_relu() != 0) + ); + assert!( + !(self.get_obiw() != 0 && self.get_offset_value() != 0 && self.get_imm_group() != 0) + ); } pub fn build(&mut self) -> InstructionData { diff --git a/backend-simulators/pim/pim-simulator/src/lib/instruction_set/isa.rs b/backend-simulators/pim/pim-simulator/src/lib/instruction_set/isa.rs index 1f78916..a1bc556 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/instruction_set/isa.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/instruction_set/isa.rs @@ -9,7 +9,7 @@ use crate::{ type_traits::{FromFloat, UpcastDestTraits, UpcastSlice}, }, tracing::TRACER, - utility::{add_offset_r1, add_offset_r2, add_offset_rd}, + utility::{AddressArg, add_offset_r1, add_offset_r2, add_offset_rd}, }; use aligned_vec::{AVec, ConstAlign}; use anyhow::{Context, Result, ensure}; @@ -58,7 +58,7 @@ pub static NAMES: LazyLock> = LazyLock::new(|| { add_name_simd!(hash, vtanh); add_name_simd!(hash, vsigm); add_name_simd!(hash, vsoftmax); - add_name!(hash, vmv); + add_name_simd!(hash, vmv); add_name!(hash, vrsu); add_name!(hash, vrsl); add_name!(hash, ld); @@ -189,6 +189,7 @@ static SIMD: LazyLock>> add_simd_to_map!(storage, vtanh); add_simd_to_map!(storage, vsigm); add_simd_to_map!(storage, vsoftmax); + add_simd_to_map!(storage, vmv); add_simd_to_map!(storage, mvmul); storage }); @@ -273,7 +274,10 @@ where "Stored crossbar bytes do not describe an integral number of columns" ); let crossbar_elem_width = crossbar_stored_bytes / bytes_per_column; - ensure!(crossbar_elem_width != 0, "Crossbar contains no stored columns"); + ensure!( + crossbar_elem_width != 0, + "Crossbar contains no stored columns" + ); let loads = memory .reserve_load(r1_val, crossbar_height * size_of::())? @@ -742,7 +746,41 @@ where #[inline(never)] pub fn vmv(cores: &mut CPU, data: InstructionData) -> Result { - todo!() + panic!("You are calling a placeholder, the real call is the generic version"); +} + +#[inline(never)] +pub(super) fn vmv_impl(cores: &mut CPU, data: InstructionData) -> Result +where + F: Copy + MemoryStorable, +{ + let (core_indx, rd, r1, r2, imm_len, _, _) = data.get_core_rd_r1_r2_immlen_offset(); + let core = cores.core(core_indx); + let source = core.register(r1).to_address_usize()?; + let destination = core.register(rd); + let stride: usize = core + .register(r2) + .try_into() + .context("vmv stride can not be negative")?; + let (element_count, _) = vector_lengths::(imm_len)?; + let stride_bytes = stride + .checked_mul(size_of::()) + .context("vmv byte stride overflow")?; + let mut result = Vec::with_capacity(element_count); + for index in 0..element_count { + let offset = index + .checked_mul(stride_bytes) + .context("vmv source offset overflow")?; + let address = source + .checked_add(offset) + .context("vmv source address overflow")?; + result.push( + core.reserve_load(address, size_of::())? + .execute_load::()?[0][0], + ); + } + core.execute_store(destination, &result)?; + Ok(InstructionStatus::Completed) } #[inline(never)] @@ -827,7 +865,7 @@ pub fn lmv(cores: &mut CPU, data: InstructionData) -> Result } #[inline(never)] -pub fn isa_send(functor : usize) -> bool{ +pub fn isa_send(functor: usize) -> bool { (send as *const () as usize) == functor } @@ -837,7 +875,7 @@ pub fn send(cores: &mut CPU, data: InstructionData) -> Result } #[inline(never)] -pub fn isa_recv(functor : usize) -> bool{ +pub fn isa_recv(functor: usize) -> bool { (recv as *const () as usize) == functor } diff --git a/backend-simulators/pim/pim-simulator/src/lib/instruction_set/mod.rs b/backend-simulators/pim/pim-simulator/src/lib/instruction_set/mod.rs index 81cf77a..8b27bfc 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/instruction_set/mod.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/instruction_set/mod.rs @@ -7,9 +7,9 @@ use crate::{ }; use anyhow::{Context, Result}; use std::mem::swap; +pub mod helper; pub mod instruction_data; pub mod isa; -pub mod helper; #[derive(Clone, Copy, Debug)] pub struct Instruction { @@ -41,7 +41,8 @@ impl Instruction { } pub fn execute<'a, 'b>(&'b self, cpu: &mut CPU<'a>) -> InstructionStatus - where 'a : 'b + where + 'a: 'b, { (self.functor)(cpu, self.data) .with_context(|| format!("Instruction: {}", functor_to_name(self.functor as usize))) diff --git a/backend-simulators/pim/pim-simulator/src/lib/memory_manager/mod.rs b/backend-simulators/pim/pim-simulator/src/lib/memory_manager/mod.rs index d217584..efdf696 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/memory_manager/mod.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/memory_manager/mod.rs @@ -78,7 +78,11 @@ impl CoreMemory { } } - pub fn reserve_load(&mut self, address: impl TryToUsize, size: impl TryToUsize) -> Result<&mut Self> + pub fn reserve_load( + &mut self, + address: impl TryToUsize, + size: impl TryToUsize, + ) -> Result<&mut Self> where { let address = address.try_into().context("address can not be negative")?; let size = size.try_into().context("size can not be negative")?; @@ -87,7 +91,8 @@ where { size, }; if self.memory.len() < address + size { - self.memory.resize(min((address + size) * 2, u32::MAX as usize), 0); + self.memory + .resize(min((address + size) * 2, u32::MAX as usize), 0); } self.load_requests.push(load_request); Ok(self) @@ -105,14 +110,24 @@ where { for (load_index, load_request) in load_requests.drain(..).enumerate() { let LoadRequest { index, size } = load_request; let memory_slice = &memory[index..index + size]; - let memory_slice = unsafe { slice_from_u8(memory_slice) } - .with_context(|| format!("Load number: {} Accessing from {} to {}", load_index, index, index + size))?; + let memory_slice = unsafe { slice_from_u8(memory_slice) }.with_context(|| { + format!( + "Load number: {} Accessing from {} to {}", + load_index, + index, + index + size + ) + })?; res.push(memory_slice); } Ok(res) } - pub fn load_const(&self, address: impl TryToUsize, size: impl TryToUsize) -> Result> + pub fn load_const( + &self, + address: impl TryToUsize, + size: impl TryToUsize, + ) -> Result> where T: MemoryStorable, { @@ -125,7 +140,7 @@ where { let mut res = Vec::new(); let memory_slice = &memory[address..address + size]; let memory_slice = unsafe { slice_from_u8(memory_slice) } - .with_context(|| format!("Accessing from {} to {}", address, address + size))?; + .with_context(|| format!("Accessing from {} to {}", address, address + size))?; res.push(memory_slice); Ok(res) } @@ -155,7 +170,12 @@ where { Ok(()) } - pub fn memset(&mut self, address: impl TryToUsize, size: impl TryToUsize, val: u8) -> Result<()> { + pub fn memset( + &mut self, + address: impl TryToUsize, + size: impl TryToUsize, + val: u8, + ) -> Result<()> { let address = address.try_into().expect("address can not be negative"); let size = size.try_into().expect("size can not be negative"); let Self { memory, .. } = self; @@ -174,11 +194,11 @@ where { } } - pub fn get_len(&self) ->usize { + pub fn get_len(&self) -> usize { self.memory.len() } - pub(crate) fn clear(&mut self) { + pub(crate) fn clear(&mut self) { self.memory.clear(); } } @@ -257,7 +277,11 @@ mod test { let mut data = [0_f32; 2]; data[0] = loads[0][0] + loads[1][0]; core_memory.execute_store(4, &data[0..1]).unwrap(); - let loads: &[f32] = core_memory.reserve_load(0, 16).unwrap().execute_load().unwrap()[0]; + let loads: &[f32] = core_memory + .reserve_load(0, 16) + .unwrap() + .execute_load() + .unwrap()[0]; println!("{:?}", loads); assert!(loads[0] == 5_f32 && loads[1] == 12_f32 && loads[2] == 7_f32 && loads[3] == 15_f32) } diff --git a/backend-simulators/pim/pim-simulator/src/lib/memory_manager/type_traits.rs b/backend-simulators/pim/pim-simulator/src/lib/memory_manager/type_traits.rs index b79d51d..d5a6c79 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/memory_manager/type_traits.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/memory_manager/type_traits.rs @@ -1,5 +1,3 @@ - - use std::{ borrow::Cow, fmt::Debug, @@ -9,32 +7,32 @@ use std::{ use anyhow::Context; pub trait FromFloat { - fn from_f32(val :f32) -> Self; - fn from_f64(val :f64) -> Self; + fn from_f32(val: f32) -> Self; + fn from_f64(val: f64) -> Self; } impl FromFloat for f32 { - fn from_f32(val :f32) -> Self { + fn from_f32(val: f32) -> Self { val } - fn from_f64(val :f64) -> Self { + fn from_f64(val: f64) -> Self { val as f32 } } impl FromFloat for f64 { - fn from_f32(val :f32) -> Self { + fn from_f32(val: f32) -> Self { val as f64 } - fn from_f64(val :f64) -> Self { - val + fn from_f64(val: f64) -> Self { + val } } pub trait HasTanh { - fn tanh(self) -> Self ; + fn tanh(self) -> Self; } impl HasTanh for f32 { @@ -50,7 +48,7 @@ impl HasTanh for f64 { } pub trait HasSigm { - fn sigm(self) -> Self ; + fn sigm(self) -> Self; } impl HasSigm for f32 { @@ -91,34 +89,36 @@ impl HasExp for f64 { } } - - -pub trait TryToUsize: TryInto -where std::result::Result : Context +pub trait TryToUsize: TryInto +where + std::result::Result: Context, { type TryError: Debug + Send + Sync + 'static + std::error::Error; } -impl TryToUsize for T -where +impl TryToUsize for T +where T: TryInto, E: Debug + Send + Sync + 'static + std::error::Error, - std::result::Result : Context + std::result::Result: Context, { type TryError = E; } - pub trait FromUsize { fn from_usize(v: usize) -> Self; } impl FromUsize for f32 { - fn from_usize(v: usize) -> Self { v as f32 } + fn from_usize(v: usize) -> Self { + v as f32 + } } impl FromUsize for f64 { - fn from_usize(v: usize) -> Self { v as f64 } + fn from_usize(v: usize) -> Self { + v as f64 + } } pub trait UpcastDestTraits: diff --git a/backend-simulators/pim/pim-simulator/src/lib/pimcore.rs b/backend-simulators/pim/pim-simulator/src/lib/pimcore.rs index d33bf34..487b65e 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/pimcore.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/pimcore.rs @@ -250,7 +250,10 @@ fn detect_deadlock(cores_instructions: &[CoreInstructions]) -> Option Option { - } + CoreState::Working | CoreState::Halted => {} } } diff --git a/backend-simulators/pim/pim-simulator/src/lib/send_recv.rs b/backend-simulators/pim/pim-simulator/src/lib/send_recv.rs index f3a9848..258ac2a 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/send_recv.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/send_recv.rs @@ -41,16 +41,17 @@ impl SendRecv { } } -pub fn handle_send_recv<'a, 'b >( +pub fn handle_send_recv<'a, 'b>( cpu: &'b mut CPU<'a>, - core_instructions: & mut [CoreInstructions], - send_recv: & mut SendRecv, + core_instructions: &mut [CoreInstructions], + send_recv: &mut SendRecv, core_result: InstructionStatus, ) -> (bool, usize) -where 'a : 'b +where + 'a: 'b, { let transfer_memory = |cpu: &'b mut CPU<'a>, - core_instructions: & mut [CoreInstructions], + core_instructions: &mut [CoreInstructions], sender: Option, receiver: Option| { if let Some(sender) = sender diff --git a/backend-simulators/pim/pim-simulator/src/lib/tracing/disable.rs b/backend-simulators/pim/pim-simulator/src/lib/tracing/disable.rs index ff6215b..ccbd0c3 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/tracing/disable.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/tracing/disable.rs @@ -1,4 +1,3 @@ - use std::fs::File; use crate::{ @@ -19,58 +18,41 @@ impl Trace { /////////////////Scalar/register Instructions////////////////// /////////////////////////////////////////////////////////////// - pub fn pre_sldi(&mut self, cores: &mut CPU, data: InstructionData) { + pub fn pre_sldi(&mut self, cores: &mut CPU, data: InstructionData) {} - } + pub fn post_sldi(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn post_sldi(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn pre_sld(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn pre_sld(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn post_sld(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn post_sld(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn pre_sadd(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn pre_sadd(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn post_sadd(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn post_sadd(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn pre_ssub(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn pre_ssub(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn post_ssub(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn post_ssub(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn pre_smul(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn pre_smul(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn post_smul(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn post_smul(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn pre_saddi(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn pre_saddi(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn post_saddi(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn post_saddi(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn pre_smuli(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn pre_smuli(&mut self, cores: &mut CPU, data: InstructionData) { - } - - pub fn post_smuli(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn post_smuli(&mut self, cores: &mut CPU, data: InstructionData) {} ///////////////////////////////////////////////////////////////// ///////////////////Matrix/vector Instructions//////////////////// ///////////////////////////////////////////////////////////////// - pub fn pre_setbw(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn pre_setbw(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn post_setbw(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn post_setbw(&mut self, cores: &mut CPU, data: InstructionData) {} pub fn pre_mvm(&mut self, cores: &mut CPU, data: InstructionData) where @@ -80,7 +62,7 @@ impl Trace { M: UpcastDestTraits + MemoryStorable + FromFloat, F: UpcastDestTraits + MemoryStorable, { - self.mvm_impl::(cores, data, "Pre"); + self.mvm_impl::(cores, data, "Pre"); } pub fn post_mvm(&mut self, cores: &mut CPU, data: InstructionData) @@ -91,11 +73,15 @@ impl Trace { M: UpcastDestTraits + MemoryStorable + FromFloat, F: UpcastDestTraits + MemoryStorable, { - self.mvm_impl::(cores, data, "Post"); + self.mvm_impl::(cores, data, "Post"); } - pub fn mvm_impl(&mut self, cores: &mut CPU, data: InstructionData, prefix : &'static str) - where + pub fn mvm_impl( + &mut self, + cores: &mut CPU, + data: InstructionData, + prefix: &'static str, + ) where [F]: UpcastSlice + UpcastSlice, [M]: UpcastSlice, T: UpcastDestTraits + MemoryStorable, @@ -267,39 +253,27 @@ impl Trace { ///////////////////////////////////////////////////////////////// /////Communication/synchronization Instructions///////////////// ///////////////////////////////////////////////////////////////// - pub fn pre_ld(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn pre_ld(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn post_ld(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn post_ld(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn pre_st(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn pre_st(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn post_st(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn post_st(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn pre_lldi(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn pre_lldi(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn post_lldi(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn post_lldi(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn pre_lmv(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn pre_lmv(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn post_lmv(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn post_lmv(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn pre_send(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn pre_send(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn post_send(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn post_send(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn pre_recv(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn pre_recv(&mut self, cores: &mut CPU, data: InstructionData) {} - pub fn post_recv(&mut self, cores: &mut CPU, data: InstructionData) { - } + pub fn post_recv(&mut self, cores: &mut CPU, data: InstructionData) {} } diff --git a/backend-simulators/pim/pim-simulator/src/lib/tracing/mod.rs b/backend-simulators/pim/pim-simulator/src/lib/tracing/mod.rs index bef60a9..b5450ce 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/tracing/mod.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/tracing/mod.rs @@ -15,7 +15,6 @@ use crate::Executable; use std::path::PathBuf; use std::sync::{LazyLock, Mutex}; - #[cfg(not(any(feature = "tracing", feature = "profile_time")))] pub struct Trace {} @@ -28,5 +27,4 @@ impl Trace { pub fn init(&mut self, num_core: usize, path: PathBuf) {} } - pub static TRACER: LazyLock> = LazyLock::new(|| Trace::new().into()); diff --git a/backend-simulators/pim/pim-simulator/src/lib/tracing/profile/mod.rs b/backend-simulators/pim/pim-simulator/src/lib/tracing/profile/mod.rs index 2583a49..65082ec 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/tracing/profile/mod.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/tracing/profile/mod.rs @@ -8,7 +8,7 @@ pub mod profile_analysis; pub mod profile_isa; pub struct Trace { - instruction_times: HashMap>, + instruction_times: HashMap>, core_start_time: HashMap>, start_time: Instant, } @@ -51,7 +51,7 @@ impl Trace { Self { instruction_times, core_start_time: HashMap::new(), - start_time: Instant::now() + start_time: Instant::now(), } } diff --git a/backend-simulators/pim/pim-simulator/src/lib/tracing/profile/profile_analysis.rs b/backend-simulators/pim/pim-simulator/src/lib/tracing/profile/profile_analysis.rs index 4ae5a2c..c06be07 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/tracing/profile/profile_analysis.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/tracing/profile/profile_analysis.rs @@ -145,17 +145,15 @@ pub fn print_textual_report(stats: &[InstructionStats]) { println!("{table}"); } - pub fn generate_interactive_report( timings: &HashMap>, instructions_to_plot: &[&str], // <-- NEW: Only plot these file_path: &str, ) { - -use plotly::common::{Mode, Marker, Line}; -use plotly::layout::{Axis, Layout}; -use plotly::{Plot, Scatter}; -use std::collections::HashMap; + use plotly::common::{Line, Marker, Mode}; + use plotly::layout::{Axis, Layout}; + use plotly::{Plot, Scatter}; + use std::collections::HashMap; let mut plot = Plot::new(); for &instruction_name in instructions_to_plot { @@ -163,8 +161,9 @@ use std::collections::HashMap; if let Some(times) = timings.get(instruction_name) { let x_axis: Vec = times.iter().map(|&(ts, _)| ts as f64).collect(); let y_axis: Vec = times.iter().map(|&(_, dur)| dur as f64).collect(); - - let text_array: Vec = times.iter() + + let text_array: Vec = times + .iter() .map(|&(_, dur)| format_time(dur as f64)) .collect(); @@ -181,7 +180,9 @@ use std::collections::HashMap; } let layout = Layout::new() - .title(plotly::common::Title::new("Simulator Timeline: Top Offenders")) + .title(plotly::common::Title::new( + "Simulator Timeline: Top Offenders", + )) .x_axis(Axis::new().title(plotly::common::Title::new("Absolute Time (ns)"))) .y_axis(Axis::new().title(plotly::common::Title::new("Execution Duration"))); @@ -189,4 +190,3 @@ use std::collections::HashMap; plot.write_html(file_path); println!("🌐 Interactive timeline saved to {}", file_path); } - diff --git a/backend-simulators/pim/pim-simulator/src/lib/tracing/profile/profile_isa.rs b/backend-simulators/pim/pim-simulator/src/lib/tracing/profile/profile_isa.rs index 88aeefa..7fa48ae 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/tracing/profile/profile_isa.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/tracing/profile/profile_isa.rs @@ -34,10 +34,11 @@ impl Trace { start_time, } = self; let now = Instant::now(); - instruction_times - .get_mut(name) - .unwrap() - .push((now.duration_since(*start_time).as_nanos(), now.duration_since(core_start_time[&core_indx].unwrap()).as_nanos())); + instruction_times.get_mut(name).unwrap().push(( + now.duration_since(*start_time).as_nanos(), + now.duration_since(core_start_time[&core_indx].unwrap()) + .as_nanos(), + )); self.core_start_time.insert(core_indx, None); } diff --git a/backend-simulators/pim/pim-simulator/src/lib/tracing/trace/mod.rs b/backend-simulators/pim/pim-simulator/src/lib/tracing/trace/mod.rs index a38b184..11fc992 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/tracing/trace/mod.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/tracing/trace/mod.rs @@ -7,7 +7,6 @@ pub struct Trace { out_files: Vec, } - impl Trace { pub fn new() -> Self { Self { @@ -25,4 +24,3 @@ impl Trace { } } } - diff --git a/backend-simulators/pim/pim-simulator/src/lib/tracing/trace/tracing_isa.rs b/backend-simulators/pim/pim-simulator/src/lib/tracing/trace/tracing_isa.rs index e4acd80..f9a4446 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/tracing/trace/tracing_isa.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/tracing/trace/tracing_isa.rs @@ -283,7 +283,6 @@ impl Trace { M: UpcastDestTraits + MemoryStorable + FromFloat, F: UpcastDestTraits + MemoryStorable, { - let (core_indx, rd, r1, mbiw, relu, group) = data.get_core_rd_r1_mbiw_immrelu_immgroup(); let file: &mut File = self .out_files @@ -337,7 +336,7 @@ impl Trace { ); pretty_print::print_slice::<_, F>(file, loads[0], 30); writeln!(file, "\tCrossbar[{}:{}](B): ", 0, crossbar_byte_size); - pretty_print::print_slice::<_,F>(file, matrix, 30); + pretty_print::print_slice::<_, F>(file, matrix, 30); writeln!( file, "\tLocal[{}:{}](out): ", @@ -409,11 +408,11 @@ impl Trace { .unwrap(); writeln!(file, "{} Memory:", prefix); write!(file, "\tLocal[{}:{}](A): ", r1_final, r1_final + byte_len); - pretty_print::print_slice::<_,f32>(file, loads[0], 30); - write!(file, "\tLocal[{}:{}](B): ", r2_final , r2_final + byte_len); - pretty_print::print_slice::<_,f32>(file, loads[1], 30); - write!(file, "\tLocal[{}:{}](out): ", rd_final, rd_final+ byte_len); - pretty_print::print_slice::<_,f32>(file, loads[2], 30); + pretty_print::print_slice::<_, f32>(file, loads[0], 30); + write!(file, "\tLocal[{}:{}](B): ", r2_final, r2_final + byte_len); + pretty_print::print_slice::<_, f32>(file, loads[1], 30); + write!(file, "\tLocal[{}:{}](out): ", rd_final, rd_final + byte_len); + pretty_print::print_slice::<_, f32>(file, loads[2], 30); if prefix == "Post" { writeln!(file, "\n###############################################\n"); } @@ -1027,9 +1026,9 @@ impl Trace { let core_memory = core.load::(rd_val, imm_len).unwrap(); writeln!(file, "{} Memory:", prefix); writeln!(file, "\tHost[{}:{}]: ", r1_val, r1_val + imm_len as usize,); - pretty_print::print_slice::<_,f32>(file, global_memory[0], 30); + pretty_print::print_slice::<_, f32>(file, global_memory[0], 30); writeln!(file, "\tLocal[{}:{}]: ", rd_val, rd_val + imm_len as usize,); - pretty_print::print_slice::<_,f32>(file, core_memory[0], 30); + pretty_print::print_slice::<_, f32>(file, core_memory[0], 30); if prefix == "Post" { writeln!(file, "\n###############################################\n"); @@ -1079,9 +1078,9 @@ impl Trace { let global_memory = host.load::(rd_val, imm_len).unwrap(); writeln!(file, "{} Memory:", prefix); writeln!(file, "\tLocal[{}:{}]: ", r1_val, r1_val + imm_len as usize,); - pretty_print::print_slice::<_,f32>(file, core_memory[0], 30); + pretty_print::print_slice::<_, f32>(file, core_memory[0], 30); writeln!(file, "\tHost[{}:{}]: ", rd_val, rd_val + imm_len as usize,); - pretty_print::print_slice::<_,f32>(file, global_memory[0], 30); + pretty_print::print_slice::<_, f32>(file, global_memory[0], 30); if prefix == "Post" { writeln!(file, "\n###############################################\n"); @@ -1096,7 +1095,6 @@ impl Trace { self.st_impl(cores, data, "Pre"); } - pub fn pre_lldi(&mut self, cores: &mut CPU, data: InstructionData) { let (core, rd, imm) = data.get_core_rd_imm(); let file: &mut File = self @@ -1136,8 +1134,7 @@ impl Trace { // Ok(InstructionStatus::Completed) } - fn lmv_impl (&mut self, cores: &mut CPU, data: InstructionData, prefix: &'static str) { - + fn lmv_impl(&mut self, cores: &mut CPU, data: InstructionData, prefix: &'static str) { let (core, rd, r1, _, imm_len, offset_select, offset_value) = data.get_core_rd_r1_r2_immlen_offset(); let file: &mut File = self @@ -1169,14 +1166,17 @@ impl Trace { let r1_val = add_offset_r1(r1_val, offset_select, offset_value); let rd_val = add_offset_rd(rd_val, offset_select, offset_value); let core_memory = core - .reserve_load(r1_val, imm_len).unwrap() - .reserve_load(rd_val, imm_len).unwrap() - .execute_load::().unwrap(); + .reserve_load(r1_val, imm_len) + .unwrap() + .reserve_load(rd_val, imm_len) + .unwrap() + .execute_load::() + .unwrap(); writeln!(file, "{} Memory:", prefix); writeln!(file, "\tLocal[{}:{}]: ", r1_val, r1_val + imm_len as usize,); - pretty_print::print_slice::<_,f32>(file, core_memory[0], 30); + pretty_print::print_slice::<_, f32>(file, core_memory[0], 30); writeln!(file, "\tLocal[{}:{}]: ", rd_val, rd_val + imm_len as usize,); - pretty_print::print_slice::<_,f32>(file, core_memory[1], 30); + pretty_print::print_slice::<_, f32>(file, core_memory[1], 30); if prefix == "Post" { writeln!(file, "\n###############################################\n"); diff --git a/backend-simulators/pim/pim-simulator/src/lib/utility.rs b/backend-simulators/pim/pim-simulator/src/lib/utility.rs index b21a9d5..c386cbd 100644 --- a/backend-simulators/pim/pim-simulator/src/lib/utility.rs +++ b/backend-simulators/pim/pim-simulator/src/lib/utility.rs @@ -1,7 +1,6 @@ -use anyhow::{Result,Context}; +use anyhow::{Context, Result}; use std::{fmt::Debug, mem::transmute}; - pub trait AddressArg { fn to_address_usize(self) -> Result; } @@ -36,42 +35,56 @@ impl AddressArg for i64 { } } - fn address_to_usize(address: i32) -> usize { address as u32 as usize } -fn add_offset_impl(address: usize, offset_select : i32, offset_value : i32, id:i32) -> usize{ - assert!(offset_select == 1 || offset_select == 2 || offset_select == 4 || offset_value == 0, "offset_select not a bit field"); - let offset_value = (offset_select & id) * offset_value; - if offset_value > 0 { - address + offset_value as usize - } else { - address - offset_value as usize - } +fn add_offset_impl(address: usize, offset_select: i32, offset_value: i32, id: i32) -> usize { + assert!( + (0..=7).contains(&offset_select), + "offset_select is not a 3-bit field" + ); + if offset_select & id == 0 { + address + } else { + address + .checked_add_signed(offset_value as isize) + .expect("address offset overflow") + } } - -pub fn add_offset_rd(address: i32, offset_select : i32, offset_value : i32) -> usize -{ - let address = address_to_usize(address); - add_offset_impl(address, offset_select, offset_value, 4) -} - -pub fn add_offset_r1(address: i32, offset_select : i32, offset_value : i32) -> usize -{ +pub fn add_offset_rd(address: i32, offset_select: i32, offset_value: i32) -> usize { let address = address_to_usize(address); add_offset_impl(address, offset_select, offset_value, 1) } -pub fn add_offset_r2(address: i32, offset_select : i32, offset_value : i32) -> usize -{ +pub fn add_offset_r1(address: i32, offset_select: i32, offset_value: i32) -> usize { let address = address_to_usize(address); add_offset_impl(address, offset_select, offset_value, 2) } - -pub fn pack_float_in_i32(val : impl TryInto) -> i32 { - let val = val.try_into().unwrap_or_else( |x| panic!("Cannot parse into f32")); - f32::to_bits(val).cast_signed() +pub fn add_offset_r2(address: i32, offset_select: i32, offset_value: i32) -> usize { + let address = address_to_usize(address); + add_offset_impl(address, offset_select, offset_value, 4) +} + +#[cfg(test)] +mod tests { + use super::{add_offset_r1, add_offset_r2, add_offset_rd}; + + #[test] + fn offset_select_uses_rd_rs1_rs2_bit_order() { + assert_eq!(add_offset_rd(100, 1, 7), 107); + assert_eq!(add_offset_r1(100, 2, 7), 107); + assert_eq!(add_offset_r2(100, 4, 7), 107); + assert_eq!(add_offset_rd(100, 6, 7), 100); + assert_eq!(add_offset_r1(100, 7, -7), 93); + } +} + +pub fn pack_float_in_i32(val: impl TryInto) -> i32 { + let val = val + .try_into() + .unwrap_or_else(|x| panic!("Cannot parse into f32")); + f32::to_bits(val).cast_signed() } diff --git a/backend-simulators/pim/pim-simulator/tests/big_mul.rs b/backend-simulators/pim/pim-simulator/tests/big_mul.rs index c66ec0b..9a62d6f 100644 --- a/backend-simulators/pim/pim-simulator/tests/big_mul.rs +++ b/backend-simulators/pim/pim-simulator/tests/big_mul.rs @@ -7,7 +7,7 @@ use pimcore::{ memory_manager::CoreMemory, }; -fn simple_read(path: &Path) -> Vec { +fn simple_read(path: &Path) -> Vec { if !path.exists() { panic!("{:?} not exists", path) } @@ -19,9 +19,7 @@ fn simple_read(path: &Path) -> Vec { } /// mvmul Test -fn mvmul_f32(err: &str) -where -{ +fn mvmul_f32(err: &str) { let matrix = simple_read(Path::new("tests/B.txt")); let mut crossbar = Crossbar::new(1024 * size_of::(), 1024, CoreMemory::new()); crossbar.execute_store(&matrix).unwrap(); @@ -36,7 +34,9 @@ where inst_builder.make_inst(sldi, idata_build.set_rdimm(1, 0).build()); inst_builder.make_inst( sldi, - idata_build.set_rdimm(3, 1024 * size_of::() as i32).build(), + idata_build + .set_rdimm(3, 1024 * size_of::() as i32) + .build(), ); inst_builder.make_inst( setbw, @@ -48,7 +48,7 @@ where mvmul, idata_build .set_rdr1(3, 1) - .set_mbiw_immrelu_immgroup(8*size_of::() as i32, 0, 0) + .set_mbiw_immrelu_immgroup(8 * size_of::() as i32, 0, 0) .build(), ); let core_instruction = vec![inst_builder.build().into()]; @@ -59,8 +59,11 @@ where executable .cpu_mut() .host() - .load::(1024 * size_of::(), 1024*size_of::()).unwrap()[0].iter().zip( - simple_read(Path::new("tests/X.txt")) ).all(|(&a,b) : (&f32, f32)| {a-b < 0.001}), + .load::(1024 * size_of::(), 1024 * size_of::()) + .unwrap()[0] + .iter() + .zip(simple_read(Path::new("tests/X.txt"))) + .all(|(&a, b): (&f32, f32)| { a - b < 0.001 }), "Wrong result for {}", err ); @@ -69,6 +72,4 @@ where #[test] fn mvmul_big_test() { mvmul_f32("mvmul_f32"); - - } diff --git a/backend-simulators/pim/pim-simulator/tests/es_runner.rs b/backend-simulators/pim/pim-simulator/tests/es_runner.rs index 8cd90a2..23c2258 100644 --- a/backend-simulators/pim/pim-simulator/tests/es_runner.rs +++ b/backend-simulators/pim/pim-simulator/tests/es_runner.rs @@ -6,9 +6,7 @@ use std::{ use anyhow::{Context, Result}; use pimcore::{ - cpu::crossbar::Crossbar, - json_to_instruction::json_to_executor, - memory_manager::CoreMemory, + cpu::crossbar::Crossbar, json_to_instruction::json_to_executor, memory_manager::CoreMemory, }; use serde_json::Value; @@ -95,9 +93,14 @@ fn json_folder_tester() { .map(|core_crossbars| core_crossbars.iter().collect()) .collect(); - let mut executable = json_to_executor::json_to_executor(config, &mut core_readers, crossbars); + let mut executable = + json_to_executor::json_to_executor(config, &mut core_readers, crossbars); let memory = fs::read(folder.join("memory.bin")).unwrap(); - executable.cpu_mut().host().execute_store(0, &memory).unwrap(); + executable + .cpu_mut() + .host() + .execute_store(0, &memory) + .unwrap(); executable.execute(); } } diff --git a/backend-simulators/pim/pim-simulator/tests/placeholder.rs b/backend-simulators/pim/pim-simulator/tests/placeholder.rs index 576ce8f..b5877d2 100644 --- a/backend-simulators/pim/pim-simulator/tests/placeholder.rs +++ b/backend-simulators/pim/pim-simulator/tests/placeholder.rs @@ -7,26 +7,17 @@ use pimcore::{ }, }; - #[test] -#[should_panic(expected = "Function not found for the requested size") ] +#[should_panic(expected = "Function not found for the requested size")] fn wrong_size_place_holder() { let cpu = common::empty_cpu(0); let mut inst_builder = InstructionsBuilder::new(); let mut idata_build = InstructionDataBuilder::new(); idata_build.set_core_indx(0).fix_core_indx(); - inst_builder.make_inst( - setbw, - idata_build - .set_ibiw_obiw(55, 55) - .build(), - ); + inst_builder.make_inst(setbw, idata_build.set_ibiw_obiw(55, 55).build()); inst_builder.make_inst( vvadd, - idata_build - .set_rdr1r2(3, 1, 2) - .set_imm_len(8) - .build(), + idata_build.set_rdr1r2(3, 1, 2).set_imm_len(8).build(), ); let core_instruction = vec![inst_builder.build().into()]; let mut executable = Executable::new(cpu, core_instruction); @@ -39,97 +30,88 @@ fn unsupported_8_bit_vectors_do_not_alias_f32() { let mut inst_builder = InstructionsBuilder::new(); let mut idata_build = InstructionDataBuilder::new(); idata_build.set_core_indx(0).fix_core_indx(); - inst_builder.make_inst( - setbw, - idata_build.set_ibiw_obiw(8, 8).build(), - ); + inst_builder.make_inst(setbw, idata_build.set_ibiw_obiw(8, 8).build()); inst_builder.make_inst( vvadd, - idata_build - .set_rdr1r2(3, 1, 2) - .set_imm_len(8) - .build(), + idata_build.set_rdr1r2(3, 1, 2).set_imm_len(8).build(), ); } - - -fn place_holder(inst : InstructionType) { +fn place_holder(inst: InstructionType) { let mut cpu = common::empty_cpu(0); let mut idata_build = InstructionDataBuilder::new(); idata_build.set_core_indx(0).fix_core_indx(); inst(&mut cpu, idata_build.build()).unwrap(); } - #[test] -#[should_panic(expected = "You are calling a placeholder, the real call is the generic version") ] +#[should_panic(expected = "You are calling a placeholder, the real call is the generic version")] fn vvadd_placeholder() { place_holder(vvadd); } #[test] -#[should_panic(expected = "You are calling a placeholder, the real call is the generic version") ] +#[should_panic(expected = "You are calling a placeholder, the real call is the generic version")] fn vvsub_placeholder() { place_holder(vvsub); } #[test] -#[should_panic(expected = "You are calling a placeholder, the real call is the generic version") ] +#[should_panic(expected = "You are calling a placeholder, the real call is the generic version")] fn vvmul_placeholder() { place_holder(vvmul); } #[test] -#[should_panic(expected = "You are calling a placeholder, the real call is the generic version") ] +#[should_panic(expected = "You are calling a placeholder, the real call is the generic version")] fn vvdmul_placeholder() { place_holder(vvdmul); } #[test] -#[should_panic(expected = "You are calling a placeholder, the real call is the generic version") ] +#[should_panic(expected = "You are calling a placeholder, the real call is the generic version")] fn vvmax_placeholder() { place_holder(vvmax); } #[test] -#[should_panic(expected = "You are calling a placeholder, the real call is the generic version") ] +#[should_panic(expected = "You are calling a placeholder, the real call is the generic version")] fn vavg_placeholder() { place_holder(vavg); } #[test] -#[should_panic(expected = "You are calling a placeholder, the real call is the generic version") ] +#[should_panic(expected = "You are calling a placeholder, the real call is the generic version")] fn vrelu_placeholder() { place_holder(vrelu); } #[test] -#[should_panic(expected = "You are calling a placeholder, the real call is the generic version") ] +#[should_panic(expected = "You are calling a placeholder, the real call is the generic version")] fn vtanh_placeholder() { place_holder(vtanh); } #[test] -#[should_panic(expected = "You are calling a placeholder, the real call is the generic version") ] +#[should_panic(expected = "You are calling a placeholder, the real call is the generic version")] fn vsigm_placeholder() { place_holder(vsigm); } #[test] -#[should_panic(expected = "You are calling a placeholder, the real call is the generic version") ] +#[should_panic(expected = "You are calling a placeholder, the real call is the generic version")] fn mvmul_placeholder() { place_holder(mvmul); } #[test] -#[should_panic ] +#[should_panic] fn vvsll_why_inst() { place_holder(vvsll); } #[test] -#[should_panic ] +#[should_panic] fn vvsra_why_inst() { place_holder(vvsra); } diff --git a/backend-simulators/pim/pim-simulator/tests/simd.rs b/backend-simulators/pim/pim-simulator/tests/simd.rs index 8f7c3fd..46d444d 100644 --- a/backend-simulators/pim/pim-simulator/tests/simd.rs +++ b/backend-simulators/pim/pim-simulator/tests/simd.rs @@ -53,10 +53,7 @@ where ); inst_builder.make_inst( vvadd, - idata_build - .set_rdr1r2(3, 1, 2) - .set_imm_len(8) - .build(), + idata_build.set_rdr1r2(3, 1, 2).set_imm_len(8).build(), ); let core_instruction = vec![inst_builder.build().into()]; let mut executable = Executable::new(cpu, core_instruction); @@ -67,7 +64,8 @@ where executable .cpu_mut() .host() - .load::(16 * size_of::(), 8 * size_of::()).unwrap()[0], + .load::(16 * size_of::(), 8 * size_of::()) + .unwrap()[0], vec![ 10.0.into(), 12.0.into(), @@ -86,17 +84,22 @@ where executable .cpu_mut() .host() - .load::(0, 16 * size_of::()).unwrap()[0], + .load::(0, 16 * size_of::()) + .unwrap()[0], &buff, "Altered first part for {}", err ); //Check that later is 0 assert_eq!( - executable.cpu_mut().host().load::( - 16 * size_of::() + 8 * size_of::(), - 4 * size_of::() - ).unwrap()[0], + executable + .cpu_mut() + .host() + .load::( + 16 * size_of::() + 8 * size_of::(), + 4 * size_of::() + ) + .unwrap()[0], [0, 0, 0, 0], "Altered first part for {}", err @@ -157,10 +160,7 @@ where ); inst_builder.make_inst( vvsub, - idata_build - .set_rdr1r2(3, 1, 2) - .set_imm_len(8) - .build(), + idata_build.set_rdr1r2(3, 1, 2).set_imm_len(8).build(), ); let core_instruction = vec![inst_builder.build().into()]; let mut executable = Executable::new(cpu, core_instruction); @@ -171,7 +171,8 @@ where executable .cpu_mut() .host() - .load::(16 * size_of::(), 8 * size_of::()).unwrap()[0], + .load::(16 * size_of::(), 8 * size_of::()) + .unwrap()[0], vec![ (-8.0).into(), (-8.0).into(), @@ -190,17 +191,22 @@ where executable .cpu_mut() .host() - .load::(0, 16 * size_of::()).unwrap()[0], + .load::(0, 16 * size_of::()) + .unwrap()[0], &buff, "Altered first part for {}", err ); //Check that later is 0 assert_eq!( - executable.cpu_mut().host().load::( - 16 * size_of::() + 8 * size_of::(), - 4 * size_of::() - ).unwrap()[0], + executable + .cpu_mut() + .host() + .load::( + 16 * size_of::() + 8 * size_of::(), + 4 * size_of::() + ) + .unwrap()[0], [0, 0, 0, 0], "Altered first part for {}", err @@ -261,10 +267,7 @@ where ); inst_builder.make_inst( vvmul, - idata_build - .set_rdr1r2(3, 1, 2) - .set_imm_len(8) - .build(), + idata_build.set_rdr1r2(3, 1, 2).set_imm_len(8).build(), ); let core_instruction = vec![inst_builder.build().into()]; let mut executable = Executable::new(cpu, core_instruction); @@ -275,7 +278,8 @@ where executable .cpu_mut() .host() - .load::(16 * size_of::(), 8 * size_of::()).unwrap()[0], + .load::(16 * size_of::(), 8 * size_of::()) + .unwrap()[0], vec![ (9.0).into(), (20.0).into(), @@ -294,17 +298,22 @@ where executable .cpu_mut() .host() - .load::(0, 16 * size_of::()).unwrap()[0], + .load::(0, 16 * size_of::()) + .unwrap()[0], &buff, "Altered first part for {}", err ); //Check that later is 0 assert_eq!( - executable.cpu_mut().host().load::( - 16 * size_of::() + 8 * size_of::(), - 4 * size_of::() - ).unwrap()[0], + executable + .cpu_mut() + .host() + .load::( + 16 * size_of::() + 8 * size_of::(), + 4 * size_of::() + ) + .unwrap()[0], [0, 0, 0, 0], "Altered first part for {}", err @@ -365,10 +374,7 @@ where ); inst_builder.make_inst( vvdmul, - idata_build - .set_rdr1r2(3, 1, 2) - .set_imm_len(8) - .build(), + idata_build.set_rdr1r2(3, 1, 2).set_imm_len(8).build(), ); let core_instruction = vec![inst_builder.build().into()]; let mut executable = Executable::new(cpu, core_instruction); @@ -379,10 +385,9 @@ where executable .cpu_mut() .host() - .load::(16 * size_of::(), size_of::()).unwrap()[0], - vec![ - (492.0).into(), - ], + .load::(16 * size_of::(), size_of::()) + .unwrap()[0], + vec![(492.0).into(),], "Wrong result for {}", err ); @@ -391,17 +396,19 @@ where executable .cpu_mut() .host() - .load::(0, 16 * size_of::()).unwrap()[0], + .load::(0, 16 * size_of::()) + .unwrap()[0], &buff, "Altered first part for {}", err ); //Check that later is 0 assert_eq!( - executable.cpu_mut().host().load::( - 16 * size_of::() + size_of::(), - 4 * size_of::() - ).unwrap()[0], + executable + .cpu_mut() + .host() + .load::(16 * size_of::() + size_of::(), 4 * size_of::()) + .unwrap()[0], [0, 0, 0, 0], "Altered first part for {}", err @@ -462,10 +469,7 @@ where ); inst_builder.make_inst( vvmax, - idata_build - .set_rdr1r2(3, 1, 2) - .set_imm_len(8) - .build(), + idata_build.set_rdr1r2(3, 1, 2).set_imm_len(8).build(), ); let core_instruction = vec![inst_builder.build().into()]; let mut executable = Executable::new(cpu, core_instruction); @@ -476,16 +480,17 @@ where executable .cpu_mut() .host() - .load::(16 * size_of::(), 8 * size_of::()).unwrap()[0], + .load::(16 * size_of::(), 8 * size_of::()) + .unwrap()[0], vec![ - 9.0.into(), - 10.0.into(), - 11.0.into(), - 12.0.into(), - 13.0.into(), - 14.0.into(), - 15.0.into(), - 16.0.into(), + 9.0.into(), + 10.0.into(), + 11.0.into(), + 12.0.into(), + 13.0.into(), + 14.0.into(), + 15.0.into(), + 16.0.into(), ], "Wrong result for {}", err @@ -495,17 +500,22 @@ where executable .cpu_mut() .host() - .load::(0, 16 * size_of::()).unwrap()[0], + .load::(0, 16 * size_of::()) + .unwrap()[0], &buff, "Altered first part for {}", err ); //Check that later is 0 assert_eq!( - executable.cpu_mut().host().load::( - 16 * size_of::() + 8 * size_of::(), - 4 * size_of::() - ).unwrap()[0], + executable + .cpu_mut() + .host() + .load::( + 16 * size_of::() + 8 * size_of::(), + 4 * size_of::() + ) + .unwrap()[0], [0, 0, 0, 0], "Altered first part for {}", err @@ -577,10 +587,9 @@ where executable .cpu_mut() .host() - .load::(16 * size_of::(), size_of::()).unwrap()[0], - vec![ - 7.5.into(), - ], + .load::(16 * size_of::(), size_of::()) + .unwrap()[0], + vec![7.5.into(),], "Wrong result for {}", err ); @@ -589,17 +598,19 @@ where executable .cpu_mut() .host() - .load::(0, 16 * size_of::()).unwrap()[0], + .load::(0, 16 * size_of::()) + .unwrap()[0], &buff, "Altered first part for {}", err ); //Check that later is 0 assert_eq!( - executable.cpu_mut().host().load::( - 16 * size_of::() + size_of::(), - 4 * size_of::() - ).unwrap()[0], + executable + .cpu_mut() + .host() + .load::(16 * size_of::() + size_of::(), 4 * size_of::()) + .unwrap()[0], [0, 0, 0, 0], "Altered first part for {}", err @@ -656,10 +667,7 @@ where ); inst_builder.make_inst( vrelu, - idata_build - .set_rdr1r2(3, 1, 1) - .set_imm_len(8) - .build(), + idata_build.set_rdr1r2(3, 1, 1).set_imm_len(8).build(), ); let core_instruction = vec![inst_builder.build().into()]; let mut executable = Executable::new(cpu, core_instruction); @@ -670,16 +678,17 @@ where executable .cpu_mut() .host() - .load::(16 * size_of::(), 8*size_of::()).unwrap()[0], + .load::(16 * size_of::(), 8 * size_of::()) + .unwrap()[0], vec![ - 0.0.into(), - 2.0.into(), - 11.0.into(), - 0.0.into(), - 13.0.into(), - 0.0.into(), - 7.0.into(), - 0.0.into(), + 0.0.into(), + 2.0.into(), + 11.0.into(), + 0.0.into(), + 13.0.into(), + 0.0.into(), + 7.0.into(), + 0.0.into(), ], "Wrong result for {}", err @@ -689,17 +698,22 @@ where executable .cpu_mut() .host() - .load::(0, 16 * size_of::()).unwrap()[0], + .load::(0, 16 * size_of::()) + .unwrap()[0], &buff, "Altered first part for {}", err ); //Check that later is 0 assert_eq!( - executable.cpu_mut().host().load::( - 16 * size_of::() + 8*size_of::(), - 4 * size_of::() - ).unwrap()[0], + executable + .cpu_mut() + .host() + .load::( + 16 * size_of::() + 8 * size_of::(), + 4 * size_of::() + ) + .unwrap()[0], [0, 0, 0, 0], "Altered first part for {}", err @@ -756,32 +770,32 @@ where ); inst_builder.make_inst( vtanh, - idata_build - .set_rdr1r2(3, 1, 1) - .set_imm_len(8) - .build(), + idata_build.set_rdr1r2(3, 1, 1).set_imm_len(8).build(), ); let core_instruction = vec![inst_builder.build().into()]; let mut executable = Executable::new(cpu, core_instruction); executable.execute(); // Check result correct - + assert!( executable .cpu_mut() .host() - .load::(16 * size_of::(), 8*size_of::()).unwrap()[0].iter().zip( - vec![ - T::from(0.1).tanh(), - T::from(0.2).tanh(), - T::from(0.3).tanh(), - T::from(0.4).tanh(), - T::from(0.5).tanh(), - T::from(0.6).tanh(), - T::from(0.7).tanh(), - T::from(0.8).tanh(), - ]).all(|(&a,b) : (&T, T)| {a-b < 0.001.into()}), + .load::(16 * size_of::(), 8 * size_of::()) + .unwrap()[0] + .iter() + .zip(vec![ + T::from(0.1).tanh(), + T::from(0.2).tanh(), + T::from(0.3).tanh(), + T::from(0.4).tanh(), + T::from(0.5).tanh(), + T::from(0.6).tanh(), + T::from(0.7).tanh(), + T::from(0.8).tanh(), + ]) + .all(|(&a, b): (&T, T)| { a - b < 0.001.into() }), "Wrong result for {}", err ); @@ -790,17 +804,22 @@ where executable .cpu_mut() .host() - .load::(0, 16 * size_of::()).unwrap()[0], + .load::(0, 16 * size_of::()) + .unwrap()[0], &buff, "Altered first part for {}", err ); //Check that later is 0 assert_eq!( - executable.cpu_mut().host().load::( - 16 * size_of::() + 8*size_of::(), - 4 * size_of::() - ).unwrap()[0], + executable + .cpu_mut() + .host() + .load::( + 16 * size_of::() + 8 * size_of::(), + 4 * size_of::() + ) + .unwrap()[0], [0, 0, 0, 0], "Altered first part for {}", err @@ -815,7 +834,6 @@ fn vtanh_test() { vtanh_test_generic::("vtanh"); } - /// vsigm Test fn vsigm_test_generic(err: &str) where @@ -858,32 +876,32 @@ where ); inst_builder.make_inst( vsigm, - idata_build - .set_rdr1r2(3, 1, 1) - .set_imm_len(8) - .build(), + idata_build.set_rdr1r2(3, 1, 1).set_imm_len(8).build(), ); let core_instruction = vec![inst_builder.build().into()]; let mut executable = Executable::new(cpu, core_instruction); executable.execute(); // Check result correct - + assert!( executable .cpu_mut() .host() - .load::(16 * size_of::(), 8*size_of::()).unwrap()[0].iter().zip( - vec![ - T::from(0.1).sigm(), - T::from(0.2).sigm(), - T::from(0.3).sigm(), - T::from(0.4).sigm(), - T::from(0.5).sigm(), - T::from(0.6).sigm(), - T::from(0.7).sigm(), - T::from(0.8).sigm(), - ]).all(|(&a,b) : (&T, T)| {a-b < 0.001.into()}), + .load::(16 * size_of::(), 8 * size_of::()) + .unwrap()[0] + .iter() + .zip(vec![ + T::from(0.1).sigm(), + T::from(0.2).sigm(), + T::from(0.3).sigm(), + T::from(0.4).sigm(), + T::from(0.5).sigm(), + T::from(0.6).sigm(), + T::from(0.7).sigm(), + T::from(0.8).sigm(), + ]) + .all(|(&a, b): (&T, T)| { a - b < 0.001.into() }), "Wrong result for {}", err ); @@ -892,17 +910,22 @@ where executable .cpu_mut() .host() - .load::(0, 16 * size_of::()).unwrap()[0], + .load::(0, 16 * size_of::()) + .unwrap()[0], &buff, "Altered first part for {}", err ); //Check that later is 0 assert_eq!( - executable.cpu_mut().host().load::( - 16 * size_of::() + 8*size_of::(), - 4 * size_of::() - ).unwrap()[0], + executable + .cpu_mut() + .host() + .load::( + 16 * size_of::() + 8 * size_of::(), + 4 * size_of::() + ) + .unwrap()[0], [0, 0, 0, 0], "Altered first part for {}", err @@ -917,10 +940,8 @@ fn vsigm_test() { vsigm_test_generic::("vsigm"); } - - /// mvmul Test -fn mvmul_test_generic(err: &str, relu:i32) +fn mvmul_test_generic(err: &str, relu: i32) where F: From + std::fmt::Debug + PartialEq + MemoryStorable, M: From + std::fmt::Debug + PartialEq + MemoryStorable, @@ -948,12 +969,7 @@ where crossbar.execute_store(&matrix).unwrap(); let mut cpu = pimcore::cpu::CPU::new(0, vec![vec![&crossbar]]); let (memory, _) = cpu.host().get_memory_crossbar(); - let vector: [F; _] = [ - 1.0.into(), - 2.0.into(), - 3.0.into(), - 4.0.into(), - ]; + let vector: [F; _] = [1.0.into(), 2.0.into(), 3.0.into(), 4.0.into()]; memory.execute_store(0, &vector).unwrap(); let mut inst_builder = InstructionsBuilder::new(); @@ -974,7 +990,7 @@ where mvmul, idata_build .set_rdr1(3, 1) - .set_mbiw_immrelu_immgroup(8*size_of::() as i32, relu, 0) + .set_mbiw_immrelu_immgroup(8 * size_of::() as i32, relu, 0) .build(), ); let core_instruction = vec![inst_builder.build().into()]; @@ -982,54 +998,50 @@ where executable.execute(); // Check result correct - if relu == 0 { - assert_eq!( - executable - .cpu_mut() - .host() - .load::(4 * size_of::(), 4*size_of::()).unwrap()[0], - vec![ - 90.0.into(), - (-24.0).into(), - 110.0.into(), - 120.0.into(), - ], - "Wrong result for {}", - err - ); - } - else { - assert_eq!( - executable - .cpu_mut() - .host() - .load::(4 * size_of::(), 4*size_of::()).unwrap()[0], - vec![ - 90.0.into(), - 0.0.into(), - 110.0.into(), - 120.0.into(), - ], - "Wrong result for {}", - err - ); - } + if relu == 0 { + assert_eq!( + executable + .cpu_mut() + .host() + .load::(4 * size_of::(), 4 * size_of::()) + .unwrap()[0], + vec![90.0.into(), (-24.0).into(), 110.0.into(), 120.0.into(),], + "Wrong result for {}", + err + ); + } else { + assert_eq!( + executable + .cpu_mut() + .host() + .load::(4 * size_of::(), 4 * size_of::()) + .unwrap()[0], + vec![90.0.into(), 0.0.into(), 110.0.into(), 120.0.into(),], + "Wrong result for {}", + err + ); + } // Check first part equal assert_eq!( executable .cpu_mut() .host() - .load::(0, 4 * size_of::()).unwrap()[0], + .load::(0, 4 * size_of::()) + .unwrap()[0], &vector, "Altered first part for {}", err ); //Check that later is 0 assert_eq!( - executable.cpu_mut().host().load::( - 4 * size_of::() + 4*size_of::(), - 4 * size_of::() - ).unwrap()[0], + executable + .cpu_mut() + .host() + .load::( + 4 * size_of::() + 4 * size_of::(), + 4 * size_of::() + ) + .unwrap()[0], [0, 0, 0, 0], "Altered first part for {}", err @@ -1038,22 +1050,21 @@ where #[test] fn mvmul_test() { - mvmul_test_generic::("mvmul",0); - mvmul_test_generic::("mvmul",0); - mvmul_test_generic::("mvmul",0); - mvmul_test_generic::("mvmul",0); - mvmul_test_generic::("mvmul",0); - mvmul_test_generic::("mvmul",0); - mvmul_test_generic::("mvmul",0); - mvmul_test_generic::("mvmul",0); - - mvmul_test_generic::("mvmul",1); - mvmul_test_generic::("mvmul",1); - mvmul_test_generic::("mvmul",1); - mvmul_test_generic::("mvmul",1); - mvmul_test_generic::("mvmul",1); - mvmul_test_generic::("mvmul",1); - mvmul_test_generic::("mvmul",1); - mvmul_test_generic::("mvmul",1); + mvmul_test_generic::("mvmul", 0); + mvmul_test_generic::("mvmul", 0); + mvmul_test_generic::("mvmul", 0); + mvmul_test_generic::("mvmul", 0); + mvmul_test_generic::("mvmul", 0); + mvmul_test_generic::("mvmul", 0); + mvmul_test_generic::("mvmul", 0); + mvmul_test_generic::("mvmul", 0); + mvmul_test_generic::("mvmul", 1); + mvmul_test_generic::("mvmul", 1); + mvmul_test_generic::("mvmul", 1); + mvmul_test_generic::("mvmul", 1); + mvmul_test_generic::("mvmul", 1); + mvmul_test_generic::("mvmul", 1); + mvmul_test_generic::("mvmul", 1); + mvmul_test_generic::("mvmul", 1); } diff --git a/backend-simulators/pim/pim-simulator/tests/sync.rs b/backend-simulators/pim/pim-simulator/tests/sync.rs index 44450e5..66094c6 100644 --- a/backend-simulators/pim/pim-simulator/tests/sync.rs +++ b/backend-simulators/pim/pim-simulator/tests/sync.rs @@ -1,7 +1,7 @@ mod common; use pimcore::{ - Executable, CoreInstructionsBuilder, + CoreInstructionsBuilder, Executable, instruction_set::{InstructionsBuilder, instruction_data::InstructionDataBuilder, isa::*}, }; @@ -158,7 +158,12 @@ fn simple_send_recv_test() { let mut inst_builder = InstructionsBuilder::new(); let mut idata_build = InstructionDataBuilder::new(); idata_build.set_core_indx(1).fix_core_indx(); - inst_builder.make_inst(sldi, idata_build.set_rdimm(1, 3*size_of::() as i32).build()); + inst_builder.make_inst( + sldi, + idata_build + .set_rdimm(1, 3 * size_of::() as i32) + .build(), + ); inst_builder.make_inst( send, idata_build @@ -188,15 +193,11 @@ fn simple_send_recv_test() { assert_eq!( res.unwrap()[0], - [ - 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0 - ], + [4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0], "send_recv failed to store" ); } - - // 1 -> 3 // 2 -> 3 // 3 <- 2 @@ -210,53 +211,54 @@ fn simple_send_recv_test() { fn multiple_send_recv_test() { let mut cpu = common::empty_cpu(4); let mut core_instruction_builder = CoreInstructionsBuilder::new(4); - let buff: [f32; _] = [ - 1.0, 1.0, 1.0, 1.0, 1.0 - ]; + let buff: [f32; _] = [1.0, 1.0, 1.0, 1.0, 1.0]; cpu.core(1).execute_store(0, &buff).unwrap(); - let buff: [f32; _] = [ - 2.0, 2.0, 2.0, 2.0, 2.0 - ]; + let buff: [f32; _] = [2.0, 2.0, 2.0, 2.0, 2.0]; cpu.core(2).execute_store(0, &buff).unwrap(); - let buff: [f32; _] = [ - 3.0, 3.0, 3.0, 3.0, 3.0 - ]; + let buff: [f32; _] = [3.0, 3.0, 3.0, 3.0, 3.0]; cpu.core(3).execute_store(0, &buff).unwrap(); - let buff: [f32; _] = [ - 4.0, 4.0, 4.0, 4.0, 4.0 - ]; + let buff: [f32; _] = [4.0, 4.0, 4.0, 4.0, 4.0]; cpu.core(4).execute_store(0, &buff).unwrap(); let send_inst = |inst_builder: &mut InstructionsBuilder, from: i32, to: i32| { - let mut idata_build = InstructionDataBuilder::new(); - idata_build.set_core_indx(from).fix_core_indx(); - inst_builder.make_inst(sldi, idata_build.set_rdimm(1, from*size_of::() as i32).build()); - inst_builder.make_inst( - send, - idata_build - .set_r1(1) - .set_imm_core(to) - .set_imm_len(size_of::() as i32) - .build(), - ); + let mut idata_build = InstructionDataBuilder::new(); + idata_build.set_core_indx(from).fix_core_indx(); + inst_builder.make_inst( + sldi, + idata_build + .set_rdimm(1, from * size_of::() as i32) + .build(), + ); + inst_builder.make_inst( + send, + idata_build + .set_r1(1) + .set_imm_core(to) + .set_imm_len(size_of::() as i32) + .build(), + ); }; let recv_inst = |inst_builder: &mut InstructionsBuilder, to: i32, from: i32| { - let mut idata_build = InstructionDataBuilder::new(); - idata_build.set_core_indx(to).fix_core_indx(); - inst_builder.make_inst(sldi, idata_build.set_rdimm(1, from*size_of::() as i32).build()); - inst_builder.make_inst( - recv, - idata_build - .set_rd(1) - .set_imm_core(from) - .set_imm_len(size_of::() as i32) - .build(), - ); + let mut idata_build = InstructionDataBuilder::new(); + idata_build.set_core_indx(to).fix_core_indx(); + inst_builder.make_inst( + sldi, + idata_build + .set_rdimm(1, from * size_of::() as i32) + .build(), + ); + inst_builder.make_inst( + recv, + idata_build + .set_rd(1) + .set_imm_core(from) + .set_imm_len(size_of::() as i32) + .build(), + ); }; let mut inst_builder = InstructionsBuilder::new(); - // 1 -> 3 send_inst(&mut inst_builder, 1, 3); core_instruction_builder.set_core(1, inst_builder.build()); @@ -289,7 +291,7 @@ fn multiple_send_recv_test() { assert_eq!( res.unwrap()[0], - [ 1.0, 2.0, 3.0, 4.0 ], + [1.0, 2.0, 3.0, 4.0], "send_recv failed to store" ); }