add pimsim-nn simulator

This commit is contained in:
NiccoloN
2026-02-23 16:17:52 +01:00
parent 9c716d2582
commit 9ba08a6780
66 changed files with 8 additions and 4 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,73 @@
use std::path::Path;
use pimcore::{Executable, cpu::CPU, instruction_set::{InstructionsBuilder, instruction_data::InstructionDataBuilder, isa::*}};
fn simple_read(path: &Path) -> Vec<f32> {
if !path.exists() {
panic!("{:?} not exists", path)
}
std::fs::read_to_string(path)
.unwrap()
.split(',')
.map(|s| s.trim().parse::<f32>().unwrap())
.collect()
}
/// mvmul Test
fn mvmul_f32(err: &str)
where
{
let mut cpu = CPU::new(0);
cpu.reserve_crossbar(1, 1024 * size_of::<f32>(), 1024);
let (memory, crossbars) = cpu.host().get_memory_crossbar();
let matrix = simple_read(Path::new("B.txt")) ;
crossbars.get_mut(0).unwrap().execute_store( &matrix).unwrap();
let vector = simple_read(Path::new("A.txt"));
memory.execute_store(0, &vector).unwrap();
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(sldi, idata_build.set_rdimm(1, 0).build());
inst_builder.make_inst(
sldi,
idata_build.set_rdimm(3, 1024 * size_of::<f32>() as i32).build(),
);
inst_builder.make_inst(
setbw,
idata_build
.set_ibiw_obiw(8 * size_of::<f32>() as i32, 8 * size_of::<f32>() as i32)
.build(),
);
inst_builder.make_inst(
mvmul,
idata_build
.set_rdr1(3, 1)
.set_mbiw_immrelu_immgroup(8*size_of::<f32>() as i32, 0, 0)
.build(),
);
let core_instruction = vec![inst_builder.build().into()];
let mut executable = Executable::new(cpu, core_instruction);
executable.execute();
assert!(
executable
.cpu_mut()
.host()
.load::<f32>(1024 * size_of::<f32>(), 1024*size_of::<f32>()).unwrap()[0].iter().zip(
simple_read(Path::new("X.txt")) ).all(|(&a,b) : (&f32, f32)| {a-b < 0.001}),
"Wrong result for {}",
err
);
}
#[test]
fn mvmul_big_test() {
mvmul_f32("mvmul_f32");
}

View File

@@ -0,0 +1 @@
{"adc_count":16,"array_group_map":{"core0":[0,1,2],"core1":[],"core2":[0,1,2],"core3":[],"core4":[0,1,2],"core5":[]},"cell_precision":2,"core_cnt":6,"inputs_addresses":[0],"outputs_addresses":[532],"xbar_array_count":8,"xbar_size":[64,64]}

View File

@@ -0,0 +1 @@
[{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":256},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"group":0,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":260,"op":"sldi","rd":0},{"imm":256,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":256},{"imm":260,"op":"sldi","rd":0},{"imm":260,"op":"sldi","rd":1},{"group":1,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"imm":260,"op":"sldi","rd":2},{"len":64,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":780,"op":"sldi","rd":0},{"imm":512,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":16},{"imm":520,"op":"sldi","rd":0},{"imm":780,"op":"sldi","rd":1},{"group":2,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"imm":520,"op":"sldi","rd":2},{"len":64,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":0,"op":"sldi","rd":0},{"core":1,"offset":{"offset_select":0,"offset_value":0},"op":"send","rd":0,"size":64}]

View File

@@ -0,0 +1 @@
[{"imm":0,"op":"sldi","rd":0},{"core":0,"offset":{"offset_select":0,"offset_value":0},"op":"recv","rd":0,"size":64},{"imm":532,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"st","rd":0,"rs1":1,"size":64}]

View File

@@ -0,0 +1 @@
[{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":256},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"group":0,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":260,"op":"sldi","rd":0},{"imm":256,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":256},{"imm":260,"op":"sldi","rd":0},{"imm":260,"op":"sldi","rd":1},{"group":1,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"imm":260,"op":"sldi","rd":2},{"len":64,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":780,"op":"sldi","rd":0},{"imm":512,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":16},{"imm":520,"op":"sldi","rd":0},{"imm":780,"op":"sldi","rd":1},{"group":2,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"imm":520,"op":"sldi","rd":2},{"len":64,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":0,"op":"sldi","rd":0},{"core":3,"offset":{"offset_select":0,"offset_value":0},"op":"send","rd":0,"size":64}]

View File

@@ -0,0 +1 @@
[{"imm":0,"op":"sldi","rd":0},{"core":2,"offset":{"offset_select":0,"offset_value":0},"op":"recv","rd":0,"size":64},{"imm":596,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"st","rd":0,"rs1":1,"size":64}]

View File

@@ -0,0 +1 @@
[{"imm":260,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":256},{"imm":0,"op":"sldi","rd":0},{"imm":260,"op":"sldi","rd":1},{"group":0,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":780,"op":"sldi","rd":0},{"imm":256,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":256},{"imm":520,"op":"sldi","rd":0},{"imm":780,"op":"sldi","rd":1},{"group":1,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"imm":520,"op":"sldi","rd":2},{"len":4,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":1040,"op":"sldi","rd":0},{"imm":512,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":16},{"imm":1040,"op":"sldi","rd":0},{"imm":1040,"op":"sldi","rd":1},{"group":2,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"imm":1040,"op":"sldi","rd":2},{"len":4,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":0,"op":"sldi","rd":0},{"core":5,"offset":{"offset_select":0,"offset_value":0},"op":"send","rd":0,"size":4}]

View File

@@ -0,0 +1 @@
[{"imm":0,"op":"sldi","rd":0},{"core":4,"offset":{"offset_select":0,"offset_value":0},"op":"recv","rd":0,"size":4},{"imm":660,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"st","rd":0,"rs1":1,"size":4}]

View File

@@ -0,0 +1 @@
{"adc_count":16,"array_group_map":{"core0":[0,1,2],"core1":[],"core2":[0,1,2],"core3":[],"core4":[0,1,2],"core5":[]},"cell_precision":2,"core_cnt":6,"inputs_addresses":[0],"outputs_addresses":[528],"xbar_array_count":8,"xbar_size":[64,64]}

View File

@@ -0,0 +1 @@
[{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":256},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"group":0,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":256,"op":"sldi","rd":0},{"imm":256,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":256},{"imm":256,"op":"sldi","rd":0},{"imm":256,"op":"sldi","rd":1},{"group":1,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"imm":256,"op":"sldi","rd":2},{"len":256,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":768,"op":"sldi","rd":0},{"imm":512,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":16},{"imm":512,"op":"sldi","rd":0},{"imm":768,"op":"sldi","rd":1},{"group":2,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"imm":512,"op":"sldi","rd":2},{"len":256,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":0,"op":"sldi","rd":0},{"core":1,"offset":{"offset_select":0,"offset_value":0},"op":"send","rd":0,"size":256}]

View File

@@ -0,0 +1 @@
[{"imm":0,"op":"sldi","rd":0},{"imm":1056,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":256},{"imm":256,"op":"sldi","rd":0},{"core":0,"offset":{"offset_select":0,"offset_value":0},"op":"recv","rd":0,"size":256},{"imm":256,"op":"sldi","rd":0},{"imm":256,"op":"sldi","rd":1},{"imm":0,"op":"sldi","rd":2},{"len":256,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":528,"op":"sldi","rd":0},{"imm":256,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"st","rd":0,"rs1":1,"size":256}]

View File

@@ -0,0 +1 @@
[{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":256},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"group":0,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":256,"op":"sldi","rd":0},{"imm":256,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":256},{"imm":256,"op":"sldi","rd":0},{"imm":256,"op":"sldi","rd":1},{"group":1,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"imm":256,"op":"sldi","rd":2},{"len":256,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":768,"op":"sldi","rd":0},{"imm":512,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":16},{"imm":512,"op":"sldi","rd":0},{"imm":768,"op":"sldi","rd":1},{"group":2,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"imm":512,"op":"sldi","rd":2},{"len":256,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":0,"op":"sldi","rd":0},{"core":3,"offset":{"offset_select":0,"offset_value":0},"op":"send","rd":0,"size":256}]

View File

@@ -0,0 +1 @@
[{"imm":0,"op":"sldi","rd":0},{"imm":1312,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":256},{"imm":256,"op":"sldi","rd":0},{"core":2,"offset":{"offset_select":0,"offset_value":0},"op":"recv","rd":0,"size":256},{"imm":256,"op":"sldi","rd":0},{"imm":256,"op":"sldi","rd":1},{"imm":0,"op":"sldi","rd":2},{"len":256,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":784,"op":"sldi","rd":0},{"imm":256,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"st","rd":0,"rs1":1,"size":256}]

