code: def _create_heterogenous_sampled_graphs_from_tensors_perhop(
      tensors_perhop_ls, num_nodes_dict, edge_dir
  ):
      if edge_dir not in ["in", "out"]:
          raise ValueError(f"Invalid edge_dir {edge_dir} provided")
      if edge_dir == "out":
          raise ValueError("Outwards edges not supported yet")
      graph_per_hop_ls = []
      output_nodes = None
  
      seed_nodes = None
      for hop_edges_dict in tensors_perhop_ls:
          block = create_heterogenous_dgl_block_from_tensors_dict(
              hop_edges_dict, num_nodes_dict, seed_nodes
          )
          seed_nodes = block.srcdata[dgl.NID]
          if output_nodes is None:
              output_nodes = block.dstdata[dgl.NID]
          graph_per_hop_ls.append(block)
  
      # default DGL behavior
      if edge_dir == "in":
          graph_per_hop_ls.reverse()
      return seed_nodes, output_nodes, graph_per_hop_ls
  
imports: from __future__ import annotations
  from typing import List, Tuple, Dict, Optional
  from collections import defaultdict
  import cudf
  from cugraph.utilities.utils import import_optional
  from cugraph_dgl.nn import SparseGraph
label_desc: Use image node_id 13 for calling a global function with example usage: _create_heterogenous_sampled_graphs_from_tensors_perhop(tensors_perhop_ls, num_nodes_dict, edge_dir) and returns: seed_nodes,  output_nodes,  graph_per_hop_ls