kernel-tuner 1.2.0__tar.gz → 1.3.1__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 (119) hide show
  1. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/PKG-INFO +5 -4
  2. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/accuracy.py +33 -12
  3. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/backends/cupy.py +0 -1
  4. kernel_tuner-1.3.1/kernel_tuner/backends/hip/__init__.py +1 -0
  5. {kernel_tuner-1.2.0/kernel_tuner/backends → kernel_tuner-1.3.1/kernel_tuner/backends/hip}/hip.py +1 -14
  6. kernel_tuner-1.3.1/kernel_tuner/backends/hip/util.py +18 -0
  7. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/backends/hypertuner.py +82 -27
  8. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/backends/nvcuda.py +45 -52
  9. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/core.py +5 -2
  10. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/file_utils.py +24 -1
  11. kernel_tuner-1.3.1/kernel_tuner/hyper.py +215 -0
  12. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/integration.py +4 -4
  13. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/interface.py +95 -43
  14. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/observers/hip.py +2 -1
  15. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/observers/nvcuda.py +8 -4
  16. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/runners/simulation.py +28 -3
  17. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/schema/T1/1.0.0/input-schema.json +2 -1
  18. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/schema/T4/1.0.0/results-schema.json +5 -1
  19. kernel_tuner-1.3.1/kernel_tuner/searchspace.py +1594 -0
  20. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/basinhopping.py +2 -2
  21. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/bayes_opt.py +11 -9
  22. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/brute_force.py +1 -1
  23. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/common.py +117 -37
  24. kernel_tuner-1.3.1/kernel_tuner/strategies/diff_evo.py +409 -0
  25. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/dual_annealing.py +6 -5
  26. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/firefly_algorithm.py +10 -8
  27. kernel_tuner-1.3.1/kernel_tuner/strategies/genetic_algorithm.py +252 -0
  28. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/greedy_ils.py +9 -4
  29. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/greedy_mls.py +2 -2
  30. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/hillclimbers.py +1 -1
  31. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/minimize.py +2 -2
  32. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/pso.py +20 -14
  33. kernel_tuner-1.3.1/kernel_tuner/strategies/pyatf_strategies.py +123 -0
  34. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/random_sample.py +2 -2
  35. kernel_tuner-1.3.1/kernel_tuner/strategies/simulated_annealing.py +174 -0
  36. kernel_tuner-1.3.1/kernel_tuner/strategies/wrapper.py +56 -0
  37. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/util.py +39 -44
  38. kernel_tuner-1.3.1/kernel_tuner/utils/nvcuda.py +63 -0
  39. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/pyproject.toml +5 -3
  40. kernel_tuner-1.3.1/test/conftest.py +7 -0
  41. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/context.py +27 -5
  42. kernel_tuner-1.3.1/test/strategies/test_cache_file.json +394 -0
  43. kernel_tuner-1.3.1/test/strategies/test_diff_evo.py +189 -0
  44. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/strategies/test_genetic_algorithm.py +9 -4
  45. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/strategies/test_strategies.py +55 -17
  46. kernel_tuner-1.3.1/test/test_cache_file_T1_input.json +82 -0
  47. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_compiler_functions.py +2 -2
  48. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_cuda_functions.py +3 -3
  49. kernel_tuner-1.3.1/test/test_custom_optimizer.py +174 -0
  50. kernel_tuner-1.3.1/test/test_hyper.py +39 -0
  51. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_integration.py +6 -6
  52. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_kernelbuilder.py +2 -2
  53. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_runners.py +10 -4
  54. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_searchspace.py +207 -0
  55. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_util_functions.py +0 -10
  56. kernel_tuner-1.3.1/test/utils/__init__.py +0 -0
  57. kernel_tuner-1.3.1/test/utils/nvcuda.py +11 -0
  58. kernel_tuner-1.3.1/test/vector_add.cu +6 -0
  59. kernel_tuner-1.2.0/kernel_tuner/hyper.py +0 -98
  60. kernel_tuner-1.2.0/kernel_tuner/searchspace.py +0 -839
  61. kernel_tuner-1.2.0/kernel_tuner/strategies/diff_evo.py +0 -42
  62. kernel_tuner-1.2.0/kernel_tuner/strategies/genetic_algorithm.py +0 -181
  63. kernel_tuner-1.2.0/kernel_tuner/strategies/simulated_annealing.py +0 -120
  64. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/LICENSE +0 -0
  65. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/README.md +0 -0
  66. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/__init__.py +0 -0
  67. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/backends/__init__.py +0 -0
  68. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/backends/backend.py +0 -0
  69. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/backends/compiler.py +0 -0
  70. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/backends/opencl.py +0 -0
  71. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/backends/pycuda.py +0 -0
  72. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/energy/__init__.py +0 -0
  73. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/energy/energy.py +0 -0
  74. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/kernelbuilder.py +0 -0
  75. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/observers/__init__.py +0 -0
  76. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/observers/compiler.py +0 -0
  77. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/observers/cupy.py +0 -0
  78. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/observers/ncu.py +0 -0
  79. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/observers/nvml.py +0 -0
  80. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/observers/observer.py +0 -0
  81. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/observers/opencl.py +0 -0
  82. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/observers/pmt.py +0 -0
  83. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/observers/powersensor.py +0 -0
  84. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/observers/pycuda.py +0 -0
  85. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/observers/register.py +0 -0
  86. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/observers/tegra.py +0 -0
  87. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/runners/__init__.py +0 -0
  88. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/runners/runner.py +0 -0
  89. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/runners/sequential.py +0 -0
  90. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/schema/T4/1.0.0/metadata-schema.json +0 -0
  91. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/__init__.py +0 -0
  92. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/mls.py +0 -0
  93. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/strategies/ordered_greedy_mls.py +0 -0
  94. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/utils/__init__.py +0 -0
  95. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/kernel_tuner/utils/directives.py +0 -0
  96. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/__init__.py +0 -0
  97. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/convolution.cu +0 -0
  98. {kernel_tuner-1.2.0/test/utils → kernel_tuner-1.3.1/test/strategies}/__init__.py +0 -0
  99. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/strategies/test_bayesian_optimization.py +0 -0
  100. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/strategies/test_common.py +0 -0
  101. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/synthetic_fp32_cache_NVIDIA_RTX_A4000.json +0 -0
  102. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_T1_input.json +0 -0
  103. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_accuracy.py +0 -0
  104. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_backend.py +0 -0
  105. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_cache_file.json +0 -0
  106. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_common.py +0 -0
  107. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_core.py +0 -0
  108. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_cupy_functions.py +0 -0
  109. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_energy.py +0 -0
  110. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_file_utils.py +0 -0
  111. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_hip_functions.py +0 -0
  112. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_nvml_mocked.py +0 -0
  113. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_observers.py +0 -0
  114. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_opencl_functions.py +0 -0
  115. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_pycuda_functions.py +0 -0
  116. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_pycuda_mocked.py +0 -0
  117. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_time_budgets.py +0 -0
  118. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/test_toml_file.py +0 -0
  119. {kernel_tuner-1.2.0 → kernel_tuner-1.3.1}/test/utils/test_directives.py +0 -0
@@ -1,8 +1,9 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: kernel_tuner
3
- Version: 1.2.0
3
+ Version: 1.3.1
4
4
  Summary: An easy to use CUDA/OpenCL kernel tuner in Python
5
- License: Apache-2.0
5
+ License-Expression: Apache-2.0
6
+ License-File: LICENSE
6
7
  Keywords: auto-tuning,gpu,computing,pycuda,cuda,pyopencl,opencl
7
8
  Author: Ben van Werkhoven
8
9
  Author-email: b.vanwerkhoven@esciencecenter.nl
@@ -43,7 +44,7 @@ Requires-Dist: pycuda (>=2025.1) ; extra == "cuda"
43
44
  Requires-Dist: pynvml (>=11.4.1) ; extra == "cuda"
44
45
  Requires-Dist: pyopencl ; extra == "cuda-opencl"
45
46
  Requires-Dist: pyopencl ; extra == "opencl"
46
- Requires-Dist: python-constraint2 (>=2.3.1)
47
+ Requires-Dist: python-constraint2 (>=2.4.0)
47
48
  Requires-Dist: scikit-learn (>=1.0.2)
48
49
  Requires-Dist: scipy (>=1.14.1)
49
50
  Requires-Dist: xmltodict
@@ -58,22 +58,43 @@ class Tunable(UserDict):
58
58
 
59
59
  def _find_bfloat16_if_available():
60
60
  # Try to get bfloat16 if available.
61
- try:
62
- from bfloat16 import bfloat16
63
- return bfloat16
64
- except ImportError:
65
- pass
61
+ dtype = None
66
62
 
63
+ # get it via numpy if available
67
64
  try:
68
- from tensorflow import bfloat16
69
- return bfloat16.as_numpy_dtype
70
- except ImportError:
65
+ dtype = np.dtype("bfloat16")
66
+ except TypeError:
71
67
  pass
