Repository navigation
Conversation
|
Hi there @mhvk 👋 - thanks for the pull request! I'm just a friendly 🤖 that checks for issues related to the changelog and making sure that this pull request is milestoned and labeled correctly. This is mainly intended for the maintainers, so if you are not a maintainer you can ignore this, and a maintainer will let you know if any action is required on your part 😃. Everything looks good from my point of view! 👍 If there are any issues with this message, please report them here. |
|
Very nice! I can help review this soon but too jet lagged for this level right now ;) In the mean time, a simple question - how hard do you think it would be to add support for OpenMP at the C level? (now that astropy-helpers supports adding OpenMP flags). Just thought I'd ask since this is being refactored anyway, we might as well think about this. |
|
@astrofrog - OpenMP at C level is a bit beyond me... But overall I would think that it should be possible to have it be done automatically to the extent that numpy can be compiled with OpenMP; my guess would be that it mostly needs adjustment in |
d5931c2 to
5d19076
Compare
|
Fixed the failure on 32-bit (which was very real, due to a poorly defined dtype) and rebased. Think all is OK now. |
|
Note that the new circle-ci 32-bit failure is a false positive; see #7486 (comment) |
|
@mhvk - to help with reviewing this, could you paste the generated C code in a gist? |
|
Somehow copy/paste was failing me for the 300 kb file, so I just put it on my web site: |
|
p.s. While you are looking at it, maybe also consider something I'm still wondering about: should all ufuncs that act on vectors/matrices just be gufuncs, so that one doesn't have to cast to the temporary structured dtypes. If this is done, the python wrappers become even thinner, just checking the status values. (Note that since it won't change the python interface, this does not have to be decided now; it is partially inspired by a numpy pull request which would bring fixed axis dimensions to the gufunc signature; see numpy/numpy#11132. (For now, I'd have to do a dimension check, but that's not too hard.) |
Using ufuncs instead of C routines and a custom iterator has the advantage that casting to arrays with the right dtype and iteration is taken care of automatically, in numpy C code. For small arrays, this means substantially faster execution. Another advantage is that classes can now override the ufuncs using __array_ufunc__ - this is important both for ensuring Quantity input is disallowed (or at least treated correctly rather than just cast to array), and that a new Distribution class can work with the erfa functions.
Before, contents of astrom and ldbody were kept as well.
98e11c4 to
7d97bb0
Compare
Also simplify the viewing back.
|
I've become convinced that the wrapping with |
This implements the suggestion I made in #6865, of wrapping the ERFA functions inside ufuncs instead of using custom wrappers. This has the advantage that casting to arrays with the right dtype and iteration is taken care of automatically, in numpy C code (well, except that it turned out it needed a custom type resolver...). Another advantage is that classes can now override the ufuncs using
__array_ufunc__- this is important both for ensuringQuantityinput is disallowed (a small bug, though one with zero impact, was in fact found this way; see first commit), and that the newDistributionclass proposed by @eteq can work with the erfa functions, a first step towards making it work withSkyCoordandTime.@jwoillez - now that I've done this, I admire your initial implementation even more!
Notes
The
ufuncare still lightly wrapped by python functions as the ufunc implementation requires that, e.g., a vector uses a structureddtype, so that its 3 elements are considered one element of the array, and broadcasting can be done properly. This wrapping may need adjusting for the use inDistribution, or perhaps it makes more sense to use those structured dtypes throughout. But I think that makes more sense in a follow-up PR. Here, though, I do expose theufuncthemselves inside_erfa, so it is easier to experiment (unlike the original C wrappers, which made no sense on their own); I also think some of the small ERFA matrix and vector routines may well be faster than the numpy equivalents, given that the number of elements is always small (the numpy ones use blas under the hood, which may well introduce an overhead for small dimensions).UPDATE: with the old implementation, functions that needed to be passed in bodies for light deflection calculations did not work correctly. Here, they are wrapped by generalized ufuncs, which works.
Initial timing
Because this removes casts to and creation of outout arrays in python, the implementation is sped up, especially for small arrays. E.g.,
For actual conversions, the effect is more modest, but still noticeable for
Timeat least: