295 lines
9.4 KiB
Rust
295 lines
9.4 KiB
Rust
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"
|
|
);
|
|
}
|