Skip to content

Commit 8121c2e

Browse files
committed
Add a check that new strides don't go outside allocated memory and add
some tests.
1 parent e9b39d8 commit 8121c2e

3 files changed

Lines changed: 59 additions & 0 deletions

File tree

pygpu/gpuarray.pxd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ cdef extern from "gpuarray/buffer.h":
7373
gpucontext *gpucontext_init(const char *name, int devno, int flags, int *ret)
7474
void gpucontext_deref(gpucontext *ctx)
7575
char *gpucontext_error(gpucontext *ctx, int err)
76+
int gpudata_property(gpudata *ctx, int prop_id, void *res)
7677
int gpucontext_property(gpucontext *ctx, int prop_id, void *res)
7778
int gpukernel_property(gpukernel *k, int prop_id, void *res)
7879
gpucontext *gpudata_context(gpudata *)
@@ -99,6 +100,9 @@ cdef extern from "gpuarray/buffer.h":
99100
int GA_CTX_PROP_MAXGSIZE0
100101
int GA_CTX_PROP_MAXGSIZE1
101102
int GA_CTX_PROP_MAXGSIZE2
103+
104+
int GA_BUFFER_PROP_SIZE
105+
102106
int GA_KERNEL_PROP_MAXLSIZE
103107
int GA_KERNEL_PROP_PREFLSIZE
104108
int GA_KERNEL_PROP_NUMARGS

pygpu/gpuarray.pyx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,32 @@ cdef ga_order to_ga_order(ord) except <ga_order>-2:
212212
else:
213213
raise ValueError, "Valid orders are: 'A' (any), 'C' (C), 'F' (Fortran)"
214214

215+
cdef int strides_ok(GpuArray a, strides):
216+
cdef ssize_t max_axis_offset
217+
cdef size_t lower = a.ga.offset
218+
cdef size_t upper = a.ga.offset
219+
cdef size_t itemsize = gpuarray_get_elsize(a.ga.typecode)
220+
cdef size_t size
221+
cdef unsigned int i
222+
223+
gpudata_property(a.ga.data, GA_BUFFER_PROP_SIZE, &size)
224+
225+
for i in range(a.ga.nd):
226+
if a.ga.dimensions[i] == 0:
227+
return 1
228+
229+
max_axis_offset = strides[i] * (a.ga.dimensions[i] - 1)
230+
if max_axis_offset > 0:
231+
if upper + max_axis_offset > size:
232+
return 0
233+
upper += max_axis_offset
234+
else:
235+
if lower < -max_axis_offset:
236+
return 0
237+
lower += max_axis_offset
238+
return (upper + itemsize) <= size
239+
240+
215241
class GpuArrayException(Exception):
216242
"""
217243
Exception used for most errors related to libgpuarray.
@@ -1944,6 +1970,8 @@ cdef class GpuArray:
19441970
cdef unsigned int i
19451971
if len(newstrides) != self.ga.nd:
19461972
raise ValueError("new strides are the wrong length")
1973+
if not strides_ok(self, newstrides):
1974+
raise ValueError("new strides go outside of allocated memory")
19471975
for i in range(self.ga.nd):
19481976
self.ga.strides[i] = newstrides[i]
19491977
array_fix_flags(self)

pygpu/tests/test_gpu_ndarray.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
import numpy
1010

11+
from nose.tools import assert_raises
1112
import pygpu
1213
from pygpu.gpuarray import GpuArray, GpuContext, GpuKernel
1314

@@ -448,6 +449,32 @@ def reshape(shps, offseted, order1, order2):
448449
assert numpy.allclose(outc, numpy.asarray(outg))
449450

450451

452+
def test_strides():
453+
yield strides_, (4, 4), 'c', 1, (4, 4)
454+
yield strides_, (4, 4), 'c', 1, (4, 16)
455+
yield strides_, (4, 4), 'c', 1, (16, 4)
456+
yield strides_, (4, 4), 'c', 1, (16, 8)
457+
yield strides_, (4, 4), 'c', 1, (16, 0)
458+
yield strides_, (4, 4), 'c', -1, (-20, 4)
459+
yield strides_, (4, 4), 'c', -1, (-12, 4)
460+
461+
462+
def set_strides(a, newstr):
463+
a.strides = newstr
464+
465+
466+
def strides_(shp, order, sliced, newstr):
467+
ac, ag = gen_gpuarray(shp, 'float32', sliced=sliced, order=order, ctx=ctx)
468+
try:
469+
ac.strides = newstr
470+
except ValueError:
471+
assert_raises(ValueError, set_strides, ag, newstr)
472+
return
473+
ag.strides = newstr
474+
check_flags(ag, ac)
475+
assert numpy.allclose(ac, numpy.asarray(ag))
476+
477+
451478
def test_transpose():
452479
for shp in [(2, 3), (4, 8, 9), (1, 2, 3, 4)]:
453480
for offseted in [True, False]:

0 commit comments

Comments
 (0)