-
Notifications
You must be signed in to change notification settings - Fork 25
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
slow hcubature for large vector-valued integrands #30
Comments
Yes, Cubature works much more in-place for vector-valued integrands than HCubature. It's not just a matter of providing an in-place integrand function, however — a lot of other parts of the code would need to be reworked to operate in-place. @ChrisRackauckas, do you have any advice here from your experience with DifferentialEquations? (A lot of realistic problems involve more expensive integrands, so that the overhead of the extra allocations matters less.) |
I don't have good advice, but I can tell you how we do it in DifferentialEquations.jl. It's not really possible to handle in-place and out-of-place in a single set of functions, so in the internals of the time stepping we have both versions, one optimized for the static array and reverse-mode AD case (since reverse-mode is another case where the array-based operations allocating is helpful), while the other is a fully non-allocating mutating case. For example, look at the implementation of Dormand-Prince: My idea here is that, in the library we might as well code the fastest thing we can until the compiler can handle it better, but it can't right now. There's too much The next thing to address then is how to automatically detect this. What we do is look at the current method table: https://github.com/SciML/DiffEqBase.jl/blob/master/src/utils.jl#L1-L46 and then use this to place a type-parameter in the problem construction: https://github.com/SciML/DiffEqBase.jl/blob/master/src/problems/ode_problems.jl#L72 So then it's type-information after that point. That lets the user override it if necessary, and lets the user add it as a literal to make it type stable. While it feels a little hacky, in practice we've been doing this for 4 years and no one has really ever complained. The breaking scenario is that a user defines One other semi-important detail is that we pair this with a separate broadcast implementation ( That's probably not as elegant of an answer as you were hoping for, but I think it's the only real answer to get the most optimal dispatches for the two cases until there's better lifetime management and array freezing in the compiler. |
I understand only the first part of your answer and I can try to write a PR to do in-place mutation. |
The basic code that would have to be duplicated is the rule evaluation, e.g. here. We could use a type parameter in the rule construction to say whether we want an in-place rule or not. I don't think we need to look at the method table. Probably we could just have an interface |
Yes, I agree that in this use case it's overkill to do the methods table reading. (and probably in DiffEq, but by now the interface is set in stone). |
If I understand correctly, there should be a |
Yes, probably by adding a type parameter to |
I am integrating
L(f) = \int K.(f .- g(x)) dx
where f is a vector of 100-1000 elements,g
andK
are scalar, the integration is in R^3. The dimension of the codomain ofK
is the same asf
because it is easy to vectorize the computation ofK
.HCubature
does worse thanCubature
, the memory allocation being 100 times that of Cubature (SVector
s do not perform well for large vectors, although it may not have anything to do withSVector
) and 20 times slower. I am not sure if part of the problem is also that Cubature allows one to copy in place the result of the computation.Here is a MWE with the timings on my machine. Is there a workaround or will passing an integrand with an extra argument that accepts an in-place return value be considered?
EDIT: timing with
@benchmark
.The text was updated successfully, but these errors were encountered: