code: def forward(self, x):
      # x: SparseTensor z: PointTensor
      z = PointTensor(x.F, x.C.float())
  
      x0 = initial_voxelize(z, 1.0, self.vres)
  
      x0 = self.stem(x0)
      z0 = voxel_to_point(x0, z, nearest=False)
      z0.F = z0.F
  
      x1 = point_to_voxel(x0, z0)
      x1 = self.stage1(x1)
      x2 = self.stage2(x1)
      x3 = self.stage3(x2)
      x4 = self.stage4(x3)
      z1 = voxel_to_point(x4, z0)
      z1.F = z1.F + self.point_transforms[0](z0.F)
  
      y1 = point_to_voxel(x4, z1)
      y1.F = self.dropout(y1.F)
      y1 = self.up1[0](y1)
      y1 = torchsparse.cat([y1, x3])
      y1 = self.up1[1](y1)
  
      y2 = self.up2[0](y1)
      y2 = torchsparse.cat([y2, x2])
      y2 = self.up2[1](y2)
      z2 = voxel_to_point(y2, z1)
      z2.F = z2.F + self.point_transforms[1](z1.F)
  
      y3 = point_to_voxel(y2, z2)
      y3.F = self.dropout(y3.F)
      y3 = self.up3[0](y3)
      y3 = torchsparse.cat([y3, x1])
      y3 = self.up3[1](y3)
  
      y4 = self.up4[0](y3)
      y4 = torchsparse.cat([y4, x0])
      y4 = self.up4[1](y4)
      z3 = voxel_to_point(y4, z2)
      z3.F = z3.F + self.point_transforms[2](z2.F)
  
      self.output = self.classifier(z3.F)
      return self.output
  
file_path: torch-points3d/torch_points3d/modules/PVCNN/pvcnn.py
imports: import torch.nn
  import torchsparse
  import torchsparse.nn
  import torchsparse.nn.functional
  from torchsparse.sparse_tensor import SparseTensor
  from torchsparse.point_tensor import PointTensor
  from torchsparse.utils.kernel_region import *
  from torchsparse.utils.helpers import *
  from torch_points3d.modules.PVCNN.blocks import *
  from torch_points3d.modules.PVCNN.utils import *
label_desc: Use image node_id 3 for calling the PVCNN obj's underlying member method code with example usage: obj.forward(x) and returns: self