Skip to content

Commit 8c15afc

Browse files
committed
Experiment with SVM backing arrays
1 parent defe185 commit 8c15afc

2 files changed

Lines changed: 73 additions & 6 deletions

File tree

examples/demo_array_svm.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import pyopencl as cl
2+
import pyopencl.array as cl_array
3+
import numpy as np
4+
import numpy.linalg as la
5+
6+
n = 5000000
7+
a = np.random.rand(n).astype(np.float32)
8+
b = np.random.rand(n).astype(np.float32)
9+
10+
11+
class SVMAllocator:
12+
def __init__(self, ctx, flags, alignment):
13+
self._context = ctx
14+
self._flags = flags
15+
self._alignment = alignment
16+
17+
def __call__(self, nbytes):
18+
return cl.SVM(cl.svm_empty(
19+
ctx, self._flags, (nbytes,), np.int8, "C", self._alignment))
20+
21+
22+
ctx = cl.create_some_context()
23+
queue = cl.CommandQueue(ctx)
24+
25+
alloc = SVMAllocator(ctx,
26+
cl.svm_mem_flags.READ_WRITE | cl.svm_mem_flags.SVM_FINE_GRAIN_BUFFER,
27+
0)
28+
29+
a_dev = cl_array.to_device(queue, a, allocator=alloc)
30+
print("A_DEV", a_dev.data.mem.nbytes, a_dev.data.mem.__array_interface__)
31+
b_dev = cl_array.to_device(queue, b, allocator=alloc)
32+
dest_dev = cl_array.empty_like(a_dev)
33+
print("DEST", dest_dev.data.mem.__array_interface__)
34+
35+
prg = cl.Program(ctx, """
36+
__kernel void sum(__global const float *a,
37+
__global const float *b, __global float *c)
38+
{
39+
int gid = get_global_id(0);
40+
c[gid] = a[gid] + b[gid];
41+
}
42+
""").build()
43+
44+
knl = prg.sum # Use this Kernel object for repeated calls
45+
knl(queue, a.shape, None, a_dev.data, b_dev.data, dest_dev.data)
46+
47+
# PROBLEM: numpy frees the temporary out of (a_dev+b_dev) before
48+
# we're done with it
49+
diff = dest_dev - (a_dev+b_dev)
50+
if 0:
51+
diff = diff.get()
52+
np.set_printoptions(linewidth=400)
53+
print(dest_dev)
54+
print((a_dev+b_dev).get())
55+
print(diff)
56+
print(la.norm(diff))
57+
print("A_DEV", a_dev.data.mem.__array_interface__)

pyopencl/array.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -720,9 +720,14 @@ def set(self, ary, queue=None, async_=None, **kwargs):
720720
stacklevel=2)
721721

722722
if self.size:
723-
event1 = cl.enqueue_copy(queue or self.queue, self.base_data, ary,
724-
device_offset=self.offset,
725-
is_blocking=not async_)
723+
if self.offset:
724+
event1 = cl.enqueue_copy(queue or self.queue, self.base_data, ary,
725+
device_offset=self.offset,
726+
is_blocking=not async_)
727+
else:
728+
event1 = cl.enqueue_copy(queue or self.queue, self.base_data, ary,
729+
is_blocking=not async_)
730+
726731
self.add_event(event1)
727732

728733
def _get(self, queue=None, ary=None, async_=None, **kwargs):
@@ -770,9 +775,14 @@ def _get(self, queue=None, ary=None, async_=None, **kwargs):
770775
"to associate one.")
771776

772777
if self.size:
773-
event1 = cl.enqueue_copy(queue, ary, self.base_data,
774-
device_offset=self.offset,
775-
wait_for=self.events, is_blocking=not async_)
778+
if self.offset:
779+
event1 = cl.enqueue_copy(queue, ary, self.base_data,
780+
device_offset=self.offset,
781+
wait_for=self.events, is_blocking=not async_)
782+
else:
783+
event1 = cl.enqueue_copy(queue, ary, self.base_data,
784+
wait_for=self.events, is_blocking=not async_)
785+
776786
self.add_event(event1)
777787
else:
778788
event1 = None

0 commit comments

Comments
 (0)