code: def forward(self, g, dest):
      src = g.num_nodes() - 1
      possible_dests = range(src)
  
      src_embed_expand = g.nodes[src].data["hv"].expand(src, -1)
      possible_dests_embed = g.nodes[possible_dests].data["hv"]
  
      dests_scores = self.choose_dest(
          torch.cat([possible_dests_embed, src_embed_expand], dim=1)
      ).view(1, -1)
      dests_probs = F.softmax(dests_scores, dim=1)
  
      if not self.training:
          dest = Categorical(dests_probs).sample().item()
  
      if not g.has_edges_between(src, dest):
          # For undirected graphs, we add edges for both directions
          # so that we can perform graph propagation.
          src_list = [src, dest]
          dest_list = [dest, src]
  
          g.add_edges(src_list, dest_list)
          self._initialize_edge_repr(g, src_list, dest_list)
  
          self.graph_op["prop"](g)
  
      if self.training:
          if dests_probs.nelement() > 1:
              self.log_prob.append(
                  F.log_softmax(dests_scores, dim=1)[:, dest : dest + 1]
              )
  
imports: from functools import partial
  import dgl
  import torch
  import torch.nn
  import torch.nn.functional
  from torch.distributions import Bernoulli, Categorical
label_desc: Use image node_id 4 for calling the ChooseDestAndUpdate obj's underlying member method code with example usage: obj.forward(g, dest) without return types