Commit a5dc2dd8 authored by Patrick Wieschollek's avatar Patrick Wieschollek Committed by Yuxin Wu

humanize time delta into a proper format rather than 48964518 sec. (#658)

* humanize time delta into a proper format rather than 48964518 sec.

* remove 3rd party dependency

* handle non-integer cases

* add documentation

* proper named function

* use datetime.timedelta
parent 4e9e35b5
...@@ -10,6 +10,7 @@ import traceback ...@@ -10,6 +10,7 @@ import traceback
from .base import Callback from .base import Callback
from .hooks import CallbackToHook from .hooks import CallbackToHook
from ..utils import logger from ..utils import logger
from ..utils.utils import humanize_time_delta
__all__ = ['Callbacks'] __all__ = ['Callbacks']
...@@ -30,13 +31,14 @@ class CallbackTimeLogger(object): ...@@ -30,13 +31,14 @@ class CallbackTimeLogger(object):
self.add(name, time.time() - s) self.add(name, time.time() - s)
def log(self): def log(self):
""" log the time of some heavy callbacks """ """ log the time of some heavy callbacks """
if self.tot < 3: if self.tot < 3:
return return
msgs = [] msgs = []
for name, t in self.times: for name, t in self.times:
if t / self.tot > 0.3 and t > 1: if t / self.tot > 0.3 and t > 1:
msgs.append("{}: {:.3f}sec".format(name, t)) msgs.append(name + ": " + humanize_time_delta(t))
logger.info( logger.info(
"Callbacks took {:.3f} sec in total. {}".format( "Callbacks took {:.3f} sec in total. {}".format(
self.tot, '; '.join(msgs))) self.tot, '; '.join(msgs)))
......
...@@ -11,6 +11,7 @@ import six ...@@ -11,6 +11,7 @@ import six
from ..callbacks import ( from ..callbacks import (
Callback, Callbacks, Monitors, TrainingMonitor) Callback, Callbacks, Monitors, TrainingMonitor)
from ..utils import logger from ..utils import logger
from ..utils.utils import humanize_time_delta
from ..utils.argtools import call_only_once from ..utils.argtools import call_only_once
from ..tfutils import get_global_step_value from ..tfutils import get_global_step_value
from ..tfutils.tower import TowerFuncWrapper from ..tfutils.tower import TowerFuncWrapper
...@@ -253,8 +254,8 @@ class Trainer(object): ...@@ -253,8 +254,8 @@ class Trainer(object):
self.run_step() # implemented by subclass self.run_step() # implemented by subclass
self._callbacks.trigger_step() self._callbacks.trigger_step()
self._callbacks.after_epoch() self._callbacks.after_epoch()
logger.info("Epoch {} (global_step {}) finished, time:{:.2f} sec.".format( logger.info("Epoch {} (global_step {}) finished, time:{}.".format(
self.loop.epoch_num, self.loop.global_step, time.time() - start_time)) self.loop.epoch_num, self.loop.global_step, humanize_time_delta(time.time() - start_time)))
# trigger epoch outside the timing region. # trigger epoch outside the timing region.
self._callbacks.trigger_epoch() self._callbacks.trigger_epoch()
......
...@@ -6,7 +6,7 @@ import os ...@@ -6,7 +6,7 @@ import os
import sys import sys
from contextlib import contextmanager from contextlib import contextmanager
import inspect import inspect
from datetime import datetime from datetime import datetime, timedelta
from tqdm import tqdm from tqdm import tqdm
import numpy as np import numpy as np
...@@ -16,9 +16,54 @@ __all__ = ['change_env', ...@@ -16,9 +16,54 @@ __all__ = ['change_env',
'fix_rng_seed', 'fix_rng_seed',
'get_tqdm', 'get_tqdm',
'execute_only_once', 'execute_only_once',
'humanize_time_delta'
] ]
def humanize_time_delta(sec):
"""Humanize timedelta given in seconds
Args:
sec (float): time difference in seconds.
Examples:
Several time differences as a human readable string
.. code-block:: python
print humanize_seconds(1) # 1 second
print humanize_seconds(60 + 1) # 1 minute 1 second
print humanize_seconds(87.6) # 1 minute 27 seconds
print humanize_seconds(0.01) # 0.01 seconds
print humanize_seconds(60 * 60 + 1) # 1 hour 0 minutes 1 second
print humanize_seconds(60 * 60 * 24 + 1) # 1 day 0 hours 0 minutes 1 second
print humanize_seconds(60 * 60 * 24 + 60 * 2 + 60*60*9+ 3) # 1 day 9 hours 2 minutes 3 seconds
Returns:
time difference as a readable string
"""
time = datetime(2000, 1, 1) + timedelta(seconds=int(sec))
units = ['day', 'hour', 'minute', 'second']
vals = [time.day - 1, time.hour, time.minute, time.second]
if sec < 60:
vals[-1] = sec
def _format(v, u):
return "{} {}{}".format(v, u, "s" if v > 1 else "")
required = False
ans = []
for v, u in zip(vals, units):
if not required:
if v > 0:
required = True
ans.append(_format(v, u))
else:
ans.append(_format(v, u))
return " ".join(ans)
@contextmanager @contextmanager
def change_env(name, val): def change_env(name, val):
""" """
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment