def grad_global_norm(parameters, max_norm):
<EOL>arrays = []<EOL>idx = <NUM_LIT:0><EOL>for p in parameters:<EOL><INDENT>if p.grad_req != '<STR_LIT:null>':<EOL><INDENT>p_grads = p.list_grad()<EOL>arrays.append(p_grads[idx % len(p_grads)])<EOL>idx += <NUM_LIT:1><EOL><DEDENT><DEDENT>assert len(arrays) > <NUM_LIT:0>, '<STR_LIT>'<EOL>def _norm(array):<EOL><INDENT>x = array.reshape((-<NUM_LIT:1>,)).astype('<STR_LIT>', copy=False)<EOL>return nd.dot(x, x)<EOL><DEDENT>norm_arrays = [_norm(arr) for arr in arrays]<EOL>def group_by_ctx(arr_list):<EOL><INDENT>groups = collections.defaultdict(list)<EOL>for arr in arr_list:<EOL><INDENT>ctx = arr.context<EOL>groups[ctx].append(arr)<EOL><DEDENT>return groups<EOL><DEDENT>norm_groups = group_by_ctx(norm_arrays)<EOL>ctx, dtype = arrays[<NUM_LIT:0>].context, '<STR_LIT>'<EOL>norms = [nd.add_n(*g).as_in_context(ctx) for g in norm_groups.values()]<EOL>total_norm = nd.add_n(*norms).sqrt()<EOL>scale = total_norm / max_norm<EOL>is_finite = nd.contrib.isfinite(scale)<EOL>scale_or_one = nd.maximum(nd.ones((<NUM_LIT:1>,), dtype=dtype, ctx=ctx), scale)<EOL>choices = nd.concat(scale, scale_or_one, dim=<NUM_LIT:0>)<EOL>chosen_scale = choices.take(is_finite)<EOL>return total_norm, chosen_scale, is_finite<EOL>
Calculate the 2-norm of gradients of parameters, and how much they should be scaled down
    such that their 2-norm does not exceed `max_norm`.

    If gradients exist for more than one context for a parameter, user needs to explicitly call
    ``trainer.allreduce_grads`` so that the gradients are summed first before calculating
    the 2-norm.

    .. note::

        This function is only for use when `update_on_kvstore` is set to False in trainer.

    Example::

        trainer = Trainer(net.collect_params(), update_on_kvstore=False, ...)
        for x, y in mx.gluon.utils.split_and_load(X, [mx.gpu(0), mx.gpu(1)]):
            with mx.autograd.record():
                y = net(x)
                loss = loss_fn(y, label)
            loss.backward()
        trainer.allreduce_grads()
        norm, ratio = grad_global_norm(net.collect_params().values(), max_norm)
        trainer.update(batch_size * ratio)
        ...

    Parameters
    ----------
    parameters : list of Parameters

    Returns
    -------
    NDArray
      Total norm. Shape is (1,)
    NDArray
      Ratio for rescaling gradients based on max_norm s.t. grad = grad / ratio.
      If total norm is NaN, ratio will be NaN, too. Shape is (1,)
    NDArray
      Whether the total norm is finite. Shape is (1,)