alpaka-group / llama

A Low-Level Abstraction of Memory Access
https://llama-doc.rtfd.io/
Mozilla Public License 2.0
80 stars 10 forks source link

Allow dynamic indexing of array members of a record #702

Open bernhardmgruber opened 1 year ago

bernhardmgruber commented 1 year ago

Given the following record dimension:

using Vec = llama::Record<
    llama::Field<tag::X, double>,
    llama::Field<tag::Y, double>
>;
using Particle = llama::Record<
    llama::Field<tag::Pos, Vec>,
    llama::Field<tag::Mass, float>,
    llama::Field<tag::Flags, bool[4]>
>;

Some users expect to be able to index the flags array. E.g. with a 1-dimensional view:

bool b2 = view[42](tag::Flags{})(2); // or [2]

However, this is a compilation error, since LLAMA does not allow dynamic indexing here. Arrays of static size inside a record are just syntactic sure for tuples with same-type elements. This e.g. allows to split off the second bool into a separate blob and producing the corresponding expressions for the memory mapping function at compile time. The right way to index is with a compile-time constant:

bool b2 = view[42](tag::Flags{})(llama::RecordCoord<2>{}); // or (2_RC)

We could make this work however, by translating runtime indices into compile time ones. A dynamic index would thus effectively call into a dispatch selecting the right instantiation of a compile-time access.

bool b2 = view[42](tag::Flags{})(i); // would switch on i and call operator() with the right RecordCoord.

This would additionally allow dynamic indexing into records with fields having the same data type. E.g. using a view of the Vec record above:

double x1 = view[42](tag::X{}); // current, static indexing
double x2 = view[42]llama::RecordCoord<0>{}); // current, static indexing
double x3 = view[42](0); // NEW: dynamic indexing, dispatch internally

This additional dispatching could easily be created using boost::mp11::mp_with_index, but definitely introduces overhead, that the compiler may optimize out again.