code: def to_csc(
      data: Union[Data, EdgeStorage],
      device: Optional[torch.device] = None,
      share_memory: bool = False,
      is_sorted: bool = False,
      src_node_time: Optional[Tensor] = None,
      edge_time: Optional[Tensor] = None,
  ) -> Tuple[Tensor, Tensor, OptTensor]:
      # Convert the graph data into a suitable format for sampling (CSC format).
      # Returns the `colptr` and `row` indices of the graph, as well as an
      # `perm` vector that denotes the permutation of edges.
      # Since no permutation of edges is applied when using `SparseTensor`,
      # `perm` can be of type `None`.
      perm: Optional[Tensor] = None
  
      if hasattr(data, "adj"):
          if src_node_time is not None:
              raise NotImplementedError(
                  "Temporal sampling via 'SparseTensor' "
                  "format not yet supported"
              )
          colptr, row, _ = data.adj.csc()
  
      elif hasattr(data, "adj_t"):
          if src_node_time is not None:
              # TODO (matthias) This only works when instantiating a
              # `SparseTensor` with `is_sorted=True`. Otherwise, the
              # `SparseTensor` will by default re-sort the neighbors according to
              # column index.
              # As such, we probably want to consider re-adding error:
              # raise NotImplementedError("Temporal sampling via 'SparseTensor' "
              #                           "format not yet supported")
              pass
          colptr, row, _ = data.adj_t.csr()
  
      elif data.edge_index is not None:
          row, col = data.edge_index
          if not is_sorted:
              row, col, perm = sort_csc(
                  row, col, src_node_time, edge_time
              )
          colptr = index2ptr(col, data.size(1))
      else:
          row = torch.empty(0, dtype=torch.long, device=device)
          colptr = torch.zeros(
              data.num_nodes + 1, dtype=torch.long, device=device
          )
  
      colptr = colptr.to(device)
      row = row.to(device)
      perm = perm.to(device) if perm is not None else None
  
      if not colptr.is_cuda and share_memory:
          colptr.share_memory_()
          row.share_memory_()
          if perm is not None:
              perm.share_memory_()
  
      return colptr, row, perm
  
file_path: pytorch_geometric/torch_geometric/sampler/utils.py
imports: from typing import Any, Dict, List, Optional, Tuple, TypeVar, Union
  import torch
  from torch import Tensor
  from torch_geometric.data import Data, HeteroData
  from torch_geometric.data.storage import EdgeStorage
  from torch_geometric.typing import EdgeType, NodeType, OptTensor
  from torch_geometric.utils import coalesce, index_sort, lexsort
  from torch_geometric.utils.sparse import index2ptr
label_desc: Use image node_id 2 for calling a global function with example usage: to_csc(data, device, share_memory, is_sorted, src_node_time, edge_time) and returns: colptr,  row,  perm