[Avida-SVN] r1412 - in branches/collect/source: cpu main

blwalker at myxo.css.msu.edu blwalker at myxo.css.msu.edu
Tue Mar 20 09:23:03 PDT 2007


Author: blwalker
Date: 2007-03-20 12:23:02 -0400 (Tue, 20 Mar 2007)
New Revision: 1412

Modified:
   branches/collect/source/cpu/cHardwareCPU.cc
   branches/collect/source/cpu/cHardwareCPU.h
   branches/collect/source/main/cAvidaConfig.h
   branches/collect/source/main/cEnvironment.cc
Log:
initial commit of various collect implementation I've been working on.

to cHardwareCPU: added Inst_Collect(), FindModifiedResource()
  FindModifiedResource() is mostly an abstraction of part of Jeff B.'s DoSense helper function.  It should be in a condition to be useful for Inst_Collect() and the various sense instructions, but has not been deeply tested right now.

to cHardwareCPU: added member variable m_rbins to store internal resources

to cAvidaConfig: added new config group, ABSORB_RESOURCE_GROUP, and various config options

to cEnvironment: comments to indicate where I'll need to make the next round of changes



Modified: branches/collect/source/cpu/cHardwareCPU.cc
===================================================================
--- branches/collect/source/cpu/cHardwareCPU.cc	2007-03-20 15:51:46 UTC (rev 1411)
+++ branches/collect/source/cpu/cHardwareCPU.cc	2007-03-20 16:23:02 UTC (rev 1412)
@@ -127,6 +127,7 @@
     tInstLibEntry<tMethod>("set_C=A", &cHardwareCPU::Inst_CopyRegCA),
     tInstLibEntry<tMethod>("set_C=B", &cHardwareCPU::Inst_CopyRegCB),
     tInstLibEntry<tMethod>("reset", &cHardwareCPU::Inst_Reset),
+	//tInstLibEntry<tMethod>("load-val", &cHardwareCPU::Inst_LoadVal),
     
     tInstLibEntry<tMethod>("pop-A", &cHardwareCPU::Inst_PopA),
     tInstLibEntry<tMethod>("pop-B", &cHardwareCPU::Inst_PopB),
@@ -200,6 +201,8 @@
     tInstLibEntry<tMethod>("sense-unit", &cHardwareCPU::Inst_SenseUnit),
     tInstLibEntry<tMethod>("sense-m100", &cHardwareCPU::Inst_SenseMult100),
     
+    tInstLibEntry<tMethod>("collect", &cHardwareCPU::Inst_Collect),
+    
     tInstLibEntry<tMethod>("donate-rnd", &cHardwareCPU::Inst_DonateRandom),
     tInstLibEntry<tMethod>("donate-kin", &cHardwareCPU::Inst_DonateKin),
     tInstLibEntry<tMethod>("donate-edt", &cHardwareCPU::Inst_DonateEditDist),
@@ -364,6 +367,7 @@
 , m_threads(hardware_cpu.m_threads)
 , m_thread_id_chart(hardware_cpu.m_thread_id_chart)
 , m_cur_thread(hardware_cpu.m_cur_thread)
+, m_rbins(hardware_cpu.m_rbins)
 , m_mal_active(hardware_cpu.m_mal_active)
 , m_advance_ip(hardware_cpu.m_advance_ip)
 , m_executedmatchstrings(hardware_cpu.m_executedmatchstrings)
@@ -387,6 +391,9 @@
   m_thread_id_chart = 1; // Mark only the first thread as taken...
   m_cur_thread = 0;
   
+  //Reset resource bins to correct number (# of resources) of empty bins
+  m_rbins.Resize(m_world->GetNumResources(), 0.0);
+  
   m_mal_active = false;
   m_executedmatchstrings = false;
   
@@ -608,6 +615,13 @@
     fp << setbase(16) << "[0x" << GetRegister(i) << "]  " << setbase(10);
   }
   
+  // Print resource bin contents if USE_RESOURCE_BINS is enabled in avida.cfg
+  if (m_world->GetConfig().USE_RESOURCE_BINS.Get()) {
+    for (int i = 0; i < m_rbins.GetSize(); i++) {
+      fp << i << ": " << m_rbins[i] << " ";
+    }
+  }
+  
   // Add some extra information if additional time costs are used for instructions,
   // leave this out if there are no differences to keep it cleaner
   if ( organism->GetPhenotype().GetTimeUsed() != organism->GetPhenotype().GetCPUCyclesUsed() )
@@ -1935,6 +1949,13 @@
   return true;
 }
 
+/*bool cHardwareCPU::Inst_LoadVal(cAvidaContext& ctx)
+{
+	const int reg_used = FindModifiedRegister(REG_BX);
+	GetRegister(reg_used) = m_world->GetConfig().INST_LOAD_VALUE.Get();
+	return true;
+}*/
+
 bool cHardwareCPU::Inst_ShiftR(cAvidaContext& ctx)
 {
   const int reg_used = FindModifiedRegister(REG_BX);
@@ -2943,6 +2964,122 @@
   // Note that we are converting <double> resources to <int> register values
 }
 
