code: def __init__(self, mat, is_symmetric, dtype):
      from pycuda.tools import DeviceData
  
      devdata = DeviceData()
  
      # all row indices in the data structure generation code are
      # "unpermuted" unless otherwise specified
      self.dtype = np.dtype(dtype)
      self.index_dtype = np.int32
      self.packed_index_dtype = np.uint32
      self.threads_per_packet = devdata.max_threads
  
      h, w = self.shape = mat.shape
      if h != w:
          raise ValueError("only square matrices are supported")
  
      self.rows_per_packet = (devdata.shared_memory - 100) // (
          2 * self.dtype.itemsize
      )
  
      self.block_count = (
          h + self.rows_per_packet - 1
      ) // self.rows_per_packet
  
      # get metis partition -------------------------------------------------
      from scipy.sparse import csr_matrix
  
      csr_mat = csr_matrix(mat, dtype=self.dtype)
  
      from pymetis import part_graph
  
      if not is_symmetric:
          # make sure adjacency graph is undirected
          adj_mat = csr_mat + csr_mat.T
      else:
          adj_mat = csr_mat
  
      while True:
          cut_count, dof_to_packet_nr = part_graph(
              int(self.block_count),
              xadj=adj_mat.indptr,
              adjncy=adj_mat.indices,
          )
  
          # build packet_nr_to_dofs
          packet_nr_to_dofs = {}
          for i, packet_nr in enumerate(dof_to_packet_nr):
              try:
                  dof_packet = packet_nr_to_dofs[packet_nr]
              except KeyError:
                  packet_nr_to_dofs[packet_nr] = dof_packet = []
  
              dof_packet.append(i)
  
          packet_nr_to_dofs = [
              packet_nr_to_dofs.get(i)
              for i in range(len(packet_nr_to_dofs))
          ]
  
          too_big = False
          for packet_dofs in packet_nr_to_dofs:
              if len(packet_dofs) >= self.rows_per_packet:
                  too_big = True
                  break
  
          if too_big:
              old_block_count = self.block_count
              self.block_count = int(2 + 1.05 * self.block_count)
              print(
                  (
                      "Metis produced a big block at block count "
                      "%d--retrying with %d"
                      % (old_block_count, self.block_count)
                  )
              )
              continue
  
          break
  
      assert len(packet_nr_to_dofs) == self.block_count
  
      # permutations, base rows ---------------------------------------------
      (
          new2old_fetch_indices,
          old2new_fetch_indices,
          packet_base_rows,
      ) = self.find_simple_index_stuff(packet_nr_to_dofs)
  
      # find local row cost and remaining_coo -------------------------------
      (
          local_row_costs,
          remaining_coo,
      ) = self.find_local_row_costs_and_remaining_coo(
          csr_mat, dof_to_packet_nr, old2new_fetch_indices
      )
      local_nnz = np.sum(local_row_costs)
  
      assert remaining_coo.nnz == csr_mat.nnz - local_nnz
  
      # find thread assignment for each block -------------------------------
      thread_count = len(packet_nr_to_dofs) * self.threads_per_packet
      thread_assignments, thread_costs = self.find_thread_assignment(
          packet_nr_to_dofs, local_row_costs, thread_count
      )
  
      max_thread_costs = np.max(thread_costs)
  
      # build data structure ------------------------------------------------
      from .pkt_build import build_pkt_data_structure
  
      build_pkt_data_structure(
          self,
          packet_nr_to_dofs,
          max_thread_costs,
          old2new_fetch_indices,
          csr_mat,
          thread_count,
          thread_assignments,
          local_row_costs,
      )
  
      self.packet_base_rows = gpuarray.to_gpu(packet_base_rows)
      self.new2old_fetch_indices = gpuarray.to_gpu(
          new2old_fetch_indices
      )
      self.old2new_fetch_indices = gpuarray.to_gpu(
          old2new_fetch_indices
      )
  
      from .coordinate import CoordinateSpMV
  
      self.remaining_coo_gpu = CoordinateSpMV(remaining_coo, dtype)
  
file_path: pycuda/pycuda/sparse/packeted.py
imports: from __future__ import division
  from __future__ import absolute_import
  from __future__ import print_function
  from pytools import memoize_method
  import pycuda.gpuarray
  from pycuda.compiler import SourceModule
  import numpy
label_desc: Use image node_id 1 to create a new PacketedSpMV object  with example: obj = PacketedSpMV(mat, is_symmetric, dtype)