def __init__(self, cells, defns, remaining_parallel_context=None, overall_parallel_context=None, trace=None, with_undo=True): if trace is None: trace = TRACE_DEFAULT self.overall_parallel_context = overall_parallel_context self.remaining_parallel_context = remaining_parallel_context self.with_undo = with_undo self.results_by_id = defns self.opt_pars = [] other_cells = [] for cell in cells: if isinstance(cell, OptPar): self.opt_pars.append(cell) else: other_cells.append(cell) self._cells = self.opt_pars + other_cells data_sets = [[0], [0, 1]][self.with_undo] self.cell_values = [[None] * len(self._cells) for switch in data_sets] self.arg_ranks = [[] for cell in self._cells] for (i, cell) in enumerate(self._cells): cell.rank = i cell.consequences = {} if isinstance(cell, OptPar): for switch in data_sets: self.cell_values[switch][i] = cell.default_value elif isinstance(cell, ConstCell): for switch in data_sets: self.cell_values[switch][i] = cell.value elif isinstance(cell, EvaluatedCell): cell.arg_ranks = [] for arg in cell.args: if hasattr(arg, 'client_ranks'): arg.client_ranks.append(i) self.arg_ranks[i].append(arg.rank) cell.arg_ranks.append(arg.rank) with parallel.parallel_context( self.remaining_parallel_context): try: cell.prime(self.cell_values) except KeyboardInterrupt: raise except Exception, detail: print("Failed initial calculation of %s" % cell.name) raise else: raise RuntimeError('Unexpected Cell type %s' % type(cell))
def __init__(self, cells, defns, remaining_parallel_context=None, overall_parallel_context=None, trace=None, with_undo=True): if trace is None: trace = TRACE_DEFAULT self.overall_parallel_context = overall_parallel_context self.remaining_parallel_context = remaining_parallel_context self.with_undo = with_undo self.results_by_id = defns self.opt_pars = [] other_cells = [] for cell in cells: if isinstance(cell, OptPar): self.opt_pars.append(cell) else: other_cells.append(cell) self._cells = self.opt_pars + other_cells data_sets = [[0], [0,1]][self.with_undo] self.cell_values = [[None]*len(self._cells) for switch in data_sets] self.arg_ranks = [[] for cell in self._cells] for (i, cell) in enumerate(self._cells): cell.rank = i cell.consequences = {} if isinstance(cell, OptPar): for switch in data_sets: self.cell_values[switch][i] = cell.default_value elif isinstance(cell, ConstCell): for switch in data_sets: self.cell_values[switch][i] = cell.value elif isinstance(cell, EvaluatedCell): cell.arg_ranks = [] for arg in cell.args: if hasattr(arg, 'client_ranks'): arg.client_ranks.append(i) self.arg_ranks[i].append(arg.rank) cell.arg_ranks.append(arg.rank) with parallel.parallel_context(self.remaining_parallel_context): try: cell.prime(self.cell_values) except KeyboardInterrupt: raise except Exception, detail: print ("Failed initial calculation of %s" % cell.name) raise else: raise RuntimeError('Unexpected Cell type %s' % type(cell))
def change(self, changes): """Returns the output value after applying 'changes', a list of (optimisable_parameter_ordinal, new_value) tuples.""" t0 = time.time() self.evaluations += 1 assert parallel.getContext() is self.overall_parallel_context, ( parallel.getContext(), self.overall_parallel_context) # If ALL of the changes made in the last step are reversed in this step # then it is safe to undo them first, taking advantage of the 1-deep # cache. if self.with_undo and self.last_undo: for (i, v) in self.last_undo: if (i,v) not in changes: break else: changes = [ch for ch in changes if ch not in self.last_undo] self._switch = not self._switch for (i, v) in self.last_undo: self.last_values[i] = v self.last_undo = [] program = self.cellsChangedBy(changes) if self.with_undo: self._switch = not self._switch data = self.cell_values[self._switch] base = self.cell_values[not self._switch] # recycle and undo interact in bad ways for rank in self.recycled_cells: if data[rank] is not base[rank]: self.spare[rank] = data[rank] data[:] = base[:] for cell in program: if cell.recycled: if data[cell.rank] is base[cell.rank]: data[cell.rank]=self.spare[cell.rank] assert data[cell.rank] is not base[cell.rank] else: data = self.cell_values[self._switch] # Set new OptPar values changed_optpars = [] for (i, v) in changes: if i < len(self.opt_pars): assert isinstance(v*1.0, float), v changed_optpars.append((i, self.last_values[i])) self.last_values[i] = v data[i] = self.opt_pars[i].transformFromOptimiser(v) else: data[i] = v with parallel.parallel_context(self.remaining_parallel_context): try: if self.trace: self.tracingUpdate(changes, program, data) else: self.plainUpdate(program, data) # if non-optimiser parameter was set then undo is invalid if (self.last_undo and max(self.last_undo)[0] >= len(self.opt_pars)): self.last_undo = [] else: self.last_undo = changed_optpars except CalculationInterupted, detail: if self.with_undo: self._switch = not self._switch for (i,v) in changed_optpars: self.last_values[i] = v self.last_undo = [] (cell, exception) = detail.args raise exception finally:
def change(self, changes): """Returns the output value after applying 'changes', a list of (optimisable_parameter_ordinal, new_value) tuples.""" t0 = time.time() self.evaluations += 1 assert parallel.getContext() is self.overall_parallel_context, ( parallel.getContext(), self.overall_parallel_context) # If ALL of the changes made in the last step are reversed in this step # then it is safe to undo them first, taking advantage of the 1-deep # cache. if self.with_undo and self.last_undo: for (i, v) in self.last_undo: if (i, v) not in changes: break else: changes = [ch for ch in changes if ch not in self.last_undo] self._switch = not self._switch for (i, v) in self.last_undo: self.last_values[i] = v self.last_undo = [] program = self.cellsChangedBy(changes) if self.with_undo: self._switch = not self._switch data = self.cell_values[self._switch] base = self.cell_values[not self._switch] # recycle and undo interact in bad ways for rank in self.recycled_cells: if data[rank] is not base[rank]: self.spare[rank] = data[rank] data[:] = base[:] for cell in program: if cell.recycled: if data[cell.rank] is base[cell.rank]: data[cell.rank] = self.spare[cell.rank] assert data[cell.rank] is not base[cell.rank] else: data = self.cell_values[self._switch] # Set new OptPar values changed_optpars = [] for (i, v) in changes: if i < len(self.opt_pars): assert isinstance(v * 1.0, float), v changed_optpars.append((i, self.last_values[i])) self.last_values[i] = v data[i] = self.opt_pars[i].transformFromOptimiser(v) else: data[i] = v with parallel.parallel_context(self.remaining_parallel_context): try: if self.trace: self.tracingUpdate(changes, program, data) else: self.plainUpdate(program, data) # if non-optimiser parameter was set then undo is invalid if (self.last_undo and max(self.last_undo)[0] >= len(self.opt_pars)): self.last_undo = [] else: self.last_undo = changed_optpars except CalculationInterupted, detail: if self.with_undo: self._switch = not self._switch for (i, v) in changed_optpars: self.last_values[i] = v self.last_undo = [] (cell, exception) = detail.args raise exception finally:
def __init__(self, cells, defns, remaining_parallel_context=None, overall_parallel_context=None, trace=None, with_undo=True): if trace is None: trace = TRACE_DEFAULT self.overall_parallel_context = overall_parallel_context self.remaining_parallel_context = remaining_parallel_context self.with_undo = with_undo self.results_by_id = defns self.opt_pars = [] other_cells = [] for cell in cells: if isinstance(cell, OptPar): self.opt_pars.append(cell) else: other_cells.append(cell) self._cells = self.opt_pars + other_cells data_sets = [[0], [0,1]][self.with_undo] self.cell_values = [[None]*len(self._cells) for switch in data_sets] self.arg_ranks = [[] for cell in self._cells] for (i, cell) in enumerate(self._cells): cell.rank = i cell.consequences = {} if isinstance(cell, OptPar): for switch in data_sets: self.cell_values[switch][i] = cell.default_value elif isinstance(cell, ConstCell): for switch in data_sets: self.cell_values[switch][i] = cell.value elif isinstance(cell, EvaluatedCell): cell.arg_ranks = [] for arg in cell.args: if hasattr(arg, 'client_ranks'): arg.client_ranks.append(i) self.arg_ranks[i].append(arg.rank) cell.arg_ranks.append(arg.rank) with parallel.parallel_context(self.remaining_parallel_context): try: cell.prime(self.cell_values) except KeyboardInterrupt: raise except Exception as detail: print(("Failed initial calculation of %s" % cell.name)) raise else: raise RuntimeError('Unexpected Cell type %s' % type(cell)) self._switch = 0 self.recycled_cells = [ cell.rank for cell in self._cells if cell.recycled] self.spare = [None] * len (self._cells) for cell in self._cells[::-1]: for arg in cell.args: arg.consequences[cell.rank] = True arg.consequences.update(cell.consequences) self._programs = {} # Just for timings pre-calc these for opt_par in self.opt_pars: self.cellsChangedBy([(opt_par.rank, None)]) self.last_values = self.getValueArray() self.last_undo = [] self.elapsed_time = 0.0 self.evaluations = 0 self.setTracing(trace) self.optimised = False