+/* Convert modifying NOPs to the index of a resource. If there are fewer 
+ * than the number of NOPs required to specify a resource, find the subset 
+ * of resources.  (Motivation: can evolve to be more specific if there is 
+ * an advantage.)
+ *
+ * Mostly ripped from Jeff B.'s DoSense(); meant to be a helper function for
+ * DoSense, Inst_Collect, and anything else that wants to use this type of
+ * resource NOP-specification.
+ * 
+ * This relies on the assumption that m_world.GetNumResources() DOES NOT CHANGE
+ * during the course of a run.  I know of no way that it can, since this is the
+ * number of resources *defined* but I will check before this code goes to any
+ * public branch.
+ *
+ * returns true if successful, false otherwise
+ *
+ * start_index and end_index of resource range are "returned" via their 
+ * respective arguments; any int at all may be passed to these, as it will just 
+ * get overwritten.  (Obviously, if the resource is fully specified, 
+ * start_index == end_index.)
+ */
+
+bool cHardwareCPU::FindModifiedResource(int& start_index, int& end_index)
+{
+  int num_resources = m_world->GetNumResources();
+  
+  //if there are no resources, translation cannot be successful; return false
+  if (num_resources <= 0)
+  {return false;}
+  
+  //calculate the maximum number of NOPs necessary to completely specify a resource
+  int num_nops = GetInstSet().GetNumNops();
+  int max_label_length = (int)(ceil(log((double)num_resources) / log((double)num_nops)));
+  
+  //attempt to read a label of the maximum length
+  ReadLabel(max_label_length);
+  
+  //find the length of the label that was actually read
+  int real_label_length = GetLabel().GetSize();
+  
+  /* find start and end resource indices specified by the label */
+  
+  cCodeLabel start_label = cCodeLabel(GetLabel());
+  cCodeLabel   end_label = cCodeLabel(GetLabel());
+  
+  //fill out any labels that are not maximum length
+  for (int i = 0; i < max_label_length - real_label_length; i++){
+    start_label.AddNop(0);
+    end_label.AddNop(num_nops - 1);
+  }
+  
+  //translate into resource indices
+  start_index = start_label.AsInt(num_nops);
+  end_index   =   end_label.AsInt(num_nops);
+  
+  return true;
+}
+
+bool cHardwareCPU::Inst_Collect(cAvidaContext& ctx)
+{
+  int start_bin, end_bin, bin_used;
+
+  bool finite_resources_exist = FindModifiedResource(start_bin, end_bin);
+  if(!finite_resources_exist) {return false;}
+
+  if(start_bin == end_bin)  // resource completely specified
+  {bin_used = start_bin;}
+  else
+  {
+    switch (m_world->GetConfig().MULTI_ABSORB_TYPE.Get())
+    {
+      case 0:
+        bin_used = ctx.GetRandom().GetInt(start_bin, end_bin + 1);  // since the max passed to GetInt() will never be returned
+        break;
+      case 1:
+        bin_used = start_bin;
+        break;
+      case 2:
+        bin_used = end_bin;
+        break;
+      case 3:
+        bin_used = -1; // not really, of course!  This just functions as a flag
+        break;
+      default:
+        bin_used = ctx.GetRandom().GetInt(start_bin, end_bin + 1);  // arbitrary choice of the default.  Shouldn't matter, since it shouldn't be needed...
+        break;
+    }
+  }
+
+  // Set up res_change and add resources to rbins
+  const tArray<double> res_count = organism->GetOrgInterface().GetResources();
+  tArray<double> res_change(res_count.GetSize());
+
+  if(bin_used >= 0)
+  {
+    res_change[bin_used] = -1 * (res_count[bin_used] * m_world->GetConfig().ABSORB_RESOURCE_FRACTION.Get());
+    m_rbins[bin_used] += -1 * res_change[bin_used];
+//cout << "bin" << bin_used << ": " << m_rbins[bin_used] << endl;
+  }
+  else
+  {
+    int num_bins = end_bin - start_bin;
+    for(int i = start_bin; i <= end_bin; i++)
+    {
+      res_change[i] = -1 * (res_count[bin_used] * m_world->GetConfig().ABSORB_RESOURCE_FRACTION.Get() / num_bins);
+      m_rbins[i] += -1 * res_change[i];    
+//cout << "multibin" << i << ": " << m_rbins[i] << endl;
+    }
+  }
+  
+  // Update resource counts to reflect res_change
+  organism->GetOrgInterface().UpdateResources(res_change);
+  
+  return true;
+}
+
 void cHardwareCPU::DoDonate(cOrganism* to_org)
 {
   assert(to_org != NULL);

Modified: branches/collect/source/cpu/cHardwareCPU.h
===================================================================
--- branches/collect/source/cpu/cHardwareCPU.h	2007-03-20 15:51:46 UTC (rev 1411)
+++ branches/collect/source/cpu/cHardwareCPU.h	2007-03-20 16:23:02 UTC (rev 1412)
@@ -132,6 +132,8 @@
   tArray<cLocalThread> m_threads;
   int m_thread_id_chart;
   int m_cur_thread;
+  
+  tArray<double> m_rbins;     //Resource bins holding stored resources (as acquired with collect instr.)
 
   // Flags...
   bool m_mal_active;         // Has an allocate occured since last divide?
@@ -344,6 +346,7 @@
   bool Inst_CopyRegCA(cAvidaContext& ctx);
   bool Inst_CopyRegCB(cAvidaContext& ctx);
   bool Inst_Reset(cAvidaContext& ctx);
+  //bool Inst_LoadVal(cAvidaContext& ctx);
 
   // Single-Argument Math
   bool Inst_ShiftR(cAvidaContext& ctx);
@@ -423,6 +426,9 @@
   bool Inst_SenseUnit(cAvidaContext& ctx);
   bool Inst_SenseMult100(cAvidaContext& ctx);
   bool DoSense(cAvidaContext& ctx, int conversion_method, double base);
+  
+  bool FindModifiedResource(int& start_index, int& end_index);
+  bool Inst_Collect(cAvidaContext& ctx);
 
   void DoDonate(cOrganism * to_org);
   bool Inst_DonateRandom(cAvidaContext& ctx);

Modified: branches/collect/source/main/cAvidaConfig.h
===================================================================
--- branches/collect/source/main/cAvidaConfig.h	2007-03-20 15:51:46 UTC (rev 1411)
+++ branches/collect/source/main/cAvidaConfig.h	2007-03-20 16:23:02 UTC (rev 1412)
@@ -190,6 +190,7 @@
   CONFIG_ADD_VAR(VIEW_MODE, int, 1, "Initial viewer screen");
   CONFIG_ADD_VAR(CLONE_FILE, cString, "-", "Clone file to load");
   CONFIG_ADD_VAR(VERBOSITY, int, 1, "Control output verbosity");
+  //CONFIG_ADD_VAR(INST_LOAD_VALUE, int, 42, "Value used by load_val instruction");
   
   CONFIG_ADD_GROUP(ARCH_GROUP, "Architecture Variables");
   CONFIG_ADD_VAR(WORLD_X, int, 60, "Width of the Avida world");
@@ -316,6 +317,12 @@
   CONFIG_ADD_VAR(BUY_PRICE, int, 0, "price offered by organisms attempting to buy");
   CONFIG_ADD_VAR(SELL_PRICE, int, 0, "price offered by organisms attempting to sell");
   
+  CONFIG_ADD_GROUP(HOARD_RESOURCE_GROUP, "Resource Hoarding Parameters\n These have no effect unless the organisms are using the collect instruction.");
+  CONFIG_ADD_VAR(USE_RESOURCE_BINS, bool, 0, "Use resources stored in resource bins.  Unless the collect instruction is availible to the organisms, this will have no effect on organism behavior.  (Even when on, this only happens when there is no appropriate resource in the environment.)  Also controls output of resource bin contents, so you aren't bothered with them if you're not using them.");
+  CONFIG_ADD_VAR(ABSORB_RESOURCE_FRACTION, double, .0025, "Fraction of available environmental resource an organism absorbs with the collect command");
+  CONFIG_ADD_VAR(MULTI_ABSORB_TYPE, int, 0, "What to do if collect is called on a range of resources.\n 0 = absorb a random resource in the range\n 1 = absorb the first resource in the range\n 2 = absorb the last resource in the range\n 3 = absorb ABSORB_RESOURCE_FRACTION / (# of resources in range) of each resource in the range");
+  CONFIG_ADD_VAR(USE_STORED_FRACTION, double, 1.0, "The fraction of stored resource to use when there is no environmental resource available");
+  
   CONFIG_ADD_GROUP(ANALYZE_GROUP, "Analysis Settings");
   CONFIG_ADD_VAR(MT_CONCURRENCY, int, 1, "Number of concurrent analyze threads");
   CONFIG_ADD_VAR(ANALYZE_OPTION_1, cString, "", "String variable accessible from analysis scripts");

Modified: branches/collect/source/main/cEnvironment.cc
===================================================================
--- branches/collect/source/main/cEnvironment.cc	2007-03-20 15:51:46 UTC (rev 1411)
+++ branches/collect/source/main/cEnvironment.cc	2007-03-20 16:23:02 UTC (rev 1412)
@@ -930,6 +930,8 @@
       consumed = resource_count[res_id] - result.GetConsumed(res_id);
       consumed *= cur_process->GetMaxFraction();
       
+      // @blw TODO check for internal use here; set flag
+      
       // Make sure we're not above the maximum consumption.
       if (consumed > max_consumed) consumed = max_consumed;
 
@@ -942,6 +944,7 @@
       if (consumed == 0.0) continue;
       
       // Mark in the results the resource consumed.
+      // @blw TODO needs an extra bool flag to say whether consumed is internal or external
       result.Consume(res_id, consumed);
     }
     




More information about the Avida-cvs mailing list