pyopencl 2024.1__cp310-cp310-macosx_11_0_arm64.whl → 2024.2__cp310-cp310-macosx_11_0_arm64.whl

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.

Potentially problematic release.


This version of pyopencl might be problematic. Click here for more details.

Files changed (107) hide show
  1. pyopencl/__init__.py +82 -80
  2. pyopencl/_cl.cpython-310-darwin.so +0 -0
  3. pyopencl/algorithm.py +8 -10
  4. pyopencl/array.py +16 -12
  5. pyopencl/bitonic_sort.py +5 -4
  6. pyopencl/cache.py +22 -22
  7. pyopencl/capture_call.py +4 -3
  8. pyopencl/characterize/__init__.py +4 -2
  9. pyopencl/characterize/performance.py +2 -1
  10. pyopencl/clmath.py +2 -1
  11. pyopencl/clrandom.py +5 -369
  12. pyopencl/cltypes.py +4 -1
  13. pyopencl/compyte/dtypes.py +1 -1
  14. pyopencl/compyte/ndarray/gen_elemwise.py +6 -5
  15. pyopencl/compyte/ndarray/gen_reduction.py +6 -6
  16. pyopencl/compyte/ndarray/setup_opencl.py +3 -2
  17. pyopencl/compyte/ndarray/test_gpu_elemwise.py +5 -4
  18. pyopencl/compyte/ndarray/test_gpu_ndarray.py +0 -1
  19. pyopencl/elementwise.py +4 -6
  20. pyopencl/invoker.py +15 -9
  21. pyopencl/ipython_ext.py +1 -1
  22. pyopencl/reduction.py +5 -5
  23. pyopencl/scan.py +17 -21
  24. pyopencl/tools.py +13 -16
  25. pyopencl/version.py +1 -1
  26. pyopencl-2024.2.data/data/CITATION.cff +74 -0
  27. {pyopencl-2024.1.dist-info → pyopencl-2024.2.data/data}/LICENSE +0 -23
  28. pyopencl-2024.2.data/data/Makefile.in +21 -0
  29. pyopencl-2024.2.data/data/README.rst +70 -0
  30. pyopencl-2024.2.data/data/README_SETUP.txt +34 -0
  31. pyopencl-2024.2.data/data/aksetup_helper.py +1013 -0
  32. pyopencl-2024.2.data/data/configure.py +6 -0
  33. pyopencl-2024.2.data/data/contrib/cldis.py +91 -0
  34. pyopencl-2024.2.data/data/contrib/fortran-to-opencl/README +29 -0
  35. pyopencl-2024.2.data/data/contrib/fortran-to-opencl/translate.py +1441 -0
  36. pyopencl-2024.2.data/data/contrib/pyopencl.vim +84 -0
  37. pyopencl-2024.2.data/data/doc/Makefile +23 -0
  38. pyopencl-2024.2.data/data/doc/algorithm.rst +214 -0
  39. pyopencl-2024.2.data/data/doc/array.rst +305 -0
  40. pyopencl-2024.2.data/data/doc/conf.py +26 -0
  41. pyopencl-2024.2.data/data/doc/howto.rst +105 -0
  42. pyopencl-2024.2.data/data/doc/index.rst +137 -0
  43. pyopencl-2024.2.data/data/doc/make_constants.py +561 -0
  44. pyopencl-2024.2.data/data/doc/misc.rst +885 -0
  45. pyopencl-2024.2.data/data/doc/runtime.rst +51 -0
  46. pyopencl-2024.2.data/data/doc/runtime_const.rst +30 -0
  47. pyopencl-2024.2.data/data/doc/runtime_gl.rst +78 -0
  48. pyopencl-2024.2.data/data/doc/runtime_memory.rst +527 -0
  49. pyopencl-2024.2.data/data/doc/runtime_platform.rst +184 -0
  50. pyopencl-2024.2.data/data/doc/runtime_program.rst +364 -0
  51. pyopencl-2024.2.data/data/doc/runtime_queue.rst +182 -0
  52. pyopencl-2024.2.data/data/doc/subst.rst +36 -0
  53. pyopencl-2024.2.data/data/doc/tools.rst +4 -0
  54. pyopencl-2024.2.data/data/doc/types.rst +42 -0
  55. pyopencl-2024.2.data/data/examples/black-hole-accretion.py +2227 -0
  56. pyopencl-2024.2.data/data/examples/demo-struct-reduce.py +75 -0
  57. pyopencl-2024.2.data/data/examples/demo.py +39 -0
  58. pyopencl-2024.2.data/data/examples/demo_array.py +32 -0
  59. pyopencl-2024.2.data/data/examples/demo_array_svm.py +37 -0
  60. pyopencl-2024.2.data/data/examples/demo_elementwise.py +34 -0
  61. pyopencl-2024.2.data/data/examples/demo_elementwise_complex.py +53 -0
  62. pyopencl-2024.2.data/data/examples/demo_mandelbrot.py +183 -0
  63. pyopencl-2024.2.data/data/examples/demo_meta_codepy.py +56 -0
  64. pyopencl-2024.2.data/data/examples/demo_meta_template.py +55 -0
  65. pyopencl-2024.2.data/data/examples/dump-performance.py +38 -0
  66. pyopencl-2024.2.data/data/examples/dump-properties.py +86 -0
  67. pyopencl-2024.2.data/data/examples/gl_interop_demo.py +84 -0
  68. pyopencl-2024.2.data/data/examples/gl_particle_animation.py +218 -0
  69. pyopencl-2024.2.data/data/examples/ipython-demo.ipynb +203 -0
  70. pyopencl-2024.2.data/data/examples/median-filter.py +99 -0
  71. pyopencl-2024.2.data/data/examples/n-body.py +1070 -0
  72. pyopencl-2024.2.data/data/examples/narray.py +37 -0
  73. pyopencl-2024.2.data/data/examples/noisyImage.jpg +0 -0
  74. pyopencl-2024.2.data/data/examples/pi-monte-carlo.py +1166 -0
  75. pyopencl-2024.2.data/data/examples/svm.py +82 -0
  76. pyopencl-2024.2.data/data/examples/transpose.py +229 -0
  77. pyopencl-2024.2.data/data/pytest.ini +3 -0
  78. pyopencl-2024.2.data/data/src/bitlog.cpp +51 -0
  79. pyopencl-2024.2.data/data/src/bitlog.hpp +83 -0
  80. pyopencl-2024.2.data/data/src/clinfo_ext.h +134 -0
  81. pyopencl-2024.2.data/data/src/mempool.hpp +444 -0
  82. pyopencl-2024.2.data/data/src/pyopencl_ext.h +77 -0
  83. pyopencl-2024.2.data/data/src/tools.hpp +90 -0
  84. pyopencl-2024.2.data/data/src/wrap_cl.cpp +61 -0
  85. pyopencl-2024.2.data/data/src/wrap_cl.hpp +5853 -0
  86. pyopencl-2024.2.data/data/src/wrap_cl_part_1.cpp +369 -0
  87. pyopencl-2024.2.data/data/src/wrap_cl_part_2.cpp +702 -0
  88. pyopencl-2024.2.data/data/src/wrap_constants.cpp +1274 -0
  89. pyopencl-2024.2.data/data/src/wrap_helpers.hpp +213 -0
  90. pyopencl-2024.2.data/data/src/wrap_mempool.cpp +731 -0
  91. pyopencl-2024.2.data/data/test/add-vectors-32.spv +0 -0
  92. pyopencl-2024.2.data/data/test/add-vectors-64.spv +0 -0
  93. pyopencl-2024.2.data/data/test/empty-header.h +1 -0
  94. pyopencl-2024.2.data/data/test/test_algorithm.py +1180 -0
  95. pyopencl-2024.2.data/data/test/test_array.py +2392 -0
  96. pyopencl-2024.2.data/data/test/test_arrays_in_structs.py +100 -0
  97. pyopencl-2024.2.data/data/test/test_clmath.py +529 -0
  98. pyopencl-2024.2.data/data/test/test_clrandom.py +75 -0
  99. pyopencl-2024.2.data/data/test/test_enqueue_copy.py +271 -0
  100. pyopencl-2024.2.data/data/test/test_wrapper.py +1554 -0
  101. pyopencl-2024.2.dist-info/LICENSE +282 -0
  102. {pyopencl-2024.1.dist-info → pyopencl-2024.2.dist-info}/METADATA +12 -12
  103. pyopencl-2024.2.dist-info/RECORD +122 -0
  104. {pyopencl-2024.1.dist-info → pyopencl-2024.2.dist-info}/WHEEL +1 -1
  105. pyopencl/cl/pyopencl-ranluxcl.cl +0 -957
  106. pyopencl-2024.1.dist-info/RECORD +0 -48
  107. {pyopencl-2024.1.dist-info → pyopencl-2024.2.dist-info}/top_level.txt +0 -0
