code: def gemm_acc_4x4_int8_int8_int32(dtype):
      """
      Int8 4x4 matrix multiplication and accumulation using sdot/udot
      instructions. This function takes two arrays of int8 datatype
      -- A[4][4] and B[4][4] and produces a 4x4 matrix
      which is equal to A*B'.
  
      The pseudo code is as follows.
  
      .. code-block:: c
  
          void gemm_acc_4x4_int8_int8_int32(int8 A[4][4], int8 B[4][4], int32 C[4][4]){
              for (int i = 0; i < 4; i++){
                  for (int j = 0; j < 4; j++){
                      for (int k = 0; k < 4; k++){
                          C[i][j] += A[i][k] * B[j][k]
                      }
              }
          }
  
      Notes:
          * The tiling strategy is picked to maximize register usage.
  
      Parameters
      ----------
      dtype : str, {"uint8", "int8"}
          Whether it works on unsigned int or signed int
  
      Returns
      -------
      intrin : TensorIntrin
          The Arm TensorIntrin that can be used in tensorizing schedule
      """
      assert dtype in ["uint8", "int8"]
      # This needs to be a variable number of "rows" since TVM
      # "thinks" I only need to compute one row because of
      # padding
      A = te.placeholder((te.var("rows"), 4), dtype, name="A")
      B = te.placeholder((4, 4), dtype, name="B")
      dtype_vec = dtype + "x16"
  
      k = te.reduce_axis((0, 4), name="k")
      C = te.compute(
          (te.var("rows"), 4),
          lambda i, j: te.sum(
              A[i, k].astype("int32") * B[j, k].astype("int32"), axis=k
          ),
          name="C",
      )
  
      aa_buffer = tvm.tir.decl_buffer(
          A.shape,
          dtype,
          name="aa_buffer",
          offset_factor=1,
          strides=[te.var("sa"), 1],
      )
      bb_buffer = tvm.tir.decl_buffer(
          B.shape,
          dtype,
          name="bb_buffer",
          offset_factor=1,
          strides=[te.var("sb"), 1],
      )
      cc_buffer = tvm.tir.decl_buffer(
          C.shape,
          dtype="int32",
          name="cc_buffer",
          offset_factor=1,
          strides=[te.var("sc"), 1],
      )
  
      llvm_intrin = (
          "llvm.aarch64.neon.sdot"
          if dtype == "int8"
          else "llvm.aarch64.neon.udot"
      )
  
      def _intrin_func(ins, outs):
          def _instr(index):
              ib = tvm.tir.ir_builder.create()
              if index == 1:
                  for i in range(0, 4):
                      ib.emit(
                          outs[0].vstore(
                              [i, 0], tvm.tir.const(0, "int32x4")
                          )
                      )
                  return ib.get()
              # Load all the elements of tile A.
              # vec_a = [a, b, c, d,
              #          e, f, g, h,
              #          l, m, n, o,
              #          p, q, r, s];
              vec_a = ins[0].vload([0, 0], dtype_vec)
  
              # Replicate 4 times the i-th row of A. For instance,
              # vec_a[0] = [a, b, c, d,
              #             a, b, c, d,
              #             a, b, c, d,
              #             a, b, c, d,];
              vec_aa = [
                  select_word(vec_a, i, dtype_vec) for i in range(0, 4)
              ]
  
              # Load all the elements of B. Remember that B
              # is transposed:
              # vec_b = [0, 4, 8, 12,
              #          1, 5, 9, 13,
              #          2, 6, 10, 14,
              #          3, 7, 11, 15,];
              vec_b = ins[1].vload([0, 0], dtype_vec)
  
              # Execute the dot product
              for i in range(0, 4):
                  vec_c = outs[0].vload([i, 0], "int32x4")
                  # Compute the product between the i-th row of A
                  # and all the rows of B. Remember that sdot/udot
                  # subdive the input vectors in 16 elements
                  # and then take the dot product among each group.
                  # The result is stored in a int32x4 register
                  #
                  # For instance, for i=0, we have:
                  # sdot(vec_aa[0], vec_b) = [a*0+b*4+c*8+d*12,
                  #                           a*1+b*5+c*9+d*13,
                  #                           a*2+b*6+c*10+d*14,
                  #                           a*3+b*7+c*11+d*15]
                  vdot = tvm.tir.call_llvm_intrin(
                      "int32x4",
                      llvm_intrin,
                      tvm.tir.const(3, "uint32"),
                      vec_c,
                      vec_b,
                      vec_aa[i],
                  )
  
                  # Store the result
                  ib.emit(outs[0].vstore([i, 0], vdot))
  
              return ib.get()
  
          # body, reset, update
          return _instr(0), _instr(1), _instr(2)
  
      buffer_params = {"offset_factor": 1}
      return te.decl_tensor_intrin(
          C.op,
          _intrin_func,
          binds={A: aa_buffer, B: bb_buffer, C: cc_buffer},
          default_buffer_params=buffer_params,
      )
  
file_path: tvm/python/tvm/topi/arm_cpu/tensor_intrin.py
imports: import tvm
  from tvm import te
  from tvm.ir import register_intrin_lowering
label_desc: Use image node_id 5 for calling a global function with example usage: gemm_acc_4x4_int8_int8_int32(dtype) and returns: te, _instr,  _instr,  _instr, ib, ib