[Avida-SVN] r2041 - in development: source/actions source/cpu source/main tests/_testrunner

brysonda at myxo.css.msu.edu brysonda at myxo.css.msu.edu
Wed Sep 5 11:18:59 PDT 2007


Author: brysonda
Date: 2007-09-05 14:18:58 -0400 (Wed, 05 Sep 2007)
New Revision: 2041

Modified:
   development/source/actions/PopulationActions.cc
   development/source/cpu/cHardwareGX.cc
   development/source/main/cMutationRates.cc
   development/source/main/cMutationRates.h
   development/source/main/cOrganism.h
   development/tests/_testrunner/testrunner.py
Log:
Update cMutationRates to check select mutation rate values prior to consulting the random number generator.  This change yields ~10% improvement in landscape calculation performance on an Octo-Core Mac Pro (TestRunner performance test results).   Note that this is going to break a lot of consistency tests, more commits forthcoming.

Also, updated TestRunner to 1.5.  New feature, a --ignore-consistency option.  This feature allows for performance tests to be run without the consistency tests phase.  The results are not saved, but can be used to gauge how intentional changes in consistency affect performance. i.e. the above mentioned change to cMutationRates.

Modified: development/source/actions/PopulationActions.cc
===================================================================
--- development/source/actions/PopulationActions.cc	2007-09-03 22:24:41 UTC (rev 2040)
+++ development/source/actions/PopulationActions.cc	2007-09-05 18:18:58 UTC (rev 2041)
@@ -810,7 +810,6 @@
     }
 
     switch (m_mut_type) {
-      case POINT: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetPointMutProb(m_prob); break;
       case COPY: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetCopyMutProb(m_prob); break;
       case INS: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetInsMutProb(m_prob); break;
       case DEL: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetDelMutProb(m_prob); break;
@@ -918,7 +917,6 @@
     }
     
     switch (m_mut_type) {
-      case POINT: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetPointMutProb(prob); break;
       case COPY: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetCopyMutProb(prob); break;
       case INS: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetInsMutProb(prob); break;
       case DEL: for (int i = m_start; i < m_end; i++) m_world->GetPopulation().GetCell(i).MutationRates().SetDelMutProb(prob); break;

Modified: development/source/cpu/cHardwareGX.cc
===================================================================
--- development/source/cpu/cHardwareGX.cc	2007-09-03 22:24:41 UTC (rev 2040)
+++ development/source/cpu/cHardwareGX.cc	2007-09-05 18:18:58 UTC (rev 2041)
@@ -3626,13 +3626,13 @@
   
   bool ret = true;
   // Normal h-copy, unless a deletion occured
-  if (!organism->TestCopyDel(ctx)) {
+  if (!organism->TestDelMut(ctx)) {
       // Normal h-copy
     ret = Inst_HeadCopy(ctx);
   }
   
   // Divide Insertion
-  if (organism->TestCopyIns(ctx)) {
+  if (organism->TestInsMut(ctx)) {
     write.GetMemory().Insert(write.GetPosition(), GetInstSet().GetRandomInst(ctx));
     // Advance the write head;
     write++;

Modified: development/source/main/cMutationRates.cc
===================================================================
--- development/source/main/cMutationRates.cc	2007-09-03 22:24:41 UTC (rev 2040)
+++ development/source/main/cMutationRates.cc	2007-09-05 18:18:58 UTC (rev 2041)
@@ -31,7 +31,6 @@
 
 void cMutationRates::Setup(cWorld* world)
 {
-  exec.point_mut_prob = world->GetConfig().POINT_MUT_PROB.Get();
   copy.mut_prob = world->GetConfig().COPY_MUT_PROB.Get();
   copy.slip_prob = world->GetConfig().COPY_SLIP_PROB.Get();
   divide.ins_prob = world->GetConfig().INS_MUT_PROB.Get();
@@ -52,7 +51,6 @@
 
 void cMutationRates::Clear()
 {
-  exec.point_mut_prob = 0.0;
   copy.mut_prob = 0.0;
   copy.slip_prob = 0.0;
   divide.ins_prob = 0.0;
@@ -73,7 +71,6 @@
 
 void cMutationRates::Copy(const cMutationRates& in_muts)
 {
-  exec.point_mut_prob = in_muts.exec.point_mut_prob;
   copy.mut_prob = in_muts.copy.mut_prob;
   copy.slip_prob = in_muts.copy.slip_prob;
   divide.ins_prob = in_muts.divide.ins_prob;

Modified: development/source/main/cMutationRates.h
===================================================================
--- development/source/main/cMutationRates.h	2007-09-03 22:24:41 UTC (rev 2040)
+++ development/source/main/cMutationRates.h	2007-09-05 18:18:58 UTC (rev 2041)
@@ -40,12 +40,6 @@
 private:
   // Mutations are divided up by when they occur...
 
-  // ...anytime during execution...
-  struct sExecMuts {
-    double point_mut_prob;
-  };
-  sExecMuts exec;
-
   // ...during an instruction copy...
   struct sCopyMuts {
     double mut_prob;
@@ -93,28 +87,26 @@
   void Clear();
   void Copy(const cMutationRates& in_muts);
 
-  bool TestPointMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(exec.point_mut_prob); }
-  bool TestCopyMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(copy.mut_prob); }
-  bool TestCopyIns(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.ins_prob); }
-  bool TestCopyDel(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.del_prob); }
-  bool TestCopySlip(cAvidaContext& ctx) const { return (copy.slip_prob == 0.0) ? 0 : ctx.GetRandom().P(copy.slip_prob); }
+  // Copy muts should always check if they are 0.0 before consulting the random number generator for performance
+  bool TestCopyMut(cAvidaContext& ctx) const { return (copy.mut_prob == 0.0) ? false : ctx.GetRandom().P(copy.mut_prob); }
+  bool TestCopySlip(cAvidaContext& ctx) const { return (copy.slip_prob == 0.0) ? false : ctx.GetRandom().P(copy.slip_prob); }
+  
+  bool TestInsMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.ins_prob); }
+  bool TestDelMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.del_prob); }
   bool TestDivideMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.divide_mut_prob); }
   bool TestDivideIns(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.divide_ins_prob); }
   bool TestDivideDel(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.divide_del_prob); }
