[Avida-cvs] [avida-svn] r616 - in development: Avida.xcodeproj source/cpu
brysonda@myxo.css.msu.edu
brysonda at myxo.css.msu.edu
Fri Apr 14 11:17:00 PDT 2006
Author: brysonda
Date: 2006-04-14 14:17:00 -0400 (Fri, 14 Apr 2006)
New Revision: 616
Modified:
development/Avida.xcodeproj/project.pbxproj
development/source/cpu/cHardware4Stack.cc
development/source/cpu/cHardware4Stack.h
development/source/cpu/cHardwareBase.cc
development/source/cpu/cHardwareBase.h
development/source/cpu/cHardwareCPU.cc
development/source/cpu/cHardwareCPU.h
development/source/cpu/cHardwareSMT.cc
development/source/cpu/cHardwareSMT.h
Log:
Move various instances of duplicate hardware functionality into cHardwareBase.
Modified: development/Avida.xcodeproj/project.pbxproj
===================================================================
--- development/Avida.xcodeproj/project.pbxproj 2006-04-14 17:24:47 UTC (rev 615)
+++ development/Avida.xcodeproj/project.pbxproj 2006-04-14 18:17:00 UTC (rev 616)
@@ -40,6 +40,17 @@
702F52AA0992F8F600B2B507 /* cSymbolTable.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702F52A80992F8F600B2B507 /* cSymbolTable.cc */; };
702F52E10992FD8000B2B507 /* cScriptObject.cc in Sources */ = {isa = PBXBuildFile; fileRef = 702F52DF0992FD8000B2B507 /* cScriptObject.cc */; };
702F532F0993060A00B2B507 /* avida-s in CopyFiles */ = {isa = PBXBuildFile; fileRef = 70DCAD1C097AF7CC002F8733 /* avida-s */; };
+ 7039884C09F00CFE0052ACE7 /* avida-smt.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2D409EE8501001AEA89 /* avida-smt.cfg */; };
+ 7039884D09F00D020052ACE7 /* analyze.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2D309EE8501001AEA89 /* analyze.cfg */; };
+ 7039884E09F00D030052ACE7 /* avida.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2D509EE8501001AEA89 /* avida.cfg */; };
+ 7039884F09F00D060052ACE7 /* environment.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2D709EE8501001AEA89 /* environment.cfg */; };
+ 7039885009F00D080052ACE7 /* events.cfg in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2D809EE8501001AEA89 /* events.cfg */; };
+ 7039885109F00D0D0052ACE7 /* inst_set.smt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2DC09EE8501001AEA89 /* inst_set.smt */; };
+ 7039885209F00D0D0052ACE7 /* inst_set.sex in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2DB09EE8501001AEA89 /* inst_set.sex */; };
+ 7039885309F00D0F0052ACE7 /* inst_set.default in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2DA09EE8501001AEA89 /* inst_set.default */; };
+ 7039885409F00D150052ACE7 /* organism.default in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2F609EE8501001AEA89 /* organism.default */; };
+ 7039885509F00D190052ACE7 /* organism.sex in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2F709EE8501001AEA89 /* organism.sex */; };
+ 7039885609F00D1A0052ACE7 /* organism.smt in CopyFiles */ = {isa = PBXBuildFile; fileRef = 707AF2F809EE8501001AEA89 /* organism.smt */; };
7040CF1C0906A52E00AA820F /* cEventManager.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7040CF1A0906A52E00AA820F /* cEventManager.cc */; };
7040CF1E0906A52E00AA820F /* cEventManager.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7040CF1A0906A52E00AA820F /* cEventManager.cc */; };
7040D3A6090964D100AA820F /* cMxCodeArray.cc in Sources */ = {isa = PBXBuildFile; fileRef = 70B0865808F4974300FC65FE /* cMxCodeArray.cc */; };
@@ -444,6 +455,17 @@
dstSubfolderSpec = 16;
files = (
700E2996085A1F6000CF158A /* avida in CopyFiles */,
+ 7039884C09F00CFE0052ACE7 /* avida-smt.cfg in CopyFiles */,
+ 7039884D09F00D020052ACE7 /* analyze.cfg in CopyFiles */,
+ 7039884E09F00D030052ACE7 /* avida.cfg in CopyFiles */,
+ 7039884F09F00D060052ACE7 /* environment.cfg in CopyFiles */,
+ 7039885009F00D080052ACE7 /* events.cfg in CopyFiles */,
+ 7039885109F00D0D0052ACE7 /* inst_set.smt in CopyFiles */,
+ 7039885209F00D0D0052ACE7 /* inst_set.sex in CopyFiles */,
+ 7039885309F00D0F0052ACE7 /* inst_set.default in CopyFiles */,
+ 7039885409F00D150052ACE7 /* organism.default in CopyFiles */,
+ 7039885509F00D190052ACE7 /* organism.sex in CopyFiles */,
+ 7039885609F00D1A0052ACE7 /* organism.smt in CopyFiles */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -2383,7 +2405,6 @@
"-Wno-four-char-constants",
"-Wno-unknown-pragmas",
);
- ZERO_LINK = YES;
};
name = Development;
};
Modified: development/source/cpu/cHardware4Stack.cc
===================================================================
--- development/source/cpu/cHardware4Stack.cc 2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardware4Stack.cc 2006-04-14 18:17:00 UTC (rev 616)
@@ -844,13 +844,13 @@
// Make sure the creature will still be above the minimum size,
// TEMPORARY! INJECTED CODE CAN
if (end_pos <= 0) {
- Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
+ organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
return false; // (inject fails)
}
if (end_pos < MIN_INJECT_SIZE) {
GetMemory(mem_space_used)=cGenome(ConvertToInstruction(mem_space_used));
- Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
+ organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
return false; // (inject fails)
}
@@ -962,171 +962,7 @@
return true; // (inject succeeds!)
}
-void cHardware4Stack::Mutate(cAvidaContext& ctx, int mut_point)
-{
- // Test if trying to mutate outside of genome...
- assert(mut_point >= 0 && mut_point < GetMemory(0).GetSize());
-
- GetMemory(0)[mut_point] = m_inst_set->GetRandomInst(ctx);
- GetMemory(0).SetFlagMutated(mut_point);
- GetMemory(0).SetFlagPointMut(mut_point);
- //organism->GetPhenotype().IsMutated() = true;
- organism->CPUStats().mut_stats.point_mut_count++;
-}
-int cHardware4Stack::PointMutate(cAvidaContext& ctx, const double mut_rate)
-{
- const int num_muts =
- ctx.GetRandom().GetRandBinomial(GetMemory(0).GetSize(), mut_rate);
-
- for (int i = 0; i < num_muts; i++) {
- const int pos = ctx.GetRandom().GetUInt(GetMemory(0).GetSize());
- Mutate(ctx, pos);
- }
-
- return num_muts;
-}
-
-
-// Trigger mutations of a specific type. Outside triggers cannot specify
-// a head since hardware types are not known.
-
-bool cHardware4Stack::TriggerMutations(cAvidaContext& ctx, int trigger)
-{
- // Only update triggers should happen from the outside!
- assert(trigger == nMutation::TRIGGER_UPDATE);
-
- // Assume instruction pointer is the intended target (if one is even
- // needed!
-
- return TriggerMutations(ctx, trigger, IP());
-}
-
-bool cHardware4Stack::TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head)
-{
- // Collect information about mutations from the organism.
- cLocalMutations & mut_info = organism->GetLocalMutations();
- const tList<cMutation> & mut_list =
- mut_info.GetMutationLib().GetMutationList(trigger);
-
- // If we have no mutations for this trigger, stop here.
- if (mut_list.GetSize() == 0) return false;
- bool has_mutation = false;
-
- // Determine what memory this mutation will be affecting.
- cCPUMemory & target_mem = (trigger == nMutation::TRIGGER_DIVIDE)
- ? organism->ChildGenome() : GetMemory(0);
-
- // Loop through all mutations associated with this trigger and test them.
- tConstListIterator<cMutation> mut_it(mut_list);
-
- while (mut_it.Next() != NULL) {
- const cMutation * cur_mut = mut_it.Get();
- const int mut_id = cur_mut->GetID();
- const int scope = cur_mut->GetScope();
- const double rate = mut_info.GetRate(mut_id);
- switch (scope) {
- case nMutation::SCOPE_GENOME:
- if (TriggerMutations_ScopeGenome(ctx, cur_mut, target_mem, cur_head, rate)) {
- has_mutation = true;
- mut_info.IncCount(mut_id);
- }
- break;
- case nMutation::SCOPE_LOCAL:
- case nMutation::SCOPE_PROP:
- if (TriggerMutations_ScopeLocal(ctx, cur_mut, target_mem, cur_head, rate)) {
- has_mutation = true;
- mut_info.IncCount(mut_id);
- }
- break;
- case nMutation::SCOPE_GLOBAL:
- case nMutation::SCOPE_SPREAD:
- int num_muts =
- TriggerMutations_ScopeGlobal(ctx, cur_mut, target_mem, cur_head, rate);
- if (num_muts > 0) {
- has_mutation = true;
- mut_info.IncCount(mut_id, num_muts);
- }
- break;
- }
- }
-
- return has_mutation;
-}
-
-bool cHardware4Stack::TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut,
- cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
- // The rate we have stored indicates the probability that a single
- // mutation will occur anywhere in the genome.
-
- if (ctx.GetRandom().P(rate) == true) {
- // We must create a temporary head and use it to randomly determine the
- // position in the genome to be mutated.
- cHeadCPU tmp_head(cur_head);
- tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
- TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
- return true;
- }
- return false;
-}
-
-bool cHardware4Stack::TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut,
- cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
- // The rate we have stored is the probability for a mutation at this single
- // position in the genome.
-
- if (ctx.GetRandom().P(rate) == true) {
- TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, cur_head);
- return true;
- }
- return false;
-}
-
-int cHardware4Stack::TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation* cur_mut,
- cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
- // The probability we have stored is per-site, so we can pull a random
- // number from a binomial distribution to determine the number of mutations
- // that should occur.
-
- const int num_mut =
- ctx.GetRandom().GetRandBinomial(target_memory.GetSize(), rate);
-
- if (num_mut > 0) {
- for (int i = 0; i < num_mut; i++) {
- cHeadCPU tmp_head(cur_head);
- tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
- TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
- }
- }
-
- return num_mut;
-}
-
-void cHardware4Stack::TriggerMutations_Body(cAvidaContext& ctx, int type,
- cCPUMemory& target_memory, cHeadCPU& cur_head)
-{
- const int pos = cur_head.GetPosition();
-
- switch (type) {
- case nMutation::TYPE_POINT:
- target_memory[pos] = m_inst_set->GetRandomInst(ctx);
- target_memory.SetFlagMutated(pos);
- break;
- case nMutation::TYPE_INSERT:
- case nMutation::TYPE_DELETE:
- case nMutation::TYPE_HEAD_INC:
- case nMutation::TYPE_HEAD_DEC:
- case nMutation::TYPE_TEMP:
- case nMutation::TYPE_KILL:
- default:
- m_world->GetDriver().RaiseException("Mutation type not implemented!");
- break;
- };
-}
-
void cHardware4Stack::ReadInst(const int in_inst)
{
if (m_inst_set->IsNop( cInstruction(in_inst) )) {
@@ -1254,178 +1090,16 @@
return comp_stack%nHardware4Stack::NUM_STACKS;
}
-inline void cHardware4Stack::Fault(int fault_loc, int fault_type, cString fault_desc)
+int cHardware4Stack::GetCopiedSize(const int parent_size, const int child_size)
{
- organism->Fault(fault_loc, fault_type, fault_desc);
-}
-
-bool cHardware4Stack::Divide_CheckViable(cAvidaContext& ctx, const int parent_size,
- const int child_size, const int mem_space)
-{
- // Make sure the organism is okay with dividing now...
- if (organism->Divide_CheckViable() == false) return false; // (divide fails)
-
- // Make sure that neither parent nor child will be below the minimum size.
-
- const int genome_size = organism->GetGenome().GetSize();
- const double size_range = m_world->GetConfig().CHILD_SIZE_RANGE.Get();
- const int min_size = Max(MIN_CREATURE_SIZE, (int) (genome_size/size_range));
- const int max_size = Min(MAX_CREATURE_SIZE, (int) (genome_size*size_range));
-
- if (child_size < min_size || child_size > max_size) {
- Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
- cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
- return false; // (divide fails)
- }
-
- // Count the number of lines executed in the parent, and make sure the
- // specified fraction has been reached.
-
- int executed_size = 0;
- for (int i = 0; i < parent_size; i++) {
- if (GetMemory(0).FlagExecuted(i)) executed_size++;
- }
-
- const int min_exe_lines = (int) (parent_size * m_world->GetConfig().MIN_EXE_LINES.Get());
- if (executed_size < min_exe_lines) {
- Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
- cStringUtil::Stringf("Too few executed lines (%d < %d)",
- executed_size, min_exe_lines));
- return false; // (divide fails)
- }
-
- // Count the number of lines which were copied into the child, and make
- // sure the specified fraction has been reached.
-
int copied_size = 0;
- for (int i = 0; i < GetMemory(mem_space).GetSize(); i++) {
- if (GetMemory(mem_space).FlagCopied(i)) copied_size++;
- }
-
- const int min_copied = (int) (child_size * m_world->GetConfig().MIN_COPIED_LINES.Get());
- if (copied_size < min_copied) {
- Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
- cStringUtil::Stringf("Too few copied commands (%d < %d)",
- copied_size, min_copied));
- return false; // (divide fails)
- }
-
- // Save the information we collected here...
- organism->GetPhenotype().SetLinesExecuted(executed_size);
- organism->GetPhenotype().SetLinesCopied(copied_size);
-
- return true; // (divide succeeds!)
+ const cCPUMemory& memory = GetMemory(m_cur_child);
+ for (int i = 0; i < memory.GetSize(); i++) {
+ if (memory.FlagCopied(i)) copied_size++;
+ }
+ return copied_size;
}
-void cHardware4Stack::Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier)
-{
- sCPUStats & cpu_stats = organism->CPUStats();
- cCPUMemory & child_genome = organism->ChildGenome();
-
- organism->GetPhenotype().SetDivType(mut_multiplier);
-
- // Divide Mutations
- if (organism->TestDivideMut(ctx)) {
- const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
- child_genome[mut_line] = m_inst_set->GetRandomInst(ctx);
- cpu_stats.mut_stats.divide_mut_count++;
- }
-
- // Divide Insertions
- if (organism->TestDivideIns(ctx) && child_genome.GetSize() < MAX_CREATURE_SIZE){
- const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
- child_genome.Insert(mut_line, m_inst_set->GetRandomInst(ctx));
- cpu_stats.mut_stats.divide_insert_mut_count++;
- }
-
- // Divide Deletions
- if (organism->TestDivideDel(ctx) && child_genome.GetSize() > MIN_CREATURE_SIZE){
- const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
- child_genome.Remove(mut_line);
- cpu_stats.mut_stats.divide_delete_mut_count++;
- }
-
- // Divide Mutations (per site)
- if(organism->GetDivMutProb() > 0){
- int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
- organism->GetDivMutProb() / mut_multiplier);
- // If we have lines to mutate...
- if( num_mut > 0 ){
- for (int i = 0; i < num_mut; i++) {
- int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
- child_genome[site] = m_inst_set->GetRandomInst(ctx);
- cpu_stats.mut_stats.div_mut_count++;
- }
- }
- }
-
-
- // Insert Mutations (per site)
- if(organism->GetInsMutProb() > 0){
- int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
- organism->GetInsMutProb());
- // If would make creature to big, insert up to MAX_CREATURE_SIZE
- if( num_mut + child_genome.GetSize() > MAX_CREATURE_SIZE ){
- num_mut = MAX_CREATURE_SIZE - child_genome.GetSize();
- }
- // If we have lines to insert...
- if( num_mut > 0 ){
- // Build a list of the sites where mutations occured
- static int mut_sites[MAX_CREATURE_SIZE];
- for (int i = 0; i < num_mut; i++) {
- mut_sites[i] = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
- }
- // Sort the list
- qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
- // Actually do the mutations (in reverse sort order)
- for(int i = num_mut-1; i >= 0; i--) {
- child_genome.Insert(mut_sites[i], m_inst_set->GetRandomInst(ctx));
- cpu_stats.mut_stats.insert_mut_count++;
- }
- }
- }
-
-
- // Delete Mutations (per site)
- if( organism->GetDelMutProb() > 0 ){
- int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
- organism->GetDelMutProb());
- // If would make creature too small, delete down to MIN_CREATURE_SIZE
- if (child_genome.GetSize() - num_mut < MIN_CREATURE_SIZE) {
- num_mut = child_genome.GetSize() - MIN_CREATURE_SIZE;
- }
-
- // If we have lines to delete...
- for (int i = 0; i < num_mut; i++) {
- int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
- child_genome.Remove(site);
- cpu_stats.mut_stats.delete_mut_count++;
- }
- }
-
- // Mutations in the parent's genome
- if (organism->GetParentMutProb() > 0) {
- for (int i = 0; i < GetMemory(0).GetSize(); i++) {
- if (organism->TestParentMut(ctx)) {
- GetMemory(0)[i] = m_inst_set->GetRandomInst(ctx);
- cpu_stats.mut_stats.parent_mut_line_count++;
- }
- }
- }
-
-
- // Count up mutated lines
- for(int i = 0; i < GetMemory(0).GetSize(); i++){
- if (GetMemory(0).FlagPointMut(i)) {
- cpu_stats.mut_stats.point_mut_line_count++;
- }
- }
- for(int i = 0; i < child_genome.GetSize(); i++){
- if( child_genome.FlagCopyMut(i)) {
- cpu_stats.mut_stats.copy_mut_line_count++;
- }
- }
-}
void cHardware4Stack::Inject_DoMutations(cAvidaContext& ctx, double mut_multiplier, cCPUMemory & injected_code)
{
@@ -1526,68 +1200,6 @@
}
-// test whether the offspring creature contains an advantageous mutation.
-void cHardware4Stack::Divide_TestFitnessMeasures(cAvidaContext& ctx)
-{
- cPhenotype & phenotype = organism->GetPhenotype();
- phenotype.CopyTrue() = ( organism->ChildGenome() == organism->GetGenome() );
- phenotype.ChildFertile() = true;
-
- // Only continue if we're supposed to do a fitness test on divide...
- if (organism->GetTestOnDivide() == false) return;
-
- // If this was a perfect copy, then we don't need to worry about any other
- // tests... Theoretically, we need to worry about the parent changing,
- // but as long as the child is always compared to the original genotype,
- // this won't be an issue.
- if (phenotype.CopyTrue() == true) return;
-
- const double parent_fitness = organism->GetTestFitness();
- const double neut_min = parent_fitness * nHardware::FITNESS_NEUTRAL_MIN;
- const double neut_max = parent_fitness * nHardware::FITNESS_NEUTRAL_MAX;
-
- cTestCPU* testcpu = m_world->GetHardwareManager().CreateTestCPU();
- cCPUTestInfo test_info;
- test_info.UseRandomInputs();
- testcpu->TestGenome(ctx, test_info, organism->ChildGenome());
- const double child_fitness = test_info.GetGenotypeFitness();
- delete testcpu;
-
- bool revert = false;
- bool sterilize = false;
-
- // If implicit mutations are turned off, make sure this won't spawn one.
- if (organism->GetFailImplicit() == true) {
- if (test_info.GetMaxDepth() > 0) sterilize = true;
- }
-
- if (child_fitness == 0.0) {
- // Fatal mutation... test for reversion.
- if (ctx.GetRandom().P(organism->GetRevertFatal())) revert = true;
- if (ctx.GetRandom().P(organism->GetSterilizeFatal())) sterilize = true;
- } else if (child_fitness < neut_min) {
- if (ctx.GetRandom().P(organism->GetRevertNeg())) revert = true;
- if (ctx.GetRandom().P(organism->GetSterilizeNeg())) sterilize = true;
- } else if (child_fitness <= neut_max) {
- if (ctx.GetRandom().P(organism->GetRevertNeut())) revert = true;
- if (ctx.GetRandom().P(organism->GetSterilizeNeut())) sterilize = true;
- } else {
- if (ctx.GetRandom().P(organism->GetRevertPos())) revert = true;
- if (ctx.GetRandom().P(organism->GetSterilizePos())) sterilize = true;
- }
-
- // Ideally, we won't have reversions and sterilizations turned on at the
- // same time, but if we do, give revert the priority.
- if (revert == true) {
- organism->ChildGenome() = organism->GetGenome();
- }
-
- if (sterilize == true) {
- organism->GetPhenotype().ChildFertile() = false;
- }
-}
-
-
bool cHardware4Stack::Divide_Main(cAvidaContext& ctx, int mem_space_used, double mut_multiplier)
{
int write_head_pos = GetHead(nHardware::HEAD_WRITE).GetPosition();
@@ -1598,8 +1210,8 @@
return false;
// Make sure this divide will produce a viable offspring.
- if(!Divide_CheckViable(ctx, GetMemory(IP().GetMemSpace()).GetSize(),
- write_head_pos, mem_space_used))
+ m_cur_child = mem_space_used;
+ if(!Divide_CheckViable(ctx, GetMemory(IP().GetMemSpace()).GetSize(), write_head_pos))
return false;
// Since the divide will now succeed, set up the information to be sent
@@ -1740,11 +1352,11 @@
const int stack_used = FindModifiedStack(nHardware4Stack::STACK_BX);
if (Stack(nHardware4Stack::STACK_CX).Top() != 0) {
if (0-INT_MAX > Stack(nHardware4Stack::STACK_BX).Top() && Stack(nHardware4Stack::STACK_CX).Top() == -1)
- Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
+ organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
else
Stack(stack_used).Push(Stack(nHardware4Stack::STACK_BX).Top() / Stack(nHardware4Stack::STACK_CX).Top());
} else {
- Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
+ organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
return false;
}
return true;
@@ -2005,7 +1617,7 @@
bool cHardware4Stack::Inst_ForkThread(cAvidaContext& ctx)
{
if (!ForkThread())
- Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
+ organism->Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
else
IP().Advance();
return true;
@@ -2048,7 +1660,7 @@
else
Stack(stack_used).Push(Stack(nHardware4Stack::STACK_BX).Top() % Stack(nHardware4Stack::STACK_CX).Top());
} else {
- Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
+ organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
return false;
}
return true;
@@ -2057,7 +1669,7 @@
//35
bool cHardware4Stack::Inst_KillThread(cAvidaContext& ctx)
{
- if (!KillThread()) Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
+ if (!KillThread()) organism->Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
else AdvanceIP() = false;
return true;
}
Modified: development/source/cpu/cHardware4Stack.h
===================================================================
--- development/source/cpu/cHardware4Stack.h 2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardware4Stack.h 2006-04-14 18:17:00 UTC (rev 616)
@@ -67,7 +67,7 @@
{
public:
typedef bool (cHardware4Stack::*tHardware4StackMethod)(cAvidaContext& ctx);
-private:
+protected:
static cInstLib4Stack* s_inst_slib;
static cInstLib4Stack* initInstLib(void);
@@ -95,6 +95,8 @@
// Keeps track of fractional instructions that carry over into next update
float inst_remainder;
+
+ int m_cur_child;
bool SingleProcess_PayCosts(cAvidaContext& ctx, const cInstruction & cur_inst);
@@ -124,32 +126,21 @@
cCodeLabel & GetReadLabel() { return threads[cur_thread].read_label; }
- bool TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut, cCPUMemory& target_memory,
- cHeadCPU& cur_head, const double rate);
- bool TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut, cCPUMemory& target_memory,
- cHeadCPU& cur_head, const double rate);
- int TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation* cur_mut, cCPUMemory& target_memory,
- cHeadCPU& cur_head, const double rate);
- void TriggerMutations_Body(cAvidaContext& ctx, int type, cCPUMemory & target_memory, cHeadCPU& cur_head);
-
// ---------- Instruction Helpers -----------
int FindModifiedStack(int default_stack);
int FindModifiedHead(int default_head);
int FindComplementStack(int base_stack);
- void Fault(int fault_loc, int fault_type, cString fault_desc="");
bool Allocate_Necro(const int new_size);
bool Allocate_Random(const int old_size, const int new_size);
bool Allocate_Default(const int new_size);
bool Allocate_Main(const int allocated_size);
- bool Divide_Main(cAvidaContext& ctx, const int mem_space_used, double mut_multiplier=1);
- bool Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size, const int mem_space);
- void Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier = 1);
- void Inject_DoMutations(cAvidaContext& ctx, double mut_multiplier, cCPUMemory & injected_code);
- void Divide_TestFitnessMeasures(cAvidaContext& ctx);
- void Mutate(cAvidaContext& ctx, const int mut_point);
+ int GetCopiedSize(const int parent_size, const int child_size);
+ bool Divide_Main(cAvidaContext& ctx, const int mem_space_used, double mut_multiplier = 1.0);
+ void Inject_DoMutations(cAvidaContext& ctx, double mut_multiplier, cCPUMemory& injected_code);
+
bool HeadCopy_ErrorCorrect(double reduction);
bool InjectParasite(cAvidaContext& ctx, double mut_multiplier);
@@ -241,12 +232,6 @@
}
- // -------- Mutation --------
- int PointMutate(cAvidaContext& ctx, const double mut_rate);
- bool TriggerMutations(cAvidaContext& ctx, int trigger);
- bool TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head);
-
-
private:
// ---------- Instruction Library -----------
bool Inst_ShiftR(cAvidaContext& ctx);
Modified: development/source/cpu/cHardwareBase.cc
===================================================================
--- development/source/cpu/cHardwareBase.cc 2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardwareBase.cc 2006-04-14 18:17:00 UTC (rev 616)
@@ -10,6 +10,432 @@
#include "cHardwareBase.h"
+#include "cAvidaContext.h"
+#include "cCPUTestInfo.h"
+#include "cHardwareManager.h"
+#include "cHeadCPU.h"
+#include "cInstSet.h"
+#include "cMutation.h"
+#include "cMutationLib.h"
+#include "nMutation.h"
+#include "cOrganism.h"
+#include "cPhenotype.h"
+#include "cRandom.h"
+#include "cTestCPU.h"
+#include "cWorld.h"
+#include "cWorldDriver.h"
+#include "nHardware.h"
+
+#include "functions.h"
+
+
+int cHardwareBase::GetExecutedSize(const int parent_size)
+{
+ int executed_size = 0;
+ const cCPUMemory& memory = GetMemory();
+ for (int i = 0; i < parent_size; i++) {
+ if (memory.FlagExecuted(i)) executed_size++;
+ }
+ return executed_size;
+}
+
+bool cHardwareBase::Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size)
+{
+ // Make sure the organism is okay with dividing now...
+ if (organism->Divide_CheckViable() == false) return false; // (divide fails)
+
+ // Make sure that neither parent nor child will be below the minimum size.
+ const int genome_size = organism->GetGenome().GetSize();
+ const double size_range = m_world->GetConfig().CHILD_SIZE_RANGE.Get();
+ const int min_size = Max(MIN_CREATURE_SIZE, static_cast<int>(genome_size / size_range));
+ const int max_size = Min(MAX_CREATURE_SIZE, static_cast<int>(genome_size * size_range));
+
+ if (child_size < min_size || child_size > max_size) {
+ organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+ cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
+ return false; // (divide fails)
+ }
+ if (parent_size < min_size || parent_size > max_size) {
+ organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+ cStringUtil::Stringf("Invalid post-divide length (%d)",parent_size));
+ return false; // (divide fails)
+ }
+
+ // Count the number of lines executed in the parent, and make sure the
+ // specified fraction has been reached.
+
+ const int executed_size = GetExecutedSize(parent_size);
+ const int min_exe_lines = static_cast<int>(parent_size * m_world->GetConfig().MIN_EXE_LINES.Get());
+ if (executed_size < min_exe_lines) {
+ organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+ cStringUtil::Stringf("Too few executed lines (%d < %d)", executed_size, min_exe_lines));
+ return false; // (divide fails)
+ }
+
+ const int copied_size = GetCopiedSize(parent_size, child_size);
+ const int min_copied = static_cast<int>(child_size * m_world->GetConfig().MIN_COPIED_LINES.Get());
+ if (copied_size < min_copied) {
+ organism->Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
+ cStringUtil::Stringf("Too few copied commands (%d < %d)", copied_size, min_copied));
+ return false; // (divide fails)
+ }
+
+ // Save the information we collected here...
+ cPhenotype& phenotype = organism->GetPhenotype();
+ phenotype.SetLinesExecuted(executed_size);
+ phenotype.SetLinesCopied(copied_size);
+
+ // Determine the fitness of this organism as compared to its parent...
+ if (m_world->GetTestSterilize() && !phenotype.IsInjected()) {
+ const int merit_base = phenotype.CalcSizeMerit();
+ const double cur_fitness = merit_base * phenotype.GetCurBonus() / phenotype.GetTimeUsed();
+ const double fitness_ratio = cur_fitness / phenotype.GetLastFitness();
+
+ bool sterilize = false;
+
+ if (fitness_ratio < nHardware::FITNESS_NEUTRAL_MIN) {
+ if (ctx.GetRandom().P(organism->GetSterilizeNeg())) sterilize = true;
+ } else if (fitness_ratio <= nHardware::FITNESS_NEUTRAL_MAX) {
+ if (ctx.GetRandom().P(organism->GetSterilizeNeut())) sterilize = true;
+ } else {
+ if (ctx.GetRandom().P(organism->GetSterilizePos())) sterilize = true;
+ }
+
+ if (sterilize) {
+ // Don't let this organism have this or any more children!
+ phenotype.IsFertile() = false;
+ return false;
+ }
+ }
+
+ return true; // (divide succeeds!)
+}
+
+
+void cHardwareBase::Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier)
+{
+ sCPUStats& cpu_stats = organism->CPUStats();
+ cCPUMemory& child_genome = organism->ChildGenome();
+
+ organism->GetPhenotype().SetDivType(mut_multiplier);
+
+ // Divide Mutations
+ if (organism->TestDivideMut(ctx)) {
+ const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
+ child_genome[mut_line] = m_inst_set->GetRandomInst(ctx);
+ cpu_stats.mut_stats.divide_mut_count++;
+ }
+
+ // Divide Insertions
+ if (organism->TestDivideIns(ctx) && child_genome.GetSize() < MAX_CREATURE_SIZE) {
+ const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
+ child_genome.Insert(mut_line, m_inst_set->GetRandomInst(ctx));
+ cpu_stats.mut_stats.divide_insert_mut_count++;
+ }
+
+ // Divide Deletions
+ if (organism->TestDivideDel(ctx) && child_genome.GetSize() > MIN_CREATURE_SIZE) {
+ const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
+ child_genome.Remove(mut_line);
+ cpu_stats.mut_stats.divide_delete_mut_count++;
+ }
+
+ // Divide Mutations (per site)
+ if (organism->GetDivMutProb() > 0) {
+ int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
+ organism->GetDivMutProb() / mut_multiplier);
+ // If we have lines to mutate...
+ if (num_mut > 0) {
+ for (int i = 0; i < num_mut; i++) {
+ int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
+ child_genome[site] = m_inst_set->GetRandomInst(ctx);
+ cpu_stats.mut_stats.div_mut_count++;
+ }
+ }
+ }
+
+
+ // Insert Mutations (per site)
+ if (organism->GetInsMutProb() > 0) {
+ int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
+ organism->GetInsMutProb());
+ // If would make creature to big, insert up to MAX_CREATURE_SIZE
+ if (num_mut + child_genome.GetSize() > MAX_CREATURE_SIZE) {
+ num_mut = MAX_CREATURE_SIZE - child_genome.GetSize();
+ }
+ // If we have lines to insert...
+ if (num_mut > 0) {
+ // Build a list of the sites where mutations occured
+ static int mut_sites[MAX_CREATURE_SIZE];
+ for (int i = 0; i < num_mut; i++) {
+ mut_sites[i] = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
+ }
+ // Sort the list
+ qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
+ // Actually do the mutations (in reverse sort order)
+ for (int i = num_mut-1; i >= 0; i--) {
+ child_genome.Insert(mut_sites[i], m_inst_set->GetRandomInst(ctx));
+ cpu_stats.mut_stats.insert_mut_count++;
+ }
+ }
+ }
+
+
+ // Delete Mutations (per site)
+ if (organism->GetDelMutProb() > 0) {
+ int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
+ organism->GetDelMutProb());
+ // If would make creature too small, delete down to MIN_CREATURE_SIZE
+ if (child_genome.GetSize() - num_mut < MIN_CREATURE_SIZE) {
+ num_mut = child_genome.GetSize() - MIN_CREATURE_SIZE;
+ }
+
+ // If we have lines to delete...
+ for (int i = 0; i < num_mut; i++) {
+ int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
+ child_genome.Remove(site);
+ cpu_stats.mut_stats.delete_mut_count++;
+ }
+ }
+
+ // Mutations in the parent's genome
+ if (organism->GetParentMutProb() > 0) {
+ for (int i = 0; i < GetMemory().GetSize(); i++) {
+ if (organism->TestParentMut(ctx)) {
+ GetMemory()[i] = m_inst_set->GetRandomInst(ctx);
+ cpu_stats.mut_stats.parent_mut_line_count++;
+ }
+ }
+ }
+
+
+ // Count up mutated lines
+ for (int i = 0; i < GetMemory().GetSize(); i++) {
+ if (GetMemory().FlagPointMut(i)) {
+ cpu_stats.mut_stats.point_mut_line_count++;
+ }
+ }
+ for (int i = 0; i < child_genome.GetSize(); i++) {
+ if (child_genome.FlagCopyMut(i)) {
+ cpu_stats.mut_stats.copy_mut_line_count++;
+ }
+ }
+}
+
+
+// test whether the offspring creature contains an advantageous mutation.
+void cHardwareBase::Divide_TestFitnessMeasures(cAvidaContext& ctx)
+{
+ cPhenotype & phenotype = organism->GetPhenotype();
+ phenotype.CopyTrue() = ( organism->ChildGenome() == organism->GetGenome() );
+ phenotype.ChildFertile() = true;
+
+ // Only continue if we're supposed to do a fitness test on divide...
+ if (organism->GetTestOnDivide() == false) return;
+
+ // If this was a perfect copy, then we don't need to worry about any other
+ // tests... Theoretically, we need to worry about the parent changing,
+ // but as long as the child is always compared to the original genotype,
+ // this won't be an issue.
+ if (phenotype.CopyTrue() == true) return;
+
+ const double parent_fitness = organism->GetTestFitness();
+ const double neut_min = parent_fitness * nHardware::FITNESS_NEUTRAL_MIN;
+ const double neut_max = parent_fitness * nHardware::FITNESS_NEUTRAL_MAX;
+
+ cTestCPU* testcpu = m_world->GetHardwareManager().CreateTestCPU();
+ cCPUTestInfo test_info;
+ test_info.UseRandomInputs();
+ testcpu->TestGenome(ctx, test_info, organism->ChildGenome());
+ const double child_fitness = test_info.GetGenotypeFitness();
+ delete testcpu;
+
+ bool revert = false;
+ bool sterilize = false;
+
+ // If implicit mutations are turned off, make sure this won't spawn one.
+ if (organism->GetFailImplicit() == true) {
+ if (test_info.GetMaxDepth() > 0) sterilize = true;
+ }
+
+ if (child_fitness == 0.0) {
+ // Fatal mutation... test for reversion.
+ if (ctx.GetRandom().P(organism->GetRevertFatal())) revert = true;
+ if (ctx.GetRandom().P(organism->GetSterilizeFatal())) sterilize = true;
+ } else if (child_fitness < neut_min) {
+ if (ctx.GetRandom().P(organism->GetRevertNeg())) revert = true;
+ if (ctx.GetRandom().P(organism->GetSterilizeNeg())) sterilize = true;
+ } else if (child_fitness <= neut_max) {
+ if (ctx.GetRandom().P(organism->GetRevertNeut())) revert = true;
+ if (ctx.GetRandom().P(organism->GetSterilizeNeut())) sterilize = true;
+ } else {
+ if (ctx.GetRandom().P(organism->GetRevertPos())) revert = true;
+ if (ctx.GetRandom().P(organism->GetSterilizePos())) sterilize = true;
+ }
+
+ // Ideally, we won't have reversions and sterilizations turned on at the
+ // same time, but if we do, give revert the priority.
+ if (revert == true) {
+ organism->ChildGenome() = organism->GetGenome();
+ }
+
+ if (sterilize == true) {
+ organism->GetPhenotype().ChildFertile() = false;
+ }
+}
+
+int cHardwareBase::PointMutate(cAvidaContext& ctx, const double mut_rate)
+{
+ cCPUMemory& memory = GetMemory();
+ const int num_muts = ctx.GetRandom().GetRandBinomial(memory.GetSize(), mut_rate);
+
+ for (int i = 0; i < num_muts; i++) {
+ const int pos = ctx.GetRandom().GetUInt(memory.GetSize());
+ memory[pos] = m_inst_set->GetRandomInst(ctx);
+ memory.SetFlagMutated(pos);
+ memory.SetFlagPointMut(pos);
+ organism->CPUStats().mut_stats.point_mut_count++;
+ }
+
+ return num_muts;
+}
+
+void cHardwareBase::TriggerMutations_Body(cAvidaContext& ctx, int type, cCPUMemory & target_memory, cHeadCPU& cur_head)
+{
+ const int pos = cur_head.GetPosition();
+
+ switch (type) {
+ case nMutation::TYPE_POINT:
+ target_memory[pos] = m_inst_set->GetRandomInst(ctx);
+ target_memory.SetFlagMutated(pos);
+ break;
+ case nMutation::TYPE_INSERT:
+ case nMutation::TYPE_DELETE:
+ case nMutation::TYPE_HEAD_INC:
+ case nMutation::TYPE_HEAD_DEC:
+ case nMutation::TYPE_TEMP:
+ case nMutation::TYPE_KILL:
+ default:
+ m_world->GetDriver().RaiseException("Mutation type not implemented!");
+ break;
+ };
+}
+
+
+bool cHardwareBase::TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut,
+ cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
+{
+ // The rate we have stored indicates the probability that a single
+ // mutation will occur anywhere in the genome.
+
+ if (ctx.GetRandom().P(rate) == true) {
+ // We must create a temporary head and use it to randomly determine the
+ // position in the genome to be mutated.
+ cHeadCPU tmp_head(cur_head);
+ tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
+ TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
+ return true;
+ }
+ return false;
+}
+
+bool cHardwareBase::TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut,
+ cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
+{
+ // The rate we have stored is the probability for a mutation at this single
+ // position in the genome.
+
+ if (ctx.GetRandom().P(rate) == true) {
+ TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, cur_head);
+ return true;
+ }
+ return false;
+}
+
+int cHardwareBase::TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation * cur_mut,
+ cCPUMemory & target_memory, cHeadCPU& cur_head, const double rate)
+{
+ // The probability we have stored is per-site, so we can pull a random
+ // number from a binomial distribution to determine the number of mutations
+ // that should occur.
+
+ const int num_mut =
+ ctx.GetRandom().GetRandBinomial(target_memory.GetSize(), rate);
+
+ if (num_mut > 0) {
+ for (int i = 0; i < num_mut; i++) {
+ cHeadCPU tmp_head(cur_head);
+ tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
+ TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
+ }
+ }
+
+ return num_mut;
+}
+
+// Trigger mutations of a specific type. Outside triggers cannot specify
+// a head since hardware types are not known.
+bool cHardwareBase::TriggerMutations(cAvidaContext& ctx, int trigger)
+{
+ // Only update triggers should happen from the outside!
+ assert(trigger == nMutation::TRIGGER_UPDATE);
+
+ // Assume instruction pointer is the intended target (if one is even
+ // needed!
+
+ return TriggerMutations(ctx, trigger, IP());
+}
+
+bool cHardwareBase::TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head)
+{
+ // Collect information about mutations from the organism.
+ cLocalMutations& mut_info = organism->GetLocalMutations();
+ const tList<cMutation>& mut_list = mut_info.GetMutationLib().GetMutationList(trigger);
+
+ // If we have no mutations for this trigger, stop here.
+ if (mut_list.GetSize() == 0) return false;
+ bool has_mutation = false;
+
+ // Determine what memory this mutation will be affecting.
+ cCPUMemory& target_mem = (trigger == nMutation::TRIGGER_DIVIDE) ? organism->ChildGenome() : GetMemory();
+
+ // Loop through all mutations associated with this trigger and test them.
+ tConstListIterator<cMutation> mut_it(mut_list);
+
+ while (mut_it.Next() != NULL) {
+ const cMutation* cur_mut = mut_it.Get();
+ const int mut_id = cur_mut->GetID();
+ const int scope = cur_mut->GetScope();
+ const double rate = mut_info.GetRate(mut_id);
+ switch (scope) {
+ case nMutation::SCOPE_GENOME:
+ if (TriggerMutations_ScopeGenome(ctx, cur_mut, target_mem, cur_head, rate)) {
+ has_mutation = true;
+ mut_info.IncCount(mut_id);
+ }
+ break;
+ case nMutation::SCOPE_LOCAL:
+ case nMutation::SCOPE_PROP:
+ if (TriggerMutations_ScopeLocal(ctx, cur_mut, target_mem, cur_head, rate)) {
+ has_mutation = true;
+ mut_info.IncCount(mut_id);
+ }
+ break;
+ case nMutation::SCOPE_GLOBAL:
+ case nMutation::SCOPE_SPREAD:
+ int num_muts = TriggerMutations_ScopeGlobal(ctx, cur_mut, target_mem, cur_head, rate);
+ if (num_muts > 0) {
+ has_mutation = true;
+ mut_info.IncCount(mut_id, num_muts);
+ }
+ break;
+ }
+ }
+
+ return has_mutation;
+}
+
+
bool cHardwareBase::Inst_Nop(cAvidaContext& ctx) // Do Nothing.
{
return true;
Modified: development/source/cpu/cHardwareBase.h
===================================================================
--- development/source/cpu/cHardwareBase.h 2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardwareBase.h 2006-04-14 18:17:00 UTC (rev 616)
@@ -25,6 +25,7 @@
class cInjectGenotype;
class cInstruction;
class cInstSet;
+class cMutation;
class cOrganism;
class cString;
class cWorld;
@@ -34,10 +35,24 @@
protected:
cWorld* m_world;
cOrganism* organism; // Organism using this hardware.
- cInstSet* m_inst_set; // Instruction set being used.
+ cInstSet* m_inst_set; // Instruction set being used.
cHardwareTracer* m_tracer; // Set this if you want execution traced.
-
+ virtual int GetExecutedSize(const int parent_size);
+ virtual int GetCopiedSize(const int parent_size, const int child_size) = 0;
+
+ bool Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size);
+ void Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier = 1.0);
+ void Divide_TestFitnessMeasures(cAvidaContext& ctx);
+
+ void TriggerMutations_Body(cAvidaContext& ctx, int type, cCPUMemory& target_memory, cHeadCPU& cur_head);
+ bool TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut,
+ cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
+ bool TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut,
+ cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
+ int TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation* cur_mut,
+ cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
+
cHardwareBase(); // @not_implemented
cHardwareBase(const cHardwareBase&); // @not_implemented
cHardwareBase& operator=(const cHardwareBase&); // @not_implemented
@@ -126,9 +141,9 @@
// -------- Mutation --------
- virtual int PointMutate(cAvidaContext& ctx, const double mut_rate) = 0;
- virtual bool TriggerMutations(cAvidaContext& ctx, int trigger) = 0;
- virtual bool TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head) = 0;
+ virtual int PointMutate(cAvidaContext& ctx, const double mut_rate);
+ virtual bool TriggerMutations(cAvidaContext& ctx, int trigger);
+ virtual bool TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head);
protected:
Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc 2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardwareCPU.cc 2006-04-14 18:17:00 UTC (rev 616)
@@ -1002,175 +1002,7 @@
}
}
-void cHardwareCPU::InjectCodeThread(const cGenome & inject_code, const int line_num)
-{
-}
-void cHardwareCPU::Mutate(cAvidaContext& ctx, int mut_point)
-{
- // Test if trying to mutate outside of genome...
- assert(mut_point >= 0 && mut_point < GetMemory().GetSize());
-
- GetMemory()[mut_point] = m_inst_set->GetRandomInst(ctx);
- GetMemory().SetFlagMutated(mut_point);
- GetMemory().SetFlagPointMut(mut_point);
- //organism->GetPhenotype().IsMutated() = true;
- organism->CPUStats().mut_stats.point_mut_count++;
-}
-
-int cHardwareCPU::PointMutate(cAvidaContext& ctx, const double mut_rate)
-{
- const int num_muts =
- ctx.GetRandom().GetRandBinomial(GetMemory().GetSize(), mut_rate);
-
- for (int i = 0; i < num_muts; i++) {
- const int pos = ctx.GetRandom().GetUInt(GetMemory().GetSize());
- Mutate(ctx, pos);
- }
-
- return num_muts;
-}
-
-
-// Trigger mutations of a specific type. Outside triggers cannot specify
-// a head since hardware types are not known.
-
-bool cHardwareCPU::TriggerMutations(cAvidaContext& ctx, int trigger)
-{
- // Only update triggers should happen from the outside!
- assert(trigger == nMutation::TRIGGER_UPDATE);
-
- // Assume instruction pointer is the intended target (if one is even
- // needed!
-
- return TriggerMutations(ctx, trigger, IP());
-}
-
-bool cHardwareCPU::TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU & cur_head)
-{
- // Collect information about mutations from the organism.
- cLocalMutations & mut_info = organism->GetLocalMutations();
- const tList<cMutation> & mut_list =
- mut_info.GetMutationLib().GetMutationList(trigger);
-
- // If we have no mutations for this trigger, stop here.
- if (mut_list.GetSize() == 0) return false;
- bool has_mutation = false;
-
- // Determine what memory this mutation will be affecting.
- cCPUMemory & target_mem = (trigger == nMutation::TRIGGER_DIVIDE)
- ? organism->ChildGenome() : GetMemory();
-
- // Loop through all mutations associated with this trigger and test them.
- tConstListIterator<cMutation> mut_it(mut_list);
-
- while (mut_it.Next() != NULL) {
- const cMutation * cur_mut = mut_it.Get();
- const int mut_id = cur_mut->GetID();
- const int scope = cur_mut->GetScope();
- const double rate = mut_info.GetRate(mut_id);
- switch (scope) {
- case nMutation::SCOPE_GENOME:
- if (TriggerMutations_ScopeGenome(ctx, cur_mut, target_mem, cur_head, rate)) {
- has_mutation = true;
- mut_info.IncCount(mut_id);
- }
- break;
- case nMutation::SCOPE_LOCAL:
- case nMutation::SCOPE_PROP:
- if (TriggerMutations_ScopeLocal(ctx, cur_mut, target_mem, cur_head, rate)) {
- has_mutation = true;
- mut_info.IncCount(mut_id);
- }
- break;
- case nMutation::SCOPE_GLOBAL:
- case nMutation::SCOPE_SPREAD:
- int num_muts =
- TriggerMutations_ScopeGlobal(ctx, cur_mut, target_mem, cur_head, rate);
- if (num_muts > 0) {
- has_mutation = true;
- mut_info.IncCount(mut_id, num_muts);
- }
- break;
- }
- }
-
- return has_mutation;
-}
-
-bool cHardwareCPU::TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut,
- cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
- // The rate we have stored indicates the probability that a single
- // mutation will occur anywhere in the genome.
-
- if (ctx.GetRandom().P(rate) == true) {
- // We must create a temporary head and use it to randomly determine the
- // position in the genome to be mutated.
- cHeadCPU tmp_head(cur_head);
- tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
- TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
- return true;
- }
- return false;
-}
-
-bool cHardwareCPU::TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut,
- cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
- // The rate we have stored is the probability for a mutation at this single
- // position in the genome.
-
- if (ctx.GetRandom().P(rate) == true) {
- TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, cur_head);
- return true;
- }
- return false;
-}
-
-int cHardwareCPU::TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation* cur_mut,
- cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
- // The probability we have stored is per-site, so we can pull a random
- // number from a binomial distribution to determine the number of mutations
- // that should occur.
-
- const int num_mut =
- ctx.GetRandom().GetRandBinomial(target_memory.GetSize(), rate);
-
- if (num_mut > 0) {
- for (int i = 0; i < num_mut; i++) {
- cHeadCPU tmp_head(cur_head);
- tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
- TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
- }
- }
-
- return num_mut;
-}
-
-void cHardwareCPU::TriggerMutations_Body(cAvidaContext& ctx, int type, cCPUMemory & target_memory,
- cHeadCPU & cur_head)
-{
- const int pos = cur_head.GetPosition();
-
- switch (type) {
- case nMutation::TYPE_POINT:
- target_memory[pos] = m_inst_set->GetRandomInst(ctx);
- target_memory.SetFlagMutated(pos);
- break;
- case nMutation::TYPE_INSERT:
- case nMutation::TYPE_DELETE:
- case nMutation::TYPE_HEAD_INC:
- case nMutation::TYPE_HEAD_DEC:
- case nMutation::TYPE_TEMP:
- case nMutation::TYPE_KILL:
- default:
- m_world->GetDriver().RaiseException("Mutation type not implemented!");
- break;
- };
-}
-
void cHardwareCPU::ReadInst(const int in_inst)
{
if (m_inst_set->IsNop( cInstruction(in_inst) )) {
@@ -1308,12 +1140,6 @@
}
-inline void cHardwareCPU::Fault(int fault_loc, int fault_type, cString fault_desc)
-{
- organism->Fault(fault_loc, fault_type, fault_desc);
-}
-
-
bool cHardwareCPU::Allocate_Necro(const int new_size)
{
GetMemory().ResizeOld(new_size);
@@ -1343,11 +1169,11 @@
{
// must do divide before second allocate & must allocate positive amount...
if (m_world->GetConfig().REQUIRE_ALLOCATE.Get() && mal_active == true) {
- Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR, "Allocate already active");
+ organism->Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR, "Allocate already active");
return false;
}
if (allocated_size < 1) {
- Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
+ organism->Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
cStringUtil::Stringf("Allocate of %d too small", allocated_size));
return false;
}
@@ -1357,7 +1183,7 @@
// Make sure that the new size is in range.
if (new_size > MAX_CREATURE_SIZE || new_size < MIN_CREATURE_SIZE) {
- Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
+ organism->Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
cStringUtil::Stringf("Invalid post-allocate size (%d)",
new_size));
return false;
@@ -1365,7 +1191,7 @@
const int max_alloc_size = (int) (old_size * m_world->GetConfig().CHILD_SIZE_RANGE.Get());
if (allocated_size > max_alloc_size) {
- Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
+ organism->Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
cStringUtil::Stringf("Allocate too large (%d > %d)",
allocated_size, max_alloc_size));
return false;
@@ -1374,7 +1200,7 @@
const int max_old_size =
(int) (allocated_size * m_world->GetConfig().CHILD_SIZE_RANGE.Get());
if (old_size > max_old_size) {
- Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
+ organism->Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
cStringUtil::Stringf("Allocate too small (%d > %d)",
old_size, max_old_size));
return false;
@@ -1397,287 +1223,24 @@
return true;
}
-
-bool cHardwareCPU::Divide_CheckViable(cAvidaContext& ctx, const int child_size,
- const int parent_size)
+int cHardwareCPU::GetCopiedSize(const int parent_size, const int child_size)
{
- // Make sure the organism is okay with dividing now...
- if (organism->Divide_CheckViable() == false) return false; // (divide fails)
-
- // If required, make sure an allocate has occured.
- if (m_world->GetConfig().REQUIRE_ALLOCATE.Get() && mal_active == false) {
- Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR, "Must allocate before divide");
- return false; // (divide fails)
- }
-
- // Make sure that neither parent nor child will be below the minimum size.
-
- const int genome_size = organism->GetGenome().GetSize();
- const double size_range = m_world->GetConfig().CHILD_SIZE_RANGE.Get();
- const int min_size = Max(MIN_CREATURE_SIZE, (int) (genome_size/size_range));
- const int max_size = Min(MAX_CREATURE_SIZE, (int) (genome_size*size_range));
-
- if (child_size < min_size || child_size > max_size) {
- Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
- cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
- return false; // (divide fails)
- }
- if (parent_size < min_size || parent_size > max_size) {
- Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
- cStringUtil::Stringf("Invalid post-divide length (%d)",parent_size));
- return false; // (divide fails)
- }
-
- // Count the number of lines executed in the parent, and make sure the
- // specified fraction has been reached.
-
- int executed_size = 0;
- for (int i = 0; i < parent_size; i++) {
- if (GetMemory().FlagExecuted(i)) executed_size++;
- }
-
- const int min_exe_lines = (int) (parent_size * m_world->GetConfig().MIN_EXE_LINES.Get());
- if (executed_size < min_exe_lines) {
- Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
- cStringUtil::Stringf("Too few executed lines (%d < %d)",
- executed_size, min_exe_lines));
- return false; // (divide fails)
- }
-
- // Count the number of lines which were copied into the child, and make
- // sure the specified fraction has been reached.
-
int copied_size = 0;
+ const cCPUMemory& memory = GetMemory();
for (int i = parent_size; i < parent_size + child_size; i++) {
- if (GetMemory().FlagCopied(i)) copied_size++;
+ if (memory.FlagCopied(i)) copied_size++;
}
-
- const int min_copied = (int) (child_size * m_world->GetConfig().MIN_COPIED_LINES.Get());
- if (copied_size < min_copied) {
- Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
- cStringUtil::Stringf("Too few copied commands (%d < %d)",
- copied_size, min_copied));
- return false; // (divide fails)
- }
-
- // Save the information we collected here...
- cPhenotype & phenotype = organism->GetPhenotype();
- phenotype.SetLinesExecuted(executed_size);
- phenotype.SetLinesCopied(copied_size);
-
- // Determine the fitness of this organism as compared to its parent...
- if (m_world->GetTestSterilize() == true &&
- phenotype.IsInjected() == false) {
- const int merit_base = phenotype.CalcSizeMerit();
- const double cur_fitness =
- merit_base * phenotype.GetCurBonus() / phenotype.GetTimeUsed();
- const double fitness_ratio = cur_fitness / phenotype.GetLastFitness();
-
-
- // const double neut_min = parent_fitness * nHardware::FITNESS_NEUTRAL_MIN;
- // const double neut_max = parent_fitness * nHardware::FITNESS_NEUTRAL_MAX;
-
- bool sterilize = false;
-
- if (fitness_ratio < nHardware::FITNESS_NEUTRAL_MIN) {
- if (ctx.GetRandom().P(organism->GetSterilizeNeg())) sterilize = true;
- } else if (fitness_ratio <= nHardware::FITNESS_NEUTRAL_MAX) {
- if (ctx.GetRandom().P(organism->GetSterilizeNeut())) sterilize = true;
- } else {
- if (ctx.GetRandom().P(organism->GetSterilizePos())) sterilize = true;
- }
-
- if (sterilize == true) {
- //Don't let this organism have this or any more children!
- phenotype.IsFertile() = false;
- return false;
- }
- }
-
- return true; // (divide succeeds!)
-}
+ return copied_size;
+}
-void cHardwareCPU::Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier)
-{
- sCPUStats & cpu_stats = organism->CPUStats();
- cCPUMemory & child_genome = organism->ChildGenome();
-
- organism->GetPhenotype().SetDivType(mut_multiplier);
-
- // Divide Mutations
- if (organism->TestDivideMut(ctx)) {
- const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
- child_genome[mut_line] = m_inst_set->GetRandomInst(ctx);
- cpu_stats.mut_stats.divide_mut_count++;
- }
-
- // Divide Insertions
- if (organism->TestDivideIns(ctx) && child_genome.GetSize() < MAX_CREATURE_SIZE){
- const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
- child_genome.Insert(mut_line, m_inst_set->GetRandomInst(ctx));
- cpu_stats.mut_stats.divide_insert_mut_count++;
- }
-
- // Divide Deletions
- if (organism->TestDivideDel(ctx) && child_genome.GetSize() > MIN_CREATURE_SIZE){
- const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
- child_genome.Remove(mut_line);
- cpu_stats.mut_stats.divide_delete_mut_count++;
- }
-
- // Divide Mutations (per site)
- if(organism->GetDivMutProb() > 0){
- int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
- organism->GetDivMutProb() / mut_multiplier);
- // If we have lines to mutate...
- if( num_mut > 0 ){
- for (int i = 0; i < num_mut; i++) {
- int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
- child_genome[site] = m_inst_set->GetRandomInst(ctx);
- cpu_stats.mut_stats.div_mut_count++;
- }
- }
- }
-
-
- // Insert Mutations (per site)
- if(organism->GetInsMutProb() > 0){
- int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
- organism->GetInsMutProb());
- // If would make creature to big, insert up to MAX_CREATURE_SIZE
- if( num_mut + child_genome.GetSize() > MAX_CREATURE_SIZE ){
- num_mut = MAX_CREATURE_SIZE - child_genome.GetSize();
- }
- // If we have lines to insert...
- if( num_mut > 0 ){
- // Build a list of the sites where mutations occured
- static int mut_sites[MAX_CREATURE_SIZE];
- for (int i = 0; i < num_mut; i++) {
- mut_sites[i] = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
- }
- // Sort the list
- qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
- // Actually do the mutations (in reverse sort order)
- for(int i = num_mut-1; i >= 0; i--) {
- child_genome.Insert(mut_sites[i], m_inst_set->GetRandomInst(ctx));
- cpu_stats.mut_stats.insert_mut_count++;
- }
- }
- }
-
-
- // Delete Mutations (per site)
- if( organism->GetDelMutProb() > 0 ){
- int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
- organism->GetDelMutProb());
- // If would make creature too small, delete down to MIN_CREATURE_SIZE
- if (child_genome.GetSize() - num_mut < MIN_CREATURE_SIZE) {
- num_mut = child_genome.GetSize() - MIN_CREATURE_SIZE;
- }
-
- // If we have lines to delete...
- for (int i = 0; i < num_mut; i++) {
- int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
- child_genome.Remove(site);
- cpu_stats.mut_stats.delete_mut_count++;
- }
- }
-
- // Mutations in the parent's genome
- if (organism->GetParentMutProb() > 0) {
- for (int i = 0; i < GetMemory().GetSize(); i++) {
- if (organism->TestParentMut(ctx)) {
- GetMemory()[i] = m_inst_set->GetRandomInst(ctx);
- cpu_stats.mut_stats.parent_mut_line_count++;
- }
- }
- }
-
-
- // Count up mutated lines
- for(int i = 0; i < GetMemory().GetSize(); i++){
- if (GetMemory().FlagPointMut(i)) {
- cpu_stats.mut_stats.point_mut_line_count++;
- }
- }
- for(int i = 0; i < child_genome.GetSize(); i++){
- if( child_genome.FlagCopyMut(i)) {
- cpu_stats.mut_stats.copy_mut_line_count++;
- }
- }
-}
-
-
-// test whether the offspring creature contains an advantageous mutation.
-void cHardwareCPU::Divide_TestFitnessMeasures(cAvidaContext& ctx)
-{
- cPhenotype & phenotype = organism->GetPhenotype();
- phenotype.CopyTrue() = ( organism->ChildGenome() == organism->GetGenome() );
- phenotype.ChildFertile() = true;
-
- // Only continue if we're supposed to do a fitness test on divide...
- if (organism->GetTestOnDivide() == false) return;
-
- // If this was a perfect copy, then we don't need to worry about any other
- // tests... Theoretically, we need to worry about the parent changing,
- // but as long as the child is always compared to the original genotype,
- // this won't be an issue.
- if (phenotype.CopyTrue() == true) return;
-
- const double parent_fitness = organism->GetTestFitness();
- const double neut_min = parent_fitness * nHardware::FITNESS_NEUTRAL_MIN;
- const double neut_max = parent_fitness * nHardware::FITNESS_NEUTRAL_MAX;
-
- cTestCPU* testcpu = m_world->GetHardwareManager().CreateTestCPU();
- cCPUTestInfo test_info;
- test_info.UseRandomInputs();
- testcpu->TestGenome(ctx, test_info, organism->ChildGenome());
- const double child_fitness = test_info.GetGenotypeFitness();
- delete testcpu;
-
- bool revert = false;
- bool sterilize = false;
-
- // If implicit mutations are turned off, make sure this won't spawn one.
- if (organism->GetFailImplicit() == true) {
- if (test_info.GetMaxDepth() > 0) sterilize = true;
- }
-
- if (child_fitness == 0.0) {
- // Fatal mutation... test for reversion.
- if (ctx.GetRandom().P(organism->GetRevertFatal())) revert = true;
- if (ctx.GetRandom().P(organism->GetSterilizeFatal())) sterilize = true;
- } else if (child_fitness < neut_min) {
- if (ctx.GetRandom().P(organism->GetRevertNeg())) revert = true;
- if (ctx.GetRandom().P(organism->GetSterilizeNeg())) sterilize = true;
- } else if (child_fitness <= neut_max) {
- if (ctx.GetRandom().P(organism->GetRevertNeut())) revert = true;
- if (ctx.GetRandom().P(organism->GetSterilizeNeut())) sterilize = true;
- } else {
- if (ctx.GetRandom().P(organism->GetRevertPos())) revert = true;
- if (ctx.GetRandom().P(organism->GetSterilizePos())) sterilize = true;
- }
-
- // Ideally, we won't have reversions and sterilizations turned on at the
- // same time, but if we do, give revert the priority.
- if (revert == true) {
- organism->ChildGenome() = organism->GetGenome();
- }
-
- if (sterilize == true) {
- organism->GetPhenotype().ChildFertile() = false;
- }
-}
-
-
bool cHardwareCPU::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, child_size, div_point);
+ 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
@@ -2195,7 +1758,7 @@
const int value = GetRegister(reg_used);
if (value > 1) GetRegister(reg_used) = (int) sqrt((double) value);
else if (value < 0) {
- Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "sqrt: value is negative");
+ organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "sqrt: value is negative");
return false;
}
return true;
@@ -2207,7 +1770,7 @@
const int value = GetRegister(reg_used);
if (value >= 1) GetRegister(reg_used) = (int) log((double) value);
else if (value < 0) {
- Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "log: value is negative");
+ organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "log: value is negative");
return false;
}
return true;
@@ -2219,7 +1782,7 @@
const int value = GetRegister(reg_used);
if (value >= 1) GetRegister(reg_used) = (int) log10((double) value);
else if (value < 0) {
- Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "log10: value is negative");
+ organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "log10: value is negative");
return false;
}
return true;
@@ -2258,11 +1821,11 @@
const int reg_used = FindModifiedRegister(nHardwareCPU::REG_BX);
if (GetRegister(nHardwareCPU::REG_CX) != 0) {
if (0-INT_MAX > GetRegister(nHardwareCPU::REG_BX) && GetRegister(nHardwareCPU::REG_CX) == -1)
- Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
+ organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
else
GetRegister(reg_used) = GetRegister(nHardwareCPU::REG_BX) / GetRegister(nHardwareCPU::REG_CX);
} else {
- Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
+ organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
return false;
}
return true;
@@ -2274,7 +1837,7 @@
if (GetRegister(nHardwareCPU::REG_CX) != 0) {
GetRegister(reg_used) = GetRegister(nHardwareCPU::REG_BX) % GetRegister(nHardwareCPU::REG_CX);
} else {
- Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
+ organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
return false;
}
return true;
@@ -2569,11 +2132,11 @@
// Make sure the creature will still be above the minimum size,
if (inject_size <= 0) {
- Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
+ organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
return false; // (inject fails)
}
if (start_pos < MIN_CREATURE_SIZE) {
- Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
+ organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
return false; // (inject fails)
}
@@ -2590,7 +2153,7 @@
// If there is no label, abort.
if (GetLabel().GetSize() == 0) {
- Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: label required");
+ organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: label required");
return false; // (inject fails)
}
@@ -2599,7 +2162,7 @@
const bool inject_signal = host_organism->GetHardware().InjectHost(GetLabel(), inject_code);
if (inject_signal) {
- Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: host too large.");
+ organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: host too large.");
return false; // Inject failed.
}
@@ -2636,11 +2199,11 @@
// Make sure the creature will still be above the minimum size,
if (inject_size <= 0) {
- Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
+ organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
return false; // (inject fails)
}
if (start_pos < MIN_CREATURE_SIZE) {
- Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
+ organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
return false; // (inject fails)
}
@@ -2657,7 +2220,7 @@
// If there is no label, abort.
if (GetLabel().GetSize() == 0) {
- Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: label required");
+ organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: label required");
return false; // (inject fails)
}
@@ -3036,13 +2599,13 @@
bool cHardwareCPU::Inst_ForkThread(cAvidaContext& ctx)
{
IP().Advance();
- if (!ForkThread()) Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
+ if (!ForkThread()) organism->Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
return true;
}
bool cHardwareCPU::Inst_KillThread(cAvidaContext& ctx)
{
- if (!KillThread()) Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
+ if (!KillThread()) organism->Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
else advance_ip = false;
return true;
}
Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h 2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardwareCPU.h 2006-04-14 18:17:00 UTC (rev 616)
@@ -67,7 +67,7 @@
public:
typedef bool (cHardwareCPU::*tHardwareCPUMethod)(cAvidaContext& ctx);
-private:
+protected:
static cInstLibCPU* s_inst_slib;
static cInstLibCPU* initInstLib(void);
@@ -92,7 +92,57 @@
tArray<int> inst_ft_cost;
#endif
+
+ bool SingleProcess_PayCosts(cAvidaContext& ctx, const cInstruction& cur_inst);
+ 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();
+
+
+ // -------- Head Manipulation (including IP) --------
+ cHeadCPU& GetActiveHead() { return threads[cur_thread].heads[threads[cur_thread].cur_head]; }
+ void AdjustHeads();
+
+
+ // -------- Label Manipulation -------
+ 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);
+ cHeadCPU FindFullLabel(const cCodeLabel & in_label);
+ const cCodeLabel& GetReadLabel() const { return threads[cur_thread].read_label; }
+ cCodeLabel& GetReadLabel() { return threads[cur_thread].read_label; }
+
+
+
+ // ---------- Instruction Helpers -----------
+ int FindModifiedRegister(int default_register);
+ int FindModifiedHead(int default_head);
+ int FindComplementRegister(int base_reg);
+
+ bool Allocate_Necro(const int new_size);
+ bool Allocate_Random(cAvidaContext& ctx, const int old_size, const int new_size);
+ bool Allocate_Default(const int new_size);
+ 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);
+
+ 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);
+
cHardwareCPU& operator=(const cHardwareCPU&); // @not_implemented
public:
@@ -173,12 +223,6 @@
}
- // -------- Mutation --------
- int PointMutate(cAvidaContext& ctx, const double mut_rate);
- bool TriggerMutations(cAvidaContext& ctx, int trigger);
- bool TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head);
-
-
// Non-Standard Methods
int GetActiveStack() const { return threads[cur_thread].cur_stack; }
@@ -385,71 +429,6 @@
//// Placebo ////
bool Inst_Skip(cAvidaContext& ctx);
-
-
- // Internal Implementation
-
- bool SingleProcess_PayCosts(cAvidaContext& ctx, const cInstruction& cur_inst);
- 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();
-
-
- // -------- Head Manipulation (including IP) --------
- cHeadCPU& GetActiveHead() { return threads[cur_thread].heads[threads[cur_thread].cur_head]; }
- void AdjustHeads();
-
-
- // -------- Label Manipulation -------
- 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);
- cHeadCPU FindFullLabel(const cCodeLabel & in_label);
- const cCodeLabel& GetReadLabel() const { return threads[cur_thread].read_label; }
- cCodeLabel& GetReadLabel() { return threads[cur_thread].read_label; }
-
-
- bool TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut,
- cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
- bool TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut,
- cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
- int TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation* cur_mut,
- cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
- void TriggerMutations_Body(cAvidaContext& ctx, int type, cCPUMemory& target_memory, cHeadCPU& cur_head);
-
-
- // ---------- Instruction Helpers -----------
- int FindModifiedRegister(int default_register);
- int FindModifiedHead(int default_head);
- int FindComplementRegister(int base_reg);
-
- void Fault(int fault_loc, int fault_type, cString fault_desc="");
-
- bool Allocate_Necro(const int new_size);
- bool Allocate_Random(cAvidaContext& ctx, const int old_size, const int new_size);
- bool Allocate_Default(const int new_size);
- bool Allocate_Main(cAvidaContext& ctx, const int allocated_size);
-
- bool Divide_Main(cAvidaContext& ctx, const int divide_point, const int extra_lines=0, double mut_multiplier=1);
- bool Divide_CheckViable(cAvidaContext& ctx, const int child_size, const int parent_size);
- void Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier=1);
- void Divide_TestFitnessMeasures(cAvidaContext& ctx);
- void Mutate(cAvidaContext& ctx, const int mut_point);
-
- void InjectCode(const cGenome& injection, const int line_num);
- void InjectCodeThread(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);
};
Modified: development/source/cpu/cHardwareSMT.cc
===================================================================
--- development/source/cpu/cHardwareSMT.cc 2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardwareSMT.cc 2006-04-14 18:17:00 UTC (rev 616)
@@ -700,12 +700,12 @@
// Make sure the creature will still be above the minimum size
if (end_pos <= 0) {
- Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
+ organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
return false; // (inject fails)
}
if (end_pos < MIN_INJECT_SIZE) {
m_mem_array[mem_space_used] = cGenome("a");
- Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
+ organism->Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
return false; // (inject fails)
}
@@ -742,168 +742,7 @@
return true;
}
-void cHardwareSMT::Mutate(cAvidaContext& ctx, int mut_point)
-{
- // Test if trying to mutate outside of genome...
- assert(mut_point >= 0 && mut_point < m_mem_array[0].GetSize());
-
- m_mem_array[0][mut_point] = m_inst_set->GetRandomInst(ctx);
- m_mem_array[0].SetFlagMutated(mut_point);
- m_mem_array[0].SetFlagPointMut(mut_point);
- organism->CPUStats().mut_stats.point_mut_count++;
-}
-int cHardwareSMT::PointMutate(cAvidaContext& ctx, const double mut_rate)
-{
- const int num_muts = ctx.GetRandom().GetRandBinomial(m_mem_array[0].GetSize(), mut_rate);
-
- for (int i = 0; i < num_muts; i++) {
- const int pos = ctx.GetRandom().GetUInt(m_mem_array[0].GetSize());
- Mutate(ctx, pos);
- }
-
- return num_muts;
-}
-
-
-// Trigger mutations of a specific type. Outside triggers cannot specify
-// a head since hardware types are not known.
-
-bool cHardwareSMT::TriggerMutations(cAvidaContext& ctx, int trigger)
-{
- // Only update triggers should happen from the outside!
- assert(trigger == nMutation::TRIGGER_UPDATE);
-
- // Assume instruction pointer is the intended target (if one is even
- // needed!
-
- return TriggerMutations(ctx, trigger, IP());
-}
-
-bool cHardwareSMT::TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head)
-{
- // Collect information about mutations from the organism.
- cLocalMutations& mut_info = organism->GetLocalMutations();
- const tList<cMutation> & mut_list =
- mut_info.GetMutationLib().GetMutationList(trigger);
-
- // If we have no mutations for this trigger, stop here.
- if (mut_list.GetSize() == 0) return false;
- bool has_mutation = false;
-
- // Determine what memory this mutation will be affecting.
- cCPUMemory & target_mem = (trigger == nMutation::TRIGGER_DIVIDE)
- ? organism->ChildGenome() : m_mem_array[0];
-
- // Loop through all mutations associated with this trigger and test them.
- tConstListIterator<cMutation> mut_it(mut_list);
-
- while (mut_it.Next() != NULL) {
- const cMutation * cur_mut = mut_it.Get();
- const int mut_id = cur_mut->GetID();
- const int scope = cur_mut->GetScope();
- const double rate = mut_info.GetRate(mut_id);
- switch (scope) {
- case nMutation::SCOPE_GENOME:
- if (TriggerMutations_ScopeGenome(ctx, cur_mut, target_mem, cur_head, rate)) {
- has_mutation = true;
- mut_info.IncCount(mut_id);
- }
- break;
- case nMutation::SCOPE_LOCAL:
- case nMutation::SCOPE_PROP:
- if (TriggerMutations_ScopeLocal(ctx, cur_mut, target_mem, cur_head, rate)) {
- has_mutation = true;
- mut_info.IncCount(mut_id);
- }
- break;
- case nMutation::SCOPE_GLOBAL:
- case nMutation::SCOPE_SPREAD:
- int num_muts =
- TriggerMutations_ScopeGlobal(ctx, cur_mut, target_mem, cur_head, rate);
- if (num_muts > 0) {
- has_mutation = true;
- mut_info.IncCount(mut_id, num_muts);
- }
- break;
- }
- }
-
- return has_mutation;
-}
-
-bool cHardwareSMT::TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut,
- cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
- // The rate we have stored indicates the probability that a single
- // mutation will occur anywhere in the genome.
-
- if (ctx.GetRandom().P(rate) == true) {
- // We must create a temporary head and use it to randomly determine the
- // position in the genome to be mutated.
- cHeadCPU tmp_head(cur_head);
- tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
- TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
- return true;
- }
- return false;
-}
-
-bool cHardwareSMT::TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut,
- cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate)
-{
- // The rate we have stored is the probability for a mutation at this single
- // position in the genome.
-
- if (ctx.GetRandom().P(rate) == true) {
- TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, cur_head);
- return true;
- }
- return false;
-}
-
-int cHardwareSMT::TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation * cur_mut,
- cCPUMemory & target_memory, cHeadCPU& cur_head, const double rate)
-{
- // The probability we have stored is per-site, so we can pull a random
- // number from a binomial distribution to determine the number of mutations
- // that should occur.
-
- const int num_mut =
- ctx.GetRandom().GetRandBinomial(target_memory.GetSize(), rate);
-
- if (num_mut > 0) {
- for (int i = 0; i < num_mut; i++) {
- cHeadCPU tmp_head(cur_head);
- tmp_head.AbsSet(ctx.GetRandom().GetUInt(target_memory.GetSize()));
- TriggerMutations_Body(ctx, cur_mut->GetType(), target_memory, tmp_head);
- }
- }
-
- return num_mut;
-}
-
-void cHardwareSMT::TriggerMutations_Body(cAvidaContext& ctx, int type, cCPUMemory & target_memory, cHeadCPU& cur_head)
-{
- const int pos = cur_head.GetPosition();
-
- switch (type) {
- case nMutation::TYPE_POINT:
- target_memory[pos] = m_inst_set->GetRandomInst(ctx);
- target_memory.SetFlagMutated(pos);
- break;
- case nMutation::TYPE_INSERT:
- case nMutation::TYPE_DELETE:
- case nMutation::TYPE_HEAD_INC:
- case nMutation::TYPE_HEAD_DEC:
- case nMutation::TYPE_TEMP:
- case nMutation::TYPE_KILL:
- default:
- m_world->GetDriver().RaiseException("Mutation type not implemented!");
- break;
- };
-}
-
void cHardwareSMT::ReadInst(const int in_inst)
{
if (m_inst_set->IsNop( cInstruction(in_inst) )) {
@@ -1069,179 +908,17 @@
return (base_stack + 2) % nHardwareSMT::NUM_STACKS;
}
-inline void cHardwareSMT::Fault(int fault_loc, int fault_type, cString fault_desc)
-{
- organism->Fault(fault_loc, fault_type, fault_desc);
-}
-bool cHardwareSMT::Divide_CheckViable(cAvidaContext& ctx, const int parent_size,
- const int child_size, const int mem_space)
+int cHardwareSMT::GetCopiedSize(const int parent_size, const int child_size)
{
- // Make sure the organism is okay with dividing now...
- if (organism->Divide_CheckViable() == false) return false; // (divide fails)
-
- // Make sure that neither parent nor child will be below the minimum size.
-
- const int genome_size = organism->GetGenome().GetSize();
- const double size_range = m_world->GetConfig().CHILD_SIZE_RANGE.Get();
- const int min_size = Max(MIN_CREATURE_SIZE, (int) (genome_size/size_range));
- const int max_size = Min(MAX_CREATURE_SIZE, (int) (genome_size*size_range));
-
- if (child_size < min_size || child_size > max_size) {
- Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
- cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
- return false; // (divide fails)
- }
-
- // Count the number of lines executed in the parent, and make sure the
- // specified fraction has been reached.
-
- int executed_size = 0;
- for (int i = 0; i < parent_size; i++) {
- if (m_mem_array[0].FlagExecuted(i)) executed_size++;
- }
-
- const int min_exe_lines = (int) (parent_size * m_world->GetConfig().MIN_EXE_LINES.Get());
- if (executed_size < min_exe_lines) {
- Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
- cStringUtil::Stringf("Too few executed lines (%d < %d)",
- executed_size, min_exe_lines));
- return false; // (divide fails)
- }
-
- // Count the number of lines which were copied into the child, and make
- // sure the specified fraction has been reached.
-
int copied_size = 0;
- for (int i = 0; i < m_mem_array[mem_space].GetSize(); i++) {
- if (m_mem_array[mem_space].FlagCopied(i)) copied_size++;
+ const cCPUMemory& memory = m_mem_array[m_cur_child];
+ for (int i = 0; i < memory.GetSize(); i++) {
+ if (memory.FlagCopied(i)) copied_size++;
}
-
- const int min_copied = static_cast<int>(child_size * m_world->GetConfig().MIN_COPIED_LINES.Get());
- if (copied_size < min_copied) {
- Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
- cStringUtil::Stringf("Too few copied commands (%d < %d)",
- copied_size, min_copied));
- return false; // (divide fails)
- }
-
- // Save the information we collected here...
- organism->GetPhenotype().SetLinesExecuted(executed_size);
- organism->GetPhenotype().SetLinesCopied(copied_size);
-
- return true; // (divide succeeds!)
+ return copied_size;
}
-void cHardwareSMT::Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier)
-{
- sCPUStats& cpu_stats = organism->CPUStats();
- cCPUMemory& child_genome = organism->ChildGenome();
-
- organism->GetPhenotype().SetDivType(mut_multiplier);
-
- // Divide Mutations
- if (organism->TestDivideMut(ctx)) {
- const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
- child_genome[mut_line] = m_inst_set->GetRandomInst(ctx);
- cpu_stats.mut_stats.divide_mut_count++;
- }
-
- // Divide Insertions
- if (organism->TestDivideIns(ctx) && child_genome.GetSize() < MAX_CREATURE_SIZE){
- const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
- child_genome.Insert(mut_line, m_inst_set->GetRandomInst(ctx));
- cpu_stats.mut_stats.divide_insert_mut_count++;
- }
-
- // Divide Deletions
- if (organism->TestDivideDel(ctx) && child_genome.GetSize() > MIN_CREATURE_SIZE){
- const unsigned int mut_line = ctx.GetRandom().GetUInt(child_genome.GetSize());
- child_genome.Remove(mut_line);
- cpu_stats.mut_stats.divide_delete_mut_count++;
- }
-
- // Divide Mutations (per site)
- if(organism->GetDivMutProb() > 0){
- int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
- organism->GetDivMutProb() / mut_multiplier);
- // If we have lines to mutate...
- if( num_mut > 0 ){
- for (int i = 0; i < num_mut; i++) {
- int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
- child_genome[site] = m_inst_set->GetRandomInst(ctx);
- cpu_stats.mut_stats.div_mut_count++;
- }
- }
- }
-
-
- // Insert Mutations (per site)
- if(organism->GetInsMutProb() > 0){
- int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
- organism->GetInsMutProb());
- // If would make creature to big, insert up to MAX_CREATURE_SIZE
- if( num_mut + child_genome.GetSize() > MAX_CREATURE_SIZE ){
- num_mut = MAX_CREATURE_SIZE - child_genome.GetSize();
- }
- // If we have lines to insert...
- if( num_mut > 0 ){
- // Build a list of the sites where mutations occured
- static int mut_sites[MAX_CREATURE_SIZE];
- for (int i = 0; i < num_mut; i++) {
- mut_sites[i] = ctx.GetRandom().GetUInt(child_genome.GetSize() + 1);
- }
- // Sort the list
- qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
- // Actually do the mutations (in reverse sort order)
- for(int i = num_mut-1; i >= 0; i--) {
- child_genome.Insert(mut_sites[i], m_inst_set->GetRandomInst(ctx));
- cpu_stats.mut_stats.insert_mut_count++;
- }
- }
- }
-
-
- // Delete Mutations (per site)
- if( organism->GetDelMutProb() > 0 ){
- int num_mut = ctx.GetRandom().GetRandBinomial(child_genome.GetSize(),
- organism->GetDelMutProb());
- // If would make creature too small, delete down to MIN_CREATURE_SIZE
- if (child_genome.GetSize() - num_mut < MIN_CREATURE_SIZE) {
- num_mut = child_genome.GetSize() - MIN_CREATURE_SIZE;
- }
-
- // If we have lines to delete...
- for (int i = 0; i < num_mut; i++) {
- int site = ctx.GetRandom().GetUInt(child_genome.GetSize());
- child_genome.Remove(site);
- cpu_stats.mut_stats.delete_mut_count++;
- }
- }
-
- // Mutations in the parent's genome
- if (organism->GetParentMutProb() > 0) {
- for (int i = 0; i < m_mem_array[0].GetSize(); i++) {
- if (organism->TestParentMut(ctx)) {
- m_mem_array[0][i] = m_inst_set->GetRandomInst(ctx);
- cpu_stats.mut_stats.parent_mut_line_count++;
- }
- }
- }
-
-
- // Count up mutated lines
- for(int i = 0; i < m_mem_array[0].GetSize(); i++){
- if (m_mem_array[0].FlagPointMut(i)) {
- cpu_stats.mut_stats.point_mut_line_count++;
- }
- }
- for(int i = 0; i < child_genome.GetSize(); i++){
- if( child_genome.FlagCopyMut(i)) {
- cpu_stats.mut_stats.copy_mut_line_count++;
- }
- }
-}
-
void cHardwareSMT::Inject_DoMutations(cAvidaContext& ctx, double mut_multiplier, cCPUMemory & injected_code)
{
organism->GetPhenotype().SetDivType(mut_multiplier);
@@ -1331,82 +1008,20 @@
}
-// test whether the offspring creature contains an advantageous mutation.
-void cHardwareSMT::Divide_TestFitnessMeasures(cAvidaContext& ctx)
-{
- cPhenotype & phenotype = organism->GetPhenotype();
- phenotype.CopyTrue() = ( organism->ChildGenome() == organism->GetGenome() );
- phenotype.ChildFertile() = true;
-
- // Only continue if we're supposed to do a fitness test on divide...
- if (organism->GetTestOnDivide() == false) return;
-
- // If this was a perfect copy, then we don't need to worry about any other
- // tests... Theoretically, we need to worry about the parent changing,
- // but as long as the child is always compared to the original genotype,
- // this won't be an issue.
- if (phenotype.CopyTrue() == true) return;
-
- const double parent_fitness = organism->GetTestFitness();
- const double neut_min = parent_fitness * nHardware::FITNESS_NEUTRAL_MIN;
- const double neut_max = parent_fitness * nHardware::FITNESS_NEUTRAL_MAX;
-
- cTestCPU* testcpu = m_world->GetHardwareManager().CreateTestCPU();
- cCPUTestInfo test_info;
- test_info.UseRandomInputs();
- testcpu->TestGenome(ctx, test_info, organism->ChildGenome());
- const double child_fitness = test_info.GetGenotypeFitness();
- delete testcpu;
-
- bool revert = false;
- bool sterilize = false;
-
- // If implicit mutations are turned off, make sure this won't spawn one.
- if (organism->GetFailImplicit() == true) {
- if (test_info.GetMaxDepth() > 0) sterilize = true;
- }
-
- if (child_fitness == 0.0) {
- // Fatal mutation... test for reversion.
- if (ctx.GetRandom().P(organism->GetRevertFatal())) revert = true;
- if (ctx.GetRandom().P(organism->GetSterilizeFatal())) sterilize = true;
- } else if (child_fitness < neut_min) {
- if (ctx.GetRandom().P(organism->GetRevertNeg())) revert = true;
- if (ctx.GetRandom().P(organism->GetSterilizeNeg())) sterilize = true;
- } else if (child_fitness <= neut_max) {
- if (ctx.GetRandom().P(organism->GetRevertNeut())) revert = true;
- if (ctx.GetRandom().P(organism->GetSterilizeNeut())) sterilize = true;
- } else {
- if (ctx.GetRandom().P(organism->GetRevertPos())) revert = true;
- if (ctx.GetRandom().P(organism->GetSterilizePos())) sterilize = true;
- }
-
- // Ideally, we won't have reversions and sterilizations turned on at the
- // same time, but if we do, give revert the priority.
- if (revert == true) {
- organism->ChildGenome() = organism->GetGenome();
- }
-
- if (sterilize == true) {
- organism->GetPhenotype().ChildFertile() = false;
- }
-}
-
-
bool cHardwareSMT::Divide_Main(cAvidaContext& ctx, int mem_space_used, double mut_multiplier)
{
int write_head_pos = GetHead(nHardware::HEAD_WRITE).GetPosition();
- // @DMB - change to allow ???
// We're going to disallow division calls from memory spaces other than zero for right now @law
+ // @DMB - change to allow ???
if(IP().GetMemSpace() != 0) return false;
// Make sure the memory space we're using exists
if (m_mem_array.GetSize() <= mem_space_used) return false;
-
+
// Make sure this divide will produce a viable offspring.
- if(!Divide_CheckViable(ctx, m_mem_array[IP().GetMemSpace()].GetSize(), write_head_pos, mem_space_used))
- return false;
+ m_cur_child = mem_space_used; // save current child memory space for use by dependent functions (e.g. GetCopiedSize())
+ if (!Divide_CheckViable(ctx, m_mem_array[IP().GetMemSpace()].GetSize(), write_head_pos)) return false;
// Since the divide will now succeed, set up the information to be sent to the new organism
m_mem_array[mem_space_used].Resize(write_head_pos);
@@ -1574,11 +1189,11 @@
#endif
if (Stack(op2).Top() != 0) {
if (0-INT_MAX > Stack(op1).Top() && Stack(op2).Top() == -1)
- Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
+ organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
else
Stack(dst).Push(Stack(op1).Top() / Stack(op2).Top());
} else {
- Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
+ organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
return false;
}
return true;
@@ -1629,7 +1244,7 @@
else
Stack(dst).Push(Stack(op1).Top() % Stack(op2).Top());
} else {
- Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
+ organism->Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
return false;
}
return true;
@@ -1938,7 +1553,7 @@
bool cHardwareSMT::Inst_ThreadCreate(cAvidaContext& ctx)
{
if (!ForkThread())
- Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
+ organism->Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
else
IP().Advance();
return true;
@@ -1956,7 +1571,7 @@
//35
bool cHardwareSMT::Inst_ThreadExit(cAvidaContext& ctx)
{
- if (!KillThread()) Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
+ if (!KillThread()) organism->Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
else AdvanceIP() = false;
return true;
}
Modified: development/source/cpu/cHardwareSMT.h
===================================================================
--- development/source/cpu/cHardwareSMT.h 2006-04-14 17:24:47 UTC (rev 615)
+++ development/source/cpu/cHardwareSMT.h 2006-04-14 18:17:00 UTC (rev 616)
@@ -66,7 +66,7 @@
public:
typedef bool (cHardwareSMT::*tMethod)(cAvidaContext& ctx);
-private:
+protected:
static tInstLib<cHardwareSMT::tMethod>* s_inst_slib;
static tInstLib<cHardwareSMT::tMethod>* initInstLib(void);
@@ -89,6 +89,8 @@
tArray<int> inst_cost;
tArray<int> inst_ft_cost;
#endif
+
+ int m_cur_child;
bool SingleProcess_PayCosts(cAvidaContext& ctx, const cInstruction& cur_inst);
@@ -117,16 +119,7 @@
const cCodeLabel& GetReadLabel() const { return m_threads[m_cur_thread].read_label; }
cCodeLabel& GetReadLabel() { return m_threads[m_cur_thread].read_label; }
-
- bool TriggerMutations_ScopeGenome(cAvidaContext& ctx, const cMutation* cur_mut,
- cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
- bool TriggerMutations_ScopeLocal(cAvidaContext& ctx, const cMutation* cur_mut,
- cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
- int TriggerMutations_ScopeGlobal(cAvidaContext& ctx, const cMutation* cur_mut,
- cCPUMemory& target_memory, cHeadCPU& cur_head, const double rate);
- void TriggerMutations_Body(cAvidaContext& ctx, int type, cCPUMemory& target_memory,
- cHeadCPU& cur_head);
-
+
// ---------- Instruction Helpers -----------
int FindModifiedStack(int default_stack);
int FindModifiedNextStack(int default_stack);
@@ -139,18 +132,15 @@
int FindMemorySpaceLabel(const cCodeLabel& label, int mem_space);
bool MemorySpaceExists(const cCodeLabel& label);
- void Fault(int fault_loc, int fault_type, cString fault_desc="");
bool Allocate_Necro(const int new_size);
bool Allocate_Random(const int old_size, const int new_size);
bool Allocate_Default(const int new_size);
bool Allocate_Main(const int allocated_size);
-
- bool Divide_Main(cAvidaContext& ctx, const int mem_space_used, double mut_multiplier=1);
- bool Divide_CheckViable(cAvidaContext& ctx, const int parent_size, const int child_size, const int mem_space);
- void Divide_DoMutations(cAvidaContext& ctx, double mut_multiplier = 1);
+
+ int GetCopiedSize(const int parent_size, const int child_size);
+
+ bool Divide_Main(cAvidaContext& ctx, const int mem_space_used, double mut_multiplier = 1.0);
void Inject_DoMutations(cAvidaContext& ctx, double mut_multiplier, cCPUMemory& injected_code);
- void Divide_TestFitnessMeasures(cAvidaContext& ctx);
- void Mutate(cAvidaContext& ctx, const int mut_point);
bool InjectParasite(cAvidaContext& ctx, double mut_multiplier);
@@ -239,12 +229,6 @@
}
- // -------- Mutation --------
- int PointMutate(cAvidaContext& ctx, const double mut_rate);
- bool TriggerMutations(cAvidaContext& ctx, int trigger);
- bool TriggerMutations(cAvidaContext& ctx, int trigger, cHeadCPU& cur_head);
-
-
private:
// ---------- Instruction Library -----------
bool Inst_ShiftR(cAvidaContext& ctx);
More information about the Avida-cvs
mailing list