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-41994: Use galsim primitives vs higher level interface. #48

Merged
merged 5 commits into from Dec 7, 2023

Conversation

erykoff
Copy link
Contributor

@erykoff erykoff commented Dec 4, 2023

No description provided.

Copy link

@rmjarvis rmjarvis left a comment

Choose a reason for hiding this comment

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

I wouldn't recommend going this way. This is using implementation details in ways that are basically equivalent to the C++ syntax reliance that you currently have in the stack. I assume most of the reason for this is to avoid the heavy overhead in the galsim.Image constructor.

However, you should be able to remove most of that using the supported galsim._Image factory function. It's a leading underscore function, but it is documented, which means it is guaranteed to be API stable using the normal semantic versioning rules. cf. http://galsim-developers.github.io/GalSim/_build/html/image_class.html#galsim._Image

I think using that would get you most of the performance you're looking for here without the fragility of relying on implementation details.

array.strides[1]//array.itemsize,
array.strides[0]//array.itemsize,
bounds._b,
)
Copy link

Choose a reason for hiding this comment

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

Is this actually faster than using galsim._Image(array, bounds, None)? That's the supported API that skips most of the sanity checks. This interface isn't guaranteed to be stable across versions.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks! I didn't know about this, and will take a look. It does look like it should do what we need, and will confirm.

shape = galsim.hsm.ShapeData()
hsmparams = galsim.hsm.HSMParams.default

galsim._galsim.FindAdaptiveMomView(
Copy link

Choose a reason for hiding this comment

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

Even this isn't really guaranteed to be stable, but it should be very close to equivalent to image.FindAdaptiveMom(...).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So there was actually a significant amount of time spent in _convertMask which was some of the motivation to use the primitive. If there was an officially supported way of bypassing this I think we could use the official API.

Copy link
Member

Choose a reason for hiding this comment

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

Oh right. The direct Python API calls the _convertMask function which has a bunch of galsim.Image instantiations making it slow as well. I could open an issue on the GalSim repo if there's no immediate supported API.

Copy link

Choose a reason for hiding this comment

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

That's fair. What mask do you use? None? Or something real?

Copy link
Member

Choose a reason for hiding this comment

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

We supply a value for badpix that masks some pixels, so very much real. I think the overheads there can be reduced by using galsim._ImageI instead of galsim.ImageI in _convertMask.

Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

Right now, this is the only sticking point I believe. Either we use the FindAdaptiveMom call or have a TODO comment here referring to a ticket that should replace it with FindAdaptiveMom as soon as we have a version of GalSim with the above issue implemented.

@@ -278,19 +292,20 @@ def measure(self, record, exposure):
# Create a GalSim image using the extracted array.
# NOTE: GalSim's HSM uses the FITS convention of 1,1 for the
# lower-left corner.
image = galsim.Image(imageArray, bounds=bounds, copy=False)
_image = _quickGalsimImageView(imageArray, bounds)
Copy link

Choose a reason for hiding this comment

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

Here, I would recommend image = galsim._Image(imageArray, bounds, None).

@@ -430,7 +445,17 @@ def measure(self, record, exposure):
imageArray = psfImage.array

# Create a GalSim image using the PSF image array.
image = galsim.Image(imageArray, bounds=bounds, copy=False)
_image = _quickGalsimImageView(imageArray, bounds)
Copy link

Choose a reason for hiding this comment

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

Also here. image = galsim._Image(imageArray, bounds, None).

@arunkannawadi
Copy link
Member

@rmjarvis recommends using galsim._Image to avoid the overhead instead of the APIs that aren’t guaranteed to be stable. In hindsight, I should have known it but completely forgot about it. That should be the best alternative to _quickGalsimImageView. We don’t gain much by using FindAdaptiveMomView directly so perhaps we should stick to using the Python interface there.

http://galsim-developers.github.io/GalSim/_build/html/image_class.html#galsim._Image

@arunkannawadi
Copy link
Member

Eli, for this ticket, should we just move on to galsim._Image and perhaps galsim._Bounds and close this ticket? I suspect it'll be a while before a more supported API for FindAdaptiveMom will make its way to rubin-env anyway.

@erykoff
Copy link
Contributor Author

erykoff commented Dec 5, 2023

@arunkannawadi This is ready for re-review. I have done what you suggest, and I didn't know about the _BoundsI constructor until now.

@arunkannawadi
Copy link
Member

That was also a suggestion from Mike on Slack (DM). Per my calculations, it should save us some 5% of the total run time on single-visit images (and lesser on coadds).

hsmparams=None,

# Use galsim c++/python interface directly.
shape = galsim.hsm.ShapeData()
Copy link
Member

Choose a reason for hiding this comment

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

Pass in arguments here: observed_shape=galsim._Shear(), psf_shape=galsim._Shear(), moments_centroid=galsim._PositionD(). These avoid initializing objects underneath without the overhead.

@@ -130,21 +123,25 @@ def _calculate(
"""
# Convert centroid to GalSim's PositionD type.
guessCentroid = galsim.PositionD(centroid.x, centroid.y)
Copy link
Member

Choose a reason for hiding this comment

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

Make this _PositionD

shape = galsim.hsm.ShapeData()
hsmparams = galsim.hsm.HSMParams.default

galsim._galsim.FindAdaptiveMomView(
Copy link
Member

Choose a reason for hiding this comment

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

Right now, this is the only sticking point I believe. Either we use the FindAdaptiveMom call or have a TODO comment here referring to a ticket that should replace it with FindAdaptiveMom as soon as we have a version of GalSim with the above issue implemented.

e1=shape.observed_shape.e1,
e2=shape.observed_shape.e2,
e1=observed_shape.e1,
e2=observed_shape.e2,
Copy link
Member

Choose a reason for hiding this comment

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

Capturing the observed_shape in a variable is great, because getting this attribute is expensive. It constructs a Shear object, with overheads, each time observed_shape is accessed from a ShapeData object.

@erykoff erykoff merged commit 87969a0 into main Dec 7, 2023
2 checks passed
@erykoff erykoff deleted the tickets/DM-41994 branch December 7, 2023 05:30
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

3 participants