Blame tests/buffers/mockbuffers.pxi

Packit Service 99d393
from libc cimport stdlib
Packit Service 99d393
from libc cimport stdio
Packit Service 99d393
cimport cpython.buffer
Packit Service 99d393
Packit Service 99d393
import sys
Packit Service 99d393
Packit Service 99d393
available_flags = (
Packit Service 99d393
    ('FORMAT', cpython.buffer.PyBUF_FORMAT),
Packit Service 99d393
    ('INDIRECT', cpython.buffer.PyBUF_INDIRECT),
Packit Service 99d393
    ('ND', cpython.buffer.PyBUF_ND),
Packit Service 99d393
    ('STRIDES', cpython.buffer.PyBUF_STRIDES),
Packit Service 99d393
    ('C_CONTIGUOUS', cpython.buffer.PyBUF_C_CONTIGUOUS),
Packit Service 99d393
    ('F_CONTIGUOUS', cpython.buffer.PyBUF_F_CONTIGUOUS),
Packit Service 99d393
    ('WRITABLE', cpython.buffer.PyBUF_WRITABLE)
Packit Service 99d393
)
Packit Service 99d393
Packit Service 99d393
cdef class MockBuffer:
Packit Service 99d393
    cdef object format, offset
Packit Service 99d393
    cdef void* buffer
Packit Service 99d393
    cdef Py_ssize_t len, itemsize
Packit Service 99d393
    cdef Py_ssize_t* strides
Packit Service 99d393
    cdef Py_ssize_t* shape
Packit Service 99d393
    cdef Py_ssize_t* suboffsets
Packit Service 99d393
    cdef object label, log
Packit Service 99d393
    cdef int ndim
Packit Service 99d393
    cdef bint writable
Packit Service 99d393
Packit Service 99d393
    cdef readonly object received_flags, release_ok
Packit Service 99d393
    cdef public object fail
Packit Service 99d393
Packit Service 99d393
    def __init__(self, label, data, shape=None, strides=None, format=None, writable=True, offset=0):
Packit Service 99d393
        # It is important not to store references to data after the constructor
Packit Service 99d393
        # as refcounting is checked on object buffers.
Packit Service 99d393
        self.label = label
Packit Service 99d393
        self.release_ok = True
Packit Service 99d393
        self.log = ""
Packit Service 99d393
        self.offset = offset
Packit Service 99d393
        self.itemsize = self.get_itemsize()
Packit Service 99d393
        self.writable = writable
Packit Service 99d393
        if format is None: format = self.get_default_format()
Packit Service 99d393
        if shape is None: shape = (len(data),)
Packit Service 99d393
        if strides is None:
Packit Service 99d393
            strides = []
Packit Service 99d393
            cumprod = 1
Packit Service 99d393
            rshape = list(shape)
Packit Service 99d393
            rshape.reverse()
Packit Service 99d393
            for s in rshape:
Packit Service 99d393
                strides.append(cumprod)
Packit Service 99d393
                cumprod *= s
Packit Service 99d393
            strides.reverse()
Packit Service 99d393
        strides = [x * self.itemsize for x in strides]
Packit Service 99d393
        suboffsets = [-1] * len(shape)
Packit Service 99d393
        datashape = [len(data)]
Packit Service 99d393
        p = data
Packit Service 99d393
        while True:
Packit Service 99d393
            p = p[0]
Packit Service 99d393
            if isinstance(p, list): datashape.append(len(p))
Packit Service 99d393
            else: break
Packit Service 99d393
        if len(datashape) > 1:
Packit Service 99d393
            # indirect access
Packit Service 99d393
            self.ndim = <int>len(datashape)
Packit Service 99d393
            shape = datashape
Packit Service 99d393
            self.buffer = self.create_indirect_buffer(data, shape)
Packit Service 99d393
            suboffsets = [0] * (self.ndim-1) + [-1]
Packit Service 99d393
            strides = [sizeof(void*)] * (self.ndim-1) + [self.itemsize]
Packit Service 99d393
            self.suboffsets = self.list_to_sizebuf(suboffsets)
Packit Service 99d393
        else:
Packit Service 99d393
            # strided and/or simple access
Packit Service 99d393
            self.buffer = self.create_buffer(data)
Packit Service 99d393
            self.ndim = <int>len(shape)
Packit Service 99d393
            self.suboffsets = NULL
Packit Service 99d393
Packit Service 99d393
        try:
Packit Service 99d393
            format = format.encode('ASCII')
Packit Service 99d393
        except AttributeError:
Packit Service 99d393
            pass
Packit Service 99d393
        self.format = format
Packit Service 99d393
        self.len = len(data) * self.itemsize
Packit Service 99d393
Packit Service 99d393
        self.strides = self.list_to_sizebuf(strides)
Packit Service 99d393
        self.shape = self.list_to_sizebuf(shape)
Packit Service 99d393
Packit Service 99d393
    def __dealloc__(self):
Packit Service 99d393
        stdlib.free(self.strides)
Packit Service 99d393
        stdlib.free(self.shape)
Packit Service 99d393
        if self.suboffsets != NULL:
Packit Service 99d393
            stdlib.free(self.suboffsets)
Packit Service 99d393
            # must recursively free indirect...
Packit Service 99d393
        else:
Packit Service 99d393
            stdlib.free(self.buffer)
Packit Service 99d393
Packit Service 99d393
    cdef void* create_buffer(self, data) except NULL:
Packit Service 99d393
        cdef size_t n = <size_t>(len(data) * self.itemsize)
Packit Service 99d393
        cdef char* buf = <char*>stdlib.malloc(n)
Packit Service 99d393
        if buf == NULL:
Packit Service 99d393
            raise MemoryError
Packit Service 99d393
        cdef char* it = buf
Packit Service 99d393
        for value in data:
Packit Service 99d393
            self.write(it, value)
Packit Service 99d393
            it += self.itemsize
Packit Service 99d393
        return buf
Packit Service 99d393
Packit Service 99d393
    cdef void* create_indirect_buffer(self, data, shape) except NULL:
Packit Service 99d393
        cdef size_t n = 0
Packit Service 99d393
        cdef void** buf
Packit Service 99d393
        assert shape[0] == len(data), (shape[0], len(data))
Packit Service 99d393
        if len(shape) == 1:
Packit Service 99d393
            return self.create_buffer(data)
Packit Service 99d393
        else:
Packit Service 99d393
            shape = shape[1:]
Packit Service 99d393
            n = <size_t>len(data) * sizeof(void*)
Packit Service 99d393
            buf = <void**>stdlib.malloc(n)
Packit Service 99d393
            if buf == NULL:
Packit Service 99d393
                return NULL
Packit Service 99d393
Packit Service 99d393
            for idx, subdata in enumerate(data):
Packit Service 99d393
                buf[idx] = self.create_indirect_buffer(subdata, shape)
Packit Service 99d393
Packit Service 99d393
            return buf
Packit Service 99d393
Packit Service 99d393
    cdef Py_ssize_t* list_to_sizebuf(self, l):
Packit Service 99d393
        cdef size_t n = <size_t>len(l) * sizeof(Py_ssize_t)
Packit Service 99d393
        cdef Py_ssize_t* buf = <Py_ssize_t*>stdlib.malloc(n)
Packit Service 99d393
        for i, x in enumerate(l):
Packit Service 99d393
            buf[i] = x
Packit Service 99d393
        return buf
Packit Service 99d393
Packit Service 99d393
    def __getbuffer__(MockBuffer self, Py_buffer* buffer, int flags):
Packit Service 99d393
        if self.fail:
Packit Service 99d393
            raise ValueError("Failing on purpose")
Packit Service 99d393
Packit Service 99d393
        self.received_flags = []
Packit Service 99d393
        cdef int value
Packit Service 99d393
        for name, value in available_flags:
Packit Service 99d393
            if (value & flags) == value:
Packit Service 99d393
                self.received_flags.append(name)
Packit Service 99d393
Packit Service 99d393
        if flags & cpython.buffer.PyBUF_WRITABLE and not self.writable:
Packit Service 99d393
            raise BufferError("Writable buffer requested from read-only mock: %s" % ' | '.join(self.received_flags))
