code: def test_elemwise_binary_ops():
      # skip testing on GPU because only CPU ops are implemented
      if default_device().device_type is "gpu":
          return
  
      def test_elemwise_binary_op(
          name,
          lhs_stype,
          rhs_stype,
          shape,
          forward_mxnet_call,
          forward_numpy_call,
          backward_numpy_call,
          lhs_grad_stype,
          rhs_grad_stype,
          expected_result_storage_type=None,
          modifier_func=None,
          lhs_density=0.5,
          rhs_density=0.5,
          force_lr_overlap=False,
          force_grad_overlap=False,
          ograd_density=0.0,
          skip_gradient_check=False,
          shuffle_csr_indices=True,
          verbose=False,
      ):
          if lhs_grad_stype is None:
              lhs_grad_stype = lhs_stype
          if rhs_grad_stype is None:
              rhs_grad_stype = rhs_stype
  
          lhs_grad_stype = get_result_type_3(
              backward_numpy_call, lhs_grad_stype
          )
          rhs_grad_stype = get_result_type_3(
              backward_numpy_call, rhs_grad_stype
          )
  
          if verbose is True:
              print(
                  "testing: {}  lhs={}, rhs={}, lhs_grad_stype={}, rhs_grad_stype={}".format(
                      name,
                      lhs_stype,
                      rhs_stype,
                      lhs_grad_stype,
                      rhs_grad_stype,
                  )
              )
  
          # Output type should be same as lvalue type, unless otherwise specified
          if expected_result_storage_type is None:
              if lhs_stype == "default" or rhs_stype == "default":
                  expected_result_storage_type = "default"
              else:
                  expected_result_storage_type = lhs_stype
  
          lhs = mx.symbol.Variable("lhs", stype=lhs_stype)
          rhs = mx.symbol.Variable("rhs", stype=rhs_stype)
  
          grad_stypes = dict()
          grad_stypes["lhs"] = lhs_grad_stype
          grad_stypes["rhs"] = rhs_grad_stype
  
          if lhs_stype == "default":
              lhs_nd = rand_ndarray(shape, "default")
              if abs(lhs_density) < 1e-4:
                  func = all_zero
              else:
                  func = modifier_func
              lhs_nd = mx.nd.array(assign_each(lhs_nd.asnumpy(), func))
          else:
              lhs_nd = create_sparse_array_zd(
                  shape,
                  lhs_stype,
                  density=lhs_density,
                  modifier_func=modifier_func,
                  shuffle_csr_indices=shuffle_csr_indices,
                  rsp_indices=gen_rsp_random_indices(
                      shape,
                      density=lhs_density,
                      force_indices=[(shape[0] / 2)]
                      if force_lr_overlap is True
                      else None,
                  ),
              )
  
          if rhs_stype == "default":
              rhs_nd = rand_ndarray(shape, "default")
              if abs(rhs_density) < 1e-4:
                  func = all_zero
              else:
                  func = modifier_func
              rhs_nd = mx.nd.array(assign_each(rhs_nd.asnumpy(), func))
          else:
              rhs_nd = create_sparse_array_zd(
                  shape,
                  rhs_stype,
                  density=rhs_density,
                  modifier_func=modifier_func,
                  shuffle_csr_indices=shuffle_csr_indices,
                  rsp_indices=gen_rsp_random_indices(
                      shape,
                      density=rhs_density,
                      force_indices=[(shape[0] / 2)]
                      if force_lr_overlap is True
                      else None,
                  ),
              )
  
          lhs_np = lhs_nd.asnumpy()
          rhs_np = rhs_nd.asnumpy()
  
          if verbose is True:
              print("lhs input: {}".format(lhs_np))
              print("rhs input: {}".format(rhs_np))
  
          out_np = forward_numpy_call(lhs_np, rhs_np)
  
          if verbose is True:
              print("out_np: {}".format(out_np))
  
          test = forward_mxnet_call(lhs, rhs)
  
          location = {"lhs": lhs_nd, "rhs": rhs_nd}
  
          outputs = check_symbolic_forward(
              test, location, [out_np], equal_nan=True
          )
          assert len(outputs) == 1
          assert outputs[0].stype == expected_result_storage_type
  
          if verbose is True:
              print("mx forward output: ", outputs[0].asnumpy())
              print("lhs_nd: ", lhs_nd.stype)
              print("rhs_nd: ", rhs_nd.stype)
              print("forward output: ", outputs[0].stype)
  
          if outputs[0].stype != "default":
              out_grad = create_sparse_array_zd(
                  shape,
                  outputs[0].stype,
                  density=ograd_density,
                  data_init=1,
                  modifier_func=lambda x: 2,
                  shuffle_csr_indices=shuffle_csr_indices,
                  rsp_indices=gen_rsp_random_indices(
                      shape,
                      density=ograd_density,
                      force_indices=[(shape[0] / 2)]
                      if force_grad_overlap is True
                      else None,
                  ),
              )
          else:
              if abs(ograd_density) < 1e-4:
                  out_grad = mx.nd.array(np.zeros(shape))
              else:
                  out_grad = mx.nd.array(np.ones(shape))
  
          out_grad_np = out_grad.asnumpy()
  
          if verbose is True:
              print("out_grad_np", out_grad_np)
  
          ingrad_lhs_np, ingrad_rhs_np = backward_numpy_call(
              out_grad_np, lhs_np, rhs_np
          )
  
          if verbose is True:
              print("out_grad", out_grad.asnumpy())
              print("ingrad_lhs_np", ingrad_lhs_np)
              print("ingrad_rhs_np", ingrad_rhs_np)
  
          igrads_result = check_symbolic_backward(
              test,
              location,
              [out_grad],
              [ingrad_lhs_np, ingrad_rhs_np],
              grad_stypes=grad_stypes,
              equal_nan=True,
          )
  
          if verbose is True:
              print("ingrad_lhs", igrads_result["lhs"].asnumpy())
              print("ingrad_rhs", igrads_result["rhs"].asnumpy())
  
          assert len(igrads_result) == 2
  
          if lhs_grad_stype is not None:
              assert igrads_result["lhs"].stype == lhs_grad_stype
          if rhs_grad_stype is not None:
              assert igrads_result["rhs"].stype == rhs_grad_stype
          if not skip_gradient_check:
              check_numeric_gradient(
                  test, location, grad_stype_dict=grad_stypes
              )
  
      def check_all(l, r, check_function):
          assert l.shape == r.shape
          return check_function(l, r)
  
      def gt(l, r):
          return check_all(l, r, lambda a, b: a > b)
  
      def ge(l, r):
          return check_all(l, r, lambda a, b: a >= b)
  
      def lt(l, r):
          return check_all(l, r, lambda a, b: a < b)
  
      def le(l, r):
          return check_all(l, r, lambda a, b: a <= b)
  
      def elemwise_mul_stype(lstype, rstype):
          if lstype == rstype:
              return lstype
          elif lstype == "default" and rstype == "row_sparse":
              return "row_sparse"
          elif lstype == "row_sparse" and rstype == "default":
              return "row_sparse"
          else:
              return "default"
  
      def elemwise_mul_lhs_grad_stype(lstype, rstype):
          return elemwise_mul_stype(
              elemwise_mul_stype(lstype, rstype), rstype
          )
  
      def elemwise_mul_rhs_grad_stype(lstype, rstype):
          return elemwise_mul_stype(
              elemwise_mul_stype(lstype, rstype), lstype
          )
  
      def check_elemwise_binary_ops(
          lhs_stype,
          rhs_stype,
          shape,
          lhs_grad_stype=None,
          rhs_grad_stype=None,
          lhs_density=0.5,
          rhs_density=0.5,
          force_lr_overlap=False,
          force_grad_overlap=False,
          ograd_density=0.0,
      ):
          test_elemwise_binary_op(
              "elemwise_add",
              lhs_stype,
              rhs_stype,
              shape,
              lambda l, r: mx.sym.sparse.elemwise_add(l, r),
              lambda l, r: l + r,
              lambda outg, l, r: (outg, outg),
              lhs_grad_stype,
              rhs_grad_stype,
              ograd_density=ograd_density,
              force_lr_overlap=force_lr_overlap,
              force_grad_overlap=force_grad_overlap,
              lhs_density=lhs_density,
              rhs_density=rhs_density,
              verbose=False,
          )
  
          if (
              (lhs_stype is "default" and rhs_stype is "row_sparse")
              or (
                  lhs_stype is "row_sparse"
                  and rhs_stype is "row_sparse"
              )
              and (rhs_density == 0.0)
          ):
              test_elemwise_binary_op(
                  "elemwise_add",
                  lhs_stype,
                  rhs_stype,
                  shape,
                  lambda l, r: mx.sym.sparse.elemwise_add(l, r, out=l),
                  lambda l, r: l + r,
                  lambda outg, l, r: (outg, outg),
                  lhs_grad_stype,
                  rhs_grad_stype,
                  ograd_density=ograd_density,
                  force_lr_overlap=force_lr_overlap,
                  force_grad_overlap=force_grad_overlap,
                  lhs_density=lhs_density,
                  rhs_density=rhs_density,
                  verbose=False,
              )
              test_elemwise_binary_op(
                  "elemwise_sub",
                  lhs_stype,
                  rhs_stype,
                  shape,
                  lambda l, r: mx.sym.sparse.elemwise_sub(l, r, out=l),
                  lambda l, r: l - r,
                  lambda outg, l, r: (outg, -outg),
                  lhs_grad_stype,
                  rhs_grad_stype,
                  ograd_density=ograd_density,
                  force_lr_overlap=force_lr_overlap,
                  force_grad_overlap=force_grad_overlap,
                  lhs_density=lhs_density,
                  rhs_density=rhs_density,
                  verbose=False,
              )
          if (
              lhs_stype is "row_sparse" and rhs_stype is "row_sparse"
          ) and (lhs_density == 0.0):
              test_elemwise_binary_op(
                  "elemwise_add",
                  lhs_stype,
                  rhs_stype,
                  shape,
                  lambda l, r: mx.sym.sparse.elemwise_add(l, r, out=r),
                  lambda l, r: l + r,
                  lambda outg, l, r: (outg, outg),
                  lhs_grad_stype,
                  rhs_grad_stype,
                  ograd_density=ograd_density,
                  force_lr_overlap=force_lr_overlap,
                  force_grad_overlap=force_grad_overlap,
                  lhs_density=lhs_density,
                  rhs_density=rhs_density,
                  verbose=False,
              )
              test_elemwise_binary_op(
                  "elemwise_sub",
                  lhs_stype,
                  rhs_stype,
                  shape,
                  lambda l, r: mx.sym.sparse.elemwise_sub(l, r, out=l),
                  lambda l, r: l - r,
                  lambda outg, l, r: (outg, -outg),
                  lhs_grad_stype,
                  rhs_grad_stype,
                  ograd_density=ograd_density,
                  force_lr_overlap=force_lr_overlap,
                  force_grad_overlap=force_grad_overlap,
                  lhs_density=lhs_density,
                  rhs_density=rhs_density,
                  verbose=False,
              )
  
          test_elemwise_binary_op(
              "elemwise_sub",
              lhs_stype,
              rhs_stype,
              shape,
              lambda l, r: mx.sym.sparse.elemwise_sub(l, r),
              lambda l, r: l - r,
              lambda outg, l, r: (outg, -outg),
              lhs_grad_stype,
              rhs_grad_stype,
              ograd_density=ograd_density,
              force_lr_overlap=force_lr_overlap,
              force_grad_overlap=force_grad_overlap,
              lhs_density=lhs_density,
              rhs_density=rhs_density,
              verbose=False,
          )
  
          test_elemwise_binary_op(
              "elemwise_mul",
              lhs_stype,
              rhs_stype,
              shape,
              lambda l, r: mx.sym.sparse.elemwise_mul(l, r),
              lambda l, r: l * r,
              lambda outg, l, r: (outg * r, outg * l),
              elemwise_mul_lhs_grad_stype(lhs_stype, rhs_stype),
              elemwise_mul_rhs_grad_stype(lhs_stype, rhs_stype),
              expected_result_storage_type=elemwise_mul_stype(
                  lhs_stype, rhs_stype
              ),
              ograd_density=ograd_density,
              force_lr_overlap=force_lr_overlap,
              force_grad_overlap=force_grad_overlap,
              lhs_density=lhs_density,
              rhs_density=rhs_density,
              verbose=False,
          )
  
          test_elemwise_binary_op(
              "elemwise_div",
              lhs_stype,
              rhs_stype,
              shape,
              lambda l, r: mx.sym.sparse.elemwise_div(l, r),
              lambda l, r: l / r,
              lambda outg, l, r: (
                  outg * (1 / r),
                  outg * (-l / (r * r)),
              ),
              lhs_grad_stype,
              rhs_grad_stype,
              modifier_func=lambda a: a
              if abs(a) > 0.25
              else abs(a) + 1,
              force_lr_overlap=force_lr_overlap,
              force_grad_overlap=force_grad_overlap,
              lhs_density=lhs_density,
              rhs_density=rhs_density,
              ograd_density=ograd_density,
              expected_result_storage_type="default",
              skip_gradient_check=True,
              verbose=False,
          )
  
          test_elemwise_binary_op(
              "maximum",
              lhs_stype,
              rhs_stype,
              shape,
              lambda l, r: mx.sym._internal._maximum(l, r),
              lambda l, r: np.maximum(l, r),
              lambda outg, l, r: (outg * ge(l, r), outg * lt(l, r)),
              lhs_grad_stype,
              rhs_grad_stype,
              modifier_func=lambda a: a
              if abs(a) > 0.25
              else abs(a) + 1,
              force_lr_overlap=force_lr_overlap,
              force_grad_overlap=force_grad_overlap,
              lhs_density=lhs_density,
              rhs_density=rhs_density,
              skip_gradient_check=True,
              ograd_density=ograd_density,
              verbose=False,
          )
  
          test_elemwise_binary_op(
              "minimum",
              lhs_stype,
              rhs_stype,
              shape,
              lambda l, r: mx.sym._internal._minimum(l, r),
              lambda l, r: np.minimum(l, r),
              lambda outg, l, r: (outg * le(l, r), outg * gt(l, r)),
              lhs_grad_stype,
              rhs_grad_stype,
              modifier_func=lambda a: a
              if abs(a) > 0.25
              else abs(a) + 1,
              force_lr_overlap=force_lr_overlap,
              force_grad_overlap=force_grad_overlap,
              lhs_density=lhs_density,
              rhs_density=rhs_density,
              ograd_density=ograd_density,
              skip_gradient_check=True,
              verbose=False,
          )
  
          test_elemwise_binary_op(
              "hypot",
              lhs_stype,
              rhs_stype,
              shape,
              lambda l, r: mx.sym._internal._hypot(l, r),
              lambda l, r: np.hypot(l, r),
              lambda outg, l, r: (
                  outg
                  * assign_each2(
                      l, r, lambda a, b: a / np.sqrt(a * a + b * b)
                  ),
                  outg
                  * assign_each2(
                      l, r, lambda a, b: b / np.sqrt(a * a + b * b)
                  ),
              ),
              lhs_grad_stype,
              rhs_grad_stype,
              force_lr_overlap=force_lr_overlap,
              force_grad_overlap=force_grad_overlap,
              lhs_density=lhs_density,
              rhs_density=rhs_density,
              ograd_density=ograd_density,
              skip_gradient_check=True,
              verbose=False,
          )
  
      # Run basic tests
      with warnings.catch_warnings():
          warnings.simplefilter("ignore")
  
          for _ in range(1):
              # Run defaults
              check_elemwise_binary_ops(
                  "default", "default", rand_shape_2d(5, 5)
              )
  
              # Try different densities
              shape = rand_shape_2d(5, 5)
              for lhs_density in [0.0, random.uniform(0, 1), 1.0]:
                  for rhs_density in [0.0, random.uniform(0, 1), 1.0]:
                      for ograd_density in [
                          0.0,
                          random.uniform(0, 1),
                          1.0,
                      ]:
                          print(
                              "lhs_density={}, rhs_density={}, ograd_density={}, shape: {}".format(
                                  lhs_density,
                                  rhs_density,
                                  ograd_density,
                                  shape,
                              )
                          )
  
                          # Try row_sparse overlaps
                          for force_lr_overlap in [False, True]:
                              for force_grad_overlap in [False, True]:
                                  print(
                                      "  force_lr_overlap={}, force_grad_overlap={}, shape={}".format(
                                          force_lr_overlap,
                                          force_grad_overlap,
                                          shape,
                                      )
                                  )
  
                                  # Back to left-right overlap possiblities
                                  check_elemwise_binary_ops(
                                      "row_sparse",
                                      "row_sparse",
                                      shape,
                                      lhs_grad_stype="row_sparse",
                                      rhs_grad_stype="row_sparse",
                                      lhs_density=lhs_density,
                                      rhs_density=rhs_density,
                                      force_lr_overlap=force_lr_overlap,
                                      force_grad_overlap=force_grad_overlap,
                                      ograd_density=ograd_density,
                                  )
  
imports: from mxnet.test_utils import *
  from mxnet.base import MXNetError
  import pytest
  from common import assertRaises
  import random
  import warnings
label_desc: Use image node_id 11 for calling a global function with example usage: test_elemwise_binary_ops() and returns: check_function, check_all, check_all, check_all, check_all, elemwise_mul_stype, elemwise_mul_stype, lstype, str, str, str