cython-devel
view Cython/Includes/numpy.pxd @ 1996:58ff50bda693
__name__ == "__main__" for embedded modules
| author | Robert Bradshaw <robertwb@math.washington.edu> |
|---|---|
| date | Tue Apr 21 02:11:16 2009 -0700 (11 months ago) |
| parents | fa14f80b335c |
| children | fa5aefbc3b0f |
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, i, ndim
56 ndim = PyArray_NDIM(self)
58 if sizeof(npy_intp) != sizeof(Py_ssize_t):
59 copy_shape = 1
60 else:
61 copy_shape = 0
63 if ((flags & pybuf.PyBUF_C_CONTIGUOUS == pybuf.PyBUF_C_CONTIGUOUS)
64 and not PyArray_CHKFLAGS(self, NPY_C_CONTIGUOUS)):
65 raise ValueError("ndarray is not C contiguous")
67 if ((flags & pybuf.PyBUF_F_CONTIGUOUS == pybuf.PyBUF_F_CONTIGUOUS)
68 and not PyArray_CHKFLAGS(self, NPY_F_CONTIGUOUS)):
69 raise ValueError("ndarray is not Fortran contiguous")
71 info.buf = PyArray_DATA(self)
72 info.ndim = ndim
73 if copy_shape:
74 # Allocate new buffer for strides and shape info. This is allocated
75 # as one block, strides first.
76 info.strides = <Py_ssize_t*>stdlib.malloc(sizeof(Py_ssize_t) * ndim * 2)
77 info.shape = info.strides + ndim
78 for i in range(ndim):
79 info.strides[i] = PyArray_STRIDES(self)[i]
80 info.shape[i] = PyArray_DIMS(self)[i]
81 else:
82 info.strides = <Py_ssize_t*>PyArray_STRIDES(self)
83 info.shape = <Py_ssize_t*>PyArray_DIMS(self)
84 info.suboffsets = NULL
85 info.itemsize = PyArray_ITEMSIZE(self)
86 info.readonly = not PyArray_ISWRITEABLE(self)
88 cdef int t
89 cdef char* f = NULL
90 cdef dtype descr = self.descr
91 cdef list stack
93 cdef bint hasfields = PyDataType_HASFIELDS(descr)
95 # Ugly hack warning:
96 # Cython currently will not support helper functions in
97 # pxd files -- so we must keep our own, manual stack!
98 # In addition, avoid allocation of the stack in the common
99 # case that we are dealing with a single non-nested datatype...
100 # (this would look much prettier if we could use utility
101 # functions).
103 if not hasfields and not copy_shape:
104 # do not call releasebuffer
105 info.obj = None
106 else:
107 # need to call releasebuffer
108 info.obj = self
110 if not hasfields:
111 t = descr.type_num
112 if t == NPY_BYTE: f = "b"
113 elif t == NPY_UBYTE: f = "B"
114 elif t == NPY_SHORT: f = "h"
115 elif t == NPY_USHORT: f = "H"
116 elif t == NPY_INT: f = "i"
117 elif t == NPY_UINT: f = "I"
118 elif t == NPY_LONG: f = "l"
119 elif t == NPY_ULONG: f = "L"
120 elif t == NPY_LONGLONG: f = "q"
121 elif t == NPY_ULONGLONG: f = "Q"
122 elif t == NPY_FLOAT: f = "f"
123 elif t == NPY_DOUBLE: f = "d"
124 elif t == NPY_LONGDOUBLE: f = "g"
125 elif t == NPY_CFLOAT: f = "Zf"
126 elif t == NPY_CDOUBLE: f = "Zd"
127 elif t == NPY_CLONGDOUBLE: f = "Zg"
128 elif t == NPY_OBJECT: f = "O"
129 else:
130 raise ValueError("unknown dtype code in numpy.pxd (%d)" % t)
131 info.format = f
132 return
133 else:
134 info.format = <char*>stdlib.malloc(255) # static size
135 f = _util_dtypestring(descr, info.format, info.format + 255)
136 f[0] = 0 # Terminate format string
138 def __releasebuffer__(ndarray self, Py_buffer* info):
139 if PyArray_HASFIELDS(self):
140 stdlib.free(info.format)
141 if sizeof(npy_intp) != sizeof(Py_ssize_t):
142 stdlib.free(info.strides)
143 # info.shape was stored after info.strides in the same block
146 cdef void* PyArray_DATA(ndarray arr)
147 cdef int PyArray_TYPE(ndarray arr)
148 cdef int PyArray_NDIM(ndarray arr)
149 cdef int PyArray_ISWRITEABLE(ndarray arr)
150 cdef npy_intp* PyArray_STRIDES(ndarray arr)
151 cdef npy_intp* PyArray_DIMS(ndarray arr)
152 cdef int PyArray_ITEMSIZE(ndarray arr)
153 cdef int PyArray_CHKFLAGS(ndarray arr, int flags)
154 cdef int PyArray_HASFIELDS(ndarray arr)
156 cdef int PyDataType_HASFIELDS(dtype obj)
158 ctypedef signed int npy_byte
159 ctypedef signed int npy_short
160 ctypedef signed int npy_int
161 ctypedef signed int npy_long
162 ctypedef signed int npy_longlong
164 ctypedef unsigned int npy_ubyte
165 ctypedef unsigned int npy_ushort
166 ctypedef unsigned int npy_uint
167 ctypedef unsigned int npy_ulong
168 ctypedef unsigned int npy_ulonglong
170 ctypedef float npy_float
171 ctypedef float npy_double
172 ctypedef float npy_longdouble
174 ctypedef signed int npy_int8
175 ctypedef signed int npy_int16
176 ctypedef signed int npy_int32
177 ctypedef signed int npy_int64
178 ctypedef signed int npy_int96
179 ctypedef signed int npy_int128
181 ctypedef unsigned int npy_uint8
182 ctypedef unsigned int npy_uint16
183 ctypedef unsigned int npy_uint32
184 ctypedef unsigned int npy_uint64
185 ctypedef unsigned int npy_uint96
186 ctypedef unsigned int npy_uint128
188 ctypedef float npy_float32
189 ctypedef float npy_float64
190 ctypedef float npy_float80
191 ctypedef float npy_float96
192 ctypedef float npy_float128
194 ctypedef struct npy_cfloat:
195 float real
196 float imag
198 ctypedef struct npy_cdouble:
199 double real
200 double imag
202 ctypedef struct npy_clongdouble:
203 long double real
204 long double imag
206 # Typedefs that matches the runtime dtype objects in
207 # the numpy module.
209 # The ones that are commented out needs an IFDEF function
210 # in Cython to enable them only on the right systems.
212 ctypedef npy_int8 int8_t
213 ctypedef npy_int16 int16_t
214 ctypedef npy_int32 int32_t
215 ctypedef npy_int64 int64_t
216 #ctypedef npy_int96 int96_t
217 #ctypedef npy_int128 int128_t
219 ctypedef npy_uint8 uint8_t
220 ctypedef npy_uint16 uint16_t
221 ctypedef npy_uint32 uint32_t
222 ctypedef npy_uint64 uint64_t
223 #ctypedef npy_uint96 uint96_t
224 #ctypedef npy_uint128 uint128_t
226 ctypedef npy_float32 float32_t
227 ctypedef npy_float64 float64_t
228 #ctypedef npy_float80 float80_t
229 #ctypedef npy_float128 float128_t
231 # The int types are mapped a bit surprising --
232 # numpy.int corresponds to 'l' and numpy.long to 'q'
233 ctypedef npy_long int_t
234 ctypedef npy_longlong long_t
236 ctypedef npy_ulong uint_t
237 ctypedef npy_ulonglong ulong_t
239 ctypedef npy_double float_t
240 ctypedef npy_double double_t
241 ctypedef npy_longdouble longdouble_t
243 ctypedef npy_cfloat cfloat_t
244 ctypedef npy_cdouble cdouble_t
245 ctypedef npy_clongdouble clongdouble_t
248 cdef inline char* _util_dtypestring(dtype descr, char* f, char* end) except NULL:
249 # Recursive utility function used in __getbuffer__ to get format
250 # string. The new location in the format string is returned.
252 cdef dtype child
253 cdef tuple i
254 for i in descr.fields.itervalues():
255 child = i[0]
256 if not PyDataType_HASFIELDS(child):
257 t = child.type_num
258 if end - f < 15: # this should leave room for "T{" and "}" as well
259 raise RuntimeError("Format string allocated too short.")
261 # Until ticket #99 is fixed, use integers to avoid warnings
262 if t == NPY_BYTE: f[0] = 98 #"b"
263 elif t == NPY_UBYTE: f[0] = 66 #"B"
264 elif t == NPY_SHORT: f[0] = 104 #"h"
265 elif t == NPY_USHORT: f[0] = 72 #"H"
266 elif t == NPY_INT: f[0] = 105 #"i"
267 elif t == NPY_UINT: f[0] = 73 #"I"
268 elif t == NPY_LONG: f[0] = 108 #"l"
269 elif t == NPY_ULONG: f[0] = 76 #"L"
270 elif t == NPY_LONGLONG: f[0] = 113 #"q"
271 elif t == NPY_ULONGLONG: f[0] = 81 #"Q"
272 elif t == NPY_FLOAT: f[0] = 102 #"f"
273 elif t == NPY_DOUBLE: f[0] = 100 #"d"
274 elif t == NPY_LONGDOUBLE: f[0] = 103 #"g"
275 elif t == NPY_CFLOAT: f[0] = 90; f[1] = 102; f += 1
276 elif t == NPY_CDOUBLE: f[0] = 90; f[1] = 100; f += 1
277 elif t == NPY_CLONGDOUBLE: f[0] = 90; f[1] = 103; f += 1
278 elif t == NPY_OBJECT: f[0] = 79 #"O"
279 else:
280 raise ValueError("unknown dtype code in numpy.pxd (%d)" % t)
281 f += 1
282 else:
283 f[0] = 84 #"T"
284 f[1] = 123 #"{"
285 f += 2
286 f = _util_dtypestring(child, f, end)
287 f[0] = 125 #"}"
288 f += 1
289 return f
