class_docstr: The graph convolutional operator adapted from the `"Semi-supervised
  Classification with Graph Convolutional Networks"
  <https://arxiv.org/abs/1609.02907>`_ paper, with weights not trainable.
  .. math::
      \mathbf{X}^{\prime} = \mathbf{\hat{D}}^{-1/2} \mathbf{\hat{A}}
      \mathbf{\hat{D}}^{-1/2} \mathbf{X} \mathbf{\Theta},
  where :math:`\mathbf{\hat{A}} = \mathbf{A} + \mathbf{I}` denotes the
  adjacency matrix with inserted self-loops and
  :math:`\hat{D}_{ii} = \sum_{j=0} \hat{A}_{ij}` its diagonal degree matrix.
  The adjacency matrix can include other values than :obj:`1` representing
  edge weights via the optional :obj:`edge_weight` tensor.
  Its node-wise formulation is given by:
  .. math::
      \mathbf{x}^{\prime}_i = \mathbf{\Theta} \sum_{j \in \mathcal{N}(v) \cup
      \{ i \}} \frac{e_{j,i}}{\sqrt{\hat{d}_j \hat{d}_i}} \mathbf{x}_j
  with :math:`\hat{d}_i = 1 + \sum_{j \in \mathcal{N}(i)} e_{j,i}`, where
  :math:`e_{j,i}` denotes the edge weight from source node :obj:`j` to target
  node :obj:`i` (default: :obj:`1.0`)
  Args:
      in_channels (int): Size of each input sample, or :obj:`-1` to derive
          the size from the first input(s) to the forward method.
      out_channels (int): Size of each output sample.
      improved (bool, optional): If set to :obj:`True`, the layer computes
          :math:`\mathbf{\hat{A}}` as :math:`\mathbf{A} + 2\mathbf{I}`.
          (default: :obj:`False`)
      cached (bool, optional): If set to :obj:`True`, the layer will cache
          the computation of :math:`\mathbf{\hat{D}}^{-1/2} \mathbf{\hat{A}}
          \mathbf{\hat{D}}^{-1/2}` on first execution, and will use the
          cached version for further executions.
          This parameter should only be set to :obj:`True` in transductive
          learning scenarios. (default: :obj:`False`)
      add_self_loops (bool, optional): If set to :obj:`False`, will not add
          self-loops to the input graph. (default: :obj:`True`)
      normalize (bool, optional): Whether to add self-loops and compute
          symmetric normalization coefficients on the fly.
          (default: :obj:`True`)
      **kwargs (optional): Additional arguments of
          :class:`torch_geometric.nn.conv.MessagePassing`.
code: def message(self, x_j: Tensor, edge_weight: OptTensor) -> Tensor:
      return (
          x_j if edge_weight is None else edge_weight.view(-1, 1) * x_j
      )
  
imports: from typing import Optional, Tuple
  import torch
  from torch import Tensor
  from torch.nn import GRU
  from torch_geometric.typing import Adj, OptTensor
  from torch_sparse import SparseTensor
  from torch_geometric.nn.inits import glorot
  from torch_geometric.nn.conv import MessagePassing
  from torch_geometric.nn.conv.gcn_conv import gcn_norm
label_desc: Use image node_id 4 for calling the GCNConv_Fixed_W obj's underlying member method code with example usage: obj.message(x_j, edge_weight) and returns: unknown