We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
nn.Embedding improperly sorts inputs when max_norm is specified
```python
import torch
import torch.nn as nn
from torch.autograd import Variable

ids = Variable(torch.LongTensor([2, 12, 4, 8, 8, 6]))
embed = nn.Embedding(22, 5, max_norm=1.0)
print(ids)  # before: 2 12 4 8 8 6
out = embed(ids)
print(ids)  # after: 2 4 6 8 8 12
```

The output is also incorrect. It's the output from the sorted indices, instead of the user specified indices.

Reported by @adampolyak 

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `torch/nn/_functions/thnn/sparse.py`
Content:
```
1 import torch
2 from torch.autograd.function import Function
3 from torch._thnn import type2backend
4 from torch.autograd.function import once_differentiable
5 
6 from . import _all_functions
7 
8 
9 class Embedding(Function):
10 
11     @staticmethod
12     def _renorm(ctx, indices, weight, max_norm, norm_type):
13         if indices.dim() == 2:
14             indices = indices.clone().view(-1)
15 
16         ctx._backend.LookupTable_renorm(
17             ctx._backend.library_state,
18             indices,
19             weight,
20             max_norm,
21             norm_type
22         )
23 
24     @classmethod
25     def forward(cls, ctx, indices, weight, padding_idx, max_norm, norm_type, scale_grad_by_freq,
26                 sparse=False):
27 
28         ctx.padding_idx = padding_idx
29         ctx.scale_grad_by_freq = scale_grad_by_freq
30         ctx._indices = None
31         ctx.sparse = sparse
32 
33         assert indices.dim() <= 2
34         assert not ctx.needs_input_grad[0], "Embedding doesn't " \
35             "compute the gradient w.r.t. the indices"
36 
37         ctx._backend = type2backend[type(weight)]
38         ctx._weight_size = weight.size()
39 
40         if not indices.is_contiguous():
41             ctx._indices = indices.contiguous()
42             indices = ctx._indices
43         else:
44             ctx.save_for_backward(indices)
45 
46         output = weight.new()
47         if max_norm is not None:
48             cls._renorm(ctx, indices, weight, max_norm, norm_type)
49 
50         if indices.dim() == 1:
51             output = torch.index_select(weight, 0, indices)
52         else:
53             output = torch.index_select(weight, 0, indices.view(-1))
54             output = output.view(indices.size(0), indices.size(1), weight.size(1))
55 
56         return output
57 
58     @staticmethod
59     @once_differentiable
60     def backward(ctx, grad_output):
61         if ctx._indices is not None:
62             indices = ctx._indices
63         else:
64             indices, = ctx.saved_tensors
65 
66         grad_output = grad_output.contiguous()
67         if not ctx.sparse:
68             if indices.dim() == 2:
69                 indices = indices.view(-1)
70 
71             with torch.cuda.device_of(grad_output):
72                 if grad_output.is_cuda:
73                     _sorted = torch.cuda.LongTensor()
74                     _indices = torch.cuda.LongTensor()
75                     _count = torch.cuda.LongTensor()
76                 else:
77                     _count = torch.IntTensor()
78                     _sorted = _indices = None
79 
80             grad_weight = grad_output.new(ctx._weight_size).zero_()
81             # Doesn't support Variable grad_output
82             ctx._backend.LookupTable_accGradParameters(
83                 ctx._backend.library_state,
84                 indices,
85                 grad_output,
86                 grad_weight,
87                 _count,
88                 _sorted,
89                 _indices,
90                 ctx.scale_grad_by_freq,
91                 ctx.padding_idx,
92                 1
93             )
94         else:
95             tensor_type = type(grad_output).__name__
96             if grad_output.is_cuda:
97                 SparseTensor = getattr(torch.cuda.sparse, tensor_type)
98             else:
99                 SparseTensor = getattr(torch.sparse, tensor_type)
100             grad_weight = SparseTensor(
101                 indices.view(1, -1),
102                 grad_output.view(-1, ctx._weight_size[1]),
103                 ctx._weight_size,
104             )
105         return None, grad_weight, None, None, None, None, None
106 
107 
108 _all_functions.append(Embedding)
109 
110 MODE_SUM = 0
111 MODE_MEAN = 1
112 
113 
114 class EmbeddingBag(Function):
115 
116     def __init__(self, max_norm, norm_type, scale_grad_by_freq, mode):
117         super(EmbeddingBag, self).__init__()
118         self.max_norm = max_norm
119         self.norm_type = norm_type
120         self.scale_grad_by_freq = scale_grad_by_freq
121         self._indices = None
122         assert mode is not None
123         if mode == 'sum':
124             self.mode = MODE_SUM
125         elif mode == 'mean':
126             self.mode = MODE_MEAN
127         else:
128             raise ValueError("mode needs to be 'sum' or 'mean', but got {}"
129                              .format(mode))
130 
131     def _renorm(self, indices, weight):
132         self._backend.LookupTable_renorm(
133             self._backend.library_state,
134             indices,
135             weight,
136             self.max_norm,
137             self.norm_type
138         )
139 
140     def forward(self, weight, indices, offsets):
141         assert not self.needs_input_grad[1], "EmbeddingBag doesn't " \
142             "compute the gradient w.r.t. the indices"
143 
144         assert not self.needs_input_grad[2], "EmbeddingBag doesn't " \
145             "compute the gradient w.r.t. the offsets"
146 
147         assert indices.dim() == 1
148         if offsets.dim() != 1:
149             raise ValueError("offsets has to be a 1D Tensor")
150 
151         if offsets[0] != 0:
152             raise ValueError("offsets[0] has to be 0, i.e. the first sequence"
153                              " in the mini-batch has to start from position 0."
154                              "However, got {}".format(offsets[0]))
155         if offsets[-1] > indices.size(0):
156             raise ValueError("offsets[-1] has to be smaller than indices's length"
157                              " ({}), but got offsets[-1] of {}"
158                              .format(indices.size(0), offsets[-1]))
159 
160         self._backend = type2backend[type(weight)]
161         self._weight_size = weight.size()
162         self._offset2bag = offsets.new()
163 
164         self.save_for_backward(indices)
165 
166         indices = indices.contiguous().view(-1)
167         output = weight.new()
168         if self.max_norm is not None:
169             self._renorm(indices, weight)
170 
171         if weight.is_cuda:
172             if self.mode == MODE_MEAN:
173                 self.bag_size = offsets.new().resize_(offsets.size())
174             else:
175                 self.bag_size = None
176 
177             self._backend.LookupTableBag_updateOutput(
178                 self._backend.library_state,
179                 indices,
180                 offsets,
181                 weight,
182                 output,
183                 self._offset2bag,
184                 self.mode,
185                 self.bag_size
186             )
187         else:
188             # slow CPU implementation
189             index_output = torch.index_select(weight, 0, indices)
190             # indices = [1, 2, 30, 100, 12], offsets = [0, 2, 3]
191             self._offset2bag.resize_(indices.size(0)).zero_()  # offset2bag = [0 0 0 0 0]
192             self._offset2bag.index_fill_(0, offsets, 1)  # offset2bag = [1 0 1 0 1]
193             self._offset2bag[0] = 0  # offset2bag = [0 0 1 0 1]
194             self._offset2bag = self._offset2bag.cumsum(0)  # offset2bag = [0 0 1 1 2]
195             output.resize_(offsets.size(0), weight.size(1)).zero_()
196             output.index_add_(0, self._offset2bag, index_output)
197             if self.mode == MODE_MEAN:
198                 if offsets.size(0) == 1:
199                     self.bag_size = indices.size(0)
200                 else:
201                     self.bag_size = weight.new().resize_(offsets.size())
202                     self.bag_size[:-1] = offsets[1:] - offsets[:-1]
203                     self.bag_size[-1] = indices.size(0) - offsets[-1]
204                     self.bag_size = self.bag_size[:, None].expand_as(output)
205                 output /= self.bag_size
206 
207         return output
208 
209     def backward(self, grad_output):
210         indices, = self.saved_tensors
211         indices = indices.contiguous().view(-1)
212         grad_output = grad_output.contiguous()
213 
214         with torch.cuda.device_of(grad_output):
215             if grad_output.is_cuda:
216                 _sorted = torch.cuda.LongTensor()
217                 _indices = torch.cuda.LongTensor()
218                 _count = torch.cuda.LongTensor()
219             else:
220                 _count = torch.IntTensor()
221                 _sorted = _indices = None
222 
223         grad_weight = grad_output.new(self._weight_size).zero_()
224 
225         if grad_output.is_cuda:
226             self._backend.LookupTableBag_accGradParameters(
227                 self._backend.library_state,
228                 indices,
229                 grad_output,
230                 grad_weight,
231                 self._offset2bag,
232                 _count,
233                 _sorted,
234                 _indices,
235                 self.scale_grad_by_freq,
236                 self.mode,
237                 self.bag_size,
238                 1
239             )
240         else:
241             # slow CPU implementation
242             if self.mode == MODE_MEAN:
243                 # divide by average count
244                 grad_output = grad_output / self.bag_size
245 
246             index_grad_output = grad_output.index_select(0, self._offset2bag)
247             self._backend.LookupTable_accGradParameters(
248                 self._backend.library_state,
249                 indices,
250                 index_grad_output,
251                 grad_weight,
252                 _count,
253                 _sorted,
254                 _indices,
255                 self.scale_grad_by_freq,
256                 -1,
257                 1
258             )
259 
260         return grad_weight, None, None
261 
262 
263 _all_functions.append(EmbeddingBag)
264
```
--- 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/torch/nn/_functions/thnn/sparse.py b/torch/nn/_functions/thnn/sparse.py
--- a/torch/nn/_functions/thnn/sparse.py
+++ b/torch/nn/_functions/thnn/sparse.py
@@ -10,12 +10,10 @@
 
     @staticmethod
     def _renorm(ctx, indices, weight, max_norm, norm_type):
-        if indices.dim() == 2:
-            indices = indices.clone().view(-1)
-
+        # clone indices since LookupTable_renorm modifies it in-place
         ctx._backend.LookupTable_renorm(
             ctx._backend.library_state,
-            indices,
+            indices.clone().view(-1),
             weight,
             max_norm,
             norm_type

{"golden_diff": "diff --git a/torch/nn/_functions/thnn/sparse.py b/torch/nn/_functions/thnn/sparse.py\n--- a/torch/nn/_functions/thnn/sparse.py\n+++ b/torch/nn/_functions/thnn/sparse.py\n@@ -10,12 +10,10 @@\n \n     @staticmethod\n     def _renorm(ctx, indices, weight, max_norm, norm_type):\n-        if indices.dim() == 2:\n-            indices = indices.clone().view(-1)\n-\n+        # clone indices since LookupTable_renorm modifies it in-place\n         ctx._backend.LookupTable_renorm(\n             ctx._backend.library_state,\n-            indices,\n+            indices.clone().view(-1),\n             weight,\n             max_norm,\n             norm_type\n", "issue": "nn.Embedding improperly sorts inputs when max_norm is specified\n```python\r\nimport torch\r\nimport torch.nn as nn\r\nfrom torch.autograd import Variable\r\n\r\nids = Variable(torch.LongTensor([2, 12, 4, 8, 8, 6]))\r\nembed = nn.Embedding(22, 5, max_norm=1.0)\r\nprint(ids)  # before: 2 12 4 8 8 6\r\nout = embed(ids)\r\nprint(ids)  # after: 2 4 6 8 8 12\r\n```\r\n\r\nThe output is also incorrect. It's the output from the sorted indices, instead of the user specified indices.\r\n\r\nReported by @adampolyak \n", "before_files": [{"content": "import torch\nfrom torch.autograd.function import Function\nfrom torch._thnn import type2backend\nfrom torch.autograd.function import once_differentiable\n\nfrom . import _all_functions\n\n\nclass Embedding(Function):\n\n    @staticmethod\n    def _renorm(ctx, indices, weight, max_norm, norm_type):\n        if indices.dim() == 2:\n            indices = indices.clone().view(-1)\n\n        ctx._backend.LookupTable_renorm(\n            ctx._backend.library_state,\n            indices,\n            weight,\n            max_norm,\n            norm_type\n        )\n\n    @classmethod\n    def forward(cls, ctx, indices, weight, padding_idx, max_norm, norm_type, scale_grad_by_freq,\n                sparse=False):\n\n        ctx.padding_idx = padding_idx\n        ctx.scale_grad_by_freq = scale_grad_by_freq\n        ctx._indices = None\n        ctx.sparse = sparse\n\n        assert indices.dim() <= 2\n        assert not ctx.needs_input_grad[0], \"Embedding doesn't \" \\\n            \"compute the gradient w.r.t. the indices\"\n\n        ctx._backend = type2backend[type(weight)]\n        ctx._weight_size = weight.size()\n\n        if not indices.is_contiguous():\n            ctx._indices = indices.contiguous()\n            indices = ctx._indices\n        else:\n            ctx.save_for_backward(indices)\n\n        output = weight.new()\n        if max_norm is not None:\n            cls._renorm(ctx, indices, weight, max_norm, norm_type)\n\n        if indices.dim() == 1:\n            output = torch.index_select(weight, 0, indices)\n        else:\n            output = torch.index_select(weight, 0, indices.view(-1))\n            output = output.view(indices.size(0), indices.size(1), weight.size(1))\n\n        return output\n\n    @staticmethod\n    @once_differentiable\n    def backward(ctx, grad_output):\n        if ctx._indices is not None:\n            indices = ctx._indices\n        else:\n            indices, = ctx.saved_tensors\n\n        grad_output = grad_output.contiguous()\n        if not ctx.sparse:\n            if indices.dim() == 2:\n                indices = indices.view(-1)\n\n            with torch.cuda.device_of(grad_output):\n                if grad_output.is_cuda:\n                    _sorted = torch.cuda.LongTensor()\n                    _indices = torch.cuda.LongTensor()\n                    _count = torch.cuda.LongTensor()\n                else:\n                    _count = torch.IntTensor()\n                    _sorted = _indices = None\n\n            grad_weight = grad_output.new(ctx._weight_size).zero_()\n            # Doesn't support Variable grad_output\n            ctx._backend.LookupTable_accGradParameters(\n                ctx._backend.library_state,\n                indices,\n                grad_output,\n                grad_weight,\n                _count,\n                _sorted,\n                _indices,\n                ctx.scale_grad_by_freq,\n                ctx.padding_idx,\n                1\n            )\n        else:\n            tensor_type = type(grad_output).__name__\n            if grad_output.is_cuda:\n                SparseTensor = getattr(torch.cuda.sparse, tensor_type)\n            else:\n                SparseTensor = getattr(torch.sparse, tensor_type)\n            grad_weight = SparseTensor(\n                indices.view(1, -1),\n                grad_output.view(-1, ctx._weight_size[1]),\n                ctx._weight_size,\n            )\n        return None, grad_weight, None, None, None, None, None\n\n\n_all_functions.append(Embedding)\n\nMODE_SUM = 0\nMODE_MEAN = 1\n\n\nclass EmbeddingBag(Function):\n\n    def __init__(self, max_norm, norm_type, scale_grad_by_freq, mode):\n        super(EmbeddingBag, self).__init__()\n        self.max_norm = max_norm\n        self.norm_type = norm_type\n        self.scale_grad_by_freq = scale_grad_by_freq\n        self._indices = None\n        assert mode is not None\n        if mode == 'sum':\n            self.mode = MODE_SUM\n        elif mode == 'mean':\n            self.mode = MODE_MEAN\n        else:\n            raise ValueError(\"mode needs to be 'sum' or 'mean', but got {}\"\n                             .format(mode))\n\n    def _renorm(self, indices, weight):\n        self._backend.LookupTable_renorm(\n            self._backend.library_state,\n            indices,\n            weight,\n            self.max_norm,\n            self.norm_type\n        )\n\n    def forward(self, weight, indices, offsets):\n        assert not self.needs_input_grad[1], \"EmbeddingBag doesn't \" \\\n            \"compute the gradient w.r.t. the indices\"\n\n        assert not self.needs_input_grad[2], \"EmbeddingBag doesn't \" \\\n            \"compute the gradient w.r.t. the offsets\"\n\n        assert indices.dim() == 1\n        if offsets.dim() != 1:\n            raise ValueError(\"offsets has to be a 1D Tensor\")\n\n        if offsets[0] != 0:\n            raise ValueError(\"offsets[0] has to be 0, i.e. the first sequence\"\n                             \" in the mini-batch has to start from position 0.\"\n                             \"However, got {}\".format(offsets[0]))\n        if offsets[-1] > indices.size(0):\n            raise ValueError(\"offsets[-1] has to be smaller than indices's length\"\n                             \" ({}), but got offsets[-1] of {}\"\n                             .format(indices.size(0), offsets[-1]))\n\n        self._backend = type2backend[type(weight)]\n        self._weight_size = weight.size()\n        self._offset2bag = offsets.new()\n\n        self.save_for_backward(indices)\n\n        indices = indices.contiguous().view(-1)\n        output = weight.new()\n        if self.max_norm is not None:\n            self._renorm(indices, weight)\n\n        if weight.is_cuda:\n            if self.mode == MODE_MEAN:\n                self.bag_size = offsets.new().resize_(offsets.size())\n            else:\n                self.bag_size = None\n\n            self._backend.LookupTableBag_updateOutput(\n                self._backend.library_state,\n                indices,\n                offsets,\n                weight,\n                output,\n                self._offset2bag,\n                self.mode,\n                self.bag_size\n            )\n        else:\n            # slow CPU implementation\n            index_output = torch.index_select(weight, 0, indices)\n            # indices = [1, 2, 30, 100, 12], offsets = [0, 2, 3]\n            self._offset2bag.resize_(indices.size(0)).zero_()  # offset2bag = [0 0 0 0 0]\n            self._offset2bag.index_fill_(0, offsets, 1)  # offset2bag = [1 0 1 0 1]\n            self._offset2bag[0] = 0  # offset2bag = [0 0 1 0 1]\n            self._offset2bag = self._offset2bag.cumsum(0)  # offset2bag = [0 0 1 1 2]\n            output.resize_(offsets.size(0), weight.size(1)).zero_()\n            output.index_add_(0, self._offset2bag, index_output)\n            if self.mode == MODE_MEAN:\n                if offsets.size(0) == 1:\n                    self.bag_size = indices.size(0)\n                else:\n                    self.bag_size = weight.new().resize_(offsets.size())\n                    self.bag_size[:-1] = offsets[1:] - offsets[:-1]\n                    self.bag_size[-1] = indices.size(0) - offsets[-1]\n                    self.bag_size = self.bag_size[:, None].expand_as(output)\n                output /= self.bag_size\n\n        return output\n\n    def backward(self, grad_output):\n        indices, = self.saved_tensors\n        indices = indices.contiguous().view(-1)\n        grad_output = grad_output.contiguous()\n\n        with torch.cuda.device_of(grad_output):\n            if grad_output.is_cuda:\n                _sorted = torch.cuda.LongTensor()\n                _indices = torch.cuda.LongTensor()\n                _count = torch.cuda.LongTensor()\n            else:\n                _count = torch.IntTensor()\n                _sorted = _indices = None\n\n        grad_weight = grad_output.new(self._weight_size).zero_()\n\n        if grad_output.is_cuda:\n            self._backend.LookupTableBag_accGradParameters(\n                self._backend.library_state,\n                indices,\n                grad_output,\n                grad_weight,\n                self._offset2bag,\n                _count,\n                _sorted,\n                _indices,\n                self.scale_grad_by_freq,\n                self.mode,\n                self.bag_size,\n                1\n            )\n        else:\n            # slow CPU implementation\n            if self.mode == MODE_MEAN:\n                # divide by average count\n                grad_output = grad_output / self.bag_size\n\n            index_grad_output = grad_output.index_select(0, self._offset2bag)\n            self._backend.LookupTable_accGradParameters(\n                self._backend.library_state,\n                indices,\n                index_grad_output,\n                grad_weight,\n                _count,\n                _sorted,\n                _indices,\n                self.scale_grad_by_freq,\n                -1,\n                1\n            )\n\n        return grad_weight, None, None\n\n\n_all_functions.append(EmbeddingBag)\n", "path": "torch/nn/_functions/thnn/sparse.py"}], "after_files": [{"content": "import torch\nfrom torch.autograd.function import Function\nfrom torch._thnn import type2backend\nfrom torch.autograd.function import once_differentiable\n\nfrom . import _all_functions\n\n\nclass Embedding(Function):\n\n    @staticmethod\n    def _renorm(ctx, indices, weight, max_norm, norm_type):\n        # clone indices since LookupTable_renorm modifies it in-place\n        ctx._backend.LookupTable_renorm(\n            ctx._backend.library_state,\n            indices.clone().view(-1),\n            weight,\n            max_norm,\n            norm_type\n        )\n\n    @classmethod\n    def forward(cls, ctx, indices, weight, padding_idx, max_norm, norm_type, scale_grad_by_freq,\n                sparse=False):\n\n        ctx.padding_idx = padding_idx\n        ctx.scale_grad_by_freq = scale_grad_by_freq\n        ctx._indices = None\n        ctx.sparse = sparse\n\n        assert indices.dim() <= 2\n        assert not ctx.needs_input_grad[0], \"Embedding doesn't \" \\\n            \"compute the gradient w.r.t. the indices\"\n\n        ctx._backend = type2backend[type(weight)]\n        ctx._weight_size = weight.size()\n\n        if not indices.is_contiguous():\n            ctx._indices = indices.contiguous()\n            indices = ctx._indices\n        else:\n            ctx.save_for_backward(indices)\n\n        output = weight.new()\n        if max_norm is not None:\n            cls._renorm(ctx, indices, weight, max_norm, norm_type)\n\n        if indices.dim() == 1:\n            output = torch.index_select(weight, 0, indices)\n        else:\n            output = torch.index_select(weight, 0, indices.view(-1))\n            output = output.view(indices.size(0), indices.size(1), weight.size(1))\n\n        return output\n\n    @staticmethod\n    @once_differentiable\n    def backward(ctx, grad_output):\n        if ctx._indices is not None:\n            indices = ctx._indices\n        else:\n            indices, = ctx.saved_tensors\n\n        grad_output = grad_output.contiguous()\n        if not ctx.sparse:\n            if indices.dim() == 2:\n                indices = indices.view(-1)\n\n            with torch.cuda.device_of(grad_output):\n                if grad_output.is_cuda:\n                    _sorted = torch.cuda.LongTensor()\n                    _indices = torch.cuda.LongTensor()\n                    _count = torch.cuda.LongTensor()\n                else:\n                    _count = torch.IntTensor()\n                    _sorted = _indices = None\n\n            grad_weight = grad_output.new(ctx._weight_size).zero_()\n            # Doesn't support Variable grad_output\n            ctx._backend.LookupTable_accGradParameters(\n                ctx._backend.library_state,\n                indices,\n                grad_output,\n                grad_weight,\n                _count,\n                _sorted,\n                _indices,\n                ctx.scale_grad_by_freq,\n                ctx.padding_idx,\n                1\n            )\n        else:\n            tensor_type = type(grad_output).__name__\n            if grad_output.is_cuda:\n                SparseTensor = getattr(torch.cuda.sparse, tensor_type)\n            else:\n                SparseTensor = getattr(torch.sparse, tensor_type)\n            grad_weight = SparseTensor(\n                indices.view(1, -1),\n                grad_output.view(-1, ctx._weight_size[1]),\n                ctx._weight_size,\n            )\n        return None, grad_weight, None, None, None, None, None\n\n\n_all_functions.append(Embedding)\n\nMODE_SUM = 0\nMODE_MEAN = 1\n\n\nclass EmbeddingBag(Function):\n\n    def __init__(self, max_norm, norm_type, scale_grad_by_freq, mode):\n        super(EmbeddingBag, self).__init__()\n        self.max_norm = max_norm\n        self.norm_type = norm_type\n        self.scale_grad_by_freq = scale_grad_by_freq\n        self._indices = None\n        assert mode is not None\n        if mode == 'sum':\n            self.mode = MODE_SUM\n        elif mode == 'mean':\n            self.mode = MODE_MEAN\n        else:\n            raise ValueError(\"mode needs to be 'sum' or 'mean', but got {}\"\n                             .format(mode))\n\n    def _renorm(self, indices, weight):\n        self._backend.LookupTable_renorm(\n            self._backend.library_state,\n            indices,\n            weight,\n            self.max_norm,\n            self.norm_type\n        )\n\n    def forward(self, weight, indices, offsets):\n        assert not self.needs_input_grad[1], \"EmbeddingBag doesn't \" \\\n            \"compute the gradient w.r.t. the indices\"\n\n        assert not self.needs_input_grad[2], \"EmbeddingBag doesn't \" \\\n            \"compute the gradient w.r.t. the offsets\"\n\n        assert indices.dim() == 1\n        if offsets.dim() != 1:\n            raise ValueError(\"offsets has to be a 1D Tensor\")\n\n        if offsets[0] != 0:\n            raise ValueError(\"offsets[0] has to be 0, i.e. the first sequence\"\n                             \" in the mini-batch has to start from position 0.\"\n                             \"However, got {}\".format(offsets[0]))\n        if offsets[-1] > indices.size(0):\n            raise ValueError(\"offsets[-1] has to be smaller than indices's length\"\n                             \" ({}), but got offsets[-1] of {}\"\n                             .format(indices.size(0), offsets[-1]))\n\n        self._backend = type2backend[type(weight)]\n        self._weight_size = weight.size()\n        self._offset2bag = offsets.new()\n\n        self.save_for_backward(indices)\n\n        indices = indices.contiguous().view(-1)\n        output = weight.new()\n        if self.max_norm is not None:\n            self._renorm(indices, weight)\n\n        if weight.is_cuda:\n            if self.mode == MODE_MEAN:\n                self.bag_size = offsets.new().resize_(offsets.size())\n            else:\n                self.bag_size = None\n\n            self._backend.LookupTableBag_updateOutput(\n                self._backend.library_state,\n                indices,\n                offsets,\n                weight,\n                output,\n                self._offset2bag,\n                self.mode,\n                self.bag_size\n            )\n        else:\n            # slow CPU implementation\n            index_output = torch.index_select(weight, 0, indices)\n            # indices = [1, 2, 30, 100, 12], offsets = [0, 2, 3]\n            self._offset2bag.resize_(indices.size(0)).zero_()  # offset2bag = [0 0 0 0 0]\n            self._offset2bag.index_fill_(0, offsets, 1)  # offset2bag = [1 0 1 0 1]\n            self._offset2bag[0] = 0  # offset2bag = [0 0 1 0 1]\n            self._offset2bag = self._offset2bag.cumsum(0)  # offset2bag = [0 0 1 1 2]\n            output.resize_(offsets.size(0), weight.size(1)).zero_()\n            output.index_add_(0, self._offset2bag, index_output)\n            if self.mode == MODE_MEAN:\n                if offsets.size(0) == 1:\n                    self.bag_size = indices.size(0)\n                else:\n                    self.bag_size = weight.new().resize_(offsets.size())\n                    self.bag_size[:-1] = offsets[1:] - offsets[:-1]\n                    self.bag_size[-1] = indices.size(0) - offsets[-1]\n                    self.bag_size = self.bag_size[:, None].expand_as(output)\n                output /= self.bag_size\n\n        return output\n\n    def backward(self, grad_output):\n        indices, = self.saved_tensors\n        indices = indices.contiguous().view(-1)\n        grad_output = grad_output.contiguous()\n\n        with torch.cuda.device_of(grad_output):\n            if grad_output.is_cuda:\n                _sorted = torch.cuda.LongTensor()\n                _indices = torch.cuda.LongTensor()\n                _count = torch.cuda.LongTensor()\n            else:\n                _count = torch.IntTensor()\n                _sorted = _indices = None\n\n        grad_weight = grad_output.new(self._weight_size).zero_()\n\n        if grad_output.is_cuda:\n            self._backend.LookupTableBag_accGradParameters(\n                self._backend.library_state,\n                indices,\n                grad_output,\n                grad_weight,\n                self._offset2bag,\n                _count,\n                _sorted,\n                _indices,\n                self.scale_grad_by_freq,\n                self.mode,\n                self.bag_size,\n                1\n            )\n        else:\n            # slow CPU implementation\n            if self.mode == MODE_MEAN:\n                # divide by average count\n                grad_output = grad_output / self.bag_size\n\n            index_grad_output = grad_output.index_select(0, self._offset2bag)\n            self._backend.LookupTable_accGradParameters(\n                self._backend.library_state,\n                indices,\n                index_grad_output,\n                grad_weight,\n                _count,\n                _sorted,\n                _indices,\n                self.scale_grad_by_freq,\n                -1,\n                1\n            )\n\n        return grad_weight, None, None\n\n\n_all_functions.append(EmbeddingBag)\n", "path": "torch/nn/_functions/thnn/sparse.py"}]}