Tpetra parallel linear algebra  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Tpetra_Distribution1D.hpp
1 // @HEADER
2 // *****************************************************************************
3 // Tpetra: Templated Linear Algebra Services Package
4 //
5 // Copyright 2008 NTESS and the Tpetra contributors.
6 // SPDX-License-Identifier: BSD-3-Clause
7 // *****************************************************************************
8 // @HEADER
9 
10 // 1D Row-based Distribution class
11 // Assumes square matrix
12 // Karen Devine, SNL
13 //
14 
15 #ifndef __TPETRA_DISTRIBUTION1D_HPP
16 #define __TPETRA_DISTRIBUTION1D_HPP
17 
18 namespace Tpetra {
19 
20 // Forward definition
21 template <typename gno_t, typename scalar_t>
22 class DistributionLowerTriangularBlock;
23 
25 template <typename gno_t, typename scalar_t>
26 class Distribution1D : public Distribution<gno_t,scalar_t> {
27 // 1D row-wise distribution of matrix and vector entries
28 // Rows and vector entries may be linearly or randomly distributed, or
29 // read from a file.
30 // Row map and vector map are identical
31 
32 public:
33  using Distribution<gno_t,scalar_t>::me;
34  using Distribution<gno_t,scalar_t>::np;
35  using Distribution<gno_t,scalar_t>::nrows;
36  using Distribution<gno_t,scalar_t>::Mine;
37 
38  Distribution1D(size_t nrows_,
39  const Teuchos::RCP<const Teuchos::Comm<int> > &comm_,
40  const Teuchos::ParameterList &params) :
41  Distribution<gno_t,scalar_t>(nrows_, comm_, params)
42  {
43  int npRow = -1; // Number of processors among which to distribute rows;
44  // Will compute if not set by user
45  const Teuchos::ParameterEntry *pe = params.getEntryPtr("nProcessorRows");
46  if (pe != NULL) npRow = pe->getValue<int>(&npRow);
47 
48  TEUCHOS_TEST_FOR_EXCEPTION(npRow != -1 && npRow != np, std::logic_error,
49  " nProcessorRows " << npRow << " must equal" <<
50  " nProcessors " << np <<
51  " for 1D distribution");
52 
53  if (me == 0) std::cout << "\n 1D Distribution: "
54  << "\n np = " << np << std::endl;
55  }
56 
57  // Return whether this rank owns vector entry i.
58  virtual bool VecMine(gno_t i) = 0;
59 
60  // Return whether this rank owns nonzero (i,j)
61  // Vector map and row map are the same in 1D distribution.
62  inline bool Mine(gno_t i, gno_t j) {return VecMine(i);}
63  inline bool Mine(gno_t i, gno_t j, int p) {return VecMine(i);}
64 };
65 
67 template <typename gno_t, typename scalar_t>
68 class Distribution1DLinear: public Distribution1D<gno_t,scalar_t> {
69 
70 public:
71  using Distribution<gno_t,scalar_t>::me;
72  using Distribution<gno_t,scalar_t>::np;
73  using Distribution<gno_t,scalar_t>::nrows;
74 
75  Distribution1DLinear(size_t nrows_,
76  const Teuchos::RCP<const Teuchos::Comm<int> > &comm_,
77  const Teuchos::ParameterList &params) :
78  Distribution1D<gno_t,scalar_t>(nrows_, comm_, params)
79  {
80  gno_t nMyRows = getNumRow(me);
81  myFirstRow = getFirstRow(me);
82  myLastRow = myFirstRow + nMyRows - 1;
83  }
84 
85  inline enum DistributionType DistType() { return OneDLinear; }
86 
87  inline bool VecMine(gno_t i) { return (i >= myFirstRow && i <= myLastRow); }
88 
89 private:
90  gno_t myFirstRow;
91  gno_t myLastRow;
92 
93  inline size_t getNumRow(int p) {
94  return (nrows / np + (int(nrows % np) > p));
95  }
96 
97  inline gno_t getFirstRow(int p) {
98  return (p * (nrows / np) + std::min<int>(int(nrows % np), p));
99  }
100 
101 // DistributionLowerTriangularBlock class needs a 1DLinear distribution
102 friend class DistributionLowerTriangularBlock<gno_t,scalar_t>;
103 
104 };
105 
107 template <typename gno_t, typename scalar_t>
108 class Distribution1DRandom : public Distribution1D<gno_t,scalar_t> {
109 
110 
111 public:
112  using Distribution<gno_t,scalar_t>::me;
113 
114  Distribution1DRandom(size_t nrows_,
115  const Teuchos::RCP<const Teuchos::Comm<int> > &comm_,
116  const Teuchos::ParameterList &params) :
117  Distribution1D<gno_t,scalar_t>(nrows_, comm_, params)
118  { if (me == 0) std::cout << " randomize = true" << std::endl; }
119 
120  inline enum DistributionType DistType() { return OneDRandom; }
121 
122  inline bool VecMine(gno_t i) { return (this->HashToProc(i) == me); }
123 };
124 
126 template <typename gno_t, typename scalar_t>
127 class Distribution1DVec : public Distribution1D<gno_t,scalar_t> {
128 // Distribution of nonzeros is determined by the distribution of the
129 // vector entries, as read from a file.
130 //
131 // Assumptions include:
132 // - Distribution file containing the vector part assignments (N lines)
133 // is provided. This file is read during the constructor.
134 // Format for an NxN matrix:
135 // line 1 to N: 0-based part assignment of vector entry
136 
137 public:
138  using Distribution<gno_t,scalar_t>::me;
139  using Distribution<gno_t,scalar_t>::np;
140  using Distribution<gno_t,scalar_t>::comm;
141  using Distribution<gno_t,scalar_t>::nrows;
142  using Distribution<gno_t,scalar_t>::Mine;
143 
144  Distribution1DVec(size_t nrows_,
145  const Teuchos::RCP<const Teuchos::Comm<int> > &comm_,
146  const Teuchos::ParameterList &params,
147  std::string &distributionfile) :
148  Distribution1D<gno_t,scalar_t>(nrows_, comm_, params)
149  {
150  std::ifstream fpin;
151  if (me == 0) {
152  fpin.open(distributionfile.c_str(), std::ios::in);
153  if (!fpin.is_open()) {
154  std::cout << "Error: distributionfile " << distributionfile
155  << " not found" << std::endl;
156  exit(-1);
157  }
158  }
159 
160  // Read the vector part assignment and broadcast it to all processes.
161  // Broadcast in chunks of bcastsize values.
162  // TODO: Make the vector part assignment more scalable instead of
163  // TODO: storing entire vector on every process.
164 
165  vecpart = new int[nrows];
166 
167  const int bcastsize = 1000000;
168 
169  gno_t start = 0;
170  int cnt = 0;
171  for (size_t i = 0; i < nrows; i++) {
172  if (me == 0) fpin >> vecpart[i];
173  cnt++;
174  if (cnt == bcastsize || i == nrows-1) {
175  Teuchos::broadcast<int, int>(*comm, 0, cnt, &(vecpart[start]));
176  start += cnt;
177  cnt = 0;
178  }
179  }
180 
181  if (me == 0) fpin.close();
182  }
183 
184  ~Distribution1DVec() {delete [] vecpart;}
185 
186  inline enum DistributionType DistType() { return OneDVec; }
187 
188  // Vector distribution was read in.
189  inline bool VecMine(gno_t i) { return (vecpart[i] == me); }
190 
191 protected:
192  int *vecpart; // part assignment of vector entries
193 
194 };
195 
196 }
197 
198 #endif
void start()
Start the deep_copy counter.