class_docstr: Implementation of bigraph interface in pgl.
  
  This is a simple implementation of graph structure in pgl. 
  
  `pgl.BiGraph` is an alias for `pgl.graph.BiGraph` 
  
  Args:
  
      edges: list of (u, v) tuples, 2D numpy.ndarry or 2D paddle.Tensor 
  
      src_num_nodes (optional: int, numpy or paddle.Tensor): Number of src_nodes in a bigraph. 
                         If not provided, the number of src nodes will be infered from edges[:, 0]. 
      dst_num_nodes (optional: int, numpy or paddle.Tensor): Number of dst nodes in a bigraph. 
                         If not provided, the number of dst_nodes will be infered from edges[:, 1]. 
  
      src_node_feat (optional): a dict of numpy array as src node features
      dst_node_feat (optional): a dict of numpy array as dst node features
  
      edge_feat (optional): a dict of numpy array as edge features (should
                              have consistent order with edges)
  
  Examples 1:
  
      - Create a graph with numpy.
      - Convert it into paddle.Tensor .
      - Do send recv for graph neural network.
  
      .. code-block:: python
  
          import numpy as np
          import pgl
  
          src_num_nodes = 4
          dst_num_nodes = 5
          edges = [ (0, 1), (1, 2), (3, 4)]
          src_feat = np.random.randn(4, 100).astype(np.float32)
          dst_feat = np.random.randn(5, 100).astype(np.float32)
          edge_feature = np.random.randn(3, 100).astype(np.float32)
          graph = pgl.BiGraph(
                      src_num_nodes=src_num_nodes,
                      dst_num_nodes=dst_num_nodes,
                      edges=edges,
                      src_node_feat={
                          "src_feat": src_feat
                      },
                      dst_node_feat={
                          "dst_feat": dst_feat
                      },
                      edge_feat={
                          "edge_feature": edge_feature
                      })
          graph.tensor() 
  
  Examples 2: 
  
      - Create a graph with paddle.Tensor.
      - Do send recv for graph neural network.
  
      .. code-block:: python
          import numpy as np
          import pgl
  
          src_num_nodes = 4
          dst_num_nodes = 5
          edges = paddle.to_tensor([ (0, 1), (1, 2), (3, 4)])
          src_feat = np.random.randn(4, 100).astype(np.float32)
          src_feat = paddle.to_tensor(src_feat)
          dst_feat = np.random.randn(5, 100).astype(np.float32)
          dst_feat = paddle.to_tensor(dst_feat)
          edge_feature = np.random.randn(3, 100).astype(np.float32)
          edge_feature = paddle.to_tensor(edge_feature)
          graph = pgl.BiGraph(
                      src_num_nodes=src_num_nodes,
                      dst_num_nodes=dst_num_nodes,
                      edges=edges,
                      src_node_feat={
                          "src_feat": src_feat
                      },
                      dst_node_feat={
                          "dst_feat": dst_feat
                      },
                      edge_feat={
                          "edge_feature": edge_feature
                      })