Packit Service 99d393
Packit Service 99d393
        buffer.buf = <void*>(<char*>self.buffer + (<int>self.offset * self.itemsize))
Packit Service 99d393
        buffer.obj = self
Packit Service 99d393
        buffer.len = self.len
Packit Service 99d393
        buffer.readonly = not self.writable
Packit Service 99d393
        buffer.format = <char*>self.format
Packit Service 99d393
        buffer.ndim = self.ndim
Packit Service 99d393
        buffer.shape = self.shape
Packit Service 99d393
        buffer.strides = self.strides
Packit Service 99d393
        buffer.suboffsets = self.suboffsets
Packit Service 99d393
        buffer.itemsize = self.itemsize
Packit Service 99d393
        buffer.internal = NULL
Packit Service 99d393
        if self.label:
Packit Service 99d393
            msg = "acquired %s" % self.label
Packit Service 99d393
            print msg
Packit Service 99d393
            self.log += msg + "\n"
Packit Service 99d393
Packit Service 99d393
    def __releasebuffer__(MockBuffer self, Py_buffer* buffer):
Packit Service 99d393
        if buffer.suboffsets != self.suboffsets:
Packit Service 99d393
            self.release_ok = False
Packit Service 99d393
        if self.label:
Packit Service 99d393
            msg = "released %s" % self.label
Packit Service 99d393
            print msg
Packit Service 99d393
            self.log += msg + "\n"
Packit Service 99d393
Packit Service 99d393
    def printlog(self):
Packit Service 99d393
        print self.log[:-1]
Packit Service 99d393
Packit Service 99d393
    def resetlog(self):
Packit Service 99d393
        self.log = ""
Packit Service 99d393
Packit Service 99d393
    cdef int write(self, char* buf, object value) except -1: raise Exception()
Packit Service 99d393
    cdef get_itemsize(self):
Packit Service 99d393
        print "ERROR, not subclassed", self.__class__
Packit Service 99d393
    cdef get_default_format(self):
Packit Service 99d393
        print "ERROR, not subclassed", self.__class__
Packit Service 99d393
Packit Service 99d393
cdef class CharMockBuffer(MockBuffer):
Packit Service 99d393
    cdef int write(self, char* buf, object value) except -1:
Packit Service 99d393
        (<char*>buf)[0] = <char>value
Packit Service 99d393
        return 0
Packit Service 99d393
    cdef get_itemsize(self): return sizeof(char)
Packit Service 99d393
    cdef get_default_format(self): return b"@b"
Packit Service 99d393
Packit Service 99d393
cdef class IntMockBuffer(MockBuffer):
Packit Service 99d393
    cdef int write(self, char* buf, object value) except -1:
Packit Service 99d393
        (<int*>buf)[0] = <int>value
Packit Service 99d393
        return 0
Packit Service 99d393
    cdef get_itemsize(self): return sizeof(int)
Packit Service 99d393
    cdef get_default_format(self): return b"@i"
Packit Service 99d393
Packit Service 99d393
cdef class UnsignedIntMockBuffer(MockBuffer):
Packit Service 99d393
    cdef int write(self, char* buf, object value) except -1:
Packit Service 99d393
        (<unsigned int*>buf)[0] = <unsigned int>value
Packit Service 99d393
        return 0
Packit Service 99d393
    cdef get_itemsize(self): return sizeof(unsigned int)
Packit Service 99d393
    cdef get_default_format(self): return b"@I"
Packit Service 99d393
Packit Service 99d393
cdef class ShortMockBuffer(MockBuffer):
Packit Service 99d393
    cdef int write(self, char* buf, object value) except -1:
Packit Service 99d393
        (<short*>buf)[0] = <short>value
Packit Service 99d393
        return 0
Packit Service 99d393
    cdef get_itemsize(self): return sizeof(short)
Packit Service 99d393
    cdef get_default_format(self): return b"h" # Try without endian specifier
Packit Service 99d393
Packit Service 99d393
cdef class UnsignedShortMockBuffer(MockBuffer):
Packit Service 99d393
    cdef int write(self, char* buf, object value) except -1:
Packit Service 99d393
        (<unsigned short*>buf)[0] = <unsigned short>value
