code: def xprop_winograd(
      I, F, O, padding, minimal=False, trans=False, backward=False
  ):
      if backward:
          # C <=> K and mirror R,S
          F = np.transpose(F[:, ::-1, ::-1, :], (3, 1, 2, 0)).copy()
          # Invert padding
          padding = [4 - p for p in padding]
  
      C, Y, X, N = I.shape
      K, P, Q, N = O.shape
  
      B = 2
      D = 6
      Yw = ceil_div(Y, B)
      Xw = ceil_div(X, B)
  
      Fw = np.empty((D, D, C, K))
      Iw = np.empty((D, D, C, Yw, Xw, N))
      Mw = np.empty((D, D, K, Yw, Xw, N))  # , dtype=np.int64
      O.fill(0.0)
  
      # Transform Filters
      for c in range(C):
          for k in range(K):
              trans_F_2x2_5x5(
                  Fw[:, :, c, k], F[c, :, :, k], minimal, trans
              )
  
      # Iterate over image transform dimensions and slice out tiles of the image
      for y in range(Yw):
          slice_y, pad_y = image_slice(y, Y, B)
  
          for x in range(Xw):
              slice_x, pad_x = image_slice(x, X, B)
  
              sliceI = I[:, slice_y, slice_x, :]
  
              # add any zero padding if needed
              if pad_y[1] or pad_x[1]:
                  sliceI = np.pad(
                      sliceI, ((0, 0), pad_y, pad_x, (0, 0)), "constant"
                  )
  
              # Apply the Image transform
              for c in range(C):
                  for n in range(N):
                      trans_I_2x2_5x5(
                          Iw[:, :, c, y, x, n],
                          sliceI[c, :, :, n],
                          minimal,
                          trans,
                      )
  
      # print Iw[:,:,0,0,0,0]
      # print Fw[:,:,0,0].reshape(36,1)
      # exit()
  
      # Fw, scaleF = quantize(Fw, 16)
      # Iw, scaleI = quantize(Iw, 16)
  
      # Fw = Fw.astype(np.float16).astype(np.float64)
      # Iw = Iw.astype(np.float32).astype(np.float64)
  
      # Batched gemm for the pointwise multiplication step
      for s in range(D):
          for t in range(D):
              # [K,Yw,Xw,N] = [C,K].T . [C,YwXwN]
              Mw[s, t] = np.dot(
                  Fw[s, t].T, Iw[s, t].reshape(C, -1)
              ).reshape((K, Yw, Xw, N))
  
      # print Mw[:,:,0,0,0,0]
      # exit()
  
      # Mw = Mw.astype(np.float64) * scaleF * scaleI
  
      # Iterate over the convovled result in the pointwise space and apply inverse transform
      for y in range(Yw):
          slice_p, slice_y = output_slice(y, P, B, D, padding[0])
          for x in range(Xw):
              slice_q, slice_x = output_slice(x, Q, B, D, padding[1])
              for k in range(K):
                  for n in range(N):
                      # Toss out any points that don't fit
                      Out = trans_O_2x2_5x5(
                          Mw[:, :, k, y, x, n], minimal, trans
                      )
  
                      O[k, slice_p, slice_q, n] += Out[slice_y, slice_x]
  
file_path: neon/neon/backends/winograd5.py
imports: from __future__ import division
  import numpy
  from struct import pack, unpack
  from neon import logger
label_desc: Use image node_id 15 for calling a global function with example usage: xprop_winograd(I, F, O, padding, minimal, trans, backward) without return types