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::() 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::(0, 10 * size_of::()); 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::() 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::(0, 10 * size_of::()); 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::() 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::(0, 10 * size_of::()); 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::() as i32) .build(), ); inst_builder.make_inst( lmv, idata_build .set_rdr1(1, 2) .set_imm_len(8 * size_of::() 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::(0, 16 * size_of::()); 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::() as i32).build()); inst_builder.make_inst( send, idata_build .set_r1(1) .set_imm_core(2) .set_imm_len(8 * size_of::() 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::() 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::(0, 8 * size_of::()); 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::() 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 = |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::() 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 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::(4, 4 * size_of::()); assert_eq!( res.unwrap()[0], [ 1.0, 2.0, 3.0, 4.0 ], "send_recv failed to store" ); }