kernel-tuner 0.1.1__tar.gz → 0.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/MANIFEST.in +1 -1
  2. kernel_tuner-0.1.2/PKG-INFO +232 -0
  3. kernel_tuner-0.1.2/README.rst +208 -0
  4. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/kernel_tuner/c.py +28 -6
  5. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/kernel_tuner/core.py +23 -2
  6. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/kernel_tuner/cuda.py +10 -1
  7. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/kernel_tuner/interface.py +83 -123
  8. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/kernel_tuner/runners/random_sample.py +3 -3
  9. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/kernel_tuner/runners/sequential_brute_force.py +10 -3
  10. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/kernel_tuner/util.py +34 -21
  11. kernel_tuner-0.1.2/kernel_tuner.egg-info/PKG-INFO +232 -0
  12. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/kernel_tuner.egg-info/SOURCES.txt +1 -1
  13. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/requirements.txt +2 -1
  14. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/setup.cfg +1 -1
  15. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/setup.py +6 -2
  16. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/test/test_c_functions.py +0 -1
  17. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/test/test_cuda_functions.py +1 -1
  18. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/test/test_cuda_mocked.py +0 -1
  19. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/test/test_interface.py +4 -5
  20. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/test/test_kernel_tuner.py +28 -31
  21. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/test/test_opencl_functions.py +1 -3
  22. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/test/test_runners.py +1 -4
  23. kernel_tuner-0.1.1/PKG-INFO +0 -136
  24. kernel_tuner-0.1.1/README.md +0 -142
  25. kernel_tuner-0.1.1/kernel_tuner.egg-info/PKG-INFO +0 -136
  26. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/LICENSE +0 -0
  27. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/kernel_tuner/__init__.py +0 -0
  28. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/kernel_tuner/opencl.py +0 -0
  29. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/kernel_tuner/runners/__init__.py +0 -0
  30. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/kernel_tuner.egg-info/dependency_links.txt +0 -0
  31. {kernel_tuner-0.1.1 → kernel_tuner-0.1.2}/kernel_tuner.egg-info/top_level.txt +0 -0
@@ -1,3 +1,3 @@
1
1
  include setup.py
2
2
  include LICENSE
