47 #ifndef __TPETRA_DISTRIBUTION2D_HPP
48 #define __TPETRA_DISTRIBUTION2D_HPP
54 template <
typename gno_t,
typename scalar_t>
55 class Distribution2D :
public Distribution<gno_t,scalar_t> {
77 using Distribution<gno_t,scalar_t>::me;
78 using Distribution<gno_t,scalar_t>::np;
79 using Distribution<gno_t,scalar_t>::comm;
80 using Distribution<gno_t,scalar_t>::nrows;
81 using Distribution<gno_t,scalar_t>::Mine;
83 Distribution2D(
size_t nrows_,
84 const Teuchos::RCP<
const Teuchos::Comm<int> > &comm_,
85 const Teuchos::ParameterList ¶ms) :
86 Distribution<gno_t,scalar_t>(nrows_, comm_, params),
87 npRows(-1), npCols(-1)
91 const Teuchos::ParameterEntry *pe = params.getEntryPtr(
"nProcessorRows");
93 npRows = pe->getValue<
int>(&npRows);
97 const Teuchos::ParameterEntry *pe = params.getEntryPtr(
"nProcessorCols");
99 npCols = pe->getValue<
int>(&npCols);
104 if (npRows == -1 && npCols == -1) {
106 npRows = (int)(sqrt(np));
107 npCols = np / npRows;
109 while (npRows * npCols != np) {
111 npCols = np / npRows;
116 npRows = np / npCols;
117 else if (npCols == -1)
118 npCols = np / npRows;
120 if (npCols * npRows != np) {
121 TEUCHOS_TEST_FOR_EXCEPTION(npRows * npCols != np, std::logic_error,
122 "nProcessorCols " << npCols <<
123 " * nProcessorRows " << npRows <<
124 " = " << npCols * npRows <<
125 " must equal nProcessors " << np <<
126 " for 2D distribution");
130 std::cout <<
"\n2D Distribution: "
131 <<
"\n npRows = " << npRows
132 <<
"\n npCols = " << npCols
133 <<
"\n np = " << np << std::endl;
135 mypCol = this->TWODPCOL(me);
136 mypRow = this->TWODPROW(me);
139 virtual ~Distribution2D() {};
144 inline int TWODPROW(
int p) {
return (p % npRows);}
147 inline int TWODPCOL(
int p) {
return (p / npRows);}
150 inline int TWODPRANK(
int i,
int j) {
return (j * npRows + (j+i) % npRows);}
159 template <
typename gno_t,
typename scalar_t>
160 class Distribution2DLinear :
public Distribution2D<gno_t,scalar_t> {
163 using Distribution<gno_t,scalar_t>::me;
164 using Distribution<gno_t,scalar_t>::np;
165 using Distribution<gno_t,scalar_t>::nrows;
166 using Distribution2D<gno_t,scalar_t>::npRows;
167 using Distribution2D<gno_t,scalar_t>::npCols;
168 using Distribution2D<gno_t,scalar_t>::mypRow;
169 using Distribution2D<gno_t,scalar_t>::mypCol;
171 Distribution2DLinear(
size_t nrows_,
172 const Teuchos::RCP<
const Teuchos::Comm<int> > &comm_,
173 const Teuchos::ParameterList ¶ms) :
174 Distribution2D<gno_t,scalar_t>(nrows_, comm_, params)
177 entries.assign(np+1, nrows / np);
178 int nExtraEntries = nrows % np;
188 for (
int cnt = 0, i = 0; (cnt < nExtraEntries) && (i < npRows); i++) {
189 for (
int j = 0; (cnt < nExtraEntries) && (j < npCols); cnt++, j++) {
190 int rankForExtra = Distribution2D<gno_t,scalar_t>::TWODPRANK(i, j);
191 entries[rankForExtra+1]++;
198 for (
int i = 1; i <= np; i++)
199 entries[i] = entries[i-1] + entries[i];
203 int firstRank = mypCol * npRows;
204 myFirstCol = entries[firstRank];
207 for (
int i = firstRank; i < firstRank + npRows; i++)
208 nMyCols += entries[i+1] - entries[i];
209 myLastCol = myFirstCol + nMyCols - 1;
212 inline enum DistributionType DistType() {
return TwoDLinear; }
214 bool Mine(gno_t i, gno_t j) {
215 int idx = int(
float(i) *
float(np) /
float(nrows));
216 while (i < entries[idx]) idx--;
217 while (i >= entries[idx+1]) idx++;
218 return ((mypRow == Distribution2D<gno_t,scalar_t>::TWODPROW(idx))
219 && (j >= myFirstCol && j <= myLastCol));
221 inline bool Mine(gno_t i, gno_t j,
int p) {
return Mine(i,j);}
223 inline bool VecMine(gno_t i) {
224 return(i >= entries[me] && i < entries[me+1]);
229 std::vector<gno_t> entries;
236 template <
typename gno_t,
typename scalar_t>
237 class Distribution2DRandom :
public Distribution2D<gno_t,scalar_t> {
240 using Distribution<gno_t,scalar_t>::me;
241 using Distribution2D<gno_t,scalar_t>::mypRow;
242 using Distribution2D<gno_t,scalar_t>::mypCol;
244 Distribution2DRandom(
size_t nrows_,
245 const Teuchos::RCP<
const Teuchos::Comm<int> > &comm_,
246 const Teuchos::ParameterList ¶ms) :
247 Distribution2D<gno_t,scalar_t>(nrows_, comm_, params)
248 {
if (me == 0) std::cout <<
" randomize = true" << std::endl; }
250 inline enum DistributionType DistType() {
return TwoDRandom; }
252 inline bool Mine(gno_t i, gno_t j) {
253 return ((mypRow == this->TWODPROW(this->HashToProc(i))) &&
254 (mypCol == this->TWODPCOL(this->HashToProc(j))));
256 inline bool Mine(gno_t i, gno_t j,
int p) {
return Mine(i,j);}
258 inline bool VecMine(gno_t i) {
return (me == this->HashToProc(i)); }
264 template <
typename gno_t,
typename scalar_t>
265 class Distribution2DVec :
public Distribution2D<gno_t,scalar_t>
271 using Distribution<gno_t,scalar_t>::me;
272 using Distribution<gno_t,scalar_t>::np;
273 using Distribution<gno_t,scalar_t>::comm;
274 using Distribution<gno_t,scalar_t>::nrows;
275 using Distribution2D<gno_t,scalar_t>::npRows;
276 using Distribution2D<gno_t,scalar_t>::npCols;
278 Distribution2DVec(
size_t nrows_,
279 const Teuchos::RCP<
const Teuchos::Comm<int> > &comm_,
280 const Teuchos::ParameterList ¶ms,
281 std::string &distributionfile) :
282 Distribution2D<gno_t,scalar_t>(nrows_, comm_, params)
284 if (me == 0) std::cout <<
"\n 2DVec Distribution: "
285 <<
"\n np = " << np << std::endl;
288 fpin.open(distributionfile.c_str(), std::ios::in);
289 if (!fpin.is_open()) {
290 std::cout <<
"Error: distributionfile " << distributionfile
291 <<
" not found" << std::endl;
301 vecpart =
new int[nrows];
303 const int bcastsize = 1000000;
307 for (
size_t i = 0; i < nrows; i++) {
308 if (me == 0) fpin >> vecpart[i];
310 if (cnt == bcastsize || i == nrows-1) {
311 Teuchos::broadcast(*comm, 0, cnt, &(vecpart[start]));
317 if (me == 0) fpin.close();
320 ~Distribution2DVec() {
delete [] vecpart;}
322 inline enum DistributionType DistType() {
return TwoDVec; }
324 bool Mine(gno_t i, gno_t j) {
325 return (me == (vecpart[i] % npRows + (vecpart[j] / npRows) * npRows));
327 inline bool Mine(gno_t i, gno_t j,
int p) {
return Mine(i,j);}
329 inline bool VecMine(gno_t i) {
return(vecpart[i] == me); }
void start()
Start the deep_copy counter.