VirtualCPU.hpp
A simple virtual CPU styled after the original and extended Avidian architectures. @TODO.
Expanded heads?
expanded_nop_args useful?
Consider changing default return value for search functions
Consider switching to (or adding an optional mode) where nops are only curated as-needed instead of all at once
-
namespace emp
-
template<typename DERIVED>
class VirtualCPU - #include <VirtualCPU.hpp>
A simple virtual CPU styled after those seen in Avida.
This class represents a single virtual CPU following a genome of assembly-level instructions. By default, each CPU features four heads, two stacks, multiple registers, and a circular genome. Both the original and extended architectures are supported.
Public Types
-
using data_t = int32_t
-
using inst_t = Instruction
-
using inst_lib_t = VirtualCPU_InstLib<derived_t, data_t, 0>
-
using genome_t = Genome<Instruction, inst_lib_t>
Public Functions
-
inline VirtualCPU(const genome_t &in_genome)
CONSTRUCTORS / DESTRUCTOR Create a new VirtualCPU with the same genome (and thus instruction library)
-
inline VirtualCPU()
Create a default VirtualCPU (no genome sequence, default instruction set)
-
VirtualCPU(const VirtualCPU&) = default
Create a perfect copy of passed VirtualCPU.
-
VirtualCPU(VirtualCPU&&) = default
Default move constructor.
-
inline virtual ~VirtualCPU()
Default destructor.
-
inline size_t GetGenomeSize() const
GETTERS Return size of original genome
-
inline size_t GetWorkingGenomeSize() const
Return size of working genome.
-
inline size_t GetNumRegs() const
Return the number of registers in the CPU.
-
inline size_t GetNumNops() const
Return the number of NOP instructions found in the CPU’s instruction library.
-
inline Ptr<const inst_lib_t> GetInstLib() const
Return a pointer to the CPU’s instruction library.
-
inline size_t GetNumInstsExecuted() const
Return the number of instructions that have been executed.
-
inline size_t GetNumInstsCopied() const
Return the number of instructions that have been copied.
-
inline bool Load(std::istream &input)
GENOME & INSTRUCTION MANIPULATION Load instructions from input stream
-
inline void PushInst(size_t idx)
Add a new instruction to the end of the genome, by index in the instruction library.
-
inline void PushInst(int idx)
Redirect literal ints to PushInst(size_t) overload.
-
inline void PushInst(char c)
Add a new instruction to the end of the genome, by the instruction’s symbol/char.
-
inline void PushInst(const std::string &name)
Add a new instruction to the end of the genome, by name.
-
inline void PushInst(const inst_t &inst, size_t count)
Add multiple copies of a specified instruction to the end of the genome.
-
inline void PushDefaultInst(size_t count = 1)
Add one or more default instructions to the end of the genome.
-
inline inst_t GetRandomInst(Random &rand)
Return a random instruction from the instruction library.
-
inline void SetInst(size_t pos, const inst_t &inst)
Overwrite the instruction at the given genome index with passed instruction.
-
inline void RandomizeInst(size_t pos, Random &rand)
Overwrite the instruction at the given genome index with a random instruction.
-
inline void PushRandomInst(Random &random, const size_t count = 1)
Add a random instruction from the instruction library to the end of the genome.
-
inline void InsertInst(const inst_t &inst, const size_t idx)
Insert the given instruction at the specified genome position.
-
inline void InsertRandomInst(const size_t idx, Random &random)
Inserts a random instruction at the given genome position.
-
inline void RemoveInst(const size_t idx)
Remove the instruction at the specified genome position.
-
inline void IncreaseCooldown(size_t val)
Increase the cooldown by some value, so instructions cannot be processed for longer.
-
inline void DecreaseCooldown(size_t val)
Decrease the cooldown by some value, so instructions can be processed sooner.
-
inline void ResetCooldown()
Reset the cooldown timer.
-
inline void ResetIP()
Move instruction pointer to beginning of the genome.
-
inline void ResetRH()
Move read head to beginning of the genome.
-
inline void ResetWH()
Move write head to beginning of the genome.
-
inline void ResetFH()
Move flow head to beginning of the genome.
-
inline void AdvanceIP(size_t steps = 1)
Advance the instruction pointer so many steps and wrap around the end of the genome.
-
inline void AdvanceRH(size_t steps = 1)
Advance the read head so many steps and wrap around the end of the genome.
-
inline void AdvanceWH(size_t steps = 1)
Advance the write head so many steps and wrap around the end of the genome.
-
inline void AdvanceFH(size_t steps = 1)
Advance the flow head so many steps and wrap around the end of the genome.
-
inline void SetIP(size_t pos)
Set the instruction pointer to the genome index, wrap around the end of the genome.
-
inline void SetRH(size_t pos)
Set the read head to the genome index, wrap around the end of the genome.
-
inline void SetWH(size_t pos)
Set the write head to the genome index, wrap around the end of the genome.
-
inline void SetFH(size_t pos)
Set the flow head to the genome index, wrap around the end of the genome.
-
inline void ResetModdedHead(size_t head_idx)
Set the specified head (which can wrap) to the beginning of the genome,.
-
inline void SetModdedHead(size_t head_idx, size_t pos)
Set the specified head (which can wrap) to the given genome position, wrap around the end of the genome
-
inline void AdvanceModdedHead(size_t head_idx, size_t steps = 1)
Advance the specified head (which can wrap) the given number of instructions, wrap around the end of the genome
-
inline size_t GetModdedHead(size_t head_idx)
Return the head POSITION of the specified head (can wrap)
-
inline void Initialize()
HARDWARE MANIPULATION Initializes the CPU by counting the number of NOP instructions in the instruction library and expanding the number of registers to match
-
inline void ResetHeads()
Reset all heads.
-
inline void ResetIO()
Reset all inputs and outputs.
-
inline void ResetMemory()
Reset all memory/data.
-
inline void ResetBookkeeping()
Reset all bookkeeping variables.
-
inline void ResetWorkingGenome()
Reset the working genome back to the original genome.
-
inline void ResetHardware()
Reset just the CPU hardware, but keep the original genome.
-
inline void ClearGenome()
Clear the main genome of the organism and reset all hardware.
-
inline void CurateNops()
Compile NOP instructions in genome into useful nop vectors for each instruction, and records the position of all LABEL instructions
-
inline void CountNops()
Determine the number of sequential NOP instructions in the instruction library
Starts at NopA and continues from there. Any missing instructions force count to stop. Last possible NOP instruction is NopW, as NopX is a special case in Avida.
-
inline void ExpandRegisters()
Expand the CPU’s registers to match the number of NOP instructions in the instruction library
-
inline size_t GetComplementNop(size_t idx)
NOP SEQUENCE METHODS For a given NOP instruction (as an index), return its complement index
-
inline nop_vec_t GetComplementNopSequence(const nop_vec_t &nop_vec)
For a vector of NOP instructions (as indices), return a vector of complement indices in the same order
-
inline bool CompareNopSequences(const nop_vec_t &search_vec, const nop_vec_t &compare_vec)
Check if a vector of NOP instructions is the same as the START of another vector.
-
inline bool CheckIfLastCopied(const nop_vec_t &label)
Check if the given vector of NOP instructions (as indices) were the last instructions to be copied by the CPU
-
inline size_t FindLabel_Reverse(bool start_local)
Search up the genome (backward) for a sequence of NOP instructions following a LABEL instruction that match the NOP sequence following the current instruction
- Parameters:
start_local – If true, search from instruction pointer. If false, search from start of the genome
-
inline size_t FindLabel(bool start_local, bool reverse = false)
Search the genome for a sequence of NOP instructions following a LABEL instruction that match the NOP sequence following the current instruction
- Parameters:
start_local – If true, search from instruction pointer. If false, search from start of the genome
reverse – If true, traverse the genome backward. If false, traverse forward
-
inline size_t FindNopSequence_Reverse(const nop_vec_t &search_vec, size_t start_idx)
Search up the genome (backward) for a sequence of NOP instructions that match the given NOP sequence
- Parameters:
search_vec – The sequence of NOP instructions to search for
start_idx – Position in the genome to start the search
-
inline size_t FindNopSequence_Reverse(const nop_vec_t &search_vec, bool start_local)
Search up the genome (backward) for a sequence of NOP instructions that match the given NOP sequence
- Parameters:
search_vec – The sequence of NOP instructions to search for
start_local – If true, search from instruction pointer. If false, search from start of the genome
-
inline size_t FindNopSequence_Reverse(bool start_local)
Search up the genome (backward) for a sequence of NOP instructions that match the NOP sequence following the current instruction
- Parameters:
start_local – If true, search from instruction pointer. If false, search from start of the genome
-
inline size_t FindNopSequence(const nop_vec_t &search_vec, size_t start_idx, bool reverse = false)
Search the genome for a sequence of NOP instructions that match the given NOP sequence
- Parameters:
search_vec – The sequence of NOP instructions to search for
start_idx – Position in the genome to start the search
-
inline size_t FindNopSequence(const nop_vec_t &search_vec, bool start_local, bool reverse = false)
Search the genome for a sequence of NOP instructions that match the given NOP sequence
- Parameters:
search_vec – The sequence of NOP instructions to search for
start_local – If true, search from instruction pointer. If false, search from start of the genome
reverse – If true, traverse the genome backward. If false, traverse forward
-
inline size_t FindNopSequence(bool start_local, bool reverse = false)
Search up the genome (backward) for a sequence of NOP instructions that match the NOP sequence following the current instruction
- Parameters:
start_local – If true, search from instruction pointer. If false, search from start of the genome
reverse – If true, traverse the genome backward. If false, traverse forward
-
inline void StackPush(size_t reg_idx)
STACK MANIPULATION Push the value in the specified register on top of the active stack
-
inline void StackPop(size_t reg_idx)
Remove the value from the top of the active stack and store it in the specified register
-
inline void StackSwap()
Swap which stack is active.
-
inline data_t GetStackVal(size_t stack_idx, size_t val_idx)
Fetch the nth value of the specified stack.
-
inline void SingleProcess(bool verbose = true)
PROCESSING Process the next instruction pointed to be the instruction pointer
-
inline void Process(size_t num_inst = 1, bool verbose = true)
Process the next SERIES of instructions, directed by the instruction pointer.
-
inline std::string GetWorkingGenomeString() const
STATE -> STRING FUNCTIONS Return the working genome in string form.
Each instruction is represented by a single character, dictated by the instruction’s ID.
-
inline std::string GetGenomeString() const
Return the original genome in string form.
Each instruction is represented by a single character, dictated by the instruction’s ID.
Public Members
-
bool are_nops_counted = false
in the CPU’s library have been counted
Flag detailing if the number of NOP instructions
-
bool are_regs_expanded = false
Flag signaling if the number of registers have been expanded to accommodate the number of NOP instructions in the library
-
bool nops_need_curated = true
Flag signaling that NOP instructions need curated.
-
bool expanded_nop_args = false
Flag signaling that CPU is used the expanded.
-
array<stack_t, NUM_STACKS> stacks
Array of stacks for this CPU.
-
size_t inst_ptr
instruction to be executed
Instruction pointer, signifies next
-
size_t flow_head
values
Flow head, used for moving heads and
-
size_t read_head
copy next
Read head, signals what instruction to
-
size_t write_head
instruction
Write head, signals where to copy next
-
size_t cooldown_timer = 0
Decrease this value instead ///// HELPER CONSTRUCTS.
Do not process inst if value > 0.
-
unordered_map<size_t, size_t> nop_id_map
NOP inst id -> Nop index (e.g., NopA -> 0, NopB -> 1, NopE -> 5)
-
genome_t genome
that should not change in any way
Preserved copy of genome from organism creation/birth
-
genome_t genome_working
Working copy of genome that can mutate, resize, and change ///// BOOKKEEPING.
-
size_t active_stack_idx = 0
Index of CPU’s active stack.
-
size_t num_insts_executed = 0
Number of instructions that have been executed.
Public Static Attributes
-
static constexpr size_t NUM_STACKS = 2
Number of stacks in this CPU (currently 2)
-
static constexpr size_t MAX_NOPS = 23
Maximum number of nop instructions supported.
Protected Attributes
-
size_t num_regs = 0
Number of registers found in this CPU.
-
size_t num_nops = 0
Number of NOP instructions found in this CPU’s library.
-
struct Instruction : public inst_lib_t::InstructionBase
- #include <VirtualCPU.hpp>
Representation of a single instruction in the CPU’s genome.
Only contains the necessary information for which instruction is being represented as well as any data it needs in the genome. Does NOT contain the actual logic of the instruction, nor the name. These are handled by the instruction library itself.
Public Functions
-
Instruction() = delete
-
Instruction(const Instruction&) = default
-
Instruction(Instruction&&) = default
-
Instruction &operator=(const Instruction&) = default
-
Instruction &operator=(Instruction&&) = default
-
inline bool operator<(const Instruction &in) const
-
inline bool operator==(const Instruction &in) const
-
inline bool operator!=(const Instruction &in) const
-
inline bool operator>(const Instruction &in) const
-
inline bool operator>=(const Instruction &in) const
-
inline bool operator<=(const Instruction &in) const
-
inline size_t GetIndex() const override
Public Members
-
size_t idx
-
size_t id
Index of the instruction in the instruction library.
-
vector<size_t> nop_vec
Identifier for the instruction that gives the user flexibility over the instruction (e.g., what symbol it should use in a string representation)
-
bool has_been_executed = false
instructions following this instruction in the genome
Representation of the contiguous sequence of NOP
-
bool has_been_copied = false
Has this instruction been executed?
-
Instruction() = delete
-
using data_t = int32_t
-
template<typename DERIVED>