code: def test_min_max_quantize_forward_backward(
      seed,
      x_shape,
      q_shape,
      decay,
      x_min_max,
      ema,
      ste_fine_grained,
      eps,
      quantize,
      ctx,
      func_name,
  ):
      from nbla_test_utils import cap_ignore_region, function_tester
  
      rng = np.random.RandomState(seed)
      # Inputs
      x = rng.randn(*x_shape)
      qr_min = -0.5 * rng.rand(*q_shape)
      qr_max = +0.5 * rng.rand(*q_shape)
      ql_min = np.zeros(q_shape)
      ql_max = np.ones(q_shape) * 255
      inputs = [x, qr_min, qr_max, ql_min, ql_max]
      func_args = [
          decay,
          x_min_max,
          ema,
          ste_fine_grained,
          eps,
          quantize,
      ]
  
      # No quantization
      if not quantize:
          vinputs = [nn.Variable.from_numpy_array(xd) for xd in inputs]
          v = vinputs[0]
          with nn.context_scope(ctx):
              o = F.min_max_quantize(*(vinputs + func_args))
          np.allclose(o.d, v.d)
          return
      # x_min_max and ema
      # function_tester does not work in this combination
      # when comparing gradients between true_g = v.g - g_init (accum=True) and g (accum=False)
      # since forward changes the exponential moving averages
      if x_min_max and ema:
          from nbla_test_utils import ArrayDiffStats
  
          vinputs = [nn.Variable.from_numpy_array(xd) for xd in inputs]
          vinputs[0].need_grad = True
          with nn.context_scope(ctx):
              y = F.min_max_quantize(*(vinputs + func_args))
          # forward check
          y.forward()
          y_ref = ref_min_max_quantize(
              x,
              qr_min,
              qr_max,
              ql_min,
              ql_max,
              decay,
              x_min_max,
              ema,
              ste_fine_grained,
              eps,
              quantize,
          )
          assert np.allclose(y_ref, y.d, atol=1e-5), ArrayDiffStats(
              y_ref, y.d
          )
          # backward check (accum=False)
          xv = vinputs[0]
          xv.grad.zero()
          dy = rng.randn(*y.shape)
          y.backward(dy)
          gx_ref = ref_grad_min_max_quantize(
              x,
              qr_min,
              qr_max,
              ql_min,
              ql_max,
              dy,
              decay,
              x_min_max,
              ema,
              ste_fine_grained,
              eps,
              quantize,
          )
          ag = xv.g.copy()
          assert np.allclose(
              gx_ref, ag.flatten(), atol=1e-5
          ), ArrayDiffStats(gx_ref, ag.flatten())
          # backward check (accum=True)
          y.backward(dy)
          assert np.allclose(
              ag * 2.0, xv.g.copy(), atol=1e-5
          ), ArrayDiffStats(ag * 2.0, xv.g.copy())
          return
      # General tests
      backward = (
          [True, False, False, False, False, False]
          if x_min_max or ema
          else [True, True, True, False, False, False]
      )
      function_tester(
          rng,
          F.min_max_quantize,
          ref_min_max_quantize,
          inputs,
          func_args=func_args,
          atol_b=1e-3,
          backward=backward,
          ctx=ctx,
          func_name=func_name,
          disable_half_test=True,
          ref_grad=ref_grad_min_max_quantize,
      )
  
file_path: nnabla/python/test/function/test_min_max_quantize.py
imports: import pytest
  import numpy
  import nnabla
  import nnabla.functions
  from nbla_test_utils import list_context
label_desc: Use image node_id 4 for calling a global function with example usage: test_min_max_quantize_forward_backward(seed, x_shape, q_shape, decay, x_min_max, ema, ste_fine_grained, eps, quantize, ctx, func_name) without return types