code: def _compute_and_update_PI_kernel(
      idx,
      T_A,
      T_B,
      m,
      QT_even,
      QT_odd,
      QT_first,
      μ_Q,
      σ_Q,
      M_T,
      Σ_T,
      Q_subseq_isconstant,
      T_subseq_isconstant,
      w,
      ignore_trivial,
      excl_zone,
      profile,
      profile_L,
      profile_R,
      indices,
      indices_L,
      indices_R,
      compute_QT,
      bfs,
      nlevel,
      k,
  ):
      """
      A Numba CUDA kernel to update the matrix profile and matrix profile indices
  
      Parameters
      ----------
      idx : int
          The index for sliding window `j` (in  `T_B`)
  
      T_A : numpy.ndarray
          The time series or sequence for which to compute the dot product
  
      T_B : numpy.ndarray
          The time series or sequence that will be used to annotate T_A. For every
          subsequence in T_A, its nearest neighbor in T_B will be recorded.
  
      m : int
          Window size
  
      QT_even : numpy.ndarray
          The input QT array (dot product between the query sequence,`Q`, and
          time series, `T`) to use when `i` is even
  
      QT_odd : numpy.ndarray
          The input QT array (dot product between the query sequence,`Q`, and
          time series, `T`) to use when `i` is odd
  
      QT_first : numpy.ndarray
          Dot product between the first query sequence,`Q`, and time series, `T`
  
      μ_Q : numpy.ndarray
          Mean of the query sequence, `Q`
  
      σ_Q : numpy.ndarray
          Standard deviation of the query sequence, `Q`
  
      M_T : numpy.ndarray
          Sliding mean of time series, `T`
  
      Σ_T : numpy.ndarray
          Sliding standard deviation of time series, `T`
  
      Q_subseq_isconstant : numpy.ndarray
          A boolean array that indicates whether the subsequence in `Q` is constant (True)
  
      T_subseq_isconstant : numpy.ndarray
          A boolean array that indicates whether a subsequence in `T` is constant (True)
  
      w : int
          The total number of sliding windows to iterate over
  
      ignore_trivial : bool
          Set to `True` if this is a self-join. Otherwise, for AB-join, set this to
          `False`.
  
      excl_zone : int
          The half width for the exclusion zone relative to the current
          sliding window
  
      profile : numpy.ndarray
          The (top-k) matrix profile, sorted in ascending order per row
  
      profile_L : numpy.ndarray
          The (top-1) left matrix profile
  
      profile_R : numpy.ndarray
          The (top-1) right matrix profile
  
      indices : numpy.ndarray
          The (top-k) matrix profile indices
  
      indices_L : numpy.ndarray
          The (top-1) left matrix profile indices
  
      indices_R : numpy.ndarray
          The (top-1) right matrix profile indices
  
      compute_QT : bool
          A boolean flag for whether or not to compute QT
  
      bfs : numpy.ndarray
          The breadth-first-search indices where the missing leaves of its corresponding
          binary search tree are filled with -1.
  
      nlevel : int
          The number of levels in the binary search tree from which the array
          `bfs` is obtained.
  
      k : int
          The number of top `k` smallest distances used to construct the matrix profile.
          Note that this will increase the total computational time and memory usage
          when k > 1.
  
      Returns
      -------
      None
  
      Notes
      -----
      `DOI: 10.1109/ICDM.2016.0085 \
      <https://www.cs.ucr.edu/~eamonn/STOMP_GPU_final_submission_camera_ready.pdf>`__
  
      See Table II, Figure 5, and Figure 6
      """
      start = cuda.grid(1)
      stride = cuda.gridsize(1)
  
      j = idx
      # The name `i` is reserved to be used as an index for `T_A`
  
      if j % 2 == 0:
          QT_out = QT_even
          QT_in = QT_odd
      else:
          QT_out = QT_odd
          QT_in = QT_even
  
      for i in range(start, QT_out.shape[0], stride):
          zone_start = max(0, i - excl_zone)
          zone_stop = min(w, i + excl_zone)
  
          if compute_QT:
              QT_out[i] = (
                  QT_in[i - 1]
                  - T_A[i - 1] * T_B[j - 1]
                  + T_A[i + m - 1] * T_B[j + m - 1]
              )
  
              QT_out[0] = QT_first[j]
          if math.isinf(μ_Q[i]) or math.isinf(M_T[j]):
              p_norm = np.inf
          elif Q_subseq_isconstant[i] and T_subseq_isconstant[j]:
              p_norm = 0
          elif Q_subseq_isconstant[i] or T_subseq_isconstant[j]:
              p_norm = m
          else:
              denom = (σ_Q[i] * Σ_T[j]) * m
              denom = max(denom, config.STUMPY_DENOM_THRESHOLD)
              ρ = (QT_out[i] - (μ_Q[i] * M_T[j]) * m) / denom
              ρ = min(ρ, 1.0)
              p_norm = 2 * m * (1.0 - ρ)
  
          if ignore_trivial:
              if j <= zone_stop and j >= zone_start:
                  p_norm = np.inf
              if p_norm < profile_L[i] and j < i:
                  profile_L[i] = p_norm
                  indices_L[i] = j
              if p_norm < profile_R[i] and j > i:
                  profile_R[i] = p_norm
                  indices_R[i] = j
  
          if p_norm < profile[i, -1]:
              idx = core._gpu_searchsorted_right(
                  profile[i], p_norm, bfs, nlevel
              )
              for g in range(k - 1, idx, -1):
                  profile[i, g] = profile[i, g - 1]
                  indices[i, g] = indices[i, g - 1]
  
              profile[i, idx] = p_norm
              indices[i, idx] = j
  
file_path: stumpy/stumpy/gpu_stump.py
imports: import math
  import multiprocessing
  import os
  import numpy
  from numba import cuda
  from .None import config, core
  from .gpu_aamp import gpu_aamp
label_desc: Use image node_id 1 for calling a global function with example usage: _compute_and_update_PI_kernel(idx, T_A, T_B, m, QT_even, QT_odd, QT_first, μ_Q, σ_Q, M_T, Σ_T, Q_subseq_isconstant, T_subseq_isconstant, w, ignore_trivial, excl_zone, profile, profile_L, profile_R, indices, indices_L, indices_R, compute_QT, bfs, nlevel, k) without return types