We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
UnicodeDecodeError in compiler.py
Reported here: https://stackoverflow.com/questions/45473903/unicodedecodeerror-when-i-use-cuda-to-train-dataset

Versions:
- chainer (2.0.2)
- cupy (1.0.2)

It seems `nvcc` generated non-UTF8 output.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cupy/cuda/compiler.py`
Content:
```
1 import hashlib
2 import os
3 import re
4 import shutil
5 import subprocess
6 import sys
7 import tempfile
8 
9 import six
10 
11 from cupy.cuda import device
12 from cupy.cuda import function
13 
14 
15 _nvcc_version = None
16 
17 
18 def _get_nvcc_version():
19     global _nvcc_version
20     if _nvcc_version is None:
21         cmd = ['nvcc', '--version']
22         _nvcc_version = _run_nvcc(cmd, '.')
23 
24     return _nvcc_version
25 
26 
27 def _get_arch():
28     cc = device.Device().compute_capability
29     return 'sm_%s' % cc
30 
31 
32 class TemporaryDirectory(object):
33 
34     def __enter__(self):
35         self.path = tempfile.mkdtemp()
36         return self.path
37 
38     def __exit__(self, exc_type, exc_value, traceback):
39         if exc_value is not None:
40             return
41 
42         for name in os.listdir(self.path):
43             os.unlink(os.path.join(self.path, name))
44         os.rmdir(self.path)
45 
46 
47 def _run_nvcc(cmd, cwd):
48     try:
49         return subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT)
50     except subprocess.CalledProcessError as e:
51         msg = ('`nvcc` command returns non-zero exit status. \n'
52                'command: {0}\n'
53                'return-code: {1}\n'
54                'stdout/stderr: \n'
55                '{2}'.format(e.cmd, e.returncode, e.output))
56         raise RuntimeError(msg)
57     except OSError as e:
58         msg = 'Failed to run `nvcc` command. ' \
59               'Check PATH environment variable: ' \
60               + str(e)
61         raise OSError(msg)
62 
63 
64 def nvcc(source, options=(), arch=None):
65     if not arch:
66         arch = _get_arch()
67     cmd = ['nvcc', '--cubin', '-arch', arch] + list(options)
68 
69     with TemporaryDirectory() as root_dir:
70         path = os.path.join(root_dir, 'kern')
71         cu_path = '%s.cu' % path
72         cubin_path = '%s.cubin' % path
73 
74         with open(cu_path, 'w') as cu_file:
75             cu_file.write(source)
76 
77         cmd.append(cu_path)
78         _run_nvcc(cmd, root_dir)
79 
80         with open(cubin_path, 'rb') as bin_file:
81             return bin_file.read()
82 
83 
84 def preprocess(source, options=()):
85     cmd = ['nvcc', '--preprocess'] + list(options)
86     with TemporaryDirectory() as root_dir:
87         path = os.path.join(root_dir, 'kern')
88         cu_path = '%s.cu' % path
89 
90         with open(cu_path, 'w') as cu_file:
91             cu_file.write(source)
92 
93         cmd.append(cu_path)
94         pp_src = _run_nvcc(cmd, root_dir)
95 
96         if isinstance(pp_src, six.binary_type):
97             pp_src = pp_src.decode('utf-8')
98         return re.sub('(?m)^#.*$', '', pp_src)
99 
100 
101 _default_cache_dir = os.path.expanduser('~/.cupy/kernel_cache')
102 
103 
104 def get_cache_dir():
105     return os.environ.get('CUPY_CACHE_DIR', _default_cache_dir)
106 
107 
108 _empty_file_preprocess_cache = {}
109 
110 
111 def compile_with_cache(source, options=(), arch=None, cache_dir=None):
112     global _empty_file_preprocess_cache
113     if cache_dir is None:
114         cache_dir = get_cache_dir()
115     if arch is None:
116         arch = _get_arch()
117 
118     if 'win32' == sys.platform:
119         options += ('-Xcompiler', '/wd 4819')
120         if sys.maxsize == 9223372036854775807:
121             options += '-m64',
122         elif sys.maxsize == 2147483647:
123             options += '-m32',
124 
125     env = (arch, options, _get_nvcc_version())
126     if '#include' in source:
127         pp_src = '%s %s' % (env, preprocess(source, options))
128     else:
129         base = _empty_file_preprocess_cache.get(env, None)
130         if base is None:
131             base = _empty_file_preprocess_cache[env] = preprocess('', options)
132         pp_src = '%s %s %s' % (env, base, source)
133 
134     if isinstance(pp_src, six.text_type):
135         pp_src = pp_src.encode('utf-8')
136     name = '%s_2.cubin' % hashlib.md5(pp_src).hexdigest()
137 
138     if not os.path.isdir(cache_dir):
139         try:
140             os.makedirs(cache_dir)
141         except OSError:
142             if not os.path.isdir(cache_dir):
143                 raise
144 
145     mod = function.Module()
146     # To handle conflicts in concurrent situation, we adopt lock-free method
147     # to avoid performance degradation.
148     path = os.path.join(cache_dir, name)
149     if os.path.exists(path):
150         with open(path, 'rb') as file:
151             data = file.read()
152         if len(data) >= 32:
153             hash = data[:32]
154             cubin = data[32:]
155             cubin_hash = six.b(hashlib.md5(cubin).hexdigest())
156             if hash == cubin_hash:
157                 mod.load(cubin)
158                 return mod
159 
160     cubin = nvcc(source, options, arch)
161     cubin_hash = six.b(hashlib.md5(cubin).hexdigest())
162 
163     # shutil.move is not atomic operation, so it could result in a corrupted
164     # file. We detect it by appending md5 hash at the beginning of each cache
165     # file. If the file is corrupted, it will be ignored next time it is read.
166     with tempfile.NamedTemporaryFile(dir=cache_dir, delete=False) as tf:
167         tf.write(cubin_hash)
168         tf.write(cubin)
169         temp_path = tf.name
170     shutil.move(temp_path, path)
171 
172     mod.load(cubin)
173     return mod
174
```
--- 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/cupy/cuda/compiler.py b/cupy/cuda/compiler.py
--- a/cupy/cuda/compiler.py
+++ b/cupy/cuda/compiler.py
@@ -93,9 +93,8 @@
         cmd.append(cu_path)
         pp_src = _run_nvcc(cmd, root_dir)
 
-        if isinstance(pp_src, six.binary_type):
-            pp_src = pp_src.decode('utf-8')
-        return re.sub('(?m)^#.*$', '', pp_src)
+        assert isinstance(pp_src, six.binary_type)
+        return re.sub(b'(?m)^#.*$', b'', pp_src)
 
 
 _default_cache_dir = os.path.expanduser('~/.cupy/kernel_cache')

{"golden_diff": "diff --git a/cupy/cuda/compiler.py b/cupy/cuda/compiler.py\n--- a/cupy/cuda/compiler.py\n+++ b/cupy/cuda/compiler.py\n@@ -93,9 +93,8 @@\n         cmd.append(cu_path)\n         pp_src = _run_nvcc(cmd, root_dir)\n \n-        if isinstance(pp_src, six.binary_type):\n-            pp_src = pp_src.decode('utf-8')\n-        return re.sub('(?m)^#.*$', '', pp_src)\n+        assert isinstance(pp_src, six.binary_type)\n+        return re.sub(b'(?m)^#.*$', b'', pp_src)\n \n \n _default_cache_dir = os.path.expanduser('~/.cupy/kernel_cache')\n", "issue": "UnicodeDecodeError in compiler.py\nReported here: https://stackoverflow.com/questions/45473903/unicodedecodeerror-when-i-use-cuda-to-train-dataset\r\n\r\nVersions:\r\n- chainer (2.0.2)\r\n- cupy (1.0.2)\r\n\r\nIt seems `nvcc` generated non-UTF8 output.\n", "before_files": [{"content": "import hashlib\nimport os\nimport re\nimport shutil\nimport subprocess\nimport sys\nimport tempfile\n\nimport six\n\nfrom cupy.cuda import device\nfrom cupy.cuda import function\n\n\n_nvcc_version = None\n\n\ndef _get_nvcc_version():\n    global _nvcc_version\n    if _nvcc_version is None:\n        cmd = ['nvcc', '--version']\n        _nvcc_version = _run_nvcc(cmd, '.')\n\n    return _nvcc_version\n\n\ndef _get_arch():\n    cc = device.Device().compute_capability\n    return 'sm_%s' % cc\n\n\nclass TemporaryDirectory(object):\n\n    def __enter__(self):\n        self.path = tempfile.mkdtemp()\n        return self.path\n\n    def __exit__(self, exc_type, exc_value, traceback):\n        if exc_value is not None:\n            return\n\n        for name in os.listdir(self.path):\n            os.unlink(os.path.join(self.path, name))\n        os.rmdir(self.path)\n\n\ndef _run_nvcc(cmd, cwd):\n    try:\n        return subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT)\n    except subprocess.CalledProcessError as e:\n        msg = ('`nvcc` command returns non-zero exit status. \\n'\n               'command: {0}\\n'\n               'return-code: {1}\\n'\n               'stdout/stderr: \\n'\n               '{2}'.format(e.cmd, e.returncode, e.output))\n        raise RuntimeError(msg)\n    except OSError as e:\n        msg = 'Failed to run `nvcc` command. ' \\\n              'Check PATH environment variable: ' \\\n              + str(e)\n        raise OSError(msg)\n\n\ndef nvcc(source, options=(), arch=None):\n    if not arch:\n        arch = _get_arch()\n    cmd = ['nvcc', '--cubin', '-arch', arch] + list(options)\n\n    with TemporaryDirectory() as root_dir:\n        path = os.path.join(root_dir, 'kern')\n        cu_path = '%s.cu' % path\n        cubin_path = '%s.cubin' % path\n\n        with open(cu_path, 'w') as cu_file:\n            cu_file.write(source)\n\n        cmd.append(cu_path)\n        _run_nvcc(cmd, root_dir)\n\n        with open(cubin_path, 'rb') as bin_file:\n            return bin_file.read()\n\n\ndef preprocess(source, options=()):\n    cmd = ['nvcc', '--preprocess'] + list(options)\n    with TemporaryDirectory() as root_dir:\n        path = os.path.join(root_dir, 'kern')\n        cu_path = '%s.cu' % path\n\n        with open(cu_path, 'w') as cu_file:\n            cu_file.write(source)\n\n        cmd.append(cu_path)\n        pp_src = _run_nvcc(cmd, root_dir)\n\n        if isinstance(pp_src, six.binary_type):\n            pp_src = pp_src.decode('utf-8')\n        return re.sub('(?m)^#.*$', '', pp_src)\n\n\n_default_cache_dir = os.path.expanduser('~/.cupy/kernel_cache')\n\n\ndef get_cache_dir():\n    return os.environ.get('CUPY_CACHE_DIR', _default_cache_dir)\n\n\n_empty_file_preprocess_cache = {}\n\n\ndef compile_with_cache(source, options=(), arch=None, cache_dir=None):\n    global _empty_file_preprocess_cache\n    if cache_dir is None:\n        cache_dir = get_cache_dir()\n    if arch is None:\n        arch = _get_arch()\n\n    if 'win32' == sys.platform:\n        options += ('-Xcompiler', '/wd 4819')\n        if sys.maxsize == 9223372036854775807:\n            options += '-m64',\n        elif sys.maxsize == 2147483647:\n            options += '-m32',\n\n    env = (arch, options, _get_nvcc_version())\n    if '#include' in source:\n        pp_src = '%s %s' % (env, preprocess(source, options))\n    else:\n        base = _empty_file_preprocess_cache.get(env, None)\n        if base is None:\n            base = _empty_file_preprocess_cache[env] = preprocess('', options)\n        pp_src = '%s %s %s' % (env, base, source)\n\n    if isinstance(pp_src, six.text_type):\n        pp_src = pp_src.encode('utf-8')\n    name = '%s_2.cubin' % hashlib.md5(pp_src).hexdigest()\n\n    if not os.path.isdir(cache_dir):\n        try:\n            os.makedirs(cache_dir)\n        except OSError:\n            if not os.path.isdir(cache_dir):\n                raise\n\n    mod = function.Module()\n    # To handle conflicts in concurrent situation, we adopt lock-free method\n    # to avoid performance degradation.\n    path = os.path.join(cache_dir, name)\n    if os.path.exists(path):\n        with open(path, 'rb') as file:\n            data = file.read()\n        if len(data) >= 32:\n            hash = data[:32]\n            cubin = data[32:]\n            cubin_hash = six.b(hashlib.md5(cubin).hexdigest())\n            if hash == cubin_hash:\n                mod.load(cubin)\n                return mod\n\n    cubin = nvcc(source, options, arch)\n    cubin_hash = six.b(hashlib.md5(cubin).hexdigest())\n\n    # shutil.move is not atomic operation, so it could result in a corrupted\n    # file. We detect it by appending md5 hash at the beginning of each cache\n    # file. If the file is corrupted, it will be ignored next time it is read.\n    with tempfile.NamedTemporaryFile(dir=cache_dir, delete=False) as tf:\n        tf.write(cubin_hash)\n        tf.write(cubin)\n        temp_path = tf.name\n    shutil.move(temp_path, path)\n\n    mod.load(cubin)\n    return mod\n", "path": "cupy/cuda/compiler.py"}], "after_files": [{"content": "import hashlib\nimport os\nimport re\nimport shutil\nimport subprocess\nimport sys\nimport tempfile\n\nimport six\n\nfrom cupy.cuda import device\nfrom cupy.cuda import function\n\n\n_nvcc_version = None\n\n\ndef _get_nvcc_version():\n    global _nvcc_version\n    if _nvcc_version is None:\n        cmd = ['nvcc', '--version']\n        _nvcc_version = _run_nvcc(cmd, '.')\n\n    return _nvcc_version\n\n\ndef _get_arch():\n    cc = device.Device().compute_capability\n    return 'sm_%s' % cc\n\n\nclass TemporaryDirectory(object):\n\n    def __enter__(self):\n        self.path = tempfile.mkdtemp()\n        return self.path\n\n    def __exit__(self, exc_type, exc_value, traceback):\n        if exc_value is not None:\n            return\n\n        for name in os.listdir(self.path):\n            os.unlink(os.path.join(self.path, name))\n        os.rmdir(self.path)\n\n\ndef _run_nvcc(cmd, cwd):\n    try:\n        return subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT)\n    except subprocess.CalledProcessError as e:\n        msg = ('`nvcc` command returns non-zero exit status. \\n'\n               'command: {0}\\n'\n               'return-code: {1}\\n'\n               'stdout/stderr: \\n'\n               '{2}'.format(e.cmd, e.returncode, e.output))\n        raise RuntimeError(msg)\n    except OSError as e:\n        msg = 'Failed to run `nvcc` command. ' \\\n              'Check PATH environment variable: ' \\\n              + str(e)\n        raise OSError(msg)\n\n\ndef nvcc(source, options=(), arch=None):\n    if not arch:\n        arch = _get_arch()\n    cmd = ['nvcc', '--cubin', '-arch', arch] + list(options)\n\n    with TemporaryDirectory() as root_dir:\n        path = os.path.join(root_dir, 'kern')\n        cu_path = '%s.cu' % path\n        cubin_path = '%s.cubin' % path\n\n        with open(cu_path, 'w') as cu_file:\n            cu_file.write(source)\n\n        cmd.append(cu_path)\n        _run_nvcc(cmd, root_dir)\n\n        with open(cubin_path, 'rb') as bin_file:\n            return bin_file.read()\n\n\ndef preprocess(source, options=()):\n    cmd = ['nvcc', '--preprocess'] + list(options)\n    with TemporaryDirectory() as root_dir:\n        path = os.path.join(root_dir, 'kern')\n        cu_path = '%s.cu' % path\n\n        with open(cu_path, 'w') as cu_file:\n            cu_file.write(source)\n\n        cmd.append(cu_path)\n        pp_src = _run_nvcc(cmd, root_dir)\n\n        assert isinstance(pp_src, six.binary_type)\n        return re.sub(b'(?m)^#.*$', b'', pp_src)\n\n\n_default_cache_dir = os.path.expanduser('~/.cupy/kernel_cache')\n\n\ndef get_cache_dir():\n    return os.environ.get('CUPY_CACHE_DIR', _default_cache_dir)\n\n\n_empty_file_preprocess_cache = {}\n\n\ndef compile_with_cache(source, options=(), arch=None, cache_dir=None):\n    global _empty_file_preprocess_cache\n    if cache_dir is None:\n        cache_dir = get_cache_dir()\n    if arch is None:\n        arch = _get_arch()\n\n    if 'win32' == sys.platform:\n        options += ('-Xcompiler', '/wd 4819')\n        if sys.maxsize == 9223372036854775807:\n            options += '-m64',\n        elif sys.maxsize == 2147483647:\n            options += '-m32',\n\n    env = (arch, options, _get_nvcc_version())\n    if '#include' in source:\n        pp_src = '%s %s' % (env, preprocess(source, options))\n    else:\n        base = _empty_file_preprocess_cache.get(env, None)\n        if base is None:\n            base = _empty_file_preprocess_cache[env] = preprocess('', options)\n        pp_src = '%s %s %s' % (env, base, source)\n\n    if isinstance(pp_src, six.text_type):\n        pp_src = pp_src.encode('utf-8')\n    name = '%s_2.cubin' % hashlib.md5(pp_src).hexdigest()\n\n    if not os.path.isdir(cache_dir):\n        try:\n            os.makedirs(cache_dir)\n        except OSError:\n            if not os.path.isdir(cache_dir):\n                raise\n\n    mod = function.Module()\n    # To handle conflicts in concurrent situation, we adopt lock-free method\n    # to avoid performance degradation.\n    path = os.path.join(cache_dir, name)\n    if os.path.exists(path):\n        with open(path, 'rb') as file:\n            data = file.read()\n        if len(data) >= 32:\n            hash = data[:32]\n            cubin = data[32:]\n            cubin_hash = six.b(hashlib.md5(cubin).hexdigest())\n            if hash == cubin_hash:\n                mod.load(cubin)\n                return mod\n\n    cubin = nvcc(source, options, arch)\n    cubin_hash = six.b(hashlib.md5(cubin).hexdigest())\n\n    # shutil.move is not atomic operation, so it could result in a corrupted\n    # file. We detect it by appending md5 hash at the beginning of each cache\n    # file. If the file is corrupted, it will be ignored next time it is read.\n    with tempfile.NamedTemporaryFile(dir=cache_dir, delete=False) as tf:\n        tf.write(cubin_hash)\n        tf.write(cubin)\n        temp_path = tf.name\n    shutil.move(temp_path, path)\n\n    mod.load(cubin)\n    return mod\n", "path": "cupy/cuda/compiler.py"}]}