class_docstr: This module implement base class for graph wrapper.
  
  Currently our PGL is developed based on static computational mode of
  paddle (we'll support dynamic computational model later). We need to build
  model upon a virtual data holder. BaseGraphWrapper provide a virtual
  graph structure that users can build deep learning models
  based on this virtual graph. And then feed real graph data to run
  the models. Moreover, we provide convenient message-passing interface
  (send & recv) for building graph neural networks.
  
  NOTICE: Don't use this BaseGraphWrapper directly. Use :code:`GraphWrapper`
  and :code:`StaticGraphWrapper` to create graph wrapper instead.
class_docstr_tok: ["This","module","implement","base","class","for","graph","wrapper",".","Currently","our","PGL","is","developed","based","on","static","computational","mode","of","paddle","(","we","'ll","support","dynamic","computational","model","later",")",".","We","need","to","build","model","upon","a","virtual","data","holder",".","BaseGraphWrapper","provide","a","virtual","graph","structure","that","users","can","build","deep","learning","models","based","on","this","virtual","graph",".","And","then","feed","real","graph","data","to","run","the","models",".","Moreover",",","we","provide","convenient","message-passing","interface","(","send","&","recv",")","for","building","graph","neural","networks",".","NOTICE",":","Do","n't","use","this","BaseGraphWrapper","directly",".","Use",":","code",":","`","GraphWrapper","`","and",":","code",":","`","StaticGraphWrapper","`","to","create","graph","wrapper","instead","."]
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).
          '''
          pass
  
  Args:
      message_func: UDF function.
      nfeat_list: a list of names or tuple (name, tensor)
      efeat_list: a list of names or tuple (name, tensor)
  
  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",")",".","``","'","pass","Args",":","message_func",":","UDF","function",".","nfeat_list",":","a","list","of","names","or","tuple","(","name",",","tensor",")","efeat_list",":","a","list","of","names","or","tuple","(","name",",","tensor",")","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, nfeat_list=None, efeat_list=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).
              '''
              pass
  
      Args:
          message_func: UDF function.
          nfeat_list: a list of names or tuple (name, tensor)
          efeat_list: a list of names or tuple (name, tensor)
  
      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 efeat_list is None:
          efeat_list = {}
      else:
          warnings.warn(
              "The edge features in argument `efeat_list` should be fetched "
              "from a instance of `pgl.graph_wrapper.GraphWrapper`, "
              "because we have sorted the edges and the order of edges is changed.\n"
              "Therefore, if you use external edge features, "
              "the order of features of each edge may not match its edge, "
              "which can cause serious errors.\n"
              "If you use the `efeat_list` correctly, please ignore this warning."
          )
  
      if nfeat_list is None:
          nfeat_list = {}
  
      src, dst = self.edges
      nfeat = {}
  
      for feat in nfeat_list:
          if isinstance(feat, str):
              nfeat[feat] = self.node_feat[feat]
          else:
              name, tensor = feat
              nfeat[name] = tensor
  
      efeat = {}
      for feat in efeat_list:
          if isinstance(feat, str):
              efeat[feat] = self.edge_feat[feat]
          else:
              name, tensor = feat
              efeat[name] = tensor
  
      msg = send(src, dst, nfeat, efeat, message_func)
      return msg
  
imports: import warnings
  import numpy
  import paddle.fluid
  import paddle.fluid.layers
  from pgl.utils import op
  from pgl.utils import paddle_helper
  from pgl.utils.logger import log
label_desc: Use image node_id 3 for calling the BaseGraphWrapper obj's underlying member method code with example usage: obj.send(message_func, nfeat_list, efeat_list) and returns: msg