# -------------------------------------------------------- # SiamMask # Licensed under The MIT License # Written by Qiang Wang (wangqiang2015 at ia.ac.cn) # -------------------------------------------------------- from __future__ import division import os import logging import sys import math if hasattr(sys, 'frozen'): # support for py2exe _srcfile = "logging%s__init__%s" % (os.sep, __file__[-4:]) elif __file__[-4:].lower() in ['.pyc', '.pyo']: _srcfile = __file__[:-4] + '.py' else: _srcfile = __file__ _srcfile = os.path.normcase(_srcfile) logs = set() class Filter: def __init__(self, flag): self.flag = flag def filter(self, x): return self.flag class Dummy: def __init__(self, *arg, **kwargs): pass def __getattr__(self, arg): def dummy(*args, **kwargs): pass return dummy def get_format(logger, level): if 'SLURM_PROCID' in os.environ: rank = int(os.environ['SLURM_PROCID']) if level == logging.INFO: logger.addFilter(Filter(rank == 0)) else: rank = 0 format_str = '[%(asctime)s-rk{}-%(filename)s#%(lineno)3d] %(message)s'.format(rank) formatter = logging.Formatter(format_str) return formatter def get_format_custom(logger, level): if 'SLURM_PROCID' in os.environ: rank = int(os.environ['SLURM_PROCID']) if level == logging.INFO: logger.addFilter(Filter(rank == 0)) else: rank = 0 format_str = '[%(asctime)s-rk{}-%(message)s'.format(rank) formatter = logging.Formatter(format_str) return formatter def init_log(name, level = logging.INFO, format_func=get_format): if (name, level) in logs: return logs.add((name, level)) logger = logging.getLogger(name) logger.setLevel(level) ch = logging.StreamHandler() ch.setLevel(level) formatter = format_func(logger, level) ch.setFormatter(formatter) logger.addHandler(ch) return logger def add_file_handler(name, log_file, level = logging.INFO): logger = logging.getLogger(name) fh = logging.FileHandler(log_file) fh.setFormatter(get_format(logger, level)) logger.addHandler(fh) init_log('global') def print_speed(i, i_time, n): """print_speed(index, index_time, total_iteration)""" logger = logging.getLogger('global') average_time = i_time remaining_time = (n - i) * average_time remaining_day = math.floor(remaining_time / 86400) remaining_hour = math.floor(remaining_time / 3600 - remaining_day * 24) remaining_min = math.floor(remaining_time / 60 - remaining_day * 1440 - remaining_hour * 60) logger.info('Progress: %d / %d [%d%%], Speed: %.3f s/iter, ETA %d:%02d:%02d (D:H:M)\n' % (i, n, i/n*100, average_time, remaining_day, remaining_hour, remaining_min)) def find_caller(): def current_frame(): try: raise Exception except: return sys.exc_info()[2].tb_frame.f_back f = current_frame() if f is not None: f = f.f_back rv = "(unknown file)", 0, "(unknown function)" while hasattr(f, "f_code"): co = f.f_code filename = os.path.normcase(co.co_filename) rv = (co.co_filename, f.f_lineno, co.co_name) if filename == _srcfile: f = f.f_back continue break rv = list(rv) rv[0] = os.path.basename(rv[0]) return rv class LogOnce: def __init__(self): self.logged = set() self.logger = init_log('log_once', format_func=get_format_custom) def log(self, strings): fn, lineno, caller = find_caller() key = (fn, lineno, caller, strings) if key in self.logged: return self.logged.add(key) message = "{filename:s}<{caller}>#{lineno:3d}] {strings}".format(filename=fn, lineno=lineno, strings=strings, caller=caller) self.logger.info(message) once_logger = LogOnce() def log_once(strings): once_logger.log(strings)