code: def _gpu_aamp(
      T_A_fname,
      T_B_fname,
      m,
      range_stop,
      excl_zone,
      T_A_subseq_isfinite_fname,
      T_B_subseq_isfinite_fname,
      p,
      p_norm_fname,
      p_norm_first_fname,
      w,
      ignore_trivial=True,
      range_start=1,
      device_id=0,
      k=1,
  ):
      """
      A Numba CUDA version of AAMP for parallel computation of the non-normalized (i.e.,
      without z-normalization) matrix profile, matrix profile indices, left matrix profile
      indices, and right matrix profile indices.
  
      Parameters
      ----------
      T_A_fname : str
          The file name for the time series or sequence for which to compute
          the matrix profile
  
      T_B_fname : str
          The file name for 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
  
      range_stop : int
          The index value along T_B for which to stop the matrix profile
          calculation. This parameter is here for consistency with the
          distributed `stumped` algorithm.
  
      excl_zone : int
          The half width for the exclusion zone relative to the current
          sliding window
  
      T_A_subseq_isfinite_fname : str
          The file name for the boolean array that indicates whether a subsequence in
          `T_A` contains a `np.nan`/`np.inf` value (False)
  
      T_B_subseq_isfinite_fname : str
          The file name for the boolean array that indicates whether a subsequence in
          `T_B` contains a `np.nan`/`np.inf` value (False)
  
      p : float
          The p-norm to apply for computing the Minkowski distance. Minkowski distance is
          typically used with `p` being 1 or 2, which correspond to the Manhattan distance
          and the Euclidean distance, respectively.
  
      p_norm_fname : str
          The file name for the p-norm between some query sequence,`Q`,
          and time series, `T`
  
      p_norm_first_fname : str
          The file name for the p-norm for the first window relative to the current
          sliding window
  
      w : int
          The total number of sliding windows to iterate over
  
      ignore_trivial : bool, default True
          Set to `True` if this is a self-join. Otherwise, for AB-join, set this to
          `False`. Default is `True`.
  
      range_start : int, default 1
          The starting index value along T_B for which to start the matrix
          profile calculation. Default is 1.
  
      device_id : int, default 0
          The (GPU) device number to use. The default value is `0`.
  
      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
      -------
      profile_fname : str
          The file name for the (top-k) matrix profile
  
      profile_L_fname : str
          The file name for the (top-1) left matrix profile
  
      profile_R_fname : str
          The file name for the (top-1) right matrix profile
  
      indices_fname : str
          The file name for the (top-k) matrix profile indices
  
      indices_L_fname : str
          The file name for the (top-1) left matrix profile indices
  
      indices_R_fname : str
          The file name for the (top-1) right matrix profile indices
  
      Notes
      -----
      `arXiv:1901.05708 \
      <https://arxiv.org/pdf/1901.05708.pdf>`__
  
      See Algorithm 1
  
      Note that we have extended this algorithm for AB-joins as well.
  
      `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
      """
      threads_per_block = config.STUMPY_THREADS_PER_BLOCK
      blocks_per_grid = math.ceil(w / threads_per_block)
  
      T_A = np.load(T_A_fname, allow_pickle=False)
      T_B = np.load(T_B_fname, allow_pickle=False)
      p_norm = np.load(p_norm_fname, allow_pickle=False)
      p_norm_first = np.load(p_norm_first_fname, allow_pickle=False)
      T_A_subseq_isfinite = np.load(
          T_A_subseq_isfinite_fname, allow_pickle=False
      )
      T_B_subseq_isfinite = np.load(
          T_B_subseq_isfinite_fname, allow_pickle=False
      )
  
      nlevel = np.floor(np.log2(k) + 1).astype(np.int64)
      # number of levels in binary search tree from which `bfs` is constructed.
  
      with cuda.gpus[device_id]:
          device_T_A = cuda.to_device(T_A)
          device_T_A_subseq_isfinite = cuda.to_device(
              T_A_subseq_isfinite
          )
          device_p_norm_odd = cuda.to_device(p_norm)
          device_p_norm_even = cuda.to_device(p_norm)
          device_p_norm_first = cuda.to_device(p_norm_first)
          if ignore_trivial:
              device_T_B = device_T_A
              device_T_B_subseq_isfinite = device_T_A_subseq_isfinite
          else:
              device_T_B = cuda.to_device(T_B)
              device_T_B_subseq_isfinite = cuda.to_device(
                  T_B_subseq_isfinite
              )
  
          profile = np.full((w, k), np.inf, dtype=np.float64)
          indices = np.full((w, k), -1, dtype=np.int64)
  
          profile_L = np.full(w, np.inf, dtype=np.float64)
          indices_L = np.full(w, -1, dtype=np.int64)
  
          profile_R = np.full(w, np.inf, dtype=np.float64)
          indices_R = np.full(w, -1, dtype=np.int64)
  
          device_profile = cuda.to_device(profile)
          device_profile_L = cuda.to_device(profile_L)
          device_profile_R = cuda.to_device(profile_R)
          device_indices = cuda.to_device(indices)
          device_indices_L = cuda.to_device(indices_L)
          device_indices_R = cuda.to_device(indices_R)
          device_bfs = cuda.to_device(
              core._bfs_indices(k, fill_value=-1)
          )
  
          _compute_and_update_PI_kernel[
              blocks_per_grid, threads_per_block
          ](
              range_start - 1,
              device_T_A,
              device_T_B,
              m,
              p,
              device_p_norm_even,
              device_p_norm_odd,
              device_p_norm_first,
              device_T_A_subseq_isfinite,
              device_T_B_subseq_isfinite,
              w,
              ignore_trivial,
              excl_zone,
              device_profile,
              device_profile_L,
              device_profile_R,
              device_indices,
              device_indices_L,
              device_indices_R,
              False,
              device_bfs,
              nlevel,
              k,
          )
  
          for i in range(range_start, range_stop):
              _compute_and_update_PI_kernel[
                  blocks_per_grid, threads_per_block
              ](
                  i,
                  device_T_A,
                  device_T_B,
                  m,
                  p,
                  device_p_norm_even,
                  device_p_norm_odd,
                  device_p_norm_first,
                  device_T_A_subseq_isfinite,
                  device_T_B_subseq_isfinite,
                  w,
                  ignore_trivial,
                  excl_zone,
                  device_profile,
                  device_profile_L,
                  device_profile_R,
                  device_indices,
                  device_indices_L,
                  device_indices_R,
                  True,
                  device_bfs,
                  nlevel,
                  k,
              )
  
          profile = device_profile.copy_to_host()
          profile_L = device_profile_L.copy_to_host()
          profile_R = device_profile_R.copy_to_host()
          indices = device_indices.copy_to_host()
          indices_L = device_indices_L.copy_to_host()
          indices_R = device_indices_R.copy_to_host()
  
          profile[:, :] = np.power(profile, 1.0 / p)
          profile_L[:] = np.power(profile_L, 1.0 / p)
          profile_R[:] = np.power(profile_R, 1.0 / p)
  
          profile_fname = core.array_to_temp_file(profile)
          profile_L_fname = core.array_to_temp_file(profile_L)
          profile_R_fname = core.array_to_temp_file(profile_R)
          indices_fname = core.array_to_temp_file(indices)
          indices_L_fname = core.array_to_temp_file(indices_L)
          indices_R_fname = core.array_to_temp_file(indices_R)
  
      return (
          profile_fname,
          profile_L_fname,
          profile_R_fname,
          indices_fname,
          indices_L_fname,
          indices_R_fname,
      )
  
file_path: stumpy/stumpy/gpu_aamp.py
imports: import math
  import multiprocessing
  import os
  import numpy
  from numba import cuda
  from .None import config, core
label_desc: Use image node_id 2 for calling a global function with example usage: _gpu_aamp(T_A_fname, T_B_fname, m, range_stop, excl_zone, T_A_subseq_isfinite_fname, T_B_subseq_isfinite_fname, p, p_norm_fname, p_norm_first_fname, w, ignore_trivial, range_start, device_id, k) and returns: profile_fname,  profile_L_fname,  profile_R_fname,  indices_fname,  indices_L_fname,  indices_R_fname