Understanding mixed objects
Closed this issue · 4 comments
I was wondering if someone could explain why we have mixed objects in PyOP2. Looking at DatPack
and MixedDatPack
it is clear that during code generation mixed objects are handled quite differently to non-mixed ones. Could someone explain what is going on here and, more importantly, why?
The data associated with a Dat
is a single contiguous array. To stage from global to local in generated code we effectively do
staged[i] = dat[map[i]] # implicit Einstein notation
The data in a MixedDat
is not a single contiguous array, but is a bag of Dat
s. Therefore to stage a mixed dat one must do:
for j, (dat, map) in enumerate(zip(dats, maps)):
staged[j, i] = dat[map[i]] # note pseudo-code for linear unravelling of a ragged array.
To get a single contiguous array to pass to the kernel.
Historically, when assembling forms over mixed spaces we would split them into forms on the subspaces and then insert into the subfields. This is a nice interface, but it is not always possible to split the contributions like this as a separate kernels. So the codegen needs to scatter-gather into the mixed spaces (which is what mixeddatpack vs. Datpack are for).
Make sense?
This does thanks. Can I ask why we don't just have:
staged1[i] = dat1[map1[i]]
staged2[i] = dat2[map2[i]]
and pass both to the kernel?
Because we generate a kernel that acts on the whole mixed space (so the concatenation of staged1
and staged2
)
Ok. Thank you for such prompt replies! I've been having a bit of a headache with this today so this has been really helpful.