def forward(self, graph, feat, edge_feat):
        """

        Description
        -----------
        Compute gated graph convolution layer.

        Parameters
        ----------
        graph : DGLGraph
            The graph.
        feat : torch.Tensor
            The input feature of shape :math:`(N, D_{in})` where :math:`N`
            is the number of nodes of the graph and :math:`D_{in}` is the
            input feature size.
        edge_feat : torch.Tensor
            The input edge feature of shape :math:`(E, D_{edge})`,
            where :math:`E` is the number of edges and :math:`D_{edge}`
            is the size of the edge features.

        Returns
        -------
        torch.Tensor
            The output node feature of shape :math:`(N, D_{out})` where :math:`D_{out}`
            is the output feature size.
        torch.Tensor
            The output edge feature of shape :math:`(E, D_{out})` where :math:`D_{out}`
            is the output feature size.
        """
        with graph.local_scope():
            # For residual connection
            h_in = feat
            e_in = edge_feat

            graph.ndata["Ah"] = self.A(feat)
            graph.ndata["Bh"] = self.B(feat)
            graph.ndata["Dh"] = self.D(feat)
            graph.ndata["Eh"] = self.E(feat)
            graph.edata["Ce"] = self.C(edge_feat)

            graph.apply_edges(fn.u_add_v("Dh", "Eh", "DEh"))

            # Get edge feature
            graph.edata["e"] = graph.edata["DEh"] + graph.edata["Ce"]
            graph.edata["sigma"] = torch.sigmoid(graph.edata["e"])

            graph.update_all(
                fn.u_mul_e("Bh", "sigma", "m"), fn.sum("m", "sum_sigma_h")
            )
            graph.update_all(fn.copy_e("sigma", "m"), fn.sum("m", "sum_sigma"))
            graph.ndata["h"] = graph.ndata["Ah"] + graph.ndata[
                "sum_sigma_h"
            ] / (graph.ndata["sum_sigma"] + 1e-6)

            # Result of graph convolution.
            feat = graph.ndata["h"]
            edge_feat = graph.edata["e"]

            # Batch normalization.
            if self.batch_norm:
                feat = self.bn_node(feat)
                edge_feat = self.bn_edge(edge_feat)

            # Non-linear activation.
            if self.activation:
                feat = self.activation(feat)
                edge_feat = self.activation(edge_feat)

            # Residual connection.
            if self.residual:
                feat = h_in + feat
                edge_feat = e_in + edge_feat

            feat = self.dropout(feat)
            edge_feat = self.dropout(edge_feat)

            return feat, edge_feat


        Description
        -----------
        Compute gated graph convolution layer.

        Parameters
        ----------
        graph : DGLGraph
            The graph.
        feat : torch.Tensor
            The input feature of shape :math:`(N, D_{in})` where :math:`N`
            is the number of nodes of the graph and :math:`D_{in}` is the
            input feature size.
        edge_feat : torch.Tensor
            The input edge feature of shape :math:`(E, D_{edge})`,
            where :math:`E` is the number of edges and :math:`D_{edge}`
            is the size of the edge features.

        Returns
        -------
        torch.Tensor
            The output node feature of shape :math:`(N, D_{out})` where :math:`D_{out}`
            is the output feature size.
        torch.Tensor
            The output edge feature of shape :math:`(E, D_{out})` where :math:`D_{out}`
            is the output feature size.
        
python/dgl/nn/pytorch/conv/gatedgcnconv.py