code: def check_rnn(
      seq_len,
      input_size,
      hidden_size,
      batch_size,
      init_func,
      inp_moms=[0.0, 1.0],
  ):
      # init_func is the initializer for the model params
      # inp_moms is the [ mean, std dev] of the random input
      input_shape = (input_size, seq_len * batch_size)
      output_shape = (hidden_size, seq_len * batch_size)
      NervanaObject.be.bsz = NervanaObject.be.batch_size = batch_size
  
      # ======== create models ========
      # neon RNN
      rnn = Recurrent(hidden_size, init_func, activation=Tanh())
  
      # reference numpy RNN
      rnn_ref = RefRecurrent(input_size, hidden_size)
      Wxh = rnn_ref.Wxh
      Whh = rnn_ref.Whh
      bh = rnn_ref.bh
  
      # ========= generate data =================
      # generate random input tensor
      inp = np.random.rand(*input_shape) * inp_moms[1] + inp_moms[0]
      inpa = rnn.be.array(inp)
      # generate random deltas tensor
      deltas = np.random.randn(*output_shape)
  
      # the reference code expects these shapes:
      # input_shape: (seq_len, input_size, batch_size)
      # output_shape: (seq_len, hidden_size, batch_size)
      inp_ref = (
          inp.copy()
          .T.reshape(seq_len, batch_size, input_size)
          .swapaxes(1, 2)
      )
      deltas_ref = (
          deltas.copy()
          .T.reshape(seq_len, batch_size, hidden_size)
          .swapaxes(1, 2)
      )
  
      # ========= running models ==========
      # run neon fprop
      rnn.configure((input_size, seq_len))
      rnn.prev_layer = True
      rnn.allocate()
  
      dtree = DeltasTree()
      rnn.allocate_deltas(dtree)
      dtree.allocate_buffers()
      rnn.set_deltas(dtree)
  
      rnn.fprop(inpa)
  
      # weights are only initialized after doing fprop, so now
      # make ref weights and biases the same with neon model
      Wxh[:] = rnn.W_input.get()
      Whh[:] = rnn.W_recur.get()
      bh[:] = rnn.b.get()
  
      (
          dWxh_ref,
          dWhh_ref,
          db_ref,
          h_ref_list,
          dh_ref_list,
          d_out_ref,
      ) = rnn_ref.lossFun(inp_ref, deltas_ref)
  
      # now test the bprop
      rnn.bprop(rnn.be.array(deltas))
      # grab the delta W from gradient buffer
      dWxh_neon = rnn.dW_input.get()
      dWhh_neon = rnn.dW_recur.get()
      db_neon = rnn.db.get()
  
      # comparing outputs
      neon_logger.display("====Verifying hidden states====")
      assert allclose_with_out(
          rnn.outputs.get(), h_ref_list, rtol=0.0, atol=1.0e-5
      )
  
      neon_logger.display("fprop is verified")
  
      neon_logger.display("====Verifying update on W and b ====")
      neon_logger.display("dWxh")
      assert allclose_with_out(
          dWxh_neon, dWxh_ref, rtol=0.0, atol=1.0e-5
      )
      neon_logger.display("dWhh")
      assert allclose_with_out(
          dWhh_neon, dWhh_ref, rtol=0.0, atol=1.0e-5
      )
  
      neon_logger.display("====Verifying update on bias====")
      neon_logger.display("db")
      assert allclose_with_out(db_neon, db_ref, rtol=0.0, atol=1.0e-5)
  
      neon_logger.display("bprop is verified")
  
      return
  
file_path: neon/tests/test_recurrent.py
imports: import os
  import pytest
  import subprocess
  import itertools
  import numpy
  from neon import NervanaObject, logger
  from neon.initializers.initializer import Constant, Gaussian
  from neon.layers import Recurrent
  from neon.layers.container import DeltasTree
  from neon.transforms import Tanh
  from recurrent_ref import Recurrent
  from utils import allclose_with_out
label_desc: Use image node_id 4 for calling a global function with example usage: check_rnn(seq_len, input_size, hidden_size, batch_size, init_func, inp_moms) without return types