code: def forward(self, root_batch):
      orders = []
      for root in root_batch:
          order = get_prop_order(root)
          orders.append(order)
  
      h = {}
      max_depth = max([len(x) for x in orders])
      padding = create_var(torch.zeros(self.hidden_size), False)
  
      for t in range(max_depth):
          prop_list = []
          for order in orders:
              if t < len(order):
                  prop_list.extend(order[t])
  
          cur_x = []
          cur_h_nei = []
          for node_x, node_y in prop_list:
              x, y = node_x.idx, node_y.idx
              cur_x.append(node_x.wid)
  
              h_nei = []
              for node_z in node_x.neighbors:
                  z = node_z.idx
                  if z == y:
                      continue
                  h_nei.append(h[(z, x)])
  
              pad_len = MAX_NB - len(h_nei)
              h_nei.extend([padding] * pad_len)
              cur_h_nei.extend(h_nei)
  
          cur_x = create_var(torch.LongTensor(cur_x))
          cur_x = self.embedding(cur_x)
          cur_h_nei = torch.cat(cur_h_nei, dim=0).view(
              -1, MAX_NB, self.hidden_size
          )
  
          new_h = GRU(
              cur_x, cur_h_nei, self.W_z, self.W_r, self.U_r, self.W_h
          )
          for i, m in enumerate(prop_list):
              x, y = m[0].idx, m[1].idx
              h[(x, y)] = new_h[i]
  
      root_vecs = node_aggregate(root_batch, h, self.embedding, self.W)
  
      return h, root_vecs
  
file_path: DIG/dig/ggraph/method/JTVAE/fast_jtnn/jtnn_enc_bo.py
imports: import torch
  import torch.nn
  from collections import deque
  from .nnutils import create_var, GRU
label_desc: Use image node_id 2 for calling the JTNNEncoderBO obj's underlying member method code with example usage: obj.forward(root_batch) and returns: h,  root_vecs