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

cython.memoryview implementation

parent 2aa1bd83
...@@ -4,6 +4,7 @@ from Nodes import * ...@@ -4,6 +4,7 @@ from Nodes import *
from ExprNodes import * from ExprNodes import *
from StringEncoding import EncodedString from StringEncoding import EncodedString
from Errors import CompileError from Errors import CompileError
from UtilityCode import CythonUtilityCode
from Code import UtilityCode from Code import UtilityCode
import Cython.Compiler.Options import Cython.Compiler.Options
import Interpreter import Interpreter
...@@ -27,12 +28,13 @@ class IntroduceBufferAuxiliaryVars(CythonTransform): ...@@ -27,12 +28,13 @@ class IntroduceBufferAuxiliaryVars(CythonTransform):
# #
buffers_exists = False buffers_exists = False
using_memoryview = False
def __call__(self, node): def __call__(self, node):
assert isinstance(node, ModuleNode) assert isinstance(node, ModuleNode)
self.max_ndim = 0 self.max_ndim = 0
result = super(IntroduceBufferAuxiliaryVars, self).__call__(node) result = super(IntroduceBufferAuxiliaryVars, self).__call__(node)
if self.buffers_exists: if self.buffers_exists or self.using_memoryview:
use_bufstruct_declare_code(node.scope) use_bufstruct_declare_code(node.scope)
use_py2_buffer_functions(node.scope) use_py2_buffer_functions(node.scope)
use_empty_bufstruct_code(node.scope, self.max_ndim) use_empty_bufstruct_code(node.scope, self.max_ndim)
...@@ -52,6 +54,18 @@ class IntroduceBufferAuxiliaryVars(CythonTransform): ...@@ -52,6 +54,18 @@ class IntroduceBufferAuxiliaryVars(CythonTransform):
if len(bufvars) > 0: if len(bufvars) > 0:
self.buffers_exists = True self.buffers_exists = True
memviewvars = [entry for name, entry
in scope.entries.iteritems()
if entry.type.is_memoryview]
if len(memviewvars) > 0:
self.buffers_exists = True
for (name, entry) in scope.entries.iteritems():
if name == 'memoryview' and isinstance(entry.utility_code_definition, CythonUtilityCode):
self.using_memoryview = True
break
if isinstance(node, ModuleNode) and len(bufvars) > 0: if isinstance(node, ModuleNode) and len(bufvars) > 0:
# for now...note that pos is wrong # for now...note that pos is wrong
......
...@@ -88,8 +88,23 @@ class CythonScope(ModuleScope): ...@@ -88,8 +88,23 @@ class CythonScope(ModuleScope):
is_cdef=True) is_cdef=True)
entry.utility_code_definition = view_utility_code entry.utility_code_definition = view_utility_code
#
# cython.view.memoryview declaration
#
name = u'memoryview'
entry = viewscope.declare_c_class(name, None,
implementing=1,
objstruct_cname = '__pyx_obj_'+name,
typeobj_cname = '__pyx_tobj_'+name,
typeptr_cname=Naming.typeptr_prefix+name)
entry.utility_code_definition = view_utility_code
#
# cython.array declaration
#
name = u'array' name = u'array'
entry = self.declare_c_class(u'array', None, entry = self.declare_c_class(name, None,
implementing=1, implementing=1,
objstruct_cname='__pyx_obj_array', objstruct_cname='__pyx_obj_array',
typeobj_cname='__pyx_tobj_array', typeobj_cname='__pyx_tobj_array',
...@@ -101,13 +116,34 @@ class CythonScope(ModuleScope): ...@@ -101,13 +116,34 @@ class CythonScope(ModuleScope):
entry.utility_code_definition = cython_array_utility_code entry.utility_code_definition = cython_array_utility_code
entry.type.scope.declare_var(u'data', c_char_ptr_type, None, is_cdef = 1) arr_scope = entry.type.scope
entry.type.scope.declare_var(u'len', c_size_t_type, None, is_cdef = 1)
entry.type.scope.declare_var(u'format', c_char_ptr_type, None, is_cdef = 1) arr_scope.declare_var(u'data', c_char_ptr_type, None, is_cdef = 1)
entry.type.scope.declare_var(u'ndim', c_int_type, None, is_cdef = 1) arr_scope.declare_var(u'len', c_size_t_type, None, is_cdef = 1)
entry.type.scope.declare_var(u'shape', c_py_ssize_t_ptr_type, None, is_cdef = 1) arr_scope.declare_var(u'format', c_char_ptr_type, None, is_cdef = 1)
entry.type.scope.declare_var(u'strides', c_py_ssize_t_ptr_type, None, is_cdef = 1) arr_scope.declare_var(u'ndim', c_int_type, None, is_cdef = 1)
entry.type.scope.declare_var(u'itemsize', c_py_ssize_t_type, None, is_cdef = 1) arr_scope.declare_var(u'shape', c_py_ssize_t_ptr_type, None, is_cdef = 1)
arr_scope.declare_var(u'strides', c_py_ssize_t_ptr_type, None, is_cdef = 1)
arr_scope.declare_var(u'itemsize', c_py_ssize_t_type, None, is_cdef = 1)
# declare the __getbuffer__ & __releasebuffer__ functions
for name in ('__getbuffer__', '__releasebuffer__'):
entry = arr_scope.declare_pyfunction(name, None)
# XXX: absolutely horrendous hack right here!!!
# To be fixed!!!
entry.func_cname = '__pyx_pf_9__pyxutil_5array_' + name
entry.utility_code_definition = cython_array_utility_code
#
# Declare the array modes
#
entry = self.declare_var(u'PyBUF_C_CONTIGUOUS', c_int_type, None,
cname='PyBUF_C_CONTIGUOUS',is_cdef = 1)
entry = self.declare_var(u'PyBUF_F_CONTIGUOUS', c_int_type, None,
is_cdef = 1)
entry = self.declare_var(u'PyBUF_ANY_CONTIGUOUS', c_int_type, None,
is_cdef = 1)
def create_cython_scope(context, create_testscope): def create_cython_scope(context, create_testscope):
...@@ -214,8 +250,25 @@ cdef follow = Enum("<follow axis packing mode>") ...@@ -214,8 +250,25 @@ cdef follow = Enum("<follow axis packing mode>")
cdef direct = Enum("<direct axis access mode>") cdef direct = Enum("<direct axis access mode>")
cdef ptr = Enum("<ptr axis access mode>") cdef ptr = Enum("<ptr axis access mode>")
cdef full = Enum("<full axis access mode>") cdef full = Enum("<full axis access mode>")
cdef extern from *:
int __Pyx_GetBuffer(object, Py_buffer *, int)
void __Pyx_ReleaseBuffer(Py_buffer *)
cdef class memoryview:
cdef Py_buffer view
def __cinit__(memoryview self, obj, int flags):
__Pyx_GetBuffer(obj, &self.view, flags)
def __dealloc__(memoryview self):
__Pyx_ReleaseBuffer(&self.view)
""", prefix="__pyx_viewaxis_") """, prefix="__pyx_viewaxis_")
cyarray_prefix = u'__pyx_cythonarray_'
cython_array_utility_code = CythonUtilityCode(u''' cython_array_utility_code = CythonUtilityCode(u'''
cdef extern from "stdlib.h": cdef extern from "stdlib.h":
void *malloc(size_t) void *malloc(size_t)
...@@ -224,27 +277,9 @@ cdef extern from "stdlib.h": ...@@ -224,27 +277,9 @@ cdef extern from "stdlib.h":
cdef extern from "Python.h": cdef extern from "Python.h":
cdef enum: cdef enum:
PyBUF_SIMPLE,
PyBUF_WRITABLE,
PyBUF_WRITEABLE, # backwards compatability
PyBUF_FORMAT,
PyBUF_ND,
PyBUF_STRIDES,
PyBUF_C_CONTIGUOUS, PyBUF_C_CONTIGUOUS,
PyBUF_F_CONTIGUOUS, PyBUF_F_CONTIGUOUS,
PyBUF_ANY_CONTIGUOUS, PyBUF_ANY_CONTIGUOUS
PyBUF_INDIRECT,
PyBUF_CONTIG,
PyBUF_CONTIG_RO,
PyBUF_STRIDED,
PyBUF_STRIDED_RO,
PyBUF_RECORDS,
PyBUF_RECORDS_RO,
PyBUF_FULL,
PyBUF_FULL_RO,
PyBUF_READ,
PyBUF_WRITE,
PyBUF_SHADOW
cdef class array: cdef class array:
...@@ -336,7 +371,9 @@ cdef class array: ...@@ -336,7 +371,9 @@ cdef class array:
info.obj = None info.obj = None
def __releasebuffer__(array self, Py_buffer* info): def __releasebuffer__(array self, Py_buffer* info):
print "array.__releasebuffer__" # array.__releasebuffer__ should not be called,
# because the Py_buffer's 'obj' field is set to None.
raise NotImplementedError()
def __dealloc__(array self): def __dealloc__(array self):
if self.data: if self.data:
...@@ -350,4 +387,4 @@ cdef class array: ...@@ -350,4 +387,4 @@ cdef class array:
self.shape = NULL self.shape = NULL
self.format = NULL self.format = NULL
self.itemsize = 0 self.itemsize = 0
''', prefix='__pyx_cythonarray_') ''', prefix=cyarray_prefix)
\ No newline at end of file \ No newline at end of file
...@@ -19,7 +19,7 @@ def get_axes_specs(env, axes): ...@@ -19,7 +19,7 @@ def get_axes_specs(env, axes):
packing is one of 'contig', 'strided' or 'follow' packing is one of 'contig', 'strided' or 'follow'
''' '''
cythonscope = env.context.cython_scope cythonscope = env.global_scope().context.cython_scope
viewscope = cythonscope.viewscope viewscope = cythonscope.viewscope
access_specs = tuple([viewscope.lookup(name) access_specs = tuple([viewscope.lookup(name)
......
...@@ -823,16 +823,14 @@ class MemoryViewTypeNode(CBaseTypeNode): ...@@ -823,16 +823,14 @@ class MemoryViewTypeNode(CBaseTypeNode):
return self.type return self.type
self.type = PyrexTypes.MemoryViewType(base_type, axes_specs) self.type = PyrexTypes.MemoryViewType(base_type, axes_specs)
return base_type # XXX: just for testing!!! return self.type
class CNestedBaseTypeNode(CBaseTypeNode): class CNestedBaseTypeNode(CBaseTypeNode):
# For C++ classes that live inside other C++ classes. # For C++ classes that live inside other C++ classes.
# name string # name string
# base_type CBaseTypeNode # base_type CBaseTypeNode
child_attrs = ['base_type'] child_attrs = ['base_type']
def analyse(self, env, could_be_name = None): def analyse(self, env, could_be_name = None):
base_type = self.base_type.analyse(env) base_type = self.base_type.analyse(env)
if base_type is PyrexTypes.error_type: if base_type is PyrexTypes.error_type:
...@@ -2277,13 +2275,15 @@ class DefNode(FuncDefNode): ...@@ -2277,13 +2275,15 @@ class DefNode(FuncDefNode):
prefix = env.next_id(env.scope_prefix) prefix = env.next_id(env.scope_prefix)
entry.func_cname = \ entry.func_cname = \
Naming.pyfunc_prefix + prefix + name env.mangle(Naming.pyfunc_prefix, name)
# Naming.pyfunc_prefix + prefix + name
entry.pymethdef_cname = \ entry.pymethdef_cname = \
Naming.pymethdef_prefix + prefix + name env.mangle(Naming.pymethdef_prefix, name)
# Naming.pymethdef_prefix + prefix + name
if Options.docstrings: if Options.docstrings:
entry.doc = embed_position(self.pos, self.doc) entry.doc = embed_position(self.pos, self.doc)
entry.doc_cname = \ entry.doc_cname = \
Naming.funcdoc_prefix + prefix + name env.mangle(Naming.funcdoc_prefix, name)
if entry.is_special: if entry.is_special:
if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']): if entry.name in TypeSlots.invisible or not entry.doc or (entry.name in '__getattr__' and env.directives['fast_getattr']):
entry.wrapperbase_cname = None entry.wrapperbase_cname = None
......
...@@ -17,7 +17,7 @@ class NonManglingModuleScope(Symtab.ModuleScope): ...@@ -17,7 +17,7 @@ class NonManglingModuleScope(Symtab.ModuleScope):
def mangle(self, prefix, name=None): def mangle(self, prefix, name=None):
if name: if name:
if prefix in (Naming.typeobj_prefix, Naming.func_prefix, Naming.var_prefix): if prefix in (Naming.typeobj_prefix, Naming.func_prefix, Naming.var_prefix, Naming.pyfunc_prefix):
# Functions, classes etc. gets a manually defined prefix easily # Functions, classes etc. gets a manually defined prefix easily
# manually callable instead (the one passed to CythonUtilityCode) # manually callable instead (the one passed to CythonUtilityCode)
prefix = self.prefix prefix = self.prefix
......
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