Skip to content

Implement gather2D proxy behaviour into SOACollections

Arthur Marius Hennequin requested to merge ahennequ_gather2D into master

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.

@graven @sponce

Edited by Arthur Marius Hennequin

Merge request reports