[Avida-SVN] r1505 - in development: Avida.xcodeproj source/cpu source/main support/config
dknoester at myxo.css.msu.edu
dknoester at myxo.css.msu.edu
Thu Apr 26 20:48:40 PDT 2007
Author: dknoester
Date: 2007-04-26 23:48:40 -0400 (Thu, 26 Apr 2007)
New Revision: 1505
Added:
development/support/config/default-gx.org
Modified:
development/Avida.xcodeproj/project.pbxproj
development/source/cpu/cCPUMemory.cc
development/source/cpu/cCPUMemory.h
development/source/cpu/cHardwareGX.cc
development/source/cpu/cHardwareGX.h
development/source/main/cGenome.cc
development/source/main/cGenome.h
Log:
Checkpoint commit for cHardwareGX; touches cGenome and cCPUMemory.
Modified: development/Avida.xcodeproj/project.pbxproj
===================================================================
--- development/Avida.xcodeproj/project.pbxproj 2007-04-27 02:49:56 UTC (rev 1504)
+++ development/Avida.xcodeproj/project.pbxproj 2007-04-27 03:48:40 UTC (rev 1505)
@@ -932,7 +932,7 @@
DCC315CF076253A5008F7A48 /* Makefile */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.make; path = Makefile; sourceTree = "<group>"; };
DCC315D0076253A5008F7A48 /* task_event_gen.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = task_event_gen.cc; sourceTree = "<group>"; };
DCC315D1076253A5008F7A48 /* task_event_gen.old.cc */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = task_event_gen.old.cc; sourceTree = "<group>"; };
- DCC3164D07626CF3008F7A48 /* avida */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = avida; sourceTree = BUILT_PRODUCTS_DIR; };
+ DCC3164D07626CF3008F7A48 /* avida */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = "compiled.mach-o.executable"; path = avida; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
Modified: development/source/cpu/cCPUMemory.cc
===================================================================
--- development/source/cpu/cCPUMemory.cc 2007-04-27 02:49:56 UTC (rev 1504)
+++ development/source/cpu/cCPUMemory.cc 2007-04-27 03:48:40 UTC (rev 1505)
@@ -39,6 +39,7 @@
}
}
+
void cCPUMemory::SloppyResize(int new_size)
{
assert(new_size > 0);
Modified: development/source/cpu/cCPUMemory.h
===================================================================
--- development/source/cpu/cCPUMemory.h 2007-04-27 02:49:56 UTC (rev 1504)
+++ development/source/cpu/cCPUMemory.h 2007-04-27 03:48:40 UTC (rev 1505)
@@ -59,6 +59,8 @@
cCPUMemory(const cCPUMemory& in_memory);
cCPUMemory(const cGenome& in_genome) : cGenome(in_genome), flag_array(in_genome.GetSize()) { ; }
cCPUMemory(const cString& in_string) : cGenome(in_string), flag_array(in_string.GetSize()) { ; }
+ //! Construct a cCPUMemory object from a cInstruction range.
+ cCPUMemory(cInstruction* begin, cInstruction* end) : cGenome(begin, end), flag_array(GetSize()) { }
~cCPUMemory() { ; }
void operator=(const cCPUMemory& other_memory);
Modified: development/source/cpu/cHardwareGX.cc
===================================================================
--- development/source/cpu/cHardwareGX.cc 2007-04-27 02:49:56 UTC (rev 1504)
+++ development/source/cpu/cHardwareGX.cc 2007-04-27 03:48:40 UTC (rev 1505)
@@ -90,8 +90,6 @@
tInstLibEntry<tMethod>("if-A!=C", &cHardwareGX::Inst_IfANotEqC),
tInstLibEntry<tMethod>("if-bit-1", &cHardwareGX::Inst_IfBit1),
- tInstLibEntry<tMethod>("jump-f", &cHardwareGX::Inst_JumpF),
- tInstLibEntry<tMethod>("jump-b", &cHardwareGX::Inst_JumpB),
tInstLibEntry<tMethod>("call", &cHardwareGX::Inst_Call),
tInstLibEntry<tMethod>("return", &cHardwareGX::Inst_Return),
@@ -166,13 +164,9 @@
tInstLibEntry<tMethod>("compare", &cHardwareGX::Inst_Compare),
tInstLibEntry<tMethod>("if-n-cpy", &cHardwareGX::Inst_IfNCpy),
tInstLibEntry<tMethod>("allocate", &cHardwareGX::Inst_Allocate),
- tInstLibEntry<tMethod>("divide", &cHardwareGX::Inst_Divide),
- tInstLibEntry<tMethod>("divideRS", &cHardwareGX::Inst_DivideRS),
tInstLibEntry<tMethod>("c-alloc", &cHardwareGX::Inst_CAlloc),
- tInstLibEntry<tMethod>("c-divide", &cHardwareGX::Inst_CDivide),
tInstLibEntry<tMethod>("inject", &cHardwareGX::Inst_Inject),
tInstLibEntry<tMethod>("inject-r", &cHardwareGX::Inst_InjectRand),
- tInstLibEntry<tMethod>("transposon", &cHardwareGX::Inst_Transposon),
tInstLibEntry<tMethod>("search-f", &cHardwareGX::Inst_SearchF),
tInstLibEntry<tMethod>("search-b", &cHardwareGX::Inst_SearchB),
tInstLibEntry<tMethod>("mem-size", &cHardwareGX::Inst_MemSize),
@@ -207,25 +201,16 @@
// Energy instruction
tInstLibEntry<tMethod>("recover", &cHardwareGX::Inst_ZeroEnergyUsed),
-
- // Threading instructions
- tInstLibEntry<tMethod>("fork-th", &cHardwareGX::Inst_ForkThread),
- tInstLibEntry<tMethod>("kill-th", &cHardwareGX::Inst_KillThread),
- tInstLibEntry<tMethod>("id-th", &cHardwareGX::Inst_ThreadID),
-
+
// Head-based instructions
tInstLibEntry<tMethod>("h-alloc", &cHardwareGX::Inst_MaxAlloc, nInstFlag::DEFAULT, "Allocate maximum allowed space"),
tInstLibEntry<tMethod>("h-divide", &cHardwareGX::Inst_HeadDivide, nInstFlag::DEFAULT, "Divide code between read and write heads."),
- tInstLibEntry<tMethod>("h-divide1RS", &cHardwareGX::Inst_HeadDivide1RS, 0, "Divide code between read and write heads, at most one mutation on divide, resample if reverted."),
- tInstLibEntry<tMethod>("h-divide2RS", &cHardwareGX::Inst_HeadDivide2RS, 0, "Divide code between read and write heads, at most two mutations on divide, resample if reverted."),
- tInstLibEntry<tMethod>("h-divideRS", &cHardwareGX::Inst_HeadDivideRS, 0, "Divide code between read and write heads, resample if reverted."),
tInstLibEntry<tMethod>("h-read", &cHardwareGX::Inst_HeadRead),
tInstLibEntry<tMethod>("h-write", &cHardwareGX::Inst_HeadWrite),
tInstLibEntry<tMethod>("h-copy", &cHardwareGX::Inst_HeadCopy, nInstFlag::DEFAULT, "Copy from read-head to write-head; advance both"),
tInstLibEntry<tMethod>("h-search", &cHardwareGX::Inst_HeadSearch, nInstFlag::DEFAULT, "Find complement template and make with flow head"),
tInstLibEntry<tMethod>("h-push", &cHardwareGX::Inst_HeadPush),
tInstLibEntry<tMethod>("h-pop", &cHardwareGX::Inst_HeadPop),
- tInstLibEntry<tMethod>("set-head", &cHardwareGX::Inst_SetHead),
tInstLibEntry<tMethod>("adv-head", &cHardwareGX::Inst_AdvanceHead),
tInstLibEntry<tMethod>("mov-head", &cHardwareGX::Inst_MoveHead, nInstFlag::DEFAULT, "Move head ?IP? to the flow head"),
tInstLibEntry<tMethod>("jmp-head", &cHardwareGX::Inst_JumpHead, nInstFlag::DEFAULT, "Move head ?IP? by amount in CX register; CX = old pos."),
@@ -243,72 +228,7 @@
tInstLibEntry<tMethod>("h-copy8", &cHardwareGX::Inst_HeadCopy8),
tInstLibEntry<tMethod>("h-copy9", &cHardwareGX::Inst_HeadCopy9),
tInstLibEntry<tMethod>("h-copy10", &cHardwareGX::Inst_HeadCopy10),
-
- tInstLibEntry<tMethod>("divide-sex", &cHardwareGX::Inst_HeadDivideSex),
- tInstLibEntry<tMethod>("divide-asex", &cHardwareGX::Inst_HeadDivideAsex),
-
- tInstLibEntry<tMethod>("div-sex", &cHardwareGX::Inst_HeadDivideSex),
- tInstLibEntry<tMethod>("div-asex", &cHardwareGX::Inst_HeadDivideAsex),
- tInstLibEntry<tMethod>("div-asex-w", &cHardwareGX::Inst_HeadDivideAsexWait),
- tInstLibEntry<tMethod>("div-sex-MS", &cHardwareGX::Inst_HeadDivideMateSelect),
-
- tInstLibEntry<tMethod>("h-divide1", &cHardwareGX::Inst_HeadDivide1),
- tInstLibEntry<tMethod>("h-divide2", &cHardwareGX::Inst_HeadDivide2),
- tInstLibEntry<tMethod>("h-divide3", &cHardwareGX::Inst_HeadDivide3),
- tInstLibEntry<tMethod>("h-divide4", &cHardwareGX::Inst_HeadDivide4),
- tInstLibEntry<tMethod>("h-divide5", &cHardwareGX::Inst_HeadDivide5),
- tInstLibEntry<tMethod>("h-divide6", &cHardwareGX::Inst_HeadDivide6),
- tInstLibEntry<tMethod>("h-divide7", &cHardwareGX::Inst_HeadDivide7),
- tInstLibEntry<tMethod>("h-divide8", &cHardwareGX::Inst_HeadDivide8),
- tInstLibEntry<tMethod>("h-divide9", &cHardwareGX::Inst_HeadDivide9),
- tInstLibEntry<tMethod>("h-divide10", &cHardwareGX::Inst_HeadDivide10),
- tInstLibEntry<tMethod>("h-divide16", &cHardwareGX::Inst_HeadDivide16),
- tInstLibEntry<tMethod>("h-divide32", &cHardwareGX::Inst_HeadDivide32),
- tInstLibEntry<tMethod>("h-divide50", &cHardwareGX::Inst_HeadDivide50),
- tInstLibEntry<tMethod>("h-divide100", &cHardwareGX::Inst_HeadDivide100),
- tInstLibEntry<tMethod>("h-divide500", &cHardwareGX::Inst_HeadDivide500),
- tInstLibEntry<tMethod>("h-divide1000", &cHardwareGX::Inst_HeadDivide1000),
- tInstLibEntry<tMethod>("h-divide5000", &cHardwareGX::Inst_HeadDivide5000),
- tInstLibEntry<tMethod>("h-divide10000", &cHardwareGX::Inst_HeadDivide10000),
- tInstLibEntry<tMethod>("h-divide50000", &cHardwareGX::Inst_HeadDivide50000),
- tInstLibEntry<tMethod>("h-divide0.5", &cHardwareGX::Inst_HeadDivide0_5),
- tInstLibEntry<tMethod>("h-divide0.1", &cHardwareGX::Inst_HeadDivide0_1),
- tInstLibEntry<tMethod>("h-divide0.05", &cHardwareGX::Inst_HeadDivide0_05),
- tInstLibEntry<tMethod>("h-divide0.01", &cHardwareGX::Inst_HeadDivide0_01),
- tInstLibEntry<tMethod>("h-divide0.001", &cHardwareGX::Inst_HeadDivide0_001),
-
- // High-level instructions
- tInstLibEntry<tMethod>("repro", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-A", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-B", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-C", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-D", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-E", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-F", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-G", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-H", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-I", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-J", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-K", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-L", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-M", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-N", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-O", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-P", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-Q", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-R", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-S", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-T", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-U", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-V", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-W", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-X", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-Y", &cHardwareGX::Inst_Repro),
- tInstLibEntry<tMethod>("repro-Z", &cHardwareGX::Inst_Repro),
-
- tInstLibEntry<tMethod>("put-repro", &cHardwareGX::Inst_TaskPutRepro),
- tInstLibEntry<tMethod>("metabolize", &cHardwareGX::Inst_TaskPutResetInputsRepro),
-
+
tInstLibEntry<tMethod>("spawn-deme", &cHardwareGX::Inst_SpawnDeme),
// Suicide
@@ -339,48 +259,42 @@
return new tInstLib<tMethod>(f_size, s_f_array, n_names, nop_mods, functions, error, def);
}
+
+/*! Construct a cHardwareGX instance from the passed-in cOrganism. This amounts to
+creating an initial cProgramid from in_organism's genome.
+*/
cHardwareGX::cHardwareGX(cWorld* world, cOrganism* in_organism, cInstSet* in_m_inst_set)
: cHardwareBase(world, in_organism, in_m_inst_set)
{
- /* FIXME: reorganize storage of m_functions. -- kgn */
m_functions = s_inst_slib->GetFunctions();
- /**/
- m_memory = in_organism->GetGenome(); // Initialize memory...
+ m_programids.push_back(programid_ptr(new cProgramid(in_organism->GetGenome(), this)));
+ m_current = m_programids.back();
Reset(); // Setup the rest of the hardware...
}
-cHardwareGX::cHardwareGX(const cHardwareGX &hardware_cpu)
-: cHardwareBase(hardware_cpu.m_world, hardware_cpu.organism, hardware_cpu.m_inst_set)
-, m_functions(hardware_cpu.m_functions)
-, m_memory(hardware_cpu.m_memory)
-, m_global_stack(hardware_cpu.m_global_stack)
-, m_threads(hardware_cpu.m_threads)
-, m_thread_id_chart(hardware_cpu.m_thread_id_chart)
-, m_cur_thread(hardware_cpu.m_cur_thread)
-, m_mal_active(hardware_cpu.m_mal_active)
-, m_advance_ip(hardware_cpu.m_advance_ip)
-, m_executedmatchstrings(hardware_cpu.m_executedmatchstrings)
-#if INSTRUCTION_COSTS
-, inst_cost(hardware_cpu.inst_cost)
-, inst_ft_cost(hardware_cpu.inst_ft_cost)
-#endif
+/*! Destructor; delete all programids. */
+cHardwareGX::~cHardwareGX()
{
-}
+ for(programid_list::iterator i=m_programids.begin(); i!=m_programids.end(); ++i) {
+ delete *i;
+ }
+}
+/*! Reset this cHardwareGX to a known state. Removes all the cProgramids, creates
+a new cProgramid from the germ.
+*/
void cHardwareGX::Reset()
{
- m_global_stack.Clear();
+ for(programid_list::iterator i=m_programids.begin(); i!=m_programids.end(); ++i) {
+ delete *i;
+ }
- // We want to reset to have a single thread.
- m_threads.Resize(1);
-
- // Reset that single thread.
- m_threads[0].Reset(this, 0);
- m_thread_id_chart = 1; // Mark only the first thread as taken...
- m_cur_thread = 0;
-
+ m_programids.clear();
+ m_programids.push_back(programid_ptr(new cProgramid(organism->GetGenome(), this)));
+ m_current = m_programids.back();
+
m_mal_active = false;
m_executedmatchstrings = false;
@@ -398,106 +312,133 @@
}
-void cHardwareGX::cLocalThread::operator=(const cLocalThread& in_thread)
-{
- m_id = in_thread.m_id;
- for (int i = 0; i < NUM_REGISTERS; i++) reg[i] = in_thread.reg[i];
- for (int i = 0; i < NUM_HEADS; i++) heads[i] = in_thread.heads[i];
- stack = in_thread.stack;
-}
+//void cHardwareGX::cLocalThread::operator=(const cLocalThread& in_thread)
+//{
+// m_id = in_thread.m_id;
+// for (int i = 0; i < NUM_REGISTERS; i++) reg[i] = in_thread.reg[i];
+// for (int i = 0; i < NUM_HEADS; i++) heads[i] = in_thread.heads[i];
+// stack = in_thread.stack;
+//}
+//
+//void cHardwareGX::cLocalThread::Reset(cHardwareBase* in_hardware, int in_id)
+//{
+// m_id = in_id;
+//
+// for (int i = 0; i < NUM_REGISTERS; i++) reg[i] = 0;
+// for (int i = 0; i < NUM_HEADS; i++) heads[i].Reset(in_hardware);
+//
+// stack.Clear();
+// cur_stack = 0;
+// cur_head = nHardware::HEAD_IP;
+// read_label.Clear();
+// next_label.Clear();
+//}
-void cHardwareGX::cLocalThread::Reset(cHardwareBase* in_hardware, int in_id)
-{
- m_id = in_id;
-
- for (int i = 0; i < NUM_REGISTERS; i++) reg[i] = 0;
- for (int i = 0; i < NUM_HEADS; i++) heads[i].Reset(in_hardware);
-
- stack.Clear();
- cur_stack = 0;
- cur_head = nHardware::HEAD_IP;
- read_label.Clear();
- next_label.Clear();
-}
-
// This function processes the very next command in the genome, and is made
// to be as optimized as possible. This is the heart of avida.
-
+/*! In cHardwareGX, SingleProcess is something of a misnomer. Each time this method
+ is called, each cProgramid executes a single instruction.
+ */
void cHardwareGX::SingleProcess(cAvidaContext& ctx)
{
- // Mark this organism as running...
+ cPhenotype& phenotype = organism->GetPhenotype();
+
organism->SetRunning(true);
-
- cPhenotype & phenotype = organism->GetPhenotype();
phenotype.IncTimeUsed();
- phenotype.IncCPUCyclesUsed();
- const int num_threads = GetNumThreads();
-
- // If we have threads turned on and we executed each thread in a single
- // timestep, adjust the number of instructions executed accordingly.
- const int num_inst_exec = (m_world->GetConfig().THREAD_SLICING_METHOD.Get() == 1) ?
-num_threads : 1;
-
- for (int i = 0; i < num_inst_exec; i++) {
- // Setup the hardware for the next instruction to be executed.
- ThreadNext();
- m_advance_ip = true;
- IP().Adjust();
+ for(programid_list::iterator i=m_programids.begin(); i!=m_programids.end(); ++i) {
+ // Set the currently-executing cProgramid.
+ m_current = *i;
-#if BREAKPOINTS
- if (IP().FlagBreakpoint()) {
- organism->DoBreakpoint();
- }
-#endif
-
- // Print the status of this CPU at each step...
- if (m_tracer != NULL) m_tracer->TraceHardware(*this);
-
- // Find the instruction to be executed
+ // Find the instruction to be executed.
const cInstruction& cur_inst = IP().GetInst();
-
- // Test if costs have been paid and it is okay to execute this now...
- bool exec = SingleProcess_PayCosts(ctx, cur_inst);
- // Now execute the instruction...
- if (exec == true) {
- // NOTE: This call based on the cur_inst must occur prior to instruction
- // execution, because this instruction reference may be invalid after
- // certain classes of instructions (namely divide instructions) @DMB
- const int addl_time_cost = m_inst_set->GetAddlTimeCost(cur_inst);
-
- // Prob of exec (moved from SingleProcess_PayCosts so that we advance IP after a fail)
- if ( m_inst_set->GetProbFail(cur_inst) > 0.0 )
- {
- exec = !( ctx.GetRandom().P(m_inst_set->GetProbFail(cur_inst)) );
- }
-
- if (exec == true) SingleProcess_ExecuteInst(ctx, cur_inst);
-
- // Some instruction (such as jump) may turn m_advance_ip off. Usually
- // we now want to move to the next instruction in the memory.
- if (m_advance_ip == true) IP().Advance();
-
- // Pay the additional death_cost of the instruction now
- phenotype.IncTimeUsed(addl_time_cost);
- } // if exec
+ m_advance_ip = true;
+ SingleProcess_ExecuteInst(ctx, cur_inst);
+ if (m_advance_ip == true) {
+ IP().Advance();
+ }
- } // Previous was executed once for each thread...
-
- // Kill creatures who have reached their max num of instructions executed
+ // Update phenotype.
+ phenotype.IncCPUCyclesUsed();
+ }
+
+ // Kill creatures who have reached their max num of instructions executed.
const int max_executed = organism->GetMaxExecuted();
if ((max_executed > 0 && phenotype.GetTimeUsed() >= max_executed)
|| phenotype.GetToDie() == true) {
organism->Die();
- }
+ }
organism->SetRunning(false);
}
+// const int num_threads = GetNumThreads();
+//
+// // If we have threads turned on and we executed each thread in a single
+// // timestep, adjust the number of instructions executed accordingly.
+// const int num_inst_exec = (m_world->GetConfig().THREAD_SLICING_METHOD.Get() == 1) ?
+//num_threads : 1;
+//
+// for (int i = 0; i < num_inst_exec; i++) {
+// // Setup the hardware for the next instruction to be executed.
+// ThreadNext();
+// m_advance_ip = true;
+// IP().Adjust();
+//
+//#if BREAKPOINTS
+// if (IP().FlagBreakpoint()) {
+// organism->DoBreakpoint();
+// }
+//#endif
+//
+// // Print the status of this CPU at each step...
+// if (m_tracer != NULL) m_tracer->TraceHardware(*this);
+//
+// // Find the instruction to be executed
+// const cInstruction& cur_inst = IP().GetInst();
+//
+// // Test if costs have been paid and it is okay to execute this now...
+// bool exec = SingleProcess_PayCosts(ctx, cur_inst);
+//
+// // Now execute the instruction...
+// if (exec == true) {
+// // NOTE: This call based on the cur_inst must occur prior to instruction
+// // execution, because this instruction reference may be invalid after
+// // certain classes of instructions (namely divide instructions) @DMB
+// const int addl_time_cost = m_inst_set->GetAddlTimeCost(cur_inst);
+//
+// // Prob of exec (moved from SingleProcess_PayCosts so that we advance IP after a fail)
+// if ( m_inst_set->GetProbFail(cur_inst) > 0.0 )
+// {
+// exec = !( ctx.GetRandom().P(m_inst_set->GetProbFail(cur_inst)) );
+// }
+//
+// if (exec == true) SingleProcess_ExecuteInst(ctx, cur_inst);
+//
+// // Some instruction (such as jump) may turn m_advance_ip off. Usually
+// // we now want to move to the next instruction in the memory.
+// if (m_advance_ip == true) IP().Advance();
+//
+// // Pay the additional death_cost of the instruction now
+// phenotype.IncTimeUsed(addl_time_cost);
+// } // if exec
+//
+// } // Previous was executed once for each thread...
+//
+// // Kill creatures who have reached their max num of instructions executed
+// const int max_executed = organism->GetMaxExecuted();
+// if ((max_executed > 0 && phenotype.GetTimeUsed() >= max_executed)
+// || phenotype.GetToDie() == true) {
+// organism->Die();
+// }
+//
+// organism->SetRunning(false);
+//}
+
// This method will test to see if all costs have been paid associated
// with executing an instruction and only return true when that instruction
// should proceed.
@@ -581,17 +522,15 @@
bool cHardwareGX::OK()
{
bool result = true;
-
- if (!m_memory.OK()) result = false;
-
- for (int i = 0; i < GetNumThreads(); i++) {
- if (m_threads[i].stack.OK() == false) result = false;
- if (m_threads[i].next_label.OK() == false) result = false;
+ for(programid_list::iterator i=m_programids.begin(); i!=m_programids.end() && result; ++i) {
+ result = result && (*i)->m_memory.OK() && (*i)->m_stack.OK() && (*i)->m_nextLabel.OK();
}
-
return result;
}
+
+/*! \todo Revisit.
+*/
void cHardwareGX::PrintStatus(ostream& fp)
{
fp << organism->GetPhenotype().GetCPUCyclesUsed() << " ";
@@ -615,13 +554,16 @@
<< "F-Head:" << GetHead(nHardware::HEAD_FLOW).GetPosition() << " "
<< "RL:" << GetReadLabel().AsString() << " "
<< endl;
-
- int number_of_stacks = GetNumStacks();
- for (int stack_id = 0; stack_id < number_of_stacks; stack_id++) {
- fp << ((m_threads[m_cur_thread].cur_stack == stack_id) ? '*' : ' ') << " Stack " << stack_id << ":" << setbase(16) << setfill('0');
- for (int i = 0; i < nHardware::STACK_SIZE; i++) fp << " Ox" << setw(8) << GetStack(i, stack_id, 0);
- fp << setfill(' ') << setbase(10) << endl;
- }
+
+// This will have to be revisited soon.
+// int number_of_stacks = GetNumStacks();
+// for (int stack_id = 0; stack_id < number_of_stacks; stack_id++) {
+// fp << ((m_threads[m_cur_thread].cur_stack == stack_id) ? '*' : ' ') << " Stack "
+// << stack_id << ":" << setbase(16) << setfill('0');
+// for (int i = 0; i < nHardware::STACK_SIZE; i++)
+// fp << " Ox" << setw(8) << GetStack(i, stack_id, 0);
+// fp << setfill(' ') << setbase(10) << endl;
+// }
fp << " Mem (" << GetMemory().GetSize() << "):"
<< " " << GetMemory().AsString()
@@ -880,44 +822,30 @@
}
+/*! Inject a genome fragment into this CPU. This works a little differently in
+cHardwareGX, in that we don't insert a genome fragment into a preexisting genome,
+but instead ust create a new cProgramid with the genome-to-be-injected.
+*/
bool cHardwareGX::InjectHost(const cCodeLabel & in_label, const cGenome & injection)
{
- // Make sure the genome will be below max size after injection.
-
- const int new_size = injection.GetSize() + GetMemory().GetSize();
- if (new_size > MAX_CREATURE_SIZE) return false; // (inject fails)
-
- const int inject_line = FindLabelFull(in_label).GetPosition();
-
- // Abort if no compliment is found.
- if (inject_line == -1) return false; // (inject fails)
-
- // Inject the code!
- InjectCode(injection, inject_line+1);
-
- return true; // (inject succeeds!)
+ InjectCode(injection, -1);
+ return true;
}
+
+/*! Inject a genome fragment into this CPU. This works differently in
+cHardwareGX -- We just insert a new cProgramid.
+*/
void cHardwareGX::InjectCode(const cGenome & inject_code, const int line_num)
{
- assert(line_num >= 0);
- assert(line_num <= m_memory.GetSize());
- assert(m_memory.GetSize() + inject_code.GetSize() < MAX_CREATURE_SIZE);
+ m_programids.push_back(programid_ptr(new cProgramid(inject_code, this)));
+ programid_ptr injected = m_programids.back();
- // Inject the new code.
- const int inject_size = inject_code.GetSize();
- m_memory.Insert(line_num, inject_code);
-
// Set instruction flags on the injected code
- for (int i = line_num; i < line_num + inject_size; i++) {
- m_memory.SetFlagInjected(i);
+ for(int i=0; i<injected->m_memory.GetSize(); ++i) {
+ injected->m_memory.SetFlagInjected(i);
}
organism->GetPhenotype().IsModified() = true;
-
- // Adjust all of the heads to take into account the new mem size.
- for (int i = 0; i < NUM_HEADS; i++) {
- if (GetHead(i).GetPosition() > line_num) GetHead(i).Jump(inject_size);
- }
}
@@ -933,11 +861,11 @@
void cHardwareGX::AdjustHeads()
{
- for (int i = 0; i < GetNumThreads(); i++) {
- for (int j = 0; j < NUM_HEADS; j++) {
- m_threads[i].heads[j].Adjust();
- }
- }
+// for (int i = 0; i < GetNumThreads(); i++) {
+// for (int j = 0; j < NUM_HEADS; j++) {
+// m_threads[i].heads[j].Adjust();
+// }
+// }
}
@@ -967,54 +895,54 @@
}
-bool cHardwareGX::ForkThread()
-{
- const int num_threads = GetNumThreads();
- if (num_threads == m_world->GetConfig().MAX_CPU_THREADS.Get()) return false;
-
- // Make room for the new thread.
- m_threads.Resize(num_threads + 1);
-
- // Initialize the new thread to the same values as the current one.
- m_threads[num_threads] = m_threads[m_cur_thread];
-
- // Find the first free bit in m_thread_id_chart to determine the new
- // thread id.
- int new_id = 0;
- while ( (m_thread_id_chart >> new_id) & 1 == 1) new_id++;
- m_threads[num_threads].SetID(new_id);
- m_thread_id_chart |= (1 << new_id);
-
- return true;
-}
+//bool cHardwareGX::ForkThread()
+//{
+// const int num_threads = GetNumThreads();
+// if (num_threads == m_world->GetConfig().MAX_CPU_THREADS.Get()) return false;
+//
+// // Make room for the new thread.
+// m_threads.Resize(num_threads + 1);
+//
+// // Initialize the new thread to the same values as the current one.
+// m_threads[num_threads] = m_threads[m_cur_thread];
+//
+// // Find the first free bit in m_thread_id_chart to determine the new
+// // thread id.
+// int new_id = 0;
+// while ( (m_thread_id_chart >> new_id) & 1 == 1) new_id++;
+// m_threads[num_threads].SetID(new_id);
+// m_thread_id_chart |= (1 << new_id);
+//
+// return true;
+//}
+//
+//
+//bool cHardwareGX::KillThread()
+//{
+// // Make sure that there is always at least one thread...
+// if (GetNumThreads() == 1) return false;
+//
+// // Note the current thread and set the current back one.
+// const int kill_thread = m_cur_thread;
+// ThreadPrev();
+//
+// // Turn off this bit in the m_thread_id_chart...
+// m_thread_id_chart ^= 1 << m_threads[kill_thread].GetID();
+//
+// // Copy the last thread into the kill position
+// const int last_thread = GetNumThreads() - 1;
+// if (last_thread != kill_thread) {
+// m_threads[kill_thread] = m_threads[last_thread];
+// }
+//
+// // Kill the thread!
+// m_threads.Resize(GetNumThreads() - 1);
+//
+// if (m_cur_thread > kill_thread) m_cur_thread--;
+//
+// return true;
+//}
-
-bool cHardwareGX::KillThread()
-{
- // Make sure that there is always at least one thread...
- if (GetNumThreads() == 1) return false;
-
- // Note the current thread and set the current back one.
- const int kill_thread = m_cur_thread;
- ThreadPrev();
-
- // Turn off this bit in the m_thread_id_chart...
- m_thread_id_chart ^= 1 << m_threads[kill_thread].GetID();
-
- // Copy the last thread into the kill position
- const int last_thread = GetNumThreads() - 1;
- if (last_thread != kill_thread) {
- m_threads[kill_thread] = m_threads[last_thread];
- }
-
- // Kill the thread!
- m_threads.Resize(GetNumThreads() - 1);
-
- if (m_cur_thread > kill_thread) m_cur_thread--;
-
- return true;
-}
-
////////////////////////////
// Instruction Helpers...
////////////////////////////
@@ -1173,327 +1101,67 @@
}
-bool cHardwareGX::Divide_Main(cAvidaContext& ctx, const int div_point,
- const int extra_lines, double mut_multiplier)
-{
- const int child_size = GetMemory().GetSize() - div_point - extra_lines;
-
- // Make sure this divide will produce a viable offspring.
- const bool viable = Divide_CheckViable(ctx, div_point, child_size);
- if (viable == false) return false;
-
- // Since the divide will now succeed, set up the information to be sent
- // to the new organism
- cGenome & child_genome = organism->ChildGenome();
- child_genome = cGenomeUtil::Crop(m_memory, div_point, div_point+child_size);
-
- // Cut off everything in this memory past the divide point.
- GetMemory().Resize(div_point);
-
- // Handle Divide Mutations...
- Divide_DoMutations(ctx, mut_multiplier);
-
- // Many tests will require us to run the offspring through a test CPU;
- // this is, for example, to see if mutations need to be reverted or if
- // lineages need to be updated.
- Divide_TestFitnessMeasures(ctx);
-
-#if INSTRUCTION_COSTS
- // reset first time instruction costs
- for (int i = 0; i < inst_ft_cost.GetSize(); i++) {
- inst_ft_cost[i] = m_inst_set->GetFTCost(cInstruction(i));
- }
-#endif
-
- m_mal_active = false;
- if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
- m_advance_ip = false;
- }
-
- // Activate the child
- bool parent_alive = organism->ActivateDivide(ctx);
-
- // Do more work if the parent lives through the birth of the offspring
- if (parent_alive) {
- if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) Reset();
- }
-
- return true;
-}
-
-/*
- Almost the same as Divide_Main, but resamples reverted offspring.
-
- RESAMPLING ONLY WORKS CORRECTLY WHEN ALL MUTIONS OCCUR ON DIVIDE!!
-
- AWC - 06/29/06
+/*! Divide works a little differently in cHardwareGX than in other CPUs. First,
+the cProgramid directly builds its offspring (rather than attaching its genome), so
+we don't need to do any genome splitting. This also enables the offspring to be
+active during replication. Second, we have to divvy up the other cProgramid objects
+between the parent and offspring. We also have to be careful to make sure that
+we have two genomes!
*/
-bool cHardwareGX::Divide_MainRS(cAvidaContext& ctx, const int div_point,
- const int extra_lines, double mut_multiplier)
+bool cHardwareGX::Divide_Main(cAvidaContext& ctx)
{
-
- //cStats stats = m_world->GetStats();
- const int child_size = GetMemory().GetSize() - div_point - extra_lines;
- // Make sure this divide will produce a viable offspring.
- const bool viable = Divide_CheckViable(ctx, div_point, child_size);
- if (viable == false) return false;
+// if(m_current->TriggerReplication()) {
+// } else {
+// }
+//
- // Since the divide will now succeed, set up the information to be sent
- // to the new organism
- cGenome & child_genome = organism->ChildGenome();
- child_genome = cGenomeUtil::Crop(m_memory, div_point, div_point+child_size);
-
- // Cut off everything in this memory past the divide point.
- GetMemory().Resize(div_point);
-
- unsigned
- totalMutations = 0,
- mutations = 0;
- //RScount = 0;
-
-
- bool
- fitTest = false;
-
- // Handle Divide Mutations...
- /*
- Do mutations until one of these conditions are satisified:
- we have resampled X times
- we have an offspring with the same number of muations as the first offspring
- that is not reverted
- the parent is steralized (usually means an implicit mutation)
- */
- for(unsigned i = 0; i <= 100; i++){
- if(i == 0){
- mutations = totalMutations = Divide_DoMutations(ctx, mut_multiplier);
- }
- else{
- mutations = Divide_DoMutations(ctx, mut_multiplier);
- m_world->GetStats().IncResamplings();
- }
-
- fitTest = Divide_TestFitnessMeasures(ctx);
-
- if(!fitTest && mutations >= totalMutations) break;
-
- }
- // think about making this mutations == totalMuations - though this may be too hard...
- /*
- if(RScount > 2)
- cerr << "Resampled " << RScount << endl;
- */
- //org could not be resampled beneath the hard cap -- it is then steraalized
- if(fitTest/*RScount == 11*/) {
- organism->GetPhenotype().ChildFertile() = false;
- m_world->GetStats().IncFailedResamplings();
- }
-
-#if INSTRUCTION_COSTS
- // reset first time instruction costs
- for (int i = 0; i < inst_ft_cost.GetSize(); i++) {
- inst_ft_cost[i] = m_inst_set->GetFTCost(cInstruction(i));
- }
-#endif
-
- m_mal_active = false;
- if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
- m_advance_ip = false;
- }
-
- // Activate the child, and do more work if the parent lives through the
- // birth.
- bool parent_alive = organism->ActivateDivide(ctx);
- if (parent_alive) {
- if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) Reset();
- }
-
+// const int child_size = GetMemory().GetSize() - div_point - extra_lines;
+//
+// // Make sure this divide will produce a viable offspring.
+// const bool viable = Divide_CheckViable(ctx, div_point, child_size);
+// if (viable == false) return false;
+//
+// // Since the divide will now succeed, set up the information to be sent
+// // to the new organism
+// cGenome & child_genome = organism->ChildGenome();
+// child_genome = cGenomeUtil::Crop(m_memory, div_point, div_point+child_size);
+//
+// // Cut off everything in this memory past the divide point.
+// GetMemory().Resize(div_point);
+//
+// // Handle Divide Mutations...
+// Divide_DoMutations(ctx, mut_multiplier);
+//
+// // Many tests will require us to run the offspring through a test CPU;
+// // this is, for example, to see if mutations need to be reverted or if
+// // lineages need to be updated.
+// Divide_TestFitnessMeasures(ctx);
+//
+//#if INSTRUCTION_COSTS
+// // reset first time instruction costs
+// for (int i = 0; i < inst_ft_cost.GetSize(); i++) {
+// inst_ft_cost[i] = m_inst_set->GetFTCost(cInstruction(i));
+// }
+//#endif
+//
+// m_mal_active = false;
+// if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
+// m_advance_ip = false;
+// }
+//
+// // Activate the child
+// bool parent_alive = organism->ActivateDivide(ctx);
+//
+// // Do more work if the parent lives through the birth of the offspring
+// if (parent_alive) {
+// if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) Reset();
+// }
+//
return true;
}
-/*
- Almost the same as Divide_Main, but only allows for one mutation
- on divde and resamples reverted offspring.
- RESAMPLING ONLY WORKS CORRECTLY WHEN ALL MUTIONS OCCUR ON DIVIDE!!
-
- AWC - 07/28/06
-*/
-bool cHardwareGX::Divide_Main1RS(cAvidaContext& ctx, const int div_point,
- const int extra_lines, double mut_multiplier)
-{
-
- //cStats stats = m_world->GetStats();
- const int child_size = GetMemory().GetSize() - div_point - extra_lines;
-
- // Make sure this divide will produce a viable offspring.
- const bool viable = Divide_CheckViable(ctx, div_point, child_size);
- if (viable == false) return false;
-
- // Since the divide will now succeed, set up the information to be sent
- // to the new organism
- cGenome & child_genome = organism->ChildGenome();
- child_genome = cGenomeUtil::Crop(m_memory, div_point, div_point+child_size);
-
- // Cut off everything in this memory past the divide point.
- GetMemory().Resize(div_point);
-
- unsigned
- totalMutations = 0,
- mutations = 0;
- // RScount = 0;
-
- bool
- fitTest = false;
-
-
- // Handle Divide Mutations...
- /*
- Do mutations until one of these conditions are satisified:
- we have resampled X times
- we have an offspring with the same number of muations as the first offspring
- that is not reverted
- the parent is steralized (usually means an implicit mutation)
- */
- for(unsigned i = 0; i < 100; i++){
- if(!i){
- mutations = totalMutations = Divide_DoMutations(ctx, mut_multiplier,1);
- }
- else{
- mutations = Divide_DoExactMutations(ctx, mut_multiplier,1);
- m_world->GetStats().IncResamplings();
- }
-
- fitTest = Divide_TestFitnessMeasures(ctx);
- //if(mutations > 1 ) cerr << "Too Many mutations!!!!!!!!!!!!!!!" << endl;
- if(!fitTest && mutations >= totalMutations) break;
-
- }
- // think about making this mutations == totalMuations - though this may be too hard...
- /*
- if(RScount > 2)
- cerr << "Resampled " << RScount << endl;
- */
- //org could not be resampled beneath the hard cap -- it is then steraalized
- if(fitTest/*RScount == 11*/) {
- organism->GetPhenotype().ChildFertile() = false;
- m_world->GetStats().IncFailedResamplings();
- }
-
-#if INSTRUCTION_COSTS
- // reset first time instruction costs
- for (int i = 0; i < inst_ft_cost.GetSize(); i++) {
- inst_ft_cost[i] = m_inst_set->GetFTCost(cInstruction(i));
- }
-#endif
-
- m_mal_active = false;
- if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
- m_advance_ip = false;
- }
-
- // Activate the child, and do more work if the parent lives through the
- // birth.
- bool parent_alive = organism->ActivateDivide(ctx);
- if (parent_alive) {
- if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) Reset();
- }
-
- return true;
-}
-
-/*
- Almost the same as Divide_Main, but only allows for one mutation
- on divde and resamples reverted offspring.
-
- RESAMPLING ONLY WORKS CORRECTLY WHEN ALL MUTIONS OCCUR ON DIVIDE!!
-
- AWC - 07/28/06
-*/
-bool cHardwareGX::Divide_Main2RS(cAvidaContext& ctx, const int div_point,
- const int extra_lines, double mut_multiplier)
-{
-
- //cStats stats = m_world->GetStats();
- const int child_size = GetMemory().GetSize() - div_point - extra_lines;
-
- // Make sure this divide will produce a viable offspring.
- const bool viable = Divide_CheckViable(ctx, div_point, child_size);
- if (viable == false) return false;
-
- // Since the divide will now succeed, set up the information to be sent
- // to the new organism
- cGenome & child_genome = organism->ChildGenome();
- child_genome = cGenomeUtil::Crop(m_memory, div_point, div_point+child_size);
-
- // Cut off everything in this memory past the divide point.
- GetMemory().Resize(div_point);
-
- unsigned
- totalMutations = 0,
- mutations = 0;
- // RScount = 0;
-
- bool
- fitTest = false;
-
-
- // Handle Divide Mutations...
- /*
- Do mutations until one of these conditions are satisified:
- we have resampled X times
- we have an offspring with the same number of muations as the first offspring
- that is not reverted
- the parent is steralized (usually means an implicit mutation)
- */
- for(unsigned i = 0; i < 100; i++){
- if(!i){
- mutations = totalMutations = Divide_DoMutations(ctx, mut_multiplier,2);
- }
- else{
- Divide_DoExactMutations(ctx, mut_multiplier,mutations);
- m_world->GetStats().IncResamplings();
- }
-
- fitTest = Divide_TestFitnessMeasures(ctx);
- //if(mutations > 1 ) cerr << "Too Many mutations!!!!!!!!!!!!!!!" << endl;
- if(!fitTest && mutations >= totalMutations) break;
-
- }
- // think about making this mutations == totalMuations - though this may be too hard...
- /*
- if(RScount > 2)
- cerr << "Resampled " << RScount << endl;
- */
- //org could not be resampled beneath the hard cap -- it is then steraalized
- if(fitTest/*RScount == 11*/) {
- organism->GetPhenotype().ChildFertile() = false;
- m_world->GetStats().IncFailedResamplings();
- }
-
-#if INSTRUCTION_COSTS
- // reset first time instruction costs
- for (int i = 0; i < inst_ft_cost.GetSize(); i++) {
- inst_ft_cost[i] = m_inst_set->GetFTCost(cInstruction(i));
- }
-#endif
-
- m_mal_active = false;
- if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) {
- m_advance_ip = false;
- }
-
- // Activate the child, and do more work if the parent lives through the
- // birth.
- bool parent_alive = organism->ActivateDivide(ctx);
- if (parent_alive) {
- if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) Reset();
- }
-
- return true;
-}
-
-
//////////////////////////
// And the instructions...
//////////////////////////
@@ -1613,55 +1281,7 @@
return true;
}
-bool cHardwareGX::Inst_JumpF(cAvidaContext& ctx)
-{
- ReadLabel();
- GetLabel().Rotate(1, NUM_NOPS);
-
- // If there is no label, jump BX steps.
- if (GetLabel().GetSize() == 0) {
- GetActiveHead().Jump(GetRegister(REG_BX));
- return true;
- }
-
- // Otherwise, try to jump to the complement label.
- const cHeadCPU jump_location(FindLabel(1));
- if ( jump_location.GetPosition() != -1 ) {
- GetActiveHead().Set(jump_location);
- return true;
- }
-
- // If complement label was not found; record an error.
- organism->Fault(FAULT_LOC_JUMP, FAULT_TYPE_ERROR,
- "jump-f: No complement label");
- return false;
-}
-
-bool cHardwareGX::Inst_JumpB(cAvidaContext& ctx)
-{
- ReadLabel();
- GetLabel().Rotate(1, NUM_NOPS);
-
- // If there is no label, jump BX steps.
- if (GetLabel().GetSize() == 0) {
- GetActiveHead().Jump(GetRegister(REG_BX));
- return true;
- }
-
- // otherwise jump to the complement label.
- const cHeadCPU jump_location(FindLabel(-1));
- if ( jump_location.GetPosition() != -1 ) {
- GetActiveHead().Set(jump_location);
- return true;
- }
-
- // If complement label was not found; record an error.
- organism->Fault(FAULT_LOC_JUMP, FAULT_TYPE_ERROR,
- "jump-b: No complement label");
- return false;
-}
-
bool cHardwareGX::Inst_Call(cAvidaContext& ctx)
{
// Put the starting location onto the stack
@@ -2327,32 +1947,7 @@
} else return false;
}
-bool cHardwareGX::Inst_Divide(cAvidaContext& ctx)
-{
- const int src = REG_AX;
- return Divide_Main(ctx, GetRegister(src));
-}
-/*
- Divide with resampling -- Same as regular divide but on reversions will be
- resampled after they are reverted.
-
- AWC 06/29/06
-
- */
-
-bool cHardwareGX::Inst_DivideRS(cAvidaContext& ctx)
-{
- const int src = REG_AX;
- return Divide_MainRS(ctx, GetRegister(src));
-}
-
-
-bool cHardwareGX::Inst_CDivide(cAvidaContext& ctx)
-{
- return Divide_Main(ctx, GetMemory().GetSize() / 2);
-}
-
bool cHardwareGX::Inst_CAlloc(cAvidaContext& ctx)
{
return Allocate_Main(ctx, GetMemory().GetSize());
@@ -2370,139 +1965,7 @@
} else return false;
}
-bool cHardwareGX::Inst_Transposon(cAvidaContext& ctx)
-{
- ReadLabel();
- //organism->GetPhenotype().ActivateTransposon(GetLabel());
- return true;
-}
-void cHardwareGX::Divide_DoTransposons(cAvidaContext& ctx)
-{
- // This only works if 'transposon' is in the current instruction set
- static bool transposon_in_use = GetInstSet().InstInSet(cStringUtil::Stringf("transposon"));
- if (!transposon_in_use) return;
-
- static cInstruction transposon_inst = GetInstSet().GetInst(cStringUtil::Stringf("transposon"));
- cCPUMemory& child_genome = organism->ChildGenome();
-
- // Count the number of transposons that are marked as executed
- int tr_count = 0;
- for (int i=0; i < child_genome.GetSize(); i++)
- {
- if (child_genome.FlagExecuted(i) && (child_genome[i] == transposon_inst)) tr_count++;
- }
-
- for (int i=0; i < tr_count; i++)
- {
- if (ctx.GetRandom().P(0.01))
- {
- const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
- child_genome.Insert(mut_line, transposon_inst);
- }
- }
-
-
-/*
- const tArray<cCodeLabel> tr = organism->GetPhenotype().GetActiveTransposons();
- cCPUMemory& child_genome = organism->ChildGenome();
-
- for (int i=0; i < tr.GetSize(); i++)
- {
- if (ctx.GetRandom().P(0.1))
- {
- const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
- child_genome.Insert(mut_line, transposon_inst);
- }
- }
-*/
-}
-
-bool cHardwareGX::Inst_Repro(cAvidaContext& ctx)
-{
- // const bool viable = Divide_CheckViable(ctx, div_point, child_size);
- // these checks should be done, but currently they make some assumptions
- // that crash when evaluating this kind of organism -- JEB
-
- // Setup child
- cCPUMemory& child_genome = organism->ChildGenome();
- child_genome = GetMemory();
- organism->GetPhenotype().SetLinesCopied(GetMemory().GetSize());
-
- // @JEB - Make sure that an organism has accumulated any required bonus
- const int bonus_required = m_world->GetConfig().REQUIRED_BONUS.Get();
- if (organism->GetPhenotype().GetCurBonus() < bonus_required) {
- return false; // (divide fails)
- }
-
- int lines_executed = 0;
- for ( int i = 0; i < GetMemory().GetSize(); i++ ) {
- if ( GetMemory().FlagExecuted(i)) lines_executed++;
- }
- organism->GetPhenotype().SetLinesExecuted(lines_executed);
-
- // Do transposon movement and copying before other mutations
- Divide_DoTransposons(ctx);
-
- // Perform Copy Mutations...
- if (organism->GetCopyMutProb() > 0) { // Skip this if no mutations....
- for (int i = 0; i < GetMemory().GetSize(); i++) {
- if (organism->TestCopyMut(ctx)) {
- child_genome[i] = m_inst_set->GetRandomInst(ctx);
- //organism->GetPhenotype().IsMutated() = true;
- }
- }
- }
- Divide_DoMutations(ctx);
-
- // Many tests will require us to run the offspring through a test CPU;
- // this is, for example, to see if mutations need to be reverted or if
- // lineages need to be updated.
- Divide_TestFitnessMeasures(ctx);
-
-#if INSTRUCTION_COSTS
- // reset first time instruction costs
- for (int i = 0; i < inst_ft_cost.GetSize(); i++) {
- inst_ft_cost[i] = m_inst_set->GetFTCost(cInstruction(i));
- }
-#endif
-
- if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) m_advance_ip = false;
-
- organism->ActivateDivide(ctx);
-
- //Reset the parent
- if (m_world->GetConfig().DIVIDE_METHOD.Get() == DIVIDE_METHOD_SPLIT) Reset();
-
- return true;
-}
-
-bool cHardwareGX::Inst_TaskPutRepro(cAvidaContext& ctx)
-{
- // Do normal IO, but don't zero register
- //Inst_TaskPut(ctx);
-
- const int reg_used = FindModifiedRegister(REG_BX);
- const int value = GetRegister(reg_used);
- // GetRegister(reg_used) = 0;
- organism->DoOutput(ctx, value);
-
- // Immediately attempt a repro
- return Inst_Repro(ctx);
-}
-
-bool cHardwareGX::Inst_TaskPutResetInputsRepro(cAvidaContext& ctx)
-{
- // Do normal IO
- bool return_value = Inst_TaskPutResetInputs(ctx);
-
- // Immediately attempt a repro
- Inst_Repro(ctx);
-
- // return value of put since successful repro would wipe state anyway
- return return_value;
-}
-
bool cHardwareGX::Inst_SpawnDeme(cAvidaContext& ctx)
{
organism->SpawnDeme();
@@ -2598,61 +2061,7 @@
return true;
}
-// The inject instruction can be used instead of a divide command, paired
-// with an allocate. Note that for an inject to work, one needs to have a
-// broad range for sizes allowed to be allocated.
-//
-// This command will cut out from read-head to write-head.
-// It will then look at the template that follows the command and inject it
-// into the complement template found in a neighboring organism.
-bool cHardwareGX::Inst_InjectThread(cAvidaContext& ctx)
-{
- AdjustHeads();
- const int start_pos = GetHead(nHardware::HEAD_READ).GetPosition();
- const int end_pos = GetHead(nHardware::HEAD_WRITE).GetPosition();
- const int inject_size = end_pos - start_pos;
-
- // Make sure the creature will still be above the minimum size,
- if (inject_size <= 0) {
- organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
- return false; // (inject fails)
- }
- if (start_pos < MIN_CREATURE_SIZE) {
- organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
- return false; // (inject fails)
- }
-
- // Since its legal to cut out the injected piece, do so.
- cGenome inject_code( cGenomeUtil::Crop(GetMemory(), start_pos, end_pos) );
- GetMemory().Remove(start_pos, inject_size);
-
- // If we don't have a host, stop here.
- cOrganism * host_organism = organism->GetNeighbor();
- if (host_organism == NULL) return false;
-
- // Scan for the label to match...
- ReadLabel();
-
- // If there is no label, abort.
- if (GetLabel().GetSize() == 0) {
- organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: label required");
- return false; // (inject fails)
- }
-
- // Search for the label in the host...
- GetLabel().Rotate(1, NUM_NOPS);
-
- if (host_organism->GetHardware().InjectHost(GetLabel(), inject_code)) {
- if (ForkThread()) organism->GetPhenotype().IsMultiThread() = true;
- }
-
- // Set the relevent flags.
- organism->GetPhenotype().IsModifier() = true;
-
- return true;
-}
-
bool cHardwareGX::Inst_TaskGet(cAvidaContext& ctx)
{
const int reg_used = FindModifiedRegister(REG_CX);
@@ -3196,38 +2605,15 @@
return true;
}
-// Multi-threading.
-bool cHardwareGX::Inst_ForkThread(cAvidaContext& ctx)
-{
- IP().Advance();
- if (!ForkThread()) organism->Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
- return true;
-}
-
-bool cHardwareGX::Inst_KillThread(cAvidaContext& ctx)
-{
- if (!KillThread()) organism->Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
- else m_advance_ip = false;
- return true;
-}
-
-bool cHardwareGX::Inst_ThreadID(cAvidaContext& ctx)
-{
- const int reg_used = FindModifiedRegister(REG_BX);
- GetRegister(reg_used) = GetCurThreadID();
- return true;
-}
-
-
// Head-based instructions
-bool cHardwareGX::Inst_SetHead(cAvidaContext& ctx)
-{
- const int head_used = FindModifiedHead(nHardware::HEAD_IP);
- m_threads[m_cur_thread].cur_head = static_cast<unsigned char>(head_used);
- return true;
-}
+//bool cHardwareGX::Inst_SetHead(cAvidaContext& ctx)
+//{
+// const int head_used = FindModifiedHead(nHardware::HEAD_IP);
+// m_threads[m_cur_thread].cur_head = static_cast<unsigned char>(head_used);
+// return true;
+//}
bool cHardwareGX::Inst_AdvanceHead(cAvidaContext& ctx)
{
@@ -3283,136 +2669,13 @@
return true;
}
-bool cHardwareGX::Inst_HeadDivideMut(cAvidaContext& ctx, double mut_multiplier)
-{
- AdjustHeads();
- const int divide_pos = GetHead(nHardware::HEAD_READ).GetPosition();
- int child_end = GetHead(nHardware::HEAD_WRITE).GetPosition();
- if (child_end == 0) child_end = GetMemory().GetSize();
- const int extra_lines = GetMemory().GetSize() - child_end;
- bool ret_val = Divide_Main(ctx, divide_pos, extra_lines, mut_multiplier);
- // Re-adjust heads.
- AdjustHeads();
- return ret_val;
-}
bool cHardwareGX::Inst_HeadDivide(cAvidaContext& ctx)
{
- return Inst_HeadDivideMut(ctx, 1);
-
+ return Divide_Main(ctx);
}
-/*
- Resample Divide -- AWC 06/29/06
-*/
-bool cHardwareGX::Inst_HeadDivideRS(cAvidaContext& ctx)
-{
- AdjustHeads();
- const int divide_pos = GetHead(nHardware::HEAD_READ).GetPosition();
- int child_end = GetHead(nHardware::HEAD_WRITE).GetPosition();
- if (child_end == 0) child_end = GetMemory().GetSize();
- const int extra_lines = GetMemory().GetSize() - child_end;
- bool ret_val = Divide_MainRS(ctx, divide_pos, extra_lines, 1);
- // Re-adjust heads.
- AdjustHeads();
- return ret_val;
-}
-
-/*
- Resample Divide -- single mut on divide-- AWC 07/28/06
-*/
-
-bool cHardwareGX::Inst_HeadDivide1RS(cAvidaContext& ctx)
-{
- AdjustHeads();
- const int divide_pos = GetHead(nHardware::HEAD_READ).GetPosition();
- int child_end = GetHead(nHardware::HEAD_WRITE).GetPosition();
- if (child_end == 0) child_end = GetMemory().GetSize();
- const int extra_lines = GetMemory().GetSize() - child_end;
- bool ret_val = Divide_Main1RS(ctx, divide_pos, extra_lines, 1);
- // Re-adjust heads.
- AdjustHeads();
- return ret_val;
-}
-
-/*
- Resample Divide -- double mut on divide-- AWC 08/29/06
-*/
-
-bool cHardwareGX::Inst_HeadDivide2RS(cAvidaContext& ctx)
-{
- AdjustHeads();
- const int divide_pos = GetHead(nHardware::HEAD_READ).GetPosition();
- int child_end = GetHead(nHardware::HEAD_WRITE).GetPosition();
- if (child_end == 0) child_end = GetMemory().GetSize();
- const int extra_lines = GetMemory().GetSize() - child_end;
- bool ret_val = Divide_Main2RS(ctx, divide_pos, extra_lines, 1);
- // Re-adjust heads.
- AdjustHeads();
- return ret_val;
-}
-
-
-bool cHardwareGX::Inst_HeadDivideSex(cAvidaContext& ctx)
-{
- organism->GetPhenotype().SetDivideSex(true);
- organism->GetPhenotype().SetCrossNum(1);
- return Inst_HeadDivide(ctx);
-}
-
-bool cHardwareGX::Inst_HeadDivideAsex(cAvidaContext& ctx)
-{
- organism->GetPhenotype().SetDivideSex(false);
- organism->GetPhenotype().SetCrossNum(0);
- return Inst_HeadDivide(ctx);
-}
-
-bool cHardwareGX::Inst_HeadDivideAsexWait(cAvidaContext& ctx)
-{
- organism->GetPhenotype().SetDivideSex(true);
- organism->GetPhenotype().SetCrossNum(0);
- return Inst_HeadDivide(ctx);
-}
-
-bool cHardwareGX::Inst_HeadDivideMateSelect(cAvidaContext& ctx)
-{
- // Take the label that follows this divide and use it as the ID for which
- // other organisms this one is willing to mate with.
- ReadLabel();
- organism->GetPhenotype().SetMateSelectID( GetLabel().AsInt(NUM_NOPS) );
-
- // Proceed as normal with the rest of mate selection.
- organism->GetPhenotype().SetDivideSex(true);
- organism->GetPhenotype().SetCrossNum(1);
- return Inst_HeadDivide(ctx);
-}
-
-bool cHardwareGX::Inst_HeadDivide1(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 1); }
-bool cHardwareGX::Inst_HeadDivide2(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 2); }
-bool cHardwareGX::Inst_HeadDivide3(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 3); }
-bool cHardwareGX::Inst_HeadDivide4(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 4); }
-bool cHardwareGX::Inst_HeadDivide5(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 5); }
-bool cHardwareGX::Inst_HeadDivide6(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 6); }
-bool cHardwareGX::Inst_HeadDivide7(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 7); }
-bool cHardwareGX::Inst_HeadDivide8(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 8); }
-bool cHardwareGX::Inst_HeadDivide9(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 9); }
-bool cHardwareGX::Inst_HeadDivide10(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 10); }
-bool cHardwareGX::Inst_HeadDivide16(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 16); }
-bool cHardwareGX::Inst_HeadDivide32(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 32); }
-bool cHardwareGX::Inst_HeadDivide50(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 50); }
-bool cHardwareGX::Inst_HeadDivide100(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 100); }
-bool cHardwareGX::Inst_HeadDivide500(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 500); }
-bool cHardwareGX::Inst_HeadDivide1000(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 1000); }
-bool cHardwareGX::Inst_HeadDivide5000(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 5000); }
-bool cHardwareGX::Inst_HeadDivide10000(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 10000); }
-bool cHardwareGX::Inst_HeadDivide50000(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 50000); }
-bool cHardwareGX::Inst_HeadDivide0_5(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 0.5); }
-bool cHardwareGX::Inst_HeadDivide0_1(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 0.1); }
-bool cHardwareGX::Inst_HeadDivide0_05(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 0.05); }
-bool cHardwareGX::Inst_HeadDivide0_01(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 0.01); }
-bool cHardwareGX::Inst_HeadDivide0_001(cAvidaContext& ctx) { return Inst_HeadDivideMut(ctx, 0.001); }
-
bool cHardwareGX::Inst_HeadRead(cAvidaContext& ctx)
{
const int dst = REG_BX;
@@ -3554,3 +2817,96 @@
return true;
}
+
+/*! This instruction reads the trailing label and tries to match it against other
+programids in the CPU. Note: labels that follow a match instruction in the
+programid to be matched against are *ignored*. Note that match should be a
+'free' instruction, that is, it should not cost anything to execute.
+
+\todo Determine if Inst_Match should wait for a match, as opposed to letting the
+cProgramid continue. This seems like a good idea...
+
+\todo Have to determine the correct placement of the heads on Bind. If we're not
+careful, we'll allow two RNAPs to bind to each other and start copying each other's
+genome. Probably a bad idea.
+*/
+bool cHardwareGX::Inst_Match(cAvidaContext& ctx) {
+ // Get the label that we're trying to match.
+ ReadLabel();
+
+ // Now, select another programid to match against. To start with, let's
+ // look at all our programids and pick the first one that matches. This will
+ // need to be revisited.
+ for(programid_list::iterator i=m_programids.begin(); i!=m_programids.end(); ++i) {
+ std::pair<bool, cMatchSite> match = (*i)->Matches(GetLabel());
+
+ if(match.first == true) {
+ // Ok, it matched. Bind the current programid to the matched site.
+ // For right now, we only support read-head binding.
+ m_current->Bind(nHardware::HEAD_READ, match.second);
+
+ // And we're done.
+ return true;
+ }
+ }
+
+ // If nothing matched, we're done; but the instruction didn't really work.
+ return false;
+}
+
+
+/*! This instruction runs asynchronously compared to the rest of the cProgramid,
+and it is exectued ONLY when a cProgramid disassociates from another. cProgramids
+are not required to have this instruction in their genome.
+
+IF a cProgramid disassociates AND it has this instruction, then its HEAD_IP is
+updated to point to this instruction.
+
+\todo What if a cProgramid has multiple Inst_OnDisassociates?
+*/
+bool cHardwareGX::Inst_OnDisassociate(cAvidaContext& ctx) {
+ return false;
+}
+
+
+/*! Construct this cProgramid, and initialize hardware resources.
+*/
+cHardwareGX::cProgramid::cProgramid(const cGenome& genome, cHardwareBase* cpu)
+: m_offspring(0)
+, m_memory(genome) {
+ for(int i=0; i<NUM_HEADS; ++i) {
+ m_heads[i].Reset(cpu);
+ }
+}
+
+
+/*! This method attempts to match this cProgramid with the passed-in label. If the
+match is succesful, it returns true and a cMatchSite object that may be used to bind
+to the programid. If the match is unsuccessful, it return false and the cMatchSite
+object points to null.
+
+A "successful" match is one where this cProgramid has a series of NOPs that are similar
+to the the passed-in label. A number of configuration options (will eventually)
+control how precisely the NOPs must be related (e.g., exact, all-but-one, etc.).
+*/
+std::pair<bool, cHardwareGX::cMatchSite> cHardwareGX::cProgramid::Matches(const cCodeLabel& label) {
+ return std::make_pair(false, cMatchSite());
+}
+
+
+/*! Bind attaches parts of this cProgramid to the cProgramid specified in the
+passed-in cMatchSite. Currently, we only support binding the read head to a
+location in the genome of the other cProgramid, but this will be extended later.
+*/
+void cHardwareGX::cProgramid::Bind(nHardware::tHeads head, cMatchSite& site) {
+}
+
+
+/*! Disassociate is called when this cProgramids's read head traverses over the
+complement of the label that was used to Bind this cProgramid to another. When
+called, Disassociate removes this cProgramid's read head from the bound cProgramid,
+searches for an Inst_OnDisassociate in its own genome, and, if found, updates this
+cProgramid's IP to point to it.
+*/
+void cHardwareGX::cProgramid::Disassociate() {
+}
Modified: development/source/cpu/cHardwareGX.h
===================================================================
--- development/source/cpu/cHardwareGX.h 2007-04-27 02:49:56 UTC (rev 1504)
+++ development/source/cpu/cHardwareGX.h 2007-04-27 03:48:40 UTC (rev 1505)
@@ -2,6 +2,25 @@
* cHardwareGX.h
* Avida
*
+ * cHardwareGX enables gene expression as follows:
+ * 1) Unlike cHardware{CPU,SMT,TransSMT}, the genome is not directly
+ * executed by this organism. Instead, cHardwareGX enables portions of the
+ * genome to be transcribed into "programids," which are able to execute
+ * independently.
+ * 2) The interaction between programids within cHardwareGX is based on
+ * pattern-matching different genome fragments. Each programid is able to
+ * specify a "match" that will be probabilistically compared against other
+ * programids. When (if) a match is found, those two programids "bind"
+ * together. Different actions may be taken on bind, depending on the
+ * type of match performed.
+ *
+ * \todo cHardwareGX is really not a new CPU architecture, but rather a way for
+ * CPUs to interact. It's much easier, however, to start off by implementing a
+ * new CPU, so that's what we're doing. Eventually we'll need to revisit this.
+ *
+ * \todo There should be better ways for promoter regions to work. Right now,
+ * we stop at the first one encountered.
+ *
* Copyright 1999-2007 Michigan State University. All rights reserved.
*
* This program is free software; you can redistribute it and/or
@@ -24,6 +43,7 @@
#include <iomanip>
#include <vector>
+#include <utility>
#include "cCodeLabel.h"
#include "cHeadCPU.h"
#include "cCPUMemory.h"
@@ -51,58 +71,72 @@
class cHardwareGX : public cHardwareBase
{
public:
- typedef bool (cHardwareGX::*tMethod)(cAvidaContext& ctx);
+ typedef bool (cHardwareGX::*tMethod)(cAvidaContext& ctx); //!< Instruction type.
-protected:
- // -------- Structure Constants --------
- static const int NUM_REGISTERS = 3;
+ static const int NUM_REGISTERS = 3; //!< Number of registers each cProgramid has.
+ //! Number of heads each cProgramid has.
static const int NUM_HEADS = nHardware::NUM_HEADS >= NUM_REGISTERS ? nHardware::NUM_HEADS : NUM_REGISTERS;
- enum tRegisters { REG_AX = 0, REG_BX, REG_CX, REG_DX, REG_EX, REG_FX };
- static const int NUM_NOPS = 3;
+ static const int NUM_NOPS = 3; //!< Number of NOPS that cHardwareGX supports.
+
+ //! Enums for the different supported registers.
+ enum tRegisters { REG_AX=0, REG_BX, REG_CX };
- // -------- Data Structures --------
- struct cLocalThread
- {
- private:
- int m_id;
+ struct cProgramid; // pre-declaration.
+ typedef cProgramid* programid_ptr; //!< It would be nice to change this to boost::shared_ptr.
+ typedef std::vector<programid_ptr> programid_list; //!< Type for the list of cProgramids.
+
+ //! cMatchSite holds a couple useful pointers for cProgramid::Match, Bind.
+ struct cMatchSite {
+ cMatchSite() : m_programid(0), m_site(0) { }
+ cProgramid* m_programid; //!< The programid matched against; 0 if not matched.
+ cInstruction* m_site; //!< Location in the cProgramid where a match occurred; 0 if not matched.
+ cCodeLabel m_label; //!< The label that was matched against.
+ };
+
+ /*! cProgramid is the "heart" of the gene expression hardware. It encapsulates
+ the genome fragment that is used by both active and passive elements within
+ this organism, and enables these fragments to match against, and bind to, each
+ other depending on their particular instruction sequence.
- public:
- int reg[NUM_REGISTERS];
- cHeadCPU heads[NUM_HEADS];
- cCPUStack stack;
- unsigned char cur_stack; // 0 = local stack, 1 = global stack.
- unsigned char cur_head;
+ It is similar in spirit to a thread, but has certain operational characteristics
+ that make it unique (e.g., matching, disassociation, and a self-contained genome
+ fragment).
- cCodeLabel read_label;
- cCodeLabel next_label;
+ \todo Need to rework cHeadCPU to not need a pointer to cHardwareBase.
+ */
+ struct cProgramid {
+ //! Constructs a cProgramid from a genome and CPU.
+ cProgramid(const cGenome& genome, cHardwareBase* cpu);
+ //! Returns whether and where this cProgramid matches the passed-in label.
+ std::pair<bool, cMatchSite> Matches(const cCodeLabel& label);
+ //! Binds one of this cProgramid's heads to the passed-in match site.
+ void Bind(nHardware::tHeads head, cMatchSite& site);
+ //! Called when this cProgramid "falls off" the cProgramid it is bound to.
+ void Disassociate();
-
- cLocalThread(cHardwareBase* in_hardware = NULL, int in_id = -1) { Reset(in_hardware, in_id); }
- ~cLocalThread() { ; }
-
- void operator=(const cLocalThread& in_thread);
-
- void Reset(cHardwareBase* in_hardware, int in_id);
- int GetID() const { return m_id; }
- void SetID(int in_id) { m_id = in_id; }
+ programid_ptr m_offspring; //!< An offspring of this cProgramid; may be null.
+ cCodeLabel m_terminator; //!< The label that this cProgramid must traverse to disassociate.
+ cCodeLabel m_readLabel; //!< ?
+ cCodeLabel m_nextLabel; //!< ?
+ cCPUMemory m_memory; //!< This cProgramid's genome fragment.
+ cCPUStack m_stack; //!< This cProgramid's stack (no global stack).
+ cHeadCPU m_heads[NUM_HEADS]; //!< This cProgramid's heads.
+ int m_regs[NUM_REGISTERS]; //!< This cProgramid's registers.
};
+
-
- // -------- Static Variables --------
- static tInstLib<tMethod>* s_inst_slib;
- static tInstLib<tMethod>* initInstLib(void);
+
+protected:
+ static tInstLib<tMethod>* initInstLib(void); //!< Initialize the instruction library.
+ static tInstLib<tMethod>* s_inst_slib; //!< Instruction library (method pointers for all instructions).
+ programid_list m_programids; //!< The list of cProgramids.
+ programid_ptr m_current; //!< The currently-executing cProgramid.
+
// -------- Member Variables --------
const tMethod* m_functions;
- cCPUMemory m_memory; // Memory...
- cCPUStack m_global_stack; // A stack that all threads share.
-
- tArray<cLocalThread> m_threads;
- int m_thread_id_chart;
- int m_cur_thread;
-
// Flags...
bool m_mal_active; // Has an allocate occured since last divide?
bool m_advance_ip; // Should the IP advance after this instruction?
@@ -119,35 +153,26 @@
bool SingleProcess_ExecuteInst(cAvidaContext& ctx, const cInstruction& cur_inst);
// -------- Stack Manipulation... --------
- inline void StackPush(int value);
- inline int StackPop();
- inline void StackFlip();
- inline void StackClear();
- inline void SwitchStack();
+ inline void StackPush(int value) { m_current->m_stack.Push(value); }
+ inline int StackPop() { return m_current->m_stack.Pop(); }
+ inline void StackFlip() { m_current->m_stack.Flip(); }
+ inline void StackClear() { m_current->m_stack.Clear(); }
+ inline void SwitchStack() { }
-
// -------- Head Manipulation (including IP) --------
- cHeadCPU& GetActiveHead() { return m_threads[m_cur_thread].heads[m_threads[m_cur_thread].cur_head]; }
void AdjustHeads();
-
// -------- Label Manipulation -------
- const cCodeLabel& GetLabel() const { return m_threads[m_cur_thread].next_label; }
- cCodeLabel& GetLabel() { return m_threads[m_cur_thread].next_label; }
+ const cCodeLabel& GetLabel() const { return m_current->m_nextLabel; }
+ cCodeLabel& GetLabel() { return m_current->m_nextLabel; }
void ReadLabel(int max_size=nHardware::MAX_LABEL_SIZE);
cHeadCPU FindLabel(int direction);
int FindLabel_Forward(const cCodeLabel & search_label, const cGenome& search_genome, int pos);
int FindLabel_Backward(const cCodeLabel & search_label, const cGenome& search_genome, int pos);
cHeadCPU FindLabel(const cCodeLabel & in_label, int direction);
- const cCodeLabel& GetReadLabel() const { return m_threads[m_cur_thread].read_label; }
- cCodeLabel& GetReadLabel() { return m_threads[m_cur_thread].read_label; }
-
-
- // -------- Thread Manipulation -------
- bool ForkThread(); // Adds a new thread based off of m_cur_thread.
- bool KillThread(); // Kill the current thread!
-
-
+ const cCodeLabel& GetReadLabel() const { return m_current->m_readLabel; }
+ cCodeLabel& GetReadLabel() { return m_current->m_readLabel; }
+
// ---------- Instruction Helpers -----------
int FindModifiedRegister(int default_register);
int FindModifiedNextRegister(int default_register);
@@ -161,28 +186,16 @@
bool Allocate_Main(cAvidaContext& ctx, const int allocated_size);
int GetCopiedSize(const int parent_size, const int child_size);
-
- bool Divide_Main(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1);
- bool Divide_MainRS(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1); //AWC 06/29/06
- bool Divide_Main1RS(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1); //AWC 07/28/06
- bool Divide_Main2RS(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1); //AWC 07/28/06
-
- void Divide_DoTransposons(cAvidaContext& ctx);
-
+ bool Divide_Main(cAvidaContext& ctx);
void InjectCode(const cGenome& injection, const int line_num);
-
bool HeadCopy_ErrorCorrect(cAvidaContext& ctx, double reduction);
- bool Inst_HeadDivideMut(cAvidaContext& ctx, double mut_multiplier = 1);
-
void ReadInst(const int in_inst);
-
- cHardwareGX& operator=(const cHardwareGX&); // @not_implemented
-
public:
+ //! Main constructor for cHardwareGX; called from cHardwareManager for every(?) organism.
cHardwareGX(cWorld* world, cOrganism* in_organism, cInstSet* in_inst_set);
- explicit cHardwareGX(const cHardwareGX&);
- ~cHardwareGX() { ; }
+ virtual ~cHardwareGX(); //!< Destructor; removes all cProgramids.
+
static tInstLib<tMethod>* GetInstLib() { return s_inst_slib; }
static cString GetDefaultInstFilename() { return "instset-gx.cfg"; }
@@ -198,60 +211,54 @@
// -------- Stack Manipulation... --------
- inline int GetStack(int depth=0, int stack_id=-1, int in_thread=-1) const;
+ inline int GetStack(int depth=0, int stack_id=-1, int in_thread=-1) const { return m_current->m_stack.Get(depth); }
inline int GetNumStacks() const { return 2; }
-
-
+
// -------- Head Manipulation (including IP) --------
- const cHeadCPU& GetHead(int head_id) const { return m_threads[m_cur_thread].heads[head_id]; }
- cHeadCPU& GetHead(int head_id) { return m_threads[m_cur_thread].heads[head_id];}
- const cHeadCPU& GetHead(int head_id, int thread) const { return m_threads[thread].heads[head_id]; }
- cHeadCPU& GetHead(int head_id, int thread) { return m_threads[thread].heads[head_id];}
+ const cHeadCPU& GetHead(int head_id) const { return m_current->m_heads[head_id]; }
+ cHeadCPU& GetHead(int head_id) { return m_current->m_heads[head_id];}
+ const cHeadCPU& GetHead(int head_id, int thread) const { return m_current->m_heads[head_id]; }
+ cHeadCPU& GetHead(int head_id, int thread) { return m_current->m_heads[head_id];}
int GetNumHeads() const { return NUM_HEADS; }
- const cHeadCPU& IP() const { return m_threads[m_cur_thread].heads[nHardware::HEAD_IP]; }
- cHeadCPU& IP() { return m_threads[m_cur_thread].heads[nHardware::HEAD_IP]; }
- const cHeadCPU& IP(int thread) const { return m_threads[thread].heads[nHardware::HEAD_IP]; }
- cHeadCPU& IP(int thread) { return m_threads[thread].heads[nHardware::HEAD_IP]; }
+ const cHeadCPU& IP() const { return m_current->m_heads[nHardware::HEAD_IP]; }
+ cHeadCPU& IP() { return m_current->m_heads[nHardware::HEAD_IP]; }
+ const cHeadCPU& IP(int thread) const { return m_current->m_heads[nHardware::HEAD_IP]; }
+ cHeadCPU& IP(int thread) { return m_current->m_heads[nHardware::HEAD_IP]; }
// -------- Memory Manipulation --------
- const cCPUMemory& GetMemory() const { return m_memory; }
- cCPUMemory& GetMemory() { return m_memory; }
- const cCPUMemory& GetMemory(int value) const { return m_memory; }
- cCPUMemory& GetMemory(int value) { return m_memory; }
+ const cCPUMemory& GetMemory() const { return m_current->m_memory; }
+ cCPUMemory& GetMemory() { return m_current->m_memory; }
+ const cCPUMemory& GetMemory(int value) const { return m_current->m_memory; }
+ cCPUMemory& GetMemory(int value) { return m_current->m_memory; }
int GetNumMemSpaces() const { return 1; }
// -------- Register Manipulation --------
- const int GetRegister(int reg_id) const { return m_threads[m_cur_thread].reg[reg_id]; }
- int& GetRegister(int reg_id) { return m_threads[m_cur_thread].reg[reg_id]; }
- int GetNumRegisters() const { return NUM_REGISTERS; }
-
+ const int GetRegister(int reg_id) const { return m_current->m_regs[reg_id]; }
+ int& GetRegister(int reg_id) { return m_current->m_regs[reg_id]; }
+ int GetNumRegisters() const { return NUM_REGISTERS; }
- // -------- Thread Manipulation --------
- bool ThreadSelect(const int thread_num);
- bool ThreadSelect(const cCodeLabel& in_label) { return false; } // Labeled threads not supported
- inline void ThreadPrev(); // Shift the current thread in use.
- inline void ThreadNext();
- cInjectGenotype* ThreadGetOwner() { return NULL; } // @DMB - cHardwareGX does not really implement cInjectGenotype yet
- void ThreadSetOwner(cInjectGenotype* in_genotype) { return; }
+ // -------- Thread Manipuluation --------
+ /* cHardwareGX does not support threads (at least, not as in other CPUs). */
+ virtual bool ThreadSelect(const int thread_id) { return false; }
+ virtual bool ThreadSelect(const cCodeLabel& in_label) { return false; }
+ virtual void ThreadPrev() { }
+ virtual void ThreadNext() { }
+ virtual cInjectGenotype* ThreadGetOwner() { return 0; }
+ virtual void ThreadSetOwner(cInjectGenotype* in_genotype) { }
- int GetNumThreads() const { return m_threads.GetSize(); }
- int GetCurThread() const { return m_cur_thread; }
- int GetCurThreadID() const { return m_threads[m_cur_thread].GetID(); }
+ virtual int GetNumThreads() const { return -1; }
+ virtual int GetCurThread() const { return -1; }
+ virtual int GetCurThreadID() const { return -1; }
-
- // -------- Parasite Stuff --------
bool InjectHost(const cCodeLabel& in_label, const cGenome& injection);
-
- // Non-Standard Methods
-
- int GetActiveStack() const { return m_threads[m_cur_thread].cur_stack; }
- bool GetMalActive() const { return m_mal_active; }
-
private:
+ cHardwareGX& operator=(const cHardwareGX&); //!< Not implemented.
+ cHardwareGX(const cHardwareGX&); //!< Not implemented.
+
// ---------- Instruction Library -----------
// Flow Control
@@ -272,8 +279,8 @@
bool Inst_IfBNotEqC(cAvidaContext& ctx);
bool Inst_IfANotEqC(cAvidaContext& ctx);
- bool Inst_JumpF(cAvidaContext& ctx);
- bool Inst_JumpB(cAvidaContext& ctx);
+// bool Inst_JumpF(cAvidaContext& ctx);
+// bool Inst_JumpB(cAvidaContext& ctx);
bool Inst_Call(cAvidaContext& ctx);
bool Inst_Return(cAvidaContext& ctx);
@@ -357,18 +364,10 @@
bool Inst_Compare(cAvidaContext& ctx);
bool Inst_IfNCpy(cAvidaContext& ctx);
bool Inst_Allocate(cAvidaContext& ctx);
- bool Inst_Divide(cAvidaContext& ctx);
- bool Inst_DivideRS(cAvidaContext& ctx); // AWC 06/29/06
bool Inst_CAlloc(cAvidaContext& ctx);
- bool Inst_CDivide(cAvidaContext& ctx);
bool Inst_MaxAlloc(cAvidaContext& ctx);
bool Inst_Inject(cAvidaContext& ctx);
bool Inst_InjectRand(cAvidaContext& ctx);
- bool Inst_InjectThread(cAvidaContext& ctx);
- bool Inst_Transposon(cAvidaContext& ctx);
- bool Inst_Repro(cAvidaContext& ctx);
- bool Inst_TaskPutRepro(cAvidaContext& ctx);
- bool Inst_TaskPutResetInputsRepro(cAvidaContext& ctx);
bool Inst_SpawnDeme(cAvidaContext& ctx);
bool Inst_Kazi(cAvidaContext& ctx);
@@ -405,25 +404,15 @@
bool Inst_MemSize(cAvidaContext& ctx);
// Environment
-
bool Inst_RotateL(cAvidaContext& ctx);
bool Inst_RotateR(cAvidaContext& ctx);
bool Inst_SetCopyMut(cAvidaContext& ctx);
bool Inst_ModCopyMut(cAvidaContext& ctx);
// Energy use
-
bool Inst_ZeroEnergyUsed(cAvidaContext& ctx);
- // Multi-threading...
-
- bool Inst_ForkThread(cAvidaContext& ctx);
- bool Inst_KillThread(cAvidaContext& ctx);
- bool Inst_ThreadID(cAvidaContext& ctx);
-
// Head-based instructions...
-
- bool Inst_SetHead(cAvidaContext& ctx);
bool Inst_AdvanceHead(cAvidaContext& ctx);
bool Inst_MoveHead(cAvidaContext& ctx);
bool Inst_JumpHead(cAvidaContext& ctx);
@@ -431,9 +420,6 @@
bool Inst_IfLabel(cAvidaContext& ctx);
bool Inst_IfLabel2(cAvidaContext& ctx);
bool Inst_HeadDivide(cAvidaContext& ctx);
- bool Inst_HeadDivideRS(cAvidaContext& ctx); //AWC 06/29/06
- bool Inst_HeadDivide1RS(cAvidaContext& ctx); //AWC 07/28/06
- bool Inst_HeadDivide2RS(cAvidaContext& ctx); //AWC 08/29/06
bool Inst_HeadRead(cAvidaContext& ctx);
bool Inst_HeadWrite(cAvidaContext& ctx);
bool Inst_HeadCopy(cAvidaContext& ctx);
@@ -450,38 +436,12 @@
bool Inst_HeadCopy9(cAvidaContext& ctx);
bool Inst_HeadCopy10(cAvidaContext& ctx);
- bool Inst_HeadDivideSex(cAvidaContext& ctx);
- bool Inst_HeadDivideAsex(cAvidaContext& ctx);
- bool Inst_HeadDivideAsexWait(cAvidaContext& ctx);
- bool Inst_HeadDivideMateSelect(cAvidaContext& ctx);
-
- bool Inst_HeadDivide1(cAvidaContext& ctx);
- bool Inst_HeadDivide2(cAvidaContext& ctx);
- bool Inst_HeadDivide3(cAvidaContext& ctx);
- bool Inst_HeadDivide4(cAvidaContext& ctx);
- bool Inst_HeadDivide5(cAvidaContext& ctx);
- bool Inst_HeadDivide6(cAvidaContext& ctx);
- bool Inst_HeadDivide7(cAvidaContext& ctx);
- bool Inst_HeadDivide8(cAvidaContext& ctx);
- bool Inst_HeadDivide9(cAvidaContext& ctx);
- bool Inst_HeadDivide10(cAvidaContext& ctx);
- bool Inst_HeadDivide16(cAvidaContext& ctx);
- bool Inst_HeadDivide32(cAvidaContext& ctx);
- bool Inst_HeadDivide50(cAvidaContext& ctx);
- bool Inst_HeadDivide100(cAvidaContext& ctx);
- bool Inst_HeadDivide500(cAvidaContext& ctx);
- bool Inst_HeadDivide1000(cAvidaContext& ctx);
- bool Inst_HeadDivide5000(cAvidaContext& ctx);
- bool Inst_HeadDivide10000(cAvidaContext& ctx);
- bool Inst_HeadDivide50000(cAvidaContext& ctx);
- bool Inst_HeadDivide0_5(cAvidaContext& ctx);
- bool Inst_HeadDivide0_1(cAvidaContext& ctx);
- bool Inst_HeadDivide0_05(cAvidaContext& ctx);
- bool Inst_HeadDivide0_01(cAvidaContext& ctx);
- bool Inst_HeadDivide0_001(cAvidaContext& ctx);
-
//// Placebo ////
bool Inst_Skip(cAvidaContext& ctx);
+
+ // -= Gene expression instructions =-
+ bool Inst_Match(cAvidaContext& ctx); //!< Attempt to match the currently executing cProgramid against other cProgramids.
+ bool Inst_OnDisassociate(cAvidaContext& ctx); //!< Called automatically when a cProgramid disassociates.
};
@@ -494,89 +454,6 @@
**/
void UnitTests(bool full = false);
}
-#endif
+#endif
-
-inline bool cHardwareGX::ThreadSelect(const int thread_num)
-{
- if (thread_num >= 0 && thread_num < m_threads.GetSize()) {
- m_cur_thread = thread_num;
- return true;
- }
-
- return false;
-}
-
-inline void cHardwareGX::ThreadNext()
-{
- m_cur_thread++;
- if (m_cur_thread >= GetNumThreads()) m_cur_thread = 0;
-}
-
-inline void cHardwareGX::ThreadPrev()
-{
- if (m_cur_thread == 0) m_cur_thread = GetNumThreads() - 1;
- else m_cur_thread--;
-}
-
-inline void cHardwareGX::StackPush(int value)
-{
- if (m_threads[m_cur_thread].cur_stack == 0) {
- m_threads[m_cur_thread].stack.Push(value);
- } else {
- m_global_stack.Push(value);
- }
-}
-
-inline int cHardwareGX::StackPop()
-{
- int pop_value;
-
- if (m_threads[m_cur_thread].cur_stack == 0) {
- pop_value = m_threads[m_cur_thread].stack.Pop();
- } else {
- pop_value = m_global_stack.Pop();
- }
-
- return pop_value;
-}
-
-inline void cHardwareGX::StackFlip()
-{
- if (m_threads[m_cur_thread].cur_stack == 0) {
- m_threads[m_cur_thread].stack.Flip();
- } else {
- m_global_stack.Flip();
- }
-}
-
-inline int cHardwareGX::GetStack(int depth, int stack_id, int in_thread) const
-{
- int value = 0;
-
- if(in_thread >= m_threads.GetSize() || in_thread < 0) in_thread = m_cur_thread;
-
- if (stack_id == -1) stack_id = m_threads[in_thread].cur_stack;
-
- if (stack_id == 0) value = m_threads[in_thread].stack.Get(depth);
- else if (stack_id == 1) value = m_global_stack.Get(depth);
-
- return value;
-}
-
-inline void cHardwareGX::StackClear()
-{
- if (m_threads[m_cur_thread].cur_stack == 0) {
- m_threads[m_cur_thread].stack.Clear();
- } else {
- m_global_stack.Clear();
- }
-}
-
-inline void cHardwareGX::SwitchStack()
-{
- m_threads[m_cur_thread].cur_stack++;
- if (m_threads[m_cur_thread].cur_stack > 1) m_threads[m_cur_thread].cur_stack = 0;
-}
-
#endif
Modified: development/source/main/cGenome.cc
===================================================================
--- development/source/main/cGenome.cc 2007-04-27 02:49:56 UTC (rev 1504)
+++ development/source/main/cGenome.cc 2007-04-27 03:48:40 UTC (rev 1505)
@@ -52,6 +52,22 @@
}
}
+
+/*! This constructor is used to build a new cGenome from a range of instructions.
+It expects STL semantics for an iterator range. We're avoiding templating this
+(for now). Refactor if a new range type is needed.
+
+\todo Just as an aside, it looks like Push continually reallocs memory in tArray.
+*/
+cGenome::cGenome(cInstruction* begin, cInstruction* end)
+: active_size(0)
+{
+ for(cInstruction* i=begin; i!=end; ++i,++active_size) {
+ genome.Push(*i);
+ }
+}
+
+
cGenome::~cGenome()
{
}
Modified: development/source/main/cGenome.h
===================================================================
--- development/source/main/cGenome.h 2007-04-27 02:49:56 UTC (rev 1504)
+++ development/source/main/cGenome.h 2007-04-27 03:48:40 UTC (rev 1505)
@@ -43,7 +43,6 @@
* a genome should not be modified; only the corresponding memory should be,
* before creating the genome. Keeping genome light-weight...
**/
-
class cGenome
{
protected:
@@ -51,11 +50,15 @@
int active_size;
public:
+ //! Default constructor.
cGenome() { ; }
- explicit cGenome(int _size);
- cGenome(const cGenome& in_genome);
- cGenome(const cString& in_string);
- virtual ~cGenome();
+ explicit cGenome(int _size); //! Constructor that builds a 'blank' cGenome of the specified size.
+ cGenome(const cGenome& in_genome); //! Copy constructor.
+ cGenome(const cString& in_string); //! Constructor that builds a cGenome from a string.
+ //! Constructor that takes a range of instructions from which to build a new cGenome.
+ cGenome(cInstruction* begin, cInstruction* end);
+
+ virtual ~cGenome(); //! Virtual destructor; there are subclasses.
virtual void operator=(const cGenome& other_genome);
virtual bool operator==(const cGenome& other_genome) const;
Added: development/support/config/default-gx.org
===================================================================
--- development/support/config/default-gx.org (rev 0)
+++ development/support/config/default-gx.org 2007-04-27 03:48:40 UTC (rev 1505)
@@ -0,0 +1,20 @@
+nop-A # Origin of replication.
+nop-B # Beginning of RNAP.
+match # Attempt to match against a nop-B.
+ nop-B
+h-copy # Copy from read-head to write-head (requires a match).
+on-da # When the complement of nop-B is reached...
+ sever # Sever the link between RNAP and it's transcription target.
+nop-C # End of RNAP.
+nop-C # ...
+nop-B # Beginning of DNAP.
+match # Attempt to match against a nop-A/nop-B.
+ nop-A
+ nop-B
+h-copy # Copy from read-head to write-head (requires a match).
+on-da # When the complement of nop-A/nop-B is reached...
+ h-divide # Divide!
+nop-C # End of DNAP.
+nop-C # ...
+nop-B # Replication terminator.
+nop-C
More information about the Avida-cvs
mailing list