code: def forward(self, g, feat_dict):
      # the input graph is a multi-relational graph, so treated as hetero-graph.
  
      funcs = {}  # message and reduce functions dict
      # for each type of edges, compute messages and reduce them all
      for srctype, etype, dsttype in g.canonical_etypes:
          messages = self.W[etype](
              feat_dict[srctype]
          )  # apply W_l on src feature
          film_weights = self.film[etype](
              feat_dict[dsttype]
          )  # use dst feature to compute affine function paras
          gamma = film_weights[
              :, : self.out_size
          ]  # "gamma" for the affine function
          beta = film_weights[
              :, self.out_size :
          ]  # "beta" for the affine function
          messages = gamma * messages + beta  # compute messages
          messages = F.relu_(messages)
          g.nodes[srctype].data[etype] = messages  # store in ndata
          funcs[etype] = (
              fn.copy_u(etype, "m"),
              fn.sum("m", "h"),
          )  # define message and reduce functions
      g.multi_update_all(
          funcs, "sum"
      )  # update all, reduce by first type-wisely then across different types
      feat_dict = {}
      for ntype in g.ntypes:
          feat_dict[ntype] = self.dropout(
              self.layernorm(g.nodes[ntype].data["h"])
          )  # apply layernorm and dropout
      return feat_dict
  
file_path: dgl/examples/pytorch/GNN-FiLM/main.py
imports: import argparse
  import os
  import dgl
  import dgl.function
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  from data_loader import load_PPI
  from utils import evaluate_f1_score
label_desc: Use image node_id 2 for calling the GNNFiLMLayer obj's underlying member method code with example usage: obj.forward(g, feat_dict) and returns: feat_dict