class_docstr: An utility API to create function_hook callbacks to profile the execution time of each function.
  Passing ``ext_name`` and ``device_id``, you can define which device time you want to profile.
  If `ext_name` = "cuda" or "cudnn", then cudaEvent will be used to measure the execution time.
  For more information about cudaEvent, see the CUDA `document <https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__EVENT.html>`_.
  If `ext_name`="cpu" , then wall-clock-time on host will be used.
  
  Example:
  
  .. code-block:: python
  
      ext_name = "cpu"
      device_id = "0"
  
      from nnabla.ext_utils import get_extension_context
      ctx = get_extension_context(ext_name, device_id=device_id)
      nn.set_default_context(ctx)
  
      y = model(...)
  
      from nnabla.utils.inspection import TimeProfiler
      tp = TimeProfiler(ext_name=ext_name, device_id=device_id)
  
      for i in range(max_iter):
          # All results of executions under "forward" scope are registered as "forward" execution.
          with tp.scope("forward"):
              y.forward(function_pre_hook=tp.pre_hook, function_post_hook=tp.post_hook)
  
          # All results of executions under "backward" scope are registered as "backward" execution.
          with tp.scope("backward") as tp:
              y.backward(function_pre_hook=tp.pre_hook, function_post_hook=tp.post_hook)
  
          # All results are evaluated by passing scopes to .calc_elapsed_time().
          # Be sure to call calc_elapsed_time at each iteration, otherwise nothing is measured.
          tp.calc_elapsed_time(["forward", "backward", "summary"])
  
      # To output results on stdout, call instance as a function.
      tp()
  
      # To write out as csv file, call .to_csv().
      tp.to_csv(output_file_name)
class_docstr_tok: ["An","utility","API","to","create","function_hook","callbacks","to","profile","the","execution","time","of","each","function",".","Passing","``","ext_name","``","and","``","device_id","``",",","you","can","define","which","device","time","you","want","to","profile",".","If","`","ext_name","`","=","``","cuda","''","or","``","cudnn","''",",","then","cudaEvent","will","be","used","to","measure","the","execution","time",".","For","more","information","about","cudaEvent",",","see","the","CUDA","`","document","<","https",":","\/\/docs.nvidia.com\/cuda\/cuda-runtime-api\/group__CUDART__EVENT.html",">","`","_",".","If","`","ext_name","`","=","''","cpu","''",",","then","wall-clock-time","on","host","will","be","used",".","Example",":","..","code-block",":",":","python","ext_name","=","``","cpu","''","device_id","=","``","0","''","from","nnabla.ext_utils","import","get_extension_context","ctx","=","get_extension_context","(","ext_name",",","device_id=device_id",")","nn.set_default_context","(","ctx",")","y","=","model","(","...",")","from","nnabla.utils.inspection","import","TimeProfiler","tp","=","TimeProfiler","(","ext_name=ext_name",",","device_id=device_id",")","for","i","in","range","(","max_iter",")",":","#","All","results","of","executions","under","``","forward","''","scope","are","registered","as","``","forward","''","execution",".","with","tp.scope","(","``","forward","''",")",":","y.forward","(","function_pre_hook=tp.pre_hook",",","function_post_hook=tp.post_hook",")","#","All","results","of","executions","under","``","backward","''","scope","are","registered","as","``","backward","''","execution",".","with","tp.scope","(","``","backward","''",")","as","tp",":","y.backward","(","function_pre_hook=tp.pre_hook",",","function_post_hook=tp.post_hook",")","#","All","results","are","evaluated","by","passing","scopes","to",".calc_elapsed_time","(",")",".","#","Be","sure","to","call","calc_elapsed_time","at","each","iteration",",","otherwise","nothing","is","measured",".","tp.calc_elapsed_time","(","[","``","forward","''",",","``","backward","''",",","``","summary","''","]",")","#","To","output","results","on","stdout",",","call","instance","as","a","function",".","tp","(",")","#","To","write","out","as","csv","file",",","call",".to_csv","(",")",".","tp.to_csv","(","output_file_name",")"]
docstr: Writes out to csv file. Output directory can be specified by `out_dir`.
  As default, the elapsed times of first iteration will be omitted.
  If you evaluate the first iteration as well, pass True to `ignore_init`.
  
  Args:
       out_dir (str): Output directory.
       ignore_init (bool): Ignore the result of the first iteration or not.
docstr_tok: ["Writes","out","to","csv","file",".","Output","directory","can","be","specified","by","`","out_dir","`",".","As","default",",","the","elapsed","times","of","first","iteration","will","be","omitted",".","If","you","evaluate","the","first","iteration","as","well",",","pass","True","to","`","ignore_init","`",".","Args",":","out_dir","(","str",")",":","Output","directory",".","ignore_init","(","bool",")",":","Ignore","the","result","of","the","first","iteration","or","not","."]
code: def to_csv(self, out_dir="./", ignore_init=True):
      """
      Writes out to csv file. Output directory can be specified by `out_dir`.
      As default, the elapsed times of first iteration will be omitted.
      If you evaluate the first iteration as well, pass True to `ignore_init`.
  
      Args:
           out_dir (str): Output directory.
           ignore_init (bool): Ignore the result of the first iteration or not.
      """
      if not os.path.exists(out_dir):
          os.makedirs(out_dir)
  
      res_all = self.average(start_index=1 if ignore_init else 0)
  
      summary_out = [
          dict(res, scope=scope)
          for scope, res in res_all["summary"].items()
      ]
  
      with open(os.path.join(out_dir, "profile_summary.csv"), "w") as f:
          writer = csv.DictWriter(f, ["scope", "time", "scale", "num"])
          writer.writeheader()
          writer.writerows(summary_out)
  
      # below is basically for nnabla functions
      # key is identically distinguished by its id. (not str expression)
      keystr_to_count = {}  # count number based on id
      key_to_unique = {}  # id of key to unique str expression
      out_dict = {}
  
      for scope, scope_res in res_all.items():
          if scope == "summary":
              continue
  
          for key, key_res in scope_res.items():
              insert = {
                  "{}_{}".format(k, scope): v
                  for k, v in key_res.items()
              }
  
              # same key has already existed. -> update
              if key in key_to_unique:
                  out_dict[key_to_unique[key]].update(insert)
                  continue
  
              # new key -> create
              count = keystr_to_count.get(str(key), 0)
              keystr_to_count[str(key)] = count + 1
              key_to_unique[key] = "{}_{}".format(str(key), count)
  
              out_dict[key_to_unique[key]] = insert
  
      # preparation for writing to csv
      detail_out = []
      header = set()
      unique_to_key = {v: k for k, v in key_to_unique.items()}
      for scope, res in out_dict.items():
          header.update([*res.keys()])
          detail_out.append(
              dict(res, scope=scope, original_key=unique_to_key[scope])
          )
  
      with open(os.path.join(out_dir, "profile_detail.csv"), "w") as f:
          writer = csv.DictWriter(
              f, ["scope", "original_key"] + list(header)
          )
          writer.writeheader()
          writer.writerows(detail_out)
  
imports: from __future__ import absolute_import
  import csv
  import os
  import time
  from collections import OrderedDict
  from contextlib import contextmanager
  from importlib import import_module
  import numpy
  from nnabla.ext_utils import import_extension_module
  from .base import FunctionHookCallbackBase
label_desc: Use image node_id 11 for calling the TimeProfiler obj's underlying member method code with example usage: obj.to_csv(out_dir, ignore_init) without return types