[Avida-SVN] r2129 - in development/source: cpu main

barrick at myxo.css.msu.edu barrick at myxo.css.msu.edu
Mon Oct 8 11:03:02 PDT 2007


Author: barrick
Date: 2007-10-08 14:03:01 -0400 (Mon, 08 Oct 2007)
New Revision: 2129

Modified:
   development/source/cpu/cHardwareCPU.cc
   development/source/cpu/cHardwareCPU.h
   development/source/main/cAvidaConfig.h
Log:
Various new logic promoter model instructions and improvements.


Modified: development/source/cpu/cHardwareCPU.cc
===================================================================
--- development/source/cpu/cHardwareCPU.cc	2007-10-08 17:56:28 UTC (rev 2128)
+++ development/source/cpu/cHardwareCPU.cc	2007-10-08 18:03:01 UTC (rev 2129)
@@ -362,8 +362,12 @@
     tInstLibEntry<tMethod>("promoter", &cHardwareCPU::Inst_Promoter),
     tInstLibEntry<tMethod>("terminate", &cHardwareCPU::Inst_Terminate),
     tInstLibEntry<tMethod>("regulate", &cHardwareCPU::Inst_Regulate),
+    tInstLibEntry<tMethod>("regulate-sp", &cHardwareCPU::Inst_RegulateSpecificPromoters),
+    tInstLibEntry<tMethod>("s-regulate", &cHardwareCPU::Inst_SenseRegulate),
     tInstLibEntry<tMethod>("numberate", &cHardwareCPU::Inst_Numberate),
+    tInstLibEntry<tMethod>("numberate-24", &cHardwareCPU::Inst_Numberate24),
     tInstLibEntry<tMethod>("bit-cons", &cHardwareCPU::Inst_BitConsensus),
+    tInstLibEntry<tMethod>("bit-cons-24", &cHardwareCPU::Inst_BitConsensus24),
 
     // Energy usage
     tInstLibEntry<tMethod>("double-energy-usage", &cHardwareCPU::Inst_DoubleEnergyUsage),
@@ -479,13 +483,12 @@
 
     m_promoter_index = -1; // Meaning the last promoter was nothing
     m_promoter_offset = 0;
-    m_promoter_regulation = 0;
     m_promoters.Resize(0);
     for (int i=0; i<GetMemory().GetSize(); i++)
     {
       if ( (GetMemory())[i] == promoter_inst)
       {
-        int code = Numberate(i-1, -1);
+        int code = Numberate(i-1, -1, m_world->GetConfig().PROMOTER_CODE_SIZE.Get());
         m_promoters.Push( cPromoter(i,code) );
       }
     }
@@ -565,11 +568,15 @@
     // Test if costs have been paid and it is okay to execute this now...
     bool exec = SingleProcess_PayCosts(ctx, cur_inst);
 
+    // Constitutive regulation applied here
+    if (m_world->GetConfig().CONSTITUTIVE_REGULATION.Get() == 1) {
+      Inst_SenseRegulate(ctx);
+    }
+    
     // If there are no active promoters and a certain mode is set, then don't execute any further instructions
     if ((m_world->GetConfig().PROMOTERS_ENABLED.Get() == 1) 
       && (m_world->GetConfig().NO_ACTIVE_PROMOTER_EFFECT.Get() == 2) 
-      && (m_promoter_index == -1) ) 
-    { 
+      && (m_promoter_index == -1) ) { 
       exec = false;
     }
     
@@ -733,11 +740,10 @@
   {
     fp << "Promoters: index=" << m_promoter_index << " offset=" << m_promoter_offset;
     fp << " exe_inst=" << m_threads[m_cur_thread].GetPromoterInstExecuted();
-    fp << " regulation=0x" << setbase(16) << setfill('0') << setw(8) << m_promoter_regulation << endl;
     for (int i=0; i<m_promoters.GetSize(); i++)
     {
-      fp << setfill(' ') << setbase(10) << i << "(" << m_promoters[i].m_pos << "):";
-      fp << "Ox" << setbase(16) << setfill('0') << setw(8) << (m_promoters[i].m_bit_code ^ m_promoter_regulation) << " "; 
+      fp << setfill(' ') << setbase(10) << m_promoters[i].m_pos << ":";
+      fp << "Ox" << setbase(16) << setfill('0') << setw(8) << (m_promoters[i].GetRegulatedBitCode()) << " "; 
     }
     fp << endl;    
     fp << setfill(' ') << setbase(10) << endl;
@@ -4299,8 +4305,6 @@
 {
   // Promoters don't do anything themselves
   return true;
-//  std::cerr<<"x = "<<pos.first<<"  y = "<<pos.second<<"  ans = "<<GetRegister(reg)<<std::endl;
-  return true;
 }
 
 // Move the instruction ptr to the next active promoter
@@ -4382,24 +4386,82 @@
   else
   {
     // We found an active match, offset to just after it.
-    // and put its bit code in BX for the organism to have
-      // cHeadCPU will do the mod genome size for us
+    // cHeadCPU will do the mod genome size for us
     IP().Set(m_promoters[m_promoter_index].m_pos + 1);
-    GetRegister(reg_used) = m_promoters[m_promoter_index].m_bit_code;
+    
+    // Put its bit code in BX for the organism to have if option is set
+    if ( m_world->GetConfig().PROMOTER_TO_REGISTER.Get() )
+    {
+      GetRegister(reg_used) = m_promoters[m_promoter_index].m_bit_code;
+    }
   }
   return true;
 }
 
-// Get a new regulation code (which is XOR'ed with promoter codes).
+// Set a new regulation code (which is XOR'ed with ALL promoter codes).
 bool cHardwareCPU::Inst_Regulate(cAvidaContext& ctx)
 {
   const int reg_used = FindModifiedRegister(REG_BX);
-  m_promoter_regulation = GetRegister(reg_used);
+  int regulation_code = GetRegister(reg_used);
+
+  for (int i=0; i< m_promoters.GetSize();i++)
+  {
+    m_promoters[i].m_regulation = regulation_code;
+  }
   return true;
 }
 
+// Set a new regulation code, but only on a subset of promoters.
+bool cHardwareCPU::Inst_RegulateSpecificPromoters(cAvidaContext& ctx)
+{
+  const int reg_used = FindModifiedRegister(REG_BX);
+  int regulation_code = GetRegister(reg_used);
+  
+  const int reg_promoter = FindModifiedRegister((reg_used+1) % NUM_REGISTERS);
+  int regulation_promoter = GetRegister(reg_promoter);
+  
+  for (int i=0; i< m_promoters.GetSize();i++)
+  {
+    //Look for consensus bit matches over the length of the promoter code
+    int test_p_code = m_promoters[i].m_bit_code;    
+    int test_r_code = regulation_promoter;
+    int bit_count = 0;
+    for (int j=0; j<m_world->GetConfig().PROMOTER_EXE_LENGTH.Get();j++)
+    {      
+      if ((test_p_code & 1) == (test_r_code & 1)) bit_count++;
+      test_p_code >>= 1;
+      test_r_code >>= 1;
+    }
+    if (bit_count >= m_world->GetConfig().PROMOTER_EXE_LENGTH.Get() / 2)
+    {
+      m_promoters[i].m_regulation = regulation_code;
+    }
+  }
+  return true;
+}
+
+
+bool cHardwareCPU::Inst_SenseRegulate(cAvidaContext& ctx)
+{
+  unsigned int bits = 0;
+  const tArray<double> & res_count = organism->GetOrgInterface().GetResources();
+  assert (res_count.GetSize() != 0);
+  for (int i=0; i<m_world->GetConfig().PROMOTER_CODE_SIZE.Get(); i++)
+  {
+    int b = i % res_count.GetSize();
+    bits <<= 1;
+    bits += (res_count[b] != 0);
+  }  
+  
+  for (int i=0; i< m_promoters.GetSize();i++)
+  {
+    m_promoters[i].m_regulation = bits;
+  }
+  return true;
+}
+
 // Create a number from inst bit codes
-bool cHardwareCPU::Inst_Numberate(cAvidaContext& ctx)
+bool cHardwareCPU::Do_Numberate(cAvidaContext& ctx, int num_bits)
 {
   const int reg_used = FindModifiedRegister(REG_BX);
   
@@ -4407,7 +4469,7 @@
   IP().Advance();
   m_advance_ip = false;
   
-  int num = Numberate(IP().GetPosition(), +1);
+  int num = Numberate(IP().GetPosition(), +1, num_bits);
   GetRegister(reg_used) = num;
   return true;
 }
@@ -4423,7 +4485,7 @@
     
     // Move offset, rolling over when there are not enough bits before we would have to wrap around left
     m_promoter_offset+=m_world->GetConfig().PROMOTER_EXE_LENGTH.Get();
-    if (m_promoter_offset + m_world->GetConfig().PROMOTER_EXE_LENGTH.Get() >= cHardwareCPU::PROMOTER_CODE_SIZE)
+    if (m_promoter_offset + m_world->GetConfig().PROMOTER_EXE_LENGTH.Get() >= m_world->GetConfig().PROMOTER_CODE_SIZE.Get())
     {
       m_promoter_offset = 0;
     }
