dune-grid 2.9.0
partitioning.hh
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (C) DUNE Project contributors, see file LICENSE.md in module root
2// SPDX-License-Identifier: LicenseRef-GPL-2.0-only-with-DUNE-exception
3#ifndef DUNE_GRID_YASPGRID_PARTITIONING_HH
4#define DUNE_GRID_YASPGRID_PARTITIONING_HH
5
13#include<array>
14
15#include<dune/common/math.hh>
16#include <dune/common/deprecated.hh>
17
18namespace Dune
19{
20
21 namespace Yasp
22 {
23
37 template<int d>
39 {
40 public:
41 using iTupel = std::array<int, d>;
42 virtual ~Partitioning() = default;
43 virtual void partition(const iTupel&, int, iTupel&, int) const = 0;
44 };
45
46 template<int d>
48 {
49 public:
50 using iTupel = std::array<int, d>;
51
57 void partition (const iTupel& size, int P, iTupel& dims, int overlap) const final
58 {
59 double opt=1E100;
60 iTupel trydims;
61
62 trydims.fill(-1);
63 dims.fill(-1);
64
65 optimize_dims(d-1,size,P,dims,trydims,opt,overlap);
66 if (dims[0] == -1)
67 DUNE_THROW(Dune::GridError, "Failed to find a suitable partition");
68 }
69
70 private:
71 void optimize_dims (int i, const iTupel& size, int P, iTupel& dims, iTupel& trydims, double &opt, int overlap ) const
72 {
73 if (i>0) // test all subdivisions recursively
74 {
75 for (int k=1; k<=P; k++)
76 if (
77 P%k==0 // k devides P
78 and (
79 k == 1 // no neighbors
80 or
81 size[i] / k >= 2*overlap // size sufficient for overlap
82 )
83 )
84 {
85 // P divisible by k
86 trydims[i] = k;
87 optimize_dims(i-1,size,P/k,dims,trydims,opt,overlap);
88 }
89 }
90 else
91 {
92 // found a possible combination
93 if (
94 P == 1 // no neighbors
95 or
96 size[0] / P >= 2*overlap // size sufficient for overlap
97 )
98 trydims[0] = P;
99 else
100 return;
101
102 // check for optimality
103 double m = -1.0;
104
105 for (int k=0; k<d; k++)
106 {
107 double mm=((double)size[k])/((double)trydims[k]);
108 if (fmod((double)size[k],(double)trydims[k])>0.0001) mm*=3;
109 if ( mm > m ) m = mm;
110 }
111 //if (_rank==0) std::cout << "optimize_dims: " << size << " | " << trydims << " norm=" << m << std::endl;
112 if (m<opt)
113 {
114 opt = m;
115 dims = trydims;
116 }
117 }
118 }
119 };
120
123 template<int d>
125 {
126 public:
127 typedef std::array<int, d> iTupel;
129
130 void partition (const iTupel& size, int P, iTupel& dims, int overlap) const final
131 {
132 for (int i=1; i<=P; ++i)
133 if (Dune::power(i, d) == P) {
134 std::fill(dims.begin(), dims.end(),i);
135 return;
136 }
137
138 DUNE_THROW(GridError, "Power partitioning failed: your number of processes needs to be a " << d << "-th power.");
139 }
140 };
141
146 template<int d>
148 {
149 public:
150 FixedSizePartitioning(const std::array<int,d>& dims) : _dims(dims) {}
151
153
154 void partition(const std::array<int,d>&, int P, std::array<int,d>& dims, int overlap) const final
155 {
156 int prod = 1;
157 for (int i=0; i<d; i++)
158 prod *= _dims[i];
159 if (P != prod)
160 DUNE_THROW(Dune::Exception,"Your processor number doesn't match your partitioning information");
161 dims = _dims;
162 }
163
164 private:
165 std::array<int,d> _dims;
166 };
167
169 }
170
174 template<int d>
176 {
177 public:
178 typedef std::array<int, d> iTupel;
179 [[deprecated("use the new interface of Yasp::Partitioning")]]
180 virtual ~YLoadBalance() {}
181 void partition (const iTupel& size, int P, iTupel& dims, int overlap) const final {
182 this->loadbalance(size,P,dims);
183 }
184 virtual void loadbalance(const iTupel&, int, iTupel&) const = 0;
185 };
186
187DUNE_NO_DEPRECATED_BEGIN
188 template<int d>
190 {
191 std::unique_ptr<Yasp::Partitioning<d>> p_;
192 public:
193 typedef std::array<int, d> iTupel;
194 YLoadBalanceForward(std::unique_ptr<Yasp::Partitioning<d>> && p) : p_(std::move(p)) {}
196 void loadbalance(const iTupel& size, int P, iTupel& dims) const final {
197 return p_->partition(size,P,dims,1); // assuming the usual overlap of 1
198 }
199 };
200
204 template<int d>
206 {
207 public:
209 YLoadBalanceForward<d>(std::make_unique<Yasp::DefaultPartitioning<d>>())
210 {}
211 };
212
216 template<int d>
218 {
219 public:
220 typedef std::array<int, d> iTupel;
222 YLoadBalanceForward<d>(std::make_unique<Yasp::PowerDPartitioning<d>>())
223 {}
224 };
225
231 template<int d>
233 {
234 public:
235 typedef std::array<int, d> iTupel;
236 YaspFixedSizePartitioner(const std::array<int,d>& dims) :
237 YLoadBalanceForward<d>(std::make_unique<Yasp::FixedSizePartitioning<d>>(dims))
238 {}
239 };
240
241DUNE_NO_DEPRECATED_END
242}
243
244#endif
STL namespace.
Include standard header files.
Definition: agrid.hh:60
constexpr Overlap overlap
PartitionSet for the overlap partition.
Definition: partitionset.hh:278
Base class for exceptions in Dune grid modules.
Definition: exceptions.hh:20
a base class for the yaspgrid partitioning strategy
Definition: partitioning.hh:39
std::array< int, d > iTupel
Definition: partitioning.hh:41
virtual ~Partitioning()=default
virtual void partition(const iTupel &, int, iTupel &, int) const =0
Definition: partitioning.hh:48
void partition(const iTupel &size, int P, iTupel &dims, int overlap) const final
Distribute a structured grid across a set of processors.
Definition: partitioning.hh:57
std::array< int, d > iTupel
Definition: partitioning.hh:50
Implement yaspgrid load balance strategy for P=x^{dim} processors.
Definition: partitioning.hh:125
virtual ~PowerDPartitioning()
Definition: partitioning.hh:128
std::array< int, d > iTupel
Definition: partitioning.hh:127
void partition(const iTupel &size, int P, iTupel &dims, int overlap) const final
Definition: partitioning.hh:130
Implement partitioner that gets a fixed partitioning from an array If the given partitioning doesn't ...
Definition: partitioning.hh:148
void partition(const std::array< int, d > &, int P, std::array< int, d > &dims, int overlap) const final
Definition: partitioning.hh:154
FixedSizePartitioning(const std::array< int, d > &dims)
Definition: partitioning.hh:150
virtual ~FixedSizePartitioning()
Definition: partitioning.hh:152
a base class for the yaspgrid partitioning strategy
Definition: partitioning.hh:176
void partition(const iTupel &size, int P, iTupel &dims, int overlap) const final
Definition: partitioning.hh:181
virtual void loadbalance(const iTupel &, int, iTupel &) const =0
virtual ~YLoadBalance()
Definition: partitioning.hh:180
std::array< int, d > iTupel
Definition: partitioning.hh:178
Definition: partitioning.hh:190
void loadbalance(const iTupel &size, int P, iTupel &dims) const final
Definition: partitioning.hh:196
YLoadBalanceForward(std::unique_ptr< Yasp::Partitioning< d > > &&p)
Definition: partitioning.hh:194
virtual ~YLoadBalanceForward()
Definition: partitioning.hh:195
std::array< int, d > iTupel
Definition: partitioning.hh:193
Implement the default load balance strategy of yaspgrid.
Definition: partitioning.hh:206
YLoadBalanceDefault()
Definition: partitioning.hh:208
Implement yaspgrid load balance strategy for P=x^{dim} processors.
Definition: partitioning.hh:218
std::array< int, d > iTupel
Definition: partitioning.hh:220
YLoadBalancePowerD()
Definition: partitioning.hh:221
Implement partitioner that gets a fixed partitioning from an array If the given partitioning doesn't ...
Definition: partitioning.hh:233
YaspFixedSizePartitioner(const std::array< int, d > &dims)
Definition: partitioning.hh:236
std::array< int, d > iTupel
Definition: partitioning.hh:235