Closed hameerabbasi closed 2 years ago
@hameerabbasi I've understood and started working on this. I had a doubt though, is Operands
referring to formats such as COO or CSR? If so, how are they combined into a class?
Operands
refers to other BinaryFn
s. The "base level" is a SingleLevel
, which specifies the index at which that level is present in the tuple<class... Levels>
tuple.
So you would use it like this example for Compressed * Compressed
:
CoIterate<And<SingleLevel<0>, SingleLevel<1>>, tuple<Compressed, Compressed>>
@hameerabbasi What will the base class BinaryFn
contain?
There doesn't need to be a base class, just added it to show the interface.
You might find if constexpr
useful in the implementation.
@hameerabbasi Would I be using if constexpr
to check whether the template parameter is And
or Or
and emit different merges based on the condition in CoIterate
?
@hameerabbasi Once we generate the loops, how do we actually merge into the output? Will we be using a reference to the vals
of the output? Or do we just assemble and return a Level?
We need a ForwardIterator
, as discussed.
We need a
ForwardIterator
, as discussed.
Okay, just like the iter_helper
for regular iterators returns (IK, PK)
, this forward_iterator must return (IK, PK)
for the merged level?
It will yield a std::pair<IK, std::tuple<std::optional<PK_of_each_level>>>
.
The optional tells us for which levels the IK
is present.
@hameerabbasi The PK
of each level refers to the levels that are being merged for a particular dimension?
That's correct.
That's correct.
In that case, can I use the PK
obtained from the iter_helper
of a given level and put it into the tuple?
Only if the IK
you get is equal to the minimum. Like in the codegen algorithm.
Only if the
IK
you get is equal to the minimum. Like in the codegen algorithm.
@hameerabbasi I'm not understanding how we can merge when there's different operators in the expression, something like A(i) = B(i) + C(i) * D(i)
. In such a scenario, we will have to define some precedence like the AND should be merged first and then the OR...Do we again go for recursion here?
This will be represented by a consteval bool
function: a | c & d
. You shouldn't worry too much about precedence and expression building yet -- Just abstract that away and think about iteration for now. You have an n-input boolean function and n levels, your job is just to co-iterate over or locate into those levels.
The boolean function defines the "pattern" -- when the output is "empty" and when it is not, based on when the inputs are or aren't "empty".
@hameerabbasi Okay now I have a fair idea of what is to be done. I have a question though, how do I "emit" variables for the iterators of the n levels? For example, I would need to use the iter_helper
of these levels to get the IKs and PKs, so would I be using something like a tuple to store these iterators?
@hameerabbasi how do we get the types of IK and PK to define the forward_iterator? Also, I'm not sure about how to create a tuple of iterators using std::tie
, as tuples are immutable, and we cannot append elements to a tuple.
I think IK
and PK
should be taken in the constructor.
Or that there should also be an iter_helper
function like in the levels.
As mentioned in yesterday's weekly meeting, here is the API for merge lattices, in psuedo-C++ syntax:
cc @bharath2438