1. dan mackinlay
  2. stars_in_is

Commits

howthebodyworks  committed 0654c1a

support verbose logging for debugging those horrible non-deterministic bugs

  • Participants
  • Parent commits 8f99687
  • Branches master

Comments (0)

Files changed (7)

File TODO.rst

View file
 * performance
 
   * use ruffus to get repeat calcs under control
-  * cache experiment outputs

File src/dispatch.py

View file
         self.storage = ExperimentStorage(exp_params['experiment_id'])
     
     def dispatch(self, trial_params,
-            display_plots=False,
+            verbosity=0,
             *args, **kwarg):
         """handle one trial sim"""
                 
         return write_to_file(
             storage=self.storage,
             trial_params=trial_params,
+            verbosity=verbosity,
             key=key)
         
     def wait(self):
         self.pending_procs = {}
         
     def dispatch(self, trial_params,
-            display_plots=False,
+            verbosity=0,
             *args, **kwargs):
         subprocess = self.subprocess
         key = self.storage.meta_as_key(trial_params)
         proc_args = [
             self.python, './do_trial.py',
             '--arg-file', argpath,
+            '--verbosity', verbosity,
             '--key', key
         ]
         with open(outputpath, 'wb') as handle:
 
 def write_to_file(storage,
         trial_params,
+        verbosity=0,
         key=None):
-    trial = sim.main(params=trial_params,)
+    trial = sim.main(params=trial_params, verbosity=verbosity)
     key = storage.put(trial, trial_params, key)
     return key

File src/do_experiment.py

View file
       help="seed for the first trial. subsequent seeds are generated in"
       " linear progression.",
       default=0)
+    parser.add_argument('--verbosity',
+      type=int,
+      help="How prolix must i be?",
+      default=0)
     parser.add_argument('--concurrency',
       type=str,
       help="Concurrency model",
         interactive,
         concurrency='Dispatcher',
         seed_offset=0,
+        verbosity=0,
         params='',
         *args, **kwargs):
     import exp_settings
     for seed in xrange(seed_offset, seed_offset + oversampling):
         exp_bunch['seed'] = seed
         trial_key = dispatcher.dispatch(
-            trial_params=exp_bunch)
+            trial_params=exp_bunch,
+            verbosity=verbosity)
     dispatcher.wait()
     keys = [key for key in dispatcher.pop_all_finished()]
     for key in keys:

File src/do_trial.py

View file
       default=False, help="open a shell upon completion")
     parser.add_argument('--display-plots', action='store_true',
       default=False, help="enable GUI graphics")
-    parser.set_defaults(func=simulate_trial)
+    parser.add_argument('--seed-offset',
+      type=int,
+      help="seed for the first trial. subsequent seeds are generated in"
+      " linear progression.",
+      default=0)
+    
     return parser
 
 def main(str_vers=None, *cl_args):
         interactive=False,
         cli_params='',
         seed=None,
+        verbosity=0,
         trial_params=None,
         display_plots=False,
         *args, **kwargs):
     key = dispatch.write_to_file(
         storage=storage,
         trial_params=trial_params,
+        verbosity=verbosity,
         key=key)
     
     if interactive:

File src/engine.py

View file
+#!/usr/bin/env python
+# encoding: utf-8
+"""
+engine.py
+
+Created by dan mackinlay on 2012-01-16.
+Copyright (c) 2012 __MyCompanyName__. All rights reserved.
+"""
+
+from pprint import pformat
+
+def _console_print(*args):
+    for a in args:
+        print a
+
+class Engine(object):
+    """encapsulates communicating with the outside world across different
+    process models"""
+    def __init__(self, verbosity=0, *args, **kwargs):
+        super(Engine, self).__init__(*args, **kwargs)
+        self.verbosity = verbosity
+        if verbosity>0:
+            self.message = _console_print
+        else:
+            self.message = lambda *args: None
+        
+    def pmessage(self, *args):
+        for a in args:
+            self.message(pformat(a))

File src/sim.py

View file
 #!/usr/bin/env python
 # encoding: utf-8
 """
-world.py
+sim.py
 
 Created by dan mackinlay on 2011-11-17.
 Copyright (c) 2011 __MyCompanyName__. All rights reserved.
 from exp_settings import DEFAULT_PARAMS
 import random
 from lib.util import trace
+from engine import Engine
 
-def main(params):
+def main(params, verbosity=0):
     # support lotsa calling conventions by merging params
     # then merging with default args. A bit messy.
     _ = DEFAULT_PARAMS.copy()
     # First, seed RNGs
     seed = params.seed
     random.seed(seed)
-    trace()()
     
     #Now, get the right functions loaded.
     worker_factory = get_callable(
         params.firm_info_updater)
     
     # create our agents
-    world = World(params=params)
+    world = World(params=params, engine=Engine(verbosity=verbosity))
+    world.engine.message("running sim with params")
+    world.engine.pmessage(params)
     workers = worker_factory(world=world, params=params)
     firms = firm_factory(world=world, params=params)
     world.add_firms(firms)

File src/world.py

View file
 from lib.dynamic import get_callable
 from logs import Log
 from settings import SKIP_STEPS
+from engine import Engine
 
 class World(object):
     """Holds simulation state so that statistics may be gathered against it"""
     def __init__(self,
-            params):
+            params, engine=None):
         self.timestep = 0
         self.log = Log()
         self.firms = []
         self.params = params
         #and, to save typing...
         self.stats = params.stats
+        if engine:
+            self.engine = engine
+        else:
+            self.engine = Engine()
         
     def __iter__(self, num_steps=None):
         """
         for ret in self.__iter__(num_steps): yield ret
         
     def gather_stats(self):
-        """this appends a statistic for every timestep to a log. I wonder if i
+        """this appends a statistic for every timestep to a log. I wonder if I
         should instead add a step number and not require every step have a
         value?"""
         for stat_fn_name in self.stats:
             stat_fn = get_callable(stat_fn_name)
             self.log.log_dict(stat_fn_name, stat_fn(self))
     
-
+    def __getstate__(self):
+        state = self.__dict__.copy()
+        state.pop('engine')
+        return state