コード例 #1
0
 def wrapped(*args, **kwargs):
     start_time = time()
     ret = func(*args, **kwargs)
     end_time = time()
     logger.info('collapsed time of calling %s: %0.4f seconds',
                 func.__name__, end_time - start_time)
     return ret
コード例 #2
0
 def _tf_save_data(self, path, value):
     np_array = value.np_array
     if np_array.shape == ():
         np_array = np.array([np_array])
     with open(path, "wb") as fid:
         idx2np.convert_to_file(fid, np_array)
     logger.info("saving %s", path)
コード例 #3
0
 def transform(ugraph):
     if self.APPLICABLE_LIBS is not GENERIC_SENTINEL and ugraph.lib_name not in self.APPLICABLE_LIBS:
         logger.info(
             "%s is not applicable to ugraph with lib name %s, skipping",
             self,
             ugraph.lib_name,
         )
         return ugraph
     new_ugraph = ori_transform(ugraph)
     topologic_order_graph(new_ugraph)
     if self.prune_graph:
         return _prune_graph(new_ugraph)
     return new_ugraph
コード例 #4
0
ファイル: utils.py プロジェクト: yuezha01/utensor_cgen
def save_idx(arr, fname):
    if arr.shape == ():
        arr = np.array([arr], dtype=arr.dtype)
    if arr.dtype in [np.int64]:
        logger.warning(
            "unsupported int format for idx detected: %s, using int32 instead",
            arr.dtype)
        arr = arr.astype(np.int32)
    out_dir = os.path.dirname(fname)
    if out_dir and not os.path.exists(out_dir):
        os.makedirs(out_dir)
    with open(fname, "wb") as fid:
        idx2np.convert_to_file(fid, arr)
    logger.info("%s saved", fname)
コード例 #5
0
 def transform(self, ugraph):
     logger.info("Transforming graph: %s", ugraph.name)
     logger.info("Transform pipeline: %s", ' -> '.join(self.trans_methods))
     if not self._check_generic(ugraph):
         raise ValueError(
             'the given graph is not generic:\n{}'.format(ugraph))
     new_ugraph = self.transformer.transform(ugraph)
     new_ugraph.name = ugraph.name
     logger.info('Graph transormation done')
     if self.save_graph:
         logger.info('Saving transformed graph')
         pkl_fname = "{}_transformed.pkl".format(ugraph.name)
         with open(pkl_fname, 'wb') as fid:
             pickle.dump(new_ugraph, fid)
         logger.info('{} saved'.format(pkl_fname))
     return new_ugraph
コード例 #6
0
def convert_graph(model_file, output_nodes=None, config='utensor_cli.toml', target='utensor', model_name=None):
  from utensor_cgen.frontend import FrontendSelector

  if os.path.exists(config):
    logger.info('config file {} found, reading configurations'.format(config))
    with open(config) as fid:
      config = loads(fid.read())
  else:
    config = {}
  ugraph = FrontendSelector.parse(
    model_file, output_nodes,
    config=config,
    model_name=model_name
  )
  backend = BackendManager.get_backend(target)(config)
  backend.apply(ugraph)
  return ugraph
コード例 #7
0
 def viz_memalloc(
   cls,
   ugraph,
   split_on_large_graph=True,
   num_tensors_per_split=20,
   figsize=None,
   fontsize=12,
   lw=12,
   cmap=_cm.BrBG_r,
   rand_seed=1111
 ):
   seed(rand_seed)
   if TensorAllocationPlanner.KWARGS_NAMESCOPE not in ugraph.attributes:
     logger.info('No tensor allocation plan to visualize: %s', ugraph.name)
     return plt.Figure()
   alloc_plan = ugraph.attributes[TensorAllocationPlanner.KWARGS_NAMESCOPE]
   topo_tensors = sorted(
     [tensor_name for tensor_name in alloc_plan.plan],
     key=lambda tensor_name: alloc_plan.plan[tensor_name].time_slot_start
   )
   return cls._draw_figs(topo_tensors, alloc_plan, cmap, figsize, fontsize, lw, split_on_large_graph, num_tensors_per_split)
コード例 #8
0
 def apply(self, ugraph):
     ref_cnts = Counter()
     life_span = defaultdict(lambda: [None, None])
     for op_info in ugraph.ops_info.values():
         for tensor in op_info.input_tensors:
             ref_cnts[tensor] += 1
     for time_slot, op_name in enumerate(ugraph.topo_order):
         op_info = ugraph.ops_info[op_name]
         for tensor in op_info.output_tensors:
             life_span[tensor][0] = time_slot
         for tensor in op_info.input_tensors:
             ref_cnts[tensor] -= 1
             if ref_cnts[tensor] == 0:
                 life_span[tensor][1] = time_slot
     time_alloc_plan = {}
     for tensor_info, (start, end) in life_span.items():
         time_alloc = TimeslotAllocation(time_slot_start=start,
                                         time_slot_end=end)
         time_alloc_plan[tensor_info] = time_alloc
     logger.info('topo ordered tensor life span analysis done')
     ugraph.attributes[self.KWARGS_NAMESCOPE] = time_alloc_plan
コード例 #9
0
    def _solve_space_alloc(self, tensors_to_schedule, nonoverlap_map):
        model = cp_model.CpModel()
        inter_vars = {}
        tensor_allocs = {}
        for tensor in tensors_to_schedule:
            var_start = model.NewIntVar(0, self.max_pool_size,
                                        '{}_start'.format(tensor.name))
            var_end = model.NewIntVar(0, self.max_pool_size,
                                      '{}_end'.format(tensor.name))
            size = self._compute_tensor_bytes_size(tensor)
            intv_var = model.NewIntervalVar(var_start, size, var_end,
                                            '{}_alloc'.format(tensor.name))
            inter_vars[tensor] = intv_var
            tensor_allocs[tensor] = _VarMemorySpan(var_start, var_end, size)
        for tensor in tensors_to_schedule:
            inter_var = inter_vars[tensor]
            nonoverlap_vars = [inter_vars[t] for t in nonoverlap_map[tensor]]
            for other in nonoverlap_vars:
                model.AddNoOverlap([inter_var, other])
        var_mempool_size = model.NewIntVar(0, self.max_pool_size,
                                           'mempool_size')
        model.AddMaxEquality(var_mempool_size,
                             [alloc.end for alloc in tensor_allocs.values()])
        model.Minimize(var_mempool_size)

        solver = cp_model.CpSolver()
        status = solver.Solve(model)
        alloc_plan = {}
        opt_mempool_size = None
        if status == cp_model.OPTIMAL:
            opt_mempool_size = solver.Value(var_mempool_size)
            for entity, alloc in tensor_allocs.items():
                alloc_plan[entity] = SpaceAllocation(
                    offset_start=solver.Value(alloc.start),
                    size=alloc.size,
                    data_alignment=self.data_alignment,
                )
            logger.info(
                'optimal tensor allocation plan solved, total memory required: %i bytes',
                opt_mempool_size)
            logger.info('number of tensors allocated: %i' % len(alloc_plan))
        else:
            logger.info('tensor allocation plan not found, status: %s',
                        solver.StatusName(status))
            if status == cp_model.INFEASIBLE:
                logger.info(
                    'the optimal plan is infeasible, please set `max_pool_size` a larger value: %s'
                    % self.max_pool_size)
        return alloc_plan, opt_mempool_size
