Commit d7e5e0c9 authored by Kurt Smith's avatar Kurt Smith Committed by Mark Florisson

Added validation checks on memoryviews.

parent e79e17f8
......@@ -106,8 +106,51 @@ def get_axes_specs(env, axes):
else:
raise CompileError(axis.step.pos, INVALID_ERR)
validate_axes_specs(axes[0].start.pos, axes_specs)
return axes_specs
def validate_axes_specs(pos, specs):
packing_specs = ('contig', 'strided', 'follow')
access_specs = ('direct', 'ptr', 'full')
is_c_contig = is_f_contig = False
packing_idx = 1
if (specs[0][packing_idx] == 'contig' and
all(axis[packing_idx] == 'follow' for axis in specs[1:])):
# f_contiguous: 'contig', 'follow', 'follow', ..., 'follow'
is_f_contig = True
elif (len(specs) > 1 and
specs[-1][packing_idx] == 'contig' and
all(axis[packing_idx] == 'follow' for axis in specs[:-1])):
# c_contiguous: 'follow', 'follow', ..., 'follow', 'contig'
is_c_contig = True
has_contig = has_follow = has_strided = False
for access, packing in specs:
if not (access in access_specs and
packing in packing_specs):
raise CompileError(pos, "Invalid axes specification.")
if packing == 'strided':
has_strided = True
elif packing == 'contig':
if has_contig:
raise CompileError(pos, "Only one contiguous axis may be specified.")
has_contig = True
elif packing == 'follow':
if has_strided:
raise CompileError(pos, "A memoryview cannot have both follow and strided axis specifiers.")
if not (is_c_contig or is_f_contig):
raise CompileError(pos, "Invalid use of the follow specifier.")
def _get_resolved_spec(env, spec):
# spec must be a NameNode or an AttributeNode
......
......@@ -311,9 +311,43 @@ class CTypedefType(BaseType):
class MemoryViewType(BaseType):
def __init__(self, base, axes):
'''
MemoryViewType(base, axes)
Base is the C base type; axes is a list of (access, packing) strings,
where access is one of 'full', 'direct' or 'ptr' and packing is one of
'contig', 'strided' or 'follow'. There is one (access, packing) tuple
for each dimension.
the access specifiers determine whether the array data contains
pointers that need to be dereferenced along that axis when
retrieving/setting:
'direct' -- No pointers stored in this dimension.
'ptr' -- Pointer stored in this dimension.
'full' -- Check along this dimension, don't assume either.
the packing specifiers specify how the array elements are layed-out
in memory.
'contig' -- The data are contiguous in memory along this dimension.
At most one dimension may be specified as 'contig'.
'strided' -- The data aren't contiguous along this dimenison.
'follow' -- Used for C/Fortran contiguous arrays, a 'follow' dimension
has its stride automatically computed from extents of the other
dimensions to ensure C or Fortran memory layout.
C-contiguous memory has 'direct' as the access spec, 'contig' as the
*last* axis' packing spec and 'follow' for all other packing specs.
Fortran-contiguous memory has 'direct' as the access spec, 'contig' as
the *first* axis' packing spec and 'follow' for all other packing
specs.
'''
self.base = base
self.axes = axes
class BufferType(BaseType):
#
# Delegates most attribute
......
......@@ -14,4 +14,4 @@ cdef unsigned long[0:, 0:, 0:, 0::0x0001] c_contig0
cdef float[::foo & bar, ::cython.view.direct & cython.view.follow] view4
cdef int[::view.full & foo] view3
cdef int[::view.ptr & follow] view1000
cdef int[::view.ptr & view.strided] view1000
# mode: error
cimport cython
from cython.view cimport contig as foo, full as bar, follow
from cython cimport view
biz = cython.view.contig
foz = cython.view.full
adict = {'view': cython.view}
alist = [adict]
......@@ -24,6 +24,7 @@ cdef signed char[::view.ptr & view.direct] no_access_spec
cdef signed char[::1-1+1] expr_spec
cdef signed char[::blargh] bad_name
cdef double[::alist[0]['view'].full] expr_attribute
cdef double[::view.ptr & view.follow] no_single_follow
_ERRORS = u'''
11:25: Cannot specify an array that is both C and Fortran contiguous.
......@@ -42,4 +43,5 @@ _ERRORS = u'''
24:22: Invalid axis specification.
25:25: Invalid axis specification.
26:22: no expressions allowed in axis spec, only names (e.g. cython.view.contig).
27:12: Invalid use of the follow specifier.
'''
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment