FCoreCommon.hpp 4.81 KB
Newer Older
1
// See LICENCE file at project root
2 3 4
#ifndef FCORECOMMON_HPP
#define FCORECOMMON_HPP

5 6 7
#include <vector>
#include "Utils/FGlobal.hpp"
#include "Utils/FAssert.hpp"
8

9 10 11 12
/**
 * @brief The FFmmOperations enum
 * To chose which operation has to be performed.
 */
13
enum FFmmOperations {
14 15
    FFmmP2P   = (1 << 0),
    FFmmP2M  = (1 << 1),
16
    FFmmM2M = (1 << 2),
17 18 19
    FFmmM2L  = (1 << 3),
    FFmmL2L  = (1 << 4),
    FFmmL2P  = (1 << 5),
20 21
    FFmmP2L  = (1 << 6),
    FFmmM2P  = (1 << 7),
22
//
23
    FFmmNearField = FFmmP2P,
24
    FFmmFarField  = (FFmmP2M|FFmmM2M|FFmmM2L|FFmmL2L|FFmmL2P|FFmmM2P|FFmmP2L),
25
//
26 27
    FFmmNearAndFarFields = (FFmmNearField|FFmmFarField)
};
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
std::string FFmmOperations_string(/*enum FFmmOperations*/ const unsigned int & value){

 //if (value & FFmmNearAndFarFields) return std::string("FFmmNearAndFarFields") ;
 //if (value & FFmmFarField) return std::string("FFmmFarField") ;
 //if (value & FFmmNearField) return std::string("FFmmNearField" );
  std::string op("");
  if (value & FFmmP2P)
    op += " FFmmP2P |";
  if (value & FFmmP2M)
    op += " FFmmP2M |";
  if (value & FFmmM2M)
    op += " FFmmM2M |";
  if (value & FFmmM2L)
    op += " FFmmM2L |";
  if (value & FFmmL2L)
    op += " FFmmL2L |";
  if (value & FFmmL2P)
    op += " FFmmL2P |";
  op.erase(op.size()-2,op.size()-1);
  return op;
};
49

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
/**
 * \brief Algorithm interface
 *
 * All algorithms should implement this interface.
 */
struct FAlgorithmInterface {

    /** \brief Destructor */
    virtual ~FAlgorithmInterface() {}

    /** \brief Get algorithm short description
     *
     * \return A short string identifying the algorithm implementation
     */
    virtual std::string name() const {
        return "error: unnamed algorithm";
    }

    /** \brief Get algorithm environment description
     *
     * Easily parsable string describing the algorithm settings and environment
     * (thread count, specific settings, etc).
     *
     * \return String describing algorithm settings
     */
    virtual std::string description() const {
        return "error: description not implemented";
    }

    /** \brief Run specific steps of the algorithm
     *
     * \param operations Specifies the algorithm operations to run, see
     * FFmmOperations.
     */
    virtual void execute(const unsigned int operations) = 0;

    /** \brief Run the algorithm */
    virtual void execute() {
        this->execute(FFmmNearAndFarFields);
    }
};





96
/**
97 98 99 100
 * \brief Base class of algorithms
 *
 * This class is an abstract algorithm to be able to use the FAlgorithmBuilder
 * and execute from an abstract pointer.
101
 */
102
class FAbstractAlgorithm : public FAlgorithmInterface {
103
protected:
Quentin Khan's avatar
Quentin Khan committed
104 105 106 107

    int upperWorkingLevel; ///< Where to start the work
    int lowerWorkingLevel; ///< Where to end the work (exclusive)
    int nbLevelsInTree;    ///< Height of the tree
108 109

    void setNbLevelsInTree(const int inNbLevelsInTree){
110
        nbLevelsInTree    = inNbLevelsInTree;
111 112 113
        lowerWorkingLevel = nbLevelsInTree;
    }

114 115 116 117
    void validateLevels() const {
        FAssertLF(FAbstractAlgorithm::upperWorkingLevel <= FAbstractAlgorithm::lowerWorkingLevel);
        FAssertLF(2 <= FAbstractAlgorithm::upperWorkingLevel);
    }
118 119
    virtual void executeCore(const unsigned operationsToProceed) = 0;

120
public:
121 122 123 124
    FAbstractAlgorithm()
        : upperWorkingLevel(2), lowerWorkingLevel(0), nbLevelsInTree(-1){
    }

125 126 127
    virtual ~FAbstractAlgorithm(){
    }

Quentin Khan's avatar
Quentin Khan committed
128
    /** \brief Execute the whole fmm for given levels. */
129 130 131
    virtual void execute(const int inUpperWorkingLevel, const int inLowerWorkingLevel) final {
        upperWorkingLevel = inUpperWorkingLevel;
        lowerWorkingLevel = inLowerWorkingLevel;
132
        validateLevels();
133 134 135
        executeCore(FFmmNearAndFarFields);
    }

Quentin Khan's avatar
Quentin Khan committed
136
    /** \brief Execute only some FMM operations for given levels. */
137 138 139
    virtual void execute(const unsigned operationsToProceed, const int inUpperWorkingLevel, const int inLowerWorkingLevel) final {
        upperWorkingLevel = inUpperWorkingLevel;
        lowerWorkingLevel = inLowerWorkingLevel;
140
        validateLevels();
141
        executeCore(operationsToProceed);
142 143
    }

144 145
    using FAlgorithmInterface::execute;

Quentin Khan's avatar
Quentin Khan committed
146
    /** \brief Execute only some steps. */
147
    virtual void execute(const unsigned operationsToProceed) override final {
148 149
        upperWorkingLevel = 2;
        lowerWorkingLevel = nbLevelsInTree;
150
        validateLevels();
151 152
        executeCore(operationsToProceed);
    }
153 154 155

    /// Build and dill vector of the  MortonIndex Distribution at Leaf level
    ///  p = mpi process id then
156 157 158 159 160 161 162
    ///  [mortonLeafDistribution[2*p], mortonLeafDistribution[2*p+1]  is the morton index shared by process p
    virtual void getMortonLeafDistribution(std::vector<MortonIndex> & mortonLeafDistribution) {
      mortonLeafDistribution.resize(2) ;
      mortonLeafDistribution[0] = 0 ;
      mortonLeafDistribution[1] = 8 << (nbLevelsInTree-1) ;

    };
163 164 165 166 167
};




168
#endif // FCORECOMMON_HPP