def reenter(self, **kwds): """Reenter current context, i.e. restart clocks """ node = self.current node.data["cputime"] = node.data.get("cputime", 0) + Accumulator( -process_time(), repr="sum", count=False) node.data["walltime"] = node.data.get("walltime", 0) + Accumulator( -time.time(), repr="sum", count=False)
def exit(self, **kwds): """ When the label is a tour then the status is printed if verbosity > 0. """ node = self.current label = node.label if label[0] == "tour": data = basis_quality([2 ** (2 * r_) for r_ in self.instance.r]) for k, v in data.items(): if k == "/": node.data[k] = Accumulator(v, repr="max") else: node.data[k] = Accumulator(v, repr="min") if self.verbosity and label[0] == "tour": report = OrderedDict() report["i"] = label[1] report["#enum"] = node.sum("#enum") report["r_0"] = node["r_0"] report["/"] = node["/"] print(pretty_dict(report)) self.current = self.current.parent
def db_stats(stats): """ Given a list of traces, find the average of the maximum |db| and the maximum of the maximum |db| for the traces :param stats: a list of traces of type ``Node`` """ max_dbs = Accumulator(0, repr="avg", count=False) for stat in stats: max_dbs += stat.accumulate("|db|", filter=lambda node: SieveTreeTracer.is_sieve_node(node.label), repr="max").max return log(max_dbs.avg, 2), log(max_dbs.max, 2)
def exit(self, **kwds): """ By default CPU and wall time are recorded. More information is recorded for sieve labels. """ node = self.current node.data["cputime"] += process_time() node.data["walltime"] += time.time() self.instance.M.update_gso() if self.is_sieve_node(node.label): if isinstance(self.instance, Siever): instance = self.instance else: instance = self.instance.sieve node.data["|db|"] = Accumulator( len(instance), repr="max") + node.data.get("|db|", None) # determine the type of sieve: # idstring should be among SieveTreeTraces.recognized_sieves or "all". # This is used to look up what statistics to include in Siever.all_statistics if isinstance(node.label, str): idstring = node.label elif isinstance(node.label, tuple): idstring = node.label[0] else: idstring = "all" logging.warning("Unrecognized algorithm in Tracer") for key in Siever.all_statistics: # Siever.all_statistics[key][3] is a list of algorithms for which the statistic # indexed by key is meaningful instance.get_stat(key) will return None if support for # the statistics was not compiled in Siever.all_statistics[key][1] is a short string # that identifies the statistic if ((idstring == "all") or (idstring in Siever.all_statistics[key][3])) and ( instance.get_stat(key) is not None): if (len(Siever.all_statistics[key]) <= 4): node.data[Siever.all_statistics[key][1]] = Accumulator( 0, repr="sum") else: node.data[Siever.all_statistics[key][1]] = Accumulator( 0, repr=Siever.all_statistics[key][4]) node.data[Siever.all_statistics[key][1]] += node.data.get( Siever.all_statistics[key][1], None) try: i, length, v = (instance.best_lifts())[0] if i == 0: node.data["|v|"] = length else: self.instance.update_gso(0, self.instance.full_n) node.data["|v|"] = self.instance.M.get_r(0, 0) except (IndexError, AttributeError): node.data["|v|"] = None data = basis_quality(self.instance.M) for k, v in data.items(): if k == "/": node.data[k] = Accumulator(v, repr="max") else: node.data[k] = Accumulator(v, repr="min") if kwds.get("dump_gso", node.level <= 1): node.data["r"] = self.instance.M.r() verbose_labels = ["tour", "prog_tour"] if self.verbosity and node.label[0] in verbose_labels: report = OrderedDict() report["i"] = node.label[1] report["cputime"] = node["cputime"] report["walltime"] = node["walltime"] try: report["preproc"] = node.find("preprocessing", True)["cputime"] except KeyError: pass try: report["svp"] = node.find("sieve", True)["cputime"] # TODO: re-implement # report["sieve sat"] = node.find("sieve", True)["saturation"] except KeyError: pass report["r_0"] = node["r_0"] report["/"] = node["/"] print(pretty_dict(report)) self.current = self.current.parent return self.trace
def inc_cost(self, cost): self.current.data["cost"] += Accumulator(cost, repr="sum")
def reenter(self, **kwds): """ Reenter current context. """ self.current.data["cost"] = self.current.data.get("cost", Accumulator(1, repr="sum"))
class Stats: date: str host: str nlen: int m: int errors: float klen: float alg: str seed: int params: str tag: int complete: bool = False successes: Accumulator = Accumulator(0, repr="sum", count=False) trials: Accumulator = Accumulator(0, repr="sum", count=False) cputime = Accumulator(0, repr="avg", count=False) walltime = Accumulator(0, repr="avg", count=False) work = Accumulator(0, repr="avg", count=False) v_over_b0 = Accumulator(0, repr="avg", count=False) def __repr__(self): if float(self.trials) == 0: return ( "{{" "tag: 0x{stat.tag:016x}, " "nlen: {stat.nlen:3d}, klen: {stat.klen:.3f}, m: {stat.m:3d}, " " NO DATA " 'alg: "{stat.alg}", params: {{{stat.params}}}' "}}".format(stat=self)) return ( "{{" "tag: 0x{stat.tag:016x}, " "nlen: {stat.nlen:3d}, klen: {stat.klen:.3f}, m: {stat.m:3d}, " "e: {stat.errors:.3f}, " "successes: {stat.successes.sum:4.0f}, sr: {sr:5.1f}%, " "work: {work:>6s}, sf: {sf:.2f}, " "ct: {ct:10.2f}s, ct/sr: {ctsr:10.2f}s, " "wt: {wt:10.2f}s, wt/sr: {wtsr:10.2f}s, " 'alg: "{stat.alg}", params: {{{stat.params}}}' "}}".format( stat=self, sr=self.sr * 100, work="2^%.1f" % log(self.work.avg, 2), sf=self.v_over_b0.avg if self.v_over_b0._ctr else 0.0, ct=self.ct("s"), ctsr=self.ctsr("s"), wt=self.wt("s"), wtsr=self.wtsr("s"), )) def __bool__(self): return float(self.trials) != 0.0 def __lt__(self, other): return (self.nlen, self.klen, self.m, self.alg) < (other.nlen, other.klen, other.m, self.alg) def ct(self, unit="m"): if unit == "s": return float(self.cputime) if unit == "m": return ceil(float(self.cputime) / 60) elif unit == "h": return ceil(float(self.cputime) / 3600) elif unit == "d": return ceil(float(self.cputime) / 24 / 3600) else: raise ValueError(unit) def wt(self, unit="m"): if unit == "s": return float(self.walltime) if unit == "m": return ceil(float(self.walltime) / 60) elif unit == "h": return ceil(float(self.walltime) / 3600) elif unit == "d": return ceil(float(self.walltime) / 24 / 3600) else: raise ValueError(unit) def ctsr(self, unit="m"): return ceil(self.ct(unit=unit) / self.sr) if self.sr != 0.0 else 0 def wtsr(self, unit="m"): return ceil(self.wt(unit=unit) / self.sr) if self.sr != 0.0 else 0 @property def sr(self): if float(self.trials) == 0: return 0.0 else: return float(self.successes) / float(self.trials)