def __init__(self, model, task, cmdOptions): """ Constructor Args: model: The OPF Model instance against which to run the task task: A dictionary conforming to opfTaskSchema.json cmdOptions: ParseCommandLineOptionsResult namedtuple """ validateOpfJsonValue(task, "opfTaskSchema.json") # Set up our logger self.__logger = logging.getLogger(".".join( ['com.numenta', self.__class__.__module__, self.__class__.__name__])) #self.__logger.setLevel(logging.DEBUG) self.__logger.debug(("Instantiated %s(" + \ "model=%r, " + \ "task=%r, " + \ "cmdOptions=%r)") % \ (self.__class__.__name__, model, task, cmdOptions)) # Generate a new dataset from streamDef and create the dataset reader streamDef = task['dataset'] datasetReader = opfbasicenvironment.BasicDatasetReader(streamDef) self.__model = model self.__datasetReader = datasetReader self.__task = task self.__cmdOptions = cmdOptions self.__predictionLogger = opfbasicenvironment.BasicPredictionLogger( fields=model.getFieldInfo(), experimentDir=cmdOptions.experimentDir, label=task['taskLabel'], inferenceType=self.__model.getInferenceType()) taskControl = task['taskControl'] # Create Task Driver self.__taskDriver = OPFTaskDriver( taskControl=taskControl, model=model) loggedMetricPatterns = taskControl.get('loggedMetrics', None) loggedMetricLabels = matchPatterns(loggedMetricPatterns, self.__taskDriver.getMetricLabels()) self.__predictionLogger.setLoggedMetrics(loggedMetricLabels) # Create a prediction metrics logger self.__metricsLogger = opfbasicenvironment.BasicPredictionMetricsLogger( experimentDir=cmdOptions.experimentDir, label=task['taskLabel'])
class _TaskRunner(object): """This class is responsible for running a single experiment task on the given Model instance """ __FILE_SCHEME = "file://" def __init__(self, model, task, cmdOptions): """ Constructor Args: model: The OPF Model instance against which to run the task task: A dictionary conforming to opfTaskSchema.json cmdOptions: ParseCommandLineOptionsResult namedtuple """ validateOpfJsonValue(task, "opfTaskSchema.json") # Set up our logger self.__logger = logging.getLogger(".".join(["com.numenta", self.__class__.__module__, self.__class__.__name__])) # self.__logger.setLevel(logging.DEBUG) self.__logger.debug( ("Instantiated %s(" + "model=%r, " + "task=%r, " + "cmdOptions=%r)") % (self.__class__.__name__, model, task, cmdOptions) ) # Generate a new dataset from streamDef and create the dataset reader streamDef = task["dataset"] datasetReader = opfbasicenvironment.BasicDatasetReader(streamDef) self.__model = model self.__datasetReader = datasetReader self.__task = task self.__cmdOptions = cmdOptions self.__predictionLogger = opfbasicenvironment.BasicPredictionLogger( fields=model.getFieldInfo(), experimentDir=cmdOptions.experimentDir, label=task["taskLabel"], inferenceType=self.__model.getInferenceType(), ) taskControl = task["taskControl"] # Create Task Driver self.__taskDriver = OPFTaskDriver(taskControl=taskControl, model=model) loggedMetricPatterns = taskControl.get("loggedMetrics", None) loggedMetricLabels = matchPatterns(loggedMetricPatterns, self.__taskDriver.getMetricLabels()) self.__predictionLogger.setLoggedMetrics(loggedMetricLabels) # Create a prediction metrics logger self.__metricsLogger = opfbasicenvironment.BasicPredictionMetricsLogger( experimentDir=cmdOptions.experimentDir, label=task["taskLabel"] ) def __del__(self): """Destructor""" # print "IN %s.%r destructor" % (type(self), self) def run(self): """Runs a single experiment task""" self.__logger.debug("run(): Starting task <%s>", self.__task["taskLabel"]) # Set up the task # Create our main loop-control iterator if self.__cmdOptions.privateOptions["testMode"]: numIters = 10 else: numIters = self.__task["iterationCount"] if numIters >= 0: iterTracker = iter(xrange(numIters)) else: iterTracker = iter(itertools.count()) # Initialize periodic activities periodic = PeriodicActivityMgr(requestedActivities=self._createPeriodicActivities()) # Reset sequence states in the model, so it starts looking for a new # sequence # TODO: should this be done in OPFTaskDriver.setup(), instead? Is it always # desired in Nupic? self.__model.resetSequenceStates() # Have Task Driver perform its initial setup activities, including setup # callbacks self.__taskDriver.setup() # Run it! while True: # Check controlling iterator first try: next(iterTracker) except StopIteration: break # Read next input record try: inputRecord = self.__datasetReader.next() except StopIteration: break # Process input record result = self.__taskDriver.handleInputRecord(inputRecord=inputRecord) if InferenceElement.encodings in result.inferences: result.inferences.pop(InferenceElement.encodings) self.__predictionLogger.writeRecord(result) # Run periodic activities periodic.tick() # Dump the experiment metrics at the end of the task self._getAndEmitExperimentMetrics(final=True) # Have Task Driver perform its final activities self.__taskDriver.finalize() # Reset sequence states in the model, so it starts looking for a new # sequence # TODO: should this be done in OPFTaskDriver.setup(), instead? Is it always # desired in Nupic? self.__model.resetSequenceStates() def _createPeriodicActivities(self): """Creates and returns a list of activites for this TaskRunner instance Returns: a list of PeriodicActivityRequest elements """ # Initialize periodic activities periodicActivities = [] # Metrics reporting class MetricsReportCb(object): def __init__(self, taskRunner): self.__taskRunner = taskRunner return def __call__(self): self.__taskRunner._getAndEmitExperimentMetrics() reportMetrics = PeriodicActivityRequest(repeating=True, period=1000, cb=MetricsReportCb(self)) periodicActivities.append(reportMetrics) # Iteration progress class IterationProgressCb(object): PROGRESS_UPDATE_PERIOD_TICKS = 1000 def __init__(self, taskLabel, requestedIterationCount, logger): self.__taskLabel = taskLabel self.__requestedIterationCount = requestedIterationCount self.__logger = logger self.__numIterationsSoFar = 0 def __call__(self): self.__numIterationsSoFar += self.PROGRESS_UPDATE_PERIOD_TICKS self.__logger.debug( "%s: ITERATION PROGRESS: %s of %s" % (self.__taskLabel, self.__numIterationsSoFar, self.__requestedIterationCount) ) iterationProgressCb = IterationProgressCb( taskLabel=self.__task["taskLabel"], requestedIterationCount=self.__task["iterationCount"], logger=self.__logger, ) iterationProgressReporter = PeriodicActivityRequest( repeating=True, period=IterationProgressCb.PROGRESS_UPDATE_PERIOD_TICKS, cb=iterationProgressCb ) periodicActivities.append(iterationProgressReporter) return periodicActivities def _getAndEmitExperimentMetrics(self, final=False): # Get metrics metrics = self.__taskDriver.getMetrics() # Emit metrics if metrics is not None: if final: self.__metricsLogger.emitFinalMetrics(metrics) else: self.__metricsLogger.emitPeriodicMetrics(metrics)
class _TaskRunner(object): """This class is responsible for running a single experiment task on the given Model instance """ __FILE_SCHEME = "file://" def __init__(self, model, task, cmdOptions): """ Constructor Args: model: The OPF Model instance against which to run the task task: A dictionary conforming to opfTaskSchema.json cmdOptions: ParseCommandLineOptionsResult namedtuple """ validateOpfJsonValue(task, "opfTaskSchema.json") # Set up our logger self.__logger = logging.getLogger(".".join( ['com.numenta', self.__class__.__module__, self.__class__.__name__])) #self.__logger.setLevel(logging.DEBUG) self.__logger.debug(("Instantiated %s(" + \ "model=%r, " + \ "task=%r, " + \ "cmdOptions=%r)") % \ (self.__class__.__name__, model, task, cmdOptions)) # Generate a new dataset from streamDef and create the dataset reader streamDef = task['dataset'] datasetReader = opfbasicenvironment.BasicDatasetReader(streamDef) self.__model = model self.__datasetReader = datasetReader self.__task = task self.__cmdOptions = cmdOptions self.__predictionLogger = opfbasicenvironment.BasicPredictionLogger( fields=model.getFieldInfo(), experimentDir=cmdOptions.experimentDir, label=task['taskLabel'], inferenceType=self.__model.getInferenceType()) taskControl = task['taskControl'] # Create Task Driver self.__taskDriver = OPFTaskDriver( taskControl=taskControl, model=model) loggedMetricPatterns = taskControl.get('loggedMetrics', None) loggedMetricLabels = matchPatterns(loggedMetricPatterns, self.__taskDriver.getMetricLabels()) self.__predictionLogger.setLoggedMetrics(loggedMetricLabels) # Create a prediction metrics logger self.__metricsLogger = opfbasicenvironment.BasicPredictionMetricsLogger( experimentDir=cmdOptions.experimentDir, label=task['taskLabel']) def __del__(self): """Destructor""" #print "IN %s.%r destructor" % (type(self), self) def run(self): """Runs a single experiment task""" self.__logger.debug("run(): Starting task <%s>", self.__task['taskLabel']) # Set up the task # Create our main loop-control iterator if self.__cmdOptions.privateOptions['testMode']: numIters = 10 else: numIters = self.__task['iterationCount'] if numIters >= 0: iterTracker = iter(xrange(numIters)) else: iterTracker = iter(itertools.count()) # Initialize periodic activities periodic = PeriodicActivityMgr( requestedActivities=self._createPeriodicActivities()) # Reset sequence states in the model, so it starts looking for a new # sequence # TODO: should this be done in OPFTaskDriver.setup(), instead? Is it always # desired in Nupic? self.__model.resetSequenceStates() # Have Task Driver perform its initial setup activities, including setup # callbacks self.__taskDriver.setup() # Run it! while True: # Check controlling iterator first try: next(iterTracker) except StopIteration: break # Read next input record try: inputRecord = self.__datasetReader.next() except StopIteration: break # Process input record result = self.__taskDriver.handleInputRecord(inputRecord=inputRecord) if InferenceElement.encodings in result.inferences: result.inferences.pop(InferenceElement.encodings) self.__predictionLogger.writeRecord(result) # Run periodic activities periodic.tick() # Dump the experiment metrics at the end of the task self._getAndEmitExperimentMetrics(final=True) # Have Task Driver perform its final activities self.__taskDriver.finalize() # Reset sequence states in the model, so it starts looking for a new # sequence # TODO: should this be done in OPFTaskDriver.setup(), instead? Is it always # desired in Nupic? self.__model.resetSequenceStates() def _createPeriodicActivities(self): """Creates and returns a list of activites for this TaskRunner instance Returns: a list of PeriodicActivityRequest elements """ # Initialize periodic activities periodicActivities = [] # Metrics reporting class MetricsReportCb(object): def __init__(self, taskRunner): self.__taskRunner = taskRunner return def __call__(self): self.__taskRunner._getAndEmitExperimentMetrics() reportMetrics = PeriodicActivityRequest( repeating=True, period=1000, cb=MetricsReportCb(self)) periodicActivities.append(reportMetrics) # Iteration progress class IterationProgressCb(object): PROGRESS_UPDATE_PERIOD_TICKS = 1000 def __init__(self, taskLabel, requestedIterationCount, logger): self.__taskLabel = taskLabel self.__requestedIterationCount = requestedIterationCount self.__logger = logger self.__numIterationsSoFar = 0 def __call__(self): self.__numIterationsSoFar += self.PROGRESS_UPDATE_PERIOD_TICKS self.__logger.debug("%s: ITERATION PROGRESS: %s of %s" % ( self.__taskLabel, self.__numIterationsSoFar, self.__requestedIterationCount)) iterationProgressCb = IterationProgressCb( taskLabel=self.__task['taskLabel'], requestedIterationCount=self.__task['iterationCount'], logger=self.__logger) iterationProgressReporter = PeriodicActivityRequest( repeating=True, period=IterationProgressCb.PROGRESS_UPDATE_PERIOD_TICKS, cb=iterationProgressCb) periodicActivities.append(iterationProgressReporter) return periodicActivities def _getAndEmitExperimentMetrics(self, final=False): # Get metrics metrics = self.__taskDriver.getMetrics() # Emit metrics if metrics is not None: if final: self.__metricsLogger.emitFinalMetrics(metrics) else: self.__metricsLogger.emitPeriodicMetrics(metrics)