class_docstr_tok: ["Implementation","of","bigraph","interface","in","pgl",".","This","is","a","simple","implementation","of","graph","structure","in","pgl",".","`","pgl.BiGraph","`","is","an","alias","for","`","pgl.graph.BiGraph","`","Args",":","edges",":","list","of","(","u",",","v",")","tuples",",","2D","numpy.ndarry","or","2D","paddle.Tensor","src_num_nodes","(","optional",":","int",",","numpy","or","paddle.Tensor",")",":","Number","of","src_nodes","in","a","bigraph",".","If","not","provided",",","the","number","of","src","nodes","will","be","infered","from","edges","[",":",",","0","]",".","dst_num_nodes","(","optional",":","int",",","numpy","or","paddle.Tensor",")",":","Number","of","dst","nodes","in","a","bigraph",".","If","not","provided",",","the","number","of","dst_nodes","will","be","infered","from","edges","[",":",",","1","]",".","src_node_feat","(","optional",")",":","a","dict","of","numpy","array","as","src","node","features","dst_node_feat","(","optional",")",":","a","dict","of","numpy","array","as","dst","node","features","edge_feat","(","optional",")",":","a","dict","of","numpy","array","as","edge","features","(","should","have","consistent","order","with","edges",")","Examples","1",":","-","Create","a","graph","with","numpy",".","-","Convert","it","into","paddle.Tensor",".","-","Do","send","recv","for","graph","neural","network",".","..","code-block",":",":","python","import","numpy","as","np","import","pgl","src_num_nodes","=","4","dst_num_nodes","=","5","edges","=","[","(","0",",","1",")",",","(","1",",","2",")",",","(","3",",","4",")","]","src_feat","=","np.random.randn","(","4",",","100",")",".astype","(","np.float32",")","dst_feat","=","np.random.randn","(","5",",","100",")",".astype","(","np.float32",")","edge_feature","=","np.random.randn","(","3",",","100",")",".astype","(","np.float32",")","graph","=","pgl.BiGraph","(","src_num_nodes=src_num_nodes",",","dst_num_nodes=dst_num_nodes",",","edges=edges",",","src_node_feat=","{","``","src_feat","''",":","src_feat","}",",","dst_node_feat=","{","``","dst_feat","''",":","dst_feat","}",",","edge_feat=","{","``","edge_feature","''",":","edge_feature","}",")","graph.tensor","(",")","Examples","2",":","-","Create","a","graph","with","paddle.Tensor",".","-","Do","send","recv","for","graph","neural","network",".","..","code-block",":",":","python","import","numpy","as","np","import","pgl","src_num_nodes","=","4","dst_num_nodes","=","5","edges","=","paddle.to_tensor","(","[","(","0",",","1",")",",","(","1",",","2",")",",","(","3",",","4",")","]",")","src_feat","=","np.random.randn","(","4",",","100",")",".astype","(","np.float32",")","src_feat","=","paddle.to_tensor","(","src_feat",")","dst_feat","=","np.random.randn","(","5",",","100",")",".astype","(","np.float32",")","dst_feat","=","paddle.to_tensor","(","dst_feat",")","edge_feature","=","np.random.randn","(","3",",","100",")",".astype","(","np.float32",")","edge_feature","=","paddle.to_tensor","(","edge_feature",")","graph","=","pgl.BiGraph","(","src_num_nodes=src_num_nodes",",","dst_num_nodes=dst_num_nodes",",","edges=edges",",","src_node_feat=","{","``","src_feat","''",":","src_feat","}",",","dst_node_feat=","{","``","dst_feat","''",":","dst_feat","}",",","edge_feat=","{","``","edge_feature","''",":","edge_feature","}",")"]
docstr: Send message from all src nodes to dst nodes.
  
  The UDF message function should has the following format.
  
  .. code-block:: python
  
      def message_func(src_feat, dst_feat, edge_feat):
          '''
              Args:
                  src_feat: the node feat dict attached to the src nodes.
                  dst_feat: the node feat dict attached to the dst nodes.
                  edge_feat: the edge feat dict attached to the
                             corresponding (src, dst) edges.
  
              Return:
                  It should return a tensor or a dictionary of tensor. And each tensor
                  should have a shape of (num_edges, dims).
          '''
          return {'msg': src_feat['h']}
  
  Args:
      message_func: UDF function.
      src_feat: a dict {name: tensor,} to build src node feat
      dst_feat: a dict {name: tensor,} to build dst node feat
      edge_feat: a dict {name: tensor,} to build edge feat
  
  Return:
      A dictionary of tensor representing the message. Each of the values
      in the dictionary has a shape (num_edges, dim) which should be collected
      by :code:`recv` function.
