kernel-tuner 0.4.2__tar.gz → 1.0__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.
- kernel_tuner-1.0/PKG-INFO +187 -0
- kernel_tuner-1.0/README.md +133 -0
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/kernel_tuner/__init__.py +3 -2
- kernel_tuner-1.0/kernel_tuner/accuracy.py +308 -0
- kernel_tuner-1.0/kernel_tuner/backends/backend.py +89 -0
- kernel_tuner-1.0/kernel_tuner/backends/compiler.py +411 -0
- {kernel_tuner-0.4.2/kernel_tuner → kernel_tuner-1.0/kernel_tuner/backends}/cupy.py +54 -113
- kernel_tuner-1.0/kernel_tuner/backends/hip.py +320 -0
- kernel_tuner-1.0/kernel_tuner/backends/nvcuda.py +343 -0
- {kernel_tuner-0.4.2/kernel_tuner → kernel_tuner-1.0/kernel_tuner/backends}/opencl.py +71 -95
- kernel_tuner-0.4.2/kernel_tuner/cuda.py → kernel_tuner-1.0/kernel_tuner/backends/pycuda.py +125 -148
- kernel_tuner-1.0/kernel_tuner/core.py +1002 -0
- kernel_tuner-1.0/kernel_tuner/energy/energy.py +209 -0
- kernel_tuner-1.0/kernel_tuner/file_utils.py +254 -0
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/kernel_tuner/hyper.py +1 -1
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/kernel_tuner/integration.py +5 -4
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/kernel_tuner/interface.py +465 -307
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/kernel_tuner/kernelbuilder.py +0 -4
- kernel_tuner-1.0/kernel_tuner/observers/__init__.py +1 -0
- kernel_tuner-1.0/kernel_tuner/observers/compiler.py +23 -0
- kernel_tuner-1.0/kernel_tuner/observers/cupy.py +28 -0
- kernel_tuner-1.0/kernel_tuner/observers/hip.py +33 -0
- kernel_tuner-1.0/kernel_tuner/observers/nvcuda.py +31 -0
- kernel_tuner-1.0/kernel_tuner/observers/nvml.py +614 -0
- kernel_tuner-1.0/kernel_tuner/observers/observer.py +60 -0
- kernel_tuner-1.0/kernel_tuner/observers/opencl.py +21 -0
- kernel_tuner-1.0/kernel_tuner/observers/pmt.py +84 -0
- kernel_tuner-1.0/kernel_tuner/observers/powersensor.py +62 -0
- kernel_tuner-1.0/kernel_tuner/observers/pycuda.py +23 -0
- kernel_tuner-1.0/kernel_tuner/runners/__init__.py +0 -0
- kernel_tuner-1.0/kernel_tuner/runners/runner.py +22 -0
- kernel_tuner-1.0/kernel_tuner/runners/sequential.py +119 -0
- kernel_tuner-1.0/kernel_tuner/runners/simulation.py +134 -0
- kernel_tuner-1.0/kernel_tuner/schema/T4/1.0.0/metadata-schema.json +49 -0
- kernel_tuner-1.0/kernel_tuner/schema/T4/1.0.0/results-schema.json +75 -0
- kernel_tuner-1.0/kernel_tuner/searchspace.py +716 -0
- kernel_tuner-1.0/kernel_tuner/strategies/__init__.py +0 -0
- kernel_tuner-1.0/kernel_tuner/strategies/basinhopping.py +44 -0
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/kernel_tuner/strategies/bayes_opt.py +277 -175
- kernel_tuner-1.0/kernel_tuner/strategies/brute_force.py +13 -0
- kernel_tuner-1.0/kernel_tuner/strategies/common.py +245 -0
- kernel_tuner-1.0/kernel_tuner/strategies/diff_evo.py +43 -0
- kernel_tuner-1.0/kernel_tuner/strategies/dual_annealing.py +43 -0
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/kernel_tuner/strategies/firefly_algorithm.py +32 -55
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/kernel_tuner/strategies/genetic_algorithm.py +36 -50
- kernel_tuner-1.0/kernel_tuner/strategies/greedy_ils.py +66 -0
- kernel_tuner-1.0/kernel_tuner/strategies/greedy_mls.py +43 -0
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/kernel_tuner/strategies/hillclimbers.py +9 -18
- kernel_tuner-1.0/kernel_tuner/strategies/minimize.py +43 -0
- kernel_tuner-1.0/kernel_tuner/strategies/mls.py +21 -0
- kernel_tuner-1.0/kernel_tuner/strategies/ordered_greedy_mls.py +21 -0
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/kernel_tuner/strategies/pso.py +24 -46
- kernel_tuner-1.0/kernel_tuner/strategies/random_sample.py +37 -0
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/kernel_tuner/strategies/simulated_annealing.py +22 -42
- kernel_tuner-1.0/kernel_tuner/util.py +1263 -0
- kernel_tuner-1.0/kernel_tuner/utils/__init__.py +0 -0
- kernel_tuner-1.0/kernel_tuner/utils/directives.py +281 -0
- kernel_tuner-1.0/pyproject.toml +145 -0
- kernel_tuner-1.0/test/__init__.py +0 -0
- kernel_tuner-1.0/test/context.py +102 -0
- kernel_tuner-1.0/test/strategies/test_bayesian_optimization.py +155 -0
- kernel_tuner-1.0/test/strategies/test_common.py +61 -0
- kernel_tuner-1.0/test/strategies/test_genetic_algorithm.py +75 -0
- kernel_tuner-1.0/test/strategies/test_strategies.py +80 -0
- kernel_tuner-1.0/test/synthetic_fp32_cache_NVIDIA_RTX_A4000.json +48 -0
- kernel_tuner-1.0/test/test_accuracy.py +81 -0
- kernel_tuner-1.0/test/test_backend.py +47 -0
- kernel_tuner-1.0/test/test_cache_file.json +313 -0
- kernel_tuner-0.4.2/test/test_minimize.py → kernel_tuner-1.0/test/test_common.py +21 -23
- kernel_tuner-1.0/test/test_compiler_functions.py +489 -0
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/test/test_core.py +87 -7
- kernel_tuner-1.0/test/test_cuda_functions.py +60 -0
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/test/test_cupy_functions.py +3 -1
- kernel_tuner-1.0/test/test_energy.py +16 -0
- kernel_tuner-1.0/test/test_file_utils.py +57 -0
- kernel_tuner-1.0/test/test_hip_functions.py +157 -0
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/test/test_hyper.py +3 -5
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/test/test_integration.py +26 -15
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/test/test_kernelbuilder.py +12 -7
- kernel_tuner-1.0/test/test_nvml_mocked.py +56 -0
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/test/test_observers.py +7 -7
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/test/test_opencl_functions.py +42 -32
- kernel_tuner-1.0/test/test_pycuda_functions.py +59 -0
- kernel_tuner-1.0/test/test_pycuda_mocked.py +126 -0
- kernel_tuner-1.0/test/test_runners.py +296 -0
- kernel_tuner-1.0/test/test_searchspace.py +443 -0
- kernel_tuner-1.0/test/test_toml_file.py +72 -0
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/test/test_util_functions.py +260 -125
- kernel_tuner-1.0/test/test_utils_directives.py +164 -0
- kernel_tuner-0.4.2/MANIFEST.in +0 -3
- kernel_tuner-0.4.2/PKG-INFO +0 -224
- kernel_tuner-0.4.2/README.rst +0 -189
- kernel_tuner-0.4.2/kernel_tuner/c.py +0 -352
- kernel_tuner-0.4.2/kernel_tuner/core.py +0 -667
- kernel_tuner-0.4.2/kernel_tuner/nvml.py +0 -277
- kernel_tuner-0.4.2/kernel_tuner/observers.py +0 -78
- kernel_tuner-0.4.2/kernel_tuner/runners/sequential.py +0 -117
- kernel_tuner-0.4.2/kernel_tuner/runners/simulation.py +0 -248
- kernel_tuner-0.4.2/kernel_tuner/searchspace.py +0 -294
- kernel_tuner-0.4.2/kernel_tuner/strategies/basinhopping.py +0 -66
- kernel_tuner-0.4.2/kernel_tuner/strategies/brute_force.py +0 -37
- kernel_tuner-0.4.2/kernel_tuner/strategies/diff_evo.py +0 -66
- kernel_tuner-0.4.2/kernel_tuner/strategies/dual_annealing.py +0 -62
- kernel_tuner-0.4.2/kernel_tuner/strategies/greedy_ils.py +0 -86
- kernel_tuner-0.4.2/kernel_tuner/strategies/greedy_mls.py +0 -61
- kernel_tuner-0.4.2/kernel_tuner/strategies/minimize.py +0 -264
- kernel_tuner-0.4.2/kernel_tuner/strategies/mls.py +0 -31
- kernel_tuner-0.4.2/kernel_tuner/strategies/ordered_greedy_mls.py +0 -32
- kernel_tuner-0.4.2/kernel_tuner/strategies/random_sample.py +0 -57
- kernel_tuner-0.4.2/kernel_tuner/util.py +0 -841
- kernel_tuner-0.4.2/kernel_tuner.egg-info/PKG-INFO +0 -224
- kernel_tuner-0.4.2/kernel_tuner.egg-info/SOURCES.txt +0 -59
- kernel_tuner-0.4.2/kernel_tuner.egg-info/dependency_links.txt +0 -1
- kernel_tuner-0.4.2/kernel_tuner.egg-info/requires.txt +0 -44
- kernel_tuner-0.4.2/kernel_tuner.egg-info/top_level.txt +0 -1
- kernel_tuner-0.4.2/setup.cfg +0 -7
- kernel_tuner-0.4.2/setup.py +0 -55
- kernel_tuner-0.4.2/test/test_c_functions.py +0 -282
- kernel_tuner-0.4.2/test/test_cuda_functions.py +0 -64
- kernel_tuner-0.4.2/test/test_cuda_mocked.py +0 -144
- kernel_tuner-0.4.2/test/test_interface.py +0 -111
- kernel_tuner-0.4.2/test/test_runners.py +0 -112
- kernel_tuner-0.4.2/test/test_searchspace.py +0 -297
- {kernel_tuner-0.4.2 → kernel_tuner-1.0}/LICENSE +0 -0
- {kernel_tuner-0.4.2/kernel_tuner/runners → kernel_tuner-1.0/kernel_tuner/backends}/__init__.py +0 -0
- {kernel_tuner-0.4.2/kernel_tuner/strategies → kernel_tuner-1.0/kernel_tuner/energy}/__init__.py +0 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: kernel_tuner
|
|
3
|
+
Version: 1.0
|
|
4
|
+
Summary: An easy to use CUDA/OpenCL kernel tuner in Python
|
|
5
|
+
Home-page: https://KernelTuner.github.io/kernel_tuner/
|
|
6
|
+
License: Apache-2.0
|
|
7
|
+
Keywords: auto-tuning,gpu,computing,pycuda,cuda,pyopencl,opencl
|
|
8
|
+
Author: Ben van Werkhoven
|
|
9
|
+
Author-email: b.vanwerkhoven@esciencecenter.nl
|
|
10
|
+
Requires-Python: >=3.8,<3.12
|
|
11
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Environment :: GPU
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: Education
|
|
16
|
+
Classifier: Intended Audience :: Science/Research
|
|
17
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
18
|
+
Classifier: Natural Language :: English
|
|
19
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
20
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
21
|
+
Classifier: Programming Language :: Python :: 3
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
26
|
+
Classifier: Topic :: Scientific/Engineering
|
|
27
|
+
Classifier: Topic :: Software Development
|
|
28
|
+
Classifier: Topic :: System :: Distributed Computing
|
|
29
|
+
Provides-Extra: cuda
|
|
30
|
+
Provides-Extra: cuda-opencl
|
|
31
|
+
Provides-Extra: hip
|
|
32
|
+
Provides-Extra: opencl
|
|
33
|
+
Provides-Extra: tutorial
|
|
34
|
+
Requires-Dist: jsonschema
|
|
35
|
+
Requires-Dist: jupyter (>=1.0.0,<2.0.0) ; extra == "tutorial"
|
|
36
|
+
Requires-Dist: matplotlib (>=3.5.0,<4.0.0) ; extra == "tutorial"
|
|
37
|
+
Requires-Dist: numpy (>=1.22.2,<2.0.0)
|
|
38
|
+
Requires-Dist: nvidia-ml-py (>=12.535.108,<13.0.0) ; extra == "cuda" or extra == "tutorial"
|
|
39
|
+
Requires-Dist: packaging
|
|
40
|
+
Requires-Dist: pandas (>=2.0.0,<3.0.0)
|
|
41
|
+
Requires-Dist: pycuda (>=2024.1,<2025.0) ; extra == "cuda" or extra == "cuda-opencl"
|
|
42
|
+
Requires-Dist: pyhip-interface ; extra == "hip"
|
|
43
|
+
Requires-Dist: pynvml (>=11.4.1,<12.0.0) ; extra == "cuda"
|
|
44
|
+
Requires-Dist: pyopencl ; extra == "opencl" or extra == "cuda-opencl"
|
|
45
|
+
Requires-Dist: python-constraint2 (>=2.0.0b5,<3.0.0)
|
|
46
|
+
Requires-Dist: scikit-learn (>=1.0.2,<2.0.0)
|
|
47
|
+
Requires-Dist: scipy (>=1.10.1,<2.0.0)
|
|
48
|
+
Requires-Dist: xmltodict
|
|
49
|
+
Project-URL: Documentation, https://KernelTuner.github.io/kernel_tuner/
|
|
50
|
+
Project-URL: Repository, https://github.com/KernelTuner/kernel_tuner
|
|
51
|
+
Project-URL: Tracker, https://github.com/KernelTuner/kernel_tuner/issues
|
|
52
|
+
Description-Content-Type: text/markdown
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
<div align="center">
|
|
57
|
+
<img width="500px" src="doc/images/KernelTuner-logo.png"/>
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
[](https://github.com/KernelTuner/kernel_tuner/actions/workflows/build-test-python-package.yml)
|
|
62
|
+
[](https://codecov.io/gh/KernelTuner/kernel_tuner)
|
|
63
|
+
[](https://pypi.python.org/pypi/kernel_tuner/)
|
|
64
|
+
[](https://zenodo.org/badge/latestdoi/54894320)
|
|
65
|
+
[](https://sonarcloud.io/dashboard?id=KernelTuner_kernel_tuner)
|
|
66
|
+
[](https://bestpractices.coreinfrastructure.org/projects/6573)
|
|
67
|
+
[](https://fair-software.eu)
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
Create optimized GPU applications in any mainstream GPU
|
|
72
|
+
programming language (CUDA, HIP, OpenCL, OpenACC).
|
|
73
|
+
|
|
74
|
+
What Kernel Tuner does:
|
|
75
|
+
|
|
76
|
+
- Works as an external tool to benchmark and optimize GPU kernels in isolation
|
|
77
|
+
- Can be used directly on existing kernel code without extensive changes
|
|
78
|
+
- Can be used with applications in any host programming language
|
|
79
|
+
- Blazing fast search space construction
|
|
80
|
+
- More than 20 [optimization algorithms](https://kerneltuner.github.io/kernel_tuner/stable/optimization.html) to speedup tuning
|
|
81
|
+
- Energy measurements and optimizations [(power capping, clock frequency tuning)](https://arxiv.org/abs/2211.07260)
|
|
82
|
+
- ... and much more! For example, [caching](https://kerneltuner.github.io/kernel_tuner/stable/cache_files.html), [output verification](https://kerneltuner.github.io/kernel_tuner/stable/correctness.html), [tuning host and device code](https://kerneltuner.github.io/kernel_tuner/stable/hostcode.html), [user defined metrics](https://kerneltuner.github.io/kernel_tuner/stable/metrics.html), see [the full documentation](https://kerneltuner.github.io/kernel_tuner/stable/index.html).
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
## Installation
|
|
87
|
+
|
|
88
|
+
- First, make sure you have your [CUDA](https://kerneltuner.github.io/kernel_tuner/stable/install.html#cuda-and-pycuda), [OpenCL](https://kerneltuner.github.io/kernel_tuner/stable/install.html#opencl-and-pyopencl), or [HIP](https://kerneltuner.github.io/kernel_tuner/stable/install.html#hip-and-pyhipl) compiler installed
|
|
89
|
+
- Then type: `pip install kernel_tuner[cuda]`, `pip install kernel_tuner[opencl]`, or `pip install kernel_tuner[hip]`
|
|
90
|
+
- or why not all of them: `pip install kernel_tuner[cuda,opencl,hip]`
|
|
91
|
+
|
|
92
|
+
More information on installation, also for other languages, in the [installation guide](http://kerneltuner.github.io/kernel_tuner/stable/install.html).
|
|
93
|
+
|
|
94
|
+
## Example
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
import numpy as np
|
|
98
|
+
from kernel_tuner import tune_kernel
|
|
99
|
+
|
|
100
|
+
kernel_string = """
|
|
101
|
+
__global__ void vector_add(float *c, float *a, float *b, int n) {
|
|
102
|
+
int i = blockIdx.x * block_size_x + threadIdx.x;
|
|
103
|
+
if (i<n) {
|
|
104
|
+
c[i] = a[i] + b[i];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
n = np.int32(10000000)
|
|
110
|
+
|
|
111
|
+
a = np.random.randn(n).astype(np.float32)
|
|
112
|
+
b = np.random.randn(n).astype(np.float32)
|
|
113
|
+
c = np.zeros_like(a)
|
|
114
|
+
|
|
115
|
+
args = [c, a, b, n]
|
|
116
|
+
|
|
117
|
+
tune_params = {"block_size_x": [32, 64, 128, 256, 512]}
|
|
118
|
+
|
|
119
|
+
tune_kernel("vector_add", kernel_string, n, args, tune_params)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
More [examples here](https://kerneltuner.github.io/kernel_tuner/stable/examples.html).
|
|
123
|
+
|
|
124
|
+
## Resources
|
|
125
|
+
|
|
126
|
+
- [Full documentation](https://kerneltuner.github.io/kernel_tuner/stable/)
|
|
127
|
+
- Guides:
|
|
128
|
+
- [Getting Started](https://kerneltuner.github.io/kernel_tuner/stable/quickstart.html)
|
|
129
|
+
- [Convolution](https://kerneltuner.github.io/kernel_tuner/stable/convolution.html)
|
|
130
|
+
- [Diffusion](https://kerneltuner.github.io/kernel_tuner/stable/diffusion.html)
|
|
131
|
+
- [Matrix Multiplication](https://kerneltuner.github.io/kernel_tuner/stable/matrix_multiplication.html)
|
|
132
|
+
- Features & Use cases:
|
|
133
|
+
- [Full list of examples](https://kerneltuner.github.io/kernel_tuner/stable/examples.html)
|
|
134
|
+
- [Output verification](https://kerneltuner.github.io/kernel_tuner/stable/correctness.html)
|
|
135
|
+
- [Test GPU code from Python](https://github.com/KernelTuner/kernel_tuner/blob/master/examples/cuda/test_vector_add.py)
|
|
136
|
+
- [Tune code in both host and device code](https://kerneltuner.github.io/kernel_tuner/stable/hostcode.html)
|
|
137
|
+
- [Optimization algorithms](https://kerneltuner.github.io/kernel_tuner/stable/optimization.html)
|
|
138
|
+
- [Mixed-precision & Accuracy tuning](https://github.com/KernelTuner/kernel_tuner/blob/master/examples/cuda/accuracy.py)
|
|
139
|
+
- [Custom metrics & tuning objectives](https://kerneltuner.github.io/kernel_tuner/stable/metrics.html)
|
|
140
|
+
- **Kernel Tuner Tutorial** slides [[PDF]](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/slides/2022_SURF/SURF22-Kernel-Tuner-Tutorial.pdf), hands-on:
|
|
141
|
+
- Vector add example [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/00_Kernel_Tuner_Introduction.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/00_Kernel_Tuner_Introduction.ipynb)
|
|
142
|
+
- Tuning thread block dimensions [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/01_Kernel_Tuner_Getting_Started.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/01_Kernel_Tuner_Getting_Started.ipynb)
|
|
143
|
+
- Search space restrictions & output verification [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/02_Kernel_Tuner_Intermediate.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/02_Kernel_Tuner_Intermediate.ipynb)
|
|
144
|
+
- Visualization & search space optimization [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/03_Kernel_Tuner_Advanced.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/03_Kernel_Tuner_Advanced.ipynb)
|
|
145
|
+
- **Energy Efficient GPU Computing** tutorial slides [[PDF]](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/slides/2023_Supercomputing/SC23.pdf), hands-on:
|
|
146
|
+
- Kernel Tuner for GPU energy measurements [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/energy/00_Kernel_Tuner_Introduction.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/energy/00_Kernel_Tuner_Introduction.ipynb)
|
|
147
|
+
- Code optimizations for energy [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/energy/01_Code_Optimizations_for_Energy.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/energy/01_Code_Optimizations_for_Energy.ipynb)
|
|
148
|
+
- Mixed precision and accuracy tuning [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/energy/02_Mixed_precision_programming.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/energy/02_Mixed_precision_programming.ipynb)
|
|
149
|
+
- Optimzing for time vs for energy [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/energy/03_energy_efficient_computing.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/energy/03_energy_efficient_computing.ipynb)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
## Kernel Tuner ecosystem
|
|
153
|
+
|
|
154
|
+
<img width="250px" src="doc/images/kernel_launcher.png"/><br />C++ magic to integrate auto-tuned kernels into C++ applications
|
|
155
|
+
|
|
156
|
+
<img width="250px" src="doc/images/kernel_float.png"/><br />C++ data types for mixed-precision CUDA kernel programming
|
|
157
|
+
|
|
158
|
+
<img width="275px" src="doc/images/kernel_dashboard.png"/><br />Monitor, analyze, and visualize auto-tuning runs
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
## Communication & Contribution
|
|
162
|
+
|
|
163
|
+
- GitHub [Issues](https://github.com/KernelTuner/kernel_tuner/issues): Bug reports, install issues, feature requests, work in progress
|
|
164
|
+
- GitHub [Discussion group](https://github.com/orgs/KernelTuner/discussions): General questions, Q&A, thoughts
|
|
165
|
+
|
|
166
|
+
Contributions are welcome! For feature requests, bug reports, or usage problems, please feel free to create an issue.
|
|
167
|
+
For more extensive contributions, check the [contribution guide](http://kerneltuner.github.io/kernel_tuner/stable/contributing.html).
|
|
168
|
+
|
|
169
|
+
## Citation
|
|
170
|
+
|
|
171
|
+
If you use Kernel Tuner in research or research software, please cite the most relevant among the [publications on Kernel
|
|
172
|
+
Tuner](https://kerneltuner.github.io/kernel_tuner/stable/#citation). To refer to the project as a whole, please cite:
|
|
173
|
+
|
|
174
|
+
```latex
|
|
175
|
+
@article{kerneltuner,
|
|
176
|
+
author = {Ben van Werkhoven},
|
|
177
|
+
title = {Kernel Tuner: A search-optimizing GPU code auto-tuner},
|
|
178
|
+
journal = {Future Generation Computer Systems},
|
|
179
|
+
year = {2019},
|
|
180
|
+
volume = {90},
|
|
181
|
+
pages = {347-358},
|
|
182
|
+
url = {https://www.sciencedirect.com/science/article/pii/S0167739X18313359},
|
|
183
|
+
doi = {https://doi.org/10.1016/j.future.2018.08.004}
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
<div align="center">
|
|
4
|
+
<img width="500px" src="doc/images/KernelTuner-logo.png"/>
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
[](https://github.com/KernelTuner/kernel_tuner/actions/workflows/build-test-python-package.yml)
|
|
9
|
+
[](https://codecov.io/gh/KernelTuner/kernel_tuner)
|
|
10
|
+
[](https://pypi.python.org/pypi/kernel_tuner/)
|
|
11
|
+
[](https://zenodo.org/badge/latestdoi/54894320)
|
|
12
|
+
[](https://sonarcloud.io/dashboard?id=KernelTuner_kernel_tuner)
|
|
13
|
+
[](https://bestpractices.coreinfrastructure.org/projects/6573)
|
|
14
|
+
[](https://fair-software.eu)
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
Create optimized GPU applications in any mainstream GPU
|
|
19
|
+
programming language (CUDA, HIP, OpenCL, OpenACC).
|
|
20
|
+
|
|
21
|
+
What Kernel Tuner does:
|
|
22
|
+
|
|
23
|
+
- Works as an external tool to benchmark and optimize GPU kernels in isolation
|
|
24
|
+
- Can be used directly on existing kernel code without extensive changes
|
|
25
|
+
- Can be used with applications in any host programming language
|
|
26
|
+
- Blazing fast search space construction
|
|
27
|
+
- More than 20 [optimization algorithms](https://kerneltuner.github.io/kernel_tuner/stable/optimization.html) to speedup tuning
|
|
28
|
+
- Energy measurements and optimizations [(power capping, clock frequency tuning)](https://arxiv.org/abs/2211.07260)
|
|
29
|
+
- ... and much more! For example, [caching](https://kerneltuner.github.io/kernel_tuner/stable/cache_files.html), [output verification](https://kerneltuner.github.io/kernel_tuner/stable/correctness.html), [tuning host and device code](https://kerneltuner.github.io/kernel_tuner/stable/hostcode.html), [user defined metrics](https://kerneltuner.github.io/kernel_tuner/stable/metrics.html), see [the full documentation](https://kerneltuner.github.io/kernel_tuner/stable/index.html).
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
- First, make sure you have your [CUDA](https://kerneltuner.github.io/kernel_tuner/stable/install.html#cuda-and-pycuda), [OpenCL](https://kerneltuner.github.io/kernel_tuner/stable/install.html#opencl-and-pyopencl), or [HIP](https://kerneltuner.github.io/kernel_tuner/stable/install.html#hip-and-pyhipl) compiler installed
|
|
36
|
+
- Then type: `pip install kernel_tuner[cuda]`, `pip install kernel_tuner[opencl]`, or `pip install kernel_tuner[hip]`
|
|
37
|
+
- or why not all of them: `pip install kernel_tuner[cuda,opencl,hip]`
|
|
38
|
+
|
|
39
|
+
More information on installation, also for other languages, in the [installation guide](http://kerneltuner.github.io/kernel_tuner/stable/install.html).
|
|
40
|
+
|
|
41
|
+
## Example
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
import numpy as np
|
|
45
|
+
from kernel_tuner import tune_kernel
|
|
46
|
+
|
|
47
|
+
kernel_string = """
|
|
48
|
+
__global__ void vector_add(float *c, float *a, float *b, int n) {
|
|
49
|
+
int i = blockIdx.x * block_size_x + threadIdx.x;
|
|
50
|
+
if (i<n) {
|
|
51
|
+
c[i] = a[i] + b[i];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
n = np.int32(10000000)
|
|
57
|
+
|
|
58
|
+
a = np.random.randn(n).astype(np.float32)
|
|
59
|
+
b = np.random.randn(n).astype(np.float32)
|
|
60
|
+
c = np.zeros_like(a)
|
|
61
|
+
|
|
62
|
+
args = [c, a, b, n]
|
|
63
|
+
|
|
64
|
+
tune_params = {"block_size_x": [32, 64, 128, 256, 512]}
|
|
65
|
+
|
|
66
|
+
tune_kernel("vector_add", kernel_string, n, args, tune_params)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
More [examples here](https://kerneltuner.github.io/kernel_tuner/stable/examples.html).
|
|
70
|
+
|
|
71
|
+
## Resources
|
|
72
|
+
|
|
73
|
+
- [Full documentation](https://kerneltuner.github.io/kernel_tuner/stable/)
|
|
74
|
+
- Guides:
|
|
75
|
+
- [Getting Started](https://kerneltuner.github.io/kernel_tuner/stable/quickstart.html)
|
|
76
|
+
- [Convolution](https://kerneltuner.github.io/kernel_tuner/stable/convolution.html)
|
|
77
|
+
- [Diffusion](https://kerneltuner.github.io/kernel_tuner/stable/diffusion.html)
|
|
78
|
+
- [Matrix Multiplication](https://kerneltuner.github.io/kernel_tuner/stable/matrix_multiplication.html)
|
|
79
|
+
- Features & Use cases:
|
|
80
|
+
- [Full list of examples](https://kerneltuner.github.io/kernel_tuner/stable/examples.html)
|
|
81
|
+
- [Output verification](https://kerneltuner.github.io/kernel_tuner/stable/correctness.html)
|
|
82
|
+
- [Test GPU code from Python](https://github.com/KernelTuner/kernel_tuner/blob/master/examples/cuda/test_vector_add.py)
|
|
83
|
+
- [Tune code in both host and device code](https://kerneltuner.github.io/kernel_tuner/stable/hostcode.html)
|
|
84
|
+
- [Optimization algorithms](https://kerneltuner.github.io/kernel_tuner/stable/optimization.html)
|
|
85
|
+
- [Mixed-precision & Accuracy tuning](https://github.com/KernelTuner/kernel_tuner/blob/master/examples/cuda/accuracy.py)
|
|
86
|
+
- [Custom metrics & tuning objectives](https://kerneltuner.github.io/kernel_tuner/stable/metrics.html)
|
|
87
|
+
- **Kernel Tuner Tutorial** slides [[PDF]](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/slides/2022_SURF/SURF22-Kernel-Tuner-Tutorial.pdf), hands-on:
|
|
88
|
+
- Vector add example [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/00_Kernel_Tuner_Introduction.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/00_Kernel_Tuner_Introduction.ipynb)
|
|
89
|
+
- Tuning thread block dimensions [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/01_Kernel_Tuner_Getting_Started.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/01_Kernel_Tuner_Getting_Started.ipynb)
|
|
90
|
+
- Search space restrictions & output verification [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/02_Kernel_Tuner_Intermediate.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/02_Kernel_Tuner_Intermediate.ipynb)
|
|
91
|
+
- Visualization & search space optimization [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/03_Kernel_Tuner_Advanced.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/hands-on/cuda/03_Kernel_Tuner_Advanced.ipynb)
|
|
92
|
+
- **Energy Efficient GPU Computing** tutorial slides [[PDF]](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/slides/2023_Supercomputing/SC23.pdf), hands-on:
|
|
93
|
+
- Kernel Tuner for GPU energy measurements [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/energy/00_Kernel_Tuner_Introduction.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/energy/00_Kernel_Tuner_Introduction.ipynb)
|
|
94
|
+
- Code optimizations for energy [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/energy/01_Code_Optimizations_for_Energy.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/energy/01_Code_Optimizations_for_Energy.ipynb)
|
|
95
|
+
- Mixed precision and accuracy tuning [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/energy/02_Mixed_precision_programming.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/energy/02_Mixed_precision_programming.ipynb)
|
|
96
|
+
- Optimzing for time vs for energy [[.ipynb](https://github.com/KernelTuner/kernel_tuner_tutorial/blob/master/energy/03_energy_efficient_computing.ipynb)] [](https://colab.research.google.com/github/KernelTuner/kernel_tuner_tutorial/blob/master/energy/03_energy_efficient_computing.ipynb)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
## Kernel Tuner ecosystem
|
|
100
|
+
|
|
101
|
+
<img width="250px" src="doc/images/kernel_launcher.png"/><br />C++ magic to integrate auto-tuned kernels into C++ applications
|
|
102
|
+
|
|
103
|
+
<img width="250px" src="doc/images/kernel_float.png"/><br />C++ data types for mixed-precision CUDA kernel programming
|
|
104
|
+
|
|
105
|
+
<img width="275px" src="doc/images/kernel_dashboard.png"/><br />Monitor, analyze, and visualize auto-tuning runs
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
## Communication & Contribution
|
|
109
|
+
|
|
110
|
+
- GitHub [Issues](https://github.com/KernelTuner/kernel_tuner/issues): Bug reports, install issues, feature requests, work in progress
|
|
111
|
+
- GitHub [Discussion group](https://github.com/orgs/KernelTuner/discussions): General questions, Q&A, thoughts
|
|
112
|
+
|
|
113
|
+
Contributions are welcome! For feature requests, bug reports, or usage problems, please feel free to create an issue.
|
|
114
|
+
For more extensive contributions, check the [contribution guide](http://kerneltuner.github.io/kernel_tuner/stable/contributing.html).
|
|
115
|
+
|
|
116
|
+
## Citation
|
|
117
|
+
|
|
118
|
+
If you use Kernel Tuner in research or research software, please cite the most relevant among the [publications on Kernel
|
|
119
|
+
Tuner](https://kerneltuner.github.io/kernel_tuner/stable/#citation). To refer to the project as a whole, please cite:
|
|
120
|
+
|
|
121
|
+
```latex
|
|
122
|
+
@article{kerneltuner,
|
|
123
|
+
author = {Ben van Werkhoven},
|
|
124
|
+
title = {Kernel Tuner: A search-optimizing GPU code auto-tuner},
|
|
125
|
+
journal = {Future Generation Computer Systems},
|
|
126
|
+
year = {2019},
|
|
127
|
+
volume = {90},
|
|
128
|
+
pages = {347-358},
|
|
129
|
+
url = {https://www.sciencedirect.com/science/article/pii/S0167739X18313359},
|
|
130
|
+
doi = {https://doi.org/10.1016/j.future.2018.08.004}
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
from collections import UserDict
|
|
2
|
+
from typing import Dict
|
|
3
|
+
import numpy as np
|
|
4
|
+
import logging
|
|
5
|
+
import re
|
|
6
|
+
|
|
7
|
+
from kernel_tuner.observers import OutputObserver
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class Tunable(UserDict):
|
|
11
|
+
def __init__(self, param_key: str, arrays: Dict):
|
|
12
|
+
"""The ``Tunable`` object can be used as an input argument when tuning
|
|
13
|
+
kernels. It is a container that holds several arrays internally and
|
|
14
|
+
selects one array during benchmarking based on the value of a tunable parameter.
|
|
15
|
+
|
|
16
|
+
Example
|
|
17
|
+
-------
|
|
18
|
+
Consider this example::
|
|
19
|
+
|
|
20
|
+
arg = Tunable("matrix_layout", dict("c"=matrix, "f"=matrix.transpose()))
|
|
21
|
+
|
|
22
|
+
In this example, we create a Tunable object that selects either matrix
|
|
23
|
+
or matrix.transpose() for benchmarking, depending on the value of the
|
|
24
|
+
tunable parameter "matrix_layout". The first argument is the name of the tunable
|
|
25
|
+
paramater. The second argument is a dictionary that maps the tunable parameter
|
|
26
|
+
values "c" and "f" to the arrays ``matrix`` and ``matrix.transpose()``, respectively.
|
|
27
|
+
During benchmarking, the Tunable object selects the array passed to the kernel based
|
|
28
|
+
on the value of "matrix_layout".
|
|
29
|
+
|
|
30
|
+
:param param_key: : The tunable parameter used to select the array for benchmarking.
|
|
31
|
+
:param arrays: A dictionary that maps the value of that tunable parameter to options.
|
|
32
|
+
"""
|
|
33
|
+
if isinstance(arrays, (tuple, list)):
|
|
34
|
+
arrays = dict(enumerate(arrays))
|
|
35
|
+
|
|
36
|
+
super().__init__(arrays)
|
|
37
|
+
self.param_key = param_key
|
|
38
|
+
|
|
39
|
+
def select_for_configuration(self, params):
|
|
40
|
+
if callable(self.param_key):
|
|
41
|
+
option = self.param_key(params)
|
|
42
|
+
elif self.param_key in params:
|
|
43
|
+
option = params[self.param_key]
|
|
44
|
+
else:
|
|
45
|
+
option = eval(self.param_key, params, params)
|
|
46
|
+
|
|
47
|
+
if option not in self.data:
|
|
48
|
+
list = ", ".join(map(str, self.data.keys()))
|
|
49
|
+
raise KeyError(
|
|
50
|
+
f"'{option}' is not a valid parameter value, should be one of: {list}"
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
return self.data[option]
|
|
54
|
+
|
|
55
|
+
def __call__(self, params):
|
|
56
|
+
return self.select_for_configuration(params)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _find_bfloat16_if_available():
|
|
60
|
+
# Try to get bfloat16 if available.
|
|
61
|
+
try:
|
|
62
|
+
from bfloat16 import bfloat16
|
|
63
|
+
return bfloat16
|
|
64
|
+
except ImportError:
|
|
65
|
+
pass
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
from tensorflow import bfloat16
|
|
69
|
+
return bfloat16.as_numpy_dtype
|
|
70
|
+
except ImportError:
|
|
71
|
+
pass
|
|
72
|
+
|
|
73
|
+
logging.warning(
|
|
74
|
+
"could not find `bfloat16` data type for numpy, "
|
|
75
|
+
+ "please install either the package `bfloat16` or `tensorflow`"
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
return None
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def _to_float_dtype(x: str) -> np.dtype:
|
|
82
|
+
"""Convert a string to a numpy data type (``dtype``). This function recognizes
|
|
83
|
+
common names (such as ``f16`` or ``kfloat``), and uses ``np.dtype(x)`` as a
|
|
84
|
+
fallback.
|
|
85
|
+
"""
|
|
86
|
+
if isinstance(x, str):
|
|
87
|
+
x = x.lower()
|
|
88
|
+
|
|
89
|
+
if x in ("bfloat16", "bf16", "kbfloat16", "__nv_bfloat16"):
|
|
90
|
+
result = _find_bfloat16_if_available()
|
|
91
|
+
if result is not None:
|
|
92
|
+
return result
|
|
93
|
+
|
|
94
|
+
if x in ("half", "f16", "float16", "__half", "khalf", 16):
|
|
95
|
+
return np.half
|
|
96
|
+
if x in ("float", "single", "f32", "float32", "kfloat", 32):
|
|
97
|
+
return np.float32
|
|
98
|
+
if x in ("double", "f64", "float64", "kdouble", 64):
|
|
99
|
+
return np.float64
|
|
100
|
+
|
|
101
|
+
return np.dtype(x)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class TunablePrecision(Tunable):
|
|
105
|
+
def __init__(
|
|
106
|
+
self, param_key: str, array: np.ndarray, dtypes: Dict[str, np.dtype] = None
|
|
107
|
+
):
|
|
108
|
+
"""The ``Tunable`` object can be used as an input argument when tuning
|
|
109
|
+
kernels. It is a container that internally holds several arrays
|
|
110
|
+
containing the same data, but stored in using different levels of
|
|
111
|
+
precision. During benchamrking, one array is selected based on the value
|
|
112
|
+
of the tunable parameter called ``param_key``.
|
|
113
|
+
|
|
114
|
+
Example
|
|
115
|
+
-------
|
|
116
|
+
Consider this example::
|
|
117
|
+
|
|
118
|
+
arg = TunablePrecision("matrix_type", matrix)
|
|
119
|
+
|
|
120
|
+
This creates a ``TunablePrecision`` argument that selects the required
|
|
121
|
+
floating-point precision for ``matrix`` based on the tunable parameter
|
|
122
|
+
``"matrix_type"``.
|
|
123
|
+
|
|
124
|
+
:param param_key: The tunable parameter used to select the level of precision.
|
|
125
|
+
:param array: The input array. It will automatically be converted to
|
|
126
|
+
all data types given by ``dtypes``.
|
|
127
|
+
:param dtypes: Dictionary that maps names to numpy data types. The default
|
|
128
|
+
types are ``double``, ``float``, and ``half``.
|
|
129
|
+
"""
|
|
130
|
+
# If no dtypes are given, generate a default list
|
|
131
|
+
if not dtypes:
|
|
132
|
+
dtypes = dict(half=np.half, float=np.single, double=np.double)
|
|
133
|
+
|
|
134
|
+
bfloat16 = _find_bfloat16_if_available()
|
|
135
|
+
if bfloat16 is not None:
|
|
136
|
+
dtypes["bfloat16"] = bfloat16
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
# If dtype is a list, convert it to a dictionary
|
|
140
|
+
if isinstance(dtypes, (list, tuple)):
|
|
141
|
+
dtypes = dict((name, _to_float_dtype(name)) for name in dtypes)
|
|
142
|
+
|
|
143
|
+
arrays = dict()
|
|
144
|
+
for precision, dtype in dtypes.items():
|
|
145
|
+
# We convert the array into a `np.ndarray` by using `np.array`.
|
|
146
|
+
# However, if the value is a numpy scalar, then we do not want to
|
|
147
|
+
# convert it into an array but instead keep the original value
|
|
148
|
+
if not isinstance(array, np.generic):
|
|
149
|
+
array = np.array(array)
|
|
150
|
+
|
|
151
|
+
arrays[precision] = array.astype(dtype)
|
|
152
|
+
|
|
153
|
+
super().__init__(param_key, arrays)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
def error_metric_from_name(user_key, EPS=1e-8):
|
|
157
|
+
"""Find the error metric function for the given name.
|
|
158
|
+
|
|
159
|
+
Returns an function that takes two parameters (the ground-truth and the
|
|
160
|
+
estimated values) as numpy arrays and returns the error between the two
|
|
161
|
+
according to the given error metric.
|
|
162
|
+
|
|
163
|
+
Valid values for the ``key`` are:
|
|
164
|
+
|
|
165
|
+
* MSE (mean square error)
|
|
166
|
+
* RSME (Root mean square error)
|
|
167
|
+
* NRMSE (normalized root mean square error)
|
|
168
|
+
* RMSRE (root mean square relative error)
|
|
169
|
+
* RMSLE (root mean square log error)
|
|
170
|
+
* MAE (mean absolute error)
|
|
171
|
+
* MRE (mean relative error)
|
|
172
|
+
* MALE (mean absolute log error)
|
|
173
|
+
* max (maximum absolute error)
|
|
174
|
+
* max rel (maximum relative error)
|
|
175
|
+
|
|
176
|
+
The value of `EPS` is used for relative errors to prevent division by zero.
|
|
177
|
+
``
|
|
178
|
+
"""
|
|
179
|
+
|
|
180
|
+
# Prepocess the provided name:
|
|
181
|
+
# - convert to lowercase
|
|
182
|
+
# - remove the word "error"
|
|
183
|
+
# - remove underscores and dashes
|
|
184
|
+
# - strip whitespaces
|
|
185
|
+
# - replace common abreviations
|
|
186
|
+
key = user_key.lower()
|
|
187
|
+
key = re.sub(r"\berror\b", " ", key)
|
|
188
|
+
key = re.sub(r"[\s_-]+", " ", key)
|
|
189
|
+
key = key.strip()
|
|
190
|
+
|
|
191
|
+
replacements = {
|
|
192
|
+
"average": "mean",
|
|
193
|
+
"avg": "mean",
|
|
194
|
+
"square": "squared",
|
|
195
|
+
"sq": "squared",
|
|
196
|
+
"max": "maximum",
|
|
197
|
+
"rel": "relative",
|
|
198
|
+
"abs": "absolute",
|
|
199
|
+
"log": "logarithmic",
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
for pattern, replacement in replacements.items():
|
|
203
|
+
key = re.sub(rf"\b{pattern}\b", replacement, key)
|
|
204
|
+
|
|
205
|
+
# Select the right metric
|
|
206
|
+
if key in ("mse", "mean squared"):
|
|
207
|
+
|
|
208
|
+
def metric(a, b):
|
|
209
|
+
return np.average(np.square(a - b))
|
|
210
|
+
|
|
211
|
+
elif key in ("rmse", "root mean squared"):
|
|
212
|
+
|
|
213
|
+
def metric(a, b):
|
|
214
|
+
return np.sqrt(np.average(np.square(a - b)))
|
|
215
|
+
|
|
216
|
+
elif key in ("nrmse", "normalized root mean squared"):
|
|
217
|
+
|
|
218
|
+
def metric(a, b):
|
|
219
|
+
return np.sqrt(np.average(np.square(a - b)) / np.average(np.square(a)))
|
|
220
|
+
|
|
221
|
+
elif key in ("mae", "absolute", "mean absolute"):
|
|
222
|
+
|
|
223
|
+
def metric(a, b):
|
|
224
|
+
return np.average(np.abs(a - b))
|
|
225
|
+
|
|
226
|
+
elif key in ("mre", "relative", "mean relative"):
|
|
227
|
+
|
|
228
|
+
def metric(a, b):
|
|
229
|
+
return np.average(np.abs(a - b) / np.maximum(np.abs(a), EPS))
|
|
230
|
+
|
|
231
|
+
elif key in ("rmsre", "root mean squared relative"):
|
|
232
|
+
|
|
233
|
+
def metric(a, b):
|
|
234
|
+
return np.sqrt(np.average(np.square(a - b) / np.square(np.maximum(a, EPS))))
|
|
235
|
+
|
|
236
|
+
elif key in ("male", "mean absolute logarithmic"):
|
|
237
|
+
|
|
238
|
+
def metric(a, b):
|
|
239
|
+
return np.average(np.abs(np.log10(a + EPS) - np.log10(b + EPS)))
|
|
240
|
+
|
|
241
|
+
elif key in ("rmsle", "root mean squared logarithmic"):
|
|
242
|
+
|
|
243
|
+
def metric(a, b):
|
|
244
|
+
return np.sqrt(np.average(np.square(np.log10(a + EPS) - np.log10(b + EPS))))
|
|
245
|
+
|
|
246
|
+
elif key in ("maximum absolute", "maximum"):
|
|
247
|
+
|
|
248
|
+
def metric(a, b):
|
|
249
|
+
return np.amax(np.abs(a - b))
|
|
250
|
+
|
|
251
|
+
elif key in ("maximum relative",):
|
|
252
|
+
|
|
253
|
+
def metric(a, b):
|
|
254
|
+
return np.amax(np.abs(a - b) / np.maximum(np.abs(a), EPS))
|
|
255
|
+
|
|
256
|
+
else:
|
|
257
|
+
raise ValueError(f"invalid error metric provided: {user_key}")
|
|
258
|
+
|
|
259
|
+
# cast both arguments to f64 before passing them to the metric
|
|
260
|
+
return lambda a, b: metric(
|
|
261
|
+
a.astype(np.float64, copy=False), b.astype(np.float64, copy=False)
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
class AccuracyObserver(OutputObserver):
|
|
266
|
+
"""``AccuracyObserver`` measures the error on the output produced by a kernel
|
|
267
|
+
by comparing the output against a reference output.
|
|
268
|
+
|
|
269
|
+
By default, it uses the root mean-squared error (RMSE) and uses the
|
|
270
|
+
metric name ``"error"``.
|
|
271
|
+
"""
|
|
272
|
+
|
|
273
|
+
def __init__(self, metric=None, key="error", *, atol=1e-8):
|
|
274
|
+
"""Create a new ``AccuracyObserver``.
|
|
275
|
+
|
|
276
|
+
:param metric: The error metric. This should be a string that is
|
|
277
|
+
accepted by ``error_metric_from_name`` such as ``"absolute error"``
|
|
278
|
+
or ``"relative error"``. Alternatively, it can be a
|
|
279
|
+
function that accepts two numpy arrays as arguments
|
|
280
|
+
(the reference output and the kernel output)
|
|
281
|
+
:param key: The name of this metric in the results.
|
|
282
|
+
:param atol: The tolerance used in relative metrics to prevent
|
|
283
|
+
division by zero. It is ignored by absolute error metrics.
|
|
284
|
+
"""
|
|
285
|
+
|
|
286
|
+
# Default metric is RMSE
|
|
287
|
+
if not metric:
|
|
288
|
+
metric = "rmse"
|
|
289
|
+
|
|
290
|
+
# If it is a string, convert it to a function
|
|
291
|
+
if isinstance(metric, str):
|
|
292
|
+
metric = error_metric_from_name(metric, atol)
|
|
293
|
+
|
|
294
|
+
self.key = key
|
|
295
|
+
self.metric = metric
|
|
296
|
+
self.result = None
|
|
297
|
+
|
|
298
|
+
def process_output(self, answers, outputs):
|
|
299
|
+
errors = []
|
|
300
|
+
|
|
301
|
+
for answer, output in zip(answers, outputs):
|
|
302
|
+
if answer is not None:
|
|
303
|
+
errors.append(self.metric(answer, output))
|
|
304
|
+
|
|
305
|
+
self.result = max(errors)
|
|
306
|
+
|
|
307
|
+
def get_results(self):
|
|
308
|
+
return dict([(self.key, self.result)])
|