Packit Service 99d393
        return 0
Packit Service 99d393
    cdef get_itemsize(self): return sizeof(unsigned short)
Packit Service 99d393
    cdef get_default_format(self): return b"@1H" # Try with repeat count
Packit Service 99d393
Packit Service 99d393
cdef class FloatMockBuffer(MockBuffer):
Packit Service 99d393
    cdef int write(self, char* buf, object value) except -1:
Packit Service 99d393
        (<float*>buf)[0] = <float>(<double>value)
Packit Service 99d393
        return 0
Packit Service 99d393
    cdef get_itemsize(self): return sizeof(float)
Packit Service 99d393
    cdef get_default_format(self): return b"f"
Packit Service 99d393
Packit Service 99d393
cdef class DoubleMockBuffer(MockBuffer):
Packit Service 99d393
    cdef int write(self, char* buf, object value) except -1:
Packit Service 99d393
        (<double*>buf)[0] = <double>value
Packit Service 99d393
        return 0
Packit Service 99d393
    cdef get_itemsize(self): return sizeof(double)
Packit Service 99d393
    cdef get_default_format(self): return b"d"
Packit Service 99d393
Packit Service 99d393
cdef extern from *:
Packit Service 99d393
    void* addr_of_pyobject "(void*)"(object)
Packit Service 99d393
Packit Service 99d393
cdef class ObjectMockBuffer(MockBuffer):
Packit Service 99d393
    cdef int write(self, char* buf, object value) except -1:
Packit Service 99d393
        (<void**>buf)[0] = addr_of_pyobject(value)
Packit Service 99d393
        return 0
Packit Service 99d393
Packit Service 99d393
    cdef get_itemsize(self): return sizeof(void*)
Packit Service 99d393
    cdef get_default_format(self): return b"@O"
Packit Service 99d393
Packit Service 99d393
cdef class IntStridedMockBuffer(IntMockBuffer):
Packit Service 99d393
    cdef __cythonbufferdefaults__ = {"mode" : "strided"}
Packit Service 99d393
Packit Service 99d393
cdef class ErrorBuffer:
Packit Service 99d393
    cdef object label
Packit Service 99d393
Packit Service 99d393
    def __init__(self, label):
Packit Service 99d393
        self.label = label
Packit Service 99d393
Packit Service 99d393
    def __getbuffer__(ErrorBuffer self, Py_buffer* buffer, int flags):
Packit Service 99d393
        raise Exception("acquiring %s" % self.label)
Packit Service 99d393
Packit Service 99d393
    def __releasebuffer__(ErrorBuffer self, Py_buffer* buffer):
Packit Service 99d393
        raise Exception("releasing %s" % self.label)
Packit Service 99d393
Packit Service 99d393
#
Packit Service 99d393
# Structs
Packit Service 99d393
#
Packit Service 99d393
cdef struct MyStruct:
Packit Service 99d393
    signed char a
Packit Service 99d393
    signed char b
Packit Service 99d393
    long long int c
Packit Service 99d393
    int d
Packit Service 99d393
    int e
Packit Service 99d393
Packit Service 99d393
cdef struct SmallStruct:
Packit Service 99d393
    int a
Packit Service 99d393
    int b
Packit Service 99d393
Packit Service 99d393
cdef struct NestedStruct:
Packit Service 99d393
    SmallStruct x
Packit Service 99d393
    SmallStruct y
Packit Service 99d393
    int z
Packit Service 99d393
Packit Service 99d393
cdef packed struct PackedStruct:
Packit Service 99d393
    signed char a
Packit Service 99d393
    int b
Packit Service 99d393
Packit Service 99d393
cdef struct NestedPackedStruct:
Packit Service 99d393
    signed char a
Packit Service 99d393
    int b
Packit Service 99d393
    PackedStruct sub
Packit Service 99d393
    int c
Packit Service 99d393
Packit Service 99d393
cdef class MyStructMockBuffer(MockBuffer):
Packit Service 99d393
    cdef int write(self, char* buf, object value) except -1:
Packit Service 99d393
        cdef MyStruct* s
Packit Service 99d393
        s = <MyStruct*>buf
