[Numpy-discussion] using scalar input on np.PyArray_MultiIterNew2

Sebastian Berg sebastian at sipsolutions.net
Sun Jan 10 13:05:01 EST 2021


On Sun, 2021-01-10 at 09:59 -0700, zoj613 wrote:
> Hi all,
> 
> I am looking for a way to use `np.PyArray_MultiIterNew2` in Cython to
> broadcast parameters of a function. The requirement is that the two
> arguments can be scalar and/or sequences. Using the usual
> `np.broadcast`
> function works well but is slow when iterating over the broadcasted
> input in
> a tight loop. I want to achieve the same using the C API.

NB: There is also a different, newer, iterator (`NpyIter_New`).
Depending on what you do, that might be a lot faster and better
(although, I admit it tends to be more verbose too).
That iterator also does broadcasting, and one nice property is that it
can allocate a result array.  Most importantly, it casts for you and
allows you to take charge of the inner-loop (a one dimensional loop)
for performance.  (This is the core of how ufuncs work.)

> Currently, if I used `(<double*>np.PyArray_MultiIter_DATA(bcast,
> i))[0]` to
> iterate over the input when one of them is a scalar,
> I get no errors, but I notice the output of the parent function
> returns an
> array of zeros, which implies this approach didn't work. After
> investigating, it seems that np.PyArray_MultiIter_DATA only accepts
> numpy
> arrays.

I am honestly confused by this (did you mean a different command?).
`PyArray_MultiIter_DATA` returns a pointer to the raw data, i.e. in
cython you would probably do:

    cdef double *value_ptr = <double *>npc.PyArray_MultiIter_DATA(iter, 0)
    value_ptr[0] = 3.1416

Do want to reference the original data?  You could reference the
original data for scalars (read-only since scalars are immutable), but
for lists/tuples there is no original data to begin with (unless you
have Python objects inside, but it would seem strange if NumPy to
attempted to transparently expose that).

> I could write a function to handle all combinations of
> scalar/array/list/tuple, and create temporary arrays to store the
> input

The typical pattern is to convert everything to array first, but
`PyArray_MultiIter()` does that for you. Unless you want to optimize
that conversion away?

Cheers,

Sebastian


> data, but that seems daunting and error prone. Is there a way I can
> achieve
> this and have scalar arguments passed to np.PyArray_MultiIter_DATA be
> converted to same-element arrays without writing my own code from
> scratch?
> 
> Any suggestions are welcome.
> 
> 
> 
> --
> Sent from: http://numpy-discussion.10968.n7.nabble.com/
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion at python.org
> https://mail.python.org/mailman/listinfo/numpy-discussion
> 

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part
URL: <https://mail.python.org/pipermail/numpy-discussion/attachments/20210110/8baf94dd/attachment.sig>


More information about the NumPy-Discussion mailing list