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

Revision 152:2a8af582165e, 5.3 KB (checked in by Andreas Schaefer <gentryx@…>, 14 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)

Line 
1#include <libgeodecomp/config.h>
2#ifdef LIBGEODECOMP_FEATURE_MPI
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;
25    const static int ENDLESS = -1;
26
27    class Link
28    {
29    public:
30        typedef typename GRID_TYPE::CellType CellType;
31
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.
38        inline Link(
39            const Region<DIM>& _region,
40            const int& _tag,
41            MPI::Comm *communicator = &MPI::COMM_WORLD) :
42            lastNanoStep(0),
43            stride(1),
44            mpiLayer(communicator),
45            region(_region),
46            buffer(_region.size()),
47            tag(_tag)
48        {}
49
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
61        inline void wait()
62        {
63            mpiLayer.wait(tag);
64        }
65
66        inline void cancel()
67        {
68            mpiLayer.cancelAll();
69        }
70
71    protected:
72        long lastNanoStep;
73        long stride;
74        MPILayer mpiLayer;
75        Region<DIM> region;
76        SuperVector<CellType> buffer;
77        int tag;
78    };
79
80    class Accepter : 
81        public Link,
82        public PatchAccepter<GRID_TYPE>
83    {
84    public:
85        inline Accepter(
86            const Region<DIM>& _region,
87            const int& _dest,
88            const int& _tag,
89            const MPI::Datatype& _cellMPIDatatype,
90            MPI::Comm *communicator = &MPI::COMM_WORLD) : 
91            Link(_region, _tag, communicator),
92            dest(_dest),
93            cellMPIDatatype(_cellMPIDatatype)
94
95        {}
96
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
103        virtual void put(
104            const GRID_TYPE& grid, 
105            const Region<DIM>& /*validRegion*/, 
106            const long& nanoStep) 
107        {
108            if (!this->checkNanoStepPut(nanoStep))
109                return;
110
111            this->wait();
112            GridVecConv::gridToVector(grid, &this->buffer, this->region);
113            this->mpiLayer.send(
114                &this->buffer[0], dest, this->buffer.size(), this->tag, cellMPIDatatype);
115            long nextNanoStep = this->requestedNanoSteps.min() + this->stride;
116            if ((this->lastNanoStep == ENDLESS) || 
117                (nextNanoStep < this->lastNanoStep))
118                this->requestedNanoSteps << nextNanoStep;
119            this->requestedNanoSteps.erase_min();
120        }
121
122    private:
123        int dest;
124        MPI::Datatype cellMPIDatatype;
125    };
126
127    class Provider : 
128        public Link,
129        public PatchProvider<GRID_TYPE>
130    {
131    public:
132        inline Provider(
133            const Region<DIM>& _region,
134            const int& _source,
135            const int& _tag,
136            const MPI::Datatype& _cellMPIDatatype,
137            MPI::Comm *communicator = &MPI::COMM_WORLD) : 
138            Link(_region, _tag, communicator),
139            source(_source),
140            cellMPIDatatype(_cellMPIDatatype)
141        {}
142
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
149        virtual void get(
150            GRID_TYPE *grid, 
151            const Region<DIM>& patchableRegion, 
152            const long& nanoStep,
153            const bool& remove=true) 
154        {
155            this->checkNanoStepGet(nanoStep);
156            this->wait();
157            GridVecConv::vectorToGrid(this->buffer, grid, this->region);
158
159            long nextNanoStep = this->storedNanoSteps.min() + this->stride;
160            if ((this->lastNanoStep == ENDLESS) || 
161                (nextNanoStep < this->lastNanoStep))
162                recv(nextNanoStep);
163            // fixme: extract method for this
164            this->storedNanoSteps.erase_min();
165        }
166
167        void recv(const long& nanoStep)
168        {
169            this->storedNanoSteps << nanoStep;
170            this->mpiLayer.recv(&this->buffer[0], source, this->buffer.size(), this->tag, cellMPIDatatype);
171        }
172
173    private:
174        int source;
175        MPI::Datatype cellMPIDatatype;
176    };
177
178};
179
180}
181}
182
183#endif
184#endif
Note: See TracBrowser for help on using the browser.