We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
No validation for kernel name
 Although `ElementwiseKernel`'s `name` argument is directly used as a function name in generated CUDA code, there are no validation process to raise an exception when invalid characters are used in `name`.
That causes CUDA compile error, which is a bit difficult to debug.

--- 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 math
3 import os
4 import shutil
5 import sys
6 import tempfile
7 
8 import six
9 
10 from cupy.cuda import device
11 from cupy.cuda import function
12 from cupy.cuda import nvrtc
13 
14 _nvrtc_version = None
15 
16 
17 def _get_nvrtc_version():
18     global _nvrtc_version
19     if _nvrtc_version is None:
20         _nvrtc_version = nvrtc.getVersion()
21 
22     return _nvrtc_version
23 
24 
25 def _get_arch():
26     cc = device.Device().compute_capability
27     return 'compute_%s' % cc
28 
29 
30 class TemporaryDirectory(object):
31     def __enter__(self):
32         self.path = tempfile.mkdtemp()
33         return self.path
34 
35     def __exit__(self, exc_type, exc_value, traceback):
36         if exc_value is not None:
37             return
38 
39         for name in os.listdir(self.path):
40             os.unlink(os.path.join(self.path, name))
41         os.rmdir(self.path)
42 
43 
44 def _get_bool_env_variable(name, default):
45     val = os.environ.get(name)
46     if val is None or len(val) == 0:
47         return default
48     try:
49         return int(val) == 1
50     except ValueError:
51         return False
52 
53 
54 def compile_using_nvrtc(source, options=(), arch=None):
55     if not arch:
56         arch = _get_arch()
57 
58     options += ('-arch={}'.format(arch),)
59 
60     with TemporaryDirectory() as root_dir:
61         path = os.path.join(root_dir, 'kern')
62         cu_path = '%s.cu' % path
63 
64         with open(cu_path, 'w') as cu_file:
65             cu_file.write(source)
66 
67         prog = _NVRTCProgram(source, cu_path)
68         try:
69             ptx = prog.compile(options)
70         except CompileException as e:
71             dump = _get_bool_env_variable(
72                 'CUPY_DUMP_CUDA_SOURCE_ON_ERROR', False)
73             if dump:
74                 e.dump(sys.stderr)
75             raise
76 
77         return ptx
78 
79 
80 def _preprocess(source, options=()):
81     prog = _NVRTCProgram(source, '')
82     try:
83         result = prog.compile(options)
84     except CompileException as e:
85         dump = _get_bool_env_variable(
86             'CUPY_DUMP_CUDA_SOURCE_ON_ERROR', False)
87         if dump:
88             e.dump(sys.stderr)
89         raise
90 
91     assert isinstance(result, six.text_type)
92     return result
93 
94 
95 _default_cache_dir = os.path.expanduser('~/.cupy/kernel_cache')
96 
97 
98 def get_cache_dir():
99     return os.environ.get('CUPY_CACHE_DIR', _default_cache_dir)
100 
101 
102 _empty_file_preprocess_cache = {}
103 
104 
105 def compile_with_cache(source, options=(), arch=None, cache_dir=None,
106                        extra_source=None):
107     # NVRTC does not use extra_source. extra_source is used for cache key.
108     global _empty_file_preprocess_cache
109     if cache_dir is None:
110         cache_dir = get_cache_dir()
111     if arch is None:
112         arch = _get_arch()
113 
114     options += ('-ftz=true',)
115 
116     env = (arch, options, _get_nvrtc_version())
117     base = _empty_file_preprocess_cache.get(env, None)
118     if base is None:
119         # This is checking of NVRTC compiler internal version
120         base = _empty_file_preprocess_cache[env] = _preprocess('', options)
121     key_src = '%s %s %s %s' % (env, base, source, extra_source)
122 
123     key_src = key_src.encode('utf-8')
124     name = '%s_2.cubin' % hashlib.md5(key_src).hexdigest()
125 
126     if not os.path.isdir(cache_dir):
127         try:
128             os.makedirs(cache_dir)
129         except OSError:
130             if not os.path.isdir(cache_dir):
131                 raise
132 
133     mod = function.Module()
134     # To handle conflicts in concurrent situation, we adopt lock-free method
135     # to avoid performance degradation.
136     path = os.path.join(cache_dir, name)
137     if os.path.exists(path):
138         with open(path, 'rb') as file:
139             data = file.read()
140         if len(data) >= 32:
141             hash = data[:32]
142             cubin = data[32:]
143             cubin_hash = six.b(hashlib.md5(cubin).hexdigest())
144             if hash == cubin_hash:
145                 mod.load(cubin)
146                 return mod
147 
148     ptx = compile_using_nvrtc(source, options, arch)
149     ls = function.LinkState()
150     ls.add_ptr_data(ptx, six.u('cupy.ptx'))
151     cubin = ls.complete()
152     cubin_hash = six.b(hashlib.md5(cubin).hexdigest())
153 
154     # shutil.move is not atomic operation, so it could result in a corrupted
155     # file. We detect it by appending md5 hash at the beginning of each cache
156     # file. If the file is corrupted, it will be ignored next time it is read.
157     with tempfile.NamedTemporaryFile(dir=cache_dir, delete=False) as tf:
158         tf.write(cubin_hash)
159         tf.write(cubin)
160         temp_path = tf.name
161     shutil.move(temp_path, path)
162 
163     # Save .cu source file along with .cubin
164     if _get_bool_env_variable('CUPY_CACHE_SAVE_CUDA_SOURCE', False):
165         with open(path + '.cu', 'w') as f:
166             f.write(source)
167 
168     mod.load(cubin)
169     return mod
170 
171 
172 class CompileException(Exception):
173 
174     def __init__(self, msg, source, name, options):
175         self._msg = msg
176         self.source = source
177         self.name = name
178         self.options = options
179 
180     def __repr__(self):
181         return str(self)
182 
183     def __str__(self):
184         return self.get_message()
185 
186     def get_message(self):
187         return self._msg
188 
189     def dump(self, f):
190         lines = self.source.split('\n')
191         digits = int(math.floor(math.log10(len(lines)))) + 1
192         linum_fmt = '{{:0{}d}} '.format(digits)
193         f.write('NVRTC compilation error: {}\n'.format(self))
194         f.write('-----\n')
195         f.write('Name: {}\n'.format(' '.join(self.name)))
196         f.write('Options: {}\n'.format(' '.join(self.options)))
197         f.write('CUDA source:\n')
198         for i, line in enumerate(lines):
199             f.write(linum_fmt.format(i + 1) + line.rstrip() + '\n')
200         f.write('-----\n')
201         f.flush()
202 
203 
204 class _NVRTCProgram(object):
205 
206     def __init__(self, src, name="default_program", headers=(),
207                  include_names=()):
208         self.ptr = None
209 
210         if isinstance(src, six.binary_type):
211             src = src.decode('UTF-8')
212         if isinstance(name, six.binary_type):
213             name = name.decode('UTF-8')
214 
215         self.src = src
216         self.name = name
217         self.ptr = nvrtc.createProgram(src, name, headers, include_names)
218 
219     def __del__(self):
220         if self.ptr:
221             nvrtc.destroyProgram(self.ptr)
222 
223     def compile(self, options=()):
224         try:
225             nvrtc.compileProgram(self.ptr, options)
226             return nvrtc.getPTX(self.ptr)
227         except nvrtc.NVRTCError:
228             log = nvrtc.getProgramLog(self.ptr)
229             raise CompileException(log, self.src, self.name, options)
230
```
--- 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
@@ -1,6 +1,7 @@
 import hashlib
 import math
 import os
+import re
 import shutil
 import sys
 import tempfile
@@ -227,3 +228,7 @@
         except nvrtc.NVRTCError:
             log = nvrtc.getProgramLog(self.ptr)
             raise CompileException(log, self.src, self.name, options)
+
+
+def is_valid_kernel_name(name):
+    return re.match('^[a-zA-Z_][a-zA-Z_0-9]*$', name) is not None

{"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@@ -1,6 +1,7 @@\n import hashlib\n import math\n import os\n+import re\n import shutil\n import sys\n import tempfile\n@@ -227,3 +228,7 @@\n         except nvrtc.NVRTCError:\n             log = nvrtc.getProgramLog(self.ptr)\n             raise CompileException(log, self.src, self.name, options)\n+\n+\n+def is_valid_kernel_name(name):\n+    return re.match('^[a-zA-Z_][a-zA-Z_0-9]*$', name) is not None\n", "issue": "No validation for kernel name\n Although `ElementwiseKernel`'s `name` argument is directly used as a function name in generated CUDA code, there are no validation process to raise an exception when invalid characters are used in `name`.\r\nThat causes CUDA compile error, which is a bit difficult to debug.\n", "before_files": [{"content": "import hashlib\nimport math\nimport os\nimport shutil\nimport sys\nimport tempfile\n\nimport six\n\nfrom cupy.cuda import device\nfrom cupy.cuda import function\nfrom cupy.cuda import nvrtc\n\n_nvrtc_version = None\n\n\ndef _get_nvrtc_version():\n    global _nvrtc_version\n    if _nvrtc_version is None:\n        _nvrtc_version = nvrtc.getVersion()\n\n    return _nvrtc_version\n\n\ndef _get_arch():\n    cc = device.Device().compute_capability\n    return 'compute_%s' % cc\n\n\nclass TemporaryDirectory(object):\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 _get_bool_env_variable(name, default):\n    val = os.environ.get(name)\n    if val is None or len(val) == 0:\n        return default\n    try:\n        return int(val) == 1\n    except ValueError:\n        return False\n\n\ndef compile_using_nvrtc(source, options=(), arch=None):\n    if not arch:\n        arch = _get_arch()\n\n    options += ('-arch={}'.format(arch),)\n\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        prog = _NVRTCProgram(source, cu_path)\n        try:\n            ptx = prog.compile(options)\n        except CompileException as e:\n            dump = _get_bool_env_variable(\n                'CUPY_DUMP_CUDA_SOURCE_ON_ERROR', False)\n            if dump:\n                e.dump(sys.stderr)\n            raise\n\n        return ptx\n\n\ndef _preprocess(source, options=()):\n    prog = _NVRTCProgram(source, '')\n    try:\n        result = prog.compile(options)\n    except CompileException as e:\n        dump = _get_bool_env_variable(\n            'CUPY_DUMP_CUDA_SOURCE_ON_ERROR', False)\n        if dump:\n            e.dump(sys.stderr)\n        raise\n\n    assert isinstance(result, six.text_type)\n    return result\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                       extra_source=None):\n    # NVRTC does not use extra_source. extra_source is used for cache key.\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    options += ('-ftz=true',)\n\n    env = (arch, options, _get_nvrtc_version())\n    base = _empty_file_preprocess_cache.get(env, None)\n    if base is None:\n        # This is checking of NVRTC compiler internal version\n        base = _empty_file_preprocess_cache[env] = _preprocess('', options)\n    key_src = '%s %s %s %s' % (env, base, source, extra_source)\n\n    key_src = key_src.encode('utf-8')\n    name = '%s_2.cubin' % hashlib.md5(key_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    ptx = compile_using_nvrtc(source, options, arch)\n    ls = function.LinkState()\n    ls.add_ptr_data(ptx, six.u('cupy.ptx'))\n    cubin = ls.complete()\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    # Save .cu source file along with .cubin\n    if _get_bool_env_variable('CUPY_CACHE_SAVE_CUDA_SOURCE', False):\n        with open(path + '.cu', 'w') as f:\n            f.write(source)\n\n    mod.load(cubin)\n    return mod\n\n\nclass CompileException(Exception):\n\n    def __init__(self, msg, source, name, options):\n        self._msg = msg\n        self.source = source\n        self.name = name\n        self.options = options\n\n    def __repr__(self):\n        return str(self)\n\n    def __str__(self):\n        return self.get_message()\n\n    def get_message(self):\n        return self._msg\n\n    def dump(self, f):\n        lines = self.source.split('\\n')\n        digits = int(math.floor(math.log10(len(lines)))) + 1\n        linum_fmt = '{{:0{}d}} '.format(digits)\n        f.write('NVRTC compilation error: {}\\n'.format(self))\n        f.write('-----\\n')\n        f.write('Name: {}\\n'.format(' '.join(self.name)))\n        f.write('Options: {}\\n'.format(' '.join(self.options)))\n        f.write('CUDA source:\\n')\n        for i, line in enumerate(lines):\n            f.write(linum_fmt.format(i + 1) + line.rstrip() + '\\n')\n        f.write('-----\\n')\n        f.flush()\n\n\nclass _NVRTCProgram(object):\n\n    def __init__(self, src, name=\"default_program\", headers=(),\n                 include_names=()):\n        self.ptr = None\n\n        if isinstance(src, six.binary_type):\n            src = src.decode('UTF-8')\n        if isinstance(name, six.binary_type):\n            name = name.decode('UTF-8')\n\n        self.src = src\n        self.name = name\n        self.ptr = nvrtc.createProgram(src, name, headers, include_names)\n\n    def __del__(self):\n        if self.ptr:\n            nvrtc.destroyProgram(self.ptr)\n\n    def compile(self, options=()):\n        try:\n            nvrtc.compileProgram(self.ptr, options)\n            return nvrtc.getPTX(self.ptr)\n        except nvrtc.NVRTCError:\n            log = nvrtc.getProgramLog(self.ptr)\n            raise CompileException(log, self.src, self.name, options)\n", "path": "cupy/cuda/compiler.py"}], "after_files": [{"content": "import hashlib\nimport math\nimport os\nimport re\nimport shutil\nimport sys\nimport tempfile\n\nimport six\n\nfrom cupy.cuda import device\nfrom cupy.cuda import function\nfrom cupy.cuda import nvrtc\n\n_nvrtc_version = None\n\n\ndef _get_nvrtc_version():\n    global _nvrtc_version\n    if _nvrtc_version is None:\n        _nvrtc_version = nvrtc.getVersion()\n\n    return _nvrtc_version\n\n\ndef _get_arch():\n    cc = device.Device().compute_capability\n    return 'compute_%s' % cc\n\n\nclass TemporaryDirectory(object):\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 _get_bool_env_variable(name, default):\n    val = os.environ.get(name)\n    if val is None or len(val) == 0:\n        return default\n    try:\n        return int(val) == 1\n    except ValueError:\n        return False\n\n\ndef compile_using_nvrtc(source, options=(), arch=None):\n    if not arch:\n        arch = _get_arch()\n\n    options += ('-arch={}'.format(arch),)\n\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        prog = _NVRTCProgram(source, cu_path)\n        try:\n            ptx = prog.compile(options)\n        except CompileException as e:\n            dump = _get_bool_env_variable(\n                'CUPY_DUMP_CUDA_SOURCE_ON_ERROR', False)\n            if dump:\n                e.dump(sys.stderr)\n            raise\n\n        return ptx\n\n\ndef _preprocess(source, options=()):\n    prog = _NVRTCProgram(source, '')\n    try:\n        result = prog.compile(options)\n    except CompileException as e:\n        dump = _get_bool_env_variable(\n            'CUPY_DUMP_CUDA_SOURCE_ON_ERROR', False)\n        if dump:\n            e.dump(sys.stderr)\n        raise\n\n    assert isinstance(result, six.text_type)\n    return result\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                       extra_source=None):\n    # NVRTC does not use extra_source. extra_source is used for cache key.\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    options += ('-ftz=true',)\n\n    env = (arch, options, _get_nvrtc_version())\n    base = _empty_file_preprocess_cache.get(env, None)\n    if base is None:\n        # This is checking of NVRTC compiler internal version\n        base = _empty_file_preprocess_cache[env] = _preprocess('', options)\n    key_src = '%s %s %s %s' % (env, base, source, extra_source)\n\n    key_src = key_src.encode('utf-8')\n    name = '%s_2.cubin' % hashlib.md5(key_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    ptx = compile_using_nvrtc(source, options, arch)\n    ls = function.LinkState()\n    ls.add_ptr_data(ptx, six.u('cupy.ptx'))\n    cubin = ls.complete()\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    # Save .cu source file along with .cubin\n    if _get_bool_env_variable('CUPY_CACHE_SAVE_CUDA_SOURCE', False):\n        with open(path + '.cu', 'w') as f:\n            f.write(source)\n\n    mod.load(cubin)\n    return mod\n\n\nclass CompileException(Exception):\n\n    def __init__(self, msg, source, name, options):\n        self._msg = msg\n        self.source = source\n        self.name = name\n        self.options = options\n\n    def __repr__(self):\n        return str(self)\n\n    def __str__(self):\n        return self.get_message()\n\n    def get_message(self):\n        return self._msg\n\n    def dump(self, f):\n        lines = self.source.split('\\n')\n        digits = int(math.floor(math.log10(len(lines)))) + 1\n        linum_fmt = '{{:0{}d}} '.format(digits)\n        f.write('NVRTC compilation error: {}\\n'.format(self))\n        f.write('-----\\n')\n        f.write('Name: {}\\n'.format(' '.join(self.name)))\n        f.write('Options: {}\\n'.format(' '.join(self.options)))\n        f.write('CUDA source:\\n')\n        for i, line in enumerate(lines):\n            f.write(linum_fmt.format(i + 1) + line.rstrip() + '\\n')\n        f.write('-----\\n')\n        f.flush()\n\n\nclass _NVRTCProgram(object):\n\n    def __init__(self, src, name=\"default_program\", headers=(),\n                 include_names=()):\n        self.ptr = None\n\n        if isinstance(src, six.binary_type):\n            src = src.decode('UTF-8')\n        if isinstance(name, six.binary_type):\n            name = name.decode('UTF-8')\n\n        self.src = src\n        self.name = name\n        self.ptr = nvrtc.createProgram(src, name, headers, include_names)\n\n    def __del__(self):\n        if self.ptr:\n            nvrtc.destroyProgram(self.ptr)\n\n    def compile(self, options=()):\n        try:\n            nvrtc.compileProgram(self.ptr, options)\n            return nvrtc.getPTX(self.ptr)\n        except nvrtc.NVRTCError:\n            log = nvrtc.getProgramLog(self.ptr)\n            raise CompileException(log, self.src, self.name, options)\n\n\ndef is_valid_kernel_name(name):\n    return re.match('^[a-zA-Z_][a-zA-Z_0-9]*$', name) is not None\n", "path": "cupy/cuda/compiler.py"}]}