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.
Files changed (98) hide show
  1. {xobjects-0.6.7/xobjects.egg-info → xobjects-0.6.9}/PKG-INFO +1 -1
  2. xobjects-0.6.9/tests/test_general.py +266 -0
  3. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_struct.py +7 -1
  4. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/__init__.py +1 -0
  5. xobjects-0.6.9/xobjects/_version.py +1 -0
  6. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/context.py +3 -2
  7. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/context_cpu.py +34 -36
  8. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/context_cupy.py +22 -23
  9. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/context_pyopencl.py +3 -2
  10. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/general.py +11 -3
  11. xobjects-0.6.9/xobjects/settings.py +308 -0
  12. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/struct.py +7 -10
  13. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/test_helpers.py +8 -14
  14. {xobjects-0.6.7 → xobjects-0.6.9/xobjects.egg-info}/PKG-INFO +1 -1
  15. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects.egg-info/SOURCES.txt +2 -39
  16. xobjects-0.6.7/.github/workflows/black.yml +0 -10
  17. xobjects-0.6.7/.gitignore +0 -13
  18. xobjects-0.6.7/.pre-commit-config.yaml +0 -12
  19. xobjects-0.6.7/.readthedocs.yaml +0 -20
  20. xobjects-0.6.7/contributors_and_credits.txt +0 -7
  21. xobjects-0.6.7/docs/Makefile +0 -20
  22. xobjects-0.6.7/docs/architecture/contexts.rst +0 -164
  23. xobjects-0.6.7/docs/architecture/types.rst +0 -179
  24. xobjects-0.6.7/docs/architecture.rst +0 -16
  25. xobjects-0.6.7/docs/conf.py +0 -278
  26. xobjects-0.6.7/docs/index.rst +0 -79
  27. xobjects-0.6.7/docs/make.bat +0 -35
  28. xobjects-0.6.7/docs/quickstart.rst +0 -2
  29. xobjects-0.6.7/docs/reference.rst +0 -8
  30. xobjects-0.6.7/examples/api_def.py +0 -28
  31. xobjects-0.6.7/examples/api_init.py +0 -101
  32. xobjects-0.6.7/examples/capi_example.c +0 -100
  33. xobjects-0.6.7/examples/check_assembly.c +0 -101
  34. xobjects-0.6.7/examples/ex_array_init_perf.py +0 -42
  35. xobjects-0.6.7/examples/ex_cpugpu.py +0 -46
  36. xobjects-0.6.7/examples/ex_nested_ref.py +0 -49
  37. xobjects-0.6.7/examples/ex_ref_cpu.py +0 -52
  38. xobjects-0.6.7/examples/ex_struct_cpu.py +0 -39
  39. xobjects-0.6.7/examples/ex_unionref_cpu.py +0 -49
  40. xobjects-0.6.7/examples/ex_unionref_method.py +0 -120
  41. xobjects-0.6.7/examples/init_soa.py +0 -67
  42. xobjects-0.6.7/examples/issue_with_two_pyopencl_contexts.py +0 -18
  43. xobjects-0.6.7/examples/kernel_basics/kernel_cffi.py +0 -54
  44. xobjects-0.6.7/examples/kernel_basics/kernel_cupy.py +0 -42
  45. xobjects-0.6.7/examples/kernel_basics/kernel_pyopencl.py +0 -48
  46. xobjects-0.6.7/examples/opencl_offsets.py +0 -38
  47. xobjects-0.6.7/examples/simple_kernel.py +0 -59
  48. xobjects-0.6.7/examples/sixtracklib.py +0 -80
  49. xobjects-0.6.7/mktest +0 -1
  50. xobjects-0.6.7/release.sh +0 -20
  51. xobjects-0.6.7/requirements.txt +0 -3
  52. xobjects-0.6.7/tests/__init__.py +0 -4
  53. xobjects-0.6.7/tests/notest_capi.py +0 -208
  54. xobjects-0.6.7/update_cprght_statement.py +0 -49
  55. xobjects-0.6.7/xobjects/_version.py +0 -1
  56. {xobjects-0.6.7 → xobjects-0.6.9}/Architecture.md +0 -0
  57. {xobjects-0.6.7 → xobjects-0.6.9}/LICENSE +0 -0
  58. {xobjects-0.6.7 → xobjects-0.6.9}/MANIFEST.in +0 -0
  59. {xobjects-0.6.7 → xobjects-0.6.9}/README.md +0 -0
  60. {xobjects-0.6.7 → xobjects-0.6.9}/pyproject.toml +0 -0
  61. {xobjects-0.6.7 → xobjects-0.6.9}/setup.cfg +0 -0
  62. {xobjects-0.6.7 → xobjects-0.6.9}/setup.py +0 -0
  63. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_align.py +0 -0
  64. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_array.py +0 -0
  65. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_buffer.py +0 -0
  66. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_capi.py +0 -0
  67. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_chunk.py +0 -0
  68. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_common.py +0 -0
  69. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_context_opencl.py +0 -0
  70. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_hybrid_class.py +0 -0
  71. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_kernel.py +0 -0
  72. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_linked_array.py +0 -0
  73. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_nplike_arrays.py +0 -0
  74. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_ref.py +0 -0
  75. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_scalars.py +0 -0
  76. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_shared_memory.py +0 -0
  77. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_strides.py +0 -0
  78. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_string.py +0 -0
  79. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_to_dict.py +0 -0
  80. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_typeutils.py +0 -0
  81. {xobjects-0.6.7 → xobjects-0.6.9}/tests/test_unionref.py +0 -0
  82. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/_patch_pyopencl_array.py +0 -0
  83. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/array.py +0 -0
  84. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/capi.py +0 -0
  85. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/headers/atomicadd.h +0 -0
  86. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/headers/common.h +0 -0
  87. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/hybrid_class.py +0 -0
  88. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/linkedarray.py +0 -0
  89. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/ref.py +0 -0
  90. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/scalar.py +0 -0
  91. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/specialize_source.py +0 -0
  92. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/string.py +0 -0
  93. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/typeutils.py +0 -0
  94. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects/union.py +0 -0
  95. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects.egg-info/dependency_links.txt +0 -0
  96. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects.egg-info/entry_points.txt +0 -0
  97. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects.egg-info/requires.txt +0 -0
  98. {xobjects-0.6.7 → xobjects-0.6.9}/xobjects.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xobjects
3
- Version: 0.6.7
3
+ Version: 0.6.9
4
4
  Summary: In-memory serialization and code generator for CPU and GPU
5
5
  Home-page: https://xsuite.readthedocs.io/
6
6
  Download-URL: https://pypi.python.org/pypi/xobjects
@@ -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 for_all_test_contexts, requires_context
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
 
@@ -35,6 +35,7 @@ from .hybrid_class import JEncoder, HybridClass, MetaHybridClass
35
35
  from .linkedarray import BypassLinked
36
36
 
37
37
  from .general import _print
38
+ from .settings import settings
38
39
 
39
40
  from .general import assert_allclose
40
41
 
@@ -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 specfied by the enviroment variable XOBJECTS_USER_CONTEXT.
780
- If not present use ContextCpu().
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 _class_allows_no_prebuilt_kernel(cls):
26
- return (
27
- getattr(cls, "allow_no_prebuilt_kernel", False)
28
- or getattr(
29
- getattr(cls, "_DressingClass", None),
30
- "allow_no_prebuilt_kernel",
31
- False,
32
- )
33
- or getattr(
34
- getattr(cls, "_XoStruct", None), "allow_no_prebuilt_kernel", False
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 allow_no_prebuilt_kernel_enabled(context=None, classes=()):
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 os.environ.get("XSUITE_ALLOW_NO_PREBUILT_KERNELS") is not None:
46
- return True
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(_class_allows_no_prebuilt_kernel(cls) for cls in classes):
49
+ if any(_class_allows_kernel_compilation(cls) for cls in classes):
50
50
  return True
51
- return getattr(context, "allow_no_prebuilt_kernel", False)
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 allow_no_prebuilt_kernel_enabled(
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 no_prebuilt_kernel_jit_message():
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 the environment variable "
70
- "`XSUITE_ALLOW_NO_PREBUILT_KERNELS`, set "
71
- "`xobjects.context_cpu.allow_no_prebuilt_kernel = True`, or set "
72
- "`context.allow_no_prebuilt_kernel = True`. Classes that require "
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
- "`allow_no_prebuilt_kernel = True` as a class attribute. Using "
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 _forbid_compile:
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
- "Compilation is forbidden by the environment variable "
378
- "XOBJECTS_FORBID_COMPILE"
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 "XOBJECTS_KEEP_BUILD_FILES" not in os.environ:
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
- print(f"fftw simd_aligned={self.fftw.simd_aligned}")
965
- print(f"ifftw simd_aligned={self.fftw.simd_aligned}")
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
- import cupyx.scipy.signal
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
- The module-level flag ``xobjects.context_cupy.no_fast_compile`` controls
398
- whether NVRTC fast compile tuning is disabled. By default it is ``False``,
399
- so CUDA kernels built with NVRTC >= 12.9 use ``--Ofast-compile=min`` to
400
- reduce compilation time and memory usage, at the cost of some runtime
401
- performance. Set it to ``True`` to disable this option. The environment
402
- variable ``XO_CUDA_NO_FAST_COMPILE`` also disables it.
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 not backend:
438
- backend = os.environ.get("XO_CUDA_BACKEND", "nvrtc")
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 = not (
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 = os.environ.get("XO_CUDA_CLANG")
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 that 'clang++' is on PATH,"
566
- "or set the XO_CUDA_CLANG variable to the desired clang++ executable."
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
- print(f"Platform {ip} : {platform.name}")
104
+ _print(f"Platform {ip} : {platform.name}")
104
105
  for id, device in enumerate(platform.get_devices()):
105
- print(f"Device {ip}.{id}: {device.name}")
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
- suppress = False
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 not self.suppress:
14
- print(*args, **kwargs)
19
+ if settings.print_mode == 'suppress':
20
+ return
21
+
22
+ print(*args, **kwargs)
15
23
 
16
24
 
17
25
  _print = Print()