class_docstr: Sparse Embedding for Knowledge Graph
  It is used to store both entity embeddings and relation embeddings.
  
  Parameters
  ----------
  num : int
      Number of embeddings.
  dim : int
      Embedding dimention size.
  device : th.device
      Device to store the embedding.
class_docstr_tok: ["Sparse","Embedding","for","Knowledge","Graph","It","is","used","to","store","both","entity","embeddings","and","relation","embeddings",".","Parameters","--","--","--","--","--","num",":","int","Number","of","embeddings",".","dim",":","int","Embedding","dimention","size",".","device",":","th.device","Device","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
      with th.no_grad():
          for idx, data in self.trace:
              grad = data.grad.data
  
              clr = self.lr
              # clr = self.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
              if self.async_q is not None:
                  grad_indices.share_memory_()
                  grad_values.share_memory_()
                  self.async_q.put((grad_indices, grad_values, gpu_id))
              else:
                  grad_sum = (grad_values * grad_values).mean(1)
                  device = self.state_sum.device
                  if device != grad_indices.device:
                      grad_indices = grad_indices.to(device)
                  if device != grad_sum.device:
                      grad_sum = grad_sum.to(device)
  
                  if self.has_cross_rel:
                      cpu_mask = self.cpu_bitmap[grad_indices]
                      cpu_idx = grad_indices[cpu_mask]
                      if cpu_idx.shape[0] > 0:
                          cpu_grad = grad_values[cpu_mask]
                          cpu_sum = grad_sum[cpu_mask].cpu()
                          cpu_idx = cpu_idx.cpu()
                          self.global_emb.state_sum.index_add_(
                              0, cpu_idx, cpu_sum
                          )
                          std = self.global_emb.state_sum[cpu_idx]
                          if gpu_id >= 0:
                              std = std.cuda(gpu_id)
                          std_values = (
                              std.sqrt_().add_(1e-10).unsqueeze(1)
                          )
                          tmp = -clr * cpu_grad / std_values
                          tmp = tmp.cpu()
                          self.global_emb.emb.index_add_(
                              0, cpu_idx, tmp
                          )
                  self.state_sum.index_add_(0, grad_indices, grad_sum)
                  std = self.state_sum[grad_indices]  # _sparse_mask
                  if gpu_id >= 0:
                      std = std.cuda(gpu_id)
                  std_values = std.sqrt_().add_(1e-10).unsqueeze(1)
                  tmp = -clr * grad_values / std_values
                  if tmp.device != device:
                      tmp = tmp.to(device)
                  # TODO(zhengda) the overhead is here.
                  self.emb.index_add_(0, grad_indices, tmp)
      self.trace = []
  
imports: import os
  import numpy
  import torch
  import torch.nn
  import torch.nn.functional
  import torch.nn.init
  import torch.multiprocessing
  from torch.multiprocessing import Queue
  from _thread import start_new_thread
  import traceback
  from functools import wraps
  from ..None import *
  from .tensor_models import thread_wrapped_func
label_desc: Use image node_id 12 for calling the KGEmbedding obj's underlying member method code with example usage: obj.update(gpu_id) without return types