code: def _sum_sqnorm_grads(params):
      # Calculates sum of squares of gradients.
  
      # Returns a tuple of the sum and the device of the sum.
      # The device will be `None` in multi-device case.
  
      # If the inputs are on a single device, the sum is returned
      # as an ndarray on the device, so that no synchronization is taken place.
      # If there are multiple devices, accumulation is done on each device
      # first, and the total sum is returned as a python float.
  
      # TODO(niboshi): Support and test len(params) == 0
  
      params_grouped = collections.defaultdict(list)
      devices_map = {}
  
      # Group params by devices.
      for param in params:
          device = param.device
          params_grouped[device.name].append(param)
          devices_map[device.name] = device
  
      # Calculates partial sums for each device.
      sq_sums = []
      for device_name, paramlist in six.iteritems(params_grouped):
          device = devices_map[device_name]
          with chainer.using_device(device):
              dots = []
              for param in paramlist:
                  g = param.grad
                  g = g.ravel()
                  dots.append(g.dot(g))
              sq_sums.append(sum(dots))
  
      # Return the total sum.
      if len(sq_sums) == 1:
          # single device
          sqnorm = sq_sums[0]
          ret_device = params[0].device
      else:
          # multi-device
          sqnorm = sum([float(s) for s in sq_sums])
          ret_device = None
      return sqnorm, ret_device
  
file_path: chainer/chainer/optimizer_hooks/gradient_clipping.py
imports: import collections
  import numpy
  import six
  import chainer
  from chainer import backend
label_desc: Use image node_id 1 for calling a global function with example usage: _sum_sqnorm_grads(params) and returns: sqnorm,  ret_device