3
- include README.md
3
+ include README.rst
@@ -0,0 +1,232 @@
1
+ Metadata-Version: 1.1
2
+ Name: kernel_tuner
3
+ Version: 0.1.2
4
+ Summary: A simple CUDA/OpenCL kernel tuner in Python
5
+ Home-page: http://benvanwerkhoven.github.io/kernel_tuner/
6
+ Author: Ben van Werkhoven
7
+ Author-email: b.vanwerkhoven@esciencecenter.nl
8
+ License: Apache 2.0
9
+ Description: A simple CUDA/OpenCL kernel tuner in Python
10
+ ===========================================
11
+
12
+ |Build Status| |Codacy Badge| |Codacy Badge2|
13
+
14
+ The goal of this project is to provide a - as simple as possible - tool
15
+ for tuning CUDA and OpenCL kernels. This implies that any CUDA or OpenCL
16
+ kernel can be tuned without requiring extensive changes to the original
17
+ kernel code.
18
+
19
+ A very common problem in GPU programming is that some combination of
20
+ thread block dimensions and other kernel parameters, like tiling or
21
+ unrolling factors, results in dramatically better performance than other
22
+ kernel configurations. The goal of auto-tuning is to automate the
23
+ process of finding the best performing configuration for a given device.
24
+
25
+ This kernel tuner aims that you can directly use the tuned kernel
26
+ without introducing any new dependencies. The tuned kernels can
27
+ afterwards be used independently of the programming environment, whether
28
+ that is using C/C++/Java/Fortran or Python doesn't matter.
29
+
30
+ The kernel\_tuner module currently only contains main one function which
31
+ is called tune\_kernel to which you pass at least the kernel name, a
32
+ string containing the kernel code, the problem size, a list of kernel
33
+ function arguments, and a dictionary of tunable parameters. There are
34
+ also a lot of optional parameters, for a complete list see the full
35
+ documentation of
36
+ `tune\_kernel <http://benvanwerkhoven.github.io/kernel_tuner/details.html>`__.
37
+
38
+ Documentation
39
+ -------------
40
+
41
+ The full documentation is available
42
+ `here <http://benvanwerkhoven.github.io/kernel_tuner/index.html>`__.
43
+
44
+ Installation
45
+ ------------
46
+
47
+ To install from PyPi:
48
+
49
+ - ``pip install kernel_tuner``
50
+
51
+ To install from the source (and get the tutorial and examples):
52
+
53
+ - clone the repository
54
+
55
+ - With a GitHub account: ``git clone git@github.com:benvanwerkhoven/kernel_tuner.git``
56
+ - Without GitHub account: ``git clone https://github.com/benvanwerkhoven/kernel_tuner.git``
57
+
58
+ - change into the top-level directory
59
+
60
+ - ``cd kernel_tuner``
61
+
62
+ - install using
63
+
64
+ - ``pip install .``
65
+
66
+ Dependencies
67
+ ------------
68
+ Python 2.7 or Python 3.5
69
+
70
+ PyCuda and/or PyOpenCL (https://mathema.tician.de/software/)
71
+
72
+ - To tune CUDA kernels
73
+
74
+ - Make sure you have the `CUDA Toolkit <https://developer.nvidia.com/cuda-toolkit>`_ installed
75
+ - You can install PyCuda using ``pip install pycuda``
76
+
77
+ - To tune OpenCL kernels
78
+
79
+ - Make sure you have an OpenCL compiler for your intended OpenCL platform
80
+ - You can install PyOpenCL using ``pip install pyopencl``
81
+
82
+ Example usage
83
+ -------------
84
+
85
+ The following shows a simple example for tuning a CUDA kernel:
86
+
87
+ .. code:: python
88
+
89
+ kernel_string = """
90
+ __global__ void vector_add(float *c, float *a, float *b, int n) {
91
+ int i = blockIdx.x * block_size_x + threadIdx.x;
92
+ if (i<n) {
93
+ c[i] = a[i] + b[i];
94
+ }
95
+ }
96
+ """
97
+
98
+ size = 10000000
99
+
100
+ a = numpy.random.randn(size).astype(numpy.float32)
101
+ b = numpy.random.randn(size).astype(numpy.float32)
102
+ c = numpy.zeros_like(b)
103
+ n = numpy.int32(size)
104
+ args = [c, a, b, n]
105
+
106
+ tune_params = dict()
107
+ tune_params["block_size_x"] = [128+64*i for i in range(15)]
108
+
109
+ tune_kernel("vector_add", kernel_string, size, args, tune_params)
110
+
111
+ The exact same Python code can be used to tune an OpenCL kernel:
112
+
113
+ .. code:: python
114
+
115
+ kernel_string = """
116
+ __kernel void vector_add(__global float *c, __global float *a, __global float *b, int n) {
117
+ int i = get_global_id(0);
118
+ if (i<n) {
119
+ c[i] = a[i] + b[i];
120
+ }
121
+ }
122
+ """
123
+
124
+ Or even just a C function, see the example
125
+ `here <https://github.com/benvanwerkhoven/kernel_tuner/blob/master/examples/c/vector_add.py>`__.
126
+
127
+ You can find these and many - more extensive - example codes, in the
128
+ `examples <https://github.com/benvanwerkhoven/kernel_tuner/blob/master/examples/>`__
129
+ directory.
130
+
131
+ See the `full
132
+ documentation <http://benvanwerkhoven.github.io/kernel_tuner/index.html>`__
133
+ for several highly detailed tutorial-style explanations of example
134
+ kernels and the scripts to tune them.
135
+
136
+ Tuning host and kernel code
137
+ ---------------------------
138
+
139
+ It is also possible to tune for combinations of tunable parameters in
140
+ both host and kernel code. This allows for a number of powerfull things,
141
+ such as tuning the number of streams for a kernel that uses CUDA Streams
142
+ or OpenCL Command Queues to overlap transfers between host and device
143
+ with kernel execution. This can be done in combination with tuning the
144
+ parameters inside the kernel code. See the `convolution\_streams example
145
+ code <https://github.com/benvanwerkhoven/kernel_tuner/blob/master/examples/>`__
146
+ and the
147
+ `documentation <http://benvanwerkhoven.github.io/kernel_tuner/hostcode.html>`__
148
+ for a detailed explanation of the kernel tuner Python script.
149
+
150
+ Correctness verification
151
+ ------------------------
152
+
153
+ Optionally, you can let the kernel tuner verify the output of every
154
+ kernel it compiles and benchmarks, by passing an ``answer`` list. This
155
+ list matches the list of arguments to the kernel, but contains the
156
+ expected output of the kernel. Input arguments are replaced with None.
157
+
158
+ .. code:: python
159
+
160
+ answer = [a+b, None, None] # the order matches the arguments (in args) to the kernel
161
+ tune_kernel("vector_add", kernel_string, size, args, tune_params, answer=answer)
162
+
163
+ Contribution guide
164
+ ------------------
165
+
166
+ The kernel tuner follows the Google Python style guide, with Sphinxdoc
167
+ docstrings for module public functions. If you want to contribute to the
168
+ project please fork it, create a branch including your addition, and
169
+ create a pull request.
170
+
171
+ The tests use relative imports and can be run directly after making
172
+ changes to the code. To run all tests use ``nosetests`` in the main
173
+ directory. To run the examples after code changes, you need to run
174
+ ``pip install --upgrade .`` in the main directory. Documentation is
175
+ generated by typing ``make html`` in the doc directory, the contents of
176
+ ``doc/build/html/`` should then be copied to ``sphinxdoc`` directory of
177
+ the ``gh-pages`` branch.
178
+
179
+ Before creating a pull request please ensure the following:
180
+
181
+ * You have written unit tests to test your additions and all unit tests pass
182
+ * The examples still work and produce the same (or better) results
183
+ * The code is compatible with both Python 2.7 and Python 3.5
184
+ * An entry about the change or addition is created in CHANGELOG.md
185
+
186
+ Contributing authors so far:
187
+
188
+ * Ben van Werkhoven
189
+ * Berend Weel
190
+
191
+ Citation
192
+ --------
193
+ A scientific paper about the Kernel Tuner is in preparation, in the meantime please cite the Kernel Tuner as follows:
194
+
195
+ .. code:: latex
196
+
197
+ @misc{
198
+ author = {Ben van Werkhoven},
199
+ title = {Kernel Tuner: A simple CUDA/OpenCL Kernel Tuner in Python},
200
+ year = {2017}
201
+ }
202
+
203
+ Related work
204
+ ------------
205
+
206
+ You may also like `CLTune <https://github.com/CNugteren/CLTune>`__ by
207
+ Cedric Nugteren. CLTune is a C++ library for kernel tuning and supports
208
+ various advanced features like machine learning to optimize the time
209
+ spent on tuning kernels.
210
+
211
+ .. |Build Status| image:: https://api.travis-ci.org/benvanwerkhoven/kernel_tuner.svg?branch=master
212
+ :target: https://travis-ci.org/benvanwerkhoven/kernel_tuner
213
+ .. |Codacy Badge| image:: https://api.codacy.com/project/badge/grade/016dc85044ab4d57b777449d93275608
214
+ :target: https://www.codacy.com/app/b-vanwerkhoven/kernel_tuner
215
+ .. |Codacy Badge2| image:: https://api.codacy.com/project/badge/coverage/016dc85044ab4d57b777449d93275608
216
+ :target: https://www.codacy.com/app/b-vanwerkhoven/kernel_tuner
217
+
218
+ Keywords: auto-tuning gpu computing pycuda cuda pyopencl opencl
219
+ Platform: UNKNOWN
220
+ Classifier: Environment :: Console
221
+ Classifier: Intended Audience :: Developers
222
+ Classifier: Intended Audience :: Science/Research
223
+ Classifier: Intended Audience :: Education
224
+ Classifier: License :: OSI Approved :: Apache Software License
225
+ Classifier: Natural Language :: English
226
+ Classifier: Operating System :: POSIX :: Linux
227
+ Classifier: Programming Language :: Python :: 2.7
228
+ Classifier: Programming Language :: Python :: 3.5
229
+ Classifier: Topic :: Scientific/Engineering
230
+ Classifier: Topic :: Software Development
231
+ Classifier: Topic :: System :: Distributed Computing
232
+ Classifier: Development Status :: 4 - Beta
@@ -0,0 +1,208 @@
1
+ A simple CUDA/OpenCL kernel tuner in Python
2
+ ===========================================
3
+
4
+ |Build Status| |Codacy Badge| |Codacy Badge2|
5
+
6
+ The goal of this project is to provide a - as simple as possible - tool
7
+ for tuning CUDA and OpenCL kernels. This implies that any CUDA or OpenCL
8
+ kernel can be tuned without requiring extensive changes to the original
9
+ kernel code.
10
+
11
+ A very common problem in GPU programming is that some combination of
12
+ thread block dimensions and other kernel parameters, like tiling or
13
+ unrolling factors, results in dramatically better performance than other
14
+ kernel configurations. The goal of auto-tuning is to automate the
15
+ process of finding the best performing configuration for a given device.
16
+
17
+ This kernel tuner aims that you can directly use the tuned kernel
18
+ without introducing any new dependencies. The tuned kernels can
19
+ afterwards be used independently of the programming environment, whether
20
+ that is using C/C++/Java/Fortran or Python doesn't matter.
21
+
22
+ The kernel\_tuner module currently only contains main one function which
23
+ is called tune\_kernel to which you pass at least the kernel name, a
24
+ string containing the kernel code, the problem size, a list of kernel
25
+ function arguments, and a dictionary of tunable parameters. There are
26
+ also a lot of optional parameters, for a complete list see the full
27
+ documentation of
28
+ `tune\_kernel <http://benvanwerkhoven.github.io/kernel_tuner/details.html>`__.
29
+
30
+ Documentation
31
+ -------------
32
+
33
+ The full documentation is available
34
+ `here <http://benvanwerkhoven.github.io/kernel_tuner/index.html>`__.
35
+
36
+ Installation
37
+ ------------
38
+
39
+ To install from PyPi:
40
+
41
+ - ``pip install kernel_tuner``
42
+
43
+ To install from the source (and get the tutorial and examples):
44
+
45
+ - clone the repository
46
+
47
+ - With a GitHub account: ``git clone git@github.com:benvanwerkhoven/kernel_tuner.git``
48
+ - Without GitHub account: ``git clone https://github.com/benvanwerkhoven/kernel_tuner.git``
49
+
50
+ - change into the top-level directory
51
+
52
+ - ``cd kernel_tuner``
53
+
54
+ - install using
55
+
56
+ - ``pip install .``
57
+
58
+ Dependencies
59
+ ------------
60
+ Python 2.7 or Python 3.5
61
+
62
+ PyCuda and/or PyOpenCL (https://mathema.tician.de/software/)
63
+
64
+ - To tune CUDA kernels
65
+
66
+ - Make sure you have the `CUDA Toolkit <https://developer.nvidia.com/cuda-toolkit>`_ installed
67
+ - You can install PyCuda using ``pip install pycuda``
68
+
69
+ - To tune OpenCL kernels
70
+
71
+ - Make sure you have an OpenCL compiler for your intended OpenCL platform
72
+ - You can install PyOpenCL using ``pip install pyopencl``
73
+
74
+ Example usage
75
+ -------------
76
+
77
+ The following shows a simple example for tuning a CUDA kernel:
78
+
79
+ .. code:: python
80
+
81
+ kernel_string = """
82
+ __global__ void vector_add(float *c, float *a, float *b, int n) {
83
+ int i = blockIdx.x * block_size_x + threadIdx.x;
84
+ if (i<n) {
85
+ c[i] = a[i] + b[i];
86
+ }
87
+ }
88
+ """
89
+
90
+ size = 10000000
91
+
92
+ a = numpy.random.randn(size).astype(numpy.float32)
93
+ b = numpy.random.randn(size).astype(numpy.float32)
94
+ c = numpy.zeros_like(b)
95
+ n = numpy.int32(size)
96
+ args = [c, a, b, n]
97
+
98
+ tune_params = dict()
99
+ tune_params["block_size_x"] = [128+64*i for i in range(15)]
100
+
101
+ tune_kernel("vector_add", kernel_string, size, args, tune_params)
102
+
103
+ The exact same Python code can be used to tune an OpenCL kernel:
104
+
105
+ .. code:: python
106
+
107
+ kernel_string = """
108
+ __kernel void vector_add(__global float *c, __global float *a, __global float *b, int n) {
109
+ int i = get_global_id(0);
110
+ if (i<n) {
111
+ c[i] = a[i] + b[i];
112
+ }
113
+ }
114
+ """
115
+
116
+ Or even just a C function, see the example
117
+ `here <https://github.com/benvanwerkhoven/kernel_tuner/blob/master/examples/c/vector_add.py>`__.
118
+
119
+ You can find these and many - more extensive - example codes, in the
120
+ `examples <https://github.com/benvanwerkhoven/kernel_tuner/blob/master/examples/>`__
121
+ directory.
122
+
123
+ See the `full
124
+ documentation <http://benvanwerkhoven.github.io/kernel_tuner/index.html>`__
125
+ for several highly detailed tutorial-style explanations of example
126
+ kernels and the scripts to tune them.
127
+
128
+ Tuning host and kernel code
129
+ ---------------------------
130
+
131
+ It is also possible to tune for combinations of tunable parameters in
132
+ both host and kernel code. This allows for a number of powerfull things,
133
+ such as tuning the number of streams for a kernel that uses CUDA Streams
134
+ or OpenCL Command Queues to overlap transfers between host and device
135
+ with kernel execution. This can be done in combination with tuning the
136
+ parameters inside the kernel code. See the `convolution\_streams example
137
+ code <https://github.com/benvanwerkhoven/kernel_tuner/blob/master/examples/>`__
138
+ and the
139
+ `documentation <http://benvanwerkhoven.github.io/kernel_tuner/hostcode.html>`__
140
+ for a detailed explanation of the kernel tuner Python script.
141
+
142
+ Correctness verification
143
+ ------------------------
144
+
145
+ Optionally, you can let the kernel tuner verify the output of every
146
+ kernel it compiles and benchmarks, by passing an ``answer`` list. This
147
+ list matches the list of arguments to the kernel, but contains the
148
+ expected output of the kernel. Input arguments are replaced with None.
149
+
150
+ .. code:: python
151
+
152
+ answer = [a+b, None, None] # the order matches the arguments (in args) to the kernel
153
+ tune_kernel("vector_add", kernel_string, size, args, tune_params, answer=answer)
154
+
155
+ Contribution guide
156
+ ------------------
157
+
158
+ The kernel tuner follows the Google Python style guide, with Sphinxdoc
159
+ docstrings for module public functions. If you want to contribute to the
160
+ project please fork it, create a branch including your addition, and
161
+ create a pull request.
162
+
163
+ The tests use relative imports and can be run directly after making
164
+ changes to the code. To run all tests use ``nosetests`` in the main
165
+ directory. To run the examples after code changes, you need to run
166
+ ``pip install --upgrade .`` in the main directory. Documentation is
167
+ generated by typing ``make html`` in the doc directory, the contents of
168
+ ``doc/build/html/`` should then be copied to ``sphinxdoc`` directory of
169
+ the ``gh-pages`` branch.
170
+
171
+ Before creating a pull request please ensure the following:
172
+
173
+ * You have written unit tests to test your additions and all unit tests pass
174
+ * The examples still work and produce the same (or better) results
175
+ * The code is compatible with both Python 2.7 and Python 3.5
176
+ * An entry about the change or addition is created in CHANGELOG.md
177
+
178
+ Contributing authors so far:
179
+
180
+ * Ben van Werkhoven
181
+ * Berend Weel
182
+
183
+ Citation
184
+ --------
185
+ A scientific paper about the Kernel Tuner is in preparation, in the meantime please cite the Kernel Tuner as follows:
186
+
187
+ .. code:: latex
188
+
189
+ @misc{
190
+ author = {Ben van Werkhoven},
191
+ title = {Kernel Tuner: A simple CUDA/OpenCL Kernel Tuner in Python},
192
+ year = {2017}
193
+ }
194
+
195
+ Related work
196
+ ------------
197
+
198
+ You may also like `CLTune <https://github.com/CNugteren/CLTune>`__ by
199
+ Cedric Nugteren. CLTune is a C++ library for kernel tuning and supports
200
+ various advanced features like machine learning to optimize the time
201
+ spent on tuning kernels.
202
+
203
+ .. |Build Status| image:: https://api.travis-ci.org/benvanwerkhoven/kernel_tuner.svg?branch=master
204
+ :target: https://travis-ci.org/benvanwerkhoven/kernel_tuner
205
+ .. |Codacy Badge| image:: https://api.codacy.com/project/badge/grade/016dc85044ab4d57b777449d93275608
206
+ :target: https://www.codacy.com/app/b-vanwerkhoven/kernel_tuner
207
+ .. |Codacy Badge2| image:: https://api.codacy.com/project/badge/coverage/016dc85044ab4d57b777449d93275608
208
+ :target: https://www.codacy.com/app/b-vanwerkhoven/kernel_tuner
@@ -2,14 +2,16 @@
2
2
 
3
3
  import numpy
4
4
  import ctypes as C
5
+ import _ctypes
5
6
  import subprocess
6
7
  import os
7
8
  import errno
8
9
 
9
10
  import numpy.ctypeslib
10
-
11
11
  from kernel_tuner.util import get_temp_filename, delete_temp_file
12
12
 
13
+ import logging
14
+
13
15
  class CFunctions(object):
14
16
  """Class that groups the code for running and compiling C functions"""
15
17
 
@@ -22,6 +24,7 @@ class CFunctions(object):
22
24
  self.ITERATIONS = iterations
23
25
  self.max_threads = 1024
24
26
  self.compiler_options = compiler_options
27
+ self.lib = None
25
28
 
26
29
  #test if nvcc is available, otherwise use gcc
27
30
  self.compiler = "nvcc"
@@ -85,6 +88,11 @@ class CFunctions(object):
85
88
  :returns: An ctypes function that can be called directly.
86
89
  :rtype: ctypes._FuncPtr
87
90
  """
91
+ logging.debug('compiling ' + kernel_name)
92
+
93
+ if self.lib != None:
94
+ self.cleanup_lib()
95
+
88
96
  filename = get_temp_filename()
89
97
  source_file = filename+".cc"
90
98
  kernel_string = "extern \"C\" {\n" + kernel_string + "\n}"
@@ -96,8 +104,6 @@ class CFunctions(object):
96
104
  if self.compiler == "nvcc":
97
105
  source_file = source_file[:-1] + "u"
98
106
  compiler_options = ["-Xcompiler=" + c for c in compiler_options]
99
- #might be better to have an optional argument to pass the desired compute capability
100
- compiler_options += ["-arch=compute_52"]
101
107
 
102
108
  if self.compiler_options:
103
109
  compiler_options += self.compiler_options
@@ -115,13 +121,14 @@ class CFunctions(object):
115
121
 
116
122
  self.lib = numpy.ctypeslib.load_library(filename, '.')
117
123
 
124
+ func = getattr(self.lib, kernel_name)
125
+ func.restype = C.c_float
126
+
118
127
  finally:
119
128
  delete_temp_file(source_file)
120
129
  delete_temp_file(filename+".o")
121
130
  delete_temp_file(filename+".so")
122
131
 
123
- func = getattr(self.lib, kernel_name)
124
- func.restype = C.c_float
125
132
 
126
133
  return func
127
134
 
@@ -189,7 +196,19 @@ class CFunctions(object):
189
196
  :returns: A robust average of values returned by the C function.
190
197
  :rtype: float
191
198
  """
192
- return func(*c_args)
199
+ time = func(*c_args)
200
+
201
+ #I would like to replace the following with actually capturing
202
+ #stderr and detecting the error directly in Python, it proved
203
+ #however that capturing stderr for non-Python functions from Python
204
+ #is a rather difficult thing to do
205
+ #
206
+ #The current, less than ideal, scheme uses the convention that a
207
+ #negative time indicates a 'too many resources requested for launch'
208
+ if time < 0.0:
209
+ raise Exception("too many resources requested for launch")
210
+
211
+ return time
193
212
 
194
213
 
195
214
  def memset(self, allocation, value, size):
@@ -219,3 +238,6 @@ class CFunctions(object):
219
238
  dest[:] = numpy.ctypeslib.as_array(src, shape=self.arg_mapping[str(src)])
220
239
 
221
240
 
241
+ def cleanup_lib(self):
242
+ """ unload the previously loaded shared library """
243
+ _ctypes.dlclose(self.lib._handle)
@@ -1,6 +1,9 @@
1
1
  """ Module for grouping the core functionality needed by most runners """
2
2
  from __future__ import print_function
3
3
 
4
+ import resource
5
+ import logging
6
+
4
7
  from kernel_tuner.cuda import CudaFunctions
5
8
  from kernel_tuner.opencl import OpenCLFunctions
6
9
  from kernel_tuner.c import CFunctions
@@ -19,6 +22,8 @@ def get_device_interface(lang, device, platform, compiler_options=None):
19
22
 
20
23
  def check_kernel_correctness(dev, func, gpu_args, threads, grid, answer, params, verbose, atol=1e-6):
21
24
  """runs the kernel once and checks the result against answer"""
25
+ logging.debug('check_kernel_correctness')
26
+
22
27
  for result, expected in zip(gpu_args, answer):
23
28
  if expected is not None:
24
29
  dev.memset(result, 0, expected.nbytes)
@@ -27,8 +32,10 @@ def check_kernel_correctness(dev, func, gpu_args, threads, grid, answer, params,
27
32
  except Exception as e:
28
33
  if "too many resources requested for launch" in str(e) or "OUT_OF_RESOURCES" in str(e):
29
34
  #ignore this error for now, it will show up when benchmarking the kernel
35
+ logging.debug('correctness check ignores runtime failure due to too many resources required')
30
36
  return True
31
37
  else:
38
+ logging.debug('correctness check encountered runtime failure: ' + str(e))
32
39
  raise e
33
40
  correct = True
34
41
  for result,expected in zip(gpu_args,answer):
@@ -45,12 +52,15 @@ def check_kernel_correctness(dev, func, gpu_args, threads, grid, answer, params,
45
52
  print("Expected:")
46
53
  print(expected)
47
54
  correct = correct and output_test
55
+ del result_host
48
56
  if not correct:
57
+ logging.debug('correctness check has found a correctness issue')
49
58
  raise Exception("Error: " + get_config_string(params) + " failed correctness check")
50
59
  return correct
51
60
 
52
61
  def compile_kernel(dev, kernel_name, kernel_string, params, grid, instance_string, verbose):
53
62
  """compile the kernel for this specific instance"""
63
+ logging.debug('compile_kernel ' + instance_string)
54
64
 
55
65
  #prepare kernel_string for compilation
56
66
  name, kernel_string = setup_kernel_strings(kernel_name, kernel_string, params, grid, instance_string)
@@ -64,15 +74,21 @@ def compile_kernel(dev, kernel_name, kernel_string, params, grid, instance_strin
64
74
  #much shared memory for example, the desired behavior is to simply
65
75
  #skip over this configuration and try the next one
66
76
  if "uses too much shared data" in str(e):
77
+ logging.debug('compile_kernel failed due to kernel using too much shared memory')
67
78
  if verbose:
68
79
  print("skipping config", instance_string, "reason: too much shared memory used")
69
80
  else:
81
+ logging.debug('compile_kernel failed due to error: ' + str(e))
70
82
  print("Error while compiling:", instance_string)
71
83
  raise e
72
84
  return func
73
85
 
74
86
  def benchmark(dev, func, gpu_args, threads, grid, instance_string, verbose):
75
87
  """benchmark the kernel instance"""
88
+ logging.debug('benchmark ' + instance_string)
89
+ logging.debug('thread block dimensions x,y,z=%d,%d,%d', *threads)
90
+ logging.debug('grid dimensions x,y,z=%d,%d,%d', *grid)
91
+
76
92
  time = None
77
93
  try:
78
94
  time = dev.benchmark(func, gpu_args, threads, grid)
@@ -82,18 +98,23 @@ def benchmark(dev, func, gpu_args, threads, grid, instance_string, verbose):
82
98
  #the desired behavior is to simply skip over this configuration
83
99
  #and proceed to try the next one
84
100
  if "too many resources requested for launch" in str(e) or "OUT_OF_RESOURCES" in str(e):
101
+ logging.debug('benchmark fails due to runtime failure too many resources required')
85
102
  if verbose:
86
103
  print("skipping config", instance_string, "reason: too many resources requested for launch")
87
104
  else:
105
+ logging.debug('benchmark encountered runtime failure: ' + str(e))
88
106
  print("Error while benchmarking:", instance_string)
89
107
  raise e
90
108
  return time
91
109
 
92
110
  def compile_and_benchmark(dev, gpu_args, kernel_name, original_kernel, params,
93
- problem_size, grid_div_y, grid_div_x, cmem_args, answer, atol, instance_string, verbose):
111
+ problem_size, grid_div_z, grid_div_y, grid_div_x, cmem_args, answer, atol, instance_string, verbose):
112
+
113
+ logging.debug('compile_and_benchmark ' + instance_string)
114
+ logging.debug('Memory usage : %2.2f MB', round(resource.getrusage(resource.RUSAGE_SELF).ru_maxrss/1024.0,1) )
94
115
 
95
116
  #setup thread block and grid dimensions
96
- threads, grid = setup_block_and_grid(dev, problem_size, grid_div_y, grid_div_x, params, instance_string, verbose)
117
+ threads, grid = setup_block_and_grid(dev, problem_size, grid_div_z, grid_div_y, grid_div_x, params, instance_string, verbose)
97
118
  if threads is None:
98
119
  return None
99
120
 
@@ -1,5 +1,7 @@
1
1
  """This module contains all CUDA specific kernel_tuner functions"""
2
+ from __future__ import print_function
2
3
  import numpy
4
+ import logging
3
5
 
4
6
  #embedded in try block to be able to generate documentation
5
7
  #and run tests without pycuda installed
@@ -41,7 +43,7 @@ class CudaFunctions(object):
41
43
  self.ITERATIONS = iterations
42
44
  self.current_module = None
43
45
  self.compiler_options = compiler_options or []
44
-
46
+ print("Using: " + str(self.context.get_device().name()))
45
47
 
46
48
  def __del__(self):
47
49
  if hasattr(self, 'context'):
@@ -154,8 +156,15 @@ class CudaFunctions(object):
154
156
  to be numpy objects, such as numpy.ndarray or numpy.int32, and so on.
155
157
  :type cmem_args: dict( string: numpy.ndarray, ... )
156
158
  """
159
+ logging.debug('copy_constant_memory_args called')
160
+ logging.debug('current module: ' + str(self.current_module))
157
161
  for k,v in cmem_args.items():
158
162
  symbol = self.current_module.get_global(k)[0]
163
+ logging.debug('copying to symbol: ' + str(symbol))
164
+ logging.debug('array to be copied: ')
165
+ logging.debug(v.nbytes)
166
+ logging.debug(v.dtype)
167
+ logging.debug(v.flags)
159
168
  drv.memcpy_htod(symbol, v)
160
169
 
161
170
  def run_kernel(self, func, gpu_args, threads, grid):