code: def forward(self, g):
      if self.num_bases < self.num_rels:
          # generate all weights from bases (equation (3))
          weight = self.weight.view(
              self.in_feat, self.num_bases, self.out_feat
          )
          weight = torch.matmul(self.w_comp, weight).view(
              self.num_rels, self.in_feat, self.out_feat
          )
      else:
          weight = self.weight
      if self.is_input_layer:
  
          def message_func(edges):
              # for input layer, matrix multiply can be converted to be
              # an embedding lookup using source node id
              embed = weight.view(-1, self.out_feat)
              index = (
                  edges.data[dgl.ETYPE] * self.in_feat + edges.src["id"]
              )
              return {"msg": embed[index] * edges.data["norm"]}
  
      else:
  
          def message_func(edges):
              w = weight[edges.data[dgl.ETYPE]]
              msg = torch.bmm(edges.src["h"].unsqueeze(1), w).squeeze()
              msg = msg * edges.data["norm"]
              return {"msg": msg}
  
      def apply_func(nodes):
          h = nodes.data["h"]
          if self.bias:
              h = h + self.bias
          if self.activation:
              h = self.activation(h)
          return {"h": h}
  
      g.update_all(message_func, fn.sum(msg="msg", out="h"), apply_func)
  
imports: import os
  from functools import partial
  import dgl
  import dgl.function
  import torch
  import torch.nn
  import torch.nn.functional
  from dgl import DGLGraph
label_desc: Use image node_id 2 for calling the RGCNLayer obj's underlying member method code with example usage: obj.forward(g) and returns: dict, dict, dict