Une nouvelle version du portail de gestion des comptes externes sera mise en production lundi 09 août. Elle permettra d'allonger la validité d'un compte externe jusqu'à 3 ans. Pour plus de détails sur cette version consulter : https://doc-si.inria.fr/x/FCeS

FEqualize.hpp 4.38 KB
Newer Older
1
// ===================================================================================
2 3 4 5
// Copyright ScalFmm 2016 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.
6
//
7
// This software is governed by the CeCILL-C and LGPL licenses and
8
// abiding by the rules of distribution of free software.
9 10 11
// An extension to the license is given to allow static linking of scalfmm
// inside a proprietary application (no matter its license).
// See the main license file for more details.
12 13 14 15
//
// 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
16 17 18
// GNU General Public and CeCILL-C Licenses for more details.
// "http://www.cecill.info".
// "http://www.gnu.org/licenses".
19
// ===================================================================================
20 21 22 23 24 25 26
#ifndef FEQUALIZE_HPP
#define FEQUALIZE_HPP


#include <iostream>
#include <vector>

BRAMAS Berenger's avatar
BRAMAS Berenger committed
27 28 29
#include "../Utils/FAssert.hpp"
#include "../Utils/FMath.hpp"

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
/**
 * This class proposes a method to distribute an interval own by a worker
 * to some others.
 * It returns a vector of Package which tell what interval to sent to which process.
 * The algorithm works only if the objectives (the intervals that the workers shoud obtain
 * are exclusive and given in ascendant order).
 * Also each of the element from the current interval must belong to someone!
 * Finally the current worker is included in the Package if its objective interval
 * is related to its starting interval.
 */
class FEqualize {
    // Just return the min
    static size_t Min(const size_t v1, const size_t v2){
        return v1 < v2 ? v1 : v2;
    }

public:
    /** To represent an interval to proceed */
    struct Package{
        int idProc;
        size_t elementFrom;
        size_t elementTo;
    };


    /**
     * To know what to send to who.
     * @param myCurrentInterval current process interval
58
     * @param allObjectives the intervals that each process should have (in ascendant order, exclusive)
59 60 61 62 63 64
     * @return the package that the current worker should sent to others
     */
    static std::vector<Package> GetPackToSend(const std::pair<size_t, size_t> myCurrentInterval,
                                              const std::vector< std::pair<size_t,size_t> >& allObjectives){
        std::vector<Package> packToSend;

PIACIBELLO Cyrille's avatar
PIACIBELLO Cyrille committed
65
        unsigned int idxProc = 0;
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

        // Find the first proc to send to
        while( idxProc != allObjectives.size()
               && allObjectives[idxProc].second < myCurrentInterval.first){
            idxProc += 1;
        }

        // We will from the first element for sure
        size_t currentElement = 0;

        // Check each proc to send to
        while( idxProc != allObjectives.size()
               && allObjectives[idxProc].first < myCurrentInterval.second){
            Package pack;
            pack.idProc = idxProc;
            // The current element must start where the previous one end
BRAMAS Berenger's avatar
BRAMAS Berenger committed
82 83
            FAssertLF(allObjectives[idxProc].first < myCurrentInterval.first
                      || currentElement == allObjectives[idxProc].first - myCurrentInterval.first );
84 85 86 87
            pack.elementFrom = currentElement;
            pack.elementTo   = Min(allObjectives[idxProc].second , myCurrentInterval.second) - myCurrentInterval.first;
            // Next time give from the previous end
            currentElement   = pack.elementTo;
88 89 90 91

            if(pack.elementTo - pack.elementFrom != 0){
                packToSend.push_back(pack);
            }
92 93 94
            // Progress
            idxProc += 1;
        }
BRAMAS Berenger's avatar
BRAMAS Berenger committed
95
        FAssertLF(currentElement == myCurrentInterval.second - myCurrentInterval.first);
96 97 98

        return packToSend;
    }
99 100 101 102 103 104 105 106 107 108 109 110


    /**
     * To know what to recv from who.
     * @param myObjectiveInterval Interval I should have
     * @param allCurrentIntervals the intevals that each process currently contains
     * @return the package that the current worker should recv from others
     */
    static std::vector<Package> GetPackToRecv(const std::pair<size_t, size_t> myObjectiveInterval,
                                              const std::vector< std::pair<size_t,size_t> >& allCurrentIntervals){
        return GetPackToSend(myObjectiveInterval,allCurrentIntervals);
    }
111 112 113
};

#endif // FEQUALIZE_HPP