pyopencl/__init__.py CHANGED
@@ -20,16 +20,16 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
20
  THE SOFTWARE.
21
21
  """
22
22
 
23
+ import logging
23
24
  from sys import intern
24
- from warnings import warn
25
25
  from typing import Any, Dict, List, Optional, Sequence, Tuple, Union
26
-
27
- from pyopencl.version import VERSION, VERSION_STATUS, VERSION_TEXT # noqa: F401
26
+ from warnings import warn
28
27
 
29
28
  # must import, otherwise dtype registry will not be fully populated
30
29
  import pyopencl.cltypes # noqa: F401
30
+ from pyopencl.version import VERSION, VERSION_STATUS, VERSION_TEXT # noqa: F401
31
+
31
32
 
32
- import logging
33
33
  logger = logging.getLogger(__name__)
34
34
 
35
35
  # This supports ocl-icd find shipped OpenCL ICDs, cf.
@@ -37,6 +37,8 @@ logger = logging.getLogger(__name__)
37
37
  # via
38
38
  # https://github.com/inducer/pyopencl/blob/0b3d0ef92497e6838eea300b974f385f94cb5100/scripts/build-wheels.sh#L43-L44
39
39
  import os
40
+
41
+
40
42
  os.environ["PYOPENCL_HOME"] = os.path.dirname(os.path.abspath(__file__))
41
43
 
42
44
  try:
@@ -50,7 +52,7 @@ except ImportError:
50
52
  stacklevel=2)
51
53
  raise
52
54
 
53
- import numpy as np
55
+ import numpy as np # noqa: I003
54
56
 
55
57
  import sys
56
58
 
@@ -168,6 +170,7 @@ from pyopencl._cl import ( # noqa: F401
168
170
  Pipe,
169
171
  )
170
172
 
173
+
171
174
  try:
172
175
  from pyopencl._cl import DeviceTopologyAmd # noqa: F401
173
176
  from pyopencl._cl import enqueue_copy_buffer_p2p_amd # noqa: F401
@@ -176,46 +179,24 @@ except ImportError:
176
179
 
177
180
  if not _PYPY:
178
181
  # FIXME: Add back to default set when pypy support catches up
179
- from pyopencl._cl import ( # noqa: F401
180
- enqueue_map_buffer,
181
- enqueue_map_image,
182
- )
182
+ from pyopencl._cl import enqueue_map_buffer # noqa: F401
183
+ from pyopencl._cl import enqueue_map_image # noqa: F401
183
184
 
184
185
  if get_cl_header_version() >= (1, 1):
185
- from pyopencl._cl import ( # noqa: F401
186
- UserEvent,
187
- )
186
+ from pyopencl._cl import UserEvent # noqa: F401
188
187
  if get_cl_header_version() >= (1, 2):
188
+ from pyopencl._cl import ImageDescriptor # noqa: F401
189
189
  from pyopencl._cl import ( # noqa: F401
190
- _enqueue_marker_with_wait_list,
191
- _enqueue_barrier_with_wait_list,
192
-
193
- unload_platform_compiler,
194
-
195
-
196
- enqueue_migrate_mem_objects,
197
- _enqueue_fill_buffer,
198
- enqueue_fill_image,
199
-
200
- ImageDescriptor,
201
- )
190
+ _enqueue_barrier_with_wait_list, _enqueue_fill_buffer,
191
+ _enqueue_marker_with_wait_list, enqueue_fill_image,
192
+ enqueue_migrate_mem_objects, unload_platform_compiler)
202
193
 
203
194
  if get_cl_header_version() >= (2, 0):
204
- from pyopencl._cl import ( # noqa: F401
205
- SVMPointer,
206
- SVM,
207
- SVMAllocation,
208
- )
195
+ from pyopencl._cl import SVM, SVMAllocation, SVMPointer # noqa: F401
209
196
 
210
197
  if _cl.have_gl():
211
198
  from pyopencl._cl import ( # noqa: F401
212
- gl_object_type,
213
- gl_texture_info,
214
-
215
- GLBuffer,
216
- GLRenderBuffer,
217
- GLTexture,
218
- )
199
+ GLBuffer, GLRenderBuffer, GLTexture, gl_object_type, gl_texture_info)
219
200
 
220
201
  try:
221
202
  from pyopencl._cl import get_apple_cgl_share_group # noqa: F401
@@ -223,15 +204,14 @@ if _cl.have_gl():
223
204
  pass
224
205
 
225
206
  try:
226
- from pyopencl._cl import ( # noqa: F401
227
- enqueue_acquire_gl_objects,
228
- enqueue_release_gl_objects,
229
- )
207
+ from pyopencl._cl import enqueue_acquire_gl_objects # noqa: F401
208
+ from pyopencl._cl import enqueue_release_gl_objects # noqa: F401
230
209
  except ImportError:
231
210
  pass
232
211
 
233
212
  import inspect as _inspect
234
213
 
214
+
235
215
  CONSTANT_CLASSES = tuple(
236
216
  getattr(_cl, name) for name in dir(_cl)
237
217
  if _inspect.isclass(getattr(_cl, name))
@@ -266,8 +246,9 @@ class CommandQueueUsedAfterExit(UserWarning):
266
246
  pass
267
247
 
268
248
 
269
- def compiler_output(text):
270
- if int(os.environ.get("PYOPENCL_COMPILER_OUTPUT", "0")):
249
+ def compiler_output(text: str) -> None:
250
+ from pytools import strtobool
251
+ if strtobool(os.environ.get("PYOPENCL_COMPILER_OUTPUT", "False")):
271
252
  warn(text, CompilerWarning, stacklevel=3)
272
253
  else:
273
254
  warn("Non-empty compiler output encountered. Set the "
@@ -279,21 +260,21 @@ def compiler_output(text):
279
260
 
280
261
  # {{{ find pyopencl shipped source code
281
262
 
282
- def _find_pyopencl_include_path():
283
- from os.path import join, abspath, dirname, exists
284
- try:
285
- # Try to find the include path in the same directory as this file
286
- include_path = join(abspath(dirname(__file__)), "cl")
287
- if not exists(include_path):
288
- raise OSError("unable to find pyopencl include path")
289
- except Exception:
290
- # Try to find the resource with pkg_resources (the recommended
291
- # setuptools approach). This is very slow.
292
- from pkg_resources import Requirement, resource_filename
293
- include_path = resource_filename(
294
- Requirement.parse("pyopencl"), "pyopencl/cl")
263
+ def _find_pyopencl_include_path() -> str:
264
+ from os.path import abspath, dirname, exists, join
265
+
266
+ # Try to find the include path in the same directory as this file
267
+ include_path = join(abspath(dirname(__file__)), "cl")
268
+ if not exists(include_path):
269
+ try:
270
+ # NOTE: only available in Python >=3.9
271
+ from importlib.resources import files
272
+ except ImportError:
273
+ from importlib_resources import files
274
+
275
+ include_path = str(files("pyopencl") / "cl")
295
276
  if not exists(include_path):
296
- raise OSError("unable to find pyopencl include path")
277
+ raise OSError("Unable to find PyOpenCL include path")
297
278
 
298
279
  # Quote the path if it contains a space and is not quoted already.
299
280
  # See https://github.com/inducer/pyopencl/issues/250 for discussion.
@@ -310,9 +291,6 @@ def _find_pyopencl_include_path():
310
291
  def _split_options_if_necessary(options):
311
292
  if isinstance(options, str):
312
293
  import shlex
313
- # shlex.split takes unicode (py3 str) on py3
314
- if isinstance(options, bytes):
315
- options = options.decode("utf-8")
316
294
 
317
295
  options = shlex.split(options)
318
296
 
@@ -362,7 +340,10 @@ def _options_to_bytestring(options):
362
340
 
363
341
  # {{{ Program (wrapper around _Program, adds caching support)
364
342
 
365
- _PYOPENCL_NO_CACHE: bool = "PYOPENCL_NO_CACHE" in os.environ
343
+ from pytools import strtobool
344
+
345
+
346
+ _PYOPENCL_NO_CACHE = strtobool(os.environ.get("PYOPENCL_NO_CACHE", "false"))
366
347
 
367
348
  _DEFAULT_BUILD_OPTIONS: List[str] = []
368
349
  _DEFAULT_INCLUDE_OPTIONS: List[str] = ["-I", _find_pyopencl_include_path()]
@@ -554,7 +535,7 @@ class Program:
554
535
  def _build_and_catch_errors(self, build_func, options_bytes, source=None):
555
536
  try:
556
537
  return build_func()
557
- except _cl.RuntimeError as e:
538
+ except RuntimeError as e:
558
539
  msg = str(e)
559
540
  if options_bytes:
560
541
  msg = msg + "\n(options: %s)" % options_bytes.decode("utf-8")
@@ -572,7 +553,7 @@ class Program:
572
553
  code = e.code
573
554
  routine = e.routine
574
555
 
575
- err = _cl.RuntimeError(
556
+ err = RuntimeError(
576
557
  _cl._ErrorRecord(
577
558
  msg=msg,
578
559
  code=code,
@@ -854,7 +835,7 @@ def _add_functionality():
854
835
  # }}}
855
836
 
856
837
  from pyopencl.invoker import generate_enqueue_and_set_args
857
- enqueue, my_set_args = \
838
+ self._enqueue, self.set_args = \
858
839
  generate_enqueue_and_set_args(
859
840
  self.function_name,
860
841
  len(arg_types), self.num_args,
@@ -863,20 +844,6 @@ def _add_functionality():
863
844
  work_around_arg_count_bug=work_around_arg_count_bug,
864
845
  devs=self.context.devices)
865
846
 
866
- # Make ourselves a kernel-specific class, so that we're able to override
867
- # __call__. Inspired by https://stackoverflow.com/a/38541437
868
- class KernelWithCustomEnqueue(type(self)):
869
- __call__ = enqueue
870
- set_args = my_set_args
871
-
872
- try:
873
- self.__class__ = KernelWithCustomEnqueue
874
- except TypeError:
875
- # __class__ assignment may not work in all cases, due to differing
876
- # object layouts. Fall back to bouncing through kernel_call below.
877
- self._enqueue = enqueue
878
- self.set_args = my_set_args
879
-
880
847
  def kernel_get_work_group_info(self, param, device):
881
848
  cache_key = (param, device.int_ptr)
882
849
  try:
@@ -1555,7 +1522,22 @@ if get_cl_header_version() >= (2, 0):
1555
1522
 
1556
1523
  # {{{ create_some_context
1557
1524
 
1558
- def create_some_context(interactive=None, answers=None):
1525
+ def choose_devices(interactive: Optional[bool] = None,
1526
+ answers: Optional[List[str]] = None) -> List[Device]:
1527
+ """
1528
+ Choose :class:`Device` instances 'somehow'.
1529
+
1530
+ :arg interactive: If multiple choices for platform and/or device exist,
1531
+ *interactive* is ``True`` (or ``None`` and ``sys.stdin.isatty()``
1532
+ returns ``True``), then the user is queried about which device should be
1533
+ chosen. Otherwise, a device is chosen in an implementation-defined
1534
+ manner.
1535
+ :arg answers: A sequence of strings that will be used to answer the
1536
+ platform/device selection questions.
1537
+
1538
+ :returns: a list of :class:`Device` instances.
1539
+ """
1540
+
1559
1541
  if answers is None:
1560
1542
  if "PYOPENCL_CTX" in os.environ:
1561
1543
  ctx_spec = os.environ["PYOPENCL_CTX"]
@@ -1565,7 +1547,7 @@ def create_some_context(interactive=None, answers=None):
1565
1547
  from pyopencl.tools import get_test_platforms_and_devices
1566
1548
  for _plat, devs in get_test_platforms_and_devices():
1567
1549
  for dev in devs:
1568
- return Context([dev])
1550
+ return [dev]
1569
1551
 
1570
1552
  if answers is not None:
1571
1553
  pre_provided_answers = answers
@@ -1677,7 +1659,27 @@ def create_some_context(interactive=None, answers=None):
1677
1659
 
1678
1660
  if answers:
1679
1661
  raise RuntimeError("not all provided choices were used by "
1680
- "create_some_context. (left over: '%s')" % ":".join(answers))
1662
+ "choose_device. (left over: '%s')" % ":".join(answers))
1663
+
1664
+ return devices
1665
+
1666
+
1667
+ def create_some_context(interactive: Optional[bool] = None,
1668
+ answers: Optional[List[str]] = None) -> Context:
1669
+ """
1670
+ Create a :class:`Context` 'somehow'.
1671
+
1672
+ :arg interactive: If multiple choices for platform and/or device exist,
1673
+ *interactive* is ``True`` (or ``None`` and ``sys.stdin.isatty()``
1674
+ returns ``True``), then the user is queried about which device should be
1675
+ chosen. Otherwise, a device is chosen in an implementation-defined
1676
+ manner.
1677
+ :arg answers: A sequence of strings that will be used to answer the
1678
+ platform/device selection questions.
1679
+
1680
+ :returns: an instance of :class:`Context`.
1681
+ """
1682
+ devices = choose_devices(interactive, answers)
1681
1683
 
1682
1684
  return Context(devices)
1683
1685
 
Binary file
pyopencl/algorithm.py CHANGED
@@ -33,24 +33,22 @@ from dataclasses import dataclass
33
33
  from typing import Optional
34
34
 
35
35
  import numpy as np
36
+ from mako.template import Template
37
+ from pytools import memoize, memoize_method
36
38
 
37
39
  import pyopencl as cl
38
40
  import pyopencl.array
39
-
40
41
  from pyopencl.elementwise import ElementwiseKernel
41
- from pyopencl.scan import ScanTemplate, GenericScanKernel
42
+ from pyopencl.scan import GenericScanKernel, ScanTemplate
42
43
  from pyopencl.tools import dtype_to_ctype, get_arg_offset_adjuster_code
43
44
 
44
- from pytools import memoize, memoize_method
45
- from mako.template import Template
46
-
47
45
 
48
46
  # {{{ "extra args" handling utility
49
47
 
50
48
  def _extract_extra_args_types_values(extra_args):
51
49
  if extra_args is None:
52
50
  extra_args = []
53
- from pyopencl.tools import VectorArg, ScalarArg
51
+ from pyopencl.tools import ScalarArg, VectorArg
54
52
 
55
53
  extra_args_types = []
56
54
  extra_args_values = []
@@ -469,7 +467,7 @@ class RadixSort:
469
467
  scan_ctype, scan_dtype, scan_t_cdecl = \
470
468
  _make_sort_scan_type(context.devices[0], self.bits, self.index_dtype)
471
469
 
472
- from pyopencl.tools import VectorArg, ScalarArg
470
+ from pyopencl.tools import ScalarArg, VectorArg
473
471
  scan_arguments = (
474
472
  list(self.arguments)
475
473
  + [VectorArg(arg.dtype, "sorted_"+arg.name) for arg in self.arguments
@@ -927,7 +925,7 @@ class ListOfListsBuilder:
927
925
  @memoize_method
928
926
  def get_count_kernel(self, index_dtype):
929
927
  index_ctype = dtype_to_ctype(index_dtype)
930
- from pyopencl.tools import VectorArg, OtherArg
928
+ from pyopencl.tools import OtherArg, VectorArg
931
929
  kernel_list_args = [
932
930
  VectorArg(index_dtype, "plb_%s_count" % name)
933
931
  for name, dtype in self.list_names_and_dtypes
@@ -986,7 +984,7 @@ class ListOfListsBuilder:
986
984
  @memoize_method
987
985
  def get_write_kernel(self, index_dtype):
988
986
  index_ctype = dtype_to_ctype(index_dtype)
989
- from pyopencl.tools import VectorArg, OtherArg
987
+ from pyopencl.tools import OtherArg, VectorArg
990
988
  kernel_list_args = []
991
989
  kernel_list_arg_values = ""
992
990
  user_list_args = []
@@ -1369,7 +1367,7 @@ class KeyValueSorter:
1369
1367
 
1370
1368
  @memoize_method
1371
1369
  def get_kernels(self, key_dtype, value_dtype, starts_dtype):
1372
- from pyopencl.tools import VectorArg, ScalarArg
1370
+ from pyopencl.tools import ScalarArg, VectorArg
1373
1371
 
1374
1372
  by_target_sorter = RadixSort(
1375
1373
  self.context, [
pyopencl/array.py CHANGED
@@ -30,23 +30,22 @@ OTHER DEALINGS IN THE SOFTWARE.
30
30
 
31
31
  import builtins
32
32
  from dataclasses import dataclass
33
- from warnings import warn
34
- from numbers import Number
35
33
  from functools import reduce
34
+ from numbers import Number
36
35
  from typing import Any, Dict, Hashable, List, Optional, Tuple, Union
36
+ from warnings import warn
37
37
 
38
38
  import numpy as np
39
- import pyopencl.elementwise as elementwise
40
39
 
41
40
  import pyopencl as cl
42
- from pyopencl.compyte.array import (
43
- as_strided as _as_strided,
44
- f_contiguous_strides as _f_contiguous_strides,
45
- c_contiguous_strides as _c_contiguous_strides,
46
- equal_strides as _equal_strides,
47
- ArrayFlags as _ArrayFlags)
48
- from pyopencl.characterize import has_double_support
41
+ import pyopencl.elementwise as elementwise
49
42
  from pyopencl import cltypes
43
+ from pyopencl.characterize import has_double_support
44
+ from pyopencl.compyte.array import (
45
+ ArrayFlags as _ArrayFlags, as_strided as _as_strided,
46
+ c_contiguous_strides as _c_contiguous_strides, equal_strides as _equal_strides,
47
+ f_contiguous_strides as _f_contiguous_strides)
48
+
50
49
 
51
50
  SCALAR_CLASSES = (Number, np.bool_, bool)
52
51
 
@@ -56,6 +55,9 @@ else:
56
55
  _SVMPointer_or_nothing = ()
57
56
 
58
57
 
58
+ _NUMPY_PRE_2 = np.__version__.startswith("1.")
59
+
60
+
59
61
  # {{{ _get_common_dtype
60
62
 
61
63
  _COMMON_DTYPE_CACHE: Dict[Tuple[Hashable, ...], np.dtype] = {}
@@ -123,7 +125,9 @@ def _get_common_dtype(obj1, obj2, queue):
123
125
  # Note that np.find_common_type, while appealing, won't be able to tell
124
126
  # the full story.
125
127
 
126
- if not (o1_is_array and o2_is_array) and o1_is_integral and o2_is_integral:
128
+ if (_NUMPY_PRE_2
129
+ and not (o1_is_array and o2_is_array)
130
+ and o1_is_integral and o2_is_integral):
127
131
  if o1_is_array:
128
132
  obj1 = np.zeros(1, dtype=o1_dtype)
129
133
  if o2_is_array:
@@ -1413,7 +1417,7 @@ class Array:
1413
1417
  def __itruediv__(self, other):
1414
1418
  # raise an error if the result cannot be cast to self
1415
1419
  common_dtype = _get_truedivide_dtype(self, other, self.queue)
1416
- if not np.can_cast(common_dtype, self.dtype.type):
1420
+ if not np.can_cast(common_dtype, self.dtype.type, "same_kind"):
1417
1421
  raise TypeError(
1418
1422
  "Cannot cast {!r} to {!r}".format(self.dtype, common_dtype))
1419
1423
 
pyopencl/bitonic_sort.py CHANGED
@@ -33,14 +33,15 @@ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33
33
  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
34
  """
35
35
 
36
- import pyopencl as cl
37
- from pyopencl.tools import dtype_to_ctype
38
- from operator import mul
39
36
  from functools import reduce
40
- from pytools import memoize_method
37
+ from operator import mul
38
+
41
39
  from mako.template import Template
40
+ from pytools import memoize_method
42
41
 
42
+ import pyopencl as cl
43
43
  import pyopencl.bitonic_sort_templates as _tmpl
44
+ from pyopencl.tools import dtype_to_ctype
44
45
 
45
46
 
46
47
  def _is_power_of_2(n):
pyopencl/cache.py CHANGED
@@ -23,24 +23,27 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
23
  THE SOFTWARE.
24
24
  """
25
25
 
26
- import re
26
+ import logging
27
27
  import os
28
+ import re
28
29
  import sys
29
30
  from dataclasses import dataclass
30
31
  from typing import List, Optional, Tuple
31
32
 
32
33
  import pyopencl._cl as _cl
33
34
 
34
- import logging
35
+
35
36
  logger = logging.getLogger(__name__)
36
37
 
37
38
 
38
39
  import hashlib
40
+
41
+
39
42
  new_hash = hashlib.md5
40
43
 
41
44
 
42
45
  def _erase_dir(dir):
43
- from os import listdir, unlink, rmdir
46
+ from os import listdir, rmdir, unlink
44
47
  from os.path import join
45
48
  for name in listdir(dir):
46
49
  unlink(join(dir, name))
@@ -168,7 +171,7 @@ C_INCLUDE_RE = re.compile(r'^\s*\#\s*include\s+[<"](.+)[">]\s*$',
168
171
  def get_dependencies(src, include_path):
169
172
  result = {}
170
173
 
171
- from os.path import realpath, join
174
+ from os.path import join, realpath
172
175
 
173
176
  def _inner(src):
174
177
  for match in C_INCLUDE_RE.finditer(src):
@@ -189,7 +192,7 @@ def get_dependencies(src, include_path):
189
192
  finally:
190
193
  src_file.close()
191
194
 
192
- # jrevent infinite recursion if some header file appears to
195
+ # prevent infinite recursion if some header file appears to
193
196
  # include itself
194
197
  result[included_file_name] = None
195
198
 
@@ -266,7 +269,7 @@ def retrieve_from_cache(cache_dir, cache_key):
266
269
  class _InvalidInfoFile(RuntimeError):
267
270
  pass
268
271
 
269
- from os.path import join, isdir
272
+ from os.path import isdir, join
270
273
  module_cache_dir = join(cache_dir, cache_key)
271
274
  if not isdir(module_cache_dir):
272
275
  return None
@@ -343,25 +346,22 @@ def _create_built_program_from_source_cached(ctx, src, options_bytes,
343
346
  from os.path import join
344
347
 
345
348
  if cache_dir is None:
346
- try:
347
- import platformdirs as appdirs
348
- except ImportError:
349
- import appdirs
349
+ import platformdirs
350
+
351
+ # Determine the cache directory in the same way as pytools.PersistentDict,
352
+ # which PyOpenCL uses for invoker caches.
353
+ if sys.platform == "darwin" and os.getenv("XDG_CACHE_HOME") is not None:
354
+ # platformdirs does not handle XDG_CACHE_HOME on macOS
355
+ # https://github.com/platformdirs/platformdirs/issues/269
356
+ cache_dir = join(os.getenv("XDG_CACHE_HOME"), "pyopencl")
357
+ else:
358
+ cache_dir = platformdirs.user_cache_dir("pyopencl", "pyopencl")
350
359
 
351
- cache_dir = join(appdirs.user_cache_dir("pyopencl", "pyopencl"),
360
+ cache_dir = join(cache_dir,
352
361
  "pyopencl-compiler-cache-v2-py{}".format(
353
362
  ".".join(str(i) for i in sys.version_info)))
354
363
 
355
- # {{{ ensure cache directory exists
356
-
357
- try:
358
- os.makedirs(cache_dir)
359
- except OSError as e:
360
- from errno import EEXIST
361
- if e.errno != EEXIST:
362
- raise
363
-
364
- # }}}
364
+ os.makedirs(cache_dir, exist_ok=True)
365
365
 
366
366
  if devices is None:
367
367
  devices = ctx.devices
@@ -513,8 +513,8 @@ def create_built_program_from_source_cached(ctx, src, options_bytes, devices=Non
513
513
  raise
514
514
 
515
515
  if not build_program_failure:
516
- from warnings import warn
517
516
  from traceback import format_exc
517
+ from warnings import warn
518
518
  warn(
519
519
  "PyOpenCL compiler caching failed with an exception:\n"
520
520
  f"[begin exception]\n{format_exc()}[end exception]",
pyopencl/capture_call.py CHANGED
@@ -21,9 +21,10 @@ THE SOFTWARE.
21
21
  """
22
22
 
23
23
 
24
- import pyopencl as cl
25
24
  import numpy as np
26
- from pytools.py_codegen import PythonCodeGenerator, Indentation
25
+ from pytools.py_codegen import Indentation, PythonCodeGenerator
26
+
27
+ import pyopencl as cl
27
28
 
28
29
 
29
30
  def capture_kernel_call(kernel, output_file, queue, g_size, l_size, *args, **kwargs):
@@ -138,8 +139,8 @@ def capture_kernel_call(kernel, output_file, queue, g_size, l_size, *args, **kwa
138
139
 
139
140
  # {{{ data
140
141
 
141
- from zlib import compress
142
142
  from base64 import b64encode
143
+ from zlib import compress
143
144
  cg("")
144
145
  line_len = 70
145
146
 
@@ -20,10 +20,12 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
20
  THE SOFTWARE.
21
21
  """
22
22
 
23
- import pyopencl as cl
24
- from pytools import memoize
25
23
  from typing import Dict, Optional, Tuple
26
24
 
25
+ from pytools import memoize
26
+
27
+ import pyopencl as cl
28
+
27
29
 
28
30
  class CLCharacterizationWarning(UserWarning):
29
31
  pass
@@ -20,9 +20,10 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
20
  THE SOFTWARE.
21
21
  """
22
22
 
23
- import pyopencl as cl
24
23
  import numpy as np
25
24
 
25
+ import pyopencl as cl
26
+
26
27
 
27
28
  # {{{ timing helpers
28
29
 
pyopencl/clmath.py CHANGED
@@ -22,10 +22,11 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
22
  THE SOFTWARE.
23
23
  """
24
24
 
25
+ import numpy as np
26
+
25
27
  import pyopencl.array as cl_array
26
28
  import pyopencl.elementwise as elementwise
27
29
  from pyopencl.array import _get_common_dtype
28
- import numpy as np
29
30
 
30
31
 
31
32
  def _make_unary_array_func(name):