We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
HAN example error on version 0.4.2
get the below error running HAN example on version 0.4.2,  version 0.4.1 works though

AttributeError: '<class 'dgl.heterograph_index.HeteroGraphIndex'>' object has no attribute 'get_immutable_gidx'


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `python/dgl/nn/pytorch/softmax.py`
Content:
```
1 """Torch modules for graph related softmax."""
2 # pylint: disable= no-member, arguments-differ
3 import torch as th
4 
5 from ...function import TargetCode
6 from ...base import ALL, is_all
7 from ... import backend as F
8 from ... import utils
9 
10 __all__ = ['edge_softmax']
11 
12 
13 class EdgeSoftmax(th.autograd.Function):
14     r"""Apply softmax over signals of incoming edges.
15 
16     For a node :math:`i`, edgesoftmax is an operation of computing
17 
18     .. math::
19       a_{ij} = \frac{\exp(z_{ij})}{\sum_{j\in\mathcal{N}(i)}\exp(z_{ij})}
20 
21     where :math:`z_{ij}` is a signal of edge :math:`j\rightarrow i`, also
22     called logits in the context of softmax. :math:`\mathcal{N}(i)` is
23     the set of nodes that have an edge to :math:`i`.
24 
25     An example of using edgesoftmax is in
26     `Graph Attention Network <https://arxiv.org/pdf/1710.10903.pdf>`__ where
27     the attention weights are computed with such an edgesoftmax operation.
28     """
29 
30     @staticmethod
31     def forward(ctx, g, score, eids):
32         """Forward function.
33 
34         Pseudo-code:
35 
36         .. code:: python
37 
38             score = dgl.EData(g, score)
39             score_max = score.dst_max()  # of type dgl.NData
40             score = score - score_max  # edge_sub_dst, ret dgl.EData
41             score_sum = score.dst_sum()  # of type dgl.NData
42             out = score / score_sum    # edge_div_dst, ret dgl.EData
43             return out.data
44         """
45         # remember to save the graph to backward cache before making it
46         # a local variable
47         if not is_all(eids):
48             g = g.edge_subgraph(eids.long())
49 
50         n_nodes = g.number_of_nodes()
51         n_edges = g.number_of_edges()
52         gidx = g._graph.get_immutable_gidx(utils.to_dgl_context(score.device))
53         ctx.backward_cache = n_nodes, n_edges, gidx
54 
55         #g.update_all(fn.copy_e('s', 'm'), fn.max('m', 'smax'))
56         smax = F.copy_reduce('max', gidx, TargetCode.EDGE, score, n_nodes)
57         #g.apply_edges(fn.e_sub_v('s', 'smax', 'out'))
58         out = F.binary_reduce(
59             'none', 'sub', gidx, TargetCode.EDGE, TargetCode.DST, score, smax, n_edges)
60         #g.edata['out'] = th.exp(g.edata['out'])
61         out = th.exp(out)
62         #g.update_all(fn.copy_e('out', 'm'), fn.sum('m', 'out_sum'))
63         out_sum = F.copy_reduce('sum', gidx, TargetCode.EDGE, out, n_nodes)
64         #g.apply_edges(fn.e_div_v('out', 'out_sum', 'out'))
65         out = F.binary_reduce(
66             'none', 'div', gidx, TargetCode.EDGE, TargetCode.DST, out, out_sum, n_edges)
67 
68         ctx.save_for_backward(out)
69         return out
70 
71     @staticmethod
72     def backward(ctx, grad_out):
73         """Backward function.
74 
75         Pseudo-code:
76 
77         .. code:: python
78 
79             g, out = ctx.backward_cache
80             grad_out = dgl.EData(g, grad_out)
81             out = dgl.EData(g, out)
82             sds = out * grad_out  # type dgl.EData
83             sds_sum = sds.dst_sum()  # type dgl.NData
84             grad_score = sds - sds * sds_sum  # multiple expressions
85             return grad_score.data
86         """
87         n_nodes, n_edges, gidx = ctx.backward_cache
88         out, = ctx.saved_tensors
89 
90         #g.edata['grad_s'] = out * grad_out
91         grad_s = out * grad_out
92         #g.update_all(fn.copy_e('grad_s', 'm'), fn.sum('m', 'accum'))
93         accum = F.copy_reduce('sum', gidx, TargetCode.EDGE, grad_s, n_nodes)
94         #g.apply_edges(fn.e_mul_v('out', 'accum', 'out'))
95         out = F.binary_reduce(
96             'none', 'mul', gidx, TargetCode.EDGE, TargetCode.DST, out, accum, n_edges)
97         #grad_score = g.edata['grad_s'] - g.edata['out']
98         grad_score = grad_s - out
99 
100         return None, grad_score, None
101 
102 
103 def edge_softmax(graph, logits, eids=ALL):
104     r"""Compute edge softmax.
105 
106     For a node :math:`i`, edge softmax is an operation of computing
107 
108     .. math::
109       a_{ij} = \frac{\exp(z_{ij})}{\sum_{j\in\mathcal{N}(i)}\exp(z_{ij})}
110 
111     where :math:`z_{ij}` is a signal of edge :math:`j\rightarrow i`, also
112     called logits in the context of softmax. :math:`\mathcal{N}(i)` is
113     the set of nodes that have an edge to :math:`i`.
114 
115     An example of using edge softmax is in
116     `Graph Attention Network <https://arxiv.org/pdf/1710.10903.pdf>`__ where
117     the attention weights are computed with such an edge softmax operation.
118 
119     Parameters
120     ----------
121     graph : DGLGraph
122         The graph to perform edge softmax
123     logits : torch.Tensor
124         The input edge feature
125     eids : torch.Tensor or ALL, optional
126         Edges on which to apply edge softmax. If ALL, apply edge
127         softmax on all edges in the graph. Default: ALL.
128 
129     Returns
130     -------
131     Tensor
132         Softmax value
133 
134     Notes
135     -----
136         * Input shape: :math:`(E, *, 1)` where * means any number of
137           additional dimensions, :math:`E` equals the length of eids.
138           If eids is ALL, :math:`E` equals number of edges in the graph.
139         * Return shape: :math:`(E, *, 1)`
140 
141     Examples
142     --------
143     >>> from dgl.nn.pytorch.softmax import edge_softmax
144     >>> import dgl
145     >>> import torch as th
146 
147     Create a :code:`DGLGraph` object and initialize its edge features.
148 
149     >>> g = dgl.DGLGraph()
150     >>> g.add_nodes(3)
151     >>> g.add_edges([0, 0, 0, 1, 1, 2], [0, 1, 2, 1, 2, 2])
152     >>> edata = th.ones(6, 1).float()
153     >>> edata
154     tensor([[1.],
155             [1.],
156             [1.],
157             [1.],
158             [1.],
159             [1.]])
160 
161     Apply edge softmax on g:
162 
163     >>> edge_softmax(g, edata)
164     tensor([[1.0000],
165         [0.5000],
166         [0.3333],
167         [0.5000],
168         [0.3333],
169         [0.3333]])
170 
171     Apply edge softmax on first 4 edges of g:
172 
173     >>> edge_softmax(g, edata[:4], th.Tensor([0,1,2,3]))
174     tensor([[1.0000],
175         [0.5000],
176         [1.0000],
177         [0.5000]])
178     """
179     return EdgeSoftmax.apply(graph, logits, eids)
180
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/python/dgl/nn/pytorch/softmax.py b/python/dgl/nn/pytorch/softmax.py
--- a/python/dgl/nn/pytorch/softmax.py
+++ b/python/dgl/nn/pytorch/softmax.py
@@ -6,6 +6,8 @@
 from ...base import ALL, is_all
 from ... import backend as F
 from ... import utils
+from ...graph import DGLGraph
+from ...heterograph import DGLHeteroGraph
 
 __all__ = ['edge_softmax']
 
@@ -49,7 +51,19 @@
 
         n_nodes = g.number_of_nodes()
         n_edges = g.number_of_edges()
-        gidx = g._graph.get_immutable_gidx(utils.to_dgl_context(score.device))
+
+        # TODO(BarclayII): this is a temporary fix of memory leakage in PyTorch
+        # in PR #1139.  We should investigate further on what was actually happening
+        # when implementing EdgeSoftmax with message passing API instead of
+        # operators.
+        score_context = utils.to_dgl_context(score.device)
+        if isinstance(g, DGLGraph):
+            gidx = g._graph.get_immutable_gidx(score_context)
+        elif isinstance(g, DGLHeteroGraph):
+            assert g._graph.number_of_etypes() == 1, \
+                "EdgeSoftmax only support one edge type"
+            gidx = g._graph.get_unitgraph(0, score_context)
+
         ctx.backward_cache = n_nodes, n_edges, gidx
 
         #g.update_all(fn.copy_e('s', 'm'), fn.max('m', 'smax'))

{"golden_diff": "diff --git a/python/dgl/nn/pytorch/softmax.py b/python/dgl/nn/pytorch/softmax.py\n--- a/python/dgl/nn/pytorch/softmax.py\n+++ b/python/dgl/nn/pytorch/softmax.py\n@@ -6,6 +6,8 @@\n from ...base import ALL, is_all\n from ... import backend as F\n from ... import utils\n+from ...graph import DGLGraph\n+from ...heterograph import DGLHeteroGraph\n \n __all__ = ['edge_softmax']\n \n@@ -49,7 +51,19 @@\n \n         n_nodes = g.number_of_nodes()\n         n_edges = g.number_of_edges()\n-        gidx = g._graph.get_immutable_gidx(utils.to_dgl_context(score.device))\n+\n+        # TODO(BarclayII): this is a temporary fix of memory leakage in PyTorch\n+        # in PR #1139.  We should investigate further on what was actually happening\n+        # when implementing EdgeSoftmax with message passing API instead of\n+        # operators.\n+        score_context = utils.to_dgl_context(score.device)\n+        if isinstance(g, DGLGraph):\n+            gidx = g._graph.get_immutable_gidx(score_context)\n+        elif isinstance(g, DGLHeteroGraph):\n+            assert g._graph.number_of_etypes() == 1, \\\n+                \"EdgeSoftmax only support one edge type\"\n+            gidx = g._graph.get_unitgraph(0, score_context)\n+\n         ctx.backward_cache = n_nodes, n_edges, gidx\n \n         #g.update_all(fn.copy_e('s', 'm'), fn.max('m', 'smax'))\n", "issue": "HAN example error on version 0.4.2\nget the below error running HAN example on version 0.4.2,  version 0.4.1 works though\r\n\r\nAttributeError: '<class 'dgl.heterograph_index.HeteroGraphIndex'>' object has no attribute 'get_immutable_gidx'\r\n\n", "before_files": [{"content": "\"\"\"Torch modules for graph related softmax.\"\"\"\n# pylint: disable= no-member, arguments-differ\nimport torch as th\n\nfrom ...function import TargetCode\nfrom ...base import ALL, is_all\nfrom ... import backend as F\nfrom ... import utils\n\n__all__ = ['edge_softmax']\n\n\nclass EdgeSoftmax(th.autograd.Function):\n    r\"\"\"Apply softmax over signals of incoming edges.\n\n    For a node :math:`i`, edgesoftmax is an operation of computing\n\n    .. math::\n      a_{ij} = \\frac{\\exp(z_{ij})}{\\sum_{j\\in\\mathcal{N}(i)}\\exp(z_{ij})}\n\n    where :math:`z_{ij}` is a signal of edge :math:`j\\rightarrow i`, also\n    called logits in the context of softmax. :math:`\\mathcal{N}(i)` is\n    the set of nodes that have an edge to :math:`i`.\n\n    An example of using edgesoftmax is in\n    `Graph Attention Network <https://arxiv.org/pdf/1710.10903.pdf>`__ where\n    the attention weights are computed with such an edgesoftmax operation.\n    \"\"\"\n\n    @staticmethod\n    def forward(ctx, g, score, eids):\n        \"\"\"Forward function.\n\n        Pseudo-code:\n\n        .. code:: python\n\n            score = dgl.EData(g, score)\n            score_max = score.dst_max()  # of type dgl.NData\n            score = score - score_max  # edge_sub_dst, ret dgl.EData\n            score_sum = score.dst_sum()  # of type dgl.NData\n            out = score / score_sum    # edge_div_dst, ret dgl.EData\n            return out.data\n        \"\"\"\n        # remember to save the graph to backward cache before making it\n        # a local variable\n        if not is_all(eids):\n            g = g.edge_subgraph(eids.long())\n\n        n_nodes = g.number_of_nodes()\n        n_edges = g.number_of_edges()\n        gidx = g._graph.get_immutable_gidx(utils.to_dgl_context(score.device))\n        ctx.backward_cache = n_nodes, n_edges, gidx\n\n        #g.update_all(fn.copy_e('s', 'm'), fn.max('m', 'smax'))\n        smax = F.copy_reduce('max', gidx, TargetCode.EDGE, score, n_nodes)\n        #g.apply_edges(fn.e_sub_v('s', 'smax', 'out'))\n        out = F.binary_reduce(\n            'none', 'sub', gidx, TargetCode.EDGE, TargetCode.DST, score, smax, n_edges)\n        #g.edata['out'] = th.exp(g.edata['out'])\n        out = th.exp(out)\n        #g.update_all(fn.copy_e('out', 'm'), fn.sum('m', 'out_sum'))\n        out_sum = F.copy_reduce('sum', gidx, TargetCode.EDGE, out, n_nodes)\n        #g.apply_edges(fn.e_div_v('out', 'out_sum', 'out'))\n        out = F.binary_reduce(\n            'none', 'div', gidx, TargetCode.EDGE, TargetCode.DST, out, out_sum, n_edges)\n\n        ctx.save_for_backward(out)\n        return out\n\n    @staticmethod\n    def backward(ctx, grad_out):\n        \"\"\"Backward function.\n\n        Pseudo-code:\n\n        .. code:: python\n\n            g, out = ctx.backward_cache\n            grad_out = dgl.EData(g, grad_out)\n            out = dgl.EData(g, out)\n            sds = out * grad_out  # type dgl.EData\n            sds_sum = sds.dst_sum()  # type dgl.NData\n            grad_score = sds - sds * sds_sum  # multiple expressions\n            return grad_score.data\n        \"\"\"\n        n_nodes, n_edges, gidx = ctx.backward_cache\n        out, = ctx.saved_tensors\n\n        #g.edata['grad_s'] = out * grad_out\n        grad_s = out * grad_out\n        #g.update_all(fn.copy_e('grad_s', 'm'), fn.sum('m', 'accum'))\n        accum = F.copy_reduce('sum', gidx, TargetCode.EDGE, grad_s, n_nodes)\n        #g.apply_edges(fn.e_mul_v('out', 'accum', 'out'))\n        out = F.binary_reduce(\n            'none', 'mul', gidx, TargetCode.EDGE, TargetCode.DST, out, accum, n_edges)\n        #grad_score = g.edata['grad_s'] - g.edata['out']\n        grad_score = grad_s - out\n\n        return None, grad_score, None\n\n\ndef edge_softmax(graph, logits, eids=ALL):\n    r\"\"\"Compute edge softmax.\n\n    For a node :math:`i`, edge softmax is an operation of computing\n\n    .. math::\n      a_{ij} = \\frac{\\exp(z_{ij})}{\\sum_{j\\in\\mathcal{N}(i)}\\exp(z_{ij})}\n\n    where :math:`z_{ij}` is a signal of edge :math:`j\\rightarrow i`, also\n    called logits in the context of softmax. :math:`\\mathcal{N}(i)` is\n    the set of nodes that have an edge to :math:`i`.\n\n    An example of using edge softmax is in\n    `Graph Attention Network <https://arxiv.org/pdf/1710.10903.pdf>`__ where\n    the attention weights are computed with such an edge softmax operation.\n\n    Parameters\n    ----------\n    graph : DGLGraph\n        The graph to perform edge softmax\n    logits : torch.Tensor\n        The input edge feature\n    eids : torch.Tensor or ALL, optional\n        Edges on which to apply edge softmax. If ALL, apply edge\n        softmax on all edges in the graph. Default: ALL.\n\n    Returns\n    -------\n    Tensor\n        Softmax value\n\n    Notes\n    -----\n        * Input shape: :math:`(E, *, 1)` where * means any number of\n          additional dimensions, :math:`E` equals the length of eids.\n          If eids is ALL, :math:`E` equals number of edges in the graph.\n        * Return shape: :math:`(E, *, 1)`\n\n    Examples\n    --------\n    >>> from dgl.nn.pytorch.softmax import edge_softmax\n    >>> import dgl\n    >>> import torch as th\n\n    Create a :code:`DGLGraph` object and initialize its edge features.\n\n    >>> g = dgl.DGLGraph()\n    >>> g.add_nodes(3)\n    >>> g.add_edges([0, 0, 0, 1, 1, 2], [0, 1, 2, 1, 2, 2])\n    >>> edata = th.ones(6, 1).float()\n    >>> edata\n    tensor([[1.],\n            [1.],\n            [1.],\n            [1.],\n            [1.],\n            [1.]])\n\n    Apply edge softmax on g:\n\n    >>> edge_softmax(g, edata)\n    tensor([[1.0000],\n        [0.5000],\n        [0.3333],\n        [0.5000],\n        [0.3333],\n        [0.3333]])\n\n    Apply edge softmax on first 4 edges of g:\n\n    >>> edge_softmax(g, edata[:4], th.Tensor([0,1,2,3]))\n    tensor([[1.0000],\n        [0.5000],\n        [1.0000],\n        [0.5000]])\n    \"\"\"\n    return EdgeSoftmax.apply(graph, logits, eids)\n", "path": "python/dgl/nn/pytorch/softmax.py"}], "after_files": [{"content": "\"\"\"Torch modules for graph related softmax.\"\"\"\n# pylint: disable= no-member, arguments-differ\nimport torch as th\n\nfrom ...function import TargetCode\nfrom ...base import ALL, is_all\nfrom ... import backend as F\nfrom ... import utils\nfrom ...graph import DGLGraph\nfrom ...heterograph import DGLHeteroGraph\n\n__all__ = ['edge_softmax']\n\n\nclass EdgeSoftmax(th.autograd.Function):\n    r\"\"\"Apply softmax over signals of incoming edges.\n\n    For a node :math:`i`, edgesoftmax is an operation of computing\n\n    .. math::\n      a_{ij} = \\frac{\\exp(z_{ij})}{\\sum_{j\\in\\mathcal{N}(i)}\\exp(z_{ij})}\n\n    where :math:`z_{ij}` is a signal of edge :math:`j\\rightarrow i`, also\n    called logits in the context of softmax. :math:`\\mathcal{N}(i)` is\n    the set of nodes that have an edge to :math:`i`.\n\n    An example of using edgesoftmax is in\n    `Graph Attention Network <https://arxiv.org/pdf/1710.10903.pdf>`__ where\n    the attention weights are computed with such an edgesoftmax operation.\n    \"\"\"\n\n    @staticmethod\n    def forward(ctx, g, score, eids):\n        \"\"\"Forward function.\n\n        Pseudo-code:\n\n        .. code:: python\n\n            score = dgl.EData(g, score)\n            score_max = score.dst_max()  # of type dgl.NData\n            score = score - score_max  # edge_sub_dst, ret dgl.EData\n            score_sum = score.dst_sum()  # of type dgl.NData\n            out = score / score_sum    # edge_div_dst, ret dgl.EData\n            return out.data\n        \"\"\"\n        # remember to save the graph to backward cache before making it\n        # a local variable\n        if not is_all(eids):\n            g = g.edge_subgraph(eids.long())\n\n        n_nodes = g.number_of_nodes()\n        n_edges = g.number_of_edges()\n\n        # TODO(BarclayII): this is a temporary fix of memory leakage in PyTorch\n        # in PR #1139.  We should investigate further on what was actually happening\n        # when implementing EdgeSoftmax with message passing API instead of\n        # operators.\n        score_context = utils.to_dgl_context(score.device)\n        if isinstance(g, DGLGraph):\n            gidx = g._graph.get_immutable_gidx(score_context)\n        elif isinstance(g, DGLHeteroGraph):\n            assert g._graph.number_of_etypes() == 1, \\\n                \"EdgeSoftmax only support one edge type\"\n            gidx = g._graph.get_unitgraph(0, score_context)\n\n        ctx.backward_cache = n_nodes, n_edges, gidx\n\n        #g.update_all(fn.copy_e('s', 'm'), fn.max('m', 'smax'))\n        smax = F.copy_reduce('max', gidx, TargetCode.EDGE, score, n_nodes)\n        #g.apply_edges(fn.e_sub_v('s', 'smax', 'out'))\n        out = F.binary_reduce(\n            'none', 'sub', gidx, TargetCode.EDGE, TargetCode.DST, score, smax, n_edges)\n        #g.edata['out'] = th.exp(g.edata['out'])\n        out = th.exp(out)\n        #g.update_all(fn.copy_e('out', 'm'), fn.sum('m', 'out_sum'))\n        out_sum = F.copy_reduce('sum', gidx, TargetCode.EDGE, out, n_nodes)\n        #g.apply_edges(fn.e_div_v('out', 'out_sum', 'out'))\n        out = F.binary_reduce(\n            'none', 'div', gidx, TargetCode.EDGE, TargetCode.DST, out, out_sum, n_edges)\n\n        ctx.save_for_backward(out)\n        return out\n\n    @staticmethod\n    def backward(ctx, grad_out):\n        \"\"\"Backward function.\n\n        Pseudo-code:\n\n        .. code:: python\n\n            g, out = ctx.backward_cache\n            grad_out = dgl.EData(g, grad_out)\n            out = dgl.EData(g, out)\n            sds = out * grad_out  # type dgl.EData\n            sds_sum = sds.dst_sum()  # type dgl.NData\n            grad_score = sds - sds * sds_sum  # multiple expressions\n            return grad_score.data\n        \"\"\"\n        n_nodes, n_edges, gidx = ctx.backward_cache\n        out, = ctx.saved_tensors\n\n        #g.edata['grad_s'] = out * grad_out\n        grad_s = out * grad_out\n        #g.update_all(fn.copy_e('grad_s', 'm'), fn.sum('m', 'accum'))\n        accum = F.copy_reduce('sum', gidx, TargetCode.EDGE, grad_s, n_nodes)\n        #g.apply_edges(fn.e_mul_v('out', 'accum', 'out'))\n        out = F.binary_reduce(\n            'none', 'mul', gidx, TargetCode.EDGE, TargetCode.DST, out, accum, n_edges)\n        #grad_score = g.edata['grad_s'] - g.edata['out']\n        grad_score = grad_s - out\n\n        return None, grad_score, None\n\n\ndef edge_softmax(graph, logits, eids=ALL):\n    r\"\"\"Compute edge softmax.\n\n    For a node :math:`i`, edge softmax is an operation of computing\n\n    .. math::\n      a_{ij} = \\frac{\\exp(z_{ij})}{\\sum_{j\\in\\mathcal{N}(i)}\\exp(z_{ij})}\n\n    where :math:`z_{ij}` is a signal of edge :math:`j\\rightarrow i`, also\n    called logits in the context of softmax. :math:`\\mathcal{N}(i)` is\n    the set of nodes that have an edge to :math:`i`.\n\n    An example of using edge softmax is in\n    `Graph Attention Network <https://arxiv.org/pdf/1710.10903.pdf>`__ where\n    the attention weights are computed with such an edge softmax operation.\n\n    Parameters\n    ----------\n    graph : DGLGraph\n        The graph to perform edge softmax\n    logits : torch.Tensor\n        The input edge feature\n    eids : torch.Tensor or ALL, optional\n        Edges on which to apply edge softmax. If ALL, apply edge\n        softmax on all edges in the graph. Default: ALL.\n\n    Returns\n    -------\n    Tensor\n        Softmax value\n\n    Notes\n    -----\n        * Input shape: :math:`(E, *, 1)` where * means any number of\n          additional dimensions, :math:`E` equals the length of eids.\n          If eids is ALL, :math:`E` equals number of edges in the graph.\n        * Return shape: :math:`(E, *, 1)`\n\n    Examples\n    --------\n    >>> from dgl.nn.pytorch.softmax import edge_softmax\n    >>> import dgl\n    >>> import torch as th\n\n    Create a :code:`DGLGraph` object and initialize its edge features.\n\n    >>> g = dgl.DGLGraph()\n    >>> g.add_nodes(3)\n    >>> g.add_edges([0, 0, 0, 1, 1, 2], [0, 1, 2, 1, 2, 2])\n    >>> edata = th.ones(6, 1).float()\n    >>> edata\n    tensor([[1.],\n            [1.],\n            [1.],\n            [1.],\n            [1.],\n            [1.]])\n\n    Apply edge softmax on g:\n\n    >>> edge_softmax(g, edata)\n    tensor([[1.0000],\n        [0.5000],\n        [0.3333],\n        [0.5000],\n        [0.3333],\n        [0.3333]])\n\n    Apply edge softmax on first 4 edges of g:\n\n    >>> edge_softmax(g, edata[:4], th.Tensor([0,1,2,3]))\n    tensor([[1.0000],\n        [0.5000],\n        [1.0000],\n        [0.5000]])\n    \"\"\"\n    return EdgeSoftmax.apply(graph, logits, eids)\n", "path": "python/dgl/nn/pytorch/softmax.py"}]}