[Avida-cvs] [avida-svn] r948 - development/source/main

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Tue Sep 12 19:17:13 PDT 2006


Author: brysonda
Date: 2006-09-12 22:17:13 -0400 (Tue, 12 Sep 2006)
New Revision: 948

Modified:
   development/source/main/cEnvironment.cc
   development/source/main/cTaskContext.h
   development/source/main/cTaskLib.cc
   development/source/main/cTaskLib.h
Log:
Remove mutable current task variable from within cur_task, as this is not thread safe.  The cTaskEntry is now placed into the task context prior to task evaluation.

Some code cleanup.


Modified: development/source/main/cEnvironment.cc
===================================================================
--- development/source/main/cEnvironment.cc	2006-09-13 01:25:25 UTC (rev 947)
+++ development/source/main/cEnvironment.cc	2006-09-13 02:17:13 UTC (rev 948)
@@ -394,11 +394,11 @@
   }
   
   // Finish loading in this reaction.
-    cString trigger_info = desc.PopWord();
+  cString trigger_info = desc.PopWord();
 	cString trigger = trigger_info.Pop('=');
   
   // Load the task trigger
-   cTaskEntry * cur_task = m_tasklib.AddTask(trigger, trigger_info);
+  cTaskEntry* cur_task = m_tasklib.AddTask(trigger, trigger_info);
   if (cur_task == NULL) {
     cerr << "...failed to find task in cTaskLib..." << endl;
     return false;
@@ -657,9 +657,11 @@
     if (cur_reaction->GetActive() == false) continue;
     
     // Examine the task trigger associated with this reaction
-    cTaskEntry * cur_task = cur_reaction->GetTask();
+    cTaskEntry* cur_task = cur_reaction->GetTask();
     assert(cur_task != NULL);
-    const double task_quality = m_tasklib.TestOutput(*cur_task, &taskctx);
+    
+    taskctx.SetTaskEntry(cur_task); // Set task entry in the context, so that tasks can reference task settings
+    const double task_quality = m_tasklib.TestOutput(&taskctx);
     const int task_id = cur_task->GetID();
     const int task_cnt = task_count[task_id];
     

Modified: development/source/main/cTaskContext.h
===================================================================
--- development/source/main/cTaskContext.h	2006-09-13 01:25:25 UTC (rev 947)
+++ development/source/main/cTaskContext.h	2006-09-13 02:17:13 UTC (rev 948)
@@ -17,7 +17,9 @@
 #include "tList.h"
 #endif
 
+class cTaskEntry;
 
+
 class cTaskContext
 {
   friend class cTaskLib;
@@ -30,16 +32,20 @@
   int net_completed;
   tBuffer<int>* received_messages;
   int logic_id;
+  
+  cTaskEntry* task_entry;
 
 public:
   cTaskContext(const tBuffer<int>& inputs, const tBuffer<int>& outputs, const tList<tBuffer<int> >& other_inputs,
                const tList<tBuffer<int> >& other_outputs, bool in_net_valid, int in_net_completed, 
-			   tBuffer<int>* in_received_messages=NULL)
+               tBuffer<int>* in_received_messages = NULL)
     : input_buffer(inputs), output_buffer(outputs), other_input_buffers(other_inputs),
     other_output_buffers(other_outputs), net_valid(in_net_valid), net_completed(in_net_completed), 
-	received_messages(in_received_messages), logic_id(0)
+    received_messages(in_received_messages), logic_id(0), task_entry(NULL)
   {
   }
+  
+  void SetTaskEntry(cTaskEntry* in_entry) { task_entry = in_entry; }
 };
 
 

Modified: development/source/main/cTaskLib.cc
===================================================================
--- development/source/main/cTaskLib.cc	2006-09-13 01:25:25 UTC (rev 947)
+++ development/source/main/cTaskLib.cc	2006-09-13 02:17:13 UTC (rev 948)
@@ -20,9 +20,7 @@
 
 cTaskLib::~cTaskLib()
 {
-  for (int i = 0; i < task_array.GetSize(); i++) {
-    delete task_array[i];
-  }
+  for (int i = 0; i < task_array.GetSize(); i++) delete task_array[i];
 }
 
 inline double cTaskLib::FractionalReward(unsigned int supplied, unsigned int correct)
@@ -34,35 +32,37 @@
   return static_cast<double>(32 - bit_diff) / 32.0; 
 }
 
-cTaskEntry * cTaskLib::AddTask(const cString & name, const cString & info)
+cTaskEntry* cTaskLib::AddTask(const cString& name, const cString& info)
 {
   // Determine if this task is already in the active library.
   for (int i = 0; i < task_array.GetSize(); i++) {
-       if (task_array[i]->GetName() == name &&
-		   		task_array[i]->GetInfo() == info) {
-      assert(task_array[i] != NULL);
-      return task_array[i];
-    }
+    assert(task_array[i] != NULL);
+    if (task_array[i]->GetName() == name && task_array[i]->GetInfo() == info) return task_array[i];
   }
   
   // Match up this name to its corresponding task
   const int start_size = task_array.GetSize();
   
+  // The following if blocks are grouped based on class of task.  Chaining too
+  // many if block causes problems block nesting depth in Visual Studio.net 2003.
+
   if (name == "echo")      NewTask(name, "Echo", &cTaskLib::Task_Echo);
   else if (name == "add")  NewTask(name, "Add",  &cTaskLib::Task_Add);
   else if (name == "sub")  NewTask(name, "Sub",  &cTaskLib::Task_Sub);
   
-  else if (name == "not")   NewTask(name, "Not",    &cTaskLib::Task_Not);
-  else if (name == "nand")  NewTask(name, "Nand",   &cTaskLib::Task_Nand);
-  else if (name == "and")   NewTask(name, "And",    &cTaskLib::Task_And);
-  else if (name == "orn")   NewTask(name, "OrNot",  &cTaskLib::Task_OrNot);
-  else if (name == "or")    NewTask(name, "Or",     &cTaskLib::Task_Or);
-  else if (name == "andn")  NewTask(name, "AndNot", &cTaskLib::Task_AndNot);
-  else if (name == "nor")   NewTask(name, "Nor",    &cTaskLib::Task_Nor);
-  else if (name == "xor")   NewTask(name, "Xor",    &cTaskLib::Task_Xor);
-  else if (name == "equ")   NewTask(name, "Equals", &cTaskLib::Task_Equ);
+  // All one and two input logic functions
+  if (name == "not") NewTask(name, "Not", &cTaskLib::Task_Not);
+  else if (name == "nand") NewTask(name, "Nand", &cTaskLib::Task_Nand);
+  else if (name == "and") NewTask(name, "And", &cTaskLib::Task_And);
+  else if (name == "orn") NewTask(name, "OrNot", &cTaskLib::Task_OrNot);
+  else if (name == "or") NewTask(name, "Or", &cTaskLib::Task_Or);
+  else if (name == "andn") NewTask(name, "AndNot", &cTaskLib::Task_AndNot);
+  else if (name == "nor") NewTask(name, "Nor", &cTaskLib::Task_Nor);
+  else if (name == "xor") NewTask(name, "Xor", &cTaskLib::Task_Xor);
+  else if (name == "equ") NewTask(name, "Equals", &cTaskLib::Task_Equ);
   
-  else if (name == "logic_3AA")
+  // All three input logic functions
+  if (name == "logic_3AA")
     NewTask(name, "Logic 3AA (A+B+C == 0)", &cTaskLib::Task_Logic3in_AA);
   else if (name == "logic_3AB")
     NewTask(name, "Logic 3AB (A+B+C == 1)", &cTaskLib::Task_Logic3in_AB);
@@ -199,6 +199,7 @@
   else if (name == "logic_3CP")
     NewTask(name, "Logic 3CP", &cTaskLib::Task_Logic3in_CP);
   
+  // Arbitrary one input math tasks
   else if (name == "math_1AA")
     NewTask(name, "Math 1AA (2X)", &cTaskLib::Task_Math1in_AA);
   else if (name == "math_1AB")
@@ -230,9 +231,10 @@
   else if (name == "math_1AO")
     NewTask(name, "Math 1AO (X-6)", &cTaskLib::Task_Math1in_AO);  
   else if (name == "math_1AP")
-    NewTask(name, "Math 1AP (X-7)", &cTaskLib::Task_Math1in_AP);  
+    NewTask(name, "Math 1AP (X-7)", &cTaskLib::Task_Math1in_AP);
   
-  else if (name == "math_2AA")
+  // Arbitrary two input math tasks
+  if (name == "math_2AA")
     NewTask(name, "Math 2AA (sqrt(X+Y))", &cTaskLib::Task_Math2in_AA);  
   else if (name == "math_2AB")
     NewTask(name, "Math 2AB ((X+Y)^2)", &cTaskLib::Task_Math2in_AB);  
@@ -277,21 +279,14 @@
   else if (name == "math_2AV")
     NewTask(name, "Math 2AV (XY^2)", &cTaskLib::Task_Math2in_AV);
   
-  else if (name == "math_3AA")
+  // Arbitrary three input logic tasks
+  if (name == "math_3AA")
     NewTask(name, "Math 3AA (X^2+Y^2+Z^2)", &cTaskLib::Task_Math3in_AA);  
   else if (name == "math_3AB")
     NewTask(name, "Math 3AB (sqrt(X)+sqrt(Y)+sqrt(Z))", &cTaskLib::Task_Math3in_AB);  
   else if (name == "math_3AC")
     NewTask(name, "Math 3AC (X+2Y+3Z)", &cTaskLib::Task_Math3in_AC);  
-  /*
-   Visual Studio.net 2003 gives compiler error:
-   fatal error C1061: compiler limit : blocks nested too deeply
-   Sherri fixed this by removing the 'else' in the next line.
-   -- K
-   */
-  //else if (name == "math_3AD")
-  //  NewTask(name, "Math 3AD (XY^2+Z^3)", &cTaskLib::Task_Math3in_AD); 
-  if (name == "math_3AD")
+  else if (name == "math_3AD")
     NewTask(name, "Math 3AD (XY^2+Z^3)", &cTaskLib::Task_Math3in_AD);  
   else if (name == "math_3AE")
     NewTask(name, "Math 3AE ((X%Y)*Z)", &cTaskLib::Task_Math3in_AE);  
@@ -304,11 +299,9 @@
   else if (name == "math_3AI")
     NewTask(name, "Math 3AI (-X-Y-Z)", &cTaskLib::Task_Math3in_AI);  
   else if (name == "math_3AJ")
-    NewTask(name, "Math 3AJ ((X-Y)^2+(Y-Z)^2+(Z-X)^2)",
-            &cTaskLib::Task_Math3in_AJ);  
+    NewTask(name, "Math 3AJ ((X-Y)^2+(Y-Z)^2+(Z-X)^2)", &cTaskLib::Task_Math3in_AJ);  
   else if (name == "math_3AK")
-    NewTask(name, "Math 3AK ((X+Y)^2+(Y+Z)^2+(Z+X)^2)",
-            &cTaskLib::Task_Math3in_AK);  
+    NewTask(name, "Math 3AK ((X+Y)^2+(Y+Z)^2+(Z+X)^2)", &cTaskLib::Task_Math3in_AK);  
   else if (name == "math_3AL")
     NewTask(name, "Math 3AL ((X-Y)^2+(X-Z)^2)", &cTaskLib::Task_Math3in_AL);  
   else if (name == "math_3AM")
@@ -318,22 +311,20 @@
   if (name == "matchstr")  NewTask(name, "MatchStr", &cTaskLib::Task_MatchStr, 0, info);
 
 	// communication tasks
-  else if (name == "comm_echo")
-    NewTask(name, "Echo of Neighbor's Input", &cTaskLib::Task_CommEcho,
-            REQ_NEIGHBOR_INPUT);
+  if (name == "comm_echo")
+    NewTask(name, "Echo of Neighbor's Input", &cTaskLib::Task_CommEcho, REQ_NEIGHBOR_INPUT);
   else if (name == "comm_not")
-	  NewTask(name, "Not of Neighbor's INput", &cTaskLib::Task_CommNot,
-            REQ_NEIGHBOR_INPUT);
+	  NewTask(name, "Not of Neighbor's Input", &cTaskLib::Task_CommNot, REQ_NEIGHBOR_INPUT);
 
-  else if (name == "net_send")
+  // Network tasks
+  if (name == "net_send")
 	  NewTask(name, "Successfully Sent Network Message", &cTaskLib::Task_NetSend);
   else if (name == "net_receive")
 	  NewTask(name, "Successfully Received Network Message", &cTaskLib::Task_NetReceive);
   
   
   
-  // Make sure we have actually found a task.
-  
+  // Make sure we have actually found a task  
   if (task_array.GetSize() == start_size) {
     cerr << "Unknown task entry '" << name << "'." << endl;
     return NULL;
@@ -343,10 +334,6 @@
   return task_array[start_size];
 }
 
-const cTaskEntry & cTaskLib::GetTask(int id) const
-{
-  return *(task_array[id]);
-}
 
 void cTaskLib::SetupTests(cTaskContext& ctx) const
 {
@@ -1735,12 +1722,11 @@
 double cTaskLib::Task_MatchStr(cTaskContext* ctx) const
 {
 	tBuffer<int> temp_buf(ctx->output_buffer);
-	if (temp_buf[0] != 357913941)
-		return 0;
+	if (temp_buf[0] != 357913941) return 0;
 
 	temp_buf.Pop(); // pop the signal value off of the buffer
 
-	const cString & string_to_match = task_array[cur_task]->GetInfo();
+	const cString& string_to_match = ctx->task_entry->GetInfo();
 	int string_index;
 	int num_matched = 0;
 	int test_output, max_num_matched = 0;

Modified: development/source/main/cTaskLib.h
===================================================================
--- development/source/main/cTaskLib.h	2006-09-13 01:25:25 UTC (rev 947)
+++ development/source/main/cTaskLib.h	2006-09-13 02:17:13 UTC (rev 948)
@@ -43,9 +43,6 @@
   bool use_neighbor_input;
   bool use_neighbor_output;
 
-  // Active task information...
-  mutable int cur_task; // the ID of the task currently being tested
-
   enum req_list
   {
     REQ_NEIGHBOR_INPUT=1,
@@ -65,16 +62,16 @@
   int GetSize() const { return task_array.GetSize(); }
 
   cTaskEntry* AddTask(const cString& name, const cString& info);
-  const cTaskEntry& GetTask(int id) const;
+  const cTaskEntry& GetTask(int id) const { return *(task_array[id]); }
   
   void SetupTests(cTaskContext& ctx) const;
-  inline double TestOutput(const cTaskEntry& task, cTaskContext* ctx) const;
+  inline double TestOutput(cTaskContext* ctx) const { return (this->*(ctx->task_entry->GetTestFun()))(ctx); }
 
   bool UseNeighborInput() const { return use_neighbor_input; }
   bool UseNeighborOutput() const { return use_neighbor_output; }
   
 private:  // Direct task related methods
-  void NewTask(const cString& name, const cString& desc, tTaskTest task_fun, int reqs = 0, const cString& info="");
+  void NewTask(const cString& name, const cString& desc, tTaskTest task_fun, int reqs = 0, const cString& info = "");
 
   inline double FractionalReward(unsigned int supplied, unsigned int correct);  
 
@@ -242,11 +239,5 @@
 #endif  
 
 
-inline double cTaskLib::TestOutput(const cTaskEntry& task, cTaskContext* ctx) const
-{
-  cur_task = task.GetID();
-  tTaskTest test_fun = task.GetTestFun();
-  return (this->*test_fun)(ctx);
-}
 
 #endif




More information about the Avida-cvs mailing list