We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Use `SOFTMAX_LOG` API of cudnn v3 in `softmax_corss_entropy`
`SOFTMAX_LOG` is supported in cudnn v3. It helps `softmax_cross_entropy` in #712 
We need to check version of cudnn. CuPy doesn't support it now.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `chainer/functions/loss/softmax_cross_entropy.py`
Content:
```
1 import numpy
2 import six
3 
4 from chainer import cuda
5 from chainer import function
6 from chainer.utils import type_check
7 
8 
9 def logsumexp(x):
10     xp = cuda.get_array_module(x)
11     m = x.max(axis=1, keepdims=True)
12     y = x - m
13     xp.exp(y, out=y)
14     return xp.log(y.sum(axis=1, keepdims=True)) + m
15 
16 
17 def softmax_log(x):
18     # TODO(unno): Use cudnn (cudnn v2 doesn't support CUDNN_SOFTMAX_LOG)
19     log_z = logsumexp(x)
20     return x - log_z
21 
22 
23 class SoftmaxCrossEntropy(function.Function):
24 
25     """Softmax activation followed by a cross entropy loss."""
26 
27     ignore_label = -1
28 
29     def __init__(self, use_cudnn=True, normalize=True):
30         self.use_cudnn = use_cudnn
31         self.normalize = normalize
32 
33     def check_type_forward(self, in_types):
34         type_check.expect(in_types.size() == 2)
35         x_type, t_type = in_types
36 
37         type_check.expect(
38             x_type.dtype == numpy.float32,
39             t_type.dtype == numpy.int32,
40             t_type.ndim == x_type.ndim - 1,
41 
42             x_type.shape[0] == t_type.shape[0],
43             x_type.shape[2:] == t_type.shape[1:],
44         )
45 
46     def forward_cpu(self, inputs):
47         x, t = inputs
48         log_y = softmax_log(x)
49         self.y = numpy.exp(log_y)
50         log_yd = numpy.rollaxis(log_y, 1)
51         log_yd = log_yd.reshape(len(log_yd), -1)
52 
53         log_p = log_yd[numpy.maximum(t.flat, 0), six.moves.range(t.size)]
54         # deal with the case where the SoftmaxCrossEntropy is
55         # unpickled from the old version
56         if getattr(self, 'normalize', True):
57             count = (t != self.ignore_label).sum()
58         else:
59             count = x.shape[0]
60         self.count = count
61 
62         if count == 0:
63             return numpy.zeros((), dtype=x.dtype),
64 
65         y = (log_p * (t.flat != self.ignore_label)).sum(keepdims=True) \
66             * (-1.0 / count)
67         return y.reshape(()),
68 
69     def forward_gpu(self, inputs):
70         cupy = cuda.cupy
71         x, t = inputs
72         log_y = softmax_log(x)
73         self.y = cupy.exp(log_y)
74         if getattr(self, 'normalize', True):
75             count = float((t != self.ignore_label).sum())
76         else:
77             count = t.shape[0]
78         self.count = count
79 
80         if count == 0:
81             return cupy.zeros((), dtype=x.dtype),
82 
83         log_y = cupy.rollaxis(log_y, 1, log_y.ndim)
84         ret = cuda.reduce(
85             'S t, raw T log_y, int32 n_channel, T inv_count', 'T out',
86             't == -1 ? 0 : log_y[_j * n_channel + t]',
87             'a + b', 'out = a * inv_count', '0', 'crossent_fwd'
88         )(t, log_y.reduced_view(), log_y.shape[-1], -1.0 / count)
89         return ret,
90 
91     def backward_cpu(self, inputs, grad_outputs):
92         x, t = inputs
93         if self.count == 0:
94             return numpy.zeros_like(x), None
95 
96         gloss = grad_outputs[0]
97         n_unit = t.size // t.shape[0]
98         if self.y.ndim == 2:
99             gx = self.y.copy()
100             gx[six.moves.xrange(len(t)), numpy.maximum(t, 0)] -= 1
101             gx *= (t != self.ignore_label).reshape((len(t), 1))
102         else:
103             # in the case where y.ndim is higher than 2,
104             # we think that a current implementation is inefficient
105             # because it yields two provisional arrays for indexing.
106             gx = self.y.copy().reshape(self.y.shape[0], self.y.shape[1], -1)
107             fst_index = numpy.arange(t.size) // n_unit
108             trd_index = numpy.arange(t.size) % n_unit
109             gx[fst_index, numpy.maximum(t.flat, 0), trd_index] -= 1
110             gx *= (t != self.ignore_label).reshape((len(t), 1, -1))
111             gx = gx.reshape(self.y.shape)
112 
113         gx *= gloss / self.count
114         return gx, None
115 
116     def backward_gpu(self, inputs, grad_outputs):
117         cupy = cuda.cupy
118         x, t = inputs
119         if self.count == 0:
120             return cupy.zeros_like(x), None
121 
122         gloss = grad_outputs[0]
123         n_unit = t.size // t.shape[0]
124         coeff = cuda.cupy.divide(gloss, self.count, dtype=gloss.dtype)
125         gx = cuda.elementwise(
126             'T y, S t, raw T coeff, S n_channel, S n_unit',
127             'T gx',
128             '''
129                const int c = (i / n_unit % n_channel);
130                if (t == -1) {
131                  gx = 0;
132                } else {
133                  gx = coeff[0] * (y - (c == t));
134                }
135             ''',
136             'softmax_crossent_bwd')(
137                 self.y, cupy.expand_dims(t, 1), coeff, x.shape[1], n_unit)
138         return gx, None
139 
140 
141 def softmax_cross_entropy(x, t, use_cudnn=True, normalize=True):
142     """Computes cross entropy loss for pre-softmax activations.
143 
144     Args:
145         x (Variable): Variable holding a multidimensional array whose element
146             indicates unnormalized log probability: the first axis of the
147             variable represents the number of samples, and the second axis
148             represents the number of classes. While this function computes
149             a usual softmax cross entropy if the number of dimensions is equal
150             to 2, it computes a cross entropy of the replicated softmax if the
151             number of dimensions is greater than 2.
152         t (Variable): Variable holding an int32 vector of groundtruth labels.
153             If ``t[i] == -1``, correspondig ``x[i]`` is ignored.
154         normalize (Variable): Variable holding a boolean value which
155             determines the normalization constant. If true, this function
156             normalizes the cross entropy loss across all instances. If else,
157             it only normalizes along a batch size.
158 
159     Returns:
160         Variable: A variable holding a scalar array of the cross entropy loss.
161 
162     .. note::
163 
164        This function is differentiable only by ``x``.
165 
166     """
167     return SoftmaxCrossEntropy(use_cudnn, normalize)(x, t)
168
```
--- 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/chainer/functions/loss/softmax_cross_entropy.py b/chainer/functions/loss/softmax_cross_entropy.py
--- a/chainer/functions/loss/softmax_cross_entropy.py
+++ b/chainer/functions/loss/softmax_cross_entropy.py
@@ -6,6 +6,14 @@
 from chainer.utils import type_check
 
 
