xobjects 0.6.7__tar.gz → 0.6.9__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.
- {xobjects-0.6.7/xobjects.egg-info → xobjects-0.6.9}/PKG-INFO +1 -1
- xobjects-0.6.9/tests/test_general.py +266 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_struct.py +7 -1
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/__init__.py +1 -0
- xobjects-0.6.9/xobjects/_version.py +1 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/context.py +3 -2
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/context_cpu.py +34 -36
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/context_cupy.py +22 -23
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/context_pyopencl.py +3 -2
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/general.py +11 -3
- xobjects-0.6.9/xobjects/settings.py +308 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/struct.py +7 -10
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/test_helpers.py +8 -14
- {xobjects-0.6.7 → xobjects-0.6.9/xobjects.egg-info}/PKG-INFO +1 -1
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects.egg-info/SOURCES.txt +2 -39
- xobjects-0.6.7/.github/workflows/black.yml +0 -10
- xobjects-0.6.7/.gitignore +0 -13
- xobjects-0.6.7/.pre-commit-config.yaml +0 -12
- xobjects-0.6.7/.readthedocs.yaml +0 -20
- xobjects-0.6.7/contributors_and_credits.txt +0 -7
- xobjects-0.6.7/docs/Makefile +0 -20
- xobjects-0.6.7/docs/architecture/contexts.rst +0 -164
- xobjects-0.6.7/docs/architecture/types.rst +0 -179
- xobjects-0.6.7/docs/architecture.rst +0 -16
- xobjects-0.6.7/docs/conf.py +0 -278
- xobjects-0.6.7/docs/index.rst +0 -79
- xobjects-0.6.7/docs/make.bat +0 -35
- xobjects-0.6.7/docs/quickstart.rst +0 -2
- xobjects-0.6.7/docs/reference.rst +0 -8
- xobjects-0.6.7/examples/api_def.py +0 -28
- xobjects-0.6.7/examples/api_init.py +0 -101
- xobjects-0.6.7/examples/capi_example.c +0 -100
- xobjects-0.6.7/examples/check_assembly.c +0 -101
- xobjects-0.6.7/examples/ex_array_init_perf.py +0 -42
- xobjects-0.6.7/examples/ex_cpugpu.py +0 -46
- xobjects-0.6.7/examples/ex_nested_ref.py +0 -49
- xobjects-0.6.7/examples/ex_ref_cpu.py +0 -52
- xobjects-0.6.7/examples/ex_struct_cpu.py +0 -39
- xobjects-0.6.7/examples/ex_unionref_cpu.py +0 -49
- xobjects-0.6.7/examples/ex_unionref_method.py +0 -120
- xobjects-0.6.7/examples/init_soa.py +0 -67
- xobjects-0.6.7/examples/issue_with_two_pyopencl_contexts.py +0 -18
- xobjects-0.6.7/examples/kernel_basics/kernel_cffi.py +0 -54
- xobjects-0.6.7/examples/kernel_basics/kernel_cupy.py +0 -42
- xobjects-0.6.7/examples/kernel_basics/kernel_pyopencl.py +0 -48
- xobjects-0.6.7/examples/opencl_offsets.py +0 -38
- xobjects-0.6.7/examples/simple_kernel.py +0 -59
- xobjects-0.6.7/examples/sixtracklib.py +0 -80
- xobjects-0.6.7/mktest +0 -1
- xobjects-0.6.7/release.sh +0 -20
- xobjects-0.6.7/requirements.txt +0 -3
- xobjects-0.6.7/tests/__init__.py +0 -4
- xobjects-0.6.7/tests/notest_capi.py +0 -208
- xobjects-0.6.7/update_cprght_statement.py +0 -49
- xobjects-0.6.7/xobjects/_version.py +0 -1
- {xobjects-0.6.7 → xobjects-0.6.9}/Architecture.md +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/LICENSE +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/MANIFEST.in +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/README.md +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/pyproject.toml +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/setup.cfg +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/setup.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_align.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_array.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_buffer.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_capi.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_chunk.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_common.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_context_opencl.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_hybrid_class.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_kernel.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_linked_array.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_nplike_arrays.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_ref.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_scalars.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_shared_memory.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_strides.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_string.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_to_dict.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_typeutils.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_unionref.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/_patch_pyopencl_array.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/array.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/capi.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/headers/atomicadd.h +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/headers/common.h +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/hybrid_class.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/linkedarray.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/ref.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/scalar.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/specialize_source.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/string.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/typeutils.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/union.py +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects.egg-info/dependency_links.txt +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects.egg-info/entry_points.txt +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects.egg-info/requires.txt +0 -0
- {xobjects-0.6.7 → xobjects-0.6.9}/xobjects.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import subprocess
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
import xobjects as xo
|
|
8
|
+
from xobjects.general import Print
|
|
9
|
+
from xobjects.test_helpers import allow_kernel_compilation
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_print_mode_default(capsys):
|
|
13
|
+
printer = Print()
|
|
14
|
+
|
|
15
|
+
printer('visible')
|
|
16
|
+
|
|
17
|
+
assert capsys.readouterr().out == 'visible\n'
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_print_mode_suppressed(capsys):
|
|
21
|
+
printer = Print()
|
|
22
|
+
with xo.settings.override(print_mode='suppress'):
|
|
23
|
+
printer('hidden')
|
|
24
|
+
|
|
25
|
+
assert capsys.readouterr().out == ''
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_settings_control_xsuite_printer(capsys):
|
|
29
|
+
with xo.settings.override(print_mode='suppress'):
|
|
30
|
+
xo._print('hidden')
|
|
31
|
+
|
|
32
|
+
assert capsys.readouterr().out == ''
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def test_python_setting_overrides_environment_default(capsys):
|
|
36
|
+
with xo.settings.override(print_mode='print'):
|
|
37
|
+
xo._print('visible')
|
|
38
|
+
|
|
39
|
+
assert capsys.readouterr().out == 'visible\n'
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def test_invalid_print_mode_setting():
|
|
43
|
+
with pytest.raises(ValueError, match='XSUITE_PRINT_MODE.*print.*suppress'):
|
|
44
|
+
xo.settings.print_mode = 'invalid'
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def test_settings_override_restores_value_after_error():
|
|
48
|
+
original = xo.settings.print_mode
|
|
49
|
+
|
|
50
|
+
with pytest.raises(RuntimeError):
|
|
51
|
+
with xo.settings.override(print_mode='suppress'):
|
|
52
|
+
assert xo.settings.print_mode == 'suppress'
|
|
53
|
+
raise RuntimeError
|
|
54
|
+
|
|
55
|
+
assert xo.settings.print_mode == original
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_settings_are_discoverable():
|
|
59
|
+
expected_settings = {
|
|
60
|
+
'print_mode',
|
|
61
|
+
'progress_indicator',
|
|
62
|
+
'allow_kernel_compilation',
|
|
63
|
+
'force_kernel_compilation',
|
|
64
|
+
'show_kernel_diagnostics',
|
|
65
|
+
'cffi_forbid_compile',
|
|
66
|
+
'cffi_keep_build_files',
|
|
67
|
+
'cuda_backend',
|
|
68
|
+
'cuda_fast_compile',
|
|
69
|
+
'cuda_compiler',
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
assert expected_settings <= set(dir(xo.settings))
|
|
73
|
+
for name in expected_settings:
|
|
74
|
+
assert f'{name}=' in repr(xo.settings)
|
|
75
|
+
assert name in type(xo.settings).__doc__
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_print_mode_environment_variable_is_startup_default():
|
|
79
|
+
environment = os.environ.copy()
|
|
80
|
+
environment['XSUITE_PRINT_MODE'] = 'suppress'
|
|
81
|
+
code = (
|
|
82
|
+
'import xobjects as xo; '
|
|
83
|
+
'assert xo.settings.print_mode == "suppress"; '
|
|
84
|
+
'xo._print("hidden")')
|
|
85
|
+
|
|
86
|
+
completed = subprocess.run(
|
|
87
|
+
[sys.executable, '-c', code],
|
|
88
|
+
env=environment,
|
|
89
|
+
capture_output=True,
|
|
90
|
+
text=True,
|
|
91
|
+
check=True,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
assert completed.stdout == ''
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def test_print_mode_environment_variable_can_be_overridden_in_python():
|
|
98
|
+
environment = os.environ.copy()
|
|
99
|
+
environment['XSUITE_PRINT_MODE'] = 'suppress'
|
|
100
|
+
code = (
|
|
101
|
+
'import xobjects as xo; '
|
|
102
|
+
'xo.settings.print_mode = "print"; '
|
|
103
|
+
'assert xo.settings.print_mode == "print"; '
|
|
104
|
+
'xo._print("visible")')
|
|
105
|
+
|
|
106
|
+
completed = subprocess.run(
|
|
107
|
+
[sys.executable, '-c', code],
|
|
108
|
+
env=environment,
|
|
109
|
+
capture_output=True,
|
|
110
|
+
text=True,
|
|
111
|
+
check=True,
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
assert completed.stdout == 'visible\n'
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def test_environment_change_after_import_does_not_override_python_setting(
|
|
118
|
+
capsys, monkeypatch):
|
|
119
|
+
with xo.settings.override(print_mode='print'):
|
|
120
|
+
monkeypatch.setenv('XSUITE_PRINT_MODE', 'suppress')
|
|
121
|
+
xo._print('visible')
|
|
122
|
+
|
|
123
|
+
assert capsys.readouterr().out == 'visible\n'
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@pytest.mark.parametrize('value', ['1', 'true', 'YES', 'on'])
|
|
127
|
+
def test_boolean_environment_true_values(value):
|
|
128
|
+
environment = os.environ.copy()
|
|
129
|
+
environment['XSUITE_ALLOW_KERNEL_COMPILATION'] = value
|
|
130
|
+
code = (
|
|
131
|
+
'import xobjects as xo; '
|
|
132
|
+
'assert xo.settings.allow_kernel_compilation is True; '
|
|
133
|
+
'xo.settings.allow_kernel_compilation = False; '
|
|
134
|
+
'assert xo.settings.allow_kernel_compilation is False')
|
|
135
|
+
|
|
136
|
+
subprocess.run(
|
|
137
|
+
[sys.executable, '-c', code],
|
|
138
|
+
env=environment,
|
|
139
|
+
capture_output=True,
|
|
140
|
+
text=True,
|
|
141
|
+
check=True,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@pytest.mark.parametrize('value', ['0', 'false', 'NO', 'off'])
|
|
146
|
+
def test_boolean_environment_false_values(value):
|
|
147
|
+
environment = os.environ.copy()
|
|
148
|
+
environment['XSUITE_FORCE_KERNEL_COMPILATION'] = value
|
|
149
|
+
code = (
|
|
150
|
+
'import xobjects as xo; '
|
|
151
|
+
'assert xo.settings.force_kernel_compilation is False')
|
|
152
|
+
|
|
153
|
+
subprocess.run(
|
|
154
|
+
[sys.executable, '-c', code],
|
|
155
|
+
env=environment,
|
|
156
|
+
capture_output=True,
|
|
157
|
+
text=True,
|
|
158
|
+
check=True,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
def test_invalid_boolean_environment_value():
|
|
163
|
+
environment = os.environ.copy()
|
|
164
|
+
environment['XSUITE_CFFI_FORBID_COMPILE'] = 'sometimes'
|
|
165
|
+
|
|
166
|
+
completed = subprocess.run(
|
|
167
|
+
[sys.executable, '-c', 'import xobjects'],
|
|
168
|
+
env=environment,
|
|
169
|
+
capture_output=True,
|
|
170
|
+
text=True,
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
assert completed.returncode != 0
|
|
174
|
+
assert 'Invalid boolean value' in completed.stderr
|
|
175
|
+
assert 'xobjects.settings.cffi_forbid_compile' in completed.stderr
|
|
176
|
+
assert 'XSUITE_CFFI_FORBID_COMPILE' in completed.stderr
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def test_runtime_settings_environment_defaults():
|
|
180
|
+
environment = os.environ.copy()
|
|
181
|
+
environment.update({
|
|
182
|
+
'XSUITE_PROGRESS_INDICATOR': 'text',
|
|
183
|
+
'XSUITE_FORCE_KERNEL_COMPILATION': 'yes',
|
|
184
|
+
'XSUITE_SHOW_KERNEL_DIAGNOSTICS': 'on',
|
|
185
|
+
'XSUITE_CFFI_FORBID_COMPILE': 'true',
|
|
186
|
+
'XSUITE_CFFI_KEEP_BUILD_FILES': '1',
|
|
187
|
+
'XSUITE_CUDA_BACKEND': 'clang',
|
|
188
|
+
'XSUITE_CUDA_FAST_COMPILE': 'false',
|
|
189
|
+
'XSUITE_CUDA_COMPILER': '/path/to/clang++',
|
|
190
|
+
})
|
|
191
|
+
code = (
|
|
192
|
+
'import xobjects as xo; '
|
|
193
|
+
'assert xo.settings.progress_indicator == "text"; '
|
|
194
|
+
'assert xo.settings.force_kernel_compilation is True; '
|
|
195
|
+
'assert xo.settings.show_kernel_diagnostics is True; '
|
|
196
|
+
'assert xo.settings.cffi_forbid_compile is True; '
|
|
197
|
+
'assert xo.settings.cffi_keep_build_files is True; '
|
|
198
|
+
'assert xo.settings.cuda_backend == "clang"; '
|
|
199
|
+
'assert xo.settings.cuda_fast_compile is False; '
|
|
200
|
+
'assert xo.settings.cuda_compiler == "/path/to/clang++"')
|
|
201
|
+
|
|
202
|
+
subprocess.run(
|
|
203
|
+
[sys.executable, '-c', code],
|
|
204
|
+
env=environment,
|
|
205
|
+
capture_output=True,
|
|
206
|
+
text=True,
|
|
207
|
+
check=True,
|
|
208
|
+
)
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@pytest.mark.parametrize(
|
|
212
|
+
'allow, force, compilation_allowed',
|
|
213
|
+
[
|
|
214
|
+
(False, False, False),
|
|
215
|
+
(True, False, True),
|
|
216
|
+
(False, True, True),
|
|
217
|
+
(True, True, True),
|
|
218
|
+
],
|
|
219
|
+
)
|
|
220
|
+
def test_kernel_compilation_settings(allow, force, compilation_allowed):
|
|
221
|
+
with xo.settings.override(
|
|
222
|
+
allow_kernel_compilation=allow,
|
|
223
|
+
force_kernel_compilation=force,
|
|
224
|
+
):
|
|
225
|
+
assert xo.context_cpu.kernel_compilation_allowed(
|
|
226
|
+
xo.ContextCpu()) is compilation_allowed
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def test_user_context_environment_variable(monkeypatch):
|
|
230
|
+
monkeypatch.setenv('XOBJECTS_USER_CONTEXT', 'ContextCpu:auto')
|
|
231
|
+
context = xo.get_user_context()
|
|
232
|
+
|
|
233
|
+
assert context.openmp_enabled
|
|
234
|
+
|
|
235
|
+
|
|
236
|
+
def test_test_contexts_environment_variable(monkeypatch):
|
|
237
|
+
monkeypatch.setenv(
|
|
238
|
+
'XOBJECTS_TEST_CONTEXTS',
|
|
239
|
+
'ContextCpu;ContextCpu:auto',
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
contexts = list(xo.context.get_test_contexts())
|
|
243
|
+
|
|
244
|
+
assert len(contexts) == 2
|
|
245
|
+
assert contexts[0].openmp_enabled is False
|
|
246
|
+
assert contexts[1].openmp_enabled is True
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
def test_cffi_forbid_compile_setting():
|
|
250
|
+
with xo.settings.override(cffi_forbid_compile=True):
|
|
251
|
+
with pytest.raises(RuntimeError) as err:
|
|
252
|
+
xo.ContextCpu().build_kernels({})
|
|
253
|
+
|
|
254
|
+
message = str(err.value)
|
|
255
|
+
assert 'xobjects.settings.cffi_forbid_compile' in message
|
|
256
|
+
assert 'XSUITE_CFFI_FORBID_COMPILE' in message
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def test_allow_kernel_compilation_decorator_restores_state():
|
|
260
|
+
@allow_kernel_compilation(skip_when_forbid_compile=False)
|
|
261
|
+
def decorated():
|
|
262
|
+
assert xo.settings.allow_kernel_compilation is True
|
|
263
|
+
|
|
264
|
+
with xo.settings.override(allow_kernel_compilation=False):
|
|
265
|
+
decorated()
|
|
266
|
+
assert xo.settings.allow_kernel_compilation is False
|
|
@@ -6,7 +6,11 @@ import cffi
|
|
|
6
6
|
import numpy as np
|
|
7
7
|
|
|
8
8
|
import xobjects as xo
|
|
9
|
-
from xobjects.test_helpers import
|
|
9
|
+
from xobjects.test_helpers import (
|
|
10
|
+
allow_kernel_compilation,
|
|
11
|
+
for_all_test_contexts,
|
|
12
|
+
requires_context,
|
|
13
|
+
)
|
|
10
14
|
|
|
11
15
|
|
|
12
16
|
def test_static_struct_def():
|
|
@@ -299,6 +303,7 @@ double mult_four(MyStruct stru) {
|
|
|
299
303
|
|
|
300
304
|
|
|
301
305
|
@requires_context("ContextCpu")
|
|
306
|
+
@allow_kernel_compilation
|
|
302
307
|
def test_compile_kernels_only_if_needed(tmp_path, mocker):
|
|
303
308
|
"""Test the use case of xtrack.
|
|
304
309
|
|
|
@@ -348,6 +353,7 @@ def test_compile_kernels_only_if_needed(tmp_path, mocker):
|
|
|
348
353
|
|
|
349
354
|
|
|
350
355
|
@requires_context("ContextCpu")
|
|
356
|
+
@allow_kernel_compilation
|
|
351
357
|
def test_thisclass_placeholder_on_struct():
|
|
352
358
|
test_context = xo.ContextCpu()
|
|
353
359
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.6.9"
|
|
@@ -207,6 +207,7 @@ class ModuleNotAvailable(object):
|
|
|
207
207
|
class XContext(ABC):
|
|
208
208
|
minimum_alignment = 1
|
|
209
209
|
allow_prebuilt_kernels = False
|
|
210
|
+
allow_kernel_compilation = False
|
|
210
211
|
|
|
211
212
|
def __init__(self):
|
|
212
213
|
self._kernels = KernelDict()
|
|
@@ -776,8 +777,8 @@ def get_test_contexts():
|
|
|
776
777
|
|
|
777
778
|
def get_user_context():
|
|
778
779
|
"""
|
|
779
|
-
Get the context
|
|
780
|
-
If not
|
|
780
|
+
Get the context specified by the environment variable
|
|
781
|
+
``XOBJECTS_USER_CONTEXT``. If it is not set, use ``ContextCpu()``.
|
|
781
782
|
|
|
782
783
|
Examples:
|
|
783
784
|
ContextPyopencl:0.0 -> ContextPyopencl(device="0.0")
|
|
@@ -13,42 +13,42 @@ from typing import Callable, Dict, List, Sequence, Tuple
|
|
|
13
13
|
import weakref
|
|
14
14
|
|
|
15
15
|
from .general import _print
|
|
16
|
+
from .settings import settings
|
|
16
17
|
|
|
17
18
|
import numpy as np
|
|
18
19
|
import scipy as sp
|
|
19
20
|
|
|
20
|
-
_forbid_compile = False
|
|
21
21
|
_suppress_warnings = False
|
|
22
|
-
allow_no_prebuilt_kernel = False
|
|
23
22
|
|
|
24
23
|
|
|
25
|
-
def
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
24
|
+
def _class_allows_kernel_compilation(cls):
|
|
25
|
+
for candidate in (
|
|
26
|
+
cls,
|
|
27
|
+
getattr(cls, "_DressingClass", None),
|
|
28
|
+
getattr(cls, "_XoStruct", None),
|
|
29
|
+
):
|
|
30
|
+
if candidate is None:
|
|
31
|
+
continue
|
|
32
|
+
if getattr(candidate, "allow_kernel_compilation", False):
|
|
33
|
+
return True
|
|
34
|
+
# Compatibility with classes from packages that have not migrated yet.
|
|
35
|
+
if getattr(candidate, "allow_no_prebuilt_kernel", False):
|
|
36
|
+
return True
|
|
37
|
+
return False
|
|
37
38
|
|
|
38
39
|
|
|
39
|
-
def
|
|
40
|
+
def kernel_compilation_allowed(context=None, classes=()):
|
|
40
41
|
if classes is None:
|
|
41
42
|
classes = ()
|
|
42
43
|
elif isinstance(classes, type):
|
|
43
44
|
classes = (classes,)
|
|
44
45
|
|
|
45
|
-
if
|
|
46
|
-
|
|
47
|
-
if allow_no_prebuilt_kernel:
|
|
46
|
+
if (settings.allow_kernel_compilation
|
|
47
|
+
or settings.force_kernel_compilation):
|
|
48
48
|
return True
|
|
49
|
-
if any(
|
|
49
|
+
if any(_class_allows_kernel_compilation(cls) for cls in classes):
|
|
50
50
|
return True
|
|
51
|
-
return getattr(context, "
|
|
51
|
+
return getattr(context, "allow_kernel_compilation", False)
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
def _is_serial_cpu_context(context):
|
|
@@ -58,20 +58,20 @@ def _is_serial_cpu_context(context):
|
|
|
58
58
|
|
|
59
59
|
|
|
60
60
|
def require_prebuilt_kernel(context=None, classes=()):
|
|
61
|
-
return not
|
|
61
|
+
return not kernel_compilation_allowed(
|
|
62
62
|
context, classes=classes
|
|
63
63
|
) and _is_serial_cpu_context(context)
|
|
64
64
|
|
|
65
65
|
|
|
66
|
-
def
|
|
66
|
+
def kernel_compilation_help_message():
|
|
67
67
|
return (
|
|
68
68
|
"To allow just-in-time compilation instead, as in older Xsuite "
|
|
69
|
-
"versions, set
|
|
70
|
-
"
|
|
71
|
-
"`
|
|
72
|
-
"`context.
|
|
69
|
+
"versions, set `xobjects.settings.allow_kernel_compilation = True`, "
|
|
70
|
+
"or equivalently set the environment variable "
|
|
71
|
+
"`XSUITE_ALLOW_KERNEL_COMPILATION=1`, or set "
|
|
72
|
+
"`context.allow_kernel_compilation = True`. Classes that require "
|
|
73
73
|
"just-in-time compilation can also define "
|
|
74
|
-
"`
|
|
74
|
+
"`allow_kernel_compilation = True` as a class attribute. Using "
|
|
75
75
|
"just-in-time compilation instead of prebuilt kernels may require "
|
|
76
76
|
"lengthy compilation whenever a different kernel is needed."
|
|
77
77
|
)
|
|
@@ -369,13 +369,11 @@ class ContextCpu(XContext):
|
|
|
369
369
|
cdefs = "\n".join(cls._gen_c_decl({}) for cls in classes)
|
|
370
370
|
cdefs += "\n" + extra_cdef
|
|
371
371
|
|
|
372
|
-
if
|
|
373
|
-
raise RuntimeError("Compilation is forbidden")
|
|
374
|
-
|
|
375
|
-
if os.environ.get("XOBJECTS_FORBID_COMPILE"):
|
|
372
|
+
if settings.cffi_forbid_compile:
|
|
376
373
|
raise RuntimeError(
|
|
377
|
-
"
|
|
378
|
-
"
|
|
374
|
+
"CFFI compilation is forbidden by "
|
|
375
|
+
"xobjects.settings.cffi_forbid_compile or equivalently "
|
|
376
|
+
"the environment variable XSUITE_CFFI_FORBID_COMPILE."
|
|
379
377
|
)
|
|
380
378
|
|
|
381
379
|
so_file = self.compile_kernel(
|
|
@@ -536,7 +534,7 @@ class ContextCpu(XContext):
|
|
|
536
534
|
return Path(output_file)
|
|
537
535
|
finally:
|
|
538
536
|
# Clean temp files
|
|
539
|
-
if
|
|
537
|
+
if not settings.cffi_keep_build_files:
|
|
540
538
|
files_to_remove = [
|
|
541
539
|
module_name + ".c",
|
|
542
540
|
module_name + ".o",
|
|
@@ -961,8 +959,8 @@ class FFTCpu(object):
|
|
|
961
959
|
direction="FFTW_BACKWARD",
|
|
962
960
|
flags=("FFTW_MEASURE",),
|
|
963
961
|
)
|
|
964
|
-
|
|
965
|
-
|
|
962
|
+
_print(f"fftw simd_aligned={self.fftw.simd_aligned}")
|
|
963
|
+
_print(f"ifftw simd_aligned={self.fftw.simd_aligned}")
|
|
966
964
|
else:
|
|
967
965
|
# I perform one fft to have numpy cache the plan
|
|
968
966
|
_ = np.fft.ifftn(np.fft.fftn(data, axes=axes), axes=axes)
|
|
@@ -25,23 +25,21 @@ from .context import (
|
|
|
25
25
|
sources_from_classes,
|
|
26
26
|
)
|
|
27
27
|
from .linkedarray import BaseLinkedArray
|
|
28
|
+
from .settings import settings
|
|
28
29
|
from .specialize_source import specialize_source
|
|
29
30
|
|
|
30
31
|
log = logging.getLogger(__name__)
|
|
31
32
|
|
|
32
|
-
no_fast_compile = False
|
|
33
|
-
"""Disable NVRTC fast compile tuning when building CUDA kernels.
|
|
34
|
-
|
|
35
|
-
When set to ``True``, ``ContextCupy`` does not pass ``--Ofast-compile=min``
|
|
36
|
-
to NVRTC. The ``XO_CUDA_NO_FAST_COMPILE`` environment variable provides the
|
|
37
|
-
same behavior.
|
|
38
|
-
"""
|
|
39
|
-
|
|
40
33
|
try:
|
|
41
34
|
import cupy
|
|
42
35
|
import cupyx.scipy
|
|
43
36
|
import cupyx.scipy.interpolate
|
|
44
|
-
|
|
37
|
+
with warnings.catch_warnings():
|
|
38
|
+
warnings.filterwarnings(
|
|
39
|
+
'ignore',
|
|
40
|
+
message=r'cupyx\.jit\.rawkernel is experimental\.',
|
|
41
|
+
category=FutureWarning)
|
|
42
|
+
import cupyx.scipy.signal
|
|
45
43
|
import cupyx.scipy.special
|
|
46
44
|
import cupyx.scipy.stats
|
|
47
45
|
from cupyx.scipy import fftpack as cufftp
|
|
@@ -394,12 +392,12 @@ class ContextCupy(XContext):
|
|
|
394
392
|
Creates a Cupy Context object, that allows performing the computations
|
|
395
393
|
on nVidia GPUs.
|
|
396
394
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
variable ``
|
|
395
|
+
``xobjects.settings.cuda_fast_compile`` controls whether NVRTC fast compile
|
|
396
|
+
tuning is enabled. By default it is ``True``, so CUDA kernels built with
|
|
397
|
+
NVRTC >= 12.9 use ``--Ofast-compile=min`` to reduce compilation time and
|
|
398
|
+
memory usage, at the cost of some runtime performance. Set
|
|
399
|
+
``xobjects.settings.cuda_fast_compile = False``, or equivalently the
|
|
400
|
+
environment variable ``XSUITE_CUDA_FAST_COMPILE=0``, to disable it.
|
|
403
401
|
|
|
404
402
|
Args:
|
|
405
403
|
default_block_size (int): CUDA thread size that is used by default
|
|
@@ -434,8 +432,8 @@ class ContextCupy(XContext):
|
|
|
434
432
|
self.default_block_size = default_block_size
|
|
435
433
|
self.default_shared_mem_size_bytes = default_shared_mem_size_bytes
|
|
436
434
|
|
|
437
|
-
if
|
|
438
|
-
backend =
|
|
435
|
+
if backend is None:
|
|
436
|
+
backend = settings.cuda_backend
|
|
439
437
|
|
|
440
438
|
if backend not in ["nvrtc", "clang"]:
|
|
441
439
|
raise ValueError(
|
|
@@ -511,9 +509,7 @@ class ContextCupy(XContext):
|
|
|
511
509
|
if self.backend == "nvrtc":
|
|
512
510
|
# NVRTC (default): add NVRTC-specific flags
|
|
513
511
|
nvrtc_args = (*extra_compile_args,)
|
|
514
|
-
fast_compile =
|
|
515
|
-
no_fast_compile or os.environ.get("XO_CUDA_NO_FAST_COMPILE")
|
|
516
|
-
)
|
|
512
|
+
fast_compile = settings.cuda_fast_compile
|
|
517
513
|
if nvrtc and nvrtc.getVersion() >= (12, 9):
|
|
518
514
|
# If supported, skip prohibitively heavy optimisations (e.g.
|
|
519
515
|
# involving cloning). This it at the expense of <20%
|
|
@@ -553,7 +549,7 @@ class ContextCupy(XContext):
|
|
|
553
549
|
return out_kernels
|
|
554
550
|
|
|
555
551
|
def _find_clang(self):
|
|
556
|
-
override =
|
|
552
|
+
override = settings.cuda_compiler
|
|
557
553
|
if override:
|
|
558
554
|
return override
|
|
559
555
|
|
|
@@ -562,8 +558,11 @@ class ContextCupy(XContext):
|
|
|
562
558
|
return found
|
|
563
559
|
|
|
564
560
|
raise RuntimeError(
|
|
565
|
-
"clang++ for the CUDA context not found. Either install clang so
|
|
566
|
-
"
|
|
561
|
+
"clang++ for the CUDA context not found. Either install clang so "
|
|
562
|
+
"that 'clang++' is on PATH, or set "
|
|
563
|
+
"xobjects.settings.cuda_compiler, or equivalently the environment "
|
|
564
|
+
"variable XSUITE_CUDA_COMPILER, to the desired clang++ "
|
|
565
|
+
"executable."
|
|
567
566
|
)
|
|
568
567
|
|
|
569
568
|
def _build_module_with_clang(self, source, extra_compile_args=()):
|
|
@@ -21,6 +21,7 @@ from .context import (
|
|
|
21
21
|
)
|
|
22
22
|
from .linkedarray import BaseLinkedArray
|
|
23
23
|
from .specialize_source import specialize_source
|
|
24
|
+
from .general import _print
|
|
24
25
|
|
|
25
26
|
log = logging.getLogger(__name__)
|
|
26
27
|
|
|
@@ -100,9 +101,9 @@ class ContextPyopencl(XContext):
|
|
|
100
101
|
@classmethod
|
|
101
102
|
def print_devices(cls):
|
|
102
103
|
for ip, platform in enumerate(cl.get_platforms()):
|
|
103
|
-
|
|
104
|
+
_print(f"Platform {ip} : {platform.name}")
|
|
104
105
|
for id, device in enumerate(platform.get_devices()):
|
|
105
|
-
|
|
106
|
+
_print(f"Device {ip}.{id}: {device.name}")
|
|
106
107
|
|
|
107
108
|
def __init__(
|
|
108
109
|
self, device=None, patch_pyopencl_array=True, minimum_alignment=None
|
|
@@ -5,13 +5,21 @@
|
|
|
5
5
|
from numpy.testing import assert_allclose as np_assert_allclose
|
|
6
6
|
import numpy as np
|
|
7
7
|
|
|
8
|
+
from .settings import settings
|
|
9
|
+
|
|
8
10
|
|
|
9
11
|
class Print:
|
|
10
|
-
|
|
12
|
+
"""Configurable wrapper around :func:`print` used by Xsuite.
|
|
13
|
+
|
|
14
|
+
The behavior is controlled by ``xobjects.settings.print_mode``, or
|
|
15
|
+
equivalently the environment variable ``XSUITE_PRINT_MODE``.
|
|
16
|
+
"""
|
|
11
17
|
|
|
12
18
|
def __call__(self, *args, **kwargs):
|
|
13
|
-
if
|
|
14
|
-
|
|
19
|
+
if settings.print_mode == 'suppress':
|
|
20
|
+
return
|
|
21
|
+
|
|
22
|
+
print(*args, **kwargs)
|
|
15
23
|
|
|
16
24
|
|
|
17
25
|
_print = Print()
|