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

DM-13854: extend cache in Psf #334

Merged
merged 2 commits into from Mar 27, 2018
Merged

DM-13854: extend cache in Psf #334

merged 2 commits into from Mar 27, 2018

Conversation

PaulPrice
Copy link
Contributor

Larger cache makes things go faster.

Copy link
Member

@TallJimbo TallJimbo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few small comments; biggest one is to try to get Cache.h out of the header files.

Another thought: could we modify the hash function and equality comparison used by the cache for computeKernelImage to round off to the nearest integer pixel, so tiny changes in the point requested don't result in cache misses? If our PSFs are changing much over the scale of a pixel, we've got bigger problems (or we've already flagged that object with INEXACT_PSF for exactly that reason). Of course, we'd probably want to modify computeKernelImageitself to do that rounding even when not using the cache, so the cache doesn't change the actual behavior, but I think that'd be fine. And obviously we can't do that rounding in computeImage.

mutable geom::Point2D _cachedImagePosition;
mutable geom::Point2D _cachedKernelImagePosition;
mutable utils::Cache<CacheKey, std::shared_ptr<Image>> _imageCache;
mutable utils::Cache<CacheKey, std::shared_ptr<Image>> _kernelImageCache;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe shared_ptr<Image const>, because it can be?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't think I can, unless I cast away the same const in Psf::computeImage.

@@ -29,6 +29,7 @@
#include <memory>

#include "lsst/daf/base.h"
#include "lsst/utils/Cache.h"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed on the utils ticket, I'd prefer to forward-declare Cache, have Psf hold it by unique_ptr, and move this include to the .cc file.


/// Set the capacity of the caches
///
/// Both the image and kernel image caches will be set to this capacity.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use /** */ for multi-line Doxygen comments.

return os << key.position;
}
};

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hopefully this can be moved to the .cc file, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pulled it out of the class, into a preceding namespace detail. But it does mess up the top of the file a bit, especially since I have to get into namespace std to provide the std::hash support (it's more annoying to work with than boost::hash).

@@ -364,6 +366,8 @@ PyPoint<T, N> declarePoint(py::module &mod, std::string const &suffix) {
cls.def("__ne__", [](Point<T, N> const &self, Point<T, N> const &other) { return self != other; },
py::is_operator());

cls.def("__hash__", [](Point<T, N> const &self) { return boost::hash<Point<T, N>>()(self); });

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure it's a good idea to add this to Python; Points are not immutable and hence putting them in dicts could definitely confuse the dict.

Copy link
Member

@TallJimbo TallJimbo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you didn't go quite far enough in moving things to the .cc file to reap the benefits (and doing that should greatly reduce the need for changes in other packages). More comments inline.

void setCacheCapacity(std::size_t capacity) {
_imageCache->reserve(capacity);
_kernelImageCache->reserve(capacity);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you define setCacheCapacity and getCacheCapacity (and ~Psf(), I think), you should no longer need to include Cache.h in other source files that use Psf. I'm not totally sure that's enough, but the goal here is to make sure that anything that uses Cache as more than an opaque pointer is in Psf.cc, and that will make it unnecessary to include Cache.h anywhere but Psf.cc.

friend std::ostream & operator<<(std::ostream &os, PsfCacheKey const &key) {
return os << key.position;
}
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll need a forward declaration of this class in the header for the typedef later, but the rest can also go in Psf.cc.

mutable image::Color _cachedKernelImageColor;
mutable geom::Point2D _cachedImagePosition;
mutable geom::Point2D _cachedKernelImagePosition;
typedef utils::Cache<detail::PsfCacheKey, std::shared_ptr<Image>> PsfCache;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using PsfCache = utils::Cache<detail::PsfCacheKey, std::shared_ptr<Image>> is preferred in C++11.

mutable geom::Point2D _cachedKernelImagePosition;
typedef utils::Cache<detail::PsfCacheKey, std::shared_ptr<Image>> PsfCache;
mutable std::shared_ptr<PsfCache> _imageCache;
mutable std::shared_ptr<PsfCache> _kernelImageCache;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe these no longer need to be mutable; the extra layer of indirection does that for you. Since Psf is already noncopyable and immutable, std::unique_ptr should be used instead of std::shared_ptr as well.

: daf::base::Citizen(typeid(this)),
_isFixed(isFixed),
_imageCache(new PsfCache(capacity)),
_kernelImageCache(new PsfCache(capacity))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Best practice is to use std::make_shared to initialize smart pointers when you're constructing the pointee at the same time (or, if you switch to std::unique_ptr, std::make_unique).

@PaulPrice PaulPrice force-pushed the tickets/DM-13854 branch 3 times, most recently from 5e9f969 to 028ffca Compare March 27, 2018 01:15
Copy link
Member

@TallJimbo TallJimbo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

Two tiny inline comments.

@@ -26,6 +26,8 @@
#ifndef LSST_AFW_DETECTION_H
#define LSST_AFW_DETECTION_H

#include "lsst/utils/Cache.h" // for afw::detection::Psf

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be removable now.

@@ -21,6 +21,7 @@
*/

#include <cmath>
#include <boost/functional/hash.hpp> // boost::hash
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use "", not <>.

Allows its use as a key in lsst::utils::Cache.

Deliberately NOT defining Point.__hash__ in python, since Point
is mutable so we don't want to be able to use it as the key in
a dict.
This allows caching many more realisations (they're relatively cheap:
50x50 pixels per realisation @ 8 bytes per pixel); the number of
realisations is configurable.

This gains about 22% in the runtime of measureCoaddSources.py using the
default 100 cache slots for all Psf instances. Allowing CoaddPsf to use
100000 cache slots increases the gain to about 25%.
@PaulPrice PaulPrice merged commit 9ecf299 into master Mar 27, 2018
@ktlim ktlim deleted the tickets/DM-13854 branch August 25, 2018 06:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants