class_docstr: Implements both the Local Spatial Encoding and Attentive Pooling blocks from
  RandLA-Net: Efficient Semantic Segmentation of Large-Scale Point Clouds
  https://arxiv.org/pdf/1911.11236
code: def message(self, x_j, pos_i, pos_j):
      if x_j is None:
          x_j = pos_j
  
      # compute relative position encoding
      vij = pos_i - pos_j
  
      dij = torch.norm(vij, dim=1).unsqueeze(1)
  
      relPointPos = torch.cat([pos_i, pos_j, vij, dij], dim=1)
  
      rij = self.point_pos_nn(relPointPos)
  
      # concatenate position encoding with feature vector
      fij_hat = torch.cat([x_j, rij], dim=1)
  
      # attentative pooling
      g_fij = self.attention_nn(fij_hat)
      s_ij = F.softmax(g_fij, -1)
  
      msg = s_ij * fij_hat
  
      return msg
  
imports: import torch
  import torch.nn.functional
  from torch_geometric.nn import MessagePassing
  from torch_points3d.core.spatial_ops import *
  from torch_points3d.core.base_conv.message_passing import *
label_desc: Use image node_id 3 for calling the RandlaKernel obj's underlying member method code with example usage: obj.message(x_j, pos_i, pos_j) and returns: msg