123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945 |
- ////////// MemviewSliceStruct.proto //////////
- //@proto_block: utility_code_proto_before_types
- /* memoryview slice struct */
- struct {{memview_struct_name}};
- typedef struct {
- struct {{memview_struct_name}} *memview;
- char *data;
- Py_ssize_t shape[{{max_dims}}];
- Py_ssize_t strides[{{max_dims}}];
- Py_ssize_t suboffsets[{{max_dims}}];
- } {{memviewslice_name}};
- // used for "len(memviewslice)"
- #define __Pyx_MemoryView_Len(m) (m.shape[0])
- /////////// Atomics.proto /////////////
- //@proto_block: utility_code_proto_before_types
- #include <pythread.h>
- #ifndef CYTHON_ATOMICS
- #define CYTHON_ATOMICS 1
- #endif
- #define __pyx_atomic_int_type int
- // todo: Portland pgcc, maybe OS X's OSAtomicIncrement32,
- // libatomic + autotools-like distutils support? Such a pain...
- #if CYTHON_ATOMICS && __GNUC__ >= 4 && (__GNUC_MINOR__ > 1 || \
- (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL >= 2)) && \
- !defined(__i386__)
- /* gcc >= 4.1.2 */
- #define __pyx_atomic_incr_aligned(value, lock) __sync_fetch_and_add(value, 1)
- #define __pyx_atomic_decr_aligned(value, lock) __sync_fetch_and_sub(value, 1)
- #ifdef __PYX_DEBUG_ATOMICS
- #warning "Using GNU atomics"
- #endif
- #elif CYTHON_ATOMICS && defined(_MSC_VER) && 0
- /* msvc */
- #include <Windows.h>
- #undef __pyx_atomic_int_type
- #define __pyx_atomic_int_type LONG
- #define __pyx_atomic_incr_aligned(value, lock) InterlockedIncrement(value)
- #define __pyx_atomic_decr_aligned(value, lock) InterlockedDecrement(value)
- #ifdef __PYX_DEBUG_ATOMICS
- #pragma message ("Using MSVC atomics")
- #endif
- #elif CYTHON_ATOMICS && (defined(__ICC) || defined(__INTEL_COMPILER)) && 0
- #define __pyx_atomic_incr_aligned(value, lock) _InterlockedIncrement(value)
- #define __pyx_atomic_decr_aligned(value, lock) _InterlockedDecrement(value)
- #ifdef __PYX_DEBUG_ATOMICS
- #warning "Using Intel atomics"
- #endif
- #else
- #undef CYTHON_ATOMICS
- #define CYTHON_ATOMICS 0
- #ifdef __PYX_DEBUG_ATOMICS
- #warning "Not using atomics"
- #endif
- #endif
- typedef volatile __pyx_atomic_int_type __pyx_atomic_int;
- #if CYTHON_ATOMICS
- #define __pyx_add_acquisition_count(memview) \
- __pyx_atomic_incr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
- #define __pyx_sub_acquisition_count(memview) \
- __pyx_atomic_decr_aligned(__pyx_get_slice_count_pointer(memview), memview->lock)
- #else
- #define __pyx_add_acquisition_count(memview) \
- __pyx_add_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
- #define __pyx_sub_acquisition_count(memview) \
- __pyx_sub_acquisition_count_locked(__pyx_get_slice_count_pointer(memview), memview->lock)
- #endif
- /////////////// ObjectToMemviewSlice.proto ///////////////
- static CYTHON_INLINE {{memviewslice_name}} {{funcname}}(PyObject *, int writable_flag);
- ////////// MemviewSliceInit.proto //////////
- #define __Pyx_BUF_MAX_NDIMS %(BUF_MAX_NDIMS)d
- #define __Pyx_MEMVIEW_DIRECT 1
- #define __Pyx_MEMVIEW_PTR 2
- #define __Pyx_MEMVIEW_FULL 4
- #define __Pyx_MEMVIEW_CONTIG 8
- #define __Pyx_MEMVIEW_STRIDED 16
- #define __Pyx_MEMVIEW_FOLLOW 32
- #define __Pyx_IS_C_CONTIG 1
- #define __Pyx_IS_F_CONTIG 2
- static int __Pyx_init_memviewslice(
- struct __pyx_memoryview_obj *memview,
- int ndim,
- __Pyx_memviewslice *memviewslice,
- int memview_is_new_reference);
- static CYTHON_INLINE int __pyx_add_acquisition_count_locked(
- __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
- static CYTHON_INLINE int __pyx_sub_acquisition_count_locked(
- __pyx_atomic_int *acquisition_count, PyThread_type_lock lock);
- #define __pyx_get_slice_count_pointer(memview) (memview->acquisition_count_aligned_p)
- #define __pyx_get_slice_count(memview) (*__pyx_get_slice_count_pointer(memview))
- #define __PYX_INC_MEMVIEW(slice, have_gil) __Pyx_INC_MEMVIEW(slice, have_gil, __LINE__)
- #define __PYX_XDEC_MEMVIEW(slice, have_gil) __Pyx_XDEC_MEMVIEW(slice, have_gil, __LINE__)
- static CYTHON_INLINE void __Pyx_INC_MEMVIEW({{memviewslice_name}} *, int, int);
- static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *, int, int);
- /////////////// MemviewSliceIndex.proto ///////////////
- static CYTHON_INLINE char *__pyx_memviewslice_index_full(
- const char *bufp, Py_ssize_t idx, Py_ssize_t stride, Py_ssize_t suboffset);
- /////////////// ObjectToMemviewSlice ///////////////
- //@requires: MemviewSliceValidateAndInit
- static CYTHON_INLINE {{memviewslice_name}} {{funcname}}(PyObject *obj, int writable_flag) {
- {{memviewslice_name}} result = {{memslice_init}};
- __Pyx_BufFmt_StackElem stack[{{struct_nesting_depth}}];
- int axes_specs[] = { {{axes_specs}} };
- int retcode;
- if (obj == Py_None) {
- /* We don't bother to refcount None */
- result.memview = (struct __pyx_memoryview_obj *) Py_None;
- return result;
- }
- retcode = __Pyx_ValidateAndInit_memviewslice(axes_specs, {{c_or_f_flag}},
- {{buf_flag}} | writable_flag, {{ndim}},
- &{{dtype_typeinfo}}, stack,
- &result, obj);
- if (unlikely(retcode == -1))
- goto __pyx_fail;
- return result;
- __pyx_fail:
- result.memview = NULL;
- result.data = NULL;
- return result;
- }
- /////////////// MemviewSliceValidateAndInit.proto ///////////////
- static int __Pyx_ValidateAndInit_memviewslice(
- int *axes_specs,
- int c_or_f_flag,
- int buf_flags,
- int ndim,
- __Pyx_TypeInfo *dtype,
- __Pyx_BufFmt_StackElem stack[],
- __Pyx_memviewslice *memviewslice,
- PyObject *original_obj);
- /////////////// MemviewSliceValidateAndInit ///////////////
- //@requires: Buffer.c::TypeInfoCompare
- //@requires: Buffer.c::BufferFormatStructs
- //@requires: Buffer.c::BufferFormatCheck
- static int
- __pyx_check_strides(Py_buffer *buf, int dim, int ndim, int spec)
- {
- if (buf->shape[dim] <= 1)
- return 1;
- if (buf->strides) {
- if (spec & __Pyx_MEMVIEW_CONTIG) {
- if (spec & (__Pyx_MEMVIEW_PTR|__Pyx_MEMVIEW_FULL)) {
- if (unlikely(buf->strides[dim] != sizeof(void *))) {
- PyErr_Format(PyExc_ValueError,
- "Buffer is not indirectly contiguous "
- "in dimension %d.", dim);
- goto fail;
- }
- } else if (unlikely(buf->strides[dim] != buf->itemsize)) {
- PyErr_SetString(PyExc_ValueError,
- "Buffer and memoryview are not contiguous "
- "in the same dimension.");
- goto fail;
- }
- }
- if (spec & __Pyx_MEMVIEW_FOLLOW) {
- Py_ssize_t stride = buf->strides[dim];
- if (stride < 0)
- stride = -stride;
- if (unlikely(stride < buf->itemsize)) {
- PyErr_SetString(PyExc_ValueError,
- "Buffer and memoryview are not contiguous "
- "in the same dimension.");
- goto fail;
- }
- }
- } else {
- if (unlikely(spec & __Pyx_MEMVIEW_CONTIG && dim != ndim - 1)) {
- PyErr_Format(PyExc_ValueError,
- "C-contiguous buffer is not contiguous in "
- "dimension %d", dim);
- goto fail;
- } else if (unlikely(spec & (__Pyx_MEMVIEW_PTR))) {
- PyErr_Format(PyExc_ValueError,
- "C-contiguous buffer is not indirect in "
- "dimension %d", dim);
- goto fail;
- } else if (unlikely(buf->suboffsets)) {
- PyErr_SetString(PyExc_ValueError,
- "Buffer exposes suboffsets but no strides");
- goto fail;
- }
- }
- return 1;
- fail:
- return 0;
- }
- static int
- __pyx_check_suboffsets(Py_buffer *buf, int dim, CYTHON_UNUSED int ndim, int spec)
- {
- // Todo: without PyBUF_INDIRECT we may not have suboffset information, i.e., the
- // ptr may not be set to NULL but may be uninitialized?
- if (spec & __Pyx_MEMVIEW_DIRECT) {
- if (unlikely(buf->suboffsets && buf->suboffsets[dim] >= 0)) {
- PyErr_Format(PyExc_ValueError,
- "Buffer not compatible with direct access "
- "in dimension %d.", dim);
- goto fail;
- }
- }
- if (spec & __Pyx_MEMVIEW_PTR) {
- if (unlikely(!buf->suboffsets || (buf->suboffsets[dim] < 0))) {
- PyErr_Format(PyExc_ValueError,
- "Buffer is not indirectly accessible "
- "in dimension %d.", dim);
- goto fail;
- }
- }
- return 1;
- fail:
- return 0;
- }
- static int
- __pyx_verify_contig(Py_buffer *buf, int ndim, int c_or_f_flag)
- {
- int i;
- if (c_or_f_flag & __Pyx_IS_F_CONTIG) {
- Py_ssize_t stride = 1;
- for (i = 0; i < ndim; i++) {
- if (unlikely(stride * buf->itemsize != buf->strides[i] && buf->shape[i] > 1)) {
- PyErr_SetString(PyExc_ValueError,
- "Buffer not fortran contiguous.");
- goto fail;
- }
- stride = stride * buf->shape[i];
- }
- } else if (c_or_f_flag & __Pyx_IS_C_CONTIG) {
- Py_ssize_t stride = 1;
- for (i = ndim - 1; i >- 1; i--) {
- if (unlikely(stride * buf->itemsize != buf->strides[i] && buf->shape[i] > 1)) {
- PyErr_SetString(PyExc_ValueError,
- "Buffer not C contiguous.");
- goto fail;
- }
- stride = stride * buf->shape[i];
- }
- }
- return 1;
- fail:
- return 0;
- }
- static int __Pyx_ValidateAndInit_memviewslice(
- int *axes_specs,
- int c_or_f_flag,
- int buf_flags,
- int ndim,
- __Pyx_TypeInfo *dtype,
- __Pyx_BufFmt_StackElem stack[],
- __Pyx_memviewslice *memviewslice,
- PyObject *original_obj)
- {
- struct __pyx_memoryview_obj *memview, *new_memview;
- __Pyx_RefNannyDeclarations
- Py_buffer *buf;
- int i, spec = 0, retval = -1;
- __Pyx_BufFmt_Context ctx;
- int from_memoryview = __pyx_memoryview_check(original_obj);
- __Pyx_RefNannySetupContext("ValidateAndInit_memviewslice", 0);
- if (from_memoryview && __pyx_typeinfo_cmp(dtype, ((struct __pyx_memoryview_obj *)
- original_obj)->typeinfo)) {
- /* We have a matching dtype, skip format parsing */
- memview = (struct __pyx_memoryview_obj *) original_obj;
- new_memview = NULL;
- } else {
- memview = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
- original_obj, buf_flags, 0, dtype);
- new_memview = memview;
- if (unlikely(!memview))
- goto fail;
- }
- buf = &memview->view;
- if (unlikely(buf->ndim != ndim)) {
- PyErr_Format(PyExc_ValueError,
- "Buffer has wrong number of dimensions (expected %d, got %d)",
- ndim, buf->ndim);
- goto fail;
- }
- if (new_memview) {
- __Pyx_BufFmt_Init(&ctx, stack, dtype);
- if (unlikely(!__Pyx_BufFmt_CheckString(&ctx, buf->format))) goto fail;
- }
- if (unlikely((unsigned) buf->itemsize != dtype->size)) {
- PyErr_Format(PyExc_ValueError,
- "Item size of buffer (%" CYTHON_FORMAT_SSIZE_T "u byte%s) "
- "does not match size of '%s' (%" CYTHON_FORMAT_SSIZE_T "u byte%s)",
- buf->itemsize,
- (buf->itemsize > 1) ? "s" : "",
- dtype->name,
- dtype->size,
- (dtype->size > 1) ? "s" : "");
- goto fail;
- }
- /* Check axes */
- if (buf->len > 0) {
- // 0-sized arrays do not undergo these checks since their strides are
- // irrelevant and they are always both C- and F-contiguous.
- for (i = 0; i < ndim; i++) {
- spec = axes_specs[i];
- if (unlikely(!__pyx_check_strides(buf, i, ndim, spec)))
- goto fail;
- if (unlikely(!__pyx_check_suboffsets(buf, i, ndim, spec)))
- goto fail;
- }
- /* Check contiguity */
- if (unlikely(buf->strides && !__pyx_verify_contig(buf, ndim, c_or_f_flag)))
- goto fail;
- }
- /* Initialize */
- if (unlikely(__Pyx_init_memviewslice(memview, ndim, memviewslice,
- new_memview != NULL) == -1)) {
- goto fail;
- }
- retval = 0;
- goto no_fail;
- fail:
- Py_XDECREF(new_memview);
- retval = -1;
- no_fail:
- __Pyx_RefNannyFinishContext();
- return retval;
- }
- ////////// MemviewSliceInit //////////
- static int
- __Pyx_init_memviewslice(struct __pyx_memoryview_obj *memview,
- int ndim,
- {{memviewslice_name}} *memviewslice,
- int memview_is_new_reference)
- {
- __Pyx_RefNannyDeclarations
- int i, retval=-1;
- Py_buffer *buf = &memview->view;
- __Pyx_RefNannySetupContext("init_memviewslice", 0);
- if (unlikely(memviewslice->memview || memviewslice->data)) {
- PyErr_SetString(PyExc_ValueError,
- "memviewslice is already initialized!");
- goto fail;
- }
- if (buf->strides) {
- for (i = 0; i < ndim; i++) {
- memviewslice->strides[i] = buf->strides[i];
- }
- } else {
- Py_ssize_t stride = buf->itemsize;
- for (i = ndim - 1; i >= 0; i--) {
- memviewslice->strides[i] = stride;
- stride *= buf->shape[i];
- }
- }
- for (i = 0; i < ndim; i++) {
- memviewslice->shape[i] = buf->shape[i];
- if (buf->suboffsets) {
- memviewslice->suboffsets[i] = buf->suboffsets[i];
- } else {
- memviewslice->suboffsets[i] = -1;
- }
- }
- memviewslice->memview = memview;
- memviewslice->data = (char *)buf->buf;
- if (__pyx_add_acquisition_count(memview) == 0 && !memview_is_new_reference) {
- Py_INCREF(memview);
- }
- retval = 0;
- goto no_fail;
- fail:
- /* Don't decref, the memoryview may be borrowed. Let the caller do the cleanup */
- /* __Pyx_XDECREF(memviewslice->memview); */
- memviewslice->memview = 0;
- memviewslice->data = 0;
- retval = -1;
- no_fail:
- __Pyx_RefNannyFinishContext();
- return retval;
- }
- #ifndef Py_NO_RETURN
- // available since Py3.3
- #define Py_NO_RETURN
- #endif
- static void __pyx_fatalerror(const char *fmt, ...) Py_NO_RETURN {
- va_list vargs;
- char msg[200];
- #ifdef HAVE_STDARG_PROTOTYPES
- va_start(vargs, fmt);
- #else
- va_start(vargs);
- #endif
- vsnprintf(msg, 200, fmt, vargs);
- va_end(vargs);
- Py_FatalError(msg);
- }
- static CYTHON_INLINE int
- __pyx_add_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
- PyThread_type_lock lock)
- {
- int result;
- PyThread_acquire_lock(lock, 1);
- result = (*acquisition_count)++;
- PyThread_release_lock(lock);
- return result;
- }
- static CYTHON_INLINE int
- __pyx_sub_acquisition_count_locked(__pyx_atomic_int *acquisition_count,
- PyThread_type_lock lock)
- {
- int result;
- PyThread_acquire_lock(lock, 1);
- result = (*acquisition_count)--;
- PyThread_release_lock(lock);
- return result;
- }
- static CYTHON_INLINE void
- __Pyx_INC_MEMVIEW({{memviewslice_name}} *memslice, int have_gil, int lineno)
- {
- int first_time;
- struct {{memview_struct_name}} *memview = memslice->memview;
- if (unlikely(!memview || (PyObject *) memview == Py_None))
- return; /* allow uninitialized memoryview assignment */
- if (unlikely(__pyx_get_slice_count(memview) < 0))
- __pyx_fatalerror("Acquisition count is %d (line %d)",
- __pyx_get_slice_count(memview), lineno);
- first_time = __pyx_add_acquisition_count(memview) == 0;
- if (unlikely(first_time)) {
- if (have_gil) {
- Py_INCREF((PyObject *) memview);
- } else {
- PyGILState_STATE _gilstate = PyGILState_Ensure();
- Py_INCREF((PyObject *) memview);
- PyGILState_Release(_gilstate);
- }
- }
- }
- static CYTHON_INLINE void __Pyx_XDEC_MEMVIEW({{memviewslice_name}} *memslice,
- int have_gil, int lineno) {
- int last_time;
- struct {{memview_struct_name}} *memview = memslice->memview;
- if (unlikely(!memview || (PyObject *) memview == Py_None)) {
- // we do not ref-count None
- memslice->memview = NULL;
- return;
- }
- if (unlikely(__pyx_get_slice_count(memview) <= 0))
- __pyx_fatalerror("Acquisition count is %d (line %d)",
- __pyx_get_slice_count(memview), lineno);
- last_time = __pyx_sub_acquisition_count(memview) == 1;
- memslice->data = NULL;
- if (unlikely(last_time)) {
- if (have_gil) {
- Py_CLEAR(memslice->memview);
- } else {
- PyGILState_STATE _gilstate = PyGILState_Ensure();
- Py_CLEAR(memslice->memview);
- PyGILState_Release(_gilstate);
- }
- } else {
- memslice->memview = NULL;
- }
- }
- ////////// MemviewSliceCopyTemplate.proto //////////
- static {{memviewslice_name}}
- __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
- const char *mode, int ndim,
- size_t sizeof_dtype, int contig_flag,
- int dtype_is_object);
- ////////// MemviewSliceCopyTemplate //////////
- static {{memviewslice_name}}
- __pyx_memoryview_copy_new_contig(const __Pyx_memviewslice *from_mvs,
- const char *mode, int ndim,
- size_t sizeof_dtype, int contig_flag,
- int dtype_is_object)
- {
- __Pyx_RefNannyDeclarations
- int i;
- __Pyx_memviewslice new_mvs = {{memslice_init}};
- struct __pyx_memoryview_obj *from_memview = from_mvs->memview;
- Py_buffer *buf = &from_memview->view;
- PyObject *shape_tuple = NULL;
- PyObject *temp_int = NULL;
- struct __pyx_array_obj *array_obj = NULL;
- struct __pyx_memoryview_obj *memview_obj = NULL;
- __Pyx_RefNannySetupContext("__pyx_memoryview_copy_new_contig", 0);
- for (i = 0; i < ndim; i++) {
- if (unlikely(from_mvs->suboffsets[i] >= 0)) {
- PyErr_Format(PyExc_ValueError, "Cannot copy memoryview slice with "
- "indirect dimensions (axis %d)", i);
- goto fail;
- }
- }
- shape_tuple = PyTuple_New(ndim);
- if (unlikely(!shape_tuple)) {
- goto fail;
- }
- __Pyx_GOTREF(shape_tuple);
- for(i = 0; i < ndim; i++) {
- temp_int = PyInt_FromSsize_t(from_mvs->shape[i]);
- if(unlikely(!temp_int)) {
- goto fail;
- } else {
- PyTuple_SET_ITEM(shape_tuple, i, temp_int);
- temp_int = NULL;
- }
- }
- array_obj = __pyx_array_new(shape_tuple, sizeof_dtype, buf->format, (char *) mode, NULL);
- if (unlikely(!array_obj)) {
- goto fail;
- }
- __Pyx_GOTREF(array_obj);
- memview_obj = (struct __pyx_memoryview_obj *) __pyx_memoryview_new(
- (PyObject *) array_obj, contig_flag,
- dtype_is_object,
- from_mvs->memview->typeinfo);
- if (unlikely(!memview_obj))
- goto fail;
- /* initialize new_mvs */
- if (unlikely(__Pyx_init_memviewslice(memview_obj, ndim, &new_mvs, 1) < 0))
- goto fail;
- if (unlikely(__pyx_memoryview_copy_contents(*from_mvs, new_mvs, ndim, ndim,
- dtype_is_object) < 0))
- goto fail;
- goto no_fail;
- fail:
- __Pyx_XDECREF(new_mvs.memview);
- new_mvs.memview = NULL;
- new_mvs.data = NULL;
- no_fail:
- __Pyx_XDECREF(shape_tuple);
- __Pyx_XDECREF(temp_int);
- __Pyx_XDECREF(array_obj);
- __Pyx_RefNannyFinishContext();
- return new_mvs;
- }
- ////////// CopyContentsUtility.proto /////////
- #define {{func_cname}}(slice) \
- __pyx_memoryview_copy_new_contig(&slice, "{{mode}}", {{ndim}}, \
- sizeof({{dtype_decl}}), {{contig_flag}}, \
- {{dtype_is_object}})
- ////////// OverlappingSlices.proto //////////
- static int __pyx_slices_overlap({{memviewslice_name}} *slice1,
- {{memviewslice_name}} *slice2,
- int ndim, size_t itemsize);
- ////////// OverlappingSlices //////////
- /* Based on numpy's core/src/multiarray/array_assign.c */
- /* Gets a half-open range [start, end) which contains the array data */
- static void
- __pyx_get_array_memory_extents({{memviewslice_name}} *slice,
- void **out_start, void **out_end,
- int ndim, size_t itemsize)
- {
- char *start, *end;
- int i;
- start = end = slice->data;
- for (i = 0; i < ndim; i++) {
- Py_ssize_t stride = slice->strides[i];
- Py_ssize_t extent = slice->shape[i];
- if (extent == 0) {
- *out_start = *out_end = start;
- return;
- } else {
- if (stride > 0)
- end += stride * (extent - 1);
- else
- start += stride * (extent - 1);
- }
- }
- /* Return a half-open range */
- *out_start = start;
- *out_end = end + itemsize;
- }
- /* Returns 1 if the arrays have overlapping data, 0 otherwise */
- static int
- __pyx_slices_overlap({{memviewslice_name}} *slice1,
- {{memviewslice_name}} *slice2,
- int ndim, size_t itemsize)
- {
- void *start1, *end1, *start2, *end2;
- __pyx_get_array_memory_extents(slice1, &start1, &end1, ndim, itemsize);
- __pyx_get_array_memory_extents(slice2, &start2, &end2, ndim, itemsize);
- return (start1 < end2) && (start2 < end1);
- }
- ////////// MemviewSliceCheckContig.proto //////////
- #define __pyx_memviewslice_is_contig_{{contig_type}}{{ndim}}(slice) \
- __pyx_memviewslice_is_contig(slice, '{{contig_type}}', {{ndim}})
- ////////// MemviewSliceIsContig.proto //////////
- static int __pyx_memviewslice_is_contig(const {{memviewslice_name}} mvs, char order, int ndim);/*proto*/
- ////////// MemviewSliceIsContig //////////
- static int
- __pyx_memviewslice_is_contig(const {{memviewslice_name}} mvs, char order, int ndim)
- {
- int i, index, step, start;
- Py_ssize_t itemsize = mvs.memview->view.itemsize;
- if (order == 'F') {
- step = 1;
- start = 0;
- } else {
- step = -1;
- start = ndim - 1;
- }
- for (i = 0; i < ndim; i++) {
- index = start + step * i;
- if (mvs.suboffsets[index] >= 0 || mvs.strides[index] != itemsize)
- return 0;
- itemsize *= mvs.shape[index];
- }
- return 1;
- }
- /////////////// MemviewSliceIndex ///////////////
- static CYTHON_INLINE char *
- __pyx_memviewslice_index_full(const char *bufp, Py_ssize_t idx,
- Py_ssize_t stride, Py_ssize_t suboffset)
- {
- bufp = bufp + idx * stride;
- if (suboffset >= 0) {
- bufp = *((char **) bufp) + suboffset;
- }
- return (char *) bufp;
- }
- /////////////// MemviewDtypeToObject.proto ///////////////
- {{if to_py_function}}
- static CYTHON_INLINE PyObject *{{get_function}}(const char *itemp); /* proto */
- {{endif}}
- {{if from_py_function}}
- static CYTHON_INLINE int {{set_function}}(const char *itemp, PyObject *obj); /* proto */
- {{endif}}
- /////////////// MemviewDtypeToObject ///////////////
- {{#__pyx_memview_<dtype_name>_to_object}}
- /* Convert a dtype to or from a Python object */
- {{if to_py_function}}
- static CYTHON_INLINE PyObject *{{get_function}}(const char *itemp) {
- return (PyObject *) {{to_py_function}}(*({{dtype}} *) itemp);
- }
- {{endif}}
- {{if from_py_function}}
- static CYTHON_INLINE int {{set_function}}(const char *itemp, PyObject *obj) {
- {{dtype}} value = {{from_py_function}}(obj);
- if ({{error_condition}})
- return 0;
- *({{dtype}} *) itemp = value;
- return 1;
- }
- {{endif}}
- /////////////// MemviewObjectToObject.proto ///////////////
- /* Function callbacks (for memoryview object) for dtype object */
- static PyObject *{{get_function}}(const char *itemp); /* proto */
- static int {{set_function}}(const char *itemp, PyObject *obj); /* proto */
- /////////////// MemviewObjectToObject ///////////////
- static PyObject *{{get_function}}(const char *itemp) {
- PyObject *result = *(PyObject **) itemp;
- Py_INCREF(result);
- return result;
- }
- static int {{set_function}}(const char *itemp, PyObject *obj) {
- Py_INCREF(obj);
- Py_DECREF(*(PyObject **) itemp);
- *(PyObject **) itemp = obj;
- return 1;
- }
- /////////// ToughSlice //////////
- /* Dimension is indexed with 'start:stop:step' */
- if (unlikely(__pyx_memoryview_slice_memviewslice(
- &{{dst}},
- {{src}}.shape[{{dim}}], {{src}}.strides[{{dim}}], {{src}}.suboffsets[{{dim}}],
- {{dim}},
- {{new_ndim}},
- &{{get_suboffset_dim()}},
- {{start}},
- {{stop}},
- {{step}},
- {{int(have_start)}},
- {{int(have_stop)}},
- {{int(have_step)}},
- 1) < 0))
- {
- {{error_goto}}
- }
- ////////// SimpleSlice //////////
- /* Dimension is indexed with ':' only */
- {{dst}}.shape[{{new_ndim}}] = {{src}}.shape[{{dim}}];
- {{dst}}.strides[{{new_ndim}}] = {{src}}.strides[{{dim}}];
- {{if access == 'direct'}}
- {{dst}}.suboffsets[{{new_ndim}}] = -1;
- {{else}}
- {{dst}}.suboffsets[{{new_ndim}}] = {{src}}.suboffsets[{{dim}}];
- if ({{src}}.suboffsets[{{dim}}] >= 0)
- {{get_suboffset_dim()}} = {{new_ndim}};
- {{endif}}
- ////////// SliceIndex //////////
- // Dimension is indexed with an integer, we could use the ToughSlice
- // approach, but this is faster
- {
- Py_ssize_t __pyx_tmp_idx = {{idx}};
- {{if wraparound or boundscheck}}
- Py_ssize_t __pyx_tmp_shape = {{src}}.shape[{{dim}}];
- {{endif}}
- Py_ssize_t __pyx_tmp_stride = {{src}}.strides[{{dim}}];
- {{if wraparound}}
- if (__pyx_tmp_idx < 0)
- __pyx_tmp_idx += __pyx_tmp_shape;
- {{endif}}
- {{if boundscheck}}
- if (unlikely(!__Pyx_is_valid_index(__pyx_tmp_idx, __pyx_tmp_shape))) {
- {{if not have_gil}}
- #ifdef WITH_THREAD
- PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();
- #endif
- {{endif}}
- PyErr_SetString(PyExc_IndexError,
- "Index out of bounds (axis {{dim}})");
- {{if not have_gil}}
- #ifdef WITH_THREAD
- PyGILState_Release(__pyx_gilstate_save);
- #endif
- {{endif}}
- {{error_goto}}
- }
- {{endif}}
- {{if all_dimensions_direct}}
- {{dst}}.data += __pyx_tmp_idx * __pyx_tmp_stride;
- {{else}}
- if ({{get_suboffset_dim()}} < 0) {
- {{dst}}.data += __pyx_tmp_idx * __pyx_tmp_stride;
- /* This dimension is the first dimension, or is preceded by */
- /* direct or indirect dimensions that are indexed away. */
- /* Hence suboffset_dim must be less than zero, and we can have */
- /* our data pointer refer to another block by dereferencing. */
- /* slice.data -> B -> C becomes slice.data -> C */
- {{if indirect}}
- {
- Py_ssize_t __pyx_tmp_suboffset = {{src}}.suboffsets[{{dim}}];
- {{if generic}}
- if (__pyx_tmp_suboffset >= 0)
- {{endif}}
- {{dst}}.data = *((char **) {{dst}}.data) + __pyx_tmp_suboffset;
- }
- {{endif}}
- } else {
- {{dst}}.suboffsets[{{get_suboffset_dim()}}] += __pyx_tmp_idx * __pyx_tmp_stride;
- /* Note: dimension can not be indirect, the compiler will have */
- /* issued an error */
- }
- {{endif}}
- }
- ////////// FillStrided1DScalar.proto //////////
- static void
- __pyx_fill_slice_{{dtype_name}}({{type_decl}} *p, Py_ssize_t extent, Py_ssize_t stride,
- size_t itemsize, void *itemp);
- ////////// FillStrided1DScalar //////////
- /* Fill a slice with a scalar value. The dimension is direct and strided or contiguous */
- /* This can be used as a callback for the memoryview object to efficienty assign a scalar */
- /* Currently unused */
- static void
- __pyx_fill_slice_{{dtype_name}}({{type_decl}} *p, Py_ssize_t extent, Py_ssize_t stride,
- size_t itemsize, void *itemp)
- {
- Py_ssize_t i;
- {{type_decl}} item = *(({{type_decl}} *) itemp);
- {{type_decl}} *endp;
- stride /= sizeof({{type_decl}});
- endp = p + stride * extent;
- while (p < endp) {
- *p = item;
- p += stride;
- }
- }
|