Re: [eigen] nesting

[ Thread Index | Date Index | More Archives ]

As discussed on IRC, I fixed that nesting issue using a much simpler approach. For the record the trick is to add a Matrix member to the Product _expression_ which can hold the result of the product when this later is nested. In addition, the product _expression_ is nested by reference just like any Matrix. This is already in the devel branch for products. If no issue is discovered we can extend this concept to the ReturnByValue class which is used to implement the solve() and inverse() functions.

During these changes I also made small outer products lazy by default, and removed the need for a Flagged _expression_.


On Mon, Feb 8, 2010 at 9:24 AM, Hauke Heibel <hauke.heibel@xxxxxxxxxxxxxx> wrote:
Some brainstorming...

1) We have two phases during _expression_ creation and evaluation

a) up-stream-phase: building up the expressions
b) down-stream-phases: _expression_ execution

For the moment I am leaving out a potential reordering phase via the
Evaluator on purpose - I think that could be easily incorporated as

Regarding the temporaries we might do the following. First, let's
assume we handle heap allocations via shared_ptrs. Then we are left
with stack temporaries only. During phase a) in which the _expression_
tree is build up from bottom to top (thus up-stream), each _expression_
can propagate its stack memory requirements to the parent - we know it
from the Matrix template parameters. In the end, we have the overall
stack requirement at the top _expression_.

Then, during the down-stream or execution phase a controller class
needs to trigger the execution and handle the stack memory management.
After the controller allocated the required amount cache, he calls the
_expression_ and passes the cache over to the next _expression_ in the
down-stream. Each _expression_ will then snatch off the required stack
memory from the cache an pass the remaining memory to the child
expressions. Thus, during the evaluation each _expression_ should have
access to the required cache.

Again, this is not an easy task but might be doable. What could be
advantageous is that from a development point of view almost all of
the required components are mutually independent. Handling heap memory
in the up-stream can be implemented independently from the stack
memory propagation as well as the down-stream execution.

It's not yet all 100% clear but I hope I made the idea clear...

- Hauke

On Mon, Feb 8, 2010 at 3:50 AM, Benoit Jacob <jacob.benoit.1@xxxxxxxxx> wrote:
> To summarize the little conversation that happened over irc:
> 1) Hauke: a very good reason why we want to evaluate intermediate
> temporaries also in the fixed-size case, as mentioned by Gael, is when
> the cost-model tells us that this reduces the complexity of the
> operation. For example, evaluating b+c in "a*(b+c)".
> 2) On the other hand the idea of an "_expression_ evaluator" seems
> really doable (albeit complex) following this strategy:
> a) At the time of the construction of the _expression_, we gather the
> information of where temporaries must be introduced when evaluating
> that _expression_. That could be a new typedef in ei_traits.
> b) when evaluating an _expression_, we instantiate an object of a
> template "Evaluator" type that uses that information to hold the
> necessary temporary matrices as member data. We then traverse the
> _expression_ tree, evaluating the designated sub-expressions into these
> temporaries.
> I'm not saying that I'm finding this _easy_!! This has got to be the
> most complicated templates exercise that we've had to solve. But it
> can be done for sure, as templates allow to do everything. To think
> about that, I'm finding it convenient to think purely in terms of
> pseudo code, and translate this into templates at the last minute.
> Templates are not human-readable code :(

Mail converted by MHonArc 2.6.19+