-
Notifications
You must be signed in to change notification settings - Fork 38
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
Error with StaticArrays #126
Comments
The in-place forms cannot use static arrays because static arrays are immutable. Did you try the out-of-place form? |
Does in-place vs out-of-place even make sense in vector-to-scalar case? It has to return a scalar, whether or not the input vector is immutable or not. With my proposed change, you could (with the same cache) pass in either static vectors or normal (mutable) vectors. Right now it results some rather obscure errors if you try to mix the cache and input types. |
You never want to use static vectors and mutable vectors in the same code. If you do, then one of the two is seeing a very suboptimal code path. Just use the out-of-place form for the differentiation of static arrays: you don't want to use it on vectors because it's allocating, but of course it's not allocating for static arrays. |
Yeah, I agree it's usually not a great way to go, but there are cases where it's warranted (like using leveraging fast computational kernels using static arrays to populate pieces of larger arrays). I'll see if I can rethink my code design a bit to simplify this. Out of curiosity, would allowing a |
You literally can never use StaticVector with in-place codes. Everything about it always fails. using StaticArrays
x = SA[1.0,2.0]
x[1] = 3.0 # errors Any code that is mutating on static arrays is thus either accidentally not using static arrays and is thus inefficient for static arrays, or is not mutating and is thus not efficient for arrays. There's two code paths because they are literally not compatible. |
Yeah, that's technically only true for As a little background, I'm the lead author of TrajectoryOptimization.jl, which has SotA performance thanks to StaticArrays, but I'm currently working on allowing it to use non-static arrays since the compilation time blows up for anything over a given size. I rely on super-efficient computation kernels for computing lots of 1st and 2nd order Taylor approximations and then caching them to solve the large optimization problem. Feel free to close this issue if you think it's not a concern (I'll just continue with my current hack until I figure something else out). |
No, because
Right now you can't. DiffEq has a code duplication for this reason. There is work going on to try and aliviate the issue, specifically JuliaLang/julia#42465, but even with that what will happen is non-mutating could code could be as efficient as mutating code, but only if the compiler can sufficiently prove everything it needs to. And that PR does not include the compilation passes required for any off the proofs, so we're quite a long ways away from being able to really use immutable vectors and allow the compiler to transform it into fast mutating code. When ImmutableArrays are good enough for DiffEq they should be good enough for other places, but right now it's a core compiler dev dream to make that a reality. As for proper use of out of place, see the test: Again, there is no cache because caching static vectors doesn't make sense: if you make an mutate a cache they will allocate, while if there is no cache they won't allocate, so not caching with immutables is a better idea. Because of that I'll close this but feel free to ask any further questions. |
Thanks for the links Chris! So while obviously it's the most efficient to work entirely with static arrays (for small sizes) to avoid copy-operations and keep everything on the stack, you can efficiently copy from a static array to a normal one. My current approach is to represent all my cached gradients and vectors using mutable containers, usually a But since a lot of the computational overhead of the algorithms I deal with is actually evaluating the gradients, Hessians, or Jacobians I need (I have a unified interface for user-defined, ForwardDiff, and FiniteDiff, and hopefully Symbolics in the near future), it's usually a win (for medium-sized input vectors) to pass in an When you do similar things and need to cache the output, do you just store a vector of array like |
No you can't, that will allocate.
This will hit the speed of static array kernels but would still require allocating mutables. It depends on the operations being done but this can be a good approach in some cases, but in the "smallest" cases never allocating the mutable will be better. It depends on the application whether that makes an appreciable difference.
Use AbstractDifferentiation.jl?
The real key here is that the algorithms you're using are likely O(n^k) for k>1 somewhere (lu-factorization?) while this copy cost is just O(n), and so sooner or later it won't matter as much as getting some optimized microkernels. That's what's done for example in RecursiveFactorization.jl or Octavian.jl, though for very small matrices (<20 x 20 or so) a purely static approach will win.
Yes, and it's lazily reconstructs the time series via the RecursiveArrayTools.jl VectorOfArray abstraction. |
I'm getting an error when running the following code:
which produces this error:
I'm explicitly not passing in
x
to theGradientCache
because I want to be able to also support normalVector
inputs with the same cache. There's definitely seems to be some errors in the non-StridedVector
gradient function, since there are calls tocompute_epsilon
passing in the vectorx
instead of an element ofx
.If I copy the
StridedVector
code and allow aStaticVector
, the gradient computes just fine and without any allocations. Since you're already depending onStaticArrays
, maybe make theStridedVector
version take in aUnion{StridedVector{<:Number},<:StaticVector{<:Any,<:Any,<:Number}}
for the input vectorx
?I'm not quite following all the logic in the
GradientCache
, and maybe my simple suggestion is missing something, but it'd be nice to allow for this type of use-case.The text was updated successfully, but these errors were encountered: