code: def forward(self, node_features, edge_indices):
      message_type_emb = {}
      for message_key, message_type in edge_indices.items():
          src_type, edge_type, dst_type = message_key
          node_feature_src = node_features[src_type]
          node_feature_dst = node_features[dst_type]
          edge_index = edge_indices[message_key]
          message_type_emb[message_key] = self.convs[message_key](
              node_feature_src,
              node_feature_dst,
              edge_index,
          )
      node_emb = {dst: [] for _, _, dst in message_type_emb.keys()}
      mapping = {}
      for (src, edge_type, dst), item in message_type_emb.items():
          mapping[len(node_emb[dst])] = (src, edge_type, dst)
          node_emb[dst].append(item)
      self.mapping = mapping
      for node_type, embs in node_emb.items():
          if len(embs) == 1:
              node_emb[node_type] = embs[0]
          else:
              node_emb[node_type] = self.aggregate(embs)
      return node_emb
  
imports: import copy
  import torch
  import argparse
  import deepsnap
  import numpy
  import torch.nn
  import torch.nn.functional
  import torch_geometric.nn
  from sklearn.metrics import f1_score
  from deepsnap.hetero_gnn import forward_op, HeteroSAGEConv
  from deepsnap.hetero_graph import HeteroGraph
  from torch_sparse import SparseTensor, matmul
label_desc: Use image node_id 3 for calling the HeteroGNNWrapperConv obj's underlying member method code with example usage: obj.forward(node_features, edge_indices) and returns: node_emb