code: def _verify_while_loop(
      cond,
      func,
      loop_var_shapes,
      free_var_shapes,
      is_train,
      max_iterations,
      is_for,
      n_steps,
  ):
      def _create_vars(num, prefix):
          return [mx.sym.var(prefix + str(i)) for i in range(num)]
  
      def _create_arrays(shapes):
          return [
              mx.nd.random.uniform(-1.0, 1.0, shape=x) for x in shapes
          ]
  
      def _create_dict(prefix, shapes):
          return {
              prefix + str(i): mx.nd.random.uniform(-1.0, 1.0, shape=x)
              for i, x in enumerate(shapes)
          }
  
      def _merge_dict(*dicts):
          result = {}
          for item in dicts:
              result.update(item)
          return result
  
      def _to_numpy_list(arrays):
          return [x.asnumpy() if x is not None else x for x in arrays]
  
      def _get_imperative_result(n_steps):
          free_vars = [
              args["FreeVar" + str(i)].copy()
              for i, _ in enumerate(free_var_shapes)
          ]
          loop_vars = [
              args["LoopVar" + str(i)].copy()
              for i, _ in enumerate(loop_var_shapes)
          ]
          loop_var_start = int(is_for)
          if is_train:
              for var in free_vars + loop_vars[loop_var_start:]:
                  var.attach_grad()
          with mx.autograd.record(train_mode=is_train):
              outputs, final_loop_vars = mx.nd.contrib.while_loop(
                  cond=lambda *_loop_vars: cond(_loop_vars, free_vars),
                  func=lambda *_loop_vars: func(_loop_vars, free_vars),
                  loop_vars=loop_vars,
                  max_iterations=max_iterations,
              )
              outputs = _as_list(outputs)
              final_loop_vars = _as_list(final_loop_vars)
              outputs = [x[:n_steps] for x in outputs]
              out_grads = _create_arrays(
                  x.shape for x in outputs
              ) + _create_arrays(x.shape for x in final_loop_vars)
              loop_result_nd = [x * 2 for x in outputs] + [
                  x * 3 for x in final_loop_vars
              ]
              grads = []
              if is_train:
                  cat_out = mx.nd.concat(
                      *[x.reshape(-1) for x in loop_result_nd], dim=0
                  )
                  cat_out.backward(
                      out_grad=mx.nd.concat(
                          *[x.reshape(-1) for x in out_grads], dim=0
                      )
                  )
                  grads = [
                      free_vars[i].grad
                      for i, _ in enumerate(free_var_shapes)
                  ] + [
                      loop_vars[i].grad
                      for i, _ in enumerate(loop_var_shapes)
                      if i >= loop_var_start
                  ]
              return (
                  _to_numpy_list(loop_result_nd),
                  _to_numpy_list(grads),
                  out_grads,
              )
  
      def _get_symbolic_result(out_grads, n_steps):
          def _copy_args_dict(name_list):
              return {name: args[name].copy() for name in name_list}
  
          def _zeros_like_dict(name_list):
              return {
                  name: mx.nd.zeros_like(args[name])
                  for name in name_list
              }
  
          free_syms = _create_vars(len(free_var_shapes), "FreeVar")
          loop_syms = _create_vars(len(loop_var_shapes), "LoopVar")
          outputs, final_loop_syms = mx.sym.contrib.while_loop(
              cond=lambda *_loop_vars: cond(_loop_vars, free_syms),
              func=lambda *_loop_vars: func(_loop_vars, free_syms),
              loop_vars=loop_syms,
              max_iterations=max_iterations,
          )
          outputs = _as_list(outputs)
          final_loop_syms = _as_list(final_loop_syms)
          if n_steps == 0:
              outputs = []
          else:
              outputs = [
                  x.slice_axis(axis=0, begin=0, end=n_steps)
                  for x in outputs
              ]
          loop_result_sym = [x * 2 for x in outputs] + [
              x * 3 for x in final_loop_syms
          ]
          loop_result_sym = mx.sym.Group(loop_result_sym)
  
          loop_var_start = int(is_for)
          args_names = [
              "FreeVar" + str(i) for i, _ in enumerate(free_var_shapes)
          ] + [
              "LoopVar" + str(i)
              for i, _ in enumerate(loop_var_shapes)
              if i >= loop_var_start
          ]
          args_grad = (
              None
              if not is_train
              else _zeros_like_dict(x for x in args_names)
          )
          executor = loop_result_sym._bind(
              ctx=default_device(),
              args=_copy_args_dict(loop_result_sym.list_inputs()),
              args_grad=args_grad,
          )
          loop_result_nd = executor.forward(is_train=is_train)
          grads = []
          if is_train:
              executor.backward(out_grads=out_grads)
              grads = [
                  executor.grad_dict.get("FreeVar" + str(i), None)
                  for i, _ in enumerate(free_var_shapes)
              ] + [
                  executor.grad_dict.get("LoopVar" + str(i), None)
                  for i, _ in enumerate(loop_var_shapes)
                  if i >= loop_var_start
              ]
          return _to_numpy_list(loop_result_nd), _to_numpy_list(grads)
  
      args = _merge_dict(
          _create_dict("FreeVar", free_var_shapes),
          _create_dict("LoopVar", loop_var_shapes),
      )
      if is_for:
          assert loop_var_shapes[0] == (1,)
          args["LoopVar0"] = mx.nd.array([0])
      imp_outs, imp_grads, out_grads = _get_imperative_result(n_steps)
      sym_outs, sym_grads = _get_symbolic_result(out_grads, n_steps)
      for imp_out, sym_out in zip(imp_outs, sym_outs):
          if imp_out is None or sym_out is None:
              continue
          assert_almost_equal(imp_out, sym_out, rtol=1e-3, atol=1e-3)
      for imp_grad, sym_grad in zip(imp_grads, sym_grads):
          if imp_grad is None or sym_grad is None:
              continue
          assert_almost_equal(imp_grad, sym_grad, rtol=1e-3, atol=1e-3)
  
file_path: mxnet/tests/python/unittest/test_contrib_control_flow.py
imports: import pytest
  import mxnet
  from numpy.testing import assert_allclose
  from mxnet.test_utils import *
  from mxnet.base import _as_list
label_desc: Use image node_id 1 for calling a global function with example usage: _verify_while_loop(cond, func, loop_var_shapes, free_var_shapes, is_train, max_iterations, is_for, n_steps) and returns: unknown, unknown, unknown, result, unknown, _to_numpy_list,  _to_numpy_list, _to_numpy_list,  _to_numpy_list,  out_grads, unknown, unknown