Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion source/sgp_mode/hardware/GenomeLibrary.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ namespace lib_info {
{"Reproduce", 0}, {"PrivateIO", 1}, {"SharedIO", 1}, {"Donate", 0},
{"Reuptake", 1}, {"Steal", 0}, {"Infect", 0}, {"DynamicInst", 3},
{"SenseTask", 2},
{"IO", 1}, {"JumpIfNEq", 2}, {"JumpIfEq", 2}, {"JumpIfLess", 2}
{"IO", 1}
};
}

Expand Down
1 change: 0 additions & 1 deletion source/sgp_mode/hardware/Instructions.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ INST(Reproduce, {
state.MarkReproAttempt();
});

// NOTE - what is the intended difference between SharedIO and PrivateIO?
INST(IO, {
// (1) Add output to output buffer
state.GetOutputBuffer().emplace_back(a);
Expand Down
8 changes: 5 additions & 3 deletions source/sgp_mode/hardware/SGPHardware.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,16 +303,18 @@ void SGPHardware<HW_SPEC_T>::PrintOp(
} else {
tag_name = "<nowhere>";
}

if (name == "JumpIfNEq" || name == "JumpIfLess") {

if (name == "JumpIfNEq" || name == "JumpIfLess" || name == "JumpIfEq") {

out << " " << emp::to_lower(name);
for (size_t i = 0; i < 12 - name.length(); i++) {
out << ' ';
}
out << 'r' << (int)ins.args[0] << ", r" << (int)ins.args[1] << ", "
<< tag_name;

} else if (name == "Global Anchor") {
out << tag_name << " " << ins.tag << ':';
out << tag_name << ':';
} else {
out << "<unknown " << name << ">";
}
Expand Down
199 changes: 199 additions & 0 deletions source/test/sgp_mode_test/unit_tests/SGPHardware.test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
#include "emp/math/Random.hpp"

#include "../../../sgp_mode/hardware/SGPHardware.h"
#include "../../../sgp_mode/SGPWorld.h"
#include "../../../sgp_mode/SGPWorld.cc"
#include "../../../sgp_mode/SGPWorldSetup.cc"
#include "../../../sgp_mode/SGPWorldData.cc"
#include "../../../sgp_mode/ProgramBuilder.h"

#include "../../../catch/catch.hpp"

#include <array>
#include <string>

TEST_CASE("Test Printing Simple Instructions", "[sgp]"){
using world_t = sgpmode::SGPWorld;
using cpu_state_t = sgpmode::CPUState<world_t>;
using hw_spec_t = sgpmode::SGPHardwareSpec<sgpmode::Library, cpu_state_t, world_t>;
using hardware_t = sgpmode::SGPHardware<hw_spec_t>;
using program_t = typename world_t::sgp_prog_t;
using sgp_host_t = sgpmode::SGPHost<hw_spec_t>;
using tag_t = typename hw_spec_t::tag_t;

sgpmode::SymConfigSGP config;
config.CYCLES_PER_UPDATE(0);
config.HOST_REPRO_RES(1);
config.SEED(61);
config.TASK_ENV_CFG_PATH("source/test/sgp_mode_test/hardware-test-env.json");
config.FILE_PATH("hardware_test_output");
config.POP_SIZE(1);
config.START_MOI(0);
config.TASK_IO_UNIQUE_OUTPUT(true);

emp::Random random(config.SEED());
world_t world(random, &config);
world.Setup();
auto& prog_builder = world.GetProgramBuilder();

auto& org = world.GetOrg(0);
auto& sgp_host = static_cast<sgp_host_t&>(org);
hardware_t& hw = sgp_host.GetHardware();

std::ostringstream output;

WHEN("Program contains Nop Instruction"){
program_t program;
prog_builder.AddStartAnchor(program);
prog_builder.AddInst(program, "Nop-0", 0);
hw.Reset();
hw.SetProgram(program);

hw.PrintCode(output);

THEN("Global Anchor and Nop Instruction should be printed"){
REQUIRE(output.str() == "AA:\n nop-0 \n");
}
}
WHEN("Program contains Increment Instruction"){
program_t program;
prog_builder.AddStartAnchor(program);
prog_builder.AddInst(program, "Increment", 0);
hw.Reset();
hw.SetProgram(program);

hw.PrintCode(output);

THEN("Global Anchor and Increment Instruction should be printed"){
REQUIRE(output.str() == "AA:\n increment r0\n");
}
}
WHEN("Program contains Decrement Instruction"){
program_t program;
prog_builder.AddStartAnchor(program);
prog_builder.AddInst(program, "Decrement", 0);
hw.Reset();
hw.SetProgram(program);

hw.PrintCode(output);

THEN("Global Anchor and Increment Instruction should be printed"){
REQUIRE(output.str() == "AA:\n decrement r0\n");
}
}

WHEN("Program contains Nand Instruction"){
program_t program;
prog_builder.AddStartAnchor(program);
prog_builder.AddInst(program, "Nand", 0, 1, 0);
hw.Reset();
hw.SetProgram(program);

hw.PrintCode(output);

THEN("Global Anchor and Nand Instruction should be printed"){
REQUIRE(output.str() == "AA:\n nand r0, r1, r0\n");
}
}
}

TEST_CASE("Test Printing Complex Instructions", "[sgp]"){
using world_t = sgpmode::SGPWorld;
using cpu_state_t = sgpmode::CPUState<world_t>;
using hw_spec_t = sgpmode::SGPHardwareSpec<sgpmode::Library, cpu_state_t, world_t>;
using hardware_t = sgpmode::SGPHardware<hw_spec_t>;
using program_t = typename world_t::sgp_prog_t;
using sgp_host_t = sgpmode::SGPHost<hw_spec_t>;
using tag_t = typename hw_spec_t::tag_t;

sgpmode::SymConfigSGP config;
config.CYCLES_PER_UPDATE(0);
config.HOST_REPRO_RES(1);
config.SEED(61);
config.TASK_ENV_CFG_PATH("source/test/sgp_mode_test/hardware-test-env.json");
config.FILE_PATH("hardware_test_output");
config.POP_SIZE(1);
config.START_MOI(0);
config.TASK_IO_UNIQUE_OUTPUT(true);

emp::Random random(config.SEED());
world_t world(random, &config);
world.Setup();
auto& prog_builder = world.GetProgramBuilder();

auto& org = world.GetOrg(0);
auto& sgp_host = static_cast<sgp_host_t&>(org);
hardware_t& hw = sgp_host.GetHardware();

std::ostringstream output;

WHEN("Program contains JumpIfNEq Instruction"){
program_t program;
tag_t start_tag(prog_builder.GetStartTag());
tag_t tag1("0000000000000000000000000000000000000000000000000000000000000001");

prog_builder.AddStartAnchor(program);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "Global Anchor", tag1);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "JumpIfNEq", 0, 1, 0, tag1);
hw.Reset();
hw.SetProgram(program);

hw.PrintCode(output);

THEN("Global Anchor and Nop Instruction should be printed"){
REQUIRE(output.str() == "AA:\n nop-0 \n nop-0 \n nop-0 \nAB:\n nop-0 \n nop-0 \n jumpifneq r0, r1, AB\n");
}
}

WHEN("Program contains JumpIfEq Instruction"){
program_t program;
tag_t start_tag(prog_builder.GetStartTag());
tag_t tag1("0000000000000000000000000000000000000000000000000000000000000001");

prog_builder.AddStartAnchor(program);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "Global Anchor", tag1);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "JumpIfEq", 0, 1, 0, tag1);
hw.Reset();
hw.SetProgram(program);

hw.PrintCode(output);

THEN("Global Anchor and Nop Instruction should be printed"){
REQUIRE(output.str() == "AA:\n nop-0 \n nop-0 \n nop-0 \nAB:\n nop-0 \n nop-0 \n jumpifeq r0, r1, AB\n");
}
}

WHEN("Program contains JumpIfLess Instruction"){
program_t program;
tag_t start_tag(prog_builder.GetStartTag());
tag_t tag1("0000000000000000000000000000000000000000000000000000000000000010");

prog_builder.AddStartAnchor(program);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "Global Anchor", tag1);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "Nop-0", 0);
prog_builder.AddInst(program, "JumpIfLess", 0, 1, 0, tag1);
hw.Reset();
hw.SetProgram(program);

hw.PrintCode(output);

THEN("Global Anchor and Nop Instruction should be printed"){
REQUIRE(output.str() == "AA:\n nop-0 \n nop-0 \n nop-0 \nAB:\n nop-0 \n nop-0 \n jumpifless r0, r1, AB\n");
}
}

}
Loading