Cython has moved to github.

cython

view Cython/Includes/numpy.pxd @ 1327:b072eae5f5a9

numpy.pxd support also when Py_ssize_t and npy_intp do not have the same size.
author David Cournapeau <david@ar.media.kyoto-u.ac.jp>
date Mon Nov 10 13:19:04 2008 +0100 (3 years ago)
parents 83e49c6283a8
children 5278c13c1db6
line source
1 cimport python_buffer as pybuf
2 cimport stdlib
4 cdef extern from "Python.h":
5 ctypedef int Py_intptr_t
7 cdef extern from "numpy/arrayobject.h":
8 ctypedef Py_intptr_t npy_intp
10 cdef enum:
11 NPY_BOOL,
12 NPY_BYTE, NPY_UBYTE,
13 NPY_SHORT, NPY_USHORT,
14 NPY_INT, NPY_UINT,
15 NPY_LONG, NPY_ULONG,
16 NPY_LONGLONG, NPY_ULONGLONG,
17 NPY_FLOAT, NPY_DOUBLE, NPY_LONGDOUBLE,
18 NPY_CFLOAT, NPY_CDOUBLE, NPY_CLONGDOUBLE,
19 NPY_OBJECT,
20 NPY_STRING, NPY_UNICODE,
21 NPY_VOID,
22 NPY_NTYPES,
23 NPY_NOTYPE,
24 NPY_CHAR,
25 NPY_USERDEF,
27 NPY_C_CONTIGUOUS,
28 NPY_F_CONTIGUOUS
30 ctypedef class numpy.dtype [object PyArray_Descr]:
31 cdef int type_num
32 cdef object fields
33 cdef object names
36 ctypedef class numpy.ndarray [object PyArrayObject]:
37 cdef __cythonbufferdefaults__ = {"mode": "strided"}
39 cdef:
40 char *data
41 int ndim "nd"
42 npy_intp *shape "dimensions"
43 npy_intp *strides
44 int flags
45 dtype descr
47 # Note: This syntax (function definition in pxd files) is an
48 # experimental exception made for __getbuffer__ and __releasebuffer__
49 # -- the details of this may change.
50 def __getbuffer__(ndarray self, Py_buffer* info, int flags):
51 # This implementation of getbuffer is geared towards Cython
52 # requirements, and does not yet fullfill the PEP.
53 # In particular strided access is always provided regardless
54 # of flags
55 cdef int copy_shape
56 if sizeof(npy_intp) != sizeof(Py_ssize_t):
57 copy_shape = 1
58 else:
59 copy_shape = 0
61 if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
62 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
63 raise ValueError("ndarray is not C contiguous")
65 if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
66 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
67 raise ValueError("ndarray is not Fortran contiguous")
69 info.buf = PyArray_DATA(self)
70 info.ndim = PyArray_NDIM(self)
71 if copy_shape:
72 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * info.ndim)
73 info.shape = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * info.ndim)
74 for i in range(info.ndim):
75 info.strides[i] = PyArray_STRIDES(self)[i]
76 info.shape[i] = PyArray_DIMS(self)[i]
77 else:
78 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
79 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
80 info.suboffsets = NULL
81 info.itemsize = PyArray_ITEMSIZE(self)
82 info.readonly = not PyArray_ISWRITEABLE(self)
84 cdef int t
85 cdef char* f = NULL
86 cdef dtype descr = self.descr
87 cdef list stack
89 cdef bint hasfields = PyDataType_HASFIELDS(descr)
91 # Ugly hack warning:
92 # Cython currently will not support helper functions in
93 # pxd files -- so we must keep our own, manual stack!
94 # In addition, avoid allocation of the stack in the common
95 # case that we are dealing with a single non-nested datatype...
96 # (this would look much prettier if we could use utility
97 # functions).
99 if not hasfields and not copy_shape:
100 # do not call releasebuffer
101 info.obj = None
102 else:
103 # need to call releasebuffer
104 info.obj = self
106 if not hasfields:
107 t = descr.type_num
108 if t == NPY_BYTE: f = "b"
109 elif t == NPY_UBYTE: f = "B"
110 elif t == NPY_SHORT: f = "h"
111 elif t == NPY_USHORT: f = "H"
112 elif t == NPY_INT: f = "i"
113 elif t == NPY_UINT: f = "I"
114 elif t == NPY_LONG: f = "l"
115 elif t == NPY_ULONG: f = "L"
116 elif t == NPY_LONGLONG: f = "q"
117 elif t == NPY_ULONGLONG: f = "Q"
118 elif t == NPY_FLOAT: f = "f"
119 elif t == NPY_DOUBLE: f = "d"
120 elif t == NPY_LONGDOUBLE: f = "g"
121 elif t == NPY_CFLOAT: f = "Zf"
122 elif t == NPY_CDOUBLE: f = "Zd"
123 elif t == NPY_CLONGDOUBLE: f = "Zg"
124 elif t == NPY_OBJECT: f = "O"
125 else:
126 raise ValueError("unknown dtype code in numpy.pxd (%d)" % t)
127 info.format = f
128 return
129 else:
130 info.format = <char*>stdlib.malloc(255) # static size
131 f = info.format
132 stack = [iter(descr.fields.iteritems())]
134 while True:
135 iterator = stack[-1]
136 descr = None
137 while descr is None:
138 try:
139 descr = iterator.next()[1][0]
140 except StopIteration:
141 stack.pop()
142 if len(stack) > 0:
143 f[0] = 125 #"}"
144 f += 1
145 iterator = stack[-1]
146 else:
147 f[0] = 0 # Terminate string!
148 return
150 hasfields = PyDataType_HASFIELDS(descr)
151 if not hasfields:
152 t = descr.type_num
153 if f - info.format > 240: # this should leave room for "T{" and "}" as well
154 raise RuntimeError("Format string allocated too short.")
156 # Until ticket #99 is fixed, use integers to avoid warnings
157 if t == NPY_BYTE: f[0] = 98 #"b"
158 elif t == NPY_UBYTE: f[0] = 66 #"B"
159 elif t == NPY_SHORT: f[0] = 104 #"h"
160 elif t == NPY_USHORT: f[0] = 72 #"H"
161 elif t == NPY_INT: f[0] = 105 #"i"
162 elif t == NPY_UINT: f[0] = 73 #"I"
163 elif t == NPY_LONG: f[0] = 108 #"l"
164 elif t == NPY_ULONG: f[0] = 76 #"L"
165 elif t == NPY_LONGLONG: f[0] = 113 #"q"
166 elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
167 elif t == NPY_FLOAT: f[0] = 102 #"f"
168 elif t == NPY_DOUBLE: f[0] = 100 #"d"
169 elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
170 elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1
171 elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1
172 elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1
173 elif t == NPY_OBJECT: f[0] = 79 #"O"
174 else:
175 raise ValueError("unknown dtype code in numpy.pxd (%d)" % t)
176 f += 1
177 else:
178 f[0] = 84 #"T"
179 f[1] = 123 #"{"
180 f += 2
181 stack.append(iter(descr.fields.iteritems()))
183 def __releasebuffer__(ndarray self, Py_buffer* info):
184 # This can not be called unless format needs to be freed (as
185 # obj is set to NULL in those case)
186 stdlib.free(info.format)
187 if sizeof(npy_intp) != sizeof(Py_ssize_t):
188 stdlib.free(info.shape)
189 stdlib.free(info.strides)
192 cdef void* PyArray_DATA(ndarray arr)
193 cdef int PyArray_TYPE(ndarray arr)
194 cdef int PyArray_NDIM(ndarray arr)
195 cdef int PyArray_ISWRITEABLE(ndarray arr)
196 cdef npy_intp* PyArray_STRIDES(ndarray arr)
197 cdef npy_intp* PyArray_DIMS(ndarray arr)
198 cdef int PyArray_ITEMSIZE(ndarray arr)
199 cdef int PyArray_CHKFLAGS(ndarray arr, int flags)
200 cdef int PyArray_HASFIELDS(ndarray arr, int flags)
202 cdef int PyDataType_HASFIELDS(dtype obj)
204 ctypedef signed int npy_byte
205 ctypedef signed int npy_short
206 ctypedef signed int npy_int
207 ctypedef signed int npy_long
208 ctypedef signed int npy_longlong
210 ctypedef unsigned int npy_ubyte
211 ctypedef unsigned int npy_ushort
212 ctypedef unsigned int npy_uint
213 ctypedef unsigned int npy_ulong
214 ctypedef unsigned int npy_ulonglong
216 ctypedef float npy_float
217 ctypedef float npy_double
218 ctypedef float npy_longdouble
220 ctypedef signed int npy_int8
221 ctypedef signed int npy_int16
222 ctypedef signed int npy_int32
223 ctypedef signed int npy_int64
224 ctypedef signed int npy_int96
225 ctypedef signed int npy_int128
227 ctypedef unsigned int npy_uint8
228 ctypedef unsigned int npy_uint16
229 ctypedef unsigned int npy_uint32
230 ctypedef unsigned int npy_uint64
231 ctypedef unsigned int npy_uint96
232 ctypedef unsigned int npy_uint128
234 ctypedef float npy_float32
235 ctypedef float npy_float64
236 ctypedef float npy_float80
237 ctypedef float npy_float96
238 ctypedef float npy_float128
240 # Typedefs that matches the runtime dtype objects in
241 # the numpy module.
243 # The ones that are commented out needs an IFDEF function
244 # in Cython to enable them only on the right systems.
246 ctypedef npy_int8 int8_t
247 ctypedef npy_int16 int16_t
248 ctypedef npy_int32 int32_t
249 ctypedef npy_int64 int64_t
250 #ctypedef npy_int96 int96_t
251 #ctypedef npy_int128 int128_t
253 ctypedef npy_uint8 uint8_t
254 ctypedef npy_uint16 uint16_t
255 ctypedef npy_uint32 uint32_t
256 ctypedef npy_uint64 uint64_t
257 #ctypedef npy_uint96 uint96_t
258 #ctypedef npy_uint128 uint128_t
260 ctypedef npy_float32 float32_t
261 ctypedef npy_float64 float64_t
262 #ctypedef npy_float80 float80_t
263 #ctypedef npy_float128 float128_t
265 # The int types are mapped a bit surprising --
266 # numpy.int corresponds to 'l' and numpy.long to 'q'
267 ctypedef npy_long int_t
268 ctypedef npy_longlong long_t
270 ctypedef npy_ulong uint_t
271 ctypedef npy_ulonglong ulong_t
273 ctypedef npy_double float_t
274 ctypedef npy_double double_t
275 ctypedef npy_longdouble longdouble_t