class_docstr: GCMC layer
  
  .. math::
      z_j^{(l+1)} = \sigma_{agg}\left[\mathrm{agg}\left(
      \sum_{j\in\mathcal{N}_1}\frac{1}{c_{ij}}W_1h_j, \ldots,
      \sum_{j\in\mathcal{N}_R}\frac{1}{c_{ij}}W_Rh_j
      \right)\right]
  
  After that, apply an extra output projection:
  
  .. math::
      h_j^{(l+1)} = \sigma_{out}W_oz_j^{(l+1)}
  
  The equation is applied to both user nodes and item nodes and the
  parameters are not shared unless ``share_user_item_param`` is true.
  
  Parameters
  ----------
  rating_vals : list of int or float
      Possible rating values.
  user_in_units : int
      Size of user input feature
  item_in_units : int
      Size of item input feature
  msg_units : int
      Size of message :math:`W_rh_j`
  out_units : int
      Size of of final output user and item features
  dropout_rate : float, optional
      Dropout rate (Default: 0.0)
  agg : str, optional
      Function to aggregate messages of different ratings.
      Could be any of the supported cross type reducers:
      "sum", "max", "min", "mean", "stack".
      (Default: "stack")
  agg_act : callable, str, optional
      Activation function :math:`sigma_{agg}`. (Default: None)
  out_act : callable, str, optional
      Activation function :math:`sigma_{agg}`. (Default: None)
  share_user_item_param : bool, optional
      If true, user node and item node share the same set of parameters.
      Require ``user_in_units`` and ``move_in_units`` to be the same.
      (Default: False)
  device: str, optional
      Which device to put data in. Useful in mix_cpu_gpu training and
      multi-gpu training
class_docstr_tok: ["GCMC","layer","..","math",":",":","z_j^","{","(","l+1",")","}","=","\\sigma_","{","agg","}","\\left","[","\\mathrm","{","agg","}","\\left","(","\\sum_","{","j\\in\\mathcal","{","N","}","_1","}","\\frac","{","1","}","{","c_","{","ij","}","}","W_1h_j",",","\\ldots",",","\\sum_","{","j\\in\\mathcal","{","N","}","_R","}","\\frac","{","1","}","{","c_","{","ij","}","}","W_Rh_j","\\right",")","\\right","]","After","that",",","apply","an","extra","output","projection",":","..","math",":",":","h_j^","{","(","l+1",")","}","=","\\sigma_","{","out","}","W_oz_j^","{","(","l+1",")","}","The","equation","is","applied","to","both","user","nodes","and","item","nodes","and","the","parameters","are","not","shared","unless","``","share_user_item_param","``","is","true",".","Parameters","--","--","--","--","--","rating_vals",":","list","of","int","or","float","Possible","rating","values",".","user_in_units",":","int","Size","of","user","input","feature","item_in_units",":","int","Size","of","item","input","feature","msg_units",":","int","Size","of","message",":","math",":","`","W_rh_j","`","out_units",":","int","Size","of","of","final","output","user","and","item","features","dropout_rate",":","float",",","optional","Dropout","rate","(","Default",":","0.0",")","agg",":","str",",","optional","Function","to","aggregate","messages","of","different","ratings",".","Could","be","any","of","the","supported","cross","type","reducers",":","``","sum","''",",","``","max","''",",","``","min","''",",","``","mean","''",",","``","stack","''",".","(","Default",":","``","stack","''",")","agg_act",":","callable",",","str",",","optional","Activation","function",":","math",":","`","sigma_","{","agg","}","`",".","(","Default",":","None",")","out_act",":","callable",",","str",",","optional","Activation","function",":","math",":","`","sigma_","{","agg","}","`",".","(","Default",":","None",")","share_user_item_param",":","bool",",","optional","If","true",",","user","node","and","item","node","share","the","same","set","of","parameters",".","Require","``","user_in_units","``","and","``","move_in_units","``","to","be","the","same",".","(","Default",":","False",")","device",":","str",",","optional","Which","device","to","put","data","in",".","Useful","in","mix_cpu_gpu","training","and","multi-gpu","training"]
code: def __init__(
      self,
      rating_vals,
      user_in_units,
      item_in_units,
      msg_units,
      out_units,
      dropout_rate=0.0,
      agg="stack",  # or 'sum'
      agg_act=None,
      out_act=None,
      share_user_item_param=False,
      device=None,
  ):
      super(GCMCLayer, self).__init__()
      self.rating_vals = rating_vals
      self.agg = agg
      self.share_user_item_param = share_user_item_param
      self.ufc = nn.Linear(msg_units, out_units)
      if share_user_item_param:
          self.ifc = self.ufc
      else:
          self.ifc = nn.Linear(msg_units, out_units)
      if agg == "stack":
          # divide the original msg unit size by number of ratings to keep
          # the dimensionality
          assert msg_units % len(rating_vals) == 0
          msg_units = msg_units // len(rating_vals)
      self.dropout = nn.Dropout(dropout_rate)
      self.w_r = nn.ParameterDict()
      sub_conv = {}
      for rating in rating_vals:
          # PyTorch parameter name can't contain "."
          rating = str(rating).replace(".", "_")
          rev_rating = f"rev-{rating}"
          if share_user_item_param and user_in_units == item_in_units:
              self.w_r[rating] = nn.Parameter(
                  torch.randn(user_in_units, msg_units)
              )
              self.w_r[f"rev-{rating}"] = self.w_r[rating]
              sub_conv[rating] = GCMCGraphConv(
                  user_in_units,
                  msg_units,
                  weight=False,
                  device=device,
                  dropout_rate=dropout_rate,
              )
              sub_conv[rev_rating] = GCMCGraphConv(
                  user_in_units,
                  msg_units,
                  weight=False,
                  device=device,
                  dropout_rate=dropout_rate,
              )
          else:
              self.w_r = None
              sub_conv[rating] = GCMCGraphConv(
                  user_in_units,
                  msg_units,
                  weight=True,
                  device=device,
                  dropout_rate=dropout_rate,
              )
              sub_conv[rev_rating] = GCMCGraphConv(
                  item_in_units,
                  msg_units,
                  weight=True,
                  device=device,
                  dropout_rate=dropout_rate,
              )
      self.conv = dglnn.HeteroGraphConv(sub_conv, aggregate=agg)
      self.agg_act = get_activation(agg_act)
      self.out_act = get_activation(out_act)
      self.device = device
      self.reset_parameters()
  
imports: import dgl.function
  import dgl.nn.pytorch
  from dgl import DGLError
  import torch
  import torch.nn
  from torch.nn import init
  from .utils import get_activation
label_desc: Use image node_id 1 to create a new GCMCLayer object from inherited base classes: nn with example: obj = GCMCLayer(rating_vals, user_in_units, item_in_units, msg_units, out_units, dropout_rate, agg, agg_act, out_act, share_user_item_param, device)