Clips gradient norm.

        The norm is computed over all gradients together, as if they were
         concatenated into a single vector. Gradients are modified in-place.

        The method is first used in
         `[ICML2013] On the difficulty of training recurrent neural networks`

        Note that the gradients are concatenated per context in this implementation.

        Examples
        --------
        An example of using clip_grad_norm to clip the gradient before updating the parameters::
            >>> #Get the gradient via back-propagation
            >>> net.forward_backward(data_batch=data_batch)
            >>> norm_val = net.clip_by_global_norm(max_norm=2.0, param_names='w0')
            >>> net.update()

def clip_by_global_norm_per_ctx(self, max_norm=1.0, param_names=None):
        """Clips gradient norm.

        The norm is computed over all gradients together, as if they were
         concatenated into a single vector. Gradients are modified in-place.

        The method is first used in
         `[ICML2013] On the difficulty of training recurrent neural networks`

        Note that the gradients are concatenated per context in this implementation.

        Examples
        --------
        An example of using clip_grad_norm to clip the gradient before updating the parameters::
            >>> #Get the gradient via back-propagation
            >>> net.forward_backward(data_batch=data_batch)
            >>> norm_val = net.clip_by_global_norm(max_norm=2.0, param_names='w0')
            >>> net.update()
        """
        assert self.binded and self.params_initialized and self.optimizer_initialized
        num_ctx = len(self._exec_group.grad_arrays[0])
        grad_array_per_ctx = [[] for i in range(num_ctx)]
        assert(param_names is not None)
        for param_name in param_names:
            param_idx = self._exec_group.param_names.index(param_name)
            grad_val = self._exec_group.grad_arrays[param_idx]
            assert(len(grad_val) == num_ctx)
            for i in range(num_ctx):
                grad_array_per_ctx[i].append(grad_val[i])
        norm_vals = []
        for i in range(num_ctx):
            mx.gluon.utils.clip_global_norm(grad_array_per_ctx[i], max_norm)