code: def _get_edges_dict_from_perhop_df(
      df, etype_id_dict, etype_offset_dict, ntype_offset_dict
  ):
      # Optimize below function
      # based on _get_tensor_ls_from_sampled_df
      edges_per_type_ls = df[
          ["sources", "destinations", "edge_id"]
      ].scatter_by_map(
          df["edge_type"], map_size=len(etype_id_dict), keep_index=False
      )
      del df
      per_type_df_d = {
          etype_id_dict[i]: df for i, df in enumerate(edges_per_type_ls)
      }
      del edges_per_type_ls
      # reverse src,dst here
      per_type_tensor_d = {
          etype: (
              cast_to_tensor(etype_df["sources"])
              - ntype_offset_dict[etype[0]],
              cast_to_tensor(etype_df["destinations"])
              - ntype_offset_dict[etype[2]],
              cast_to_tensor(etype_df["edge_id"])
              - etype_offset_dict[etype],
          )
          for etype, etype_df in per_type_df_d.items()
      }
      return per_type_tensor_d
  
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 12 for calling a global function with example usage: _get_edges_dict_from_perhop_df(df, etype_id_dict, etype_offset_dict, ntype_offset_dict) and returns: per_type_tensor_d