+if cuda.cudnn_enabled:
+    cudnn = cuda.cudnn
+    libcudnn = cudnn.cudnn
+    _algorithm = libcudnn.CUDNN_SOFTMAX_LOG
+    _mode = libcudnn.CUDNN_SOFTMAX_MODE_CHANNEL
+    _cudnn_version = libcudnn.getVersion()
+
+
 def logsumexp(x):
     xp = cuda.get_array_module(x)
     m = x.max(axis=1, keepdims=True)
@@ -14,10 +22,26 @@
     return xp.log(y.sum(axis=1, keepdims=True)) + m
 
 
-def softmax_log(x):
-    # TODO(unno): Use cudnn (cudnn v2 doesn't support CUDNN_SOFTMAX_LOG)
-    log_z = logsumexp(x)
-    return x - log_z
+def softmax_log(x, use_cudnn):
+    xp = cuda.get_array_module(x)
+    if xp != numpy and cuda.cudnn_enabled and use_cudnn \
+       and _cudnn_version >= 3000:
+        dtype = x.dtype
+        one = numpy.array(1, dtype=dtype).ctypes
+        zero = numpy.array(0, dtype=dtype).ctypes
+        handle = cudnn.get_handle()
+        x_cube = x.reshape(x.shape[:2] + (-1, 1))
+        desc = cudnn.create_tensor_descriptor(x_cube)
+        y = xp.empty_like(x)
+        libcudnn.softmaxForward(
+            handle, _algorithm, _mode, one.data, desc.value,
+            x_cube.data.ptr, zero.data, desc.value,
+            y.data.ptr)
+        return y
+
+    else:
+        log_z = logsumexp(x)
+        return x - log_z
 
 
 class SoftmaxCrossEntropy(function.Function):
@@ -45,7 +69,7 @@
 
     def forward_cpu(self, inputs):
         x, t = inputs
