1059 lines
29 KiB
Rust
1059 lines
29 KiB
Rust
use pimcore::{
|
|
Executable,
|
|
cpu::CPU,
|
|
instruction_set::{InstructionsBuilder, instruction_data::InstructionDataBuilder, isa::*},
|
|
memory_manager::{MemoryStorable, type_traits::UpcastDestTraits},
|
|
};
|
|
|
|
/// VVADD Test
|
|
fn vvadd_test_generic<F, T>(err: &str)
|
|
where
|
|
F: From<f32> + std::fmt::Debug + PartialEq<F> + MemoryStorable,
|
|
T: From<f32> + std::fmt::Debug + PartialEq<T> + MemoryStorable,
|
|
{
|
|
let mut cpu = CPU::new(0);
|
|
let buff: [F; _] = [
|
|
1.0.into(),
|
|
2.0.into(),
|
|
3.0.into(),
|
|
4.0.into(),
|
|
5.0.into(),
|
|
6.0.into(),
|
|
7.0.into(),
|
|
8.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(),
|
|
];
|
|
cpu.host().execute_store(0, &buff).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(2, 8 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
sldi,
|
|
idata_build.set_rdimm(3, 16 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
setbw,
|
|
idata_build
|
|
.set_ibiw_obiw(8 * size_of::<F>() as i32, 8 * size_of::<T>() as i32)
|
|
.build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
vvadd,
|
|
idata_build
|
|
.set_rdr1r2(3, 1, 2)
|
|
.set_imm_len(8 * size_of::<F>() as i32)
|
|
.build(),
|
|
);
|
|
let core_instruction = vec![inst_builder.build().into()];
|
|
let mut executable = Executable::new(cpu, core_instruction);
|
|
executable.execute();
|
|
|
|
// Check result correct
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<T>(16 * size_of::<F>(), 8 * size_of::<T>()).unwrap()[0],
|
|
vec![
|
|
10.0.into(),
|
|
12.0.into(),
|
|
14.0.into(),
|
|
16.0.into(),
|
|
18.0.into(),
|
|
20.0.into(),
|
|
22.0.into(),
|
|
24.0.into()
|
|
],
|
|
"Wrong result for {}",
|
|
err
|
|
);
|
|
// Check first part equal
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<F>(0, 16 * size_of::<F>()).unwrap()[0],
|
|
&buff,
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
//Check that later is 0
|
|
assert_eq!(
|
|
executable.cpu_mut().host().load::<i32>(
|
|
16 * size_of::<F>() + 8 * size_of::<T>(),
|
|
4 * size_of::<i32>()
|
|
).unwrap()[0],
|
|
[0, 0, 0, 0],
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn vvadd_test() {
|
|
vvadd_test_generic::<f32, f32>("vvadd<f32,f32>");
|
|
vvadd_test_generic::<f64, f32>("vvadd<f64,f32>");
|
|
vvadd_test_generic::<f32, f64>("vvadd<f32,f64>");
|
|
vvadd_test_generic::<f64, f64>("vvadd<f64,f64>");
|
|
}
|
|
|
|
/// VVSUM Test
|
|
fn vvsub_test_generic<F, T>(err: &str)
|
|
where
|
|
F: From<f32> + std::fmt::Debug + PartialEq<F> + MemoryStorable,
|
|
T: From<f32> + std::fmt::Debug + PartialEq<T> + MemoryStorable,
|
|
{
|
|
let mut cpu = CPU::new(0);
|
|
let buff: [F; _] = [
|
|
1.0.into(),
|
|
2.0.into(),
|
|
3.0.into(),
|
|
4.0.into(),
|
|
5.0.into(),
|
|
6.0.into(),
|
|
7.0.into(),
|
|
8.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(),
|
|
];
|
|
cpu.host().execute_store(0, &buff).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(2, 8 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
sldi,
|
|
idata_build.set_rdimm(3, 16 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
setbw,
|
|
idata_build
|
|
.set_ibiw_obiw(8 * size_of::<F>() as i32, 8 * size_of::<T>() as i32)
|
|
.build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
vvsub,
|
|
idata_build
|
|
.set_rdr1r2(3, 1, 2)
|
|
.set_imm_len(8 * size_of::<F>() as i32)
|
|
.build(),
|
|
);
|
|
let core_instruction = vec![inst_builder.build().into()];
|
|
let mut executable = Executable::new(cpu, core_instruction);
|
|
executable.execute();
|
|
|
|
// Check result correct
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<T>(16 * size_of::<F>(), 8 * size_of::<T>()).unwrap()[0],
|
|
vec![
|
|
(-8.0).into(),
|
|
(-8.0).into(),
|
|
(-8.0).into(),
|
|
(-8.0).into(),
|
|
(-8.0).into(),
|
|
(-8.0).into(),
|
|
(-8.0).into(),
|
|
(-8.0).into()
|
|
],
|
|
"Wrong result for {}",
|
|
err
|
|
);
|
|
// Check first part equal
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<F>(0, 16 * size_of::<F>()).unwrap()[0],
|
|
&buff,
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
//Check that later is 0
|
|
assert_eq!(
|
|
executable.cpu_mut().host().load::<i32>(
|
|
16 * size_of::<F>() + 8 * size_of::<T>(),
|
|
4 * size_of::<i32>()
|
|
).unwrap()[0],
|
|
[0, 0, 0, 0],
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn vvsub_test() {
|
|
vvsub_test_generic::<f32, f32>("vvsub<f32,f32>");
|
|
vvsub_test_generic::<f64, f32>("vvsub<f64,f32>");
|
|
vvsub_test_generic::<f32, f64>("vvsub<f32,f64>");
|
|
vvsub_test_generic::<f64, f64>("vvsub<f64,f64>");
|
|
}
|
|
|
|
/// VVMUL Test
|
|
fn vvmul_test_generic<F, T>(err: &str)
|
|
where
|
|
F: From<f32> + std::fmt::Debug + PartialEq<F> + MemoryStorable,
|
|
T: From<f32> + std::fmt::Debug + PartialEq<T> + MemoryStorable,
|
|
{
|
|
let mut cpu = CPU::new(0);
|
|
let buff: [F; _] = [
|
|
1.0.into(),
|
|
2.0.into(),
|
|
3.0.into(),
|
|
4.0.into(),
|
|
5.0.into(),
|
|
6.0.into(),
|
|
7.0.into(),
|
|
8.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(),
|
|
];
|
|
cpu.host().execute_store(0, &buff).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(2, 8 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
sldi,
|
|
idata_build.set_rdimm(3, 16 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
setbw,
|
|
idata_build
|
|
.set_ibiw_obiw(8 * size_of::<F>() as i32, 8 * size_of::<T>() as i32)
|
|
.build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
vvmul,
|
|
idata_build
|
|
.set_rdr1r2(3, 1, 2)
|
|
.set_imm_len(8 * size_of::<F>() as i32)
|
|
.build(),
|
|
);
|
|
let core_instruction = vec![inst_builder.build().into()];
|
|
let mut executable = Executable::new(cpu, core_instruction);
|
|
executable.execute();
|
|
|
|
// Check result correct
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<T>(16 * size_of::<F>(), 8 * size_of::<T>()).unwrap()[0],
|
|
vec![
|
|
(9.0).into(),
|
|
(20.0).into(),
|
|
(33.0).into(),
|
|
(48.0).into(),
|
|
(65.0).into(),
|
|
(84.0).into(),
|
|
(105.0).into(),
|
|
(128.0).into()
|
|
],
|
|
"Wrong result for {}",
|
|
err
|
|
);
|
|
// Check first part equal
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<F>(0, 16 * size_of::<F>()).unwrap()[0],
|
|
&buff,
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
//Check that later is 0
|
|
assert_eq!(
|
|
executable.cpu_mut().host().load::<i32>(
|
|
16 * size_of::<F>() + 8 * size_of::<T>(),
|
|
4 * size_of::<i32>()
|
|
).unwrap()[0],
|
|
[0, 0, 0, 0],
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn vvmul_test() {
|
|
vvmul_test_generic::<f32, f32>("vvmul<f32,f32>");
|
|
vvmul_test_generic::<f64, f32>("vvmul<f64,f32>");
|
|
vvmul_test_generic::<f32, f64>("vvmul<f32,f64>");
|
|
vvmul_test_generic::<f64, f64>("vvmul<f64,f64>");
|
|
}
|
|
|
|
/// VVDMUL Test
|
|
fn vvdmul_test_generic<F, T>(err: &str)
|
|
where
|
|
F: From<f32> + std::fmt::Debug + PartialEq<F> + MemoryStorable,
|
|
T: From<f32> + std::fmt::Debug + PartialEq<T> + MemoryStorable,
|
|
{
|
|
let mut cpu = CPU::new(0);
|
|
let buff: [F; _] = [
|
|
1.0.into(),
|
|
2.0.into(),
|
|
3.0.into(),
|
|
4.0.into(),
|
|
5.0.into(),
|
|
6.0.into(),
|
|
7.0.into(),
|
|
8.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(),
|
|
];
|
|
cpu.host().execute_store(0, &buff).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(2, 8 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
sldi,
|
|
idata_build.set_rdimm(3, 16 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
setbw,
|
|
idata_build
|
|
.set_ibiw_obiw(8 * size_of::<F>() as i32, 8 * size_of::<T>() as i32)
|
|
.build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
vvdmul,
|
|
idata_build
|
|
.set_rdr1r2(3, 1, 2)
|
|
.set_imm_len(8 * size_of::<F>() as i32)
|
|
.build(),
|
|
);
|
|
let core_instruction = vec![inst_builder.build().into()];
|
|
let mut executable = Executable::new(cpu, core_instruction);
|
|
executable.execute();
|
|
|
|
// Check result correct
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<T>(16 * size_of::<F>(), size_of::<T>()).unwrap()[0],
|
|
vec![
|
|
(492.0).into(),
|
|
],
|
|
"Wrong result for {}",
|
|
err
|
|
);
|
|
// Check first part equal
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<F>(0, 16 * size_of::<F>()).unwrap()[0],
|
|
&buff,
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
//Check that later is 0
|
|
assert_eq!(
|
|
executable.cpu_mut().host().load::<i32>(
|
|
16 * size_of::<F>() + size_of::<T>(),
|
|
4 * size_of::<i32>()
|
|
).unwrap()[0],
|
|
[0, 0, 0, 0],
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn vvdmul_test() {
|
|
vvdmul_test_generic::<f32, f32>("vvdmul<f32,f32>");
|
|
vvdmul_test_generic::<f64, f32>("vvdmul<f64,f32>");
|
|
vvdmul_test_generic::<f32, f64>("vvdmul<f32,f64>");
|
|
vvdmul_test_generic::<f64, f64>("vvdmul<f64,f64>");
|
|
}
|
|
|
|
/// vvmax Test
|
|
fn vvmax_test_generic<F, T>(err: &str)
|
|
where
|
|
F: From<f32> + std::fmt::Debug + PartialEq<F> + MemoryStorable,
|
|
T: From<f32> + std::fmt::Debug + PartialEq<T> + MemoryStorable,
|
|
{
|
|
let mut cpu = CPU::new(0);
|
|
let buff: [F; _] = [
|
|
9.0.into(),
|
|
2.0.into(),
|
|
11.0.into(),
|
|
4.0.into(),
|
|
13.0.into(),
|
|
6.0.into(),
|
|
7.0.into(),
|
|
8.0.into(),
|
|
1.0.into(),
|
|
10.0.into(),
|
|
3.0.into(),
|
|
12.0.into(),
|
|
4.0.into(),
|
|
14.0.into(),
|
|
15.0.into(),
|
|
16.0.into(),
|
|
];
|
|
cpu.host().execute_store(0, &buff).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(2, 8 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
sldi,
|
|
idata_build.set_rdimm(3, 16 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
setbw,
|
|
idata_build
|
|
.set_ibiw_obiw(8 * size_of::<F>() as i32, 8 * size_of::<T>() as i32)
|
|
.build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
vvmax,
|
|
idata_build
|
|
.set_rdr1r2(3, 1, 2)
|
|
.set_imm_len(8 * size_of::<F>() as i32)
|
|
.build(),
|
|
);
|
|
let core_instruction = vec![inst_builder.build().into()];
|
|
let mut executable = Executable::new(cpu, core_instruction);
|
|
executable.execute();
|
|
|
|
// Check result correct
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<T>(16 * size_of::<F>(), 8 * size_of::<T>()).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(),
|
|
],
|
|
"Wrong result for {}",
|
|
err
|
|
);
|
|
// Check first part equal
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<F>(0, 16 * size_of::<F>()).unwrap()[0],
|
|
&buff,
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
//Check that later is 0
|
|
assert_eq!(
|
|
executable.cpu_mut().host().load::<i32>(
|
|
16 * size_of::<F>() + 8 * size_of::<T>(),
|
|
4 * size_of::<i32>()
|
|
).unwrap()[0],
|
|
[0, 0, 0, 0],
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn vvmax_test() {
|
|
vvmax_test_generic::<f32, f32>("vvmax<f32,f32>");
|
|
vvmax_test_generic::<f64, f32>("vvmax<f64,f32>");
|
|
vvmax_test_generic::<f32, f64>("vvmax<f32,f64>");
|
|
vvmax_test_generic::<f64, f64>("vvmax<f64,f64>");
|
|
}
|
|
|
|
/// vavg Test
|
|
fn vavg_test_generic<F, T>(err: &str)
|
|
where
|
|
F: From<f32> + std::fmt::Debug + PartialEq<F> + MemoryStorable,
|
|
T: From<f32> + std::fmt::Debug + PartialEq<T> + MemoryStorable,
|
|
{
|
|
let mut cpu = CPU::new(0);
|
|
let buff: [F; _] = [
|
|
9.0.into(),
|
|
2.0.into(),
|
|
11.0.into(),
|
|
4.0.into(),
|
|
13.0.into(),
|
|
6.0.into(),
|
|
7.0.into(),
|
|
8.0.into(),
|
|
1.0.into(),
|
|
10.0.into(),
|
|
3.0.into(),
|
|
12.0.into(),
|
|
4.0.into(),
|
|
14.0.into(),
|
|
15.0.into(),
|
|
16.0.into(),
|
|
];
|
|
cpu.host().execute_store(0, &buff).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, 16 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
setbw,
|
|
idata_build
|
|
.set_ibiw_obiw(8 * size_of::<F>() as i32, 8 * size_of::<T>() as i32)
|
|
.build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
vavg,
|
|
idata_build
|
|
.set_rdr1r2(3, 1, 1)
|
|
.set_imm_len(8 * size_of::<F>() as i32)
|
|
.build(),
|
|
);
|
|
let core_instruction = vec![inst_builder.build().into()];
|
|
let mut executable = Executable::new(cpu, core_instruction);
|
|
executable.execute();
|
|
|
|
// Check result correct
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<T>(16 * size_of::<F>(), size_of::<T>()).unwrap()[0],
|
|
vec![
|
|
7.5.into(),
|
|
],
|
|
"Wrong result for {}",
|
|
err
|
|
);
|
|
// Check first part equal
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<F>(0, 16 * size_of::<F>()).unwrap()[0],
|
|
&buff,
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
//Check that later is 0
|
|
assert_eq!(
|
|
executable.cpu_mut().host().load::<i32>(
|
|
16 * size_of::<F>() + size_of::<T>(),
|
|
4 * size_of::<i32>()
|
|
).unwrap()[0],
|
|
[0, 0, 0, 0],
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn vavg_test() {
|
|
vavg_test_generic::<f32, f32>("vavg<f32,f32>");
|
|
vavg_test_generic::<f64, f32>("vavg<f64,f32>");
|
|
vavg_test_generic::<f32, f64>("vavg<f32,f64>");
|
|
vavg_test_generic::<f64, f64>("vavg<f64,f64>");
|
|
}
|
|
|
|
/// vrelu Test
|
|
fn vrelu_test_generic<F, T>(err: &str)
|
|
where
|
|
F: From<f32> + std::fmt::Debug + PartialEq<F> + MemoryStorable,
|
|
T: From<f32> + std::fmt::Debug + PartialEq<T> + MemoryStorable,
|
|
{
|
|
let mut cpu = CPU::new(0);
|
|
let buff: [F; _] = [
|
|
(-9.0).into(),
|
|
2.0.into(),
|
|
11.0.into(),
|
|
(-4.0).into(),
|
|
13.0.into(),
|
|
(-6.0).into(),
|
|
7.0.into(),
|
|
(-6.0).into(),
|
|
1.0.into(),
|
|
(-6.0).into(),
|
|
3.0.into(),
|
|
12.0.into(),
|
|
(-6.0).into(),
|
|
14.0.into(),
|
|
(-6.0).into(),
|
|
16.0.into(),
|
|
];
|
|
cpu.host().execute_store(0, &buff).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, 16 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
setbw,
|
|
idata_build
|
|
.set_ibiw_obiw(8 * size_of::<F>() as i32, 8 * size_of::<T>() as i32)
|
|
.build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
vrelu,
|
|
idata_build
|
|
.set_rdr1r2(3, 1, 1)
|
|
.set_imm_len(8 * size_of::<F>() as i32)
|
|
.build(),
|
|
);
|
|
let core_instruction = vec![inst_builder.build().into()];
|
|
let mut executable = Executable::new(cpu, core_instruction);
|
|
executable.execute();
|
|
|
|
// Check result correct
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<T>(16 * size_of::<F>(), 8*size_of::<T>()).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(),
|
|
],
|
|
"Wrong result for {}",
|
|
err
|
|
);
|
|
// Check first part equal
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<F>(0, 16 * size_of::<F>()).unwrap()[0],
|
|
&buff,
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
//Check that later is 0
|
|
assert_eq!(
|
|
executable.cpu_mut().host().load::<i32>(
|
|
16 * size_of::<F>() + 8*size_of::<T>(),
|
|
4 * size_of::<i32>()
|
|
).unwrap()[0],
|
|
[0, 0, 0, 0],
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn vrelu_test() {
|
|
vrelu_test_generic::<f32, f32>("vrelu<f32,f32>");
|
|
vrelu_test_generic::<f64, f32>("vrelu<f64,f32>");
|
|
vrelu_test_generic::<f32, f64>("vrelu<f32,f64>");
|
|
vrelu_test_generic::<f64, f64>("vrelu<f64,f64>");
|
|
}
|
|
|
|
/// vtanh Test
|
|
fn vtanh_test_generic<F, T>(err: &str)
|
|
where
|
|
F: From<f32> + std::fmt::Debug + PartialEq<F> + MemoryStorable,
|
|
T: From<f32> + std::fmt::Debug + PartialEq<T> + MemoryStorable + UpcastDestTraits<T>,
|
|
{
|
|
let mut cpu = CPU::new(0);
|
|
let buff: [F; _] = [
|
|
0.1.into(),
|
|
0.2.into(),
|
|
0.3.into(),
|
|
0.4.into(),
|
|
0.5.into(),
|
|
0.6.into(),
|
|
0.7.into(),
|
|
0.8.into(),
|
|
0.9.into(),
|
|
0.10.into(),
|
|
0.11.into(),
|
|
0.12.into(),
|
|
0.13.into(),
|
|
0.14.into(),
|
|
0.15.into(),
|
|
0.16.into(),
|
|
];
|
|
cpu.host().execute_store(0, &buff).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, 16 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
setbw,
|
|
idata_build
|
|
.set_ibiw_obiw(8 * size_of::<F>() as i32, 8 * size_of::<T>() as i32)
|
|
.build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
vtanh,
|
|
idata_build
|
|
.set_rdr1r2(3, 1, 1)
|
|
.set_imm_len(8 * size_of::<F>() as i32)
|
|
.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::<T>(16 * size_of::<F>(), 8*size_of::<T>()).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
|
|
);
|
|
// Check first part equal
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<F>(0, 16 * size_of::<F>()).unwrap()[0],
|
|
&buff,
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
//Check that later is 0
|
|
assert_eq!(
|
|
executable.cpu_mut().host().load::<i32>(
|
|
16 * size_of::<F>() + 8*size_of::<T>(),
|
|
4 * size_of::<i32>()
|
|
).unwrap()[0],
|
|
[0, 0, 0, 0],
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn vtanh_test() {
|
|
vtanh_test_generic::<f32, f32>("vtanh<f32,f32>");
|
|
vtanh_test_generic::<f64, f32>("vtanh<f64,f32>");
|
|
vtanh_test_generic::<f32, f64>("vtanh<f32,f64>");
|
|
vtanh_test_generic::<f64, f64>("vtanh<f64,f64>");
|
|
}
|
|
|
|
|
|
/// vsigm Test
|
|
fn vsigm_test_generic<F, T>(err: &str)
|
|
where
|
|
F: From<f32> + std::fmt::Debug + PartialEq<F> + MemoryStorable,
|
|
T: From<f32> + std::fmt::Debug + PartialEq<T> + MemoryStorable + UpcastDestTraits<T>,
|
|
{
|
|
let mut cpu = CPU::new(0);
|
|
let buff: [F; _] = [
|
|
0.1.into(),
|
|
0.2.into(),
|
|
0.3.into(),
|
|
0.4.into(),
|
|
0.5.into(),
|
|
0.6.into(),
|
|
0.7.into(),
|
|
0.8.into(),
|
|
0.9.into(),
|
|
0.10.into(),
|
|
0.11.into(),
|
|
0.12.into(),
|
|
0.13.into(),
|
|
0.14.into(),
|
|
0.15.into(),
|
|
0.16.into(),
|
|
];
|
|
cpu.host().execute_store(0, &buff).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, 16 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
setbw,
|
|
idata_build
|
|
.set_ibiw_obiw(8 * size_of::<F>() as i32, 8 * size_of::<T>() as i32)
|
|
.build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
vsigm,
|
|
idata_build
|
|
.set_rdr1r2(3, 1, 1)
|
|
.set_imm_len(8 * size_of::<F>() as i32)
|
|
.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::<T>(16 * size_of::<F>(), 8*size_of::<T>()).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
|
|
);
|
|
// Check first part equal
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<F>(0, 16 * size_of::<F>()).unwrap()[0],
|
|
&buff,
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
//Check that later is 0
|
|
assert_eq!(
|
|
executable.cpu_mut().host().load::<i32>(
|
|
16 * size_of::<F>() + 8*size_of::<T>(),
|
|
4 * size_of::<i32>()
|
|
).unwrap()[0],
|
|
[0, 0, 0, 0],
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn vsigm_test() {
|
|
vsigm_test_generic::<f32, f32>("vsigm<f32,f32>");
|
|
vsigm_test_generic::<f64, f32>("vsigm<f64,f32>");
|
|
vsigm_test_generic::<f32, f64>("vsigm<f32,f64>");
|
|
vsigm_test_generic::<f64, f64>("vsigm<f64,f64>");
|
|
}
|
|
|
|
|
|
|
|
/// mvmul Test
|
|
fn mvmul_test_generic<F,M, T>(err: &str, relu:i32)
|
|
where
|
|
F: From<f32> + std::fmt::Debug + PartialEq<F> + MemoryStorable,
|
|
M: From<f32> + std::fmt::Debug + PartialEq<M> + MemoryStorable,
|
|
T: From<f32> + std::fmt::Debug + PartialEq<T> + MemoryStorable + UpcastDestTraits<T>,
|
|
{
|
|
let mut cpu = CPU::new(0);
|
|
cpu.reserve_crossbar(1, 4 * size_of::<M>(), 4);
|
|
let (memory, crossbars) = cpu.host().get_memory_crossbar();
|
|
let matrix: [M; _] = [
|
|
1.0.into(),
|
|
2.0.into(),
|
|
3.0.into(),
|
|
4.0.into(),
|
|
5.0.into(),
|
|
(-56.0).into(),
|
|
7.0.into(),
|
|
8.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(),
|
|
];
|
|
crossbars.get_mut(0).unwrap().execute_store( &matrix).unwrap();
|
|
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();
|
|
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, 4 * size_of::<F>() as i32).build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
setbw,
|
|
idata_build
|
|
.set_ibiw_obiw(8 * size_of::<F>() as i32, 8 * size_of::<T>() as i32)
|
|
.build(),
|
|
);
|
|
inst_builder.make_inst(
|
|
mvmul,
|
|
idata_build
|
|
.set_rdr1(3, 1)
|
|
.set_mbiw_immrelu_immgroup(8*size_of::<M>() as i32, relu, 0)
|
|
.build(),
|
|
);
|
|
let core_instruction = vec![inst_builder.build().into()];
|
|
let mut executable = Executable::new(cpu, core_instruction);
|
|
executable.execute();
|
|
|
|
// Check result correct
|
|
if relu == 0 {
|
|
assert_eq!(
|
|
executable
|
|
.cpu_mut()
|
|
.host()
|
|
.load::<T>(4 * size_of::<F>(), 4*size_of::<T>()).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::<T>(4 * size_of::<F>(), 4*size_of::<T>()).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::<F>(0, 4 * size_of::<F>()).unwrap()[0],
|
|
&vector,
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
//Check that later is 0
|
|
assert_eq!(
|
|
executable.cpu_mut().host().load::<i32>(
|
|
4 * size_of::<F>() + 4*size_of::<T>(),
|
|
4 * size_of::<i32>()
|
|
).unwrap()[0],
|
|
[0, 0, 0, 0],
|
|
"Altered first part for {}",
|
|
err
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn mvmul_test() {
|
|
mvmul_test_generic::<f32,f32,f32>("mvmul<f32,f32,f32>",0);
|
|
mvmul_test_generic::<f32,f32,f64>("mvmul<f32,f32,f64>",0);
|
|
mvmul_test_generic::<f32,f64,f32>("mvmul<f32,f64,f32>",0);
|
|
mvmul_test_generic::<f32,f64,f64>("mvmul<f32,f64,f64>",0);
|
|
mvmul_test_generic::<f64,f32,f32>("mvmul<f64,f32,f32>",0);
|
|
mvmul_test_generic::<f64,f32,f64>("mvmul<f64,f32,f64>",0);
|
|
mvmul_test_generic::<f64,f64,f32>("mvmul<f64,f64,f32>",0);
|
|
mvmul_test_generic::<f64,f64,f64>("mvmul<f64,f64,f64>",0);
|
|
|
|
mvmul_test_generic::<f32,f32,f32>("mvmul<f32,f32,f32>",1);
|
|
mvmul_test_generic::<f32,f32,f64>("mvmul<f32,f32,f64>",1);
|
|
mvmul_test_generic::<f32,f64,f32>("mvmul<f32,f64,f32>",1);
|
|
mvmul_test_generic::<f32,f64,f64>("mvmul<f32,f64,f64>",1);
|
|
mvmul_test_generic::<f64,f32,f32>("mvmul<f64,f32,f32>",1);
|
|
mvmul_test_generic::<f64,f32,f64>("mvmul<f64,f32,f64>",1);
|
|
mvmul_test_generic::<f64,f64,f32>("mvmul<f64,f64,f32>",1);
|
|
mvmul_test_generic::<f64,f64,f64>("mvmul<f64,f64,f64>",1);
|
|
|
|
}
|
|
|
|
|