> On Aug 22, 2016, at 5:36 AM, Rob Trangucci <
robert.t...@gmail.com> wrote:
>
>
>
> ...
> My main worry is actually memory consumption rather than computational cost, because for most of the models that I have in mind, a cubic operation (matrix-matrix multiply, or decomposition) would dominate the computational cost. However, for something like a matrix-vector product, the copying will be on the same order as the function evaluation and gradient calc.
Same order, but much lower constant given the overhead
of autodiff.
> multiply(Matrix<var, -1, -1> A, Matrix<var, -1, -1> B) has to allocate arena memory for the double values of A and B in order to compute Matrix<double, -1, -1> AB = A * B,
We shouldn't allocate a local Matrix<double, ...> in the arena.
We should just use Eigen so the memory doesn't persist beyond
the local scope.
> and then in chain() we have to make copies of the adjoint matrix of AB, and A and B. It seems like we're allocating more memory than we need to here.
Absolutely, but the dynamic overhead for the operations should
be freed as soon as the result's calculated.
> I think we can cut down on one of these allocations by allowing Eigen to reuse and resize memory for an adjoint calculation. But as we start to chain matrix operations together, we're going to have to make seemingly unnecessary copies of matrices.
Right.
> Have you worked through what the data type would look like
> and how it'd fit in with the rest of our autodiff? ...
Above paragraph from me, below from Rob---for some reason I'm not
getting nesting in his responses.
> Yes, this is where I was stumbling yesterday. I don't have a good answer yet. I'm tempted to say that we don't allow indexing, but this should be a last-resort. Is there a way to template matrix vars in such a way as to specialize for a class that allows for indexing and one that doesn't?
Not that I can figure out. The issue is that templating is resolved
statically (at compile time), but we don't know what kind of variable
we'll run into on the stack. And we have to keep things in stack order
to pass gradients. So the only way I know how to do this is with a
virtual function, which is much more epensive.
> Then you could template the matrix functions to handle inputs of indexable matrix vars and to handle inputs of non-indexable matrix vars. The class and chain method for the former would look similar to our matrix var functions now, but the class and chain methods for the latter would use the MatrixXd members of the matrix vars passed in as arguments.
>
>
(from bob)
> Then there's the issue of how the chain() method will work.
> The challenge is that you either need to store pointers to other
> scalar vari or matrix mvari.
>
(from rob)
The idea would be to store pointers to the mvari.
And then you'd need the indexes into mvari, too.
> There's also the issue of higher-order autodiff if we
> ever want to get that going for real.
>
> As long as we've added the properly templated versions of all the functions,
> we should be fine, no?
So you'd have
template <T>
mvari
Matrix<T, -1, -1> val_;
Matrix<T, -1, -1> adj_;
?
> Also, Ben's always been talking about how to store decompositions
> for reuse, which is where a lot of inefficiency in naive matrix
> use comes from in user programs.
>
> Anyway, I'd love to hear some fresh ideas on how to handle this.
> I can also ask around at the autodiff conference in a couple weeks
> in Oxford. I have a feeling I'm going to mostly be sitting there
> slack-jawed while all the calculus and applied math notation
> rolls over my head.
>
> Whatever the answer to these questions is, it'd be a massive
> undertaking at both the language and math lib level---akin to
> taking on using Nomad.
>
> No doubt, but I think we're currently stuck with either slower matrix computation or faster but memory inefficient matrix computation. Worth chatting about on Tuesday at the dev meeting?
If you have anything else to say about it, sure. I'd be gung-ho
to do this if we had a design prototype that worked and at least
a person-year's worth of programmer time.
- Bob