class_docstr: Base class for all DataFlow 
docstr: * A dataflow can optionally implement :meth:`__len__`. If not implemented, it will
    throw :class:`NotImplementedError`.
  
  * It returns an integer representing the size of the dataflow.
    The return value **may not be accurate or meaningful** at all.
    When saying the length is "accurate", it means that
    :meth:`__iter__` will always yield this many of datapoints before it stops iteration.
  
  * There could be many reasons why :meth:`__len__` is inaccurate.
    For example, some dataflow has dynamic size, if it throws away datapoints on the fly.
    Some dataflow mixes the datapoints between consecutive passes over
    the dataset, due to parallelism and buffering.
    In this case it does not make sense to stop the iteration anywhere.
  
  * Due to the above reasons, the length is only a rough guidance.
    And it's up to the user how to interpret it.
    Inside tensorpack it's only used in these places:
  
    + A default ``steps_per_epoch`` in training, but you probably want to customize
      it yourself, especially when using data-parallel trainer.
    + The length of progress bar when processing a dataflow.
    + Used by :class:`InferenceRunner` to get the number of iterations in inference.
      In this case users are **responsible** for making sure that :meth:`__len__` is "accurate".
      This is to guarantee that inference is run on a fixed set of images.
  
  Returns:
      int: rough size of this dataflow.
  
  Raises:
      :class:`NotImplementedError` if this DataFlow doesn't have a size.
docstr_tok: ["*","A","dataflow","can","optionally","implement",":","meth",":","`","__len__","`",".","If","not","implemented",",","it","will","throw",":","class",":","`","NotImplementedError","`",".","*","It","returns","an","integer","representing","the","size","of","the","dataflow",".","The","return","value","*","*","may","not","be","accurate","or","meaningful","*","*","at","all",".","When","saying","the","length","is","``","accurate","''",",","it","means","that",":","meth",":","`","__iter__","`","will","always","yield","this","many","of","datapoints","before","it","stops","iteration",".","*","There","could","be","many","reasons","why",":","meth",":","`","__len__","`","is","inaccurate",".","For","example",",","some","dataflow","has","dynamic","size",",","if","it","throws","away","datapoints","on","the","fly",".","Some","dataflow","mixes","the","datapoints","between","consecutive","passes","over","the","dataset",",","due","to","parallelism","and","buffering",".","In","this","case","it","does","not","make","sense","to","stop","the","iteration","anywhere",".","*","Due","to","the","above","reasons",",","the","length","is","only","a","rough","guidance",".","And","it","'s","up","to","the","user","how","to","interpret","it",".","Inside","tensorpack","it","'s","only","used","in","these","places",":","+","A","default","``","steps_per_epoch","``","in","training",",","but","you","probably","want","to","customize","it","yourself",",","especially","when","using","data-parallel","trainer",".","+","The","length","of","progress","bar","when","processing","a","dataflow",".","+","Used","by",":","class",":","`","InferenceRunner","`","to","get","the","number","of","iterations","in","inference",".","In","this","case","users","are","*","*","responsible","*","*","for","making","sure","that",":","meth",":","`","__len__","`","is","``","accurate","''",".","This","is","to","guarantee","that","inference","is","run","on","a","fixed","set","of","images",".","Returns",":","int",":","rough","size","of","this","dataflow",".","Raises",":",":","class",":","`","NotImplementedError","`","if","this","DataFlow","does","n't","have","a","size","."]
code: def __len__(self):
      """
      * A dataflow can optionally implement :meth:`__len__`. If not implemented, it will
        throw :class:`NotImplementedError`.
  
      * It returns an integer representing the size of the dataflow.
        The return value **may not be accurate or meaningful** at all.
        When saying the length is "accurate", it means that
        :meth:`__iter__` will always yield this many of datapoints before it stops iteration.
  
      * There could be many reasons why :meth:`__len__` is inaccurate.
        For example, some dataflow has dynamic size, if it throws away datapoints on the fly.
        Some dataflow mixes the datapoints between consecutive passes over
        the dataset, due to parallelism and buffering.
        In this case it does not make sense to stop the iteration anywhere.
  
      * Due to the above reasons, the length is only a rough guidance.
        And it's up to the user how to interpret it.
        Inside tensorpack it's only used in these places:
  
        + A default ``steps_per_epoch`` in training, but you probably want to customize
          it yourself, especially when using data-parallel trainer.
        + The length of progress bar when processing a dataflow.
        + Used by :class:`InferenceRunner` to get the number of iterations in inference.
          In this case users are **responsible** for making sure that :meth:`__len__` is "accurate".
          This is to guarantee that inference is run on a fixed set of images.
  
      Returns:
          int: rough size of this dataflow.
  
      Raises:
          :class:`NotImplementedError` if this DataFlow doesn't have a size.
      """
      raise NotImplementedError()
  
imports: import threading
  from abc import ABCMeta, abstractmethod
  import six
  from ..utils.utils import get_rng
label_desc: Use image node_id 2 for calling the DataFlow obj's underlying member method code with example usage: obj.__len__() without return types