-  bool TestDivideSlip(cAvidaContext& ctx) const { return (divide.divide_slip_prob == 0.0) ? 0 : ctx.GetRandom().P(divide.divide_slip_prob); }
-  //bool TestDivideSlip(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.divide_slip_prob); }
-    // @JEB The conditional just avoids calling for a random number to maintain consistency with past versions.
-    // It can be cleaned up in the future.
+  bool TestDivideSlip(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.divide_slip_prob); }
   bool TestParentMut(cAvidaContext& ctx) const { return ctx.GetRandom().P(divide.parent_mut_prob); }
+  
   double DoMetaCopyMut(cAvidaContext& ctx) {
-    if (ctx.GetRandom().P(meta.copy_mut_prob) == false) return 1.0;
+    if (meta.copy_mut_prob == 0.0 || !ctx.GetRandom().P(meta.copy_mut_prob)) return 1.0;
     const double exp = ctx.GetRandom().GetRandNormal() * meta.standard_dev;
     const double change = pow(2.0, exp);
     copy.mut_prob *= change;
     return change;
   }
 
-  double GetPointMutProb() const     { return exec.point_mut_prob; }
   double GetCopyMutProb() const      { return copy.mut_prob; }
   double GetInsMutProb() const       { return divide.ins_prob; }
   double GetDelMutProb() const       { return divide.del_prob; }
@@ -130,7 +122,6 @@
   double GetMetaCopyMutProb() const  { return meta.copy_mut_prob; }
   double GetMetaStandardDev() const  { return meta.standard_dev; }
   
-  void SetPointMutProb(double in_prob)  { exec.point_mut_prob    = in_prob; }
   void SetCopyMutProb(double in_prob)   { copy.mut_prob          = in_prob; }
   void SetInsMutProb(double in_prob)    { divide.ins_prob        = in_prob; }
   void SetDelMutProb(double in_prob)    { divide.del_prob        = in_prob; }

Modified: development/source/main/cOrganism.h
===================================================================
--- development/source/main/cOrganism.h	2007-09-03 22:24:41 UTC (rev 2040)
+++ development/source/main/cOrganism.h	2007-09-05 18:18:58 UTC (rev 2041)
@@ -271,8 +271,8 @@
 
   // --------  Mutation Rate Convenience Methods  --------
   bool TestCopyMut(cAvidaContext& ctx) const { return m_mut_rates.TestCopyMut(ctx); }
-  bool TestCopyIns(cAvidaContext& ctx) const { return m_mut_rates.TestCopyIns(ctx); }
-  bool TestCopyDel(cAvidaContext& ctx) const { return m_mut_rates.TestCopyDel(ctx); }
+  bool TestInsMut(cAvidaContext& ctx) const { return m_mut_rates.TestInsMut(ctx); }
+  bool TestDelMut(cAvidaContext& ctx) const { return m_mut_rates.TestDelMut(ctx); }
   bool TestCopySlip(cAvidaContext& ctx) const { return m_mut_rates.TestCopySlip(ctx); }
   bool TestDivideMut(cAvidaContext& ctx) const { return m_mut_rates.TestDivideMut(ctx); }
   bool TestDivideIns(cAvidaContext& ctx) const { return m_mut_rates.TestDivideIns(ctx); }

Modified: development/tests/_testrunner/testrunner.py
===================================================================
--- development/tests/_testrunner/testrunner.py	2007-09-03 22:24:41 UTC (rev 2040)
+++ development/tests/_testrunner/testrunner.py	2007-09-05 18:18:58 UTC (rev 2041)
@@ -52,7 +52,7 @@
 
 # Global Constants
 # ---------------------------------------------------------------------------------------------------------------------------
-TESTRUNNER_VERSION = "1.4c"
+TESTRUNNER_VERSION = "1.5"
 TESTRUNNER_COPYRIGHT = "2007"
 
 TRUE_STRINGS = ("y","Y","yes","Yes","true","True","1")
@@ -111,6 +111,10 @@
       
     --help-test-cfg
       Display a sample test configuration file
+      
+    --ignore-consistency
+      Ignore consistency tests altogether.  Performance results are not saved.
+      Valid only when used in conjunction with -p or --run-perf-tests.
     
     -j number [%(cpus)d]
       Set the number of concurrent tests to run. i.e. - the number of CPUs
@@ -482,7 +486,7 @@
 
 
   # void cTest::runPerformanceTest() {
-  def runPerformanceTest(self, dolongtest):
+  def runPerformanceTest(self, dolongtest, saveresults):
     global settings, tmpdir, CONFIGDIR, PERFDIR, TRUE_STRINGS, PERF_BASE
     
     if self.has_perf_base and self.skip:
@@ -571,33 +575,37 @@
     
     # If no baseline results exist, write out results
     if not self.has_perf_base:
-      try:
-        if not os.path.exists(perfdir):
-          os.mkdir(perfdir)
-        if not os.path.isdir(perfdir):
+      if saveresults:
+        try:
+          if not os.path.exists(perfdir):
+            os.mkdir(perfdir)
+          if not os.path.isdir(perfdir):
+            try:
+              shutil.rmtree(rundir, True) # Clean up test directory
+            except (IOError, OSError): pass
+            self.psuccess = False
+            self.presult = "unable to write out baseline, file exists"
+            return
+            
+          fp = open(basepath, "w")
+          fp.write("%f,%f,%f,%f,%f,%f,%f,%f\n" % (r_min, r_max, r_ave, r_med, t_min, t_max, t_ave, t_med))
+          fp.flush()
+          fp.close()
+        except (IOError):
           try:
             shutil.rmtree(rundir, True) # Clean up test directory
           except (IOError, OSError): pass
           self.psuccess = False
-          self.presult = "unable to write out baseline, file exists"
+          self.presult = "error occurred writing baseline results"
           return
-          
-        fp = open(basepath, "w")
-        fp.write("%f,%f,%f,%f,%f,%f,%f,%f\n" % (r_min, r_max, r_ave, r_med, t_min, t_max, t_ave, t_med))
-        fp.flush()
-        fp.close()
-      except (IOError):
-        try:
-          shutil.rmtree(rundir, True) # Clean up test directory
-        except (IOError, OSError): pass
-        self.psuccess = False
-        self.presult = "error occurred writing baseline results"
-        return
+        self.presult = "new baseline - wall time: %3.4f user time: %3.4f" % (t_min, r_min)
+      else:
+        self.presult = "*unsaved* baseline - wall time: %3.4f user time: %3.4f" % (t_min, r_min)
 
+
       try:
         shutil.rmtree(rundir, True) # Clean up test directory
       except (IOError, OSError): pass
-      self.presult = "new baseline - wall time: %3.4f user time: %3.4f" % (t_min, r_min)
       return
       
     # Compare results with baseline
@@ -616,25 +624,26 @@
       self.psuccess = False
       self.presult = "failed"
     elif r_min < r_lmargin or t_min < t_lmargin:
-      # new baseline, move old baseline and write out new results
-      try:
-        rev = "exported"
-        if self.usesvn:
-          sverp = os.popen("cd %s; %s" % (self.tdir, settings["svnversion"]))
-          rev = sverp.readline().strip()
-          sverp.close()
-          if rev == "": rev = "exported"
-        
-        oname = "perf-%s-prev-%s" % (time.strftime("%Y-%m-%d-%H.%M.%S"), rev)
-        
-        shutil.move(basepath, os.path.join(perfdir, oname))
-        
-        fp = open(basepath, "w")
-        fp.write("%f,%f,%f,%f,%f,%f,%f,%f\n" % (r_min, r_max, r_ave, r_med, t_min, t_max, t_ave, t_med))
-        fp.flush()
-        fp.close()
-      except (IOError, OSError, shutil.Error):
-        print "Warning: error updating '%s' performance baseline" % self.name
+      if saveresults:
+        # new baseline, move old baseline and write out new results
+        try:
+          rev = "exported"
+          if self.usesvn:
+            sverp = os.popen("cd %s; %s" % (self.tdir, settings["svnversion"]))
+            rev = sverp.readline().strip()
+            sverp.close()
+            if rev == "": rev = "exported"
+          
+          oname = "perf-%s-prev-%s" % (time.strftime("%Y-%m-%d-%H.%M.%S"), rev)
+          
+          shutil.move(basepath, os.path.join(perfdir, oname))
+          
+          fp = open(basepath, "w")
+          fp.write("%f,%f,%f,%f,%f,%f,%f,%f\n" % (r_min, r_max, r_ave, r_med, t_min, t_max, t_ave, t_med))
+          fp.flush()
+          fp.close()
+        except (IOError, OSError, shutil.Error):
+          print "Warning: error updating '%s' performance baseline" % self.name
       self.presult = "exceeded"
 
     # Print output on all tests
@@ -788,7 +797,7 @@
 
     sem.acquire()
     ti += 1
-    sys.stdout.write("\rPerforming Test:  %4d of %d -- %-45s " % (ti, len(tests), test.name[:45]))
+    sys.stdout.write("\rPerforming Test:  % 4d of %d -- %-45s " % (ti, len(tests), test.name[:45]))
     sys.stdout.flush()
     tthread = threading.Thread(target=runTestWrapper, args=(test, sem))
     tthread.start()
@@ -819,7 +828,7 @@
 
 
 # (int, int) runPerformanceTests(cTest[] tests) {
-def runPerformanceTests(alltests, dolongtests, force):
+def runPerformanceTests(alltests, dolongtests, force, saveresults):
   global settings, tmpdir
   
   tests = []
@@ -842,7 +851,7 @@
     ti += 1
     sys.stdout.write("\rPerforming Test:  % 4d of %d" % (ti, len(tests)))
     sys.stdout.flush()
-    test.runPerformanceTest(dolongtests)
+    test.runPerformanceTest(dolongtests, saveresults)
   
   sys.stdout.write("\n\n")
   sys.stdout.flush()
@@ -909,15 +918,16 @@
   # Process Command Line Arguments
   try:
     opts, args = getopt.getopt(argv[1:], "fhj:lm:ps:v", \
-      ["builddir=", "disable-svn", "force-perf", "help", "help-test-cfg", "list-tests", "long-tests", "mode=", \
-       "reset-perf-base", "run-perf-tests", "show-diff", "skip-tests", "svnmetadir=", "svn=", "svnversion=", "testdir=", \
-       "verbose", "version", "-testrunner-name="])
+      ["builddir=", "disable-svn", "force-perf", "help", "help-test-cfg", "ignore-consistency", "list-tests", "long-tests", \
+       "mode=", "reset-perf-base", "run-perf-tests", "show-diff", "skip-tests", "svnmetadir=", "svn=", "svnversion=", \
+       "testdir=", "verbose", "version", "-testrunner-name="])
   except getopt.GetoptError:
     usage()
     return -1
   
   # Define Option Flags
   opt_forceperf = False
+  opt_ignoreconsistency = False
   opt_listtests = False
   opt_long = False
   opt_runperf = False
@@ -941,6 +951,8 @@
       settings["_disable_svn"] = ""
     elif opt in ("-f", "--force-perf"):
       opt_forceperf = True
+    elif opt == "--ignore-consistency":
+      opt_ignoreconsistency = True
     elif opt in ("-l", "--list-tests"):
       opt_listtests = True
     elif opt == "--long-tests":
@@ -1034,11 +1046,16 @@
   tmpdir = tempfile.mkdtemp("_testrunner")
 
 
+  success = 0
+  fail = 0
+
   # Run Consistency Tests
-  (success, fail) = runConsistencyTests(tests, opt_long)
+  if (not opt_runperf or not opt_ignoreconsistency):
+    (success, fail) = runConsistencyTests(tests, opt_long)
   
-  if fail == 0 and opt_runperf:
-    (psuccess, pfail) = runPerformanceTests(tests, opt_long, opt_forceperf)
+  # Run Performance Tests
+  if (opt_ignoreconsistency or fail == 0) and opt_runperf:
+    (psuccess, pfail) = runPerformanceTests(tests, opt_long, opt_forceperf, not opt_ignoreconsistency)
     success += psuccess
     fail += pfail
 




More information about the Avida-cvs mailing list