code: def Exhaustive_Search(
      matrix, stripe_group_size=-1, escape_attempts=0, permutation=None
  ):
      global sm_perturbation_limit, sm_perturbations
      sm_perturbations = 0
      sm_perturbation_limit = escape_attempts
      if permutation is None:
          permutation = [c for c in range(matrix.shape[1])]
  
      # It is much safer to reset the stripe_set as None in the entry point of Exhaustive_Search
      global stripe_set, stripe_set_config
      stripe_set = None
      stripe_set_config = None
  
      # only support N:4 for now
      group_width = 4
  
      result = np.copy(matrix)
  
      # if the matrix is too large for a window size of 12, subdivide, then fix up with a global optimization with a window size of 8
      if (
          group_width == 4
          and stripe_group_size == 12
          and matrix.shape[1] > 512
      ):
          stripe_split = int(matrix.shape[1] / 2 / group_width)
          col_split = stripe_split * group_width
          (
              result[:, :col_split],
              durationL,
              permutation[:col_split],
          ) = Exhaustive_Search(
              result[:, :col_split],
              stripe_group_size=stripe_group_size,
              escape_attempts=escape_attempts,
              permutation=permutation[:col_split],
          )
          (
              result[:, col_split:],
              durationR,
              permutation[col_split:],
          ) = Exhaustive_Search(
              result[:, col_split:],
              stripe_group_size=stripe_group_size,
              escape_attempts=escape_attempts,
              permutation=permutation[col_split:],
          )
          escape_attempts = max(escape_attempts, 100) * 10
          result, duration, permutation = Exhaustive_Search(
              result,
              stripe_group_size=8,
              escape_attempts=escape_attempts,
              permutation=permutation,
          )
          return result, durationL + durationR + duration, permutation
  
      # small enough to optimize the entire matrix at once
      if (
          stripe_group_size != -1
          and stripe_group_size < matrix.shape[1]
      ):
          stripe_map = []
          stripe_ids = []
          perm_map = []
          used_stripes = []
  
          # in practice, this work will be cached ahead of time; doing it now.
          # (Reading the cached list from disk can take several seconds, which shouldn't be counted against the search, but amortized over every layer in a network)
          generate_all_unique_combinations(
              stripe_group_size, group_width
          )
  
          start_time = time.perf_counter()
  
          while True:
              # print("[Debug][Exhaustive_Search] Before entering the build_stripe_map function.")
              # print("[Debug][Exhaustive_Search] Now the stripe_set value is: {}".format(stripe_set))
              stripe_map, stripe_ids, perm_map = build_stripe_map(
                  result,
                  group_width,
                  stripe_group_size,
                  stripe_map,
                  stripe_ids,
                  perm_map,
                  used_stripes,
              )
              (
                  result,
                  stripe_groups_optimized,
                  stripe_map,
                  stripe_ids,
                  used_stripes,
                  improvement,
                  permutation,
              ) = use_stripe_map(
                  result,
                  group_width,
                  stripe_map,
                  stripe_ids,
                  perm_map,
                  permutation,
              )
  
              # converged?
              if len(used_stripes) == 0:
                  break
  
          duration = time.perf_counter() - start_time
  
      else:  # no sliding window, single iteration
          print(
              f"Matrix has {matrix.shape[1]} columns and the search window is only {stripe_group_size}: searching exhaustively"
          )
          result, duration, permutation, improvement = search_matrix(
              matrix, group_width
          )
  
      return result, duration, permutation
  
file_path: apex/apex/contrib/sparsity/permutation_search_kernels/exhaustive_search.py
imports: from .permutation_utilities import *
  import pickle
  import os.path
  from os import path
  import math
label_desc: Use image node_id 11 for calling a global function with example usage: Exhaustive_Search(matrix, stripe_group_size, escape_attempts, permutation) and returns: result,  duration,  permutation, result,  unknown,  permutation