class_docstr: This simple profiler records the duration of model prediction in seconds,
  and compute the net percentage duration of each sub models via 'model_dependencies'.
  Usage:
      model = modelkit.load_model(...)
      profiler = SimpleProfiler(model)
      res = model(item)
      profiler.summary() # return profiling result (Dict) or str
  
  Attributes:
      recording_hook (Dict[str, float]): record start/end time of each model call
      durations (List[float]): record duration of each model call
      net_durations (List[float]): record net duration of each model call. Net
          duration is the duration minus all the other sub models' duration.
      graph (Dict[str, Set]): model dependencies graph, get all direct children names
          (Set[str])
      graph_calls (Dict[str, Dict[str, int]]): record all model calls
          e.g
          {
              "pipeline": {
                  "__main__": 1, # "pipeline" is called once
                  "model_a": 2,
                  "model_b": 1,
                  "model_c": 1,
              }
          }
  See test_simple_profiler.py for more details.
class_docstr_tok: ["This","simple","profiler","records","the","duration","of","model","prediction","in","seconds",",","and","compute","the","net","percentage","duration","of","each","sub","models","via","'model_dependencies","'",".","Usage",":","model","=","modelkit.load_model","(","...",")","profiler","=","SimpleProfiler","(","model",")","res","=","model","(","item",")","profiler.summary","(",")","#","return","profiling","result","(","Dict",")","or","str","Attributes",":","recording_hook","(","Dict","[","str",",","float","]",")",":","record","start\/end","time","of","each","model","call","durations","(","List","[","float","]",")",":","record","duration","of","each","model","call","net_durations","(","List","[","float","]",")",":","record","net","duration","of","each","model","call",".","Net","duration","is","the","duration","minus","all","the","other","sub","models","'","duration",".","graph","(","Dict","[","str",",","Set","]",")",":","model","dependencies","graph",",","get","all","direct","children","names","(","Set","[","str","]",")","graph_calls","(","Dict","[","str",",","Dict","[","str",",","int","]","]",")",":","record","all","model","calls","e.g","{","``","pipeline","''",":","{","``","__main__","''",":","1",",","#","``","pipeline","''","is","called","once","``","model_a","''",":","2",",","``","model_b","''",":","1",",","``","model_c","''",":","1",",","}","}","See","test_simple_profiler.py","for","more","details","."]
docstr: Infer all sub models call (`sub_calls`) using `previous_calls` and update
  `graph_calls` and the end of context manager.
  
  P.S With the 'shared' context manager, we can't directly record `sub_calls`,
      but only the current model call (incremented in
      self.graph_calls[model_name]["__main__"]).
      Using the counts in "__main__" of all models, we deduce all sub models
      calls.
  
  Args:
      model_name (str): current model name
      previous_calls (Dict[str, int]):
  
  Returns:
      Dict[str, int]: sub_calls
docstr_tok: ["Infer","all","sub","models","call","(","`","sub_calls","`",")","using","`","previous_calls","`","and","update","`","graph_calls","`","and","the","end","of","context","manager",".","P.S","With","the","'shared","'","context","manager",",","we","ca","n't","directly","record","`","sub_calls","`",",","but","only","the","current","model","call","(","incremented","in","self.graph_calls","[","model_name","]","[","``","__main__","''","]",")",".","Using","the","counts","in","``","__main__","''","of","all","models",",","we","deduce","all","sub","models","calls",".","Args",":","model_name","(","str",")",":","current","model","name","previous_calls","(","Dict","[","str",",","int","]",")",":","Returns",":","Dict","[","str",",","int","]",":","sub_calls"]
code: def _compute_sub_calls_and_update_graph_calls(
      self, model_name: str, previous_calls: Dict[str, int]
  ) -> Dict[str, int]:
      """Infer all sub models call (`sub_calls`) using `previous_calls` and update
      `graph_calls` and the end of context manager.
  
      P.S With the 'shared' context manager, we can't directly record `sub_calls`,
          but only the current model call (incremented in
          self.graph_calls[model_name]["__main__"]).
          Using the counts in "__main__" of all models, we deduce all sub models
          calls.
  
      Args:
          model_name (str): current model name
          previous_calls (Dict[str, int]):
  
      Returns:
          Dict[str, int]: sub_calls
      """
      self.graph_calls[model_name]["__main__"] += 1
      sub_calls: Dict[str, int] = {}
      for sub_model in self._get_all_subs(model_name):
          sub_calls[sub_model] = self.graph_calls[sub_model][
              "__main__"
          ] - previous_calls.get(sub_model, 0)
          self.graph_calls[model_name][sub_model] += sub_calls[
              sub_model
          ]
      return sub_calls
  
file_path: modelkit/modelkit/core/profilers/simple.py
imports: import time
  from collections import OrderedDict, defaultdict
  from contextlib import contextmanager
  from typing import Dict, Generator, List, Set, Union
  from tabulate import tabulate
  from modelkit.core.model import Model
  from modelkit.core.profilers.base import BaseProfiler
label_desc: Use image node_id 8 for calling the SimpleProfiler obj's underlying member method code with example usage: obj._compute_sub_calls_and_update_graph_calls(model_name, previous_calls) and returns: sub_calls