View File

@@ -0,0 +1 @@
[{"imm":256,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":256},{"imm":0,"op":"sldi","rd":0},{"imm":256,"op":"sldi","rd":1},{"group":0,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":768,"op":"sldi","rd":0},{"imm":256,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":256},{"imm":512,"op":"sldi","rd":0},{"imm":768,"op":"sldi","rd":1},{"group":1,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"imm":512,"op":"sldi","rd":2},{"len":16,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":1024,"op":"sldi","rd":0},{"imm":512,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":16},{"imm":1024,"op":"sldi","rd":0},{"imm":1024,"op":"sldi","rd":1},{"group":2,"mbiw":8,"op":"mvmul","rd":0,"relu":0,"rs1":1},{"imm":0,"op":"sldi","rd":0},{"imm":0,"op":"sldi","rd":1},{"imm":1024,"op":"sldi","rd":2},{"len":16,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":0,"op":"sldi","rd":0},{"core":5,"offset":{"offset_select":0,"offset_value":0},"op":"send","rd":0,"size":16}]

View File

@@ -0,0 +1 @@
[{"imm":0,"op":"sldi","rd":0},{"imm":1568,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"ld","rd":0,"rs1":1,"size":16},{"imm":16,"op":"sldi","rd":0},{"core":4,"offset":{"offset_select":0,"offset_value":0},"op":"recv","rd":0,"size":16},{"imm":16,"op":"sldi","rd":0},{"imm":16,"op":"sldi","rd":1},{"imm":0,"op":"sldi","rd":2},{"len":16,"offset":{"offset_select":0,"offset_value":0},"op":"vvadd","rd":0,"rs1":1,"rs2":2},{"imm":1040,"op":"sldi","rd":0},{"imm":16,"op":"sldi","rd":1},{"offset":{"offset_select":0,"offset_value":0},"op":"st","rd":0,"rs1":1,"size":16}]

View File

@@ -0,0 +1,51 @@
use std::{fs, io::BufReader, path::Path};
use anyhow::{Context, Result};
use pimcore::json_to_instruction::json_to_executor;
use serde_json::Value;
fn collect_json_from_subfolders<P: AsRef<Path>>(root: P) -> Result<Vec<(Value, Vec<Value>)>> {
let mut result = Vec::new();
for entry in fs::read_dir(root)? {
let entry = entry.context("Root not found")?;
let path = entry.path();
if path.is_dir() {
let mut cores = Vec::new();
let mut config: Option<Value> = None;
for sub_entry in fs::read_dir(&path)
.with_context(|| format!("File {} not readable", path.display()))?
{
let sub_entry =
sub_entry.with_context(|| format!("File {} not readable", path.display()))?;
let sub_path = sub_entry.path();
if sub_path.is_file()
&& sub_path.extension().and_then(|s| s.to_str()) == Some("json")
{
let file = fs::File::open(&sub_path)
.with_context(|| format!("Subpath {} not opened", sub_path.display()))?;
let reader = BufReader::new(file);
let val: Value = serde_json::from_reader(reader).with_context(|| format!(
"Serde reader fail for subpath {}",
sub_path.display()
))?;
if sub_path.file_name().unwrap() == "config.json" {
config = Some(val);
} else {
cores.push(val);
}
}
}
result.push((config.unwrap(), cores));
}
}
Ok(result)
}
#[test]
fn json_folder_tester() {
let examples = collect_json_from_subfolders("data").unwrap();
for example in examples {
let (config, cores) = example;
json_to_executor::json_to_executor(config, cores.iter()).execute();
}
}

View File

@@ -0,0 +1,110 @@
use pimcore::{Executable, cpu::CPU, instruction_set::{InstructionType, InstructionsBuilder, instruction_data::InstructionDataBuilder, isa::*}};
#[test]
#[should_panic(expected = "Function not found for the requested size") ]
fn wrong_size_place_holder() {
let cpu = CPU::new(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(
vvadd,
idata_build
.set_rdr1r2(3, 1, 2)
.set_imm_len(8 * size_of::<f32>() as i32)
.build(),
);
let core_instruction = vec![inst_builder.build().into()];
let mut executable = Executable::new(cpu, core_instruction);
executable.execute();
}
fn place_holder(inst : InstructionType) {
let mut cpu = CPU::new(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") ]
fn vvadd_placeholder() {
place_holder(vvadd);
}
#[test]
#[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") ]
fn vvmul_placeholder() {
place_holder(vvmul);
}
#[test]
#[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") ]
fn vvmax_placeholder() {
place_holder(vvmax);
}
#[test]
#[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") ]
fn vrelu_placeholder() {
place_holder(vrelu);
}
#[test]
#[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") ]
fn vsigm_placeholder() {
place_holder(vsigm);
}
#[test]
#[should_panic(expected = "You are calling a placeholder, the real call is the generic version") ]
fn mvmul_placeholder() {
place_holder(mvmul);
}
#[test]
#[should_panic ]
fn vvsll_why_inst() {
place_holder(vvsll);
}
#[test]
#[should_panic ]
fn vvsra_why_inst() {
place_holder(vvsra);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,294 @@
use pimcore::{
Executable, CoreInstructionsBuilder,
cpu::CPU,
instruction_set::{InstructionsBuilder, instruction_data::InstructionDataBuilder, isa::*},
};
#[test]
fn ld_test() {
let mut cpu = CPU::new(1);
let mut core_instruction_builder = CoreInstructionsBuilder::new(1);
let buff: [f32; _] = [
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
];
cpu.host().execute_store(0, &buff).unwrap();
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, 0).build());
inst_builder.make_inst(sldi, idata_build.set_rdimm(2, 0).build());
inst_builder.make_inst(
ld,
idata_build
.set_rdr1(1, 2)
.set_imm_len(10 * size_of::<f32>() as i32)
.build(),
);
core_instruction_builder.set_core(1, inst_builder.build());
let mut executable = Executable::new(cpu, core_instruction_builder.build());
executable.execute();
let res = executable
.cpu_mut()
.core(1)
.load::<f32>(0, 10 * size_of::<f32>());
assert_eq!(
res.unwrap()[0],
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0],
"LD failed to load"
);
}
#[test]
fn st_test() {
let mut cpu = CPU::new(1);
let mut core_instruction_builder = CoreInstructionsBuilder::new(1);
let buff: [f32; _] = [
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
];
cpu.core(1).execute_store(0, &buff).unwrap();
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, 0).build());
inst_builder.make_inst(sldi, idata_build.set_rdimm(2, 0).build());
inst_builder.make_inst(
st,
idata_build
.set_rdr1(1, 2)
.set_imm_len(10 * size_of::<f32>() as i32)
.build(),
);
core_instruction_builder.set_core(1, inst_builder.build());
let mut executable = Executable::new(cpu, core_instruction_builder.build());
executable.execute();
let res = executable
.cpu_mut()
.host()
.load::<f32>(0, 10 * size_of::<f32>());
assert_eq!(
res.unwrap()[0],
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0],
"ST failed to store"
);
}
#[test]
fn lldi_test() {
let cpu = CPU::new(1);
let mut core_instruction_builder = CoreInstructionsBuilder::new(1);
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, 0).build());
inst_builder.make_inst(
lldi,
idata_build
.set_rdimm(1, 0xff)
.set_imm_len(10 * size_of::<i32>() as i32)
.build(),
);
core_instruction_builder.set_core(1, inst_builder.build());
let mut executable = Executable::new(cpu, core_instruction_builder.build());
executable.execute();
let res = executable
.cpu_mut()
.core(1)
.load::<i32>(0, 10 * size_of::<i32>());
assert_eq!(
res.unwrap()[0],
[-1, -1, -1, -1, -1, -1, -1, -1, -1, -1],
"Lldi failed to memset"
);
}
#[test]
fn lmv_test() {
let mut cpu = CPU::new(1);
let mut core_instruction_builder = CoreInstructionsBuilder::new(1);
let buff: [f32; _] = [
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
];
cpu.core(1).execute_store(0, &buff).unwrap();
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(2, 0).build());
inst_builder.make_inst(
sldi,
idata_build
.set_rdimm(1, 8 * size_of::<f32>() as i32)
.build(),
);
inst_builder.make_inst(
lmv,
idata_build
.set_rdr1(1, 2)
.set_imm_len(8 * size_of::<f32>() as i32)
.build(),
);
core_instruction_builder.set_core(1, inst_builder.build());
let mut executable = Executable::new(cpu, core_instruction_builder.build());
executable.execute();
let res = executable
.cpu_mut()
.core(1)
.load::<f32>(0, 16 * size_of::<f32>());
assert_eq!(
res.unwrap()[0],
[
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0,
],
"lmv failed to store"
);
}
#[test]
fn simple_send_recv_test() {
let mut cpu = CPU::new(2);
let mut core_instruction_builder = CoreInstructionsBuilder::new(2);
let buff: [f32; _] = [
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0,
];
cpu.core(1).execute_store(0, &buff).unwrap();
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::<f32>() as i32).build());
inst_builder.make_inst(
send,
idata_build
.set_r1(1)
.set_imm_core(2)
.set_imm_len(8 * size_of::<f32>() as i32)
.build(),
);
core_instruction_builder.set_core(1, inst_builder.build());
idata_build.set_core_indx(2).fix_core_indx();
inst_builder.make_inst(sldi, idata_build.set_rdimm(1, 0).build());
inst_builder.make_inst(
recv,
idata_build
.set_rd(1)
.set_imm_core(1)
.set_imm_len(8 * size_of::<f32>() as i32)
.build(),
);
core_instruction_builder.set_core(2, inst_builder.build());
let mut executable = Executable::new(cpu, core_instruction_builder.build());
executable.execute();
let res = executable
.cpu_mut()
.core(2)
.load::<f32>(0, 8 * size_of::<f32>());
assert_eq!(
res.unwrap()[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
// 4 -> 2
// 3 <- 4
// 2 <- 4
// 4 -> 3
// 3 <- 1
#[test]
fn multiple_send_recv_test() {
let mut cpu = CPU::new(4);
let mut core_instruction_builder = CoreInstructionsBuilder::new(4);
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
];
cpu.core(2).execute_store(0, &buff).unwrap();
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
];
cpu.core(4).execute_store(0, &buff).unwrap();
let send_inst = |cpu :&mut CPU, core_instruction_builder: &mut CoreInstructionsBuilder, 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::<f32>() as i32).build());
inst_builder.make_inst(
send,
idata_build
.set_r1(1)
.set_imm_core(to)
.set_imm_len(size_of::<f32>() as i32)
.build(),
);
};
let recv_inst = |cpu :&mut CPU, core_instruction_builder: &mut CoreInstructionsBuilder, mut 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::<f32>() as i32).build());
inst_builder.make_inst(
recv,
idata_build
.set_rd(1)
.set_imm_core(from)
.set_imm_len(size_of::<f32>() as i32)
.build(),
);
};
let mut inst_builder = InstructionsBuilder::new();
// 1 -> 3
send_inst(&mut cpu,&mut core_instruction_builder,&mut inst_builder,1, 3);
core_instruction_builder.set_core(1, inst_builder.build());
// 2 -> 3
// 2 <- 4
send_inst(&mut cpu,&mut core_instruction_builder,&mut inst_builder,2, 3);
recv_inst(&mut cpu,&mut core_instruction_builder,&mut inst_builder,2, 4);
core_instruction_builder.set_core(2, inst_builder.build());
// 3 <- 2
// 3 <- 4
// 3 <- 1
recv_inst(&mut cpu,&mut core_instruction_builder,&mut inst_builder,3, 2);
recv_inst(&mut cpu,&mut core_instruction_builder,&mut inst_builder,3, 4);
recv_inst(&mut cpu,&mut core_instruction_builder,&mut inst_builder,3, 1);
core_instruction_builder.set_core(3, inst_builder.build());
// 4 -> 2
// 4 -> 3
send_inst(&mut cpu,&mut core_instruction_builder,&mut inst_builder,4, 2);
send_inst(&mut cpu,&mut core_instruction_builder,&mut inst_builder,4, 3);
core_instruction_builder.set_core(4, inst_builder.build());
let mut executable = Executable::new(cpu, core_instruction_builder.build());
executable.execute();
let res = executable
.cpu_mut()
.core(3)
.load::<f32>(4, 4 * size_of::<f32>());
assert_eq!(
res.unwrap()[0],
[ 1.0, 2.0, 3.0, 4.0 ],
"send_recv failed to store"
);
}