docstr_tok: ["Send","message","from","all","src","nodes","to","dst","nodes",".","The","UDF","message","function","should","has","the","following","format",".","..","code-block",":",":","python","def","message_func","(","src_feat",",","dst_feat",",","edge_feat",")",":","``","'","Args",":","src_feat",":","the","node","feat","dict","attached","to","the","src","nodes",".","dst_feat",":","the","node","feat","dict","attached","to","the","dst","nodes",".","edge_feat",":","the","edge","feat","dict","attached","to","the","corresponding","(","src",",","dst",")","edges",".","Return",":","It","should","return","a","tensor","or","a","dictionary","of","tensor",".","And","each","tensor","should","have","a","shape","of","(","num_edges",",","dims",")",".","``","'","return","{","'msg","'",":","src_feat","[","'","h","'","]","}","Args",":","message_func",":","UDF","function",".","src_feat",":","a","dict","{","name",":","tensor",",","}","to","build","src","node","feat","dst_feat",":","a","dict","{","name",":","tensor",",","}","to","build","dst","node","feat","edge_feat",":","a","dict","{","name",":","tensor",",","}","to","build","edge","feat","Return",":","A","dictionary","of","tensor","representing","the","message",".","Each","of","the","values","in","the","dictionary","has","a","shape","(","num_edges",",","dim",")","which","should","be","collected","by",":","code",":","`","recv","`","function","."]
code: def send(
      self,
      message_func,
      src_feat=None,
      dst_feat=None,
      edge_feat=None,
  ):
      """Send message from all src nodes to dst nodes.
  
      The UDF message function should has the following format.
  
      .. code-block:: python
  
          def message_func(src_feat, dst_feat, edge_feat):
              '''
                  Args:
                      src_feat: the node feat dict attached to the src nodes.
                      dst_feat: the node feat dict attached to the dst nodes.
                      edge_feat: the edge feat dict attached to the
                                 corresponding (src, dst) edges.
  
                  Return:
                      It should return a tensor or a dictionary of tensor. And each tensor
                      should have a shape of (num_edges, dims).
              '''
              return {'msg': src_feat['h']}
  
      Args:
          message_func: UDF function.
          src_feat: a dict {name: tensor,} to build src node feat
          dst_feat: a dict {name: tensor,} to build dst node feat
          edge_feat: a dict {name: tensor,} to build edge feat
  
      Return:
          A dictionary of tensor representing the message. Each of the values
          in the dictionary has a shape (num_edges, dim) which should be collected
          by :code:`recv` function.
      """
      if self._is_tensor:
          src_feat_temp = {}
          dst_feat_temp = {}
          if src_feat is not None:
              assert isinstance(
                  src_feat, dict
              ), "The input src_feat must be a dict"
              src_feat_temp.update(src_feat)
  
          if dst_feat is not None:
              assert isinstance(
                  dst_feat, dict
              ), "The input dst_feat must be a dict"
              dst_feat_temp.update(dst_feat)
  
          edge_feat_temp = {}
          if edge_feat is not None:
              assert isinstance(
                  edge_feat, dict
              ), "The input edge_feat must be a dict"
              edge_feat_temp.update(edge_feat)
  
          src = self.edges[:, 0]
          dst = self.edges[:, 1]
  
          src_feat = op.RowReader(src_feat_temp, src)
          dst_feat = op.RowReader(dst_feat_temp, dst)
          msg = message_func(src_feat, dst_feat, edge_feat_temp)
  
          if not isinstance(msg, dict):
              raise TypeError(
                  "The outputs of the %s function is expected to be a dict, but got %s"
                  % (message_func.__name__, type(msg))
              )
          return msg
      else:
          raise ValueError("You must call BiGraph.tensor() first")
  
imports: import os
  import json
  import copy
  import warnings
  from collections import defaultdict
  import numpy
  import paddle
  import paddle.distributed
  from pgl.utils import op
  import pgl.graph_kernel
  from pgl.message import Message
  from pgl.utils.edge_index import EdgeIndex
  from pgl.utils.helper import check_is_tensor, maybe_num_nodes
  from pgl.utils.helper import generate_segment_id_from_index, unique_segment
label_desc: Use image node_id 33 for calling the BiGraph obj's underlying member method code with example usage: obj.send(message_func, src_feat, dst_feat, edge_feat) and returns: msg