Commit b2379f32 authored by Quentin Khan's avatar Quentin Khan
Browse files

FCountKernel: update to follow latest changes

Index the custom particle ontainer to allow easier testing.

Make node data inherit FBasicCell to work with standard algorithms.

Add operator call counts.

Add a partial P2P to work with OpenMP 4 task adaptive algorithm.
parent 4723fcf6
......@@ -4,18 +4,20 @@
#include <cstddef>
#include <tuple>
#include <array>
#include <unordered_map>
#include "Containers/FTreeCoordinate.hpp"
#include "Components/FBasicParticle.hpp"
#include "Components/FBasicCell.hpp"
/** \brief Particle with a count attribute for use with FCountKernel*/
template<typename FReal, std::size_t Dim>
struct TestCountParticle : public FBasicParticle<FReal, Dim, std::size_t> {
using FBase = FBasicParticle<FReal, Dim, std::size_t>;
struct TestCountParticle : public FBasicParticle<FReal, Dim, std::size_t, std::size_t> {
using FBase = FBasicParticle<FReal, Dim, std::size_t, std::size_t>;
using FBase::FBase;
/// Data index names
enum {POS1, POS2, POS3};
enum {COUNT = Dim};
enum {IDX = Dim, COUNT};
};
/** \brief Node data to use with FCountKernel
......@@ -23,7 +25,7 @@ struct TestCountParticle : public FBasicParticle<FReal, Dim, std::size_t> {
* Holds two members that count the interactions that the node multipole and
* local development represent.
*/
struct TestCountNodeData {
struct TestCountNodeData : FBasicCell {
/// FMM operators names
enum {P2P, P2M, M2M, M2L, L2L, L2P, P2L, M2P, OP_COUNT};
/// Array for operator call count
......@@ -43,17 +45,7 @@ struct FCountKernel {
using particle_t = typename ContainerClass::value_type;
constexpr static std::size_t child_count = Fpow(2, particle_t::position_t::Dim);
/** \brief Setup the kernel
*
* No-op.
*
* \tparam Tree Tree to setup.
*
* \param unnamed Unused, tree reference
*/
template<typename Tree>
void setup(Tree&) {};
std::unordered_map<std::string, std::size_t> call_count;
/** \brief Particle to multipole operator
*
......@@ -63,7 +55,9 @@ struct FCountKernel {
* \param source_particle_container Leaf particle container
*/
void P2M(CellClass* const leaf_data,
const ContainerClass* const source_particle_container) {
const ContainerClass* const source_particle_container)
{
this->call_count["P2M"] += 1;
leaf_data->up += source_particle_container->size();
leaf_data->operator_calls[TestCountNodeData::P2M] += 1;
}
......@@ -78,7 +72,9 @@ struct FCountKernel {
*/
void M2M(CellClass* const node_data,
const CellClass * const * const child_data,
const int /*level*/) {
const int /*level*/)
{
this->call_count["M2M"] += 1;
for(std::size_t idx = 0 ; idx < child_count ; ++idx) {
if(child_data[idx]) {
node_data->up += child_data[idx]->up;
......@@ -106,6 +102,7 @@ struct FCountKernel {
const int v_item_data_size,
const int /*level*/)
{
this->call_count["M2L"] += v_item_data_size;
for(int idx = 0 ; idx < v_item_data_size ; ++idx) {
if(v_item_data[idx]) {
node_data->down += v_item_data[idx]->up;
......@@ -126,6 +123,7 @@ struct FCountKernel {
CellClass** const child_data,
const int /*level*/)
{
this->call_count["L2L"] += 1;
for(std::size_t idx = 0 ; idx < child_count ; ++idx) {
if(child_data[idx]) {
child_data[idx]->down += node_data->down;
......@@ -145,6 +143,7 @@ struct FCountKernel {
void P2L(CellClass* const node_data,
const ContainerClass* const source_particle_container)
{
this->call_count["P2L"] += 1;
node_data->down += source_particle_container->size();
node_data->operator_calls[TestCountNodeData::P2L] += 1;
}
......@@ -157,7 +156,9 @@ struct FCountKernel {
* \param target_particle_container Leaf particle container
*/
void L2P(const CellClass* const leaf_data,
ContainerClass* const target_particle_container) {
ContainerClass* const target_particle_container)
{
this->call_count["L2P"] += 1;
for(auto&& particle_ref_tuple : *target_particle_container) {
std::get<particle_t::COUNT>(particle_ref_tuple) += leaf_data->down;
}
......@@ -174,6 +175,7 @@ struct FCountKernel {
void M2P(const CellClass* const node_data,
ContainerClass* const target_particle_container)
{
this->call_count["M2P"] += 1;
for(auto&& particle_ref_tuple : *target_particle_container) {
std::get<particle_t::COUNT>(particle_ref_tuple) += node_data->up;
}
......@@ -192,30 +194,50 @@ struct FCountKernel {
* \param unnamed Unused, source particle container array positions relative to current leaf
* \param u_item_count u_item_source_particle_container size
*/
void P2P(const FTreeCoordinate& ,
void P2P(const FTreeCoordinate& c,
ContainerClass* const target_particle_container,
const ContainerClass* const source_particle_container,
ContainerClass* const u_item_source_particle_container[],
const int positions[],
const int u_item_count
)
{
P2P(c, target_particle_container, source_particle_container,
u_item_source_particle_container, positions,
u_item_count, true);
}
static bool NeedFinishedM2LEvent() {return false;}
void finishedLevelM2L(int){}
void P2P(const FTreeCoordinate&,
ContainerClass* const target_particle_container,
const ContainerClass* const source_particle_container,
ContainerClass* const u_item_source_particle_container[],
const int /*positions*/[],
const int u_item_count,
CellClass* leaf_data = nullptr
bool do_inner
)
{
if(leaf_data)
leaf_data->operator_calls[TestCountNodeData::P2P] += 1 + u_item_count;
if(do_inner) {
this->call_count["P2P"] += 1;
} else {
this->call_count["partial P2P"] += 1;
}
for(auto&& particle_ref_tuple : *target_particle_container) {
std::get<particle_t::COUNT>(particle_ref_tuple) +=
source_particle_container->size();
if(do_inner) {
std::get<particle_t::COUNT>(particle_ref_tuple) +=
source_particle_container->size();
}
for(int i = 0; i < u_item_count; ++i) {
std::get<particle_t::COUNT>(particle_ref_tuple) +=
(u_item_source_particle_container[i])->size();
}
}
}
void finishedLevelM2L(int) {}
};
......
......@@ -28,6 +28,9 @@
#include "Components/FBasicParticle.hpp"
#include "Adaptive/new/FVariadicParticleContainer.hpp"
#include "Adaptive/new/FTree.hpp"
#include "Adaptive/new/FAdaptiveTask.hpp"
#include "Files/FFmaGenericLoader.hpp"
#include "FCountKernel.hpp"
......@@ -60,6 +63,9 @@ int main() {
/// FMM algorithm type
using fmm_algo_t = FFmmAlgorithm<tree_t, node_data_t, particle_container_t, kernel_t, node_data_t>;
using a_tree_t = FTree<particle_container_t, node_data_t>;
using a_fmm_algo_t = FAdaptiveTask<a_tree_t, kernel_t>;
constexpr std::size_t Height = 5;
......@@ -93,6 +99,7 @@ int main() {
// Assert that all particles have the right count attribute
tree.forEachLeaf([&](node_data_t* leaf) {
for(auto&& particle : *(leaf->getTargets())) {
(void) particle;
assert(std::get<particle_t::COUNT>(particle) == position_vect.size());
// std::cout << std::get<particle_t::COUNT>(particle) << " "
// << position_vect.size() << std::endl;;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment