Implement gather2D proxy behaviour into SOACollections
This MR introduces a new ScatterGather2D behaviour to SOACollections, allowing to do generic pointer chasing in SIMD.
Collections that want to represent a reference into other collections, need to use a Tag of type index2D_field
(single pointer) or indices2D_field
(NDarray of pointers), and implement a containers()
method returning the list of containers associated with the tag:
struct RecursiveTest;
struct ChildIndex : index2D_field<RecursiveTest> {}; // container[i]->field[j]
struct ChildIndexArray : indices2D_field<RecursiveTest, 30, 2> {}; // Type of containers, number of bits to represents j (default to 24), dimensions of the NDArray
struct RecursiveTest : public SOACollection<RecursiveTest, ChildIndex, ChildIndexArray, Float> {
template <typename Tag>
auto containers() {
if constexpr ( std::is_same_v<Tag, ChildIndex> || std::is_same_v<Tag, ChildIndexArray> ) { return childContainers; }
}
std::vector<RecursiveTest*> childContainers;
};
Example usage:
auto test1_simd = test1.simd<SIMDWrapper::InstructionSet::Best>();
using simd = SIMDWrapper::best::types;
auto proxy = test1_simd.gather2D( simd::indices(), simd::indices() < simd::size );
std::cout << "test1.float: " << proxy.get<Float>() << std::endl;
std::cout << "test1.child.float: " << proxy.get<ChildIndex>().get<Float>() << std::endl;
std::cout << "test1.child.child.float: " << proxy.get<ChildIndex>().get<ChildIndex>().get<Float>() << std::endl;
std::cout << "test1.child[0].float: " << proxy.get<ChildIndexArray>( 0 ).get<Float>() << std::endl;
std::cout << "test1.child[1].float: " << proxy.get<ChildIndexArray>( 1 ).get<Float>() << std::endl;
This got a bit complicated to stay generic, and surely will need some tweaking when we start using it for real.
Edited by Arthur Marius Hennequin