code: def forward(self, x):
      if self.metric_type == MetricType.minkowski:
          k = torch.cdist(
              x,
              self.train_data,
              p=self.p,
              compute_mode="donot_use_mm_for_euclid_dist",
          )
      elif self.metric_type == MetricType.wminkowski:
          k = torch.cdist(
              self.w * x,
              self.train_data,
              p=self.p,
              compute_mode="donot_use_mm_for_euclid_dist",
          )
      elif self.metric_type == MetricType.seuclidean:
          k = torch.cdist(
              self.V * x,
              self.train_data,
              p=2,
              compute_mode="donot_use_mm_for_euclid_dist",
          )
      elif self.metric_type == MetricType.mahalanobis:
          # We use the Cholesky decomposition to calculate the Mahalanobis distance
          # Mahalanobis distance d^2(x, x') = (x - x')T VI (x - x')
          # using Cholesky decomposition we have VI = LT L
          # then:
          #                      d^2(x, x') = (x - x')T (LT L) (x - x')
          #                                 = (Lx - Lx')T (Lx - Lx')
          k = torch.cdist(
              torch.mm(x, self.L),
              self.train_data,
              p=2,
              compute_mode="donot_use_mm_for_euclid_dist",
          )
  
      d, k = torch.topk(k, self.n_neighbors, dim=1, largest=False)
      output = torch.index_select(self.train_labels, 0, k.view(-1))
  
      if self.weights == "distance":
          d = torch.pow(d, -1)
          inf_mask = torch.isinf(d)
          inf_row = torch.any(inf_mask, axis=1)
          d[inf_row] = inf_mask[inf_row].float()
      else:
          d = torch.ones_like(k, dtype=torch.float32)
  
      if self.classification:
          # classification
          output = output.view(-1, self.n_neighbors)
          output = torch.scatter_add(self.proba_tensor, 1, output, d)
          proba_sum = output.sum(1, keepdim=True)
          proba_sum = torch.where(
              proba_sum == 0, self.one_tensor, proba_sum
          )
          output = torch.pow(proba_sum, -1) * output
  
          if self.perform_class_select:
              return (
                  torch.index_select(
                      self.classes, 0, torch.argmax(output, dim=1)
                  ),
                  output,
              )
          else:
              return torch.argmax(output, dim=1), output
      else:
          # regression
          if self.n_targets > 1:
              output = output.view(-1, self.n_neighbors, self.n_targets)
              d = d.view(-1, self.n_neighbors, 1)
          else:
              output = output.view(-1, self.n_neighbors)
          output = d * output
          if self.weights != "distance":
              output = output.sum(1) / self.n_neighbors
          else:
              denom = d.sum(1)
              output = output.sum(1) / denom
          return output
  
file_path: hummingbird/hummingbird/ml/operator_converters/_kneighbors_implementations.py
imports: from enum import Enum
  import torch
  import numpy
  from ._physical_operator import PhysicalOperator
label_desc: Use image node_id 2 for calling the KNeighborsModel obj's underlying member method code with example usage: obj.forward(x) and returns: output, torch,  output, torch,  output