コード例 #10
0
  def _naive_generate_files(
    self, ugraph, required_ops, placeholders, tensor_var_map,
  ):
    (
        ops_map,                 # dict, op_info -> variable name of op in the output files
        out_tensor_var_names,    # list of tensor variable names, which are the variable names of the output tensors of the graph
        declare_global_snippets, # list of Snippet objects, which will rendered in global scop
        declare_local_snippets,  # list of Snippet objects, which will rendered in local function scope
        weight_snippets,         # snippets for generating weights header file
      ) = self._get_declare_snippets(ugraph, required_ops, tensor_var_map)
    # eval_snippets: List of snippet objects, which will render code snippets for tensor evaluation
    eval_snippets = self._get_evaluation_snippets(ugraph, ops_map, tensor_var_map)
    template_vars = {}
    template_vars['model_name'] = ugraph.name
    template_vars['meta_data_pool_size'] = self._compute_meta_data_size(ugraph)
    template_vars['ram_data_pool_size'] = self._compute_ram_data_size(ugraph)
    template_vars['placeholders'] = placeholders
    template_vars['out_tensor_var_names'] = out_tensor_var_names
    params_dir = Path(self.params_dir) / ugraph.name
    params_dir.mkdir(parents=True, exist_ok=True)
    weight_header_fname = None
    if weight_snippets:
      weight_header_fname = 'params_{}.hpp'.format(ugraph.name)
      with (params_dir / weight_header_fname).open('w') as fid:
        fid.write("/* Auto-generated by utensor cli */\n")
        weight_container = ContextGlobalArrayContainer(
          snippets=weight_snippets
        )
        fid.write(weight_container.render())
        logger.info("model parameters header file generated: %s", fid.name)

    # generate the compute function
    model_file_dir = Path(self.model_dir)
    header_fname = self.header_fname == 'None' and '{}.hpp'.format(ugraph.name) or self.header_fname
    container_snippet = SimpleContainer()
    container_snippet.add_declare_global_snippets(*declare_global_snippets)
    container_snippet.add_declare_local_snippets(*declare_local_snippets)
    container_snippet.add_eval_snippets(*eval_snippets)
    container_snippet.template_vars.update(template_vars)
    (model_file_dir / ugraph.name).mkdir(parents=True, exist_ok=True)
    with (model_file_dir / ugraph.name / header_fname).open('w') as fid:
      fid.write("/* Auto-generated by utensor cli */\n")
      template = env.get_template('snippets/rearch/simple.hpp')
      fid.write(template.render(**template_vars))
      container_snippet.add_header(header_fname)
      logger.info("model header file generated: %s", fid.name)
    if weight_header_fname:
      container_snippet.add_header(weight_header_fname)
    composer = Composer(snippets=[container_snippet])
    src_fname = self.src_fname == 'None' and '{}.cpp'.format(ugraph.name) or self.src_fname
    with (model_file_dir / ugraph.name / src_fname ).open('w') as fid:
      fid.write("/* Auto-generated by utensor cli */\n")
      fid.write(composer.compose())
      logger.info("model cpp file generated: %s", fid.name)
コード例 #11
0
ファイル: utils.py プロジェクト: yuezha01/utensor_cgen
def save_graph(graph, graph_name="graph", out_dir="."):
    out_dir = os.path.expanduser(out_dir)
    graph_fname = os.path.join(out_dir, "{}.pb".format(graph_name))
    with tf.gfile.FastGFile(graph_fname, "wb") as fid:
        fid.write(graph.as_graph_def().SerializeToString())
    logger.info("%s saved", graph_fname)
コード例 #12
0
  def _time_slot_generate_files(
    self, ugraph, placeholders, tensor_var_map,
    weight_snippets, local_snippets, declare_op_snippets, construct_op_snippets,
    input_enums, output_enums,
  ):
    # prepare template variables
    template_vars = {}
    template_vars['model_name'] = ugraph.name
    (template_vars['meta_data_pool_size'],
     template_vars['meta_dtype']) = self._compute_meta_data_size(ugraph)
    (template_vars['ram_data_pool_size'],
     template_vars['ram_dtype']) = self._compute_ram_data_size(ugraph)
    template_vars['placeholders'] = placeholders
    template_vars['out_tensor_var_names'] = [
      tensor_var_map[tensor.name] for tensor in ugraph.output_tensors
    ]
    template_vars['input_enums'] = input_enums
    template_vars['output_enums'] = output_enums
  
    params_dir = Path(self.params_dir) / ugraph.name
    params_dir.mkdir(parents=True, exist_ok=True)
    params_header_fname = 'params_{}.hpp'.format(ugraph.name)
    with (params_dir / params_header_fname).open('w') as fid:
      fid.write("/* Auto-generated by utensor cli */\n")
      weight_container = ContextGlobalArrayContainer(
        snippets=weight_snippets
      )
      fid.write(weight_container.render())
      logger.info("model parameters header file generated: %s", fid.name)
    model_file_dir = Path(self.model_dir)
    header_fname = self.header_fname == 'None' and '{}.hpp'.format(ugraph.name) or self.header_fname
    (model_file_dir / ugraph.name).mkdir(parents=True, exist_ok=True)
    if self.use_model_api:
      container_snippet = ModelApiContainer()
      container_snippet.add_local_snippets(*local_snippets)
      container_snippet.add_construct_op_snippets(*construct_op_snippets)
      container_snippet.template_vars.update(template_vars)
      container_snippet.add_header('"{}"'.format(params_header_fname))
      with (model_file_dir / ugraph.name / header_fname).open("w") as fid:
        fid.write("/* Auto-generated by utensor cli */\n")
        template = env.get_template('snippets/rearch/model_api.hpp')
        fid.write(
          template.render(
            declare_op_snippets=declare_op_snippets,
            **template_vars
          )
        )
        # container_snippet.add_header('"{}"'.format(fid.name))
        container_snippet.add_header('"{}"'.format(header_fname))
        logger.info("model header file generated: %s", fid.name)
    else:
      container_snippet = TimeSlotContainer()
      container_snippet.add_local_snippets(*declare_op_snippets)
      container_snippet.add_local_snippets(*local_snippets)
      container_snippet.template_vars.update(template_vars)
      container_snippet.add_header('"{}"'.format(params_header_fname))
      with (model_file_dir / ugraph.name / header_fname).open('w') as fid:
        fid.write("/* Auto-generated by utensor cli */\n")
        template = env.get_template('snippets/rearch/simple.hpp')
        fid.write(template.render(**template_vars))
        # container_snippet.add_header('"{}"'.format(fid.name))
        container_snippet.add_header('"{}"'.format(header_fname))
        logger.info("model header file generated: %s", fid.name)

    composer = Composer(snippets=[container_snippet])
    src_fname = self.src_fname == 'None' and '{}.cpp'.format(ugraph.name) or self.src_fname
    with (model_file_dir / ugraph.name / src_fname ).open('w') as fid:
      fid.write("/* Auto-generated by utensor cli */\n")
      fid.write(composer.compose())
      logger.info("model cpp file generated: %s", fid.name)
コード例 #13
0
def viz_graph(ugraph, out_fname=None, view=False, cleanup=True, colored_nodes=None, suffix=''):
  if colored_nodes is None:
    colored_nodes = set()
  else:
    colored_nodes = set(colored_nodes)
  dot = Digraph()
  nodes = {}
  i = 0
  for node in ugraph.ops:
    nodes[node.name] = '{}_{}'.format(chr(ord('a') + i), suffix)
    colored = node.name in colored_nodes
    if colored:
      dot.node(
        nodes[node.name],
        "%s: %s" % (node.name, node.op_type),
        color='lightskyblue1',
        style='filled'
      )
    else:
      dot.node(nodes[node.name], "%s: %s" % (node.name, node.op_type))
    i += 1
    for n in node.input_tensors:
      if n.name in nodes:
        continue
      nodes[n.name] = '{}_{}'.format(chr(ord('a') + i), suffix)
      colored = n.name in colored_nodes
      if colored:
        dot.node(
          nodes[n.name],
          "%s: Tensor" % n.name,
          color='olivedrab2',
          style='filled',
          shape='box',
        )
      else:
        dot.node(nodes[n.name], "%s: Tensor" % n.name, shape='box')
      i += 1
    for n in node.output_tensors:
      if n.name in nodes:
        continue
      nodes[n.name] = '{}_{}'.format(chr(ord('a') + i), suffix)
      colored = n.name in colored_nodes
      if colored:
        dot.node(
          nodes[n.name],
          "%s: Tensor" % n.name,
          color='olivedrab2',
          style='filled',
          shape='box',
        )
      else:
        dot.node(nodes[n.name], "%s: Tensor" % n.name, shape='box')
      i += 1
  for node in ugraph.ops:
    for n in node.input_tensors:
      dot.edge(nodes[n.name], nodes[node.name])
    for n in node.output_tensors:
      dot.edge(nodes[node.name], nodes[n.name])
  if out_fname:
    dot.render(out_fname, view=view, cleanup=cleanup)
    logger.info('graph visualization file generated: %s', out_fname)
  return dot
