Commit 6d2c3b93 authored by serge-sans-paille's avatar serge-sans-paille Committed by Stefan Behnel

Support Pythran shape (GH-3307)

* Support Pythran shape

Through a conversion to array. I've tested that and it's ok performance wise,
the C++ compiler can deal with the abstraction (with a small overhead though).
parent d86aebef
......@@ -1556,7 +1556,13 @@ class PythranExpr(CType):
self.scope = scope = Symtab.CClassScope('', None, visibility="extern")
scope.parent_type = self
scope.directives = {}
scope.declare_var("shape", CPtrType(c_long_type), None, cname="_shape", is_cdef=True)
shape = scope.declare_cgetter(
"shape",
CPtrType(c_long_type),
pos=None,
cname="__Pyx_PythranShapeAccessor",
visibility="extern",
nogil=True)
scope.declare_var("ndim", c_long_type, None, cname="value", is_cdef=True)
return True
......
......@@ -855,6 +855,23 @@ class Scope(object):
type.entry = entry
return entry
def declare_cgetter(self, name, return_type, pos=None, cname=None,
visibility="private", modifiers=(), defining=False, **cfunc_type_config):
assert all(
k in ('exception_value', 'exception_check', 'nogil', 'with_gil', 'is_const_method', 'is_static_method')
for k in cfunc_type_config
)
cfunc_type = PyrexTypes.CFuncType(
return_type,
[PyrexTypes.CFuncTypeArg("self", self.parent_type, None)],
**cfunc_type_config)
entry = self.declare_cfunction(
name, cfunc_type, pos, cname=None, visibility=visibility, modifiers=modifiers, defining=defining)
entry.is_cgetter = True
if cname is not None:
entry.func_cname = cname
return entry
def add_cfunction(self, name, type, pos, cname, visibility, modifiers,
inherited=False):
# Add a C function entry without giving it a func_cname.
......
......@@ -56,3 +56,5 @@ auto __Pyx_pythran_to_python(T &&value) -> decltype(to_python(
using returnable_type = typename pythonic::returnable<typename std::remove_cv<typename std::remove_reference<T>::type>::type>::type;
return to_python(returnable_type{std::forward<T>(value)});
}
#define __Pyx_PythranShapeAccessor(x) (x.shape().array())
......@@ -55,3 +55,13 @@ def calculate_tax(cnp.ndarray[double, ndim=1] d):
np.sum(seg3 * prog_seg3 + 939.57) +
np.sum(seg4 * prog_seg4)
) / np.sum(d)
def access_shape():
"""
>>> access_shape()
10
"""
cdef cnp.ndarray[double, ndim=2, mode='c'] array_in = \
1e10 * np.ones((10, 10))
return array_in.shape[0]
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