| 1 | #include <libgeodecomp/config.h> |
|---|
| 2 | #ifdef LIBGEODECOMP_FEATURE_MPI |
|---|
| 3 | #ifndef _libgeodecomp_parallelization_hiparsimulator_updategroup_h_ |
|---|
| 4 | #define _libgeodecomp_parallelization_hiparsimulator_updategroup_h_ |
|---|
| 5 | |
|---|
| 6 | #include <libgeodecomp/io/initializer.h> |
|---|
| 7 | #include <libgeodecomp/misc/displacedgrid.h> |
|---|
| 8 | #include <libgeodecomp/misc/region.h> |
|---|
| 9 | #include <libgeodecomp/mpilayer/mpilayer.h> |
|---|
| 10 | #include <libgeodecomp/parallelization/hiparsimulator/intersectingregionaccumulator.h> |
|---|
| 11 | #include <libgeodecomp/parallelization/hiparsimulator/stepper.h> |
|---|
| 12 | #include <libgeodecomp/parallelization/hiparsimulator/partitionmanager.h> |
|---|
| 13 | #include <libgeodecomp/parallelization/hiparsimulator/patchaccepter.h> |
|---|
| 14 | #include <libgeodecomp/parallelization/hiparsimulator/patchprovider.h> |
|---|
| 15 | #include <libgeodecomp/parallelization/hiparsimulator/patchlink.h> |
|---|
| 16 | #include <libgeodecomp/parallelization/hiparsimulator/vanillaregionaccumulator.h> |
|---|
| 17 | #include <libgeodecomp/parallelization/hiparsimulator/vanillastepper.h> |
|---|
| 18 | |
|---|
| 19 | namespace LibGeoDecomp { |
|---|
| 20 | namespace HiParSimulator { |
|---|
| 21 | |
|---|
| 22 | template<class CELL_TYPE, class PARTITION, class STEPPER=VanillaStepper<CELL_TYPE> > |
|---|
| 23 | class UpdateGroup |
|---|
| 24 | { |
|---|
| 25 | friend class UpdateGroupPrototypeTest; |
|---|
| 26 | friend class UpdateGroupTest; |
|---|
| 27 | public: |
|---|
| 28 | const static int DIM = CELL_TYPE::Topology::DIMENSIONS; |
|---|
| 29 | typedef DisplacedGrid< |
|---|
| 30 | CELL_TYPE, typename CELL_TYPE::Topology, true> GridType; |
|---|
| 31 | typedef typename Stepper<CELL_TYPE>::PatchType PatchType; |
|---|
| 32 | typedef boost::shared_ptr<PatchProvider<GridType> > PatchProviderPtr; |
|---|
| 33 | typedef boost::shared_ptr<PatchAccepter<GridType> > PatchAccepterPtr; |
|---|
| 34 | typedef boost::shared_ptr<typename PatchLink<GridType>::Link> PatchLinkPtr; |
|---|
| 35 | typedef PartitionManager<DIM, typename CELL_TYPE::Topology> MyPartitionManager; |
|---|
| 36 | typedef typename MyPartitionManager::RegionVecMap RegionVecMap; |
|---|
| 37 | |
|---|
| 38 | UpdateGroup( |
|---|
| 39 | const PARTITION& _partition, |
|---|
| 40 | const SuperVector<long>& _weights, |
|---|
| 41 | const unsigned& _offset, |
|---|
| 42 | const CoordBox<DIM>& box, |
|---|
| 43 | const unsigned& _ghostZoneWidth, |
|---|
| 44 | Initializer<CELL_TYPE> *_initializer, |
|---|
| 45 | MPI::Comm *communicator = &MPI::COMM_WORLD) : |
|---|
| 46 | partition(_partition), |
|---|
| 47 | weights(_weights), |
|---|
| 48 | offset(_offset), |
|---|
| 49 | ghostZoneWidth(_ghostZoneWidth), |
|---|
| 50 | initializer(_initializer), |
|---|
| 51 | mpiLayer(communicator), |
|---|
| 52 | rank(mpiLayer.rank()) |
|---|
| 53 | { |
|---|
| 54 | partitionManager.reset(new MyPartitionManager()); |
|---|
| 55 | partitionManager->resetRegions( |
|---|
| 56 | box, |
|---|
| 57 | new VanillaRegionAccumulator<PARTITION>( |
|---|
| 58 | partition, |
|---|
| 59 | offset, |
|---|
| 60 | weights), |
|---|
| 61 | rank, |
|---|
| 62 | ghostZoneWidth); |
|---|
| 63 | SuperVector<CoordBox<DIM> > boundingBoxes(mpiLayer.size()); |
|---|
| 64 | CoordBox<DIM> ownBoundingBox(partitionManager->ownRegion().boundingBox()); |
|---|
| 65 | mpiLayer.allGather(ownBoundingBox, &boundingBoxes); |
|---|
| 66 | partitionManager->resetGhostZones(boundingBoxes); |
|---|
| 67 | |
|---|
| 68 | stepper.reset(new STEPPER( partitionManager, initializer)); |
|---|
| 69 | |
|---|
| 70 | RegionVecMap map = partitionManager->getInnerGhostZoneFragments(); |
|---|
| 71 | for (typename RegionVecMap::iterator i = map.begin(); i != map.end(); ++i) { |
|---|
| 72 | if (!i->second.back().empty()) { |
|---|
| 73 | boost::shared_ptr<typename PatchLink<GridType>::Accepter> link( |
|---|
| 74 | new typename PatchLink<GridType>::Accepter( |
|---|
| 75 | i->second.back(), i->first)); |
|---|
| 76 | addPatchAccepter(link, Stepper<CELL_TYPE>::GHOST); |
|---|
| 77 | patchLinks << link; |
|---|
| 78 | } |
|---|
| 79 | } |
|---|
| 80 | |
|---|
| 81 | map = partitionManager->getOuterGhostZoneFragments(); |
|---|
| 82 | for (typename RegionVecMap::iterator i = map.begin(); i != map.end(); ++i) { |
|---|
| 83 | if (!i->second.back().empty()) { |
|---|
| 84 | boost::shared_ptr<typename PatchLink<GridType>::Provider> link( |
|---|
| 85 | new typename PatchLink<GridType>::Provider( |
|---|
| 86 | i->second.back(), i->first)); |
|---|
| 87 | addPatchProvider(link, Stepper<CELL_TYPE>::GHOST); |
|---|
| 88 | patchLinks << link; |
|---|
| 89 | } |
|---|
| 90 | } |
|---|
| 91 | |
|---|
| 92 | // fixme: recharge regularly? |
|---|
| 93 | // for (int i = 0; i < patchLinks.size(); ++i) { |
|---|
| 94 | // patchLinks[i]->charge(ghostZoneWidth, 2 * ghostZoneWidth, ghostZoneWidth); |
|---|
| 95 | // } |
|---|
| 96 | } |
|---|
| 97 | |
|---|
| 98 | void addPatchProvider( |
|---|
| 99 | const PatchProviderPtr& ghostZonePatchProvider, |
|---|
| 100 | const PatchType& patchType) |
|---|
| 101 | { |
|---|
| 102 | stepper->addPatchProvider(ghostZonePatchProvider, patchType); |
|---|
| 103 | } |
|---|
| 104 | |
|---|
| 105 | void addPatchAccepter( |
|---|
| 106 | const PatchAccepterPtr& ghostZonePatchAccepter, |
|---|
| 107 | const PatchType& patchType) |
|---|
| 108 | { |
|---|
| 109 | stepper->addPatchAccepter(ghostZonePatchAccepter, patchType); |
|---|
| 110 | } |
|---|
| 111 | |
|---|
| 112 | inline void update(int nanoSteps) |
|---|
| 113 | { |
|---|
| 114 | stepper->update(nanoSteps); |
|---|
| 115 | } |
|---|
| 116 | |
|---|
| 117 | const GridType& grid() const |
|---|
| 118 | { |
|---|
| 119 | return stepper->grid(); |
|---|
| 120 | } |
|---|
| 121 | |
|---|
| 122 | private: |
|---|
| 123 | boost::shared_ptr<Stepper<CELL_TYPE> > stepper; |
|---|
| 124 | boost::shared_ptr<MyPartitionManager> partitionManager; |
|---|
| 125 | SuperVector<PatchLinkPtr> patchLinks; |
|---|
| 126 | PARTITION partition; |
|---|
| 127 | SuperVector<long> weights; |
|---|
| 128 | unsigned offset; |
|---|
| 129 | unsigned ghostZoneWidth; |
|---|
| 130 | Initializer<CELL_TYPE> *initializer; |
|---|
| 131 | MPILayer mpiLayer; |
|---|
| 132 | unsigned rank; |
|---|
| 133 | }; |
|---|
| 134 | |
|---|
| 135 | } |
|---|
| 136 | } |
|---|
| 137 | |
|---|
| 138 | #endif |
|---|
| 139 | #endif |
|---|