-
Notifications
You must be signed in to change notification settings - Fork 0
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
Implement Cubic 2d interpolation as seen in LHAPDF #5
Conversation
It's slower than LHAPDF (about 20% slower). There are two possible improvements: vectorization and caching the derivatives of the PDF with respect to x for every q at construction time but I though it was preferable to have something working (20% slower is not much when talking about PDF interpolation) and deal with a possible improvement later since both those things should be transparent to the user. |
Do you have any idea about why? In principle, C++ and Rust are fully equivalent (they might produce the same LLVM IR), and you took the implementation from there, so I wonder where is the bottleneck. However, 20% is perfectly acceptable, so we could even keep as it is... |
I haven’t looked in detail. This time I took it from there but not bug for bug, I just had a general look… LHAPDF might be doing some aggressive caching of the coefficients of the interpolation. If this is the difference this would be cheap to do when the grid is first created. |
/// Together with the trait [`ToDimension`] this struct allows to convert a `usize` into a | ||
/// `Dimension` from the `ndarray` crate. | ||
pub struct DimensionHelper<const D: usize>; | ||
|
||
/// See documentation of [`DimensionHelper`]. | ||
pub trait ToDimension { | ||
/// A `Dimension` type from the `ndarray` crate. | ||
type Dim: Dimension; | ||
} | ||
|
||
impl ToDimension for DimensionHelper<1> { | ||
type Dim = Ix1; | ||
} | ||
|
||
impl ToDimension for DimensionHelper<2> { | ||
type Dim = Ix2; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, this is not as I expected, but at least the repeated part is quite minimal!
Thanks @scarlehoff for the workaround!
I wonder if you can give a blanket implementation for usize
, and just overwrite for 1
and 2
(i.e. saying that by default is Ix0
). At least, we would reduce the boilerplate at call site, since all usize
would implement the ToDimension
trait.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I take it back: it's not possible (yet)
https://rust-lang.github.io/rfcs/1210-impl-specialization.html
Thanks @cschwan I'll try to understand your changes. Btw, for some reason the newest version of rust makes the code even slower. Now it's 40% worse than LHAPDF (from 20% before). |
Hm, that's strange. It should make any difference, because I shouldn't have changed any (acutal) code. |
Nono, independently of your changes, I updated rust and the whole thing became slower. |
This is also weird, a regression on performances of such a small amount of code is unexpected... |
Ok, now this is ready for review. RE performance, no, I tried a previous version of rust and the performance was recovered. I've seen in the changelog there was a few changes regarding the M1 mac son it might be just a problem for my laptop. Please let me know if the |
Everything seems to work well. The results seem symmetric upon changing x1 and x2 so nothing weird with that. We can merge when you want. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left a few comments, but it's essentially fine. Merge whenever you wish.
|
||
/// Cubic interpolation | ||
#[derive(Debug)] | ||
pub struct Cubic<const D: usize> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To make it (possibly) even simpler, you could make it a 1-element tuple.
This is exactly the newtype pattern, even though Rust is missing a dedicated mechanism for that.
However, it's substantially the same, it would be truely simpler only if you could avoid the generics boilerplate somehow...
This would require some caveats since in practice LHAPDF is defining a hierarchy on the axes and I'm not 100% sure it is symmetric. I would like to check that.
TODO:
Implement aThis would generate unnecessary copiesGrid
->GridSlice
method that exists only for D > 2Cubic1d
toCubic<Ix?>
Leaving this here so I don't forget, although technically is not related to this PR and I guess I should move it to an issue:
The extrapolation question arises again. In 1D is clear, if you are trying to extrapolate you can error out but now you might extrapolate only in 1D so you might still want the interpolation in the other. This would require
partons
to implement interpolation-extrapolation routines which would basically repeat some of the code here, so we might want to discuss at some point how to deal with that.It might still be
partons
calling the proper extrapolation function fromndinterp
, but I believe the functions themselves should be implemented here. Sopartons
take the decisions andndinter
performs the operations.