code: def test_convolution(self):
      #        print '\n\n*************************************************'
      #        print '           TEST CONVOLUTION'
      #        print '*************************************************'
  
      # fixed parameters
      bsize = 10  # batch size
      imshp = (28, 28)
      kshp = (5, 5)
      nkern = 5
      ssizes = ((1, 1), (2, 2), (3, 3), (4, 4))
      convmodes = ("full", "valid")
  
      # symbolic stuff
      bias = dvector()
      kerns = dmatrix()
      input = dmatrix()
      rng = np.random.default_rng(3423489)
      filters = rng.standard_normal((nkern, np.prod(kshp)))
      biasvals = rng.standard_normal(nkern)
  
      for mode in ("FAST_COMPILE", "FAST_RUN"):
          ttot, ntot = 0, 0
          for conv_mode in convmodes:
              for ss in ssizes:
                  output, outshp = sp.convolve(
                      kerns,
                      kshp,
                      nkern,
                      input,
                      imshp,
                      ss,
                      bias=bias,
                      mode=conv_mode,
                  )
                  f = function([kerns, bias, input], output, mode=mode)
  
                  # now test with real values
                  img2d = np.arange(bsize * np.prod(imshp)).reshape(
                      (bsize,) + imshp
                  )
                  img1d = img2d.reshape(bsize, -1)
  
                  # create filters (need to be flipped to use convolve2d)
                  filtersflipped = np.zeros((nkern,) + kshp)
                  for k in range(nkern):
                      it = reversed(filters[k, :])
                      for i in range(kshp[0]):
                          for j in range(kshp[1]):
                              filtersflipped[k, i, j] = next(it)
  
                  # compute output with convolve2d
                  if conv_mode == "valid":
                      fulloutshp = np.array(imshp) - np.array(kshp) + 1
                  else:
                      fulloutshp = np.array(imshp) + np.array(kshp) - 1
                  ntime1 = time.perf_counter()
                  refout = np.zeros(
                      (bsize,) + tuple(fulloutshp) + (nkern,)
                  )
                  for b in range(bsize):
                      for n in range(nkern):
                          refout[b, ..., n] = convolve2d(
                              img2d[b, :, :],
                              filtersflipped[n, ...],
                              conv_mode,
                          )
                  ntot += time.perf_counter() - ntime1
  
                  # need to flatten images
                  bench1 = refout[:, 0 :: ss[0], 0 :: ss[1], :].reshape(
                      bsize, -1, nkern
                  )
                  bench1 += biasvals.reshape(1, 1, nkern)
  
                  # swap the last two dimensions (output needs to be nkern x outshp)
                  bench1 = np.swapaxes(bench1, 1, 2)
                  ttime1 = time.perf_counter()
                  out1 = f(filters, biasvals, img1d)
                  ttot += time.perf_counter() - ttime1
                  temp = bench1.flatten() - out1.flatten()
  
                  assert (temp < 1e-5).all()
  
file_path: pytensor/tests/sparse/sandbox/test_sp.py
imports: import time
  import pytest
  import numpy
  from scipy.signal import convolve2d
  from pytensor import function
  from pytensor.sparse.sandbox import sp
  from pytensor.tensor.type import dmatrix, dvector
  from tests import unittest_tools
label_desc: Use image node_id 1 for calling the TestSP obj's underlying member method code with example usage: obj.test_convolution() without return types