@@ -4436,11 +4498,11 @@
 {
   assert( m_promoters.GetSize() != 0 );
   int count = 0;
-  unsigned int code = m_promoters[m_promoter_index].m_bit_code ^ m_promoter_regulation;
+  unsigned int code = m_promoters[m_promoter_index].GetRegulatedBitCode();
   for(int i=0; i<m_world->GetConfig().PROMOTER_EXE_LENGTH.Get(); i++)
   {
     int offset = m_promoter_offset + i;
-    offset %= cHardwareCPU::PROMOTER_CODE_SIZE;
+    offset %= m_world->GetConfig().PROMOTER_CODE_SIZE.Get();
     int state = code >> offset;
     count += (state & 1);
   }
@@ -4449,22 +4511,26 @@
 }
 
 // Construct a promoter bit code from instruction bit codes
-int cHardwareCPU::Numberate(int _pos, int _dir)
+int cHardwareCPU::Numberate(int _pos, int _dir, int _num_bits)
 {  
   int code_size = 0;
   unsigned int code = 0;
+  unsigned int max_bits = sizeof(code) * 8;
+  assert(_num_bits <= (int)max_bits);
+  if (_num_bits == 0) _num_bits = max_bits;
+  
   int j = _pos;
   j %= GetMemory().GetSize();
-  while (code_size < cHardwareCPU::PROMOTER_CODE_SIZE)
+  while (code_size < _num_bits)
   {
     unsigned int inst_code = (unsigned int) GetInstSet().GetInstructionCode( (GetMemory())[j] );
-    // shift bits in, one by one ... excuse the counter pun
-    for (int code_on = 0; (code_size < cHardwareCPU::PROMOTER_CODE_SIZE) && (code_on < m_world->GetConfig().INST_CODE_LENGTH.Get()); code_on++)
+    // shift bits in, one by one ... excuse the counter variable pun
+    for (int code_on = 0; (code_size < _num_bits) && (code_on < m_world->GetConfig().INST_CODE_LENGTH.Get()); code_on++)
     {
       if (_dir < 0)
       {
         code >>= 1; // shift first so we don't go one too far at the end
-        code += (1 << (cHardwareCPU::PROMOTER_CODE_SIZE - 1)) * (inst_code & 1);
+        code += (1 << (_num_bits - 1)) * (inst_code & 1);
         inst_code >>= 1; 
       }
       else
@@ -4481,21 +4547,35 @@
     j %= GetMemory().GetSize();
 
   }
+  
   return code;
 }
 
 /*! 
-  Sets BX to 1 if >=50% of the bits in the specified register
+  Sets BX to 1 if >=50% of the bits in the specified register places
   are 1's and zero otherwise.
 */
 
 bool cHardwareCPU::Inst_BitConsensus(cAvidaContext& ctx)
 {
+  return BitConsensus(ctx, sizeof(int) * 8);
+}
+
+// Looks at only the lower 24 bits
+bool cHardwareCPU::Inst_BitConsensus24(cAvidaContext& ctx)
+{
+  return BitConsensus(ctx, 24);
+}
+
+bool cHardwareCPU::BitConsensus(cAvidaContext& ctx, const unsigned int num_bits)
+{
+  assert(num_bits <= sizeof(int) * 8);
+
   const int reg_used = FindModifiedRegister(REG_BX);
   int reg_val = GetRegister(REG_CX);
   unsigned int bits_on = 0;
   
-  for (unsigned int i = 0; i < sizeof(int) * 8; i++)
+  for (unsigned int i = 0; i < num_bits; i++)
   {
     bits_on += (reg_val & 1);
     reg_val >>= 1;

Modified: development/source/cpu/cHardwareCPU.h
===================================================================
--- development/source/cpu/cHardwareCPU.h	2007-10-08 17:56:28 UTC (rev 2128)
+++ development/source/cpu/cHardwareCPU.h	2007-10-08 18:03:01 UTC (rev 2129)
@@ -89,7 +89,6 @@
   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 PROMOTER_CODE_SIZE = sizeof(int) * 8; // Number of bits in promoter codes
   
   // --------  Data Structures  --------
   struct cLocalThread
@@ -145,15 +144,16 @@
   // <-- Promoter model
   int m_promoter_index;       //site to begin looking for the next active promoter from
   int m_promoter_offset;      //bit offset when testing whether a promoter is on
-  int m_promoter_regulation;  //bit code that modifies current execution, via an XOR
   
   struct cPromoter 
   {
   public:
     int m_pos;      //position within genome
     int m_bit_code; //bit code of promoter
+    int m_regulation; //bit code of promoter
   public:
-    cPromoter(int _pos = 0, int _bit_code = 0) { m_pos = _pos; m_bit_code = _bit_code; }
+    cPromoter(int _pos = 0, int _bit_code = 0, int _regulation = 0) { m_pos = _pos; m_bit_code = _bit_code; m_regulation = _regulation; }
+    int GetRegulatedBitCode() { return m_bit_code ^ m_regulation; }
     ~cPromoter() { ; }
   };
   tArray<cPromoter> m_promoters;
@@ -552,14 +552,24 @@
   bool Inst_Promoter(cAvidaContext& ctx);
   bool Inst_Terminate(cAvidaContext& ctx);
   bool Inst_Regulate(cAvidaContext& ctx);
-  bool Inst_Numberate(cAvidaContext& ctx);
-  bool Inst_BitConsensus(cAvidaContext& ctx);
+  bool Inst_RegulateSpecificPromoters(cAvidaContext& ctx);
+  bool Inst_SenseRegulate(cAvidaContext& ctx);
+  bool Inst_Numberate(cAvidaContext& ctx) { return Do_Numberate(ctx); };
+  bool Inst_Numberate24(cAvidaContext& ctx) { return Do_Numberate(ctx, 24); };
+  bool Do_Numberate(cAvidaContext& ctx, int num_bits=0);
 
     // Helper functions //
   bool IsActivePromoter();
   void NextPromoter();
-  int Numberate(int _pos, int _dir);
+  int  Numberate(int _pos, int _dir, int _num_bits = 0);
+  
+  
+  //// Bit consensus functions ////
+  bool Inst_BitConsensus(cAvidaContext& ctx);
+  bool Inst_BitConsensus24(cAvidaContext& ctx);
+  bool BitConsensus(cAvidaContext& ctx, const unsigned int num_bits);
 
+
   //// Messaging ////
   bool Inst_SendMessage(cAvidaContext& ctx);
   bool Inst_RetrieveMessage(cAvidaContext& ctx);

Modified: development/source/main/cAvidaConfig.h
===================================================================
--- development/source/main/cAvidaConfig.h	2007-10-08 17:56:28 UTC (rev 2128)
+++ development/source/main/cAvidaConfig.h	2007-10-08 18:03:01 UTC (rev 2129)
@@ -468,12 +468,15 @@
   CONFIG_ADD_VAR(PROMOTER_INST_MAX, int, 0, "Maximum number of instructions to execute before terminating. 0 = off");
   CONFIG_ADD_VAR(PROMOTER_PROCESSIVITY, double, 1.0, "Chance of not terminating after each cpu cycle.");
   CONFIG_ADD_VAR(PROMOTER_PROCESSIVITY_INST, double, 1.0, "Chance of not terminating after each instruction.");
+  CONFIG_ADD_VAR(PROMOTER_TO_REGISTER, int, 0, "Place a promoter's base bit code in register BX when starting execution from it?");
   CONFIG_ADD_VAR(TERMINATION_RESETS, int, 0, "Does termination reset the thread's state?");
   CONFIG_ADD_VAR(NO_ACTIVE_PROMOTER_EFFECT, int, 0, "What happens when there are no active promoters?\n0 = Start execution at the beginning of the genome.\n1 = Kill the organism.\n2 = Stop the organism from executing any further instructions.");
-  CONFIG_ADD_VAR(PROMOTER_EXE_LENGTH, int, 4, "Length of promoter windows used to determine execution.");
-  CONFIG_ADD_VAR(PROMOTER_EXE_THRESHOLD, int, 3, "Minimum number of bits that must be set in a promoter window to allow execution.");
-  CONFIG_ADD_VAR(INST_CODE_LENGTH, int, 4, "Instruction binary code length (number of bits)");
+  CONFIG_ADD_VAR(PROMOTER_CODE_SIZE, int, 24, "Size of a promoter code in bits. (Maximum value is 32)");
+  CONFIG_ADD_VAR(PROMOTER_EXE_LENGTH, int, 3, "Length of promoter windows used to determine execution.");
+  CONFIG_ADD_VAR(PROMOTER_EXE_THRESHOLD, int, 2, "Minimum number of bits that must be set in a promoter window to allow execution.");
+  CONFIG_ADD_VAR(INST_CODE_LENGTH, int, 3, "Instruction binary code length (number of bits)");
   CONFIG_ADD_VAR(INST_CODE_DEFAULT_TYPE, int, 0, "Default value of instruction binary code value.\n0 = All zeros\n1 = Based off the instruction number");
+  CONFIG_ADD_VAR(CONSTITUTIVE_REGULATION, int, 0, "Sense a new regulation value before each CPU cycle?");
 
   CONFIG_ADD_GROUP(COLORS_GROUP, "Output colors for when data files are printed in HTML mode.\nThere are two sets of these; the first are for lineages,\nand the second are for mutation tests.");
   CONFIG_ADD_VAR(COLOR_DIFF, cString, "CCCCFF", "Color to flag stat that has changed since parent.");




More information about the Avida-cvs mailing list