3

I am modifying cython code that makes plots of complex-valued functions. This code includes something equivalent to the following:

cimport numpy as cnumpy

def do_something():
    # Buffer types only allowed as function local variables, so put
    # this inside a function.
    cdef cnumpy.ndarray[cnumpy.float_t, ndim=3, mode='c'] rgb
    pass

What does the mode='c' kwarg do? I don't see this as an option on the numpy.ndarray documentation (or anywhere else in the numpy documentation), or mentioned in the cython for numpy users documentation/tutorial, or mentioned in cython's working with numpy documentation/tutorial.

I am not fluent in cython, but I do know python and C. I see from other questions here that this is not a rare argument, but I can't find documentation or explanation for what this does.

1
  • That question is from 2014. Maybe the API has changed since. The linked documentation does not mention kwarg, but it has "order": Row-major (C-style) or column-major (Fortran-style) order. Commented Feb 14, 2022 at 18:45

2 Answers 2

3

Argument mode maps to Python's buffer protocol's flags:

  • "c" means PyBUF_C_CONTIGUOUS
  • "fortran" means PyBUF_F_CONTIGUOUS
  • "strided" means PyBUF_STRIDES

there is also "full" which maps to PyBUF_INDIRECT and thus doesn't make sense for numpy-arrays.

Knowing, that the memory layout/mode is "c" or "fortran" would lead to generation of a more performant code, but then only numpy arrays with this layout (flags of the array must be either C_CONTIGUOUS=true for mode="c" or F_CONTIGUOUS=true for mode="fortran") would be accepted.

On the other hand mode="strided" would accept any numpy ndarray, but the generated C-code would be less performant.


The gory details:

To access the content of a numpy array Cython uses Python's buffer protocol. Whenever there is a np.ndarray in the Cython code, there will be a corresponding __Pyx_Buffer variable in the C-code, for generation of which the class BufferEntry is responsible.

To get the buffer from the array object, the C-function __Pyx_GetBufferAndValidate will be emitted. The mode-argument will be translated into the buffer-protocol flags used by the above function in BufferEntry.get_flags:

def get_flags(buffer_aux, buffer_type):
    flags = 'PyBUF_FORMAT'
    mode = buffer_type.mode
    if mode == 'full':
        flags += '| PyBUF_INDIRECT'
    elif mode == 'strided':
        flags += '| PyBUF_STRIDES'
    elif mode == 'c':
        flags += '| PyBUF_C_CONTIGUOUS'
    elif mode == 'fortran':
        flags += '| PyBUF_F_CONTIGUOUS'
    else:
        assert False
    if buffer_aux.writable_needed: flags += "| PyBUF_WRITABLE"
    return flags
Sign up to request clarification or add additional context in comments.

Comments

0

My guess is it's an equivalent to the order argument in the numpy ndarray docs.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.