Commit 4ee06a01 authored by BRAMAS Berenger's avatar BRAMAS Berenger

use an abstract algorithm and a builder

parent cfc7de5e
#ifndef FALGORITHMBUILDER_HPP
#define FALGORITHMBUILDER_HPP
#include "FCoreCommon.hpp"
#include "../Utils/FGlobal.hpp"
#include "../Utils/FGlobalPeriodic.hpp"
#include "FFmmAlgorithm.hpp"
#include "FFmmAlgorithmThread.hpp"
#include "FFmmAlgorithmPeriodic.hpp"
#ifdef ScalFMM_USE_MPI
#include "../Utils/FMpi.hpp"
#include "FFmmAlgorithmThreadProc.hpp"
#include "FFmmAlgorithmThreadProcPeriodic.hpp"
#else
typedef int MPI_Comm;
#endif
/**
* @brief The FAlgorithmBuilder class
* This class manage the creation of an algorithm.
*/
class FAlgorithmBuilder {
public:
/** To give the informtion to the kernel */
struct SimulationProperties{
const int height;
const FPoint centerOfBox;
const FReal dimOfBox;
};
/** Get the simulation information from the properties (periodic or not etc.) */
static SimulationProperties BuildKernelSimulationProperties(const int realHeight, const FPoint realCenterOfBox, const FReal realDimOfBox,
const bool isPeriodic = false, const int inUpperLevel = 0){
if( isPeriodic == false ){
// Simply return the original data
SimulationProperties properties = {realHeight, realCenterOfBox, realDimOfBox};
return properties;
}
else{
// Get the new data
const int offsetRealTree(inUpperLevel + 3);
const FReal extendedBoxWidth = realDimOfBox * FReal(1<<offsetRealTree);
const FReal originalBoxWidth = realDimOfBox;
const FReal originalBoxWidthDiv2 = originalBoxWidth/2.0;
const FPoint originalBoxCenter = realCenterOfBox;
const FReal offset = extendedBoxWidth/2;
const FPoint extendedBoxCenter( originalBoxCenter.getX() - originalBoxWidthDiv2 + offset,
originalBoxCenter.getY() - originalBoxWidthDiv2 + offset,
originalBoxCenter.getZ() - originalBoxWidthDiv2 + offset);
const int extendedTreeHeight = realHeight + offsetRealTree;
SimulationProperties properties = {extendedTreeHeight, extendedBoxCenter, extendedBoxWidth};
return properties;
}
}
/**
* Build an algorithm using mpi/periodic or not.
*/
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
static FAbstractAlgorithm* BuildAlgorithm(OctreeClass*const tree, KernelClass*const kernel,
const MPI_Comm mpiComm = (MPI_Comm)0, const bool isPeriodic = false,
const int periodicUpperlevel = 0, const int inPeriodicDirections = AllDirs){
#ifdef ScalFMM_USE_MPI
if(isPeriodic == false){
return new FFmmAlgorithmThreadProc<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>(FMpi::FComm(mpiComm), tree, kernel);
}
else{
auto algo = new FFmmAlgorithmThreadProcPeriodic<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>(FMpi::FComm(mpiComm), tree, periodicUpperlevel, inPeriodicDirections);
algo->setKernel(kernel);
return algo;
}
#else
if(isPeriodic == false){
return new FFmmAlgorithmThread<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>(tree, kernel);
}
else{
auto algo = new FFmmAlgorithmPeriodic<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>(tree, periodicUpperlevel, inPeriodicDirections);
algo->setKernel(kernel);
return algo;
}
#endif
}
};
#endif // FALGORITHMBUILDER_HPP
#ifndef FCORECOMMON_HPP
#define FCORECOMMON_HPP
/**
* @brief The FFmmOperations enum
* To chose which operation has to be performed.
*/
enum FFmmOperations {
FFmmP2P = (1 << 0),
FFmmP2M = (1 << 1),
......@@ -15,4 +19,27 @@ enum FFmmOperations {
FFmmNearAndFarFields = (FFmmNearField|FFmmFarField)
};
/**
* @brief The FAbstractAlgorithm class
* Is an abstract algorithm to be able to use the FAlgorithmBuilder
* and execute from an abastrct pointer
*/
class FAbstractAlgorithm {
protected:
public:
virtual ~FAbstractAlgorithm(){
}
/** Execute all the fmm */
void execute(){
execute(FFmmNearAndFarFields);
}
/** Execute only some steps */
virtual void execute(const unsigned operationsToProceed) = 0;
};
#endif // FCORECOMMON_HPP
......@@ -40,7 +40,7 @@
* Of course this class does not deallocate pointer given in arguements.
*/
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
class FFmmAlgorithm : protected FAssertable{
class FFmmAlgorithm : protected FAssertable, public FAbstractAlgorithm {
OctreeClass* const tree; //< The octree to work on
KernelClass* const kernels; //< The kernels
......
......@@ -42,7 +42,7 @@
* Of course this class does not deallocate pointer given in arguments.
*/
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
class FFmmAlgorithmPeriodic : protected FAssertable{
class FFmmAlgorithmPeriodic : protected FAssertable, public FAbstractAlgorithm{
OctreeClass* const tree; //< The octree to work on
KernelClass* kernels; //< The kernels
......
......@@ -40,7 +40,7 @@
* Of course this class does not deallocate pointer given in arguements.
*/
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
class FFmmAlgorithmSectionTask : protected FAssertable{
class FFmmAlgorithmSectionTask : protected FAssertable, public FAbstractAlgorithm{
OctreeClass* const tree; //< The octree to work on
KernelClass** kernels; //< The kernels
......
......@@ -40,7 +40,7 @@
* Of course this class does not deallocate pointer given in arguements.
*/
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
class FFmmAlgorithmTask : protected FAssertable{
class FFmmAlgorithmTask : protected FAssertable, public FAbstractAlgorithm{
OctreeClass* const tree; //< The octree to work on
KernelClass** kernels; //< The kernels
......
......@@ -45,7 +45,7 @@
* When using this algorithm the P2P is thread safe.
*/
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
class FFmmAlgorithmThread : protected FAssertable{
class FFmmAlgorithmThread : protected FAssertable, public FAbstractAlgorithm{
OctreeClass* const tree; //< The octree to work on
KernelClass** kernels; //< The kernels
......
......@@ -58,7 +58,7 @@
* ./Tests/testFmmAlgorithmProc ../Data/testLoaderSmall.fma.tmp
*/
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
class FFmmAlgorithmThreadProc : protected FAssertable {
class FFmmAlgorithmThreadProc : protected FAssertable , public FAbstractAlgorithm {
static const int MaxSizePerCell = 1024;
......
......@@ -58,7 +58,7 @@
* ./Tests/testFmmAlgorithmProc ../Data/testLoaderSmall.fma.tmp
*/
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
class FFmmAlgorithmThreadProcPeriodic : protected FAssertable {
class FFmmAlgorithmThreadProcPeriodic : protected FAssertable, public FAbstractAlgorithm {
static const int MaxSizePerCell = 2048;
......
......@@ -45,7 +45,7 @@
* You should not write on sources in the P2P method!
*/
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
class FFmmAlgorithmThreadTsm : protected FAssertable{
class FFmmAlgorithmThreadTsm : protected FAssertable, public FAbstractAlgorithm{
OctreeClass* const tree; //< The octree to work on
KernelClass** kernels; //< The kernels
......
......@@ -39,7 +39,7 @@
* The differences with FmmAlgorithm is that it used target source model.
*/
template<class OctreeClass, class CellClass, class ContainerClass, class KernelClass, class LeafClass>
class FFmmAlgorithmTsm : protected FAssertable{
class FFmmAlgorithmTsm : protected FAssertable, public FAbstractAlgorithm{
OctreeClass* const tree; //< The octree to work on
KernelClass* const kernels; //< The kernels
......
......@@ -20,6 +20,10 @@
// Periodic condition definition
///////////////////////////////////////////////////////
/**
* @brief The PeriodicCondition enum
* To be able to chose the direction of the periodicity.
*/
enum PeriodicCondition {
DirNone = 0,
......@@ -37,6 +41,12 @@ enum PeriodicCondition {
AllDirs = (DirX | DirY | DirZ)
};
/**
* @brief TestPeriodicCondition
* @param conditions
* @param testConditions
* @return true if the direction is in the condition
*/
inline bool TestPeriodicCondition(const int conditions, const PeriodicCondition testConditions) {
return (conditions & testConditions) == testConditions;
}
......
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
// This software is a computer program whose purpose is to compute the FMM.
//
// This software is governed by the CeCILL-C and LGPL licenses and
// abiding by the rules of distribution of free software.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public and CeCILL-C Licenses for more details.
// "http://www.cecill.info".
// "http://www.gnu.org/licenses".
// ===================================================================================
#include "FUTester.hpp"
#include "../Src/Core/FAlgorithmBuilder.hpp"
#include "../../Src/Containers/FOctree.hpp"
#include "../../Src/Components/FSimpleLeaf.hpp"
#include "../../Src/Components/FTestParticleContainer.hpp"
#include "../../Src/Components/FTestCell.hpp"
#include "../../Src/Components/FTestKernels.hpp"
#include "../../Src/Components/FBasicKernels.hpp"
/** This class test the core algorithm builder */
class TestBuilder : public FUTester<TestBuilder> {
void Test(){
typedef FTestCell CellClass;
typedef FTestParticleContainer ContainerClass;
typedef FSimpleLeaf< ContainerClass > LeafClass;
typedef FOctree< CellClass, ContainerClass , LeafClass > OctreeClass;
typedef FTestKernels< CellClass, ContainerClass > KernelClass;
const int height = 5;
const FReal dim = 1.0;
const FPoint center(0.0,0.0,0.0);
OctreeClass tree(height, 2, dim, center);
KernelClass kernel;
{
FAlgorithmBuilder::SimulationProperties properties = FAlgorithmBuilder::BuildKernelSimulationProperties(height,center,dim,false);
uassert(properties.centerOfBox.getX() == center.getX() && properties.centerOfBox.getY() == center.getY() &&
properties.centerOfBox.getZ() == center.getZ() );
uassert(properties.dimOfBox == dim);
uassert(properties.height == height);
FAbstractAlgorithm*const algo = FAlgorithmBuilder::BuildAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>(&tree, &kernel, 0, false);
#ifndef ScalFMM_USE_MPI
uassert(dynamic_cast<FFmmAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>*>(algo) != 0 ||
dynamic_cast<FFmmAlgorithmThread<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>*>(algo) != 0);
#else
uassert(dynamic_cast<FFmmAlgorithmThreadProc<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>*>(algo) != 0);
#endif
delete algo;
}
{
FAlgorithmBuilder::SimulationProperties properties = FAlgorithmBuilder::BuildKernelSimulationProperties(height,center,dim,true);
uassert(properties.dimOfBox != dim);
uassert(properties.height != height);
FAbstractAlgorithm*const algo = FAlgorithmBuilder::BuildAlgorithm<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>(&tree, &kernel, 0, true);
#ifndef ScalFMM_USE_MPI
uassert(dynamic_cast<FFmmAlgorithmPeriodic<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>*>(algo) != 0 );
#else
uassert(dynamic_cast<FFmmAlgorithmThreadProcPeriodic<OctreeClass, CellClass, ContainerClass, KernelClass, LeafClass>*>(algo) != 0);
#endif
delete algo;
}
}
// set test
void SetTests(){
AddTest(&TestBuilder::Test,"Test Algo Creation");
}
};
// You must do this
TestClass(TestBuilder)
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