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  int npRow = -1; // Number of processors among which to distribute rows;
43  // Will compute if not set by user
44  const Teuchos::ParameterEntry *pe = params.getEntryPtr("nProcessorRows");
45  if (pe != NULL) npRow = pe->getValue<int>(&npRow);
46 
47  TEUCHOS_TEST_FOR_EXCEPTION(npRow != -1 && npRow != np, std::logic_error,
48  " nProcessorRows " << npRow << " must equal"
49  << " nProcessors " << np << " for 1D distribution");
50 
51  if (me == 0) std::cout << "\n 1D Distribution: "
52  << "\n np = " << np << std::endl;
53  }
54 
55  // Return whether this rank owns vector entry i.
56  virtual bool VecMine(gno_t i) = 0;
57 
58  // Return whether this rank owns nonzero (i,j)
59  // Vector map and row map are the same in 1D distribution.
60  inline bool Mine(gno_t i, gno_t j) { return VecMine(i); }
61  inline bool Mine(gno_t i, gno_t j, int p) { return VecMine(i); }
62 };
63 
65 template <typename gno_t, typename scalar_t>
66 class Distribution1DLinear : public Distribution1D<gno_t, scalar_t> {
67  public:
68  using Distribution<gno_t, scalar_t>::me;
69  using Distribution<gno_t, scalar_t>::np;
70  using Distribution<gno_t, scalar_t>::nrows;
71 
72  Distribution1DLinear(size_t nrows_,
73  const Teuchos::RCP<const Teuchos::Comm<int> > &comm_,
74  const Teuchos::ParameterList &params)
75  : Distribution1D<gno_t, scalar_t>(nrows_, comm_, params) {
76  gno_t nMyRows = getNumRow(me);
77  myFirstRow = getFirstRow(me);
78  myLastRow = myFirstRow + nMyRows - 1;
79  }
80 
81  inline enum DistributionType DistType() { return OneDLinear; }
82 
83  inline bool VecMine(gno_t i) { return (i >= myFirstRow && i <= myLastRow); }
84 
85  private:
86  gno_t myFirstRow;
87  gno_t myLastRow;
88 
89  inline size_t getNumRow(int p) {
90  return (nrows / np + (int(nrows % np) > p));
91  }
92 
93  inline gno_t getFirstRow(int p) {
94  return (p * (nrows / np) + std::min<int>(int(nrows % np), p));
95  }
96 
97  // DistributionLowerTriangularBlock class needs a 1DLinear distribution
98  friend class DistributionLowerTriangularBlock<gno_t, scalar_t>;
99 };
100 
102 template <typename gno_t, typename scalar_t>
103 class Distribution1DRandom : public Distribution1D<gno_t, scalar_t> {
104  public:
105  using Distribution<gno_t, scalar_t>::me;
106 
107  Distribution1DRandom(size_t nrows_,
108  const Teuchos::RCP<const Teuchos::Comm<int> > &comm_,
109  const Teuchos::ParameterList &params)
110  : Distribution1D<gno_t, scalar_t>(nrows_, comm_, params) {
111  if (me == 0) std::cout << " randomize = true" << std::endl;
112  }
113 
114  inline enum DistributionType DistType() { return OneDRandom; }
115 
116  inline bool VecMine(gno_t i) { return (this->HashToProc(i) == me); }
117 };
118 
120 template <typename gno_t, typename scalar_t>
121 class Distribution1DVec : public Distribution1D<gno_t, scalar_t> {
122  // Distribution of nonzeros is determined by the distribution of the
123  // vector entries, as read from a file.
124  //
125  // Assumptions include:
126  // - Distribution file containing the vector part assignments (N lines)
127  // is provided. This file is read during the constructor.
128  // Format for an NxN matrix:
129  // line 1 to N: 0-based part assignment of vector entry
130 
131  public:
132  using Distribution<gno_t, scalar_t>::me;
133  using Distribution<gno_t, scalar_t>::np;
134  using Distribution<gno_t, scalar_t>::comm;
135  using Distribution<gno_t, scalar_t>::nrows;
136  using Distribution<gno_t, scalar_t>::Mine;
137 
138  Distribution1DVec(size_t nrows_,
139  const Teuchos::RCP<const Teuchos::Comm<int> > &comm_,
140  const Teuchos::ParameterList &params,
141  std::string &distributionfile)
142  : Distribution1D<gno_t, scalar_t>(nrows_, comm_, params) {
143  std::ifstream fpin;
144  if (me == 0) {
145  fpin.open(distributionfile.c_str(), std::ios::in);
146  if (!fpin.is_open()) {
147  std::cout << "Error: distributionfile " << distributionfile
148  << " not found" << std::endl;
149  exit(-1);
150  }
151  }
152 
153  // Read the vector part assignment and broadcast it to all processes.
154  // Broadcast in chunks of bcastsize values.
155  // TODO: Make the vector part assignment more scalable instead of
156  // TODO: storing entire vector on every process.
157 
158  vecpart = new int[nrows];
159 
160  const int bcastsize = 1000000;
161 
162  gno_t start = 0;
163  int cnt = 0;
164  for (size_t i = 0; i < nrows; i++) {
165  if (me == 0) fpin >> vecpart[i];
166  cnt++;
167  if (cnt == bcastsize || i == nrows - 1) {
168  Teuchos::broadcast<int, int>(*comm, 0, cnt, &(vecpart[start]));
169  start += cnt;
170  cnt = 0;
171  }
172  }
173 
174  if (me == 0) fpin.close();
175  }
176 
177  ~Distribution1DVec() { delete[] vecpart; }
178 
179  inline enum DistributionType DistType() { return OneDVec; }
180 
181  // Vector distribution was read in.
182  inline bool VecMine(gno_t i) { return (vecpart[i] == me); }
183 
184  protected:
185  int *vecpart; // part assignment of vector entries
186 };
187 
188 } // namespace Tpetra
189 
190 #endif
void start()
Start the deep_copy counter.