class_docstr: Represent a single graph with additional attributes.
class_docstr_tok: ["Represent","a","single","graph","with","additional","attributes","."]
docstr: Returns the adjacency matrix of the graph. Returns a 2D tensor if
  it is a single graph and a 3D tensor if it is a batched graph, with
  the matrices padded with 0 (B x N x N)
  
  Parameters
  ----------
  batch_view : bool
      Whether to return a batched view of the adjacency matrix(3D, True) or not (2D).
  post_processing_fn : function
      A callback function which takes a binary adjacency matrix (2D)
      and do some post-processing on it.
      The return of this function should also be N x N
  
  Returns
  -------
  torch.Tensor:
      The adjacency matrix (N x N if batch_view=False and B x N x N if batch_view=True).
code: def adj_matrix(
      self,
      batch_view: bool = False,
      post_processing_fn: Callable = None,
  ) -> torch.Tensor:
      """
      Returns the adjacency matrix of the graph. Returns a 2D tensor if
      it is a single graph and a 3D tensor if it is a batched graph, with
      the matrices padded with 0 (B x N x N)
  
      Parameters
      ----------
      batch_view : bool
          Whether to return a batched view of the adjacency matrix(3D, True) or not (2D).
      post_processing_fn : function
          A callback function which takes a binary adjacency matrix (2D)
          and do some post-processing on it.
          The return of this function should also be N x N
  
      Returns
      -------
      torch.Tensor:
          The adjacency matrix (N x N if batch_view=False and B x N x N if batch_view=True).
      """
      if batch_view is False:
          ret = torch.zeros(
              (self.get_node_num(), self.get_node_num())
          ).to(self.device)
          all_edges = self.edges()
          for i in range(len(all_edges)):
              u, v = all_edges[i]
              ret[u][v] = 1
          if post_processing_fn is not None:
              ret = post_processing_fn(ret)
          return ret
      else:
          if not self._is_batch:
              raise Exception(
                  "Cannot enable batch view on a non-batch graph!"
              )
          # assert self._is_batch, "Cannot enable batch view on a non-batch graph!"
          max_num_nodes = max(self._batch_num_nodes)
          ret = torch.zeros(
              (self.batch_size, max_num_nodes, max_num_nodes)
          ).to(self.device)
          cum_num_nodes = 0
          cum_num_edges = 0
          all_edges = self.get_all_edges()
          for i in range(self.batch_size):
              edges = all_edges[
                  cum_num_edges : cum_num_edges
                  + self._batch_num_edges[i]
              ]
              for edge in edges:
                  ret[i][
                      edge[0] - cum_num_nodes, edge[1] - cum_num_nodes
                  ] = 1
              if post_processing_fn is not None:
                  ret[i] = post_processing_fn(ret[i])
              cum_num_nodes += self._batch_num_nodes[i]
              cum_num_edges += self._batch_num_edges[i]
          return ret
  
imports: import os
  import warnings
  from collections import namedtuple
  from typing import Any, Callable, Dict, List, Tuple, Union
  import dgl
  import scipy.sparse
  import torch
  from torch.nn.utils.rnn import pad_sequence
  from .utils import EdgeNotFoundException, SizeMismatchException, check_and_expand, entail_zero_padding, int_to_list, slice_to_list
  from .views import BatchEdgeFeatView, BatchNodeFeatView, EdgeView, NodeFeatView, NodeView
label_desc: Use image node_id 28 for calling the GraphData obj's underlying member method code with example usage: obj.adj_matrix(batch_view, post_processing_fn) and returns: ret, ret