1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
"""
Utility for changing itemsize of memoryviews, and getting
numpy arrays from byte-arrays that should be interpreted with a different
itemsize.
Authors
-------
* MinRK
"""
#-----------------------------------------------------------------------------
# Copyright (c) 2010-2012 Brian Granger, Min Ragan-Kelley
#
# This file is part of pyzmq
#
# Distributed under the terms of the New BSD License. The full license is in
# the file COPYING.BSD, distributed as part of this software.
#-----------------------------------------------------------------------------
from libc.stdlib cimport malloc
from buffers cimport *
cdef inline object _rebuffer(object obj, char * format, int itemsize):
"""clobber the format & itemsize of a 1-D
This is the Python 3 model, but will work on Python >= 2.6. Currently,
we use it only on >= 3.0.
"""
cdef Py_buffer view
cdef int flags = PyBUF_SIMPLE
cdef int mode = 0
# cdef Py_ssize_t *shape, *strides, *suboffsets
mode = check_buffer(obj)
if mode == 0:
raise TypeError("%r does not provide a buffer interface."%obj)
if mode == 3:
flags = PyBUF_ANY_CONTIGUOUS
if format:
flags |= PyBUF_FORMAT
PyObject_GetBuffer(obj, &view, flags)
assert view.ndim <= 1, "Can only reinterpret 1-D memoryviews"
assert view.len % itemsize == 0, "Buffer of length %i not divisible into items of size %i"%(view.len, itemsize)
# hack the format
view.ndim = 1
view.format = format
view.itemsize = itemsize
view.strides = <Py_ssize_t *>malloc(sizeof(Py_ssize_t))
view.strides[0] = itemsize
view.shape = <Py_ssize_t *>malloc(sizeof(Py_ssize_t))
view.shape[0] = view.len/itemsize
view.suboffsets = <Py_ssize_t *>malloc(sizeof(Py_ssize_t))
view.suboffsets[0] = 0
# for debug: make buffer writable, for zero-copy testing
# view.readonly = 0
return PyMemoryView_FromBuffer(&view)
else:
raise TypeError("This funciton is only for new-style buffer objects.")
def rebuffer(obj, format, itemsize):
"""Change the itemsize of a memoryview.
Only for 1D contiguous buffers.
"""
return _rebuffer(obj, format, itemsize)
def array_from_buffer(view, dtype, shape):
"""Get a numpy array from a memoryview, regardless of the itemsize of the original
memoryview. This is important, because pyzmq does not send memoryview shape data
over the wire, so we need to change the memoryview itemsize before calling
asarray.
"""
import numpy
A = numpy.array([],dtype=dtype)
ref = viewfromobject(A,0)
fmt = ref.format.encode()
buf = viewfromobject(view, 0)
buf = _rebuffer(view, fmt, ref.itemsize)
return numpy.asarray(buf, dtype=dtype).reshape(shape)
def print_view_info(obj):
"""simple utility for printing info on a new-style buffer object"""
cdef Py_buffer view
cdef int flags = PyBUF_ANY_CONTIGUOUS|PyBUF_FORMAT
cdef int mode = 0
mode = check_buffer(obj)
if mode == 0:
raise TypeError("%r does not provide a buffer interface."%obj)
if mode == 3:
PyObject_GetBuffer(obj, &view, flags)
print <size_t>view.buf, view.len, view.format, view.ndim,
if view.ndim:
if view.shape:
print view.shape[0],
if view.strides:
print view.strides[0],
if view.suboffsets:
print view.suboffsets[0],
print
|