Packit Service 99d393
        s.a, s.b, s.c, s.d, s.e = value
Packit Service 99d393
        return 0
Packit Service 99d393
Packit Service 99d393
    cdef get_itemsize(self): return sizeof(MyStruct)
Packit Service 99d393
    cdef get_default_format(self): return b"2cq2i"
Packit Service 99d393
Packit Service 99d393
cdef class NestedStructMockBuffer(MockBuffer):
Packit Service 99d393
    cdef int write(self, char* buf, object value) except -1:
Packit Service 99d393
        cdef NestedStruct* s
Packit Service 99d393
        s = <NestedStruct*>buf
Packit Service 99d393
        s.x.a, s.x.b, s.y.a, s.y.b, s.z = value
Packit Service 99d393
        return 0
Packit Service 99d393
Packit Service 99d393
    cdef get_itemsize(self): return sizeof(NestedStruct)
Packit Service 99d393
    cdef get_default_format(self): return b"2T{ii}i"
Packit Service 99d393
Packit Service 99d393
cdef class PackedStructMockBuffer(MockBuffer):
Packit Service 99d393
    cdef int write(self, char* buf, object value) except -1:
Packit Service 99d393
        cdef PackedStruct* s
Packit Service 99d393
        s = <PackedStruct*>buf
Packit Service 99d393
        s.a, s.b = value
Packit Service 99d393
        return 0
Packit Service 99d393
Packit Service 99d393
    cdef get_itemsize(self): return sizeof(PackedStruct)
Packit Service 99d393
    cdef get_default_format(self): return b"^ci"
Packit Service 99d393
Packit Service 99d393
cdef class NestedPackedStructMockBuffer(MockBuffer):
Packit Service 99d393
    cdef int write(self, char* buf, object value) except -1:
Packit Service 99d393
        cdef NestedPackedStruct* s
Packit Service 99d393
        s = <NestedPackedStruct*>buf
Packit Service 99d393
        s.a, s.b, s.sub.a, s.sub.b, s.c = value
Packit Service 99d393
        return 0
Packit Service 99d393
Packit Service 99d393
    cdef get_itemsize(self): return sizeof(NestedPackedStruct)
Packit Service 99d393
    cdef get_default_format(self): return b"ci^ci@i"
Packit Service 99d393
Packit Service 99d393
cdef struct LongComplex:
Packit Service 99d393
    long double real
Packit Service 99d393
    long double imag
Packit Service 99d393
Packit Service 99d393
cdef class LongComplexMockBuffer(MockBuffer):
Packit Service 99d393
    cdef int write(self, char* buf, object value) except -1:
Packit Service 99d393
        cdef LongComplex* s
Packit Service 99d393
        s = <LongComplex*>buf
Packit Service 99d393
        s.real, s.imag = value
Packit Service 99d393
        return 0
Packit Service 99d393
Packit Service 99d393
    cdef get_itemsize(self): return sizeof(LongComplex)
Packit Service 99d393
    cdef get_default_format(self): return b"Zg"
Packit Service 99d393
Packit Service 99d393
Packit Service 99d393
def print_offsets(*args, size, newline=True):
Packit Service 99d393
    sys.stdout.write(' '.join([str(item // size) for item in args]))
Packit Service 99d393
    if newline:
Packit Service 99d393
        sys.stdout.write('\n')
Packit Service 99d393
Packit Service 99d393
def print_int_offsets(*args, newline=True):
Packit Service 99d393
    print_offsets(*args, size=sizeof(int), newline=newline)
Packit Service 99d393
Packit Service 99d393
shape_5_3_4_list = [[list(range(k * 12 + j * 4, k * 12 + j * 4 + 4))
Packit Service 99d393
                        for j in range(3)]
Packit Service 99d393
                            for k in range(5)]
Packit Service 99d393
Packit Service 99d393
stride1 = 21 * 14
Packit Service 99d393
stride2 = 21
Packit Service 99d393
shape_9_14_21_list = [[list(range(k * stride1 + j * stride2, k * stride1 + j * stride2 + 21))
Packit Service 99d393
                           for j in range(14)]
Packit Service 99d393
                               for k in range(9)]