pyopencl 2024.2.1__cp38-cp38-macosx_11_0_arm64.whl → 2024.2.4__cp38-cp38-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 (102) hide show
  1. pyopencl/__init__.py +16 -4
  2. pyopencl/_cl.cpython-38-darwin.so +0 -0
  3. pyopencl/algorithm.py +3 -1
  4. pyopencl/bitonic_sort.py +2 -0
  5. pyopencl/characterize/__init__.py +23 -0
  6. pyopencl/compyte/.git +1 -0
  7. pyopencl/compyte/.github/workflows/autopush.yml +21 -0
  8. pyopencl/compyte/.github/workflows/ci.yml +30 -0
  9. pyopencl/compyte/.gitignore +21 -0
  10. pyopencl/compyte/ndarray/Makefile +31 -0
  11. pyopencl/compyte/ndarray/gpu_ndarray.h +35 -0
  12. pyopencl/compyte/ndarray/pygpu_language.h +207 -0
  13. pyopencl/compyte/ndarray/pygpu_language_cuda.cu +622 -0
  14. pyopencl/compyte/ndarray/pygpu_language_opencl.cpp +317 -0
  15. pyopencl/compyte/ndarray/pygpu_ndarray.cpp +1546 -0
  16. pyopencl/compyte/ndarray/pygpu_ndarray.h +71 -0
  17. pyopencl/compyte/ndarray/pygpu_ndarray_object.h +232 -0
  18. pyopencl/compyte/setup.cfg +9 -0
  19. pyopencl/tools.py +60 -56
  20. pyopencl/version.py +7 -3
  21. {pyopencl-2024.2.1.dist-info → pyopencl-2024.2.4.dist-info}/METADATA +14 -14
  22. pyopencl-2024.2.4.dist-info/RECORD +59 -0
  23. {pyopencl-2024.2.1.dist-info → pyopencl-2024.2.4.dist-info}/WHEEL +1 -1
  24. pyopencl-2024.2.1.data/data/CITATION.cff +0 -74
  25. pyopencl-2024.2.1.data/data/CMakeLists.txt +0 -83
  26. pyopencl-2024.2.1.data/data/Makefile.in +0 -21
  27. pyopencl-2024.2.1.data/data/README.rst +0 -70
  28. pyopencl-2024.2.1.data/data/README_SETUP.txt +0 -34
  29. pyopencl-2024.2.1.data/data/aksetup_helper.py +0 -1013
  30. pyopencl-2024.2.1.data/data/configure.py +0 -6
  31. pyopencl-2024.2.1.data/data/contrib/cldis.py +0 -91
  32. pyopencl-2024.2.1.data/data/contrib/fortran-to-opencl/README +0 -29
  33. pyopencl-2024.2.1.data/data/contrib/fortran-to-opencl/translate.py +0 -1441
  34. pyopencl-2024.2.1.data/data/contrib/pyopencl.vim +0 -84
  35. pyopencl-2024.2.1.data/data/doc/Makefile +0 -23
  36. pyopencl-2024.2.1.data/data/doc/algorithm.rst +0 -214
  37. pyopencl-2024.2.1.data/data/doc/array.rst +0 -305
  38. pyopencl-2024.2.1.data/data/doc/conf.py +0 -26
  39. pyopencl-2024.2.1.data/data/doc/howto.rst +0 -105
  40. pyopencl-2024.2.1.data/data/doc/index.rst +0 -137
  41. pyopencl-2024.2.1.data/data/doc/make_constants.py +0 -561
  42. pyopencl-2024.2.1.data/data/doc/misc.rst +0 -885
  43. pyopencl-2024.2.1.data/data/doc/runtime.rst +0 -51
  44. pyopencl-2024.2.1.data/data/doc/runtime_const.rst +0 -30
  45. pyopencl-2024.2.1.data/data/doc/runtime_gl.rst +0 -78
  46. pyopencl-2024.2.1.data/data/doc/runtime_memory.rst +0 -527
  47. pyopencl-2024.2.1.data/data/doc/runtime_platform.rst +0 -184
  48. pyopencl-2024.2.1.data/data/doc/runtime_program.rst +0 -364
  49. pyopencl-2024.2.1.data/data/doc/runtime_queue.rst +0 -182
  50. pyopencl-2024.2.1.data/data/doc/subst.rst +0 -36
  51. pyopencl-2024.2.1.data/data/doc/tools.rst +0 -4
  52. pyopencl-2024.2.1.data/data/doc/types.rst +0 -42
  53. pyopencl-2024.2.1.data/data/examples/black-hole-accretion.py +0 -2227
  54. pyopencl-2024.2.1.data/data/examples/demo-struct-reduce.py +0 -75
  55. pyopencl-2024.2.1.data/data/examples/demo.py +0 -39
  56. pyopencl-2024.2.1.data/data/examples/demo_array.py +0 -32
  57. pyopencl-2024.2.1.data/data/examples/demo_array_svm.py +0 -37
  58. pyopencl-2024.2.1.data/data/examples/demo_elementwise.py +0 -34
  59. pyopencl-2024.2.1.data/data/examples/demo_elementwise_complex.py +0 -53
  60. pyopencl-2024.2.1.data/data/examples/demo_mandelbrot.py +0 -183
  61. pyopencl-2024.2.1.data/data/examples/demo_meta_codepy.py +0 -56
  62. pyopencl-2024.2.1.data/data/examples/demo_meta_template.py +0 -55
  63. pyopencl-2024.2.1.data/data/examples/dump-performance.py +0 -38
  64. pyopencl-2024.2.1.data/data/examples/dump-properties.py +0 -86
  65. pyopencl-2024.2.1.data/data/examples/gl_interop_demo.py +0 -84
  66. pyopencl-2024.2.1.data/data/examples/gl_particle_animation.py +0 -218
  67. pyopencl-2024.2.1.data/data/examples/ipython-demo.ipynb +0 -203
  68. pyopencl-2024.2.1.data/data/examples/median-filter.py +0 -99
  69. pyopencl-2024.2.1.data/data/examples/n-body.py +0 -1070
  70. pyopencl-2024.2.1.data/data/examples/narray.py +0 -37
  71. pyopencl-2024.2.1.data/data/examples/noisyImage.jpg +0 -0
  72. pyopencl-2024.2.1.data/data/examples/pi-monte-carlo.py +0 -1166
  73. pyopencl-2024.2.1.data/data/examples/svm.py +0 -82
  74. pyopencl-2024.2.1.data/data/examples/transpose.py +0 -229
  75. pyopencl-2024.2.1.data/data/pytest.ini +0 -3
  76. pyopencl-2024.2.1.data/data/src/bitlog.cpp +0 -51
  77. pyopencl-2024.2.1.data/data/src/bitlog.hpp +0 -83
  78. pyopencl-2024.2.1.data/data/src/clinfo_ext.h +0 -134
  79. pyopencl-2024.2.1.data/data/src/mempool.hpp +0 -444
  80. pyopencl-2024.2.1.data/data/src/pyopencl_ext.h +0 -77
  81. pyopencl-2024.2.1.data/data/src/tools.hpp +0 -90
  82. pyopencl-2024.2.1.data/data/src/wrap_cl.cpp +0 -61
  83. pyopencl-2024.2.1.data/data/src/wrap_cl.hpp +0 -5853
  84. pyopencl-2024.2.1.data/data/src/wrap_cl_part_1.cpp +0 -369
  85. pyopencl-2024.2.1.data/data/src/wrap_cl_part_2.cpp +0 -702
  86. pyopencl-2024.2.1.data/data/src/wrap_constants.cpp +0 -1274
  87. pyopencl-2024.2.1.data/data/src/wrap_helpers.hpp +0 -213
  88. pyopencl-2024.2.1.data/data/src/wrap_mempool.cpp +0 -731
  89. pyopencl-2024.2.1.data/data/test/add-vectors-32.spv +0 -0
  90. pyopencl-2024.2.1.data/data/test/add-vectors-64.spv +0 -0
  91. pyopencl-2024.2.1.data/data/test/empty-header.h +0 -1
  92. pyopencl-2024.2.1.data/data/test/test_algorithm.py +0 -1180
  93. pyopencl-2024.2.1.data/data/test/test_array.py +0 -2392
  94. pyopencl-2024.2.1.data/data/test/test_arrays_in_structs.py +0 -100
  95. pyopencl-2024.2.1.data/data/test/test_clmath.py +0 -529
  96. pyopencl-2024.2.1.data/data/test/test_clrandom.py +0 -75
  97. pyopencl-2024.2.1.data/data/test/test_enqueue_copy.py +0 -271
  98. pyopencl-2024.2.1.data/data/test/test_wrapper.py +0 -1554
  99. pyopencl-2024.2.1.dist-info/LICENSE +0 -282
  100. pyopencl-2024.2.1.dist-info/RECORD +0 -123
  101. pyopencl-2024.2.1.dist-info/top_level.txt +0 -1
  102. {pyopencl-2024.2.1.data/data → pyopencl-2024.2.4.dist-info/licenses}/LICENSE +0 -0
@@ -1,731 +0,0 @@
1
- // Wrap memory pool
2
- //
3
- // Copyright (C) 2009 Andreas Kloeckner
4
- //
5
- // Permission is hereby granted, free of charge, to any person
6
- // obtaining a copy of this software and associated documentation
7
- // files (the "Software"), to deal in the Software without
8
- // restriction, including without limitation the rights to use,
9
- // copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- // copies of the Software, and to permit persons to whom the
11
- // Software is furnished to do so, subject to the following
12
- // conditions:
13
- //
14
- // The above copyright notice and this permission notice shall be
15
- // included in all copies or substantial portions of the Software.
16
- //
17
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
- // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
- // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
- // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
- // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
- // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
- // OTHER DEALINGS IN THE SOFTWARE.
25
-
26
-
27
- // Gregor Thalhammer (on Apr 13, 2011) said it's necessary to import Python.h
28
- // first to prevent OS X from overriding a bunch of macros. (e.g. isspace)
29
- #include <Python.h>
30
-
31
- #define NO_IMPORT_ARRAY
32
- #define PY_ARRAY_UNIQUE_SYMBOL pyopencl_ARRAY_API
33
-
34
- #include <memory>
35
- #include <vector>
36
- #include "wrap_helpers.hpp"
37
- #include "wrap_cl.hpp"
38
- #include "mempool.hpp"
39
- #include "tools.hpp"
40
-
41
-
42
-
43
- namespace pyopencl {
44
- // {{{ test_allocator
45
-
46
- class test_allocator
47
- {
48
- public:
49
- typedef void *pointer_type;
50
- typedef size_t size_type;
51
-
52
- bool is_deferred() const
53
- {
54
- return false;
55
- }
56
-
57
- pointer_type allocate(size_type s)
58
- {
59
- return nullptr;
60
- }
61
-
62
- pointer_type hand_out_existing_block(pointer_type &&p)
63
- {
64
- return p;
65
- }
66
-
67
- ~test_allocator()
68
- { }
69
-
70
- void free(pointer_type &&p)
71
- { }
72
-
73
- void try_release_blocks()
74
- { }
75
- };
76
-
77
- // }}}
78
-
79
-
80
- // {{{ buffer allocators
81
-
82
- class buffer_allocator_base
83
- {
84
- protected:
85
- std::shared_ptr<pyopencl::context> m_context;
86
- cl_mem_flags m_flags;
87
-
88
- public:
89
- buffer_allocator_base(std::shared_ptr<pyopencl::context> const &ctx,
90
- cl_mem_flags flags=CL_MEM_READ_WRITE)
91
- : m_context(ctx), m_flags(flags)
92
- {
93
- if (flags & (CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR))
94
- throw pyopencl::error("Allocator", CL_INVALID_VALUE,
95
- "cannot specify USE_HOST_PTR or COPY_HOST_PTR flags");
96
- }
97
-
98
- buffer_allocator_base(buffer_allocator_base const &src)
99
- : m_context(src.m_context), m_flags(src.m_flags)
100
- { }
101
-
102
- virtual ~buffer_allocator_base()
103
- { }
104
-
105
- typedef cl_mem pointer_type;
106
- typedef size_t size_type;
107
-
108
- virtual bool is_deferred() const = 0;
109
- virtual pointer_type allocate(size_type s) = 0;
110
-
111
- pointer_type hand_out_existing_block(pointer_type &&p)
112
- {
113
- return p;
114
- }
115
-
116
- void free(pointer_type &&p)
117
- {
118
- PYOPENCL_CALL_GUARDED(clReleaseMemObject, (p));
119
- }
120
-
121
- void try_release_blocks()
122
- {
123
- pyopencl::run_python_gc();
124
- }
125
- };
126
-
127
-
128
- class deferred_buffer_allocator : public buffer_allocator_base
129
- {
130
- private:
131
- typedef buffer_allocator_base super;
132
-
133
- public:
134
- deferred_buffer_allocator(std::shared_ptr<pyopencl::context> const &ctx,
135
- cl_mem_flags flags=CL_MEM_READ_WRITE)
136
- : super(ctx, flags)
137
- { }
138
-
139
- bool is_deferred() const
140
- { return true; }
141
-
142
- pointer_type allocate(size_type s)
143
- {
144
- if (s == 0)
145
- return nullptr;
146
-
147
- return pyopencl::create_buffer(m_context->data(), m_flags, s, 0);
148
- }
149
- };
150
-
151
-
152
- class immediate_buffer_allocator : public buffer_allocator_base
153
- {
154
- private:
155
- typedef buffer_allocator_base super;
156
- pyopencl::command_queue m_queue;
157
-
158
- public:
159
- immediate_buffer_allocator(pyopencl::command_queue &queue,
160
- cl_mem_flags flags=CL_MEM_READ_WRITE)
161
- : super(std::shared_ptr<pyopencl::context>(queue.get_context()), flags),
162
- m_queue(queue.data(), /*retain*/ true)
163
- { }
164
-
165
- immediate_buffer_allocator(immediate_buffer_allocator const &src)
166
- : super(src), m_queue(src.m_queue)
167
- { }
168
-
169
- bool is_deferred() const
170
- { return false; }
171
-
172
- pointer_type allocate(size_type s)
173
- {
174
- if (s == 0)
175
- return nullptr;
176
-
177
- pointer_type ptr = pyopencl::create_buffer(
178
- m_context->data(), m_flags, s, 0);
179
-
180
- // Make sure the buffer gets allocated right here and right now.
181
- // This looks (and is) expensive. But immediate allocators
182
- // have their main use in memory pools, whose basic assumption
183
- // is that allocation is too expensive anyway--but they rely
184
- // on 'out-of-memory' being reported on allocation. (If it is
185
- // reported in a deferred manner, it has no way to react
186
- // (e.g. by freeing unused memory) because it is not part of
187
- // the call stack.)
188
- if (m_queue.get_hex_device_version() < 0x1020)
189
- {
190
- unsigned zero = 0;
191
- PYOPENCL_CALL_GUARDED(clEnqueueWriteBuffer, (
192
- m_queue.data(),
193
- ptr,
194
- /* is blocking */ CL_FALSE,
195
- 0, std::min(s, sizeof(zero)), &zero,
196
- 0, NULL, NULL
197
- ));
198
- }
199
- else
200
- {
201
- PYOPENCL_CALL_GUARDED(clEnqueueMigrateMemObjects, (
202
- m_queue.data(),
203
- 1, &ptr, CL_MIGRATE_MEM_OBJECT_CONTENT_UNDEFINED,
204
- 0, NULL, NULL
205
- ));
206
- }
207
-
208
- // No need to wait for completion here. clWaitForEvents (e.g.)
209
- // cannot return mem object allocation failures. This implies that
210
- // the buffer is faulted onto the device on enqueue.
211
-
212
- return ptr;
213
- }
214
- };
215
-
216
- // }}}
217
-
218
-
219
- // {{{ pooled_buffer
220
-
221
- class pooled_buffer
222
- : public pyopencl::pooled_allocation<pyopencl::memory_pool<buffer_allocator_base> >,
223
- public pyopencl::memory_object_holder
224
- {
225
- private:
226
- typedef
227
- pyopencl::pooled_allocation<pyopencl::memory_pool<buffer_allocator_base> >
228
- super;
229
-
230
- public:
231
- pooled_buffer(
232
- std::shared_ptr<super::pool_type> p, super::size_type s)
233
- : super(p, s)
234
- { }
235
-
236
- virtual ~pooled_buffer()
237
- { }
238
-
239
- const super::pointer_type data() const
240
- { return m_ptr; }
241
-
242
- size_t size() const
243
- {
244
- return m_size;
245
- }
246
- };
247
-
248
- // }}}
249
-
250
-
251
- // {{{ allocate_from_buffer_allocator
252
-
253
- inline
254
- buffer *allocate_from_buffer_allocator(buffer_allocator_base &alloc, size_t size)
255
- {
256
- cl_mem mem = nullptr;
257
- int try_count = 0;
258
- while (try_count < 2)
259
- {
260
- try
261
- {
262
- mem = alloc.allocate(size);
263
- break;
264
- }
265
- catch (pyopencl::error &e)
266
- {
267
- if (!e.is_out_of_memory())
268
- throw;
269
- if (++try_count == 2)
270
- throw;
271
- }
272
-
273
- alloc.try_release_blocks();
274
- }
275
-
276
- if (!mem)
277
- {
278
- if (size == 0)
279
- return nullptr;
280
- else
281
- throw pyopencl::error("Allocator", CL_INVALID_VALUE,
282
- "allocator succeeded but returned NULL cl_mem");
283
- }
284
-
285
- try
286
- {
287
- return new pyopencl::buffer(mem, false);
288
- }
289
- catch (...)
290
- {
291
- PYOPENCL_CALL_GUARDED(clReleaseMemObject, (mem));
292
- throw;
293
- }
294
- }
295
-
296
- // }}}
297
-
298
-
299
- // {{{ allocate_from_buffer_pool
300
-
301
- pooled_buffer *allocate_from_buffer_pool(
302
- std::shared_ptr<memory_pool<buffer_allocator_base> > pool,
303
- memory_pool<buffer_allocator_base>::size_type sz)
304
- {
305
- return new pooled_buffer(pool, sz);
306
- }
307
-
308
- // }}}
309
-
310
-
311
- #if PYOPENCL_CL_VERSION >= 0x2000
312
-
313
- struct svm_held_pointer
314
- {
315
- void *ptr;
316
- pyopencl::command_queue_ref queue;
317
- };
318
-
319
-
320
- // {{{ svm allocator
321
-
322
- class svm_allocator
323
- {
324
- public:
325
- typedef svm_held_pointer pointer_type;
326
- typedef size_t size_type;
327
-
328
- protected:
329
- std::shared_ptr<pyopencl::context> m_context;
330
- cl_uint m_alignment;
331
- cl_svm_mem_flags m_flags;
332
- pyopencl::command_queue_ref m_queue;
333
-
334
- public:
335
- svm_allocator(std::shared_ptr<pyopencl::context> const &ctx,
336
- cl_uint alignment=0, cl_svm_mem_flags flags=CL_MEM_READ_WRITE,
337
- pyopencl::command_queue *queue=nullptr)
338
- : m_context(ctx), m_alignment(alignment), m_flags(flags)
339
- {
340
- if (queue)
341
- m_queue.set(queue->data());
342
- }
343
-
344
- svm_allocator(svm_allocator const &src)
345
- : m_context(src.m_context), m_alignment(src.m_alignment),
346
- m_flags(src.m_flags)
347
- { }
348
-
349
- ~svm_allocator()
350
- { }
351
-
352
- bool is_deferred() const
353
- {
354
- // According to experiments with the Nvidia implementation (and based
355
- // on my reading of the CL spec), clSVMalloc will return an error
356
- // immediately upon being out of memory. Therefore the
357
- // immediate/deferred split on the buffer side is not needed here.
358
- // -AK, 2022-09-07
359
-
360
- return false;
361
- }
362
-
363
- std::shared_ptr<pyopencl::context> context() const
364
- {
365
- return m_context;
366
- }
367
-
368
- pointer_type allocate(size_type size)
369
- {
370
- if (size == 0)
371
- return { nullptr, nullptr };
372
-
373
- PYOPENCL_PRINT_CALL_TRACE("clSVMalloc");
374
- return {
375
- clSVMAlloc(m_context->data(), m_flags, size, m_alignment),
376
- pyopencl::command_queue_ref(m_queue.is_valid() ? m_queue.data() : nullptr)
377
- };
378
- }
379
-
380
- pointer_type hand_out_existing_block(pointer_type &&p)
381
- {
382
- if (m_queue.is_valid())
383
- {
384
- if (p.queue.is_valid())
385
- {
386
- if (p.queue.data() != m_queue.data())
387
- {
388
- // make sure synchronization promises stay valid in new queue
389
- cl_event evt;
390
-
391
- PYOPENCL_CALL_GUARDED(clEnqueueMarker, (p.queue.data(), &evt));
392
- PYOPENCL_CALL_GUARDED(clEnqueueMarkerWithWaitList,
393
- (m_queue.data(), 1, &evt, nullptr));
394
- }
395
- }
396
- p.queue.set(m_queue.data());
397
- }
398
- else
399
- {
400
- if (p.queue.is_valid())
401
- {
402
- PYOPENCL_CALL_GUARDED_THREADED(clFinish, (p.queue.data()));
403
- p.queue.reset();
404
- }
405
- }
406
-
407
- return std::move(p);
408
- }
409
-
410
- void free(pointer_type &&p)
411
- {
412
- if (p.queue.is_valid())
413
- {
414
- PYOPENCL_CALL_GUARDED_CLEANUP(clEnqueueSVMFree, (
415
- p.queue.data(), 1, &p.ptr,
416
- nullptr, nullptr,
417
- 0, nullptr, nullptr));
418
- p.queue.reset();
419
- }
420
- else
421
- {
422
- PYOPENCL_PRINT_CALL_TRACE("clSVMFree");
423
- clSVMFree(m_context->data(), p.ptr);
424
- }
425
- }
426
-
427
- void try_release_blocks()
428
- {
429
- pyopencl::run_python_gc();
430
- }
431
- };
432
-
433
- // }}}
434
-
435
-
436
- // {{{ pooled_svm
437
-
438
- class pooled_svm
439
- : public pyopencl::pooled_allocation<pyopencl::memory_pool<svm_allocator>>,
440
- public pyopencl::svm_pointer
441
- {
442
- private:
443
- typedef
444
- pyopencl::pooled_allocation<pyopencl::memory_pool<svm_allocator>>
445
- super;
446
-
447
- public:
448
- pooled_svm(
449
- std::shared_ptr<super::pool_type> p, super::size_type s)
450
- : super(p, s)
451
- { }
452
-
453
- virtual ~pooled_svm()
454
- { }
455
-
456
- void *svm_ptr() const
457
- { return m_ptr.ptr; }
458
-
459
- size_t size() const
460
- { return m_size; }
461
-
462
- void bind_to_queue(pyopencl::command_queue const &queue)
463
- {
464
- if (pyopencl::is_queue_out_of_order(queue.data()))
465
- throw pyopencl::error("PooledSVM.bind_to_queue", CL_INVALID_VALUE,
466
- "supplying an out-of-order queue to SVMAllocation is invalid");
467
-
468
- if (m_ptr.queue.is_valid())
469
- {
470
- if (m_ptr.queue.data() != queue.data())
471
- {
472
- // make sure synchronization promises stay valid in new queue
473
- cl_event evt;
474
-
475
- PYOPENCL_CALL_GUARDED(clEnqueueMarker, (m_ptr.queue.data(), &evt));
476
- PYOPENCL_CALL_GUARDED(clEnqueueMarkerWithWaitList,
477
- (queue.data(), 1, &evt, nullptr));
478
- }
479
- }
480
-
481
- m_ptr.queue.set(queue.data());
482
- }
483
-
484
- void unbind_from_queue()
485
- {
486
- if (m_ptr.queue.is_valid())
487
- PYOPENCL_CALL_GUARDED_THREADED(clFinish, (m_ptr.queue.data()));
488
-
489
- m_ptr.queue.reset();
490
- }
491
-
492
- // only use for testing/diagnostic/debugging purposes!
493
- cl_command_queue queue() const
494
- {
495
- if (m_ptr.queue.is_valid())
496
- return m_ptr.queue.data();
497
- else
498
- return nullptr;
499
- }
500
-
501
- // This shouldn't be necessary, but somehow nanobind gets unhappy if
502
- // it's not there.
503
- void free()
504
- {
505
- super::free();
506
- }
507
- };
508
-
509
- // }}}
510
-
511
-
512
- // {{{ svm_allocator_call
513
-
514
- inline
515
- pyopencl::svm_allocation *svm_allocator_call(svm_allocator &alloc, size_t size)
516
- {
517
- int try_count = 0;
518
- while (true)
519
- {
520
- try
521
- {
522
- svm_held_pointer mem(alloc.allocate(size));
523
- if (mem.queue.is_valid())
524
- return new pyopencl::svm_allocation(
525
- alloc.context(), mem.ptr, size, mem.queue.data());
526
- else
527
- return new pyopencl::svm_allocation(
528
- alloc.context(), mem.ptr, size, nullptr);
529
- }
530
- catch (pyopencl::error &e)
531
- {
532
- if (!e.is_out_of_memory())
533
- throw;
534
- if (++try_count == 2)
535
- throw;
536
- }
537
-
538
- alloc.try_release_blocks();
539
- }
540
- }
541
-
542
- // }}}
543
-
544
-
545
- // {{{ allocate_from_svm_pool
546
-
547
- pooled_svm *allocate_from_svm_pool(
548
- std::shared_ptr<pyopencl::memory_pool<svm_allocator> > pool,
549
- pyopencl::memory_pool<svm_allocator>::size_type sz)
550
- {
551
- return new pooled_svm(pool, sz);
552
- }
553
-
554
- // }}}
555
-
556
- #endif
557
- }
558
-
559
-
560
- namespace {
561
- template<class Wrapper>
562
- void expose_memory_pool(Wrapper &wrapper)
563
- {
564
- typedef typename Wrapper::Type cls;
565
- wrapper
566
- .def_prop_ro("held_blocks", &cls::held_blocks)
567
- .def_prop_ro("active_blocks", &cls::active_blocks)
568
- .def_prop_ro("managed_bytes", &cls::managed_bytes)
569
- .def_prop_ro("active_bytes", &cls::active_bytes)
570
- .DEF_SIMPLE_METHOD(bin_number)
571
- .DEF_SIMPLE_METHOD(alloc_size)
572
- .DEF_SIMPLE_METHOD(free_held)
573
- .DEF_SIMPLE_METHOD(stop_holding)
574
-
575
- // undoc for now
576
- .def("_set_trace", &cls::set_trace)
577
- ;
578
- }
579
- }
580
-
581
-
582
-
583
-
584
- void pyopencl_expose_mempool(py::module_ &m)
585
- {
586
- m.def("bitlog2", pyopencl::bitlog2);
587
-
588
- {
589
- typedef pyopencl::buffer_allocator_base cls;
590
- py::class_<cls> wrapper(m, "AllocatorBase");
591
- wrapper
592
- .def("__call__", pyopencl::allocate_from_buffer_allocator, py::arg("size"))
593
- ;
594
-
595
- }
596
-
597
- {
598
- typedef pyopencl::memory_pool<pyopencl::test_allocator> cls;
599
-
600
- py::class_<cls> wrapper(m, "_TestMemoryPool");
601
- wrapper
602
- .def("__init__",
603
- [](cls *self, unsigned leading_bits_in_bin_id)
604
- {
605
- new (self) cls(
606
- std::shared_ptr<pyopencl::test_allocator>(
607
- new pyopencl::test_allocator()),
608
- leading_bits_in_bin_id);
609
- },
610
- py::arg("leading_bits_in_bin_id")=4
611
- )
612
- .def("allocate", [](std::shared_ptr<cls> pool, cls::size_type sz)
613
- {
614
- pool->allocate(sz);
615
- return py::none();
616
- })
617
- ;
618
-
619
- expose_memory_pool(wrapper);
620
- }
621
-
622
- {
623
- typedef pyopencl::deferred_buffer_allocator cls;
624
- py::class_<cls, pyopencl::buffer_allocator_base> wrapper(
625
- m, "DeferredAllocator");
626
- wrapper
627
- .def(py::init<std::shared_ptr<pyopencl::context> const &>())
628
- .def(py::init<
629
- std::shared_ptr<pyopencl::context> const &,
630
- cl_mem_flags>(),
631
- py::arg("queue"), py::arg("mem_flags"))
632
- ;
633
- }
634
-
635
- {
636
- typedef pyopencl::immediate_buffer_allocator cls;
637
- py::class_<cls, pyopencl::buffer_allocator_base> wrapper(
638
- m, "ImmediateAllocator");
639
- wrapper
640
- .def(py::init<pyopencl::command_queue &>())
641
- .def(py::init<pyopencl::command_queue &, cl_mem_flags>(),
642
- py::arg("queue"), py::arg("mem_flags"))
643
- ;
644
- }
645
-
646
- {
647
- typedef pyopencl::pooled_buffer cls;
648
- py::class_<cls, pyopencl::memory_object_holder>(m, "PooledBuffer")
649
- .def("release", &cls::free)
650
-
651
- .def("bind_to_queue", [](cls &self, pyopencl::command_queue &queue) { /* no-op */ })
652
- .def("unbind_from_queue", [](cls &self) { /* no-op */ })
653
- ;
654
- }
655
-
656
- {
657
- typedef pyopencl::memory_pool<pyopencl::buffer_allocator_base> cls;
658
-
659
- py::class_<cls> wrapper( m, "MemoryPool");
660
- wrapper
661
- .def(py::init<std::shared_ptr<pyopencl::buffer_allocator_base>, unsigned>(),
662
- py::arg("allocator"),
663
- py::arg("leading_bits_in_bin_id")=4
664
- )
665
- .def("allocate", pyopencl::allocate_from_buffer_pool, py::arg("size"))
666
- .def("__call__", pyopencl::allocate_from_buffer_pool, py::arg("size"))
667
- ;
668
-
669
- expose_memory_pool(wrapper);
670
- }
671
-
672
- #if PYOPENCL_CL_VERSION >= 0x2000
673
- {
674
- typedef pyopencl::svm_allocator cls;
675
- py::class_<cls> wrapper(m, "SVMAllocator");
676
- wrapper
677
- .def(py::init<std::shared_ptr<pyopencl::context> const &, cl_uint, cl_uint, pyopencl::command_queue *>(),
678
- py::arg("context"),
679
- /* py::kw_only(), */
680
- py::arg("alignment")=0,
681
- py::arg("flags")=CL_MEM_READ_WRITE,
682
- py::arg("queue").none(true)=nullptr
683
- )
684
- .def("__call__", pyopencl::svm_allocator_call, py::arg("size"))
685
- ;
686
- }
687
-
688
- {
689
- typedef pyopencl::pooled_svm cls;
690
- py::class_<cls, pyopencl::svm_pointer>(m, "PooledSVM")
691
- .def("release", &cls::free)
692
- .def("enqueue_release", &cls::free)
693
- .def("__eq__", [](const cls &self, const cls &other)
694
- { return self.svm_ptr() == other.svm_ptr(); })
695
- .def("__hash__", [](cls &self) { return (intptr_t) self.svm_ptr(); })
696
- .DEF_SIMPLE_METHOD(bind_to_queue)
697
- .DEF_SIMPLE_METHOD(unbind_from_queue)
698
-
699
- // only for diagnostic/debugging/testing purposes!
700
- .def_prop_ro("_queue",
701
- [](cls const &self) -> py::object
702
- {
703
- cl_command_queue queue = self.queue();
704
- if (queue)
705
- return py::cast(new pyopencl::command_queue(queue, true));
706
- else
707
- return py::none();
708
- })
709
- ;
710
- }
711
-
712
- {
713
- typedef pyopencl::memory_pool<pyopencl::svm_allocator> cls;
714
-
715
- py::class_<cls> wrapper( m, "SVMPool");
716
- wrapper
717
- .def(py::init<std::shared_ptr<pyopencl::svm_allocator>, unsigned>(),
718
- py::arg("allocator"),
719
- /* py::kw_only(), */
720
- py::arg("leading_bits_in_bin_id")=4
721
- )
722
- .def("__call__", pyopencl::allocate_from_svm_pool, py::arg("size"))
723
- ;
724
-
725
- expose_memory_pool(wrapper);
726
- }
727
-
728
- #endif
729
- }
730
-
731
- // vim: foldmethod=marker