Skip to content

Make erfa functions ufuncs instead of using custom wrappers? #6865

Closed

Description

@mhvk

In some of the work on distributions @eteq and I have been discussing, a bottleneck is the assumptions the current erfa wrappers make about the inputs; it would be great if those could be overridden. One possible way, which I note here mostly as a reminder, is to make all the erfa functions ufunc (or perhaps gufunc where reductions over axes take place). That way, any array can in principle override them using __array_ufunc__ and we could have Quantity helpers that take care of units. An advantage would be that broadcasting and iteration would be taken care of by the ufunc machinery (now a lot of duplicated code).

Activity

  1. jwoillez commented on Dec 7, 2017

    @jwoillez
    Member

    The documentation for gufunc (PyUFunc_FromFuncAndDataAndSignature at
    https://docs.scipy.org/doc/numpy-dev/reference/c-api.ufunc.html) states that the machinery only supports built-in data types. But we have to support the eraASTROM and eraLDBODY structures (see https://github.com/liberfa/erfa/blob/master/src/erfam.h). Is the idea/solution, to split the structures into built-in components?

    Example: the eraASTROM *astrom in void eraAticq(double ri, double di, eraASTROM *astrom, double *rc, double *dc) would be expanded.

  2. mhvk commented on Dec 7, 2017

    @mhvk
    ContributorAuthor

    @jwoillez - just goes to show how much I thought about it so far... I think the situation can be saved either by breaking up into built-in pieces, as you suggest; with PyUFunc_RegisterLoopForType (which allows one to use a user type, though it still has to be defined); or by casting the structures as Object arrays (surely not the most efficient, but perhaps not horrific since the structure is quite large, so the additional indirection may not cost that much in speed).

    More generally, do you think this is a good idea at all? I'm slightly worried about performance so had been thinking about testing it on one of the simpler erfa functions.

  3. jwoillez commented on Dec 8, 2017

    @jwoillez
    Member

    I take back what I said earlier. There seems to be a way to work with structured array.
    See the description of PyUFunc_RegisterLoopForDescr at https://docs.scipy.org/doc/numpy-dev/reference/c-api.ufunc.html. An example is given there: https://docs.scipy.org/doc/numpy/user/c-info.ufunc-tutorial.html#example-numpy-ufunc-with-structured-array-dtype-arguments.

    On the question ArrayIterator versus GUFunc I would not know. From reading the doc (https://docs.scipy.org/doc/numpy/reference/c-api.html), it feels like they are equivalent, except maybe for type casting, which is supported by ufunc but not needed for erfa. In erfa, the types are already set to floats most of the time (no need to compute the earth attitude with integers).

  4. mhvk commented on Dec 8, 2017

    @mhvk
    ContributorAuthor

    Ah, nice, so that would make it easier at least. My guess is also that for large arrays the ufuncs would likely be equivalent in speed to the current implementation, since they use the same iterator (assuming that cython is not that much slower than C). But for small arrays the overhead might be larger. But the possibility to override is nice...

  5. mhvk commented on Jul 2, 2018

    @mhvk
    ContributorAuthor

    implemented in #7502

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions