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 //
4 // Tpetra: Templated Linear Algebra Services Package
5 // Copyright (2008) Sandia Corporation
6 //
7 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8 // the U.S. Government retains certain rights in this software.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38 //
39 // ************************************************************************
40 // @HEADER
41 
42 // 1D Row-based Distribution class
43 // Assumes square matrix
44 // Karen Devine, SNL
45 //
46 
47 #ifndef __TPETRA_DISTRIBUTION1D_HPP
48 #define __TPETRA_DISTRIBUTION1D_HPP
49 
50 namespace Tpetra {
51 
52 // Forward definition
53 template <typename gno_t, typename scalar_t>
54 class DistributionLowerTriangularBlock;
55 
57 template <typename gno_t, typename scalar_t>
58 class Distribution1D : public Distribution<gno_t,scalar_t> {
59 // 1D row-wise distribution of matrix and vector entries
60 // Rows and vector entries may be linearly or randomly distributed, or
61 // read from a file.
62 // Row map and vector map are identical
63 
64 public:
65  using Distribution<gno_t,scalar_t>::me;
66  using Distribution<gno_t,scalar_t>::np;
67  using Distribution<gno_t,scalar_t>::nrows;
68  using Distribution<gno_t,scalar_t>::Mine;
69 
70  Distribution1D(size_t nrows_,
71  const Teuchos::RCP<const Teuchos::Comm<int> > &comm_,
72  const Teuchos::ParameterList &params) :
73  Distribution<gno_t,scalar_t>(nrows_, comm_, params)
74  {
75  int npRow = -1; // Number of processors among which to distribute rows;
76  // Will compute if not set by user
77  const Teuchos::ParameterEntry *pe = params.getEntryPtr("nProcessorRows");
78  if (pe != NULL) npRow = pe->getValue<int>(&npRow);
79 
80  TEUCHOS_TEST_FOR_EXCEPTION(npRow != -1 && npRow != np, std::logic_error,
81  " nProcessorRows " << npRow << " must equal" <<
82  " nProcessors " << np <<
83  " for 1D distribution");
84 
85  if (me == 0) std::cout << "\n 1D Distribution: "
86  << "\n np = " << np << std::endl;
87  }
88 
89  // Return whether this rank owns vector entry i.
90  virtual bool VecMine(gno_t i) = 0;
91 
92  // Return whether this rank owns nonzero (i,j)
93  // Vector map and row map are the same in 1D distribution.
94  inline bool Mine(gno_t i, gno_t j) {return VecMine(i);}
95  inline bool Mine(gno_t i, gno_t j, int p) {return VecMine(i);}
96 };
97 
99 template <typename gno_t, typename scalar_t>
100 class Distribution1DLinear: public Distribution1D<gno_t,scalar_t> {
101 
102 public:
103  using Distribution<gno_t,scalar_t>::me;
104  using Distribution<gno_t,scalar_t>::np;
105  using Distribution<gno_t,scalar_t>::nrows;
106 
107  Distribution1DLinear(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  {
112  gno_t nMyRows = getNumRow(me);
113  myFirstRow = getFirstRow(me);
114  myLastRow = myFirstRow + nMyRows - 1;
115  }
116 
117  inline enum DistributionType DistType() { return OneDLinear; }
118 
119  inline bool VecMine(gno_t i) { return (i >= myFirstRow && i <= myLastRow); }
120 
121 private:
122  gno_t myFirstRow;
123  gno_t myLastRow;
124 
125  inline size_t getNumRow(int p) {
126  return (nrows / np + (int(nrows % np) > p));
127  }
128 
129  inline gno_t getFirstRow(int p) {
130  return (p * (nrows / np) + std::min<int>(int(nrows % np), p));
131  }
132 
133 // DistributionLowerTriangularBlock class needs a 1DLinear distribution
134 friend class DistributionLowerTriangularBlock<gno_t,scalar_t>;
135 
136 };
137 
139 template <typename gno_t, typename scalar_t>
140 class Distribution1DRandom : public Distribution1D<gno_t,scalar_t> {
141 
142 
143 public:
144  using Distribution<gno_t,scalar_t>::me;
145 
146  Distribution1DRandom(size_t nrows_,
147  const Teuchos::RCP<const Teuchos::Comm<int> > &comm_,
148  const Teuchos::ParameterList &params) :
149  Distribution1D<gno_t,scalar_t>(nrows_, comm_, params)
150  { if (me == 0) std::cout << " randomize = true" << std::endl; }
151 
152  inline enum DistributionType DistType() { return OneDRandom; }
153 
154  inline bool VecMine(gno_t i) { return (this->HashToProc(i) == me); }
155 };
156 
158 template <typename gno_t, typename scalar_t>
159 class Distribution1DVec : public Distribution1D<gno_t,scalar_t> {
160 // Distribution of nonzeros is determined by the distribution of the
161 // vector entries, as read from a file.
162 //
163 // Assumptions include:
164 // - Distribution file containing the vector part assignments (N lines)
165 // is provided. This file is read during the constructor.
166 // Format for an NxN matrix:
167 // line 1 to N: 0-based part assignment of vector entry
168 
169 public:
170  using Distribution<gno_t,scalar_t>::me;
171  using Distribution<gno_t,scalar_t>::np;
172  using Distribution<gno_t,scalar_t>::comm;
173  using Distribution<gno_t,scalar_t>::nrows;
174  using Distribution<gno_t,scalar_t>::Mine;
175 
176  Distribution1DVec(size_t nrows_,
177  const Teuchos::RCP<const Teuchos::Comm<int> > &comm_,
178  const Teuchos::ParameterList &params,
179  std::string &distributionfile) :
180  Distribution1D<gno_t,scalar_t>(nrows_, comm_, params)
181  {
182  std::ifstream fpin;
183  if (me == 0) {
184  fpin.open(distributionfile.c_str(), std::ios::in);
185  if (!fpin.is_open()) {
186  std::cout << "Error: distributionfile " << distributionfile
187  << " not found" << std::endl;
188  exit(-1);
189  }
190  }
191 
192  // Read the vector part assignment and broadcast it to all processes.
193  // Broadcast in chunks of bcastsize values.
194  // TODO: Make the vector part assignment more scalable instead of
195  // TODO: storing entire vector on every process.
196 
197  vecpart = new int[nrows];
198 
199  const int bcastsize = 1000000;
200 
201  gno_t start = 0;
202  int cnt = 0;
203  for (size_t i = 0; i < nrows; i++) {
204  if (me == 0) fpin >> vecpart[i];
205  cnt++;
206  if (cnt == bcastsize || i == nrows-1) {
207  Teuchos::broadcast<int, int>(*comm, 0, cnt, &(vecpart[start]));
208  start += cnt;
209  cnt = 0;
210  }
211  }
212 
213  if (me == 0) fpin.close();
214  }
215 
216  ~Distribution1DVec() {delete [] vecpart;}
217 
218  inline enum DistributionType DistType() { return OneDVec; }
219 
220  // Vector distribution was read in.
221  inline bool VecMine(gno_t i) { return (vecpart[i] == me); }
222 
223 protected:
224  int *vecpart; // part assignment of vector entries
225 
226 };
227 
228 }
229 
230 #endif
void start()
Start the deep_copy counter.