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

memoryviewslice .is_c_contig() and .is_f_contig() implementations

parent 088bf12c
...@@ -180,6 +180,57 @@ def get_copy_contents_name(from_mvs, to_mvs): ...@@ -180,6 +180,57 @@ def get_copy_contents_name(from_mvs, to_mvs):
mangle_dtype_name(dtype))) mangle_dtype_name(dtype)))
def get_is_contig_func_name(c_or_f):
return "__Pyx_Buffer_is_%s_contiguous" % c_or_f
def get_is_contiguous_func(c_or_f):
func_name = get_is_contig_func_name(c_or_f)
decl = "static int %s(const __Pyx_memviewslice); /* proto */\n" % func_name
impl = """
static int %s(const __Pyx_memviewslice mvs) {
/* returns 1 if mvs is the right contiguity, 0 otherwise */
int i, ndim = mvs.memview->view.ndim;
Py_ssize_t itemsize = mvs.memview->view.itemsize;
unsigned long size = 0;
""" % func_name
if c_or_f == 'fortran':
for_loop = "for(i=0; i<ndim; i++)"
elif c_or_f == 'c':
for_loop = "for(i=ndim-1; i>-1; i--)"
else:
assert False
impl += """
size = 1;
%(for_loop)s {
#ifdef DEBUG
printf("mvs.diminfo[i].suboffsets %%d\\n", mvs.diminfo[i].suboffsets);
printf("mvs.diminfo[i].strides %%d\\n", mvs.diminfo[i].strides);
printf("mvs.diminfo[i].shape %%d\\n", mvs.diminfo[i].shape);
printf("size %%d\\n", size);
printf("ndim %%d\\n", ndim);
#endif
#undef DEBUG
if(mvs.diminfo[i].suboffsets >= 0) {
return 0;
}
if(size * itemsize != mvs.diminfo[i].strides) {
return 0;
}
size *= mvs.diminfo[i].shape;
}
return 1;
}""" % {'for_loop' : for_loop}
return decl, impl
copy_template = ''' copy_template = '''
static __Pyx_memviewslice %(copy_name)s(const __Pyx_memviewslice from_mvs) { static __Pyx_memviewslice %(copy_name)s(const __Pyx_memviewslice from_mvs) {
...@@ -754,6 +805,8 @@ static int __Pyx_init_memviewslice( ...@@ -754,6 +805,8 @@ static int __Pyx_init_memviewslice(
memviewslice->diminfo[i].shape = buf->shape[i]; memviewslice->diminfo[i].shape = buf->shape[i];
if(buf->suboffsets) { if(buf->suboffsets) {
memviewslice->diminfo[i].suboffsets = buf->suboffsets[i]; memviewslice->diminfo[i].suboffsets = buf->suboffsets[i];
} else {
memviewslice->diminfo[i].suboffsets = -1;
} }
} }
......
...@@ -394,15 +394,14 @@ class MemoryViewSliceType(PyrexType): ...@@ -394,15 +394,14 @@ class MemoryViewSliceType(PyrexType):
scope.declare_var('_data', c_char_ptr_type, None, cname='data', is_cdef=1) scope.declare_var('_data', c_char_ptr_type, None, cname='data', is_cdef=1)
mangle_dtype = MemoryView.mangle_dtype_name(self.dtype) mangle_dtype = MemoryView.mangle_dtype_name(self.dtype)
ndim = len(self.axes) ndim = len(self.axes)
to_axes_c = [('direct', 'contig')] to_axes_c = [('direct', 'contig')]
to_axes_f = [('direct', 'contig')] to_axes_f = [('direct', 'contig')]
if ndim-1: if ndim-1:
to_axes_c = [('direct', 'follow')*(ndim-1)] + to_axes_c to_axes_c = [('direct', 'follow')]*(ndim-1) + to_axes_c
to_axes_f = to_axes_f + [('direct', 'follow')*(ndim-1)] to_axes_f = to_axes_f + [('direct', 'follow')]*(ndim-1)
to_memview_c = MemoryViewSliceType(self.dtype, to_axes_c, self.env) to_memview_c = MemoryViewSliceType(self.dtype, to_axes_c, self.env)
to_memview_f = MemoryViewSliceType(self.dtype, to_axes_f, self.env) to_memview_f = MemoryViewSliceType(self.dtype, to_axes_f, self.env)
...@@ -473,7 +472,31 @@ static __Pyx_memviewslice %s(const __Pyx_memviewslice); /* proto */ ...@@ -473,7 +472,31 @@ static __Pyx_memviewslice %s(const __Pyx_memviewslice); /* proto */
if not f_copy_used: if not f_copy_used:
self.env.use_utility_code(f_copy_util_code) self.env.use_utility_code(f_copy_util_code)
# ensure the right util code is used # is_c_contiguous and is_f_contiguous functions
for c_or_f, cython_name in (('c', 'is_c_contig'), ('fortran', 'is_f_contig')):
is_contig_name = MemoryView.get_is_contig_func_name(c_or_f)
scope.declare_cfunction(cython_name,
CFuncType(c_int_type,
[CFuncTypeArg("memviewslice", self, None)]),
pos = None,
defining = 1,
cname = is_contig_name)
contig_decl, contig_impl = MemoryView.get_is_contiguous_func(c_or_f)
contig_util_code = UtilityCode(
proto = contig_decl, impl = contig_impl)
contig_used = [1 for util_code in \
self.env.global_scope().utility_code_list \
if contig_decl == util_code.proto]
if not contig_used:
self.env.use_utility_code(contig_util_code)
# use the supporting util code
MemoryView.use_cython_array(self.env) MemoryView.use_cython_array(self.env)
MemoryView.use_memview_util_code(self.env) MemoryView.use_memview_util_code(self.env)
......
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