code: def test_elemwise_add_ex():
      def check_elemwise_add_ex(
          lhs_stype,
          rhs_stype,
          shape,
          lhs_grad_stype=None,
          rhs_grad_stype=None,
      ):
          lhs = mx.symbol.Variable("lhs", stype=lhs_stype)
          rhs = mx.symbol.Variable("rhs", stype=rhs_stype)
          lhs_nd = rand_ndarray(shape, lhs_stype)
          rhs_nd = rand_ndarray(shape, rhs_stype)
          lhs_np = lhs_nd.asnumpy()
          rhs_np = rhs_nd.asnumpy()
  
          out_np = lhs_np + rhs_np
          test = mx.symbol.sparse.elemwise_add(lhs, rhs)
          location = {"lhs": lhs_nd, "rhs": rhs_nd}
          check_symbolic_forward(test, location, [out_np])
          check_numeric_gradient(test, location)
          grad_stypes = {}
          if lhs_grad_stype is not None and lhs_grad_stype != "default":
              grad_stypes["lhs"] = lhs_grad_stype
          if rhs_grad_stype is not None and rhs_grad_stype != "default":
              grad_stypes["rhs"] = rhs_grad_stype
          check_symbolic_backward(
              test,
              location,
              [out_np],
              [out_np, out_np],
              grad_stypes=grad_stypes,
          )
  
      shapes = [rand_shape_2d(), rand_shape_3d()]
      for shape in shapes:
          check_elemwise_add_ex("default", "default", shape)
          check_elemwise_add_ex(
              "row_sparse",
              "row_sparse",
              shape,
              lhs_grad_stype="row_sparse",
              rhs_grad_stype="row_sparse",
          )
  
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 17 for calling a global function with example usage: test_elemwise_add_ex() without return types