Commit d0ba4c57 authored by Quentin Khan's avatar Quentin Khan

Data/algo refactor start. Algorithms update

Introduces a new data model for the kernel specific data. This aim is to
better decouple the symbolic data (node metadata: height, index, etc),
multipole and local expansion of a cell.

The main algorithms are updated to follow the new structure.
parent d6ecd93a
......@@ -32,18 +32,22 @@
#include "FCoreCommon.hpp"
/**
* \author Berenger Bramas (berenger.bramas@inria.fr)
* \brief Implements a basic FMM algorithm.
*
* Please read the license.
*
* This class runs the FMM algorithm on a tree using the kernels that it was given.
*
* This class does not deallocate pointers given to it constructor.
*/
* \author Berenger Bramas (berenger.bramas@inria.fr)
* \brief Implements a basic FMM algorithm.
*
* Please read the license.
*
* This class runs the FMM algorithm on a tree using the kernels that it was given.
*
* This class does not deallocate pointers given to it constructor.
*/
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
class FFmmAlgorithm : public FAbstractAlgorithm, public FAlgorithmTimers {
using multipole_t = typename CellClass::multipole_t;
using local_exp_t = typename CellClass::local_expansion_t;
using symb_data_t = CellClass;
OctreeClass* const tree; ///< The octree to work on.
KernelClass* const kernels; ///< The kernels.
......@@ -86,8 +90,8 @@ public:
protected:
/**
* Runs the complete algorithm.
*/
* Runs the complete algorithm.
*/
void executeCore(const unsigned operationsToProceed) override {
Timers[P2MTimer].tic();
......@@ -128,9 +132,13 @@ protected:
do{
// We need the current cell that represents the leaf
// and the list of particles
multipole_t* const leaf_multipole
= &(octreeIterator.getCurrentCell()->getMultipoleData());
const symb_data_t* const leaf_symbolic
= octreeIterator.getCurrentCell();
FLOG(computationCounter.tic());
kernels->P2M(&(octreeIterator.getCurrentCell()->getMultipoleData()),
octreeIterator.getCurrentCell(),
kernels->P2M(leaf_multipole,
leaf_symbolic,
octreeIterator.getCurrentListSrc());
FLOG(computationCounter.tac());
} while(octreeIterator.moveRight());
......@@ -168,15 +176,26 @@ protected:
do{
// We need the current cell and the child
// child is an array (of 8 child) that may be null
using multipole_t = typename CellClass::multipole_t;
std::array<multipole_t*, 8> children_multipoles;
multipole_t* const parent_multipole
= &(octreeIterator.getCurrentCell()->getMultipoleData());
const symb_data_t* const parent_symbolic
= octreeIterator.getCurrentCell();
CellClass** children = octreeIterator.getCurrentChildren();
std::transform(children, children+8, children_multipoles.begin(),
[](CellClass* c) {return (c == nullptr ? nullptr : &(c->getMultipoleData()));});
std::array<const multipole_t*, 8> child_multipoles;
std::transform(children, children+8, child_multipoles.begin(),
[](CellClass* c) {
return (c == nullptr ? nullptr
: &(c->getMultipoleData()));
});
std::array<const symb_data_t*, 8> child_symbolics;
std::transform(children, children+8, child_symbolics.begin(),
[](CellClass* c) {return c;});
FLOG(computationCounter.tic());
kernels->M2M(&(octreeIterator.getCurrentCell()->getMultipoleData()),
children_multipoles.data(),
idxLevel);
kernels->M2M(parent_multipole,
parent_symbolic,
child_multipoles.data(),
child_symbolics.data());
FLOG(computationCounter.tac());
} while(octreeIterator.moveRight());
......@@ -223,17 +242,33 @@ protected:
do{
const int counter = tree->getInteractionNeighbors(neighbors, neighborPositions, octreeIterator.getCurrentGlobalCoordinate(), idxLevel, separationCriteria);
using multipole_t = typename CellClass::multipole_t;
if(counter == 0) {
continue;
}
local_exp_t* const target_local_exp
= &(octreeIterator.getCurrentCell()->getLocalExpansionData());
const symb_data_t* const target_symbolic
= octreeIterator.getCurrentCell();
std::array<const multipole_t*, 342> neighbor_multipoles;
std::array<const symb_data_t*, 342> neighbor_symbolics;
std::transform(neighbors, neighbors+counter, neighbor_multipoles.begin(),
[](const CellClass* c) {return (c == nullptr ? nullptr : &(c->getMultipoleData()));});
[](const CellClass* c) {
return (c == nullptr ? nullptr
: &(c->getMultipoleData()));
});
std::transform(neighbors, neighbors+counter, neighbor_symbolics.begin(),
[](const CellClass* c) {return c;});
FLOG(computationCounter.tic());
if(counter) kernels->M2L(
&(octreeIterator.getCurrentCell()->getLocalExpansionData()) ,
kernels->M2L(
target_local_exp,
target_symbolic,
neighbor_multipoles.data(),
neighbor_symbolics.data(),
neighborPositions,
counter, idxLevel);
counter);
FLOG(computationCounter.tac());
} while(octreeIterator.moveRight());
......@@ -276,18 +311,26 @@ protected:
// for each cells
do{
using local_expansion_t = typename CellClass::local_expansion_t;
std::array<local_expansion_t*, 8> children_expansions;
local_exp_t* const parent_local_exp
= &(octreeIterator.getCurrentCell()->getLocalExpansionData());
const symb_data_t* const parent_symbolic
= octreeIterator.getCurrentCell();
CellClass** children = octreeIterator.getCurrentChildren();
std::transform(children, children+8, children_expansions.begin(),
std::array<local_exp_t*, 8> child_local_expansions;
std::transform(children, children+8, child_local_expansions.begin(),
[](CellClass* c) {return (c == nullptr ? nullptr
: &(c->getLocalExpansionData()));
});
std::array<symb_data_t*, 8> child_symbolics;
std::transform(children, children+8, child_symbolics.begin(),
[](CellClass* c) {return c;});
FLOG(computationCounter.tic());
kernels->L2L(
&(octreeIterator.getCurrentCell()->getLocalExpansionData()),
children_expansions.data(),
idxLevel);
parent_local_exp,
parent_symbolic,
child_local_expansions.data(),
child_symbolics.data()
);
FLOG(computationCounter.tac());
} while(octreeIterator.moveRight());
......
This diff is collapsed.
This diff is collapsed.
......@@ -55,6 +55,10 @@
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass, class P2PExclusionClass = FP2PMiddleExclusion>
class FFmmAlgorithmSectionTask : public FAbstractAlgorithm, public FAlgorithmTimers {
using multipole_t = typename CellClass::multipole_t;
using local_exp_t = typename CellClass::local_expansion_t;
using symb_data_t = CellClass;
OctreeClass* const tree; ///< The octree to work on
KernelClass** kernels; ///< The kernels
......@@ -217,17 +221,25 @@ protected:
// child is an array (of 8 child) that may be null
#pragma omp task firstprivate(octreeIterator,idxLevel)
{
using multipole_t = typename CellClass::multipole_t;
std::array<multipole_t*, 8> children_multipoles;
multipole_t* const parent_multipole
= &(octreeIterator.getCurrentCell()->getMultipoleData());
const symb_data_t* const parent_symbolic
= octreeIterator.getCurrentCell();
CellClass** children = octreeIterator.getCurrentChildren();
std::transform(children, children+8, children_multipoles.begin(),
[](CellClass* c) {return (c == nullptr ? nullptr
: &(c->getMultipoleData()));
std::array<const multipole_t*, 8> child_multipoles;
std::transform(children, children+8, child_multipoles.begin(),
[](CellClass* c) {
return (c == nullptr ? nullptr
: &(c->getMultipoleData()));
});
kernels[omp_get_thread_num()]->M2M(
&(octreeIterator.getCurrentCell()->getMultipoleData()),
children_multipoles.data(),
idxLevel);
std::array<const symb_data_t*, 8> child_symbolics;
std::transform(children, children+8, child_symbolics.begin(),
[](CellClass* c) {return c;});
kernels[omp_get_thread_num()]->M2M(parent_multipole,
parent_symbolic,
child_multipoles.data(),
child_symbolics.data());
}
} while(octreeIterator.moveRight());
......@@ -289,19 +301,27 @@ protected:
if(counter){
#pragma omp task firstprivate(octreeIterator, neighbors, neighborPositions, counter,idxLevel)
{
using multipole_t = typename CellClass::multipole_t;
local_exp_t* const target_local_exp
= &(octreeIterator.getCurrentCell()->getLocalExpansionData());
const symb_data_t* const target_symbolic
= octreeIterator.getCurrentCell();
std::array<const multipole_t*, 342> neighbor_multipoles;
std::transform(neighbors, neighbors+counter,
neighbor_multipoles.begin(),
std::transform(neighbors, neighbors+counter, neighbor_multipoles.begin(),
[](const CellClass* c) {
return (c == nullptr ? nullptr
: &(c->getMultipoleData()));
});
std::array<const symb_data_t*, 342> neighbor_symbolics;
std::transform(neighbors, neighbors+counter, neighbor_symbolics.begin(),
[](const CellClass* c) {return c;});
kernels[omp_get_thread_num()]->M2L(
&(octreeIterator.getCurrentCell()->getLocalExpansionData()),
target_local_exp,
target_symbolic,
neighbor_multipoles.data(),
neighbor_symbolics.data(),
neighborPositions,
counter, idxLevel);
counter);
}
}
......@@ -352,19 +372,27 @@ protected:
if(counter){
#pragma omp task firstprivate(octreeIterator, neighbors, neighborPositions, counter,idxLevel)
{
using multipole_t = typename CellClass::multipole_t;
local_exp_t* const target_local_exp
= &(octreeIterator.getCurrentCell()->getLocalExpansionData());
const symb_data_t* const target_symbolic
= octreeIterator.getCurrentCell();
std::array<const multipole_t*, 342> neighbor_multipoles;
std::transform(neighbors, neighbors+counter,
neighbor_multipoles.begin(),
std::transform(neighbors, neighbors+counter, neighbor_multipoles.begin(),
[](const CellClass* c) {
return (c == nullptr ? nullptr
: &(c->getMultipoleData()));
});
std::array<const symb_data_t*, 342> neighbor_symbolics;
std::transform(neighbors, neighbors+counter, neighbor_symbolics.begin(),
[](const CellClass* c) {return c;});
kernels[omp_get_thread_num()]->M2L(
&(octreeIterator.getCurrentCell()->getLocalExpansionData()),
target_local_exp,
target_symbolic,
neighbor_multipoles.data(),
neighbor_symbolics.data(),
neighborPositions,
counter, idxLevel);
counter);
}
}
......@@ -405,18 +433,25 @@ protected:
do{
#pragma omp task firstprivate(octreeIterator,idxLevel)
{
using local_expansion_t = typename CellClass::local_expansion_t;
std::array<local_expansion_t*, 8> children_expansions;
local_exp_t* const parent_local_exp
= &(octreeIterator.getCurrentCell()->getLocalExpansionData());
const symb_data_t* const parent_symbolic
= octreeIterator.getCurrentCell();
CellClass** children = octreeIterator.getCurrentChildren();
std::transform(children, children+8, children_expansions.begin(),
[](CellClass* c) {
return (c == nullptr ? nullptr
: &(c->getLocalExpansionData()));
std::array<local_exp_t*, 8> child_local_expansions;
std::transform(children, children+8, child_local_expansions.begin(),
[](CellClass* c) {return (c == nullptr ? nullptr
: &(c->getLocalExpansionData()));
});
std::array<symb_data_t*, 8> child_symbolics;
std::transform(children, children+8, child_symbolics.begin(),
[](CellClass* c) {return c;});
kernels[omp_get_thread_num()]->L2L(
&(octreeIterator.getCurrentCell()->getLocalExpansionData()),
children_expansions.data(),
idxLevel);
parent_local_exp,
parent_symbolic,
child_local_expansions.data(),
child_symbolics.data()
);
}
} while(octreeIterator.moveRight());
......
......@@ -49,6 +49,10 @@
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass, class P2PExclusionClass = FP2PMiddleExclusion>
class FFmmAlgorithmTask : public FAbstractAlgorithm, public FAlgorithmTimers {
using multipole_t = typename CellClass::multipole_t;
using local_exp_t = typename CellClass::local_expansion_t;
using symb_data_t = CellClass;
OctreeClass* const tree; //< The octree to work on
KernelClass** kernels; //< The kernels
......@@ -212,17 +216,25 @@ protected:
// children is an array (of 8 child) that may be null
#pragma omp task firstprivate(octreeIterator,idxLevel)
{
using multipole_t = typename CellClass::multipole_t;
std::array<multipole_t*, 8> children_multipoles;
multipole_t* const parent_multipole
= &(octreeIterator.getCurrentCell()->getMultipoleData());
const symb_data_t* const parent_symbolic
= octreeIterator.getCurrentCell();
CellClass** children = octreeIterator.getCurrentChildren();
std::transform(children, children+8, children_multipoles.begin(),
[](CellClass* c) {return (c == nullptr ? nullptr
: &(c->getMultipoleData()));
std::array<const multipole_t*, 8> child_multipoles;
std::transform(children, children+8, child_multipoles.begin(),
[](CellClass* c) {
return (c == nullptr ? nullptr
: &(c->getMultipoleData()));
});
kernels[omp_get_thread_num()]->M2M(
&(octreeIterator.getCurrentCell()->getMultipoleData()),
children_multipoles.data(),
idxLevel);
std::array<const symb_data_t*, 8> child_symbolics;
std::transform(children, children+8, child_symbolics.begin(),
[](CellClass* c) {return c;});
kernels[omp_get_thread_num()]->M2M(parent_multipole,
parent_symbolic,
child_multipoles.data(),
child_symbolics.data());
}
} while(octreeIterator.moveRight());
......@@ -291,20 +303,29 @@ protected:
neighbors, neighborPositions,
octreeIterator.getCurrentGlobalCoordinate(),
idxLevel, separationCriteria);
if(counter){
using multipole_t = typename CellClass::multipole_t;
if(counter) {
local_exp_t* const target_local_exp
= &(octreeIterator.getCurrentCell()->getLocalExpansionData());
const symb_data_t* const target_symbolic
= octreeIterator.getCurrentCell();
std::array<const multipole_t*, 342> neighbor_multipoles;
std::transform(neighbors, neighbors+counter,
neighbor_multipoles.begin(),
std::transform(neighbors, neighbors+counter, neighbor_multipoles.begin(),
[](const CellClass* c) {
return (c == nullptr ? nullptr
: &(c->getMultipoleData()));
});
std::array<const symb_data_t*, 342> neighbor_symbolics;
std::transform(neighbors, neighbors+counter, neighbor_symbolics.begin(),
[](const CellClass* c) {return c;});
kernels[omp_get_thread_num()]->M2L(
&(octreeIterator.getCurrentCell()->getLocalExpansionData()),
target_local_exp,
target_symbolic,
neighbor_multipoles.data(),
neighbor_symbolics.data(),
neighborPositions,
counter, idxLevel);
counter);
}
}
......@@ -354,21 +375,31 @@ protected:
neighbors, neighborPositions,
octreeIterator.getCurrentGlobalCoordinate(),
idxLevel, separationCriteria);
if(counter){
using multipole_t = typename CellClass::multipole_t;
if(counter) {
local_exp_t* const target_local_exp
= &(octreeIterator.getCurrentCell()->getLocalExpansionData());
const symb_data_t* const target_symbolic
= octreeIterator.getCurrentCell();
std::array<const multipole_t*, 342> neighbor_multipoles;
std::transform(neighbors, neighbors+counter,
neighbor_multipoles.begin(),
std::transform(neighbors, neighbors+counter, neighbor_multipoles.begin(),
[](const CellClass* c) {
return (c == nullptr ? nullptr
: &(c->getMultipoleData()));
});
std::array<const symb_data_t*, 342> neighbor_symbolics;
std::transform(neighbors, neighbors+counter, neighbor_symbolics.begin(),
[](const CellClass* c) {return c;});
kernels[omp_get_thread_num()]->M2L(
&(octreeIterator.getCurrentCell()->getLocalExpansionData()),
target_local_exp,
target_symbolic,
neighbor_multipoles.data(),
neighbor_symbolics.data(),
neighborPositions,
counter, idxLevel);
counter);
}
}
......@@ -422,19 +453,25 @@ protected:
do{
#pragma omp task firstprivate(octreeIterator,idxLevel)
{
using local_expansion_t = typename CellClass::local_expansion_t;
std::array<local_expansion_t*, 8> children_expansions;
local_exp_t* const parent_local_exp
= &(octreeIterator.getCurrentCell()->getLocalExpansionData());
const symb_data_t* const parent_symbolic
= octreeIterator.getCurrentCell();
CellClass** children = octreeIterator.getCurrentChildren();
std::transform(children, children+8, children_expansions.begin(),
[](CellClass* c) {
return (c == nullptr ? nullptr
: &(c->getLocalExpansionData()));
std::array<local_exp_t*, 8> child_local_expansions;
std::transform(children, children+8, child_local_expansions.begin(),
[](CellClass* c) {return (c == nullptr ? nullptr
: &(c->getLocalExpansionData()));
});
std::array<symb_data_t*, 8> child_symbolics;
std::transform(children, children+8, child_symbolics.begin(),
[](CellClass* c) {return c;});
kernels[omp_get_thread_num()]->L2L(
&(octreeIterator.getCurrentCell()->getLocalExpansionData()),
children_expansions.data(),
idxLevel);
parent_local_exp,
parent_symbolic,
child_local_expansions.data(),
child_symbolics.data()
);
}
} while(octreeIterator.moveRight());
......
......@@ -51,6 +51,11 @@
*/
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass, class P2PExclusionClass = FP2PMiddleExclusion>
class FFmmAlgorithmThread : public FAbstractAlgorithm, public FAlgorithmTimers{
using multipole_t = typename CellClass::multipole_t;
using local_exp_t = typename CellClass::local_expansion_t;
using symb_data_t = CellClass;
OctreeClass* const tree; ///< The octree to work on.
KernelClass** kernels; ///< The kernels.
......@@ -274,16 +279,31 @@ protected:
#pragma omp for nowait schedule(dynamic, chunkSize)
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
// We need the current cell and its children
using multipole_t = typename CellClass::multipole_t;
std::array<multipole_t*, 8> children_multipoles;
multipole_t* const parent_multipole
= &(iterArray[idxCell].getCurrentCell()->getMultipoleData());
const symb_data_t* const parent_symbolic
= iterArray[idxCell].getCurrentCell();
CellClass** children = iterArray[idxCell].getCurrentChildren();
std::transform(children, children+8, children_multipoles.begin(),
[](CellClass* c) {return (c == nullptr ? nullptr : &(c->getMultipoleData()));});
std::array<const multipole_t*, 8> child_multipoles;
std::transform(children, children+8, child_multipoles.begin(),
[](CellClass* c) {
return (c == nullptr ? nullptr
: &(c->getMultipoleData()));
});
std::array<const symb_data_t*, 8> child_symbolics;
std::transform(children, children+8, child_symbolics.begin(),
[](CellClass* c) {
return c;
});
myThreadkernels->M2M(
&(iterArray[idxCell].getCurrentCell()->getMultipoleData()),
children_multipoles.data(),
idxLevel);
parent_multipole,
parent_symbolic,
child_multipoles.data(),
child_symbolics.data()
);
}
}
......@@ -354,7 +374,12 @@ protected:
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
const int counter = tree->getInteractionNeighbors(neighbors, neighborPositions, iterArray[idxCell].getCurrentGlobalCoordinate(), idxLevel, separationCriteria);
if(counter) {
using multipole_t = typename CellClass::multipole_t;
local_exp_t* const target_local_exp
= &(iterArray[idxCell].getCurrentCell()->getLocalExpansionData());
const symb_data_t* const target_symbolic
= iterArray[idxCell].getCurrentCell();
std::array<const multipole_t*, 342> neighbor_multipoles;
std::transform(neighbors, neighbors+counter,
neighbor_multipoles.begin(),
......@@ -362,12 +387,18 @@ protected:
return (c == nullptr ? nullptr
: &(c->getMultipoleData()));
});
std::array<const symb_data_t*, 342> neighbor_symbolics;
std::transform(neighbors, neighbors+counter,
neighbor_symbolics.begin(),
[](const CellClass* c) {return c;});
myThreadkernels->M2L(
&(iterArray[idxCell].getCurrentCell()->getLocalExpansionData()),
target_local_exp,
target_symbolic,
neighbor_multipoles.data(),
neighbor_symbolics.data(),
neighborPositions,
counter, idxLevel);
counter);
}
}
......@@ -424,19 +455,27 @@ protected:
#pragma omp for nowait schedule(dynamic, chunkSize)
for(int idxCell = 0 ; idxCell < numberOfCells ; ++idxCell){
using local_expansion_t = typename CellClass::local_expansion_t;
std::array<local_expansion_t*, 8> children_expansions;
local_exp_t* const parent_local_exp
= &(iterArray[idxCell].getCurrentCell()->getLocalExpansionData());
const symb_data_t* const parent_symbolic
= iterArray[idxCell].getCurrentCell();
std::array<local_exp_t*, 8> child_expansions;
CellClass** children = iterArray[idxCell].getCurrentChildren();
std::transform(children, children+8, children_expansions.begin(),
std::transform(children, children+8, child_expansions.begin(),
[](CellClass* c) {
return (c == nullptr ? nullptr
: &(c->getLocalExpansionData()));
});
std::array<symb_data_t*, 8> child_symbolics;
std::transform(children, children+8, child_symbolics.begin(),
[](CellClass* c) {return c;});
myThreadkernels->L2L(
&(iterArray[idxCell].getCurrentCell()->getLocalExpansionData()),
children_expansions.data(),
idxLevel);
parent_local_exp,
parent_symbolic,
child_expansions.data(),
child_symbolics.data());
}
}
FLOG(computationCounter.tac());
......
#ifndef FFmmAlgorithmThreadBalanceBALANCE_HPP
#define FFmmAlgorithmThreadBalanceBALANCE_HPP
#include <array>
#include <algorithm>
#include "../Utils/FAssert.hpp"
#include "../Utils/FLog.hpp"
......@@ -33,6 +36,11 @@
*/
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass, class P2PExclusionClass = FP2PMiddleExclusion>
class FFmmAlgorithmThreadBalance : public FAbstractAlgorithm, public FAlgorithmTimers{
using multipole_t = typename CellClass::multipole_t;
using local_exp_t = typename CellClass::local_expansion_t;
using symb_data_t = CellClass;
OctreeClass* const tree; ///< The octree to work on.
KernelClass** kernels; ///< The kernels.
......@@ -462,7 +470,11 @@ protected:
for(int idxLeafs = 0 ; idxLeafs < nbCellsToCompute ; ++idxLeafs){
// We need the current cell that represent the leaf
// and the list of particles
myThreadkernels->P2M( octreeIterator.getCurrentCell() , octreeIterator.getCurrentListSrc());
myThreadkernels->P2M(
&(octreeIterator.getCurrentCell()->getMultipoleData()),
octreeIterator.getCurrentCell(),
octreeIterator.getCurrentListSrc()
);
octreeIterator.moveRight();
}
......@@ -501,7 +513,25 @@ protected:
for(int idxCell = 0 ; idxCell < nbCellsToCompute ; ++idxCell){
// We need the current cell and the child
// child is an array (of 8 child) that may be null
myThreadkernels->M2M( octreeIterator.getCurrentCell() , octreeIterator.getCurrentChild(), idxLevel);
multipole_t* const parent_multipole
= &(octreeIterator.getCurrentCell()->getMultipoleData());
const symb_data_t* const parent_symbolic
= octreeIterator.getCurrentCell();
CellClass** children = octreeIterator.getCurrentChildren();
std::array<const multipole_t*, 8> child_multipoles;
std::transform(children, children+8, child_multipoles.begin(),
[](CellClass* c) {
return (c == nullptr ? nullptr
: &(c->getMultipoleData()));
});
std::array<const symb_data_t*, 8> child_symbolics;
std::transform(children, children+8, child_symbolics.begin(),
[](CellClass* c) {return c;});
myThreadkernels->M2M(parent_multipole,
parent_symbolic,
child_multipoles.data(),
child_symbolics.data());
octreeIterator.moveRight();
}
......@@ -527,7 +557,7 @@ protected:
/** Runs the M2L kernel. */
/** M2L */
void transferPass(){
#ifdef SCALFMM_USE_EZTRACE
#ifdef SCALFMM_USE_EZTRACE
eztrace_start();
#endif
this->transferPassWithFinalize() ;
......@@ -558,8 +588,35 @@ protected:
int neighborPositions[342];
for(int idxCell = 0 ; idxCell < nbCellsToCompute ; ++idxCell){
const int counter = tree->getInteractionNeighbors(neighbors, neighborPositions, octreeIterator.getCurrentGlobalCoordinate(), idxLevel, separationCriteria);
if(counter) myThreadkernels->M2L( octreeIterator.getCurrentCell() , neighbors, neighborPositions, counter, idxLevel);
const int counter = tree->getInteractionNeighbors(
neighbors, neighborPositions,
octreeIterator.getCurrentGlobalCoordinate(),
idxLevel, separationCriteria);
if(counter) {
local_exp_t* const target_local_exp
= &(octreeIterator.getCurrentCell()->getLocalExpansionData());
const symb_data_t* const target_symbolic
= octreeIterator.getCurrentCell();
std::array<const multipole_t*, 342> neighbor_multipoles;
std::transform(neighbors, neighbors+counter, neighbor_multipoles.begin(),
[](const CellClass* c) {
return (c == nullptr ? nullptr
: &(c->getMultipoleData()));
});
std::array<const symb_data_t*, 342> neighbor_symbolics;
std::transform(neighbors, neighbors+counter, neighbor_symbolics.begin(),
[](const CellClass* c) {return c;});
myThreadkernels->M2L(
target_local_exp,
target_symbolic,
neighbor_multipoles.data(),
neighbor_symbolics.data(),
neighborPositions,
counter);
}
octreeIterator.moveRight();
}
......@@ -603,7 +660,26 @@ protected:
typename OctreeClass::Iterator octreeIterator( workloadL2L[idxLevel][omp_get_thread_num()].iterator);
for(int idxCell = 0 ; idxCell < nbCellsToCompute ; ++idxCell){
myThreadkernels->L2L( octreeIterator.getCurrentCell() , octreeIterator.getCurrentChild(), idxLevel);
local_exp_t* const parent_local_exp
= &(octreeIterator.getCurrentCell()->getLocalExpansionData());
const symb_data_t* const parent_symbolic
= octreeIterator.getCurrentCell();
CellClass** children = octreeIterator.getCurrentChildren();