72
68
 
73
- logging.warning(
74
- "could not find `bfloat16` data type for numpy, "
75
- + "please install either the package `bfloat16` or `tensorflow`"
76
- )
69
+ # otherwise, try ml_dtypes
70
+ if dtype is None:
71
+ try:
72
+ from ml_dtypes import bfloat16
73
+ dtype = bfloat16
74
+ except ImportError:
75
+ pass
76
+
77
+ # otherwise, try jax
78
+ if dtype is None:
79
+ try:
80
+ from jax.numpy import bfloat16
81
+ dtype = bfloat16
82
+ except ImportError:
83
+ pass
84
+
85
+ # otherwise, try tensorflow
86
+ if dtype is None:
87
+ try:
88
+ from tensorflow import bfloat16
89
+ dtype = bfloat16.as_numpy_dtype
90
+ except ImportError:
91
+ pass
92
+
93
+ if dtype is None:
94
+ logging.warning(
95
+ "could not find `bfloat16` data type for numpy, "
96
+ + "please install either the package `ml_dtypes`, `jax`, or `tensorflow`"
97
+ )
77
98
 
78
99
  return None
79
100
 
@@ -1,6 +1,5 @@
1
1
  """This module contains all Cupy specific kernel_tuner functions."""
2
2
  from __future__ import print_function
3
- from warnings import warn
4
3
 
5
4
  import numpy as np
6
5
 
@@ -0,0 +1 @@
1
+ from .hip import *
@@ -8,6 +8,7 @@ import numpy as np
8
8
 
9
9
  from kernel_tuner.backends.backend import GPUBackend
10
10
  from kernel_tuner.observers.hip import HipRuntimeObserver
11
+ from kernel_tuner.backends.hip.util import hip_check
11
12
 
12
13
  try:
13
14
  from hip import hip, hiprtc
@@ -31,20 +32,6 @@ dtype_map = {
31
32
 
32
33
  hipSuccess = 0
33
34
 
34
-
35
- def hip_check(call_result):
36
- """helper function to check return values of hip calls"""
37
- err = call_result[0]
38
- result = call_result[1:]
39
- if len(result) == 1:
40
- result = result[0]
41
- if isinstance(err, hip.hipError_t) and err != hip.hipError_t.hipSuccess:
42
- _, error_name = hip.hipGetErrorName(err)
43
- _, error_str = hip.hipGetErrorString(err)
44
- raise RuntimeError(f"{error_name}: {error_str}")
45
- return result
46
-
47
-
48
35
  class HipFunctions(GPUBackend):
49
36
  """Class that groups the HIP functions on maintains state about the device."""
50
37
 
@@ -0,0 +1,18 @@
1
+ try:
2
+ from hip import hip, hiprtc
3
+ except (ImportError, RuntimeError):
4
+ hip = None
5
+
6
+
7
+ def hip_check(call_result):
8
+ """helper function to check return values of hip calls"""
9
+ err = call_result[0]
10
+ result = call_result[1:]
11
+ if len(result) == 1:
12
+ result = result[0]
13
+ if isinstance(err, hip.hipError_t) and err != hip.hipError_t.hipSuccess:
14
+ _, error_name = hip.hipGetErrorName(err)
15
+ _, error_str = hip.hipGetErrorString(err)
16
+ raise RuntimeError(f"{error_name}: {error_str}")
17
+ return result
18
+
@@ -17,6 +17,8 @@ except ImportError:
17
17
 
18
18
 
19
19
  class ScoreObserver(BenchmarkObserver):
20
+ """BenchmarkObserver subclass for registering the hyperparameter tuning score."""
21
+
20
22
  def __init__(self, dev):
21
23
  self.dev = dev
22
24
  self.scores = []
@@ -33,13 +35,70 @@ class HypertunerFunctions(Backend):
33
35
  """Class for executing hyperparameter tuning."""
34
36
  units = {}
35
37
 
36
- def __init__(self, iterations):
38
+ def __init__(self, iterations, compiler_options=None):
37
39
  self.iterations = iterations
40
+ self.compiler_options = compiler_options
38
41
  self.observers = [ScoreObserver(self)]
39
42
  self.name = platform.processor()
40
43
  self.max_threads = 1024
41
44
  self.last_score = None
42
45
 
46
+ # set the defaults
47
+ self.gpus = ["A100", "A4000", "MI250X"]
48
+ folder = "../autotuning_methodology/benchmark_hub/kernels"
49
+ self.applications = [
50
+ {
51
+ "name": "dedispersion_milo",
52
+ "folder": folder,
53
+ "input_file": "dedispersion_milo.json",
54
+ "objective_performance_keys": ["time"]
55
+ },
56
+ {
57
+ "name": "hotspot_milo",
58
+ "folder": folder,
59
+ "input_file": "hotspot_milo.json",
60
+ "objective_performance_keys": ["GFLOP/s"]
61
+ },
62
+ {
63
+ "name": "convolution_milo",
64
+ "folder": folder,
65
+ "input_file": "convolution_milo.json",
66
+ "objective_performance_keys": ["time"]
67
+ },
68
+ {
69
+ "name": "gemm_milo",
70
+ "folder": folder,
71
+ "input_file": "gemm_milo.json",
72
+ "objective_performance_keys": ["time"]
73
+ }
74
+ ]
75
+ # any additional settings
76
+ self.override = {
77
+ "experimental_groups_defaults": {
78
+ "repeats": 25,
79
+ "samples": self.iterations,
80
+ "minimum_fraction_of_budget_valid": 0.1,
81
+ "minimum_number_of_valid_search_iterations": 3,
82
+ },
83
+ "statistics_settings": {
84
+ "cutoff_percentile": 0.95,
85
+ "cutoff_percentile_start": 0.01,
86
+ "cutoff_type": "time",
87
+ "objective_time_keys": [
88
+ "all"
89
+ ]
90
+ }
91
+ }
92
+
93
+ # override the defaults with compiler options if provided
94
+ if self.compiler_options is not None:
95
+ if "gpus" in self.compiler_options:
96
+ self.gpus = self.compiler_options["gpus"]
97
+ if "applications" in self.compiler_options:
98
+ self.applications = self.compiler_options["applications"]
99
+ if "override" in self.compiler_options:
100
+ self.override = self.compiler_options["override"]
101
+
43
102
  # set the environment options
44
103
  env = dict()
45
104
  env["iterations"] = self.iterations
@@ -60,22 +119,6 @@ class HypertunerFunctions(Backend):
60
119
  path = Path(__file__).parent.parent.parent / "hyperparamtuning"
61
120
  path.mkdir(exist_ok=True)
62
121
 
63
- # TODO get applications & GPUs args from benchmark
64
- gpus = ["RTX_3090", "RTX_2080_Ti"]
65
- applications = None
66
- # applications = [
67
- # {
68
- # "name": "convolution",
69
- # "folder": "./cached_data_used/kernels",
70
- # "input_file": "convolution.json"
71
- # },
72
- # {
73
- # "name": "pnpoly",
74
- # "folder": "./cached_data_used/kernels",
75
- # "input_file": "pnpoly.json"
76
- # }
77
- # ]
78
-
79
122
  # strategy settings
80
123
  strategy: str = kernel_instance.arguments[0]
81
124
  hyperparams = [{'name': k, 'value': v} for k, v in kernel_instance.params.items()]
@@ -88,16 +131,9 @@ class HypertunerFunctions(Backend):
88
131
  'search_method_hyperparameters': hyperparams
89
132
  }]
90
133
 
91
- # any additional settings
92
- override = {
93
- "experimental_groups_defaults": {
94
- "samples": self.iterations
95
- }
96
- }
97
-
98
134
  name = kernel_instance.name if len(kernel_instance.name) > 0 else kernel_instance.kernel_source.kernel_name
99
- experiments_filepath = generate_experiment_file(name, path, searchspace_strategies, applications, gpus,
100
- override=override, overwrite_existing_file=True)
135
+ experiments_filepath = generate_experiment_file(name, path, searchspace_strategies, self.applications, self.gpus,
136
+ override=self.override, generate_unique_file=True, overwrite_existing_file=True)
101
137
  return str(experiments_filepath)
102
138
 
103
139
  def start_event(self):
@@ -114,12 +150,27 @@ class HypertunerFunctions(Backend):
114
150
  return super().synchronize()
115
151
 
116
152
  def run_kernel(self, func, gpu_args=None, threads=None, grid=None, stream=None):
153
+ # from cProfile import Profile
154
+
155
+ # # generate the experiments file
156
+ # experiments_filepath = Path(func)
157
+
158
+ # # run the methodology to get a fitness score for this configuration
159
+ # with Profile() as pr:
160
+ # scores = get_strategy_scores(str(experiments_filepath), full_validate_on_load=False)
161
+ # pr.dump_stats('diff_evo_hypertune_hotspot.prof')
162
+ # self.last_score = scores[list(scores.keys())[0]]['score']
163
+ # raise ValueError(scores)
164
+
117
165
  # generate the experiments file
118
166
  experiments_filepath = Path(func)
119
167
 
120
168
  # run the methodology to get a fitness score for this configuration
121
- scores = get_strategy_scores(str(experiments_filepath))
169
+ scores = get_strategy_scores(str(experiments_filepath), full_validate_on_load=False)
122
170
  self.last_score = scores[list(scores.keys())[0]]['score']
171
+
172
+ # remove the experiments file
173
+ experiments_filepath.unlink()
123
174
 
124
175
  def memset(self, allocation, value, size):
125
176
  return super().memset(allocation, value, size)
@@ -129,3 +180,7 @@ class HypertunerFunctions(Backend):
129
180
 
130
181
  def memcpy_htod(self, dest, src):
131
182
  return super().memcpy_htod(dest, src)
183
+
184
+ def refresh_memory(self, device_memory, host_arguments, should_sync):
185
+ """This is a no-op for the hypertuner backend, as it does not manage memory directly."""
186
+ pass
@@ -5,18 +5,23 @@ import numpy as np
5
5
 
6
6
  from kernel_tuner.backends.backend import GPUBackend
7
7
  from kernel_tuner.observers.nvcuda import CudaRuntimeObserver
8
- from kernel_tuner.util import SkippableFailure, cuda_error_check, to_valid_nvrtc_gpu_arch_cc
8
+ from kernel_tuner.util import SkippableFailure
9
+ from kernel_tuner.utils.nvcuda import cuda_error_check, to_valid_nvrtc_gpu_arch_cc
9
10
 
10
11
  # embedded in try block to be able to generate documentation
11
12
  # and run tests without cuda-python installed
12
13
  try:
13
- from cuda import cuda, cudart, nvrtc
14
+ from cuda.bindings import driver, runtime, nvrtc
14
15
  except ImportError:
15
- cuda = None
16
+ try:
17
+ # backward compatibility hack for older cuda-python versions
18
+ from cuda import cuda as driver, cudart as runtime, nvrtc as nvrtc
19
+ except ImportError:
20
+ driver = None
16
21
 
17
22
 
18
23
  class CudaFunctions(GPUBackend):
19
- """Class that groups the Cuda functions on maintains state about the device."""
24
+ """Class that groups the Cuda functions and it maintains state about the device."""
20
25
 
21
26
  def __init__(self, device=0, iterations=7, compiler_options=None, observers=None):
22
27
  """Instantiate CudaFunctions object used for interacting with the CUDA device.
@@ -38,34 +43,30 @@ class CudaFunctions(GPUBackend):
38
43
  """
39
44
  self.allocations = []
40
45
  self.texrefs = []
41
- if not cuda:
46
+ if not driver:
42
47
  raise ImportError(
43
48
  "cuda-python not installed, install using 'pip install cuda-python', or check https://kerneltuner.github.io/kernel_tuner/stable/install.html#cuda-and-pycuda."
44
49
  )
45
50
 
46
51
  # initialize and select device
47
- err = cuda.cuInit(0)
52
+ err = driver.cuInit(0)
48
53
  cuda_error_check(err)
49
- err, self.device = cuda.cuDeviceGet(device)
54
+ err, self.device = driver.cuDeviceGet(device)
50
55
  cuda_error_check(err)
51
- err, self.context = cuda.cuDevicePrimaryCtxRetain(device)
56
+ err, self.context = driver.cuDevicePrimaryCtxRetain(device)
52
57
  cuda_error_check(err)
53
58
  if CudaFunctions.last_selected_device != device:
54
- err = cuda.cuCtxSetCurrent(self.context)
59
+ err = driver.cuCtxSetCurrent(self.context)
55
60
  cuda_error_check(err)
56
61
  CudaFunctions.last_selected_device = device
57
62
 
58
63
  # compute capabilities and device properties
59
- err, major = cudart.cudaDeviceGetAttribute(
60
- cudart.cudaDeviceAttr.cudaDevAttrComputeCapabilityMajor, device
61
- )
64
+ err, major = runtime.cudaDeviceGetAttribute(runtime.cudaDeviceAttr.cudaDevAttrComputeCapabilityMajor, device)
62
65
  cuda_error_check(err)
63
- err, minor = cudart.cudaDeviceGetAttribute(
64
- cudart.cudaDeviceAttr.cudaDevAttrComputeCapabilityMinor, device
65
- )
66
+ err, minor = runtime.cudaDeviceGetAttribute(runtime.cudaDeviceAttr.cudaDevAttrComputeCapabilityMinor, device)
66
67
  cuda_error_check(err)
67
- err, self.max_threads = cudart.cudaDeviceGetAttribute(
68
- cudart.cudaDeviceAttr.cudaDevAttrMaxThreadsPerBlock, device
68
+ err, self.max_threads = runtime.cudaDeviceGetAttribute(
69
+ runtime.cudaDeviceAttr.cudaDevAttrMaxThreadsPerBlock, device
69
70
  )
70
71
  cuda_error_check(err)
71
72
  self.cc = f"{major}{minor}"
@@ -78,11 +79,11 @@ class CudaFunctions(GPUBackend):
78
79
  self.compiler_options_bytes.append(str(option).encode("UTF-8"))
79
80
 
80
81
  # create a stream and events
81
- err, self.stream = cuda.cuStreamCreate(0)
82
+ err, self.stream = driver.cuStreamCreate(0)
82
83
  cuda_error_check(err)
83
- err, self.start = cuda.cuEventCreate(0)
84
+ err, self.start = driver.cuEventCreate(0)
84
85
  cuda_error_check(err)
85
- err, self.end = cuda.cuEventCreate(0)
86
+ err, self.end = driver.cuEventCreate(0)
86
87
  cuda_error_check(err)
87
88
 
88
89
  # default dynamically allocated shared memory size, can be overwritten using smem_args
@@ -95,11 +96,11 @@ class CudaFunctions(GPUBackend):
95
96
  observer.register_device(self)
96
97
 
97
98
  # collect environment information
98
- err, device_properties = cudart.cudaGetDeviceProperties(device)
99
+ err, device_properties = runtime.cudaGetDeviceProperties(device)
99
100
  cuda_error_check(err)
100
101
  env = dict()
101
102
  env["device_name"] = device_properties.name.decode()
102
- env["cuda_version"] = cuda.CUDA_VERSION
103
+ env["cuda_version"] = driver.CUDA_VERSION
103
104
  env["compute_capability"] = self.cc
104
105
  env["iterations"] = self.iterations
105
106
  env["compiler_options"] = self.compiler_options
@@ -109,8 +110,8 @@ class CudaFunctions(GPUBackend):
109
110
 
110
111
  def __del__(self):
111
112
  for device_memory in self.allocations:
112
- if isinstance(device_memory, cuda.CUdeviceptr):
113
- err = cuda.cuMemFree(device_memory)
113
+ if isinstance(device_memory, driver.CUdeviceptr):
114
+ err = driver.cuMemFree(device_memory)
114
115
  cuda_error_check(err)
115
116
 
116
117
  def ready_argument_list(self, arguments):
@@ -128,7 +129,7 @@ class CudaFunctions(GPUBackend):
128
129
  for arg in arguments:
129
130
  # if arg is a numpy array copy it to device
130
131
  if isinstance(arg, np.ndarray):
131
- err, device_memory = cuda.cuMemAlloc(arg.nbytes)
132
+ err, device_memory = driver.cuMemAlloc(arg.nbytes)
132
133
  cuda_error_check(err)
133
134
  self.allocations.append(device_memory)
134
135
  gpu_args.append(device_memory)
@@ -164,38 +165,30 @@ class CudaFunctions(GPUBackend):
164
165
  if not any(["--std=" in opt for opt in self.compiler_options]):
165
166
  self.compiler_options.append("--std=c++11")
166
167
  if not any([b"--gpu-architecture=" in opt or b"-arch" in opt for opt in compiler_options]):
167
- compiler_options.append(
168
- f"--gpu-architecture=compute_{to_valid_nvrtc_gpu_arch_cc(self.cc)}".encode("UTF-8")
169
- )
168
+ compiler_options.append(f"--gpu-architecture=compute_{to_valid_nvrtc_gpu_arch_cc(self.cc)}".encode("UTF-8"))
170
169
  if not any(["--gpu-architecture=" in opt or "-arch" in opt for opt in self.compiler_options]):
171
170
  self.compiler_options.append(f"--gpu-architecture=compute_{to_valid_nvrtc_gpu_arch_cc(self.cc)}")
172
171
 
173
- err, program = nvrtc.nvrtcCreateProgram(
174
- str.encode(kernel_string), b"CUDAProgram", 0, [], []
175
- )
172
+ err, program = nvrtc.nvrtcCreateProgram(str.encode(kernel_string), b"CUDAProgram", 0, [], [])
176
173
  try:
177
174
  cuda_error_check(err)
178
- err = nvrtc.nvrtcCompileProgram(
179
- program, len(compiler_options), compiler_options
180
- )
175
+ err = nvrtc.nvrtcCompileProgram(program, len(compiler_options), compiler_options)
181
176
  cuda_error_check(err)
182
177
  err, size = nvrtc.nvrtcGetPTXSize(program)
183
178
  cuda_error_check(err)
184
179
  buff = b" " * size
185
180
  err = nvrtc.nvrtcGetPTX(program, buff)
186
181
  cuda_error_check(err)
187
- err, self.current_module = cuda.cuModuleLoadData(np.char.array(buff))
188
- if err == cuda.CUresult.CUDA_ERROR_INVALID_PTX:
182
+ err, self.current_module = driver.cuModuleLoadData(np.char.array(buff))
183
+ if err == driver.CUresult.CUDA_ERROR_INVALID_PTX:
189
184
  raise SkippableFailure("uses too much shared data")
190
185
  else:
191
186
  cuda_error_check(err)
192
- err, self.func = cuda.cuModuleGetFunction(
193
- self.current_module, str.encode(kernel_name)
194
- )
187
+ err, self.func = driver.cuModuleGetFunction(self.current_module, str.encode(kernel_name))
195
188
  cuda_error_check(err)
196
189
 
197
190
  # get the number of registers per thread used in this kernel
198
- num_regs = cuda.cuFuncGetAttribute(cuda.CUfunction_attribute.CU_FUNC_ATTRIBUTE_NUM_REGS, self.func)
191
+ num_regs = driver.cuFuncGetAttribute(driver.CUfunction_attribute.CU_FUNC_ATTRIBUTE_NUM_REGS, self.func)
199
192
  assert num_regs[0] == 0, f"Retrieving number of registers per thread unsuccesful: code {num_regs[0]}"
200
193
  self.num_regs = num_regs[1]
201
194
 
@@ -210,18 +203,18 @@ class CudaFunctions(GPUBackend):
210
203
 
211
204
  def start_event(self):
212
205
  """Records the event that marks the start of a measurement."""
213
- err = cudart.cudaEventRecord(self.start, self.stream)
206
+ err = runtime.cudaEventRecord(self.start, self.stream)
214
207
  cuda_error_check(err)
215
208
 
216
209
  def stop_event(self):
217
210
  """Records the event that marks the end of a measurement."""
218
- err = cudart.cudaEventRecord(self.end, self.stream)
211
+ err = runtime.cudaEventRecord(self.end, self.stream)
219
212
  cuda_error_check(err)
220
213
 
221
214
  def kernel_finished(self):
222
215
  """Returns True if the kernel has finished, False otherwise."""
223
- err = cudart.cudaEventQuery(self.end)
224
- if err[0] == cudart.cudaError_t.cudaSuccess:
216
+ err = runtime.cudaEventQuery(self.end)
217
+ if err[0] == runtime.cudaError_t.cudaSuccess:
225
218
  return True
226
219
  else:
227
220
  return False
@@ -229,7 +222,7 @@ class CudaFunctions(GPUBackend):
229
222
  @staticmethod
230
223
  def synchronize():
231
224
  """Halts execution until device has finished its tasks."""
232
- err = cudart.cudaDeviceSynchronize()
225
+ err = runtime.cudaDeviceSynchronize()
233
226
  cuda_error_check(err)
234
227
 
235
228
  def copy_constant_memory_args(self, cmem_args):
@@ -243,9 +236,9 @@ class CudaFunctions(GPUBackend):
243
236
  :type cmem_args: dict( string: numpy.ndarray, ... )
244
237
  """
245
238
  for k, v in cmem_args.items():
246
- err, symbol, _ = cuda.cuModuleGetGlobal(self.current_module, str.encode(k))
239
+ err, symbol, _ = driver.cuModuleGetGlobal(self.current_module, str.encode(k))
247
240
  cuda_error_check(err)
248
- err = cuda.cuMemcpyHtoD(symbol, v, v.nbytes)
241
+ err = driver.cuMemcpyHtoD(symbol, v, v.nbytes)
249
242
  cuda_error_check(err)
250
243
 
251
244
  def copy_shared_memory_args(self, smem_args):
@@ -284,12 +277,12 @@ class CudaFunctions(GPUBackend):
284
277
  stream = self.stream
285
278
  arg_types = list()
286
279
  for arg in gpu_args:
287
- if isinstance(arg, cuda.CUdeviceptr):
280
+ if isinstance(arg, driver.CUdeviceptr):
288
281
  arg_types.append(None)
289
282
  else:
290
283
  arg_types.append(np.ctypeslib.as_ctypes_type(arg.dtype))
291
284
  kernel_args = (tuple(gpu_args), tuple(arg_types))
292
- err = cuda.cuLaunchKernel(
285
+ err = driver.cuLaunchKernel(
293
286
  func,
294
287
  grid[0],
295
288
  grid[1],
@@ -318,7 +311,7 @@ class CudaFunctions(GPUBackend):
318
311
  :type size: int
319
312
 
320
313
  """
321
- err = cudart.cudaMemset(allocation, value, size)
314
+ err = runtime.cudaMemset(allocation, value, size)
322
315
  cuda_error_check(err)
323
316
 
324
317
  @staticmethod
@@ -331,7 +324,7 @@ class CudaFunctions(GPUBackend):
331
324
  :param src: A GPU memory allocation unit
332
325
  :type src: cuda.CUdeviceptr
333
326
  """
334
- err = cuda.cuMemcpyDtoH(dest, src, dest.nbytes)
327
+ err = driver.cuMemcpyDtoH(dest, src, dest.nbytes)
335
328
  cuda_error_check(err)
336
329
 
337
330
  @staticmethod
@@ -344,7 +337,7 @@ class CudaFunctions(GPUBackend):
344
337
  :param src: A numpy array in host memory to store the data
345
338
  :type src: numpy.ndarray
346
339
  """
347
- err = cuda.cuMemcpyHtoD(dest, src, src.nbytes)
340
+ err = driver.cuMemcpyHtoD(dest, src, src.nbytes)
348
341
  cuda_error_check(err)
349
342
 
350
343
  units = {"time": "ms"}
@@ -315,10 +315,13 @@ class DeviceInterface(object):
315
315
  observers=observers,
316
316
  )
