code: def forward(self, G, feat_dict):
      # The input is a dictionary of node features for each type
      funcs = {}
      for srctype, etype, dsttype in G.canonical_etypes:
          # Compute W_r * h
          Wh = self.weight[etype](feat_dict[srctype])
          # Save it in graph for message passing
          G.nodes[srctype].data["Wh_%s" % etype] = Wh
          # Specify per-relation message passing functions: (message_func, reduce_func).
          # Note that the results are saved to the same destination feature 'h', which
          # hints the type wise reducer for aggregation.
          funcs[etype] = (
              fn.copy_u("Wh_%s" % etype, "m"),
              fn.mean("m", "h"),
          )
      # Trigger message passing of multiple types.
      # The first argument is the message passing functions for each relation.
      # The second one is the type wise reducer, could be "sum", "max",
      # "min", "mean", "stack"
      G.multi_update_all(funcs, "sum")
      # return the updated node feature dictionary
      return {ntype: G.nodes[ntype].data["h"] for ntype in G.ntypes}
  
imports: import dgl
  import math
  import torch
  import torch.nn
  import torch.nn.functional
  import dgl.function
  from dgl.nn.functional import edge_softmax
label_desc: Use image node_id 2 for calling the HeteroRGCNLayer obj's underlying member method code with example usage: obj.forward(G, feat_dict) and returns: unknown