Ticket #299 (new task)
Buffers: Clean up internal representation of acquired buffers
| Reported by: | dagss | Owned by: | somebody |
|---|---|---|---|
| Priority: | major | Milestone: | wishlist |
| Component: | Code Generation | Keywords: | kurtgsoc |
| Cc: |
Description (last modified by dagss) (diff)
For speed purposes, some information (shape, and strides and suboffsets when applicable) is unpacked into local variables when acquiring a buffer.
The rest of the Cython codebase is (naturally) centered around "one variable Cython side is one variable C side". For instance temporary expressions must store their result in a single temporary variable C-side (which is acquired through code.funcstate.allocate_temp, Code.py).
Using structs instead of loose variables for unpacking buffers would remedy this problem, while keeping the necesarry unpacked variables on the stack (so it should compile to as optimal code).
E.g. for strided 1D mode, one would rather than
PyObject* __pyx_v_myvar
Py_buffer __pyx_buf_myvar
Py_ssize_t __pyx_bufshape0_myvar
Py_ssize_t __pyx_bufstride0_myvar
use a single struct like this:
typedef struct { Py_buffer bufinfo; Py_ssize_t shape0, stride0; } __Pyx_StridedBuf_1D; typedef struct { __Pyx_StridedBuf_1D buffer; PyObject* object; } __Pyx_StridedBuf_1D_Obj; // in function...: __Pyx_StridedBuf_1D_Obj __pyx_v_myvar;
The reason to split into a struct without and one with object, is to make it easier to implement non-object-linked buffers later (e.g. int[:]).
In addition to simply changing the variable allocation scheme (in Buffer.py), one would then need to output __pyx_v_myvar.object rather than __pyx_v_myvar everywhere the Python object is needed; this can rather easily be done in NameNode.
