We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Use `numpy.uintp` for `size_t`
`numpy.intp` is `ssize_t`, and is not `size_t`. When value of `ptr` allocated by `malloc` method is larger than the maximum value of `ssize_t`, `numpy.intp(ptr)` causes an error, because it checks actual value of `ptr`.
We need to use `numpy.uintp` in this case.

Note that `numpy.uintp` is not documented in the reference manual http://docs.scipy.org/doc/numpy-1.10.1/user/basics.types.html


--- 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/math/matmul.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 _mat_ptrs(a):
10     """Creates an array of pointers to matrices
11 
12     Args:
13         a: A batch of matrices on GPU
14     Returns:
15         GPU array of pointers to matrices
16     """
17     if a.shape[0] == 1:
18         return cuda.cupy.full((1,), a[0].data.ptr, dtype=numpy.intp)
19     else:
20         stride = a[1].data.ptr - a[0].data.ptr
21         return cuda.cupy.arange(
22             a[0].data.ptr,
23             a[0].data.ptr + stride * a.shape[0],
24             stride,
25             dtype=numpy.intp)
26 
27 
28 def _as_mat(x):
29     return x.reshape((len(x), 1)) if len(x.shape) == 1 else x
30 
31 
32 def _as_batch_mat(x):
33     return x.reshape((x.shape[0], x.shape[1], 1)) if len(x.shape) == 2 else x
34 
35 
36 def _matmul(a, b, transa=False, transb=False, transout=False):
37     a = _as_mat(a)
38     b = _as_mat(b)
39     if transa:
40         a = a.T
41     if transb:
42         b = b.T
43     if transout:
44         # (A B)^T = B^T A^T
45         a, b = b.T, a.T
46     return a.dot(b)
47 
48 
49 def _get_ld(a):
50     shape = a.shape[-2:]
51     strides = a.strides[-2:]
52     trans = numpy.argmin(strides)
53     return trans, int(max(shape[trans], max(strides) // a.itemsize))
54 
55 
56 def _batch_matmul_gpu(a, b, out, transa=False, transb=False, transout=False):
57     a = _as_batch_mat(a)
58     b = _as_batch_mat(b)
59     trans_axis = (0, 2, 1)
60     if transout:
61         out = out.transpose(trans_axis)
62     needtrans, _ = _get_ld(out)
63     if needtrans == 1:
64         # (A B)^T = B^T A^T
65         a, b = b, a
66         transa, transb = not transb, not transa
67         out = out.transpose(trans_axis)
68     if transa:
69         a = a.transpose(trans_axis)
70     if transb:
71         b = b.transpose(trans_axis)
72 
73     transa, lda = _get_ld(a)
74     transb, ldb = _get_ld(b)
75     transout, ldout = _get_ld(out)
76     la, n, ka = a.shape
77     lb, kb, m = b.shape
78 
79     assert ka == kb
80     assert transout == 0 or ldout == 1
81     assert out.shape == (la, n, m)
82 
83     ap = _mat_ptrs(a)
84     bp = _mat_ptrs(b)
85     outp = _mat_ptrs(out)
86     cuda.cublas.sgemmBatched(
87         cuda.Device().cublas_handle,
88         transa,
89         transb,
90         n, m, ka, 1.0,
91         ap.data.ptr, lda,
92         bp.data.ptr, ldb,
93         0.0, outp.data.ptr, ldout, la)
94 
95 
96 def _check_ndim(in_type, lower=1, upper=2):
97     type_check.expect(
98         in_type.ndim >= lower,
99         in_type.ndim <= upper
100     )
101 
102 
103 def _convert_type(in_type, vector_ndim=1):
104     if in_type.ndim.eval() == vector_ndim:
105         in_type = type_check.Variable(
106             type_check.TypeInfo(in_type.shape.eval() + (1,),
107                                 in_type.dtype),
108             '%s(1-D array)' % in_type.name)
109     else:
110         in_type.name = '%s(2-D array)' % in_type.name
111     return in_type
112 
113 
114 def _get_check_index(trans, right, row_idx=0, col_idx=1):
115     if trans ^ right:
116         return row_idx
117     else:
118         return col_idx
119 
120 
121 class MatMul(function.Function):
122     def __init__(self, transa=False, transb=False):
123         self.transa = transa
124         self.transb = transb
125 
126     def check_type_forward(self, in_types):
127         type_check.expect(in_types.size() == 2)
128         a_type, b_type = in_types
129 
130         type_check.expect(
131             a_type.dtype == numpy.float32,
132             b_type.dtype == numpy.float32
133         )
134 
135         _check_ndim(a_type)
136         _check_ndim(b_type)
137 
138         a_type = _convert_type(a_type)
139         b_type = _convert_type(b_type)
140         a_idx = _get_check_index(self.transa, False)
141         b_idx = _get_check_index(self.transb, True)
142         type_check.expect(
143             a_type.shape[a_idx] == b_type.shape[b_idx]
144         )
145 
146     def forward(self, x):
147         return _matmul(x[0], x[1], transa=self.transa, transb=self.transb),
148 
149     def backward(self, x, gy):
150         gx0 = _matmul(
151             gy[0], x[1], transb=not self.transb, transout=self.transa
152             ).reshape(x[0].shape)
153         gx1 = _matmul(
154             x[0], gy[0], transa=not self.transa, transout=self.transb
155             ).reshape(x[1].shape)
156         return gx0, gx1
157 
158 
159 def matmul(a, b, transa=False, transb=False):
160     """Computes the matrix multiplication of two arrays.
161 
162     Args:
163         a (Variable): The left operand of the matrix multiplication.
164             A 1-D array of shape (N,) is considered as an Nx1 matrix.
165             A 2-D array of shape (M, N) is considered as an MxN matrix.
166         b (Variable): The right operand of the matrix multiplication.
167             Its array is treated as a matrix in the same way as ``a``'s array.
168         transa (bool): If true, transpose a.
169         transb (bool): If true, transpose b.
170 
171     Returns:
172         ~chainer.Variable: The result of the matrix multiplication as a 2-D
173             array.
174     """
175     return MatMul(transa=transa, transb=transb)(a, b)
176 
177 
178 class BatchMatMul(function.Function):
179     def __init__(self, transa=False, transb=False):
180         self.transa = transa
181         self.transb = transb
182 
183     def _output_shape(self, a, b):
184         batch_size = a.shape[0]
185         a_mat_shape = _as_mat(a[0]).shape
186         b_mat_shape = _as_mat(b[0]).shape
187         m = a_mat_shape[1 if self.transa else 0]
188         n = b_mat_shape[0 if self.transb else 1]
189         return (batch_size, m, n)
190 
191     def check_type_forward(self, in_types):
192         type_check.expect(in_types.size() == 2)
193         a_type, b_type = in_types
194 
195         type_check.expect(
196             a_type.dtype == numpy.float32,
197             b_type.dtype == numpy.float32
198         )
199 
200         _check_ndim(a_type, lower=2, upper=3)
201         _check_ndim(b_type, lower=2, upper=3)
202 
203         a_type = _convert_type(a_type, vector_ndim=2)
204         b_type = _convert_type(b_type, vector_ndim=2)
205         a_idx = _get_check_index(self.transa, False, row_idx=1, col_idx=2)
206         b_idx = _get_check_index(self.transb, True, row_idx=1, col_idx=2)
207         type_check.expect(
208             a_type.shape[a_idx] == b_type.shape[b_idx]
209         )
210 
211     def forward_cpu(self, x):
212         a, b = x
213         batch_size = a.shape[0]
214         shape = self._output_shape(a, b)
215         ret_dtype = numpy.find_common_type([a.dtype, b.dtype], [])
216         ret = numpy.empty(shape, dtype=ret_dtype)
217         for i in six.moves.range(batch_size):
218             ret[i] = _matmul(
219                 a[i], b[i], transa=self.transa, transb=self.transb)
220         return ret,
221 
222     def backward_cpu(self, x, gy):
223         a, b = x
224         batch_size = a.shape[0]
225         ga = numpy.empty_like(a)
226         gb = numpy.empty_like(b)
227         for i in six.moves.range(batch_size):
228             ga[i] = _matmul(
229                 gy[0][i], b[i], transb=not self.transb,
230                 transout=self.transa).reshape(a[0].shape)
231             gb[i] = _matmul(
232                 a[i], gy[0][i], transa=not self.transa,
233                 transout=self.transb).reshape(b[0].shape)
234         return ga, gb
235 
236     def forward_gpu(self, x):
237         a, b = x
238         shape = self._output_shape(a, b)
239         ret = cuda.zeros(shape)
240         _batch_matmul_gpu(
241             a, b, transa=self.transa, transb=self.transb, out=ret)
242         return ret,
243 
244     def backward_gpu(self, x, gy):
245         a, b = x
246         batch_size = a.shape[0]
247         ga = cuda.empty((batch_size,) + _as_mat(a[0]).shape)
248         gb = cuda.empty((batch_size,) + _as_mat(b[0]).shape)
249         _batch_matmul_gpu(
250             gy[0], b, transb=not self.transb, transout=self.transa, out=ga)
251         _batch_matmul_gpu(
252             a, gy[0], transa=not self.transa, transout=self.transb, out=gb)
253         ga = ga.reshape(a.shape)
254         gb = gb.reshape(b.shape)
255         return ga, gb
256 
257 
258 def batch_matmul(a, b, transa=False, transb=False):
259     """Computes the batch matrix multiplications of two sets of arrays.
260 
261     Args:
262         a (Variable): The left operand of the batch matrix multiplications.
263             A 2-D array of shape (B, N,) is considered as B Nx1 matrices.
264             A 3-D array of shape (B, M, N) is considered as B MxN matrices.
265         b (Variable): The right operand of the batch matrix multiplications.
266             Its array is treated as matrices in the same way as ``a``'s array.
267         transa (bool): If true, transpose each matrix in a.
268         transb (bool): If true, transpose each matrix in b.
269 
270     Returns:
271         ~chainer.Variable: The result of the batch matrix multiplications as a
272             3-D array.
273     """
274     return BatchMatMul(transa=transa, transb=transb)(a, b)
275
```
--- 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/math/matmul.py b/chainer/functions/math/matmul.py
--- a/chainer/functions/math/matmul.py
+++ b/chainer/functions/math/matmul.py
@@ -15,14 +15,14 @@
         GPU array of pointers to matrices
     """
     if a.shape[0] == 1:
-        return cuda.cupy.full((1,), a[0].data.ptr, dtype=numpy.intp)
+        return cuda.cupy.full((1,), a[0].data.ptr, dtype=numpy.uintp)
     else:
         stride = a[1].data.ptr - a[0].data.ptr
         return cuda.cupy.arange(
             a[0].data.ptr,
             a[0].data.ptr + stride * a.shape[0],
             stride,
-            dtype=numpy.intp)
+            dtype=numpy.uintp)
 
 
 def _as_mat(x):

{"golden_diff": "diff --git a/chainer/functions/math/matmul.py b/chainer/functions/math/matmul.py\n--- a/chainer/functions/math/matmul.py\n+++ b/chainer/functions/math/matmul.py\n@@ -15,14 +15,14 @@\n         GPU array of pointers to matrices\n     \"\"\"\n     if a.shape[0] == 1:\n-        return cuda.cupy.full((1,), a[0].data.ptr, dtype=numpy.intp)\n+        return cuda.cupy.full((1,), a[0].data.ptr, dtype=numpy.uintp)\n     else:\n         stride = a[1].data.ptr - a[0].data.ptr\n         return cuda.cupy.arange(\n             a[0].data.ptr,\n             a[0].data.ptr + stride * a.shape[0],\n             stride,\n-            dtype=numpy.intp)\n+            dtype=numpy.uintp)\n \n \n def _as_mat(x):\n", "issue": "Use `numpy.uintp` for `size_t`\n`numpy.intp` is `ssize_t`, and is not `size_t`. When value of `ptr` allocated by `malloc` method is larger than the maximum value of `ssize_t`, `numpy.intp(ptr)` causes an error, because it checks actual value of `ptr`.\nWe need to use `numpy.uintp` in this case.\n\nNote that `numpy.uintp` is not documented in the reference manual http://docs.scipy.org/doc/numpy-1.10.1/user/basics.types.html\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 _mat_ptrs(a):\n    \"\"\"Creates an array of pointers to matrices\n\n    Args:\n        a: A batch of matrices on GPU\n    Returns:\n        GPU array of pointers to matrices\n    \"\"\"\n    if a.shape[0] == 1:\n        return cuda.cupy.full((1,), a[0].data.ptr, dtype=numpy.intp)\n    else:\n        stride = a[1].data.ptr - a[0].data.ptr\n        return cuda.cupy.arange(\n            a[0].data.ptr,\n            a[0].data.ptr + stride * a.shape[0],\n            stride,\n            dtype=numpy.intp)\n\n\ndef _as_mat(x):\n    return x.reshape((len(x), 1)) if len(x.shape) == 1 else x\n\n\ndef _as_batch_mat(x):\n    return x.reshape((x.shape[0], x.shape[1], 1)) if len(x.shape) == 2 else x\n\n\ndef _matmul(a, b, transa=False, transb=False, transout=False):\n    a = _as_mat(a)\n    b = _as_mat(b)\n    if transa:\n        a = a.T\n    if transb:\n        b = b.T\n    if transout:\n        # (A B)^T = B^T A^T\n        a, b = b.T, a.T\n    return a.dot(b)\n\n\ndef _get_ld(a):\n    shape = a.shape[-2:]\n    strides = a.strides[-2:]\n    trans = numpy.argmin(strides)\n    return trans, int(max(shape[trans], max(strides) // a.itemsize))\n\n\ndef _batch_matmul_gpu(a, b, out, transa=False, transb=False, transout=False):\n    a = _as_batch_mat(a)\n    b = _as_batch_mat(b)\n    trans_axis = (0, 2, 1)\n    if transout:\n        out = out.transpose(trans_axis)\n    needtrans, _ = _get_ld(out)\n    if needtrans == 1:\n        # (A B)^T = B^T A^T\n        a, b = b, a\n        transa, transb = not transb, not transa\n        out = out.transpose(trans_axis)\n    if transa:\n        a = a.transpose(trans_axis)\n    if transb:\n        b = b.transpose(trans_axis)\n\n    transa, lda = _get_ld(a)\n    transb, ldb = _get_ld(b)\n    transout, ldout = _get_ld(out)\n    la, n, ka = a.shape\n    lb, kb, m = b.shape\n\n    assert ka == kb\n    assert transout == 0 or ldout == 1\n    assert out.shape == (la, n, m)\n\n    ap = _mat_ptrs(a)\n    bp = _mat_ptrs(b)\n    outp = _mat_ptrs(out)\n    cuda.cublas.sgemmBatched(\n        cuda.Device().cublas_handle,\n        transa,\n        transb,\n        n, m, ka, 1.0,\n        ap.data.ptr, lda,\n        bp.data.ptr, ldb,\n        0.0, outp.data.ptr, ldout, la)\n\n\ndef _check_ndim(in_type, lower=1, upper=2):\n    type_check.expect(\n        in_type.ndim >= lower,\n        in_type.ndim <= upper\n    )\n\n\ndef _convert_type(in_type, vector_ndim=1):\n    if in_type.ndim.eval() == vector_ndim:\n        in_type = type_check.Variable(\n            type_check.TypeInfo(in_type.shape.eval() + (1,),\n                                in_type.dtype),\n            '%s(1-D array)' % in_type.name)\n    else:\n        in_type.name = '%s(2-D array)' % in_type.name\n    return in_type\n\n\ndef _get_check_index(trans, right, row_idx=0, col_idx=1):\n    if trans ^ right:\n        return row_idx\n    else:\n        return col_idx\n\n\nclass MatMul(function.Function):\n    def __init__(self, transa=False, transb=False):\n        self.transa = transa\n        self.transb = transb\n\n    def check_type_forward(self, in_types):\n        type_check.expect(in_types.size() == 2)\n        a_type, b_type = in_types\n\n        type_check.expect(\n            a_type.dtype == numpy.float32,\n            b_type.dtype == numpy.float32\n        )\n\n        _check_ndim(a_type)\n        _check_ndim(b_type)\n\n        a_type = _convert_type(a_type)\n        b_type = _convert_type(b_type)\n        a_idx = _get_check_index(self.transa, False)\n        b_idx = _get_check_index(self.transb, True)\n        type_check.expect(\n            a_type.shape[a_idx] == b_type.shape[b_idx]\n        )\n\n    def forward(self, x):\n        return _matmul(x[0], x[1], transa=self.transa, transb=self.transb),\n\n    def backward(self, x, gy):\n        gx0 = _matmul(\n            gy[0], x[1], transb=not self.transb, transout=self.transa\n            ).reshape(x[0].shape)\n        gx1 = _matmul(\n            x[0], gy[0], transa=not self.transa, transout=self.transb\n            ).reshape(x[1].shape)\n        return gx0, gx1\n\n\ndef matmul(a, b, transa=False, transb=False):\n    \"\"\"Computes the matrix multiplication of two arrays.\n\n    Args:\n        a (Variable): The left operand of the matrix multiplication.\n            A 1-D array of shape (N,) is considered as an Nx1 matrix.\n            A 2-D array of shape (M, N) is considered as an MxN matrix.\n        b (Variable): The right operand of the matrix multiplication.\n            Its array is treated as a matrix in the same way as ``a``'s array.\n        transa (bool): If true, transpose a.\n        transb (bool): If true, transpose b.\n\n    Returns:\n        ~chainer.Variable: The result of the matrix multiplication as a 2-D\n            array.\n    \"\"\"\n    return MatMul(transa=transa, transb=transb)(a, b)\n\n\nclass BatchMatMul(function.Function):\n    def __init__(self, transa=False, transb=False):\n        self.transa = transa\n        self.transb = transb\n\n    def _output_shape(self, a, b):\n        batch_size = a.shape[0]\n        a_mat_shape = _as_mat(a[0]).shape\n        b_mat_shape = _as_mat(b[0]).shape\n        m = a_mat_shape[1 if self.transa else 0]\n        n = b_mat_shape[0 if self.transb else 1]\n        return (batch_size, m, n)\n\n    def check_type_forward(self, in_types):\n        type_check.expect(in_types.size() == 2)\n        a_type, b_type = in_types\n\n        type_check.expect(\n            a_type.dtype == numpy.float32,\n            b_type.dtype == numpy.float32\n        )\n\n        _check_ndim(a_type, lower=2, upper=3)\n        _check_ndim(b_type, lower=2, upper=3)\n\n        a_type = _convert_type(a_type, vector_ndim=2)\n        b_type = _convert_type(b_type, vector_ndim=2)\n        a_idx = _get_check_index(self.transa, False, row_idx=1, col_idx=2)\n        b_idx = _get_check_index(self.transb, True, row_idx=1, col_idx=2)\n        type_check.expect(\n            a_type.shape[a_idx] == b_type.shape[b_idx]\n        )\n\n    def forward_cpu(self, x):\n        a, b = x\n        batch_size = a.shape[0]\n        shape = self._output_shape(a, b)\n        ret_dtype = numpy.find_common_type([a.dtype, b.dtype], [])\n        ret = numpy.empty(shape, dtype=ret_dtype)\n        for i in six.moves.range(batch_size):\n            ret[i] = _matmul(\n                a[i], b[i], transa=self.transa, transb=self.transb)\n        return ret,\n\n    def backward_cpu(self, x, gy):\n        a, b = x\n        batch_size = a.shape[0]\n        ga = numpy.empty_like(a)\n        gb = numpy.empty_like(b)\n        for i in six.moves.range(batch_size):\n            ga[i] = _matmul(\n                gy[0][i], b[i], transb=not self.transb,\n                transout=self.transa).reshape(a[0].shape)\n            gb[i] = _matmul(\n                a[i], gy[0][i], transa=not self.transa,\n                transout=self.transb).reshape(b[0].shape)\n        return ga, gb\n\n    def forward_gpu(self, x):\n        a, b = x\n        shape = self._output_shape(a, b)\n        ret = cuda.zeros(shape)\n        _batch_matmul_gpu(\n            a, b, transa=self.transa, transb=self.transb, out=ret)\n        return ret,\n\n    def backward_gpu(self, x, gy):\n        a, b = x\n        batch_size = a.shape[0]\n        ga = cuda.empty((batch_size,) + _as_mat(a[0]).shape)\n        gb = cuda.empty((batch_size,) + _as_mat(b[0]).shape)\n        _batch_matmul_gpu(\n            gy[0], b, transb=not self.transb, transout=self.transa, out=ga)\n        _batch_matmul_gpu(\n            a, gy[0], transa=not self.transa, transout=self.transb, out=gb)\n        ga = ga.reshape(a.shape)\n        gb = gb.reshape(b.shape)\n        return ga, gb\n\n\ndef batch_matmul(a, b, transa=False, transb=False):\n    \"\"\"Computes the batch matrix multiplications of two sets of arrays.\n\n    Args:\n        a (Variable): The left operand of the batch matrix multiplications.\n            A 2-D array of shape (B, N,) is considered as B Nx1 matrices.\n            A 3-D array of shape (B, M, N) is considered as B MxN matrices.\n        b (Variable): The right operand of the batch matrix multiplications.\n            Its array is treated as matrices in the same way as ``a``'s array.\n        transa (bool): If true, transpose each matrix in a.\n        transb (bool): If true, transpose each matrix in b.\n\n    Returns:\n        ~chainer.Variable: The result of the batch matrix multiplications as a\n            3-D array.\n    \"\"\"\n    return BatchMatMul(transa=transa, transb=transb)(a, b)\n", "path": "chainer/functions/math/matmul.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\ndef _mat_ptrs(a):\n    \"\"\"Creates an array of pointers to matrices\n\n    Args:\n        a: A batch of matrices on GPU\n    Returns:\n        GPU array of pointers to matrices\n    \"\"\"\n    if a.shape[0] == 1:\n        return cuda.cupy.full((1,), a[0].data.ptr, dtype=numpy.uintp)\n    else:\n        stride = a[1].data.ptr - a[0].data.ptr\n        return cuda.cupy.arange(\n            a[0].data.ptr,\n            a[0].data.ptr + stride * a.shape[0],\n            stride,\n            dtype=numpy.uintp)\n\n\ndef _as_mat(x):\n    return x.reshape((len(x), 1)) if len(x.shape) == 1 else x\n\n\ndef _as_batch_mat(x):\n    return x.reshape((x.shape[0], x.shape[1], 1)) if len(x.shape) == 2 else x\n\n\ndef _matmul(a, b, transa=False, transb=False, transout=False):\n    a = _as_mat(a)\n    b = _as_mat(b)\n    if transa:\n        a = a.T\n    if transb:\n        b = b.T\n    if transout:\n        # (A B)^T = B^T A^T\n        a, b = b.T, a.T\n    return a.dot(b)\n\n\ndef _get_ld(a):\n    shape = a.shape[-2:]\n    strides = a.strides[-2:]\n    trans = numpy.argmin(strides)\n    return trans, int(max(shape[trans], max(strides) // a.itemsize))\n\n\ndef _batch_matmul_gpu(a, b, out, transa=False, transb=False, transout=False):\n    a = _as_batch_mat(a)\n    b = _as_batch_mat(b)\n    trans_axis = (0, 2, 1)\n    if transout:\n        out = out.transpose(trans_axis)\n    needtrans, _ = _get_ld(out)\n    if needtrans == 1:\n        # (A B)^T = B^T A^T\n        a, b = b, a\n        transa, transb = not transb, not transa\n        out = out.transpose(trans_axis)\n    if transa:\n        a = a.transpose(trans_axis)\n    if transb:\n        b = b.transpose(trans_axis)\n\n    transa, lda = _get_ld(a)\n    transb, ldb = _get_ld(b)\n    transout, ldout = _get_ld(out)\n    la, n, ka = a.shape\n    lb, kb, m = b.shape\n\n    assert ka == kb\n    assert transout == 0 or ldout == 1\n    assert out.shape == (la, n, m)\n\n    ap = _mat_ptrs(a)\n    bp = _mat_ptrs(b)\n    outp = _mat_ptrs(out)\n    cuda.cublas.sgemmBatched(\n        cuda.Device().cublas_handle,\n        transa,\n        transb,\n        n, m, ka, 1.0,\n        ap.data.ptr, lda,\n        bp.data.ptr, ldb,\n        0.0, outp.data.ptr, ldout, la)\n\n\ndef _check_ndim(in_type, lower=1, upper=2):\n    type_check.expect(\n        in_type.ndim >= lower,\n        in_type.ndim <= upper\n    )\n\n\ndef _convert_type(in_type, vector_ndim=1):\n    if in_type.ndim.eval() == vector_ndim:\n        in_type = type_check.Variable(\n            type_check.TypeInfo(in_type.shape.eval() + (1,),\n                                in_type.dtype),\n            '%s(1-D array)' % in_type.name)\n    else:\n        in_type.name = '%s(2-D array)' % in_type.name\n    return in_type\n\n\ndef _get_check_index(trans, right, row_idx=0, col_idx=1):\n    if trans ^ right:\n        return row_idx\n    else:\n        return col_idx\n\n\nclass MatMul(function.Function):\n    def __init__(self, transa=False, transb=False):\n        self.transa = transa\n        self.transb = transb\n\n    def check_type_forward(self, in_types):\n        type_check.expect(in_types.size() == 2)\n        a_type, b_type = in_types\n\n        type_check.expect(\n            a_type.dtype == numpy.float32,\n            b_type.dtype == numpy.float32\n        )\n\n        _check_ndim(a_type)\n        _check_ndim(b_type)\n\n        a_type = _convert_type(a_type)\n        b_type = _convert_type(b_type)\n        a_idx = _get_check_index(self.transa, False)\n        b_idx = _get_check_index(self.transb, True)\n        type_check.expect(\n            a_type.shape[a_idx] == b_type.shape[b_idx]\n        )\n\n    def forward(self, x):\n        return _matmul(x[0], x[1], transa=self.transa, transb=self.transb),\n\n    def backward(self, x, gy):\n        gx0 = _matmul(\n            gy[0], x[1], transb=not self.transb, transout=self.transa\n            ).reshape(x[0].shape)\n        gx1 = _matmul(\n            x[0], gy[0], transa=not self.transa, transout=self.transb\n            ).reshape(x[1].shape)\n        return gx0, gx1\n\n\ndef matmul(a, b, transa=False, transb=False):\n    \"\"\"Computes the matrix multiplication of two arrays.\n\n    Args:\n        a (Variable): The left operand of the matrix multiplication.\n            A 1-D array of shape (N,) is considered as an Nx1 matrix.\n            A 2-D array of shape (M, N) is considered as an MxN matrix.\n        b (Variable): The right operand of the matrix multiplication.\n            Its array is treated as a matrix in the same way as ``a``'s array.\n        transa (bool): If true, transpose a.\n        transb (bool): If true, transpose b.\n\n    Returns:\n        ~chainer.Variable: The result of the matrix multiplication as a 2-D\n            array.\n    \"\"\"\n    return MatMul(transa=transa, transb=transb)(a, b)\n\n\nclass BatchMatMul(function.Function):\n    def __init__(self, transa=False, transb=False):\n        self.transa = transa\n        self.transb = transb\n\n    def _output_shape(self, a, b):\n        batch_size = a.shape[0]\n        a_mat_shape = _as_mat(a[0]).shape\n        b_mat_shape = _as_mat(b[0]).shape\n        m = a_mat_shape[1 if self.transa else 0]\n        n = b_mat_shape[0 if self.transb else 1]\n        return (batch_size, m, n)\n\n    def check_type_forward(self, in_types):\n        type_check.expect(in_types.size() == 2)\n        a_type, b_type = in_types\n\n        type_check.expect(\n            a_type.dtype == numpy.float32,\n            b_type.dtype == numpy.float32\n        )\n\n        _check_ndim(a_type, lower=2, upper=3)\n        _check_ndim(b_type, lower=2, upper=3)\n\n        a_type = _convert_type(a_type, vector_ndim=2)\n        b_type = _convert_type(b_type, vector_ndim=2)\n        a_idx = _get_check_index(self.transa, False, row_idx=1, col_idx=2)\n        b_idx = _get_check_index(self.transb, True, row_idx=1, col_idx=2)\n        type_check.expect(\n            a_type.shape[a_idx] == b_type.shape[b_idx]\n        )\n\n    def forward_cpu(self, x):\n        a, b = x\n        batch_size = a.shape[0]\n        shape = self._output_shape(a, b)\n        ret_dtype = numpy.find_common_type([a.dtype, b.dtype], [])\n        ret = numpy.empty(shape, dtype=ret_dtype)\n        for i in six.moves.range(batch_size):\n            ret[i] = _matmul(\n                a[i], b[i], transa=self.transa, transb=self.transb)\n        return ret,\n\n    def backward_cpu(self, x, gy):\n        a, b = x\n        batch_size = a.shape[0]\n        ga = numpy.empty_like(a)\n        gb = numpy.empty_like(b)\n        for i in six.moves.range(batch_size):\n            ga[i] = _matmul(\n                gy[0][i], b[i], transb=not self.transb,\n                transout=self.transa).reshape(a[0].shape)\n            gb[i] = _matmul(\n                a[i], gy[0][i], transa=not self.transa,\n                transout=self.transb).reshape(b[0].shape)\n        return ga, gb\n\n    def forward_gpu(self, x):\n        a, b = x\n        shape = self._output_shape(a, b)\n        ret = cuda.zeros(shape)\n        _batch_matmul_gpu(\n            a, b, transa=self.transa, transb=self.transb, out=ret)\n        return ret,\n\n    def backward_gpu(self, x, gy):\n        a, b = x\n        batch_size = a.shape[0]\n        ga = cuda.empty((batch_size,) + _as_mat(a[0]).shape)\n        gb = cuda.empty((batch_size,) + _as_mat(b[0]).shape)\n        _batch_matmul_gpu(\n            gy[0], b, transb=not self.transb, transout=self.transa, out=ga)\n        _batch_matmul_gpu(\n            a, gy[0], transa=not self.transa, transout=self.transb, out=gb)\n        ga = ga.reshape(a.shape)\n        gb = gb.reshape(b.shape)\n        return ga, gb\n\n\ndef batch_matmul(a, b, transa=False, transb=False):\n    \"\"\"Computes the batch matrix multiplications of two sets of arrays.\n\n    Args:\n        a (Variable): The left operand of the batch matrix multiplications.\n            A 2-D array of shape (B, N,) is considered as B Nx1 matrices.\n            A 3-D array of shape (B, M, N) is considered as B MxN matrices.\n        b (Variable): The right operand of the batch matrix multiplications.\n            Its array is treated as matrices in the same way as ``a``'s array.\n        transa (bool): If true, transpose each matrix in a.\n        transb (bool): If true, transpose each matrix in b.\n\n    Returns:\n        ~chainer.Variable: The result of the batch matrix multiplications as a\n            3-D array.\n    \"\"\"\n    return BatchMatMul(transa=transa, transb=transb)(a, b)\n", "path": "chainer/functions/math/matmul.py"}]}