コード例 #14
0
 def apply(self, ugraph):
     if not self.enabled:
         # not enabled, do nothing
         return
     time_alloc_plan = ugraph.attributes.get(
         TopoOrderTensorTimeslotPlanner.KWARGS_NAMESCOPE)
     if time_alloc_plan is None:
         TopoOrderTensorTimeslotPlanner(config={}).apply(ugraph)
         time_alloc_plan = ugraph.attributes[
             TopoOrderTensorTimeslotPlanner.KWARGS_NAMESCOPE]
     ops_to_ignore = set(ugraph.get_ops_by_type('Inline'))
     if not self.include_inputs:
         ops_to_ignore.update(ugraph.get_ops_by_type('Placeholder'))
     if not self.include_outputs:
         ops_to_ignore.update(ugraph.output_ops)
     tensors_to_schedule = set()
     nonoverlap_map = defaultdict(set)
     for time_slot, op_name in enumerate(ugraph.topo_order):
         op_info = ugraph.ops_info[op_name]
         if op_info in ops_to_ignore:
             continue
         # all output tensor should not overlap with tensors that's still alive
         for out_tensor, known_tensor in product(op_info.output_tensors,
                                                 tensors_to_schedule):
             time_alloc = time_alloc_plan[known_tensor]
             if time_slot in time_alloc:
                 nonoverlap_map[out_tensor].add(known_tensor)
         # all output tensors should not overlap with each other
         for out_tensor1, out_tensor2 in combinations(
                 op_info.output_tensors, 2):
             nonoverlap_map[out_tensor1].add(out_tensor2)
         # update tensors to be scheduled
         tensors_to_schedule.update(op_info.output_tensors)
     space_alloc_plan, opt_mempool_size = self._solve_space_alloc(
         tensors_to_schedule, nonoverlap_map)
     time_space_allocs = []
     if space_alloc_plan:
         for tensor_name in space_alloc_plan:
             space_alloc = space_alloc_plan[tensor_name]
             time_alloc = time_alloc_plan[tensor_name]
             time_space_allocs.append(
                 TimeSpaceAllocation(tensor_name,
                                     time_alloc=time_alloc,
                                     space_alloc=space_alloc))
         ugraph.attributes[self.KWARGS_NAMESCOPE] = AllocationPlan(
             allocs=time_space_allocs, total_size=opt_mempool_size)
         if self.out_fname:
             figs = viz_memalloc(ugraph=ugraph, **self.aesthetic_kwargs)
             if len(figs) == 1:
                 logger.info('saving tensor mem allocation to %s',
                             self.out_fname)
                 figs[0].savefig(self.out_fname)
             else:
                 num_digits = ceil(log10(len(figs)))
                 file_format = '{{}}_{{:0{}d}}{{}}'.format(num_digits)
                 for i, fig in enumerate(figs, 1):
                     fname, ext = os.path.splitext(self.out_fname)
                     fname = file_format.format(fname, i, ext)
                     logger.info('saving tensor mem allocation to %s',
                                 fname)
                     fig.savefig(fname)
             with open('{}.pkl'.format(self.out_fname), 'wb') as fid:
                 pickle.dump(figs, fid)
                 logger.info('matplotlib figure object dumped (pickle): %s',
                             fid.name)