Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve image combination performance #741

Merged
merged 17 commits into from
May 24, 2021

Conversation

mwcraig
Copy link
Member

@mwcraig mwcraig commented Jul 24, 2020

This pull request attempts to improve the performance of ccdproc by using using numpy's nan* functions instead of numpy MaskedArray, and using by using bottleneck. It is not intended (yet) to change the API for Combiner.

So far I have only switched average_combine to do this. If I get a couple 👍 on this I'll do the same for median_combine and the clipping routines, and also combine the implementations of sum_combine and average_combine to the extent possible.

To do:

  • Document weighting during image combination
  • Add link to preliminary benchmarking
  • Unify sum and average combination
  • Use nan* or bottleneck for clipping
  • Changelog entry
  • make bottleneck an optional dependency
  • Add prominent suggestion to use bottleneck
  • Consider making dtypes settable (might belong in CCDData). -- this is a separate issue, really, and CCDData lives in astropy, core, not here.

Edit: Fixes #719

@mwcraig mwcraig marked this pull request as draft July 24, 2020 14:14
@mwcraig mwcraig added this to the 2.2 milestone Jul 24, 2020
@codecov
Copy link

codecov bot commented Jul 24, 2020

Codecov Report

Merging #741 (3ef82d9) into main (bb9c667) will decrease coverage by 1.08%.
The diff coverage is 99.25%.

❗ Current head 3ef82d9 differs from pull request most recent head 50abe7c. Consider uploading reports for the commit 50abe7c to get more accurate results
Impacted file tree graph

@@            Coverage Diff             @@
##             main     #741      +/-   ##
==========================================
- Coverage   96.01%   94.93%   -1.09%     
==========================================
  Files          30       30              
  Lines        3942     4049     +107     
==========================================
+ Hits         3785     3844      +59     
- Misses        157      205      +48     
Impacted Files Coverage Δ
ccdproc/combiner.py 94.50% <98.33%> (+0.47%) ⬆️
ccdproc/core.py 97.24% <100.00%> (ø)
ccdproc/tests/pytest_fixtures.py 86.66% <100.00%> (ø)
ccdproc/tests/test_combiner.py 100.00% <100.00%> (ø)
ccdproc/tests/test_memory_use.py 89.65% <100.00%> (+0.36%) ⬆️
ccdproc/tests/run_with_file_number_limit.py 24.21% <0.00%> (-49.48%) ⬇️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update bb9c667...50abe7c. Read the comment docs.

@mwcraig
Copy link
Member Author

mwcraig commented Jul 24, 2020

Performance improvements (no clipping done)

Some benchmark plots are below. left-most commit is master, right-most uses bottleneck. Second-to-last uses nan* instead of masked array.

average_combine with weighting: Speedup is ~ x2

average-combine-weighted

Unweighted average_combine, some entries masked. Speedup is ~ x3

average-no-weights-some-masked

Unweigthed average_combine, no entries masked. Speedup is ~ x2.8

average-no-weights-no-mask

@mwcraig
Copy link
Member Author

mwcraig commented Jul 24, 2020

Ping @crawfordsm @MSeifert04 @saimn @cmccully @ysBach -- you are either a ccdproc maintainer or someone who is working hard separate from this to improve image combination speed. Keep an eye out for an email invite later today to talk about whether we can pool efforts on this or not.

I don't need a detailed review of this -- but if you have objects to this stop-gap approach for improving performance please speak up!

@saimn
Copy link

saimn commented Jul 24, 2020

Great to see progress on this. I started to do some comparison with what we have in DRAGONS, but it is still a wip.

About bottleneck, since I had the opportunity to look at it more closely recently (astropy/astropy#10553 (comment)):

  • It does have optimized algorithm only for little-endian data. For big-endian (FITS...) it has a fallback to np.nan* functions.
  • And currently the fallback to numpy comes with a pretty bad memory leak.

Other than that, 👍 to use nan* functions instead of masked arrays, it is much faster.

@saimn
Copy link

saimn commented Jul 24, 2020

Looking more in detail at the code it seems that ccdproc converts the data to np.float64 by default, unless a dtype is specified. So the good news is that it will not be affected by the bottleneck issue. But in terms of performance it would be faster to use the original data's dtype.

@mwcraig
Copy link
Member Author

mwcraig commented Jul 30, 2020

One other bottleneck note: there are some precision issues with sums of float32: pydata/bottleneck#193

@mwcraig mwcraig force-pushed the refactor-average-final branch from 08ef65b to 698edd1 Compare September 28, 2020 01:23
@mwcraig mwcraig closed this Nov 30, 2020
@mwcraig mwcraig reopened this Nov 30, 2020
@mwcraig mwcraig force-pushed the refactor-average-final branch 3 times, most recently from 388cbbd to 7f0c9cc Compare December 2, 2020 14:16
@mwcraig mwcraig force-pushed the refactor-average-final branch from f329196 to f942355 Compare February 10, 2021 14:11
Base automatically changed from master to main March 16, 2021 13:40
@mwcraig mwcraig marked this pull request as ready for review March 19, 2021 20:01
@mwcraig mwcraig marked this pull request as draft March 19, 2021 20:01
@mwcraig mwcraig force-pushed the refactor-average-final branch 3 times, most recently from 3560821 to dcafaab Compare March 22, 2021 14:12
@mwcraig mwcraig marked this pull request as ready for review May 19, 2021 00:30
@mwcraig mwcraig closed this May 19, 2021
@mwcraig mwcraig reopened this May 19, 2021
@mwcraig mwcraig force-pushed the refactor-average-final branch 3 times, most recently from a8f395f to d581703 Compare May 19, 2021 00:53
@mwcraig
Copy link
Member Author

mwcraig commented May 19, 2021

@saimn @ysBach -- any chance either of you can take a look at this? It has become a little convoluted because I'm trying to make sure I don't change the API. THis si only a small step towards improving performance, but it is a step...

For median the only improve is if bottleneck is installed because np.nanmedian just calls np.ma.median after setting up a mask internally.

Once this is wrapped up (hopefully this week) I'd like to come back to further improvements, likely the second week of June.

@mwcraig mwcraig force-pushed the refactor-average-final branch 2 times, most recently from 3163156 to ee57383 Compare May 22, 2021 23:47
mwcraig added 14 commits May 23, 2021 21:39
Yes, I changed one test to get this to pass. Note, though, that the test
was of the return value of a completely masked result.
Also fix a couple of small sphinx-related issues
Includes using bottleneck for performance when it is available.

Implement weighted sum and test weighted sum

This includes factoring out the guts of the weighted sum for use in a
couple of combination methods.
Putting it all in one place is the current
practice.
The worry is that users may be passing in functions
that expect masked data and we don't want to break that. It
would be an API change that requires a new major release.
@mwcraig mwcraig force-pushed the refactor-average-final branch from ee57383 to 29df104 Compare May 24, 2021 02:40
@mwcraig mwcraig merged commit ac8fcfb into astropy:main May 24, 2021
@saimn
Copy link

saimn commented May 25, 2021

Coming a bit late but I don't see any issue (and my knowledge of ccdproc's combine code is limited). 🎉

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

Successfully merging this pull request may close these issues.

combine uncertainty calculated on unscaled data
2 participants