hyrax.tensorboardx_logger
=========================

.. py:module:: hyrax.tensorboardx_logger


Attributes
----------

.. autoapisummary::

   hyrax.tensorboardx_logger.tensorboardx_logger
   hyrax.tensorboardx_logger.tensorboard_start_ns


Classes
-------

.. autoapisummary::

   hyrax.tensorboardx_logger.HyraxSummaryWriter


Functions
---------

.. autoapisummary::

   hyrax.tensorboardx_logger.get_tensorboard_logger
   hyrax.tensorboardx_logger.init_tensorboard_logger
   hyrax.tensorboardx_logger.close_tensorboard_logger


Module Contents
---------------

.. py:data:: tensorboardx_logger
   :value: None


.. py:data:: tensorboard_start_ns
   :value: 0


.. py:function:: get_tensorboard_logger()

   Get a Tensorboard logging object.

   This is a way for code that just needs to log data to get a handle to the global tensorboard logger.
   Client code does not need to handle initialization order, it can simply log.

   If there is no tensorboard logger set up, messages will be dropped silently.


.. py:function:: init_tensorboard_logger(**kwargs)

   Initialize a Tensorboard SummaryWriter for use by the whole process.

   Args are those to SummaryWriter's constructor.

   If there already is a Tensorboard Logger initialized for this process, it will
   be closed by this function call before the new one is initialized.

   This should be called by code that controls overall hyrax execution e.g. a Verb's run() method.


.. py:function:: close_tensorboard_logger()

   Close the existing global tensorboard logger.

   If there is no global tensorboard logger, this does nothing.


.. py:class:: HyraxSummaryWriter

   This is a wrapper class around TensorboardX SummaryWriter that allows definition
   of convenience methods for commonly-used logging.

   For client code that just wants to log Typical usage is:

   from hyrax.tensorboardx_logger import get_tensorboard_logger
   tensorboardx_logger = get_tensorboard_logger()

   ...in code...

   tensorboardx_logger.log_scalar(...)
   tensorboardx_logger.log_duration(...)

   For code controlling overall process execution (e.g. a hyrax verb run method) usage looks like:

   from hyrax.tensorboardx_logger import init_tensorboard_logger, close_tensorboard_logger

   def run():
       init_tensorboard_logger(log_dir="some/path/")

       ... do things ...

       close_tensorboard_logger()
       return


   __dir__ and __getattr__ pass through function calls to the underlying tensorboardX SummaryWriter if
   it exists. Otherwise empty/noop objects are returned. We don't use inheritance here because we want
   consumers to not have to think about initialization order concerns, yet have a handle to a pile of
   functions that all log to the one true tensorboard instance (if it exists)

   All functions defined here need to be noops when global tensorboardx_logger is None.

   We have the capacity to place information on instances of this class (e.g. a name prefix)
   but its not implemented. One major issue is providing continuity of interface with tensorboard's
   functions that don't recognize a name prefix. For now, the fully qualified tensorboard name of the
   data is the common interface, since that follows what tensorboard functions expect.



   .. py:method:: log_duration_ts(name: str, start_time: int)

      Log a duration to tensorboardX as a time series if configured.

      Caller provides the start of the duration in time.monotonic_ns
      End of the duration is assumed to be the moment the function is called.

      :param name: The name of the scalar to log
      :type name: str
      :param start_time: Start time in nanoseconds from time.monotonic_ns()
      :type start_time: int



   .. py:method:: log_scalar_ts(name: str, scalar, since_tensorboard_start_ns=None)

      Log a scalar to tensorboardX as a time series if configured.

      :param name: The name of the scalar to log
      :type name: str
      :param scalar: The value to log. Really ought to be a number.
      :type scalar: Any
      :param since_tensorboard_start_ns: Log time in nanoseconds from the beginning of tensorboard logging.
                                         If not provided, this will be calculated at the moment this function is called
      :type since_tensorboard_start_ns: int, Optional



   .. py:method:: __dir__()


   .. py:method:: __getattr__(name)


