class_docstr: An abstract base class to access edges from a remote graph store.
  
  Args:
      edge_attr_cls (EdgeAttr, optional): A user-defined
          :class:`EdgeAttr` class to customize the required attributes and
          their ordering to uniquely identify edges. (default: :obj:`None`)
class_docstr_tok: ["An","abstract","base","class","to","access","edges","from","a","remote","graph","store",".","Args",":","edge_attr_cls","(","EdgeAttr",",","optional",")",":","A","user-defined",":","class",":","`","EdgeAttr","`","class","to","customize","the","required","attributes","and","their","ordering","to","uniquely","identify","edges",".","(","default",":",":","obj",":","`","None","`",")"]
code: def _edges_to_layout(
      self,
      layout: EdgeLayout,
      edge_types: Optional[List[Any]] = None,
      store: bool = False,
  ) -> ConversionOutputType:
      edge_attrs: List[EdgeAttr] = self.get_all_edge_attrs()
  
      if hasattr(self, "meta"):  # `LocalGraphStore` hack.
          is_hetero = self.meta.get("is_hetero", False)
      else:
          is_hetero = all(
              attr.edge_type is not None for attr in edge_attrs
          )
  
      if not is_hetero:
          return self._edge_to_layout(edge_attrs[0], layout, store)
  
      # Obtain all edge attributes, grouped by type:
      edge_type_attrs: Dict[EdgeType, List[EdgeAttr]] = defaultdict(
          list
      )
      for attr in self.get_all_edge_attrs():
          edge_type_attrs[attr.edge_type].append(attr)
  
      # Check that requested edge types exist and filter:
      if edge_types is not None:
          for edge_type in edge_types:
              if edge_type not in edge_type_attrs:
                  raise ValueError(
                      f"The 'edge_index' of type '{edge_type}' "
                      f"was not found in the graph store."
                  )
  
          edge_type_attrs = {
              key: attr
              for key, attr in edge_type_attrs.items()
              if key in edge_types
          }
  
      # Convert layout from its most favorable original layout:
      row_dict, col_dict, perm_dict = {}, {}, {}
      for edge_type, attrs in edge_type_attrs.items():
          layouts = [attr.layout for attr in attrs]
  
          if layout in layouts:  # No conversion needed.
              attr = attrs[layouts.index(layout)]
          elif EdgeLayout.COO in layouts:  # Prefer COO for conversion.
              attr = attrs[layouts.index(EdgeLayout.COO)]
          elif EdgeLayout.CSC in layouts:
              attr = attrs[layouts.index(EdgeLayout.CSC)]
          elif EdgeLayout.CSR in layouts:
              attr = attrs[layouts.index(EdgeLayout.CSR)]
  
          (
              row_dict[edge_type],
              col_dict[edge_type],
              perm_dict[edge_type],
          ) = self._edge_to_layout(attr, layout, store)
  
      return row_dict, col_dict, perm_dict
  
imports: import copy
  from abc import abstractmethod
  from collections import defaultdict
  from dataclasses import dataclass
  from enum import Enum
  from typing import Any, Dict, List, Optional, Tuple
  from torch import Tensor
  from torch_geometric.typing import EdgeTensorType, EdgeType, OptTensor
  from torch_geometric.utils import index_sort
  from torch_geometric.utils.mixin import CastMixin
  from torch_geometric.utils.sparse import index2ptr, ptr2index
label_desc: Use image node_id 17 for calling the GraphStore obj's underlying member method code with example usage: obj._edges_to_layout(layout, edge_types, store) and returns: row_dict,  col_dict,  perm_dict, self