-        log_y = softmax_log(x)
+        log_y = softmax_log(x, False)
         self.y = numpy.exp(log_y)
         log_yd = numpy.rollaxis(log_y, 1)
         log_yd = log_yd.reshape(len(log_yd), -1)
@@ -69,7 +93,7 @@
     def forward_gpu(self, inputs):
         cupy = cuda.cupy
         x, t = inputs
-        log_y = softmax_log(x)
+        log_y = softmax_log(x, self.use_cudnn)
         self.y = cupy.exp(log_y)
         if getattr(self, 'normalize', True):
             count = float((t != self.ignore_label).sum())

{"golden_diff": "diff --git a/chainer/functions/loss/softmax_cross_entropy.py b/chainer/functions/loss/softmax_cross_entropy.py\n--- a/chainer/functions/loss/softmax_cross_entropy.py\n+++ b/chainer/functions/loss/softmax_cross_entropy.py\n@@ -6,6 +6,14 @@\n from chainer.utils import type_check\n \n \n+if cuda.cudnn_enabled:\n+    cudnn = cuda.cudnn\n+    libcudnn = cudnn.cudnn\n+    _algorithm = libcudnn.CUDNN_SOFTMAX_LOG\n+    _mode = libcudnn.CUDNN_SOFTMAX_MODE_CHANNEL\n+    _cudnn_version = libcudnn.getVersion()\n+\n+\n def logsumexp(x):\n     xp = cuda.get_array_module(x)\n     m = x.max(axis=1, keepdims=True)\n@@ -14,10 +22,26 @@\n     return xp.log(y.sum(axis=1, keepdims=True)) + m\n \n \n-def softmax_log(x):\n-    # TODO(unno): Use cudnn (cudnn v2 doesn't support CUDNN_SOFTMAX_LOG)\n-    log_z = logsumexp(x)\n-    return x - log_z\n+def softmax_log(x, use_cudnn):\n+    xp = cuda.get_array_module(x)\n+    if xp != numpy and cuda.cudnn_enabled and use_cudnn \\\n+       and _cudnn_version >= 3000:\n+        dtype = x.dtype\n+        one = numpy.array(1, dtype=dtype).ctypes\n+        zero = numpy.array(0, dtype=dtype).ctypes\n+        handle = cudnn.get_handle()\n+        x_cube = x.reshape(x.shape[:2] + (-1, 1))\n+        desc = cudnn.create_tensor_descriptor(x_cube)\n+        y = xp.empty_like(x)\n+        libcudnn.softmaxForward(\n+            handle, _algorithm, _mode, one.data, desc.value,\n+            x_cube.data.ptr, zero.data, desc.value,\n+            y.data.ptr)\n+        return y\n+\n+    else:\n+        log_z = logsumexp(x)\n+        return x - log_z\n \n \n class SoftmaxCrossEntropy(function.Function):\n@@ -45,7 +69,7 @@\n \n     def forward_cpu(self, inputs):\n         x, t = inputs\n-        log_y = softmax_log(x)\n+        log_y = softmax_log(x, False)\n         self.y = numpy.exp(log_y)\n         log_yd = numpy.rollaxis(log_y, 1)\n         log_yd = log_yd.reshape(len(log_yd), -1)\n@@ -69,7 +93,7 @@\n     def forward_gpu(self, inputs):\n         cupy = cuda.cupy\n         x, t = inputs\n-        log_y = softmax_log(x)\n+        log_y = softmax_log(x, self.use_cudnn)\n         self.y = cupy.exp(log_y)\n         if getattr(self, 'normalize', True):\n             count = float((t != self.ignore_label).sum())\n", "issue": "Use `SOFTMAX_LOG` API of cudnn v3 in `softmax_corss_entropy`\n`SOFTMAX_LOG` is supported in cudnn v3. It helps `softmax_cross_entropy` in #712 \nWe need to check version of cudnn. CuPy doesn't support it now.\n\n", "before_files": [{"content": "import numpy\nimport six\n\nfrom chainer import cuda\nfrom chainer import function\nfrom chainer.utils import type_check\n\n\ndef logsumexp(x):\n    xp = cuda.get_array_module(x)\n    m = x.max(axis=1, keepdims=True)\n    y = x - m\n    xp.exp(y, out=y)\n    return xp.log(y.sum(axis=1, keepdims=True)) + m\n\n\ndef softmax_log(x):\n    # TODO(unno): Use cudnn (cudnn v2 doesn't support CUDNN_SOFTMAX_LOG)\n    log_z = logsumexp(x)\n    return x - log_z\n\n\nclass SoftmaxCrossEntropy(function.Function):\n\n    \"\"\"Softmax activation followed by a cross entropy loss.\"\"\"\n\n    ignore_label = -1\n\n    def __init__(self, use_cudnn=True, normalize=True):\n        self.use_cudnn = use_cudnn\n        self.normalize = normalize\n\n    def check_type_forward(self, in_types):\n        type_check.expect(in_types.size() == 2)\n        x_type, t_type = in_types\n\n        type_check.expect(\n            x_type.dtype == numpy.float32,\n            t_type.dtype == numpy.int32,\n            t_type.ndim == x_type.ndim - 1,\n\n            x_type.shape[0] == t_type.shape[0],\n            x_type.shape[2:] == t_type.shape[1:],\n        )\n\n    def forward_cpu(self, inputs):\n        x, t = inputs\n        log_y = softmax_log(x)\n        self.y = numpy.exp(log_y)\n        log_yd = numpy.rollaxis(log_y, 1)\n        log_yd = log_yd.reshape(len(log_yd), -1)\n\n        log_p = log_yd[numpy.maximum(t.flat, 0), six.moves.range(t.size)]\n        # deal with the case where the SoftmaxCrossEntropy is\n        # unpickled from the old version\n        if getattr(self, 'normalize', True):\n            count = (t != self.ignore_label).sum()\n        else:\n            count = x.shape[0]\n        self.count = count\n\n        if count == 0:\n            return numpy.zeros((), dtype=x.dtype),\n\n        y = (log_p * (t.flat != self.ignore_label)).sum(keepdims=True) \\\n            * (-1.0 / count)\n        return y.reshape(()),\n\n    def forward_gpu(self, inputs):\n        cupy = cuda.cupy\n        x, t = inputs\n        log_y = softmax_log(x)\n        self.y = cupy.exp(log_y)\n        if getattr(self, 'normalize', True):\n            count = float((t != self.ignore_label).sum())\n        else:\n            count = t.shape[0]\n        self.count = count\n\n        if count == 0:\n            return cupy.zeros((), dtype=x.dtype),\n\n        log_y = cupy.rollaxis(log_y, 1, log_y.ndim)\n        ret = cuda.reduce(\n            'S t, raw T log_y, int32 n_channel, T inv_count', 'T out',\n            't == -1 ? 0 : log_y[_j * n_channel + t]',\n            'a + b', 'out = a * inv_count', '0', 'crossent_fwd'\n        )(t, log_y.reduced_view(), log_y.shape[-1], -1.0 / count)\n        return ret,\n\n    def backward_cpu(self, inputs, grad_outputs):\n        x, t = inputs\n        if self.count == 0:\n            return numpy.zeros_like(x), None\n\n        gloss = grad_outputs[0]\n        n_unit = t.size // t.shape[0]\n        if self.y.ndim == 2:\n            gx = self.y.copy()\n            gx[six.moves.xrange(len(t)), numpy.maximum(t, 0)] -= 1\n            gx *= (t != self.ignore_label).reshape((len(t), 1))\n        else:\n            # in the case where y.ndim is higher than 2,\n            # we think that a current implementation is inefficient\n            # because it yields two provisional arrays for indexing.\n            gx = self.y.copy().reshape(self.y.shape[0], self.y.shape[1], -1)\n            fst_index = numpy.arange(t.size) // n_unit\n            trd_index = numpy.arange(t.size) % n_unit\n            gx[fst_index, numpy.maximum(t.flat, 0), trd_index] -= 1\n            gx *= (t != self.ignore_label).reshape((len(t), 1, -1))\n            gx = gx.reshape(self.y.shape)\n\n        gx *= gloss / self.count\n        return gx, None\n\n    def backward_gpu(self, inputs, grad_outputs):\n        cupy = cuda.cupy\n        x, t = inputs\n        if self.count == 0:\n            return cupy.zeros_like(x), None\n\n        gloss = grad_outputs[0]\n        n_unit = t.size // t.shape[0]\n        coeff = cuda.cupy.divide(gloss, self.count, dtype=gloss.dtype)\n        gx = cuda.elementwise(\n            'T y, S t, raw T coeff, S n_channel, S n_unit',\n            'T gx',\n            '''\n               const int c = (i / n_unit % n_channel);\n               if (t == -1) {\n                 gx = 0;\n               } else {\n                 gx = coeff[0] * (y - (c == t));\n               }\n            ''',\n            'softmax_crossent_bwd')(\n                self.y, cupy.expand_dims(t, 1), coeff, x.shape[1], n_unit)\n        return gx, None\n\n\ndef softmax_cross_entropy(x, t, use_cudnn=True, normalize=True):\n    \"\"\"Computes cross entropy loss for pre-softmax activations.\n\n    Args:\n        x (Variable): Variable holding a multidimensional array whose element\n            indicates unnormalized log probability: the first axis of the\n            variable represents the number of samples, and the second axis\n            represents the number of classes. While this function computes\n            a usual softmax cross entropy if the number of dimensions is equal\n            to 2, it computes a cross entropy of the replicated softmax if the\n            number of dimensions is greater than 2.\n        t (Variable): Variable holding an int32 vector of groundtruth labels.\n            If ``t[i] == -1``, correspondig ``x[i]`` is ignored.\n        normalize (Variable): Variable holding a boolean value which\n            determines the normalization constant. If true, this function\n            normalizes the cross entropy loss across all instances. If else,\n            it only normalizes along a batch size.\n\n    Returns:\n        Variable: A variable holding a scalar array of the cross entropy loss.\n\n    .. note::\n\n       This function is differentiable only by ``x``.\n\n    \"\"\"\n    return SoftmaxCrossEntropy(use_cudnn, normalize)(x, t)\n", "path": "chainer/functions/loss/softmax_cross_entropy.py"}], "after_files": [{"content": "import numpy\nimport six\n\nfrom chainer import cuda\nfrom chainer import function\nfrom chainer.utils import type_check\n\n\nif cuda.cudnn_enabled:\n    cudnn = cuda.cudnn\n    libcudnn = cudnn.cudnn\n    _algorithm = libcudnn.CUDNN_SOFTMAX_LOG\n    _mode = libcudnn.CUDNN_SOFTMAX_MODE_CHANNEL\n    _cudnn_version = libcudnn.getVersion()\n\n\ndef logsumexp(x):\n    xp = cuda.get_array_module(x)\n    m = x.max(axis=1, keepdims=True)\n    y = x - m\n    xp.exp(y, out=y)\n    return xp.log(y.sum(axis=1, keepdims=True)) + m\n\n\ndef softmax_log(x, use_cudnn):\n    xp = cuda.get_array_module(x)\n    if xp != numpy and cuda.cudnn_enabled and use_cudnn \\\n       and _cudnn_version >= 3000:\n        dtype = x.dtype\n        one = numpy.array(1, dtype=dtype).ctypes\n        zero = numpy.array(0, dtype=dtype).ctypes\n        handle = cudnn.get_handle()\n        x_cube = x.reshape(x.shape[:2] + (-1, 1))\n        desc = cudnn.create_tensor_descriptor(x_cube)\n        y = xp.empty_like(x)\n        libcudnn.softmaxForward(\n            handle, _algorithm, _mode, one.data, desc.value,\n            x_cube.data.ptr, zero.data, desc.value,\n            y.data.ptr)\n        return y\n\n    else:\n        log_z = logsumexp(x)\n        return x - log_z\n\n\nclass SoftmaxCrossEntropy(function.Function):\n\n    \"\"\"Softmax activation followed by a cross entropy loss.\"\"\"\n\n    ignore_label = -1\n\n    def __init__(self, use_cudnn=True, normalize=True):\n        self.use_cudnn = use_cudnn\n        self.normalize = normalize\n\n    def check_type_forward(self, in_types):\n        type_check.expect(in_types.size() == 2)\n        x_type, t_type = in_types\n\n        type_check.expect(\n            x_type.dtype == numpy.float32,\n            t_type.dtype == numpy.int32,\n            t_type.ndim == x_type.ndim - 1,\n\n            x_type.shape[0] == t_type.shape[0],\n            x_type.shape[2:] == t_type.shape[1:],\n        )\n\n    def forward_cpu(self, inputs):\n        x, t = inputs\n        log_y = softmax_log(x, False)\n        self.y = numpy.exp(log_y)\n        log_yd = numpy.rollaxis(log_y, 1)\n        log_yd = log_yd.reshape(len(log_yd), -1)\n\n        log_p = log_yd[numpy.maximum(t.flat, 0), six.moves.range(t.size)]\n        # deal with the case where the SoftmaxCrossEntropy is\n        # unpickled from the old version\n        if getattr(self, 'normalize', True):\n            count = (t != self.ignore_label).sum()\n        else:\n            count = x.shape[0]\n        self.count = count\n\n        if count == 0:\n            return numpy.zeros((), dtype=x.dtype),\n\n        y = (log_p * (t.flat != self.ignore_label)).sum(keepdims=True) \\\n            * (-1.0 / count)\n        return y.reshape(()),\n\n    def forward_gpu(self, inputs):\n        cupy = cuda.cupy\n        x, t = inputs\n        log_y = softmax_log(x, self.use_cudnn)\n        self.y = cupy.exp(log_y)\n        if getattr(self, 'normalize', True):\n            count = float((t != self.ignore_label).sum())\n        else:\n            count = t.shape[0]\n        self.count = count\n\n        if count == 0:\n            return cupy.zeros((), dtype=x.dtype),\n\n        log_y = cupy.rollaxis(log_y, 1, log_y.ndim)\n        ret = cuda.reduce(\n            'S t, raw T log_y, int32 n_channel, T inv_count', 'T out',\n            't == -1 ? 0 : log_y[_j * n_channel + t]',\n            'a + b', 'out = a * inv_count', '0', 'crossent_fwd'\n        )(t, log_y.reduced_view(), log_y.shape[-1], -1.0 / count)\n        return ret,\n\n    def backward_cpu(self, inputs, grad_outputs):\n        x, t = inputs\n        if self.count == 0:\n            return numpy.zeros_like(x), None\n\n        gloss = grad_outputs[0]\n        n_unit = t.size // t.shape[0]\n        if self.y.ndim == 2:\n            gx = self.y.copy()\n            gx[six.moves.xrange(len(t)), numpy.maximum(t, 0)] -= 1\n            gx *= (t != self.ignore_label).reshape((len(t), 1))\n        else:\n            # in the case where y.ndim is higher than 2,\n            # we think that a current implementation is inefficient\n            # because it yields two provisional arrays for indexing.\n            gx = self.y.copy().reshape(self.y.shape[0], self.y.shape[1], -1)\n            fst_index = numpy.arange(t.size) // n_unit\n            trd_index = numpy.arange(t.size) % n_unit\n            gx[fst_index, numpy.maximum(t.flat, 0), trd_index] -= 1\n            gx *= (t != self.ignore_label).reshape((len(t), 1, -1))\n            gx = gx.reshape(self.y.shape)\n\n        gx *= gloss / self.count\n        return gx, None\n\n    def backward_gpu(self, inputs, grad_outputs):\n        cupy = cuda.cupy\n        x, t = inputs\n        if self.count == 0:\n            return cupy.zeros_like(x), None\n\n        gloss = grad_outputs[0]\n        n_unit = t.size // t.shape[0]\n        coeff = cuda.cupy.divide(gloss, self.count, dtype=gloss.dtype)\n        gx = cuda.elementwise(\n            'T y, S t, raw T coeff, S n_channel, S n_unit',\n            'T gx',\n            '''\n               const int c = (i / n_unit % n_channel);\n               if (t == -1) {\n                 gx = 0;\n               } else {\n                 gx = coeff[0] * (y - (c == t));\n               }\n            ''',\n            'softmax_crossent_bwd')(\n                self.y, cupy.expand_dims(t, 1), coeff, x.shape[1], n_unit)\n        return gx, None\n\n\ndef softmax_cross_entropy(x, t, use_cudnn=True, normalize=True):\n    \"\"\"Computes cross entropy loss for pre-softmax activations.\n\n    Args:\n        x (Variable): Variable holding a multidimensional array whose element\n            indicates unnormalized log probability: the first axis of the\n            variable represents the number of samples, and the second axis\n            represents the number of classes. While this function computes\n            a usual softmax cross entropy if the number of dimensions is equal\n            to 2, it computes a cross entropy of the replicated softmax if the\n            number of dimensions is greater than 2.\n        t (Variable): Variable holding an int32 vector of groundtruth labels.\n            If ``t[i] == -1``, correspondig ``x[i]`` is ignored.\n        normalize (Variable): Variable holding a boolean value which\n            determines the normalization constant. If true, this function\n            normalizes the cross entropy loss across all instances. If else,\n            it only normalizes along a batch size.\n\n    Returns:\n        Variable: A variable holding a scalar array of the cross entropy loss.\n\n    .. note::\n\n       This function is differentiable only by ``x``.\n\n    \"\"\"\n    return SoftmaxCrossEntropy(use_cudnn, normalize)(x, t)\n", "path": "chainer/functions/loss/softmax_cross_entropy.py"}]}