317
317
  elif lang.upper() == "HYPERTUNER":
318
- dev = HypertunerFunctions(iterations=iterations)
318
+ dev = HypertunerFunctions(
319
+ iterations=iterations,
320
+ compiler_options=compiler_options
321
+ )
319
322
  self.requires_warmup = False
320
323
  else:
321
- raise ValueError(
324
+ raise NotImplementedError(
322
325
  "Sorry, support for languages other than CUDA, OpenCL, HIP, C, and Fortran is not implemented yet"
323
326
  )
324
327
  self.dev = dev
@@ -3,6 +3,7 @@
3
3
  import json
4
4
  import subprocess
5
5
  from importlib.metadata import PackageNotFoundError, requires, version
6
+ from importlib.util import spec_from_file_location, module_from_spec
6
7
  from pathlib import Path
7
8
  from sys import platform
8
9
 
@@ -152,7 +153,7 @@ def get_t4_results(results, tune_params, objective="time"):
152
153
 
153
154
  # write output_data to a JSON file
154
155
  version, _ = output_file_schema("results")
155
- output_json = dict(results=output_data, schema_version=version, metadata={'timeunit': 'miliseconds'})
156
+ output_json = dict(results=output_data, schema_version=version, metadata={'timeunit': 'milliseconds'})
156
157
  return output_json
157
158
 
158
159
  def store_output_file(output_filename: str, results, tune_params, objective="time"):
@@ -302,3 +303,25 @@ def store_metadata_file(metadata_filename: str):
302
303
  with open(metadata_filenamepath, "w+") as fh:
303
304
  json.dump(metadata_json, fh, indent=" ")
304
305
 
306
+ def import_class_from_file(file_path: Path, class_name):
307
+ """Import a class from a file."""
308
+
309
+ def load_module(module_name):
310
+ spec = spec_from_file_location(module_name, file_path)
311
+ if spec is None:
312
+ raise ImportError(f"Could not load spec from {file_path}")
313
+
314
+ # create a module from the spec and execute it
315
+ module = module_from_spec(spec)
316
+ spec.loader.exec_module(module)
317
+ if not hasattr(module, class_name):
318
+ raise ImportError(f"Module '{module_name}' has no class '{class_name}'")
319
+ return module
320
+
321
+ try:
322
+ module = load_module(file_path.stem)
323
+ except ImportError:
324
+ module = load_module(f"{file_path.parent.stem}.{file_path.stem}")
325
+
326
+ # return the class from the module
327
+ return getattr(module, class_name)