root/src/parallelization/hiparsimulator/patchlink.h @ 152:2a8af582165e

Revision 152:2a8af582165e, 5.3 KB (checked in by Andreas Schaefer <gentryx@…>, 15 months ago)

removed default arguments from PatchLink? contructors to solve missing method errors in 3rd party MD code (even though the methods in question weren't actually called… GCC I hate you)

RevLine 
[117]1#include <libgeodecomp/config.h>
2#ifdef LIBGEODECOMP_FEATURE_MPI
[14]3#ifndef _libgeodecomp_parallelization_hiparsimulator_patchlink_h_
4#define _libgeodecomp_parallelization_hiparsimulator_patchlink_h_
5
6#include <deque>
7#include <libgeodecomp/mpilayer/mpilayer.h>
8#include <libgeodecomp/parallelization/hiparsimulator/patchaccepter.h>
9#include <libgeodecomp/parallelization/hiparsimulator/patchprovider.h>
10
11namespace LibGeoDecomp {
12namespace HiParSimulator {
13
14/**
15 * PatchLink encapsulates the transmission of patches to and from
16 * remote processes. PatchLink::Accepter takes the patches from a
17 * Stepper hands them on to MPI, while PatchLink::Provider will receive
18 * the patches from the net and provide then to a Stepper.
19 */
20template<class GRID_TYPE>
21class PatchLink
22{
23public:
24    const static int DIM = GRID_TYPE::DIM;
[123]25    const static int ENDLESS = -1;
[14]26
27    class Link
28    {
29    public:
[15]30        typedef typename GRID_TYPE::CellType CellType;
31
[117]32        // fixme: there may be multiple PatchLinks connecting any two
33        // nodes. Since MPI matches messages by node, datatype and tag
34        // and the first two of these three will be identical, we need
35        // to make sure that the tag differs. We could use the "level"
36        // of the UpdateGroup in the hierarchy for this or some kind
37        // of registry.
[14]38        inline Link(
[15]39            const Region<DIM>& _region,
[123]40            const int& _tag,
41            MPI::Comm *communicator = &MPI::COMM_WORLD) :
[36]42            lastNanoStep(0),
43            stride(1),
[123]44            mpiLayer(communicator),
[15]45            region(_region),
46            buffer(_region.size()),
[14]47            tag(_tag)
48        {}
49
[36]50        virtual ~Link()
51        {
52            this->wait();
53        }
54
55        virtual void charge(const long& next, const long& last, const long& newStride) 
56        {         
57            lastNanoStep = last;
58            stride = newStride;
59        }
60
[14]61        inline void wait()
62        {
[36]63            mpiLayer.wait(tag);
[14]64        }
65
[123]66        inline void cancel()
67        {
68            mpiLayer.cancelAll();
69        }
70
[14]71    protected:
[36]72        long lastNanoStep;
73        long stride;
74        MPILayer mpiLayer;
[14]75        Region<DIM> region;
[15]76        SuperVector<CellType> buffer;
[14]77        int tag;
78    };
79
80    class Accepter : 
81        public Link,
82        public PatchAccepter<GRID_TYPE>
83    {
84    public:
[15]85        inline Accepter(
[152]86            const Region<DIM>& _region,
87            const int& _dest,
88            const int& _tag,
89            const MPI::Datatype& _cellMPIDatatype,
[148]90            MPI::Comm *communicator = &MPI::COMM_WORLD) : 
91            Link(_region, _tag, communicator),
92            dest(_dest),
93            cellMPIDatatype(_cellMPIDatatype)
94
[15]95        {}
96
[36]97        virtual void charge(const long& next, const long& last, const long& newStride) 
98        {
99            Link::charge(next, last, newStride);
100            this->pushRequest(next);
101        }
102
[14]103        virtual void put(
104            const GRID_TYPE& grid, 
105            const Region<DIM>& /*validRegion*/, 
[15]106            const long& nanoStep) 
[14]107        {
108            if (!this->checkNanoStepPut(nanoStep))
109                return;
[15]110
[123]111            this->wait();
[15]112            GridVecConv::gridToVector(grid, &this->buffer, this->region);
[36]113            this->mpiLayer.send(
[148]114                &this->buffer[0], dest, this->buffer.size(), this->tag, cellMPIDatatype);
[36]115            long nextNanoStep = this->requestedNanoSteps.min() + this->stride;
[123]116            if ((this->lastNanoStep == ENDLESS) || 
117                (nextNanoStep < this->lastNanoStep))
[36]118                this->requestedNanoSteps << nextNanoStep;
119            this->requestedNanoSteps.erase_min();
[14]120        }
[15]121
122    private:
123        int dest;
[148]124        MPI::Datatype cellMPIDatatype;
[14]125    };
126
127    class Provider : 
128        public Link,
129        public PatchProvider<GRID_TYPE>
130    {
[15]131    public:
132        inline Provider(
[152]133            const Region<DIM>& _region,
134            const int& _source,
135            const int& _tag,
136            const MPI::Datatype& _cellMPIDatatype,
[148]137            MPI::Comm *communicator = &MPI::COMM_WORLD) : 
138            Link(_region, _tag, communicator),
139            source(_source),
140            cellMPIDatatype(_cellMPIDatatype)
[15]141        {}
142
[36]143        virtual void charge(const long& next, const long& last, const long& newStride) 
144        {
145            Link::charge(next, last, newStride);
146            recv(next);
147        }
148
[14]149        virtual void get(
[17]150            GRID_TYPE *grid, 
[14]151            const Region<DIM>& patchableRegion, 
[15]152            const long& nanoStep,
[14]153            const bool& remove=true) 
154        {
[15]155            this->checkNanoStepGet(nanoStep);
[36]156            this->wait();
[17]157            GridVecConv::vectorToGrid(this->buffer, grid, this->region);
[36]158
159            long nextNanoStep = this->storedNanoSteps.min() + this->stride;
[123]160            if ((this->lastNanoStep == ENDLESS) || 
161                (nextNanoStep < this->lastNanoStep))
[36]162                recv(nextNanoStep);
[142]163            // fixme: extract method for this
[36]164            this->storedNanoSteps.erase_min();
[14]165        }
[15]166
167        void recv(const long& nanoStep)
168        {
[36]169            this->storedNanoSteps << nanoStep;
[148]170            this->mpiLayer.recv(&this->buffer[0], source, this->buffer.size(), this->tag, cellMPIDatatype);
[15]171        }
172
173    private:
174        int source;
[148]175        MPI::Datatype cellMPIDatatype;
[14]176    };
177
178};
179
180}
181}
[117]182
[14]183#endif
[117]184#endif
Note: See TracBrowser for help on using the browser.