code: def test_updater(dev="cpu"):
      """updater"""
  
      def check_updater(kv, key, key_list, stype):
          # devices
          num_devs = 4
          devs = [mx.Context(dev, i) for i in range(num_devs)]
  
          # single
          vals = [mx.nd.ones(shape, d).tostype(stype) for d in devs]
          outs = [mx.nd.empty(shape, d) for d in devs]
  
          kv.push(key, vals)
          kv.pull(key, out=outs)
  
          for out in outs:
              check_diff_to_scalar(out, num_devs)
  
          # list
          vals = [
              [mx.nd.ones(shape, d).tostype(stype) for d in devs]
          ] * len(key_list)
          outs = [[mx.nd.empty(shape, d) for d in devs]] * len(key_list)
  
          num_push = 4
          for _ in range(num_push):
              kv.push(key_list, vals)
  
          kv.pull(key_list, out=outs)
  
          for out in outs:
              for o in out:
                  check_diff_to_scalar(o, num_devs * num_push)
  
      stypes = ["default", "row_sparse"]
      for stype in stypes:
          kv = init_kv()
          kv._set_updater(updater)
          check_updater(kv, 3, keys, stype)
  
          str_kv = init_kv_with_str()
          str_kv._set_updater(str_updater)
          check_updater(str_kv, "a", str_keys, stype)
  
imports: import mxnet
  import numpy
  import unittest
  from mxnet.test_utils import rand_ndarray, assert_almost_equal
  from common import assertRaises
  from mxnet.base import py_str, MXNetError
  import pytest
label_desc: Use image node_id 13 for calling a global function with example usage: test_updater(dev) without return types