1 #ifndef LIBGEODECOMP_PARALLELIZATION_HIPARSIMULATOR_STEERERADAPTER_H
2 #define LIBGEODECOMP_PARALLELIZATION_HIPARSIMULATOR_STEERERADAPTER_H
3 
4 #include <libgeodecomp/io/steerer.h>
5 #include <libgeodecomp/storage/patchprovider.h>
6 
7 namespace LibGeoDecomp {
8 namespace HiParSimulator {
9 
10 template<typename GRID_TYPE, typename CELL_TYPE>
11 class SteererAdapter : public PatchProvider<GRID_TYPE>
12 {
13 public:
14     typedef typename APITraits::SelectTopology<CELL_TYPE>::Value Topology;
15 
16     static const unsigned NANO_STEPS = APITraits::SelectNanoSteps<CELL_TYPE>::VALUE;
17     static const int DIM = Topology::DIM;
18 
19     using PatchProvider<GRID_TYPE>::storedNanoSteps;
20 
SteererAdapter(boost::shared_ptr<Steerer<CELL_TYPE>> steerer,const std::size_t firstStep,const std::size_t lastStep,Coord<Topology::DIM> globalGridDimensions,std::size_t rank,bool lastCall)21     SteererAdapter(
22         boost::shared_ptr<Steerer<CELL_TYPE> > steerer,
23         const std::size_t firstStep,
24         const std::size_t lastStep,
25         Coord<Topology::DIM> globalGridDimensions,
26         std::size_t rank,
27         bool lastCall) :
28         steerer(steerer),
29         firstNanoStep(firstStep * NANO_STEPS),
30         lastNanoStep(lastStep   * NANO_STEPS),
31         rank(rank),
32         lastCall(lastCall),
33         globalGridDimensions(globalGridDimensions)
34     {
35         std::size_t firstRegularEventStep = firstStep;
36         std::size_t period = steerer->getPeriod();
37         std::size_t offset = firstStep % period;
38         firstRegularEventStep = firstStep + period - offset;
39 
40         // fixme: make tests work with the following line enabled (ATM steerers never get the STEERER_INITIALIZED event from us if firstStep is not a multiple of period()
41         // storedNanoSteps << firstNanoStep;
42         storedNanoSteps << firstRegularEventStep * NANO_STEPS;
43         storedNanoSteps << lastNanoStep;
44     }
45 
setRegion(const Region<DIM> & region)46     virtual void setRegion(const Region<DIM>& region)
47     {
48         steerer->setRegion(region);
49     }
50 
51     virtual void get(
52         GRID_TYPE *destinationGrid,
53         const Region<DIM>& patchableRegion,
54         const std::size_t globalNanoStep,
55         const bool remove = true)
56     {
57         std::size_t nanoStep = globalNanoStep % NANO_STEPS;
58         if (nanoStep != 0) {
59             throw std::logic_error(
60                 "SteererAdapter expects to be called only at the beginning of a time step (nanoStep == 0)");
61         }
62 
63         std::size_t step = globalNanoStep / NANO_STEPS;
64 
65         SteererEvent event = STEERER_NEXT_STEP;
66         if (globalNanoStep == firstNanoStep) {
67             event = STEERER_INITIALIZED;
68         }
69         if (globalNanoStep == lastNanoStep) {
70             event = STEERER_ALL_DONE;
71         }
72 
73         if ((event == STEERER_NEXT_STEP) && (step % steerer->getPeriod() != 0)) {
74             throw std::logic_error("SteererAdapter called at wrong step (got " + StringOps::itoa(step) +
75                                    " but expected multiple of " + StringOps::itoa(steerer->getPeriod()));
76         }
77 
78         typename Steerer<CELL_TYPE>::SteererFeedback feedback;
79 
80         steerer->nextStep(
81             destinationGrid,
82             patchableRegion,
83             globalGridDimensions,
84             step,
85             event,
86             rank,
87             lastCall,
88             &feedback);
89 
90         if ((event != STEERER_INITIALIZED) && remove) {
91             storedNanoSteps.erase(globalNanoStep);
92             storedNanoSteps << globalNanoStep + NANO_STEPS * steerer->getPeriod();
93         }
94 
95         // fixme: apply SteererFeedback!
96     }
97 
98 private:
99     boost::shared_ptr<Steerer<CELL_TYPE> > steerer;
100     std::size_t firstNanoStep;
101     std::size_t lastNanoStep;
102     std::size_t rank;
103     bool lastCall;
104     Coord<Topology::DIM> globalGridDimensions;
105 
106 };
107 
108 }
109 }
110 
111 #endif
112