class_docstr: Sparse Embedding for Knowledge Graph
  It is used to store both entity embeddings and relation embeddings.
  
  Parameters
  ----------
  args :
      Global configs.
  num : int
      Number of embeddings.
  dim : int
      Embedding dimention size.
  ctx : mx.ctx
      Device context to store the embedding.
class_docstr_tok: ["Sparse","Embedding","for","Knowledge","Graph","It","is","used","to","store","both","entity","embeddings","and","relation","embeddings",".","Parameters","--","--","--","--","--","args",":","Global","configs",".","num",":","int","Number","of","embeddings",".","dim",":","int","Embedding","dimention","size",".","ctx",":","mx.ctx","Device","context","to","store","the","embedding","."]
docstr: Update embeddings in a sparse manner
  Sparse embeddings are updated in mini batches. we maintains gradient states for
  each embedding so they can be updated separately.
  
  Parameters
  ----------
  gpu_id : int
      Which gpu to accelerate the calculation. if -1 is provided, cpu is used.
docstr_tok: ["Update","embeddings","in","a","sparse","manner","Sparse","embeddings","are","updated","in","mini","batches",".","we","maintains","gradient","states","for","each","embedding","so","they","can","be","updated","separately",".","Parameters","--","--","--","--","--","gpu_id",":","int","Which","gpu","to","accelerate","the","calculation",".","if","-1","is","provided",",","cpu","is","used","."]
code: def update(self, gpu_id=-1):
      """Update embeddings in a sparse manner
      Sparse embeddings are updated in mini batches. we maintains gradient states for
      each embedding so they can be updated separately.
  
      Parameters
      ----------
      gpu_id : int
          Which gpu to accelerate the calculation. if -1 is provided, cpu is used.
      """
      self.state_step += 1
      for idx, data in self.trace:
          grad = data.grad
  
          clr = self.args.lr
          # clr = self.args.lr / (1 + (self.state_step - 1) * group['lr_decay'])
  
          # the update is non-linear so indices must be unique
          grad_indices = idx
          grad_values = grad
  
          grad_sum = (grad_values * grad_values).mean(1)
          ctx = self.state_sum.context
          if ctx != grad_indices.context:
              grad_indices = grad_indices.as_in_context(ctx)
          if ctx != grad_sum.context:
              grad_sum = grad_sum.as_in_context(ctx)
          self.state_sum[grad_indices] += grad_sum
          std = self.state_sum[grad_indices]  # _sparse_mask
          if gpu_id >= 0:
              std = std.as_in_context(mx.gpu(gpu_id))
          std_values = nd.expand_dims(nd.sqrt(std) + 1e-10, 1)
          tmp = -clr * grad_values / std_values
          if tmp.context != ctx:
              tmp = tmp.as_in_context(ctx)
          # TODO(zhengda) the overhead is here.
          self.emb[grad_indices] = (
              mx.nd.take(self.emb, grad_indices) + tmp
          )
      self.trace = []
  
imports: import os
  import numpy
  import mxnet
  from mxnet import gluon
  from mxnet import ndarray
  from .score_fun import *
  from ..None import *
label_desc: Use image node_id 5 for calling the ExternalEmbedding obj's underlying member method code with example usage: obj.update(gpu_id) without return types