belosLinProb.hh

Go to the documentation of this file.
1 
7 #ifndef BELOSLINEARPROBLEM_HH_
8 #define BELOSLINEARPROBLEM_HH_
9 
10 #include "basics.hh"
11 #include "sparseMatrix.hh"
12 #include "toolbox/sequence.hh"
13 #include <BelosLinearProblem.hpp>
14 #include <Tpetra_CrsMatrix.hpp>
15 
16 namespace concepts {
17 
24  template<class T, class MV = Tpetra::MultiVector<T, int>,
25  class OP = Tpetra::Operator<T> >
26  class BelosLinProb: public Belos::LinearProblem<T, MV, OP> {
27  public:
28 
31  }
32  ;
33 
35  virtual ~BelosLinProb() {
36  }
37  ;
38 
49  BelosLinProb(Teuchos::RCP<const Teuchos::Comm<int> > comm);
50 
62  Teuchos::RCP<const Teuchos::Comm<int> > comm);
63 
74  void setConceptsRHS(const Vector<T>& rhs,
75  Teuchos::RCP<const Teuchos::Comm<int> > comm);
76 
86  void setConceptsRHS(Teuchos::RCP<const Teuchos::Comm<int> > comm);
87 
95  void writeSolution(Vector<T>& vec,
96  Teuchos::RCP<const Teuchos::Comm<int> > comm);
97 
106  void writeSolution(Teuchos::RCP<const Teuchos::Comm<int> > comm);
107 
109  Teuchos::RCP<Tpetra::CrsMatrix<T, int, int> > getCrsMat() {
110  return A_;
111  }
112  ;
114  void setCrsMat(Teuchos::RCP<Tpetra::CrsMatrix<T, int, int> > A) {
115  A = A_;
116  this->setOperator(A_);
117  }
118 
119  private:
120 
122  Teuchos::RCP<Tpetra::CrsMatrix<T, int, int> > A_;
123  };
124 
125  template<class T, class MV, class OP>
127  Teuchos::RCP<const Teuchos::Comm<int> > Comm) {
128 
129  //Thread information
130  int MyPID = Comm->getRank();
131  int NumProc = Comm->getSize();
132 
133  //local matrix data recieved from the assembler thread
134  int * nnzPerRow;
135  int * col;
136  T * val;
137 
138  //iterators
139  int * nnzPerRowIter;
140  int * colIter;
141  T * valIter;
142 
143  //Global matrix information
144  int globalSize = 0;
145  int max_ = 0;
146 
147  //local matrix information
148  int localSize = 0;
149  int localNnz = 0;
150 
151  /*
152  ===================================
153  Extract data for other processes and send it.
154  Just one thread is allowed to know the sparse matrix
155  ===================================
156  */
157  globalSize = sparse.nofRows();
158 
159  //broadcast globalMatrix Informations
160  Comm->broadcast(0, sizeof(int), (char*) (&globalSize));
161 
162  // compute local size for each processor
163  concepts::Sequence<int> localSizes(NumProc);
164  int restsize = globalSize;
165  for(int i = 0; i < NumProc; ++i)
166  restsize -= (localSizes[i] = restsize / (NumProc - i));
167  DEBUGL(0, "localSizes = " << localSizes);
168 
169  //number of rows of this thread
170  int bias = localSizes[MyPID];
171  typename SparseMatrix<T>::iterator iter = sparse.begin(0);
172 
173  for (int i = 1; i < NumProc; ++i) {
174  //local Size of the process we collect data
175  localSize = localSizes[i];
176  //memory for local entries per row array
177  nnzPerRow = new int[localSize];
178 
179  //iterator
180  nnzPerRowIter = nnzPerRow;
181 
182  DEBUGL(0, "localSize = " << localSize);
183  DEBUGL(0, "bias = " << bias);
184 
185  //count numbers of nonzeros per row
186  for (uint j = 0; j < (uint) localSize; ++j) {
187  *nnzPerRowIter = 0;
188  iter = sparse.begin(j + bias);
189  while (iter != sparse.end() && (iter++).row() == (j + bias))
190  ++(*nnzPerRowIter);
191  ++nnzPerRowIter;
192  } //for over rows
193 
194  //send data to thread number i and delete it
195  Comm->send(localSize * sizeof(int), (char*) nnzPerRow, i);
196 
197  localNnz = 0;
198  nnzPerRowIter = nnzPerRow;
199  for (int j = 0; j < localSize; ++j)
200  localNnz += *nnzPerRowIter++;
201 
202  delete[] nnzPerRow;
203 
204  //memory for global values and colums
205  val = new T[localNnz];
206  col = new int[localNnz];
207 
208  //extract global data
209  valIter = val;
210  colIter = col;
211  for (uint j = 0; j < (uint) localSize; ++j) {
212  iter = sparse.begin(j + bias);
213  while (iter.row() == (j + bias) && (iter != sparse.end())) {
214  *colIter++ = iter.col();
215  *valIter++ = *iter++;
216  } //while
217  } //inner for
218 
219  //send data to thread number i and delete it
220  Comm->send(localNnz * sizeof(T), (char*) val, i);
221  Comm->send(localNnz * sizeof(int), (char*) col, i);
222  delete[] val;
223  delete[] col;
224 
225  //increase bias
226  bias += localSize;
227  } //for that sends data to other processes
228 
229  /*
230  ===================================
231  Extract own data
232  ===================================
233  */
234  //local Size of the process we collect data
235  localSize = localSizes[0];
236 
237  //memory for local entrie per row array
238  nnzPerRow = new int[localSize];
239 
240  //iterator
241  nnzPerRowIter = nnzPerRow;
242  iter = sparse.begin(0);
243  //TODO uint -> int Kontrollieren!
244  //count numbers of nonzeros per row
245  for (uint i = 0; i < (uint) localSize; ++i) {
246  *nnzPerRowIter = 0;
247  iter = sparse.begin(i);
248  while (iter != sparse.end() && (iter++).row() == i)
249  ++(*nnzPerRowIter);
250  ++nnzPerRowIter;
251  } //for over rows
252 
253  localNnz = 0;
254  nnzPerRowIter = nnzPerRow;
255  for (int i = 0; i < localSize; ++i) {
256  max_ = std::max(max_, *nnzPerRowIter);
257  localNnz += *nnzPerRowIter++;
258  }
259  //memory for global values and colums
260  val = new T[localNnz];
261  col = new int[localNnz];
262 
263  //extract global data
264  valIter = val;
265  colIter = col;
266  for (uint i = 0; i < (uint) localSize; ++i) {
267  iter = sparse.begin(i);
268  while (iter.row() == i && (iter != sparse.end())) {
269  *colIter++ = iter.col();
270  *valIter++ = *iter++;
271  } //while
272  } //inner for
273 
274  /*
275  ===============================
276  fill matrix
277  ===============================
278  */
279  //Create continouse and uniform mapping (in terms of rows)
280  Teuchos::RCP<const Tpetra::Map<int, int> > mapStiffRow =
281  Tpetra::createContigMap<int, int>(globalSize, localSize, Comm);
282 
283  //declare matrix, rhs and solutionVector
284  A_ = Teuchos::RCP<Tpetra::CrsMatrix<T, int, int> >(
285  new Tpetra::CrsMatrix<T, int, int>(mapStiffRow, max_));
286 
287  Teuchos::RCP<Tpetra::MultiVector<T, int> > sol(
288  new Tpetra::MultiVector<T, int>(mapStiffRow, 1));
289  Teuchos::RCP<Tpetra::MultiVector<T, int> > rhs2(
290  new Tpetra::MultiVector<T, int>(mapStiffRow, 1));
291 
292  //iterators
293  nnzPerRowIter = nnzPerRow;
294  valIter = val;
295  colIter = col;
296  int globalIndex = 0;
297  int currNnz = 0;
298 
299  for (int k = 0; k < localSize; ++k) {
300  globalIndex = mapStiffRow->getGlobalElement(k);
301  currNnz = *nnzPerRowIter;
302  if (currNnz > 0) {
303  A_->insertGlobalValues(globalIndex,
304  Teuchos::ArrayView<int>(colIter, currNnz),
305  Teuchos::ArrayView<T>(valIter, currNnz));
306  colIter += currNnz;
307  valIter += currNnz;
308  } //nnz != 0
309  nnzPerRowIter++;
310  }
311 
312  A_->fillComplete();
313 
314  delete[] nnzPerRow;
315  delete[] val;
316  delete[] col;
317 
318  this->setOperator(A_);
319  }
320  ;
321 
322  template<class T, class MV, class OP>
324  Teuchos::RCP<const Teuchos::Comm<int> > Comm) {
325 
326  //Thread information
327  int MyPID = Comm->getRank();
328  int NumProc = Comm->getSize();
329 
330  //This thread is not the first
331  if (MyPID == 0)
332  throw std::logic_error("The first thread needs a Matrix");
333 
334  //local matrix data recieved from the assembler thread
335  int * nnzPerRow;
336  int * col;
337  T * val;
338 
339  //iterators
340  int * nnzPerRowIter;
341  int * colIter;
342  T * valIter;
343 
344  //Global matrix information
345  int globalSize = 0;
346  int max_ = 0;
347 
348  //local matrix information
349  int localSize = 0;
350  int localNnz = 0;
351  //broadcast globalMatrix Informations
352  Comm->broadcast(0, sizeof(int), (char*) (&globalSize));
353 
354  // compute local data sizes
355  concepts::Sequence<int> localSizes(NumProc);
356  int restsize = globalSize;
357  for(int i = 0; i < NumProc; ++i)
358  restsize -= (localSizes[i] = restsize / (NumProc - i));
359  DEBUGL(0, "localSizes = " << localSizes);
360 
361  //calculate local data size
362  localSize = localSizes[MyPID];
363 
364  //allocate memory for array of number of entries and recieve data from assambler
365  nnzPerRow = new int[localSize];
366  nnzPerRowIter = nnzPerRow;
367  Comm->receive(0, localSize * sizeof(int), (char*) nnzPerRow);
368  max_ = *nnzPerRowIter;
369  for (int i = 0; i < localSize; ++i) {
370  max_ = std::max(max_, *nnzPerRowIter);
371  localNnz += *nnzPerRowIter++;
372  }
373  //allocate memory for locale data
374  col = new int[localNnz];
375  val = new T[localNnz];
376 
377  //receive data from assambler thread
378  Comm->receive(0, localNnz * sizeof(T), (char*) val);
379  Comm->receive(0, localNnz * sizeof(int), (char*) col);
380 
381  /*
382  ===============================
383  fill matrix
384  ===============================
385  */
386  //Create continouse and uniform mapping (in terms of rows)
387  Teuchos::RCP<const Tpetra::Map<int, int> > mapStiffRow =
388  Tpetra::createContigMap<int, int>(globalSize, localSize, Comm);
389 
390  //declare matrix, rhs and solutionVector
391  A_ = Teuchos::RCP<Tpetra::CrsMatrix<T, int, int> >(
392  new Tpetra::CrsMatrix<T, int, int>(mapStiffRow, max_));
393 
394  //iterators
395  nnzPerRowIter = nnzPerRow;
396  valIter = val;
397  colIter = col;
398  int globalIndex = 0;
399  int currNnz = 0;
400 
401  for (int k = 0; k < localSize; ++k) {
402  globalIndex = mapStiffRow->getGlobalElement(k);
403  currNnz = *nnzPerRowIter;
404  if (currNnz > 0) {
405  A_->insertGlobalValues(globalIndex,
406  Teuchos::ArrayView<int>(colIter, currNnz),
407  Teuchos::ArrayView<T>(valIter, currNnz));
408  colIter += currNnz;
409  valIter += currNnz;
410  } //nnz != 0
411  nnzPerRowIter++;
412  }
413 
414  A_->fillComplete();
415 
416  delete[] nnzPerRow;
417  delete[] val;
418  delete[] col;
419 
420  this->setOperator(A_);
421  }
422  ;
423 
424  template<class T, class MV, class OP>
426  Teuchos::RCP<const Teuchos::Comm<int> > Comm) {
427 
428  //Thread information
429  int MyPID = Comm->getRank();
430  int NumProc = Comm->getSize();
431 
432  T * rhsVal;
433  T * rhsValIter;
434  T * vecIter;
435  int globalSize = vec.size();
436 
437  //broadcast globalMatrix Informations
438  Comm->broadcast(0, sizeof(int), (char*) (&globalSize));
439 
440  // compute local data sizes
441  concepts::Sequence<int> localSizes(NumProc);
442  int restsize = globalSize;
443  for(int i = 0; i < NumProc; ++i)
444  restsize -= (localSizes[i] = restsize / (NumProc - i));
445  DEBUGL(0, "localSizes = " << localSizes);
446 
447  //number of rows of this thread
448  int bias = localSizes[MyPID];
449 
450  for (int i = 1; i < NumProc; ++i) {
451  int localSize = localSizes[i];;
452  rhsVal = new T[localSize];
453  rhsValIter = rhsVal;
454  vecIter = &(vec[bias]);
455  for (int j = 0; j < localSize; ++j)
456  *rhsValIter++ = *vecIter++;
457  //send and delete data for other processes
458  Comm->send(localSize * sizeof(T), (char*) rhsVal, i);
459  delete[] rhsVal;
460 
461  //increase bias
462  bias += localSize;
463  }
464  //my local Size
465  int localSize = localSizes[MyPID];
466  rhsVal = new T[localSize];
467  rhsValIter = rhsVal;
468  vecIter = &(vec[0]);
469  for (int j = 0; j < localSize; ++j)
470  *rhsValIter++ = *vecIter++;
471 
472  Teuchos::RCP<Tpetra::MultiVector<T, int> > rhs2(
473  new Tpetra::MultiVector<T, int>(A_->getRowMap(), 1));
474 
475  Teuchos::RCP<Tpetra::MultiVector<T, int> > sol(
476  new Tpetra::MultiVector<T, int>(A_->getRowMap(), 1));
477 
478  rhsValIter = rhsVal;
479  for (int k = 0; k < localSize; ++k) {
480  sol->replaceGlobalValue((A_->getRowMap())->getGlobalElement(k), 0,
481  *rhsValIter);
482  rhs2->replaceGlobalValue((A_->getRowMap())->getGlobalElement(k), 0,
483  *rhsValIter++);
484  }
485 
486  delete[] rhsVal;
487 
488  this->setRHS(rhs2);
489  this->setLHS(sol);
490 
491  }
492 
493  template<class T, class MV, class OP>
495  Teuchos::RCP<const Teuchos::Comm<int> > Comm) {
496 
497  //Thread information
498  int MyPID = Comm->getRank();
499  int NumProc = Comm->getSize();
500 
501  T * rhsVal;
502  T * rhsValIter;
503  int globalSize;
504 
505  //broadcast globalMatrix Informations
506  Comm->broadcast(0, sizeof(int), (char*) (&globalSize));
507 
508  // compute local data sizes
509  concepts::Sequence<int> localSizes(NumProc);
510  int restsize = globalSize;
511  for(int i = 0; i < NumProc; ++i)
512  restsize -= (localSizes[i] = restsize / (NumProc - i));
513  DEBUGL(0, "localSizes = " << localSizes);
514 
515  //calculate local data size
516  int localSize = localSizes[MyPID];
517 
518  rhsVal = new T[localSize];
519  Comm->receive(0, localSize * sizeof(T), (char*) rhsVal);
520 
521  Teuchos::RCP<Tpetra::MultiVector<T, int> > rhs2(
522  new Tpetra::MultiVector<T, int>(A_->getRowMap(), 1));
523 
524  Teuchos::RCP<Tpetra::MultiVector<T, int> > sol(
525  new Tpetra::MultiVector<T, int>(A_->getRowMap(), 1));
526 
527  rhsValIter = rhsVal;
528  for (int k = 0; k < localSize; ++k) {
529  sol->replaceGlobalValue((A_->getRowMap())->getGlobalElement(k), 0,
530  *rhsValIter);
531  rhs2->replaceGlobalValue((A_->getRowMap())->getGlobalElement(k), 0,
532  *rhsValIter++);
533  }
534 
535  delete[] rhsVal;
536 
537  this->setRHS(rhs2);
538  this->setLHS(sol);
539  //solve
540  }
541 
542  template<class T, class MV, class OP>
544  Teuchos::RCP<const Teuchos::Comm<int> > Comm) {
545 
546  int MyPID = Comm->getRank();
547  int NumProc = Comm->getSize();
548  int globalSize = sol.size();
549 
550  // compute local data sizes
551  concepts::Sequence<int> localSizes(NumProc);
552  int restsize = globalSize;
553  for(int i = 0; i < NumProc; ++i)
554  restsize -= (localSizes[i] = restsize / (NumProc - i));
555  DEBUGL(0, "localSizes = " << localSizes);
556 
557  //calculate local data size
558  int localSize = localSizes[MyPID];
559 
560  T *solutionData = new T[globalSize];
561  memcpy(solutionData, (this->getLHS()->get1dViewNonConst()).get(),
562  sizeof(T) * localSize);
563 
564  //collects data of all processes
565  int ith_size = 0;
566  int bias = localSize;
567  for (int i = 1; i < NumProc; ++i) {
568  ith_size = localSizes[i];
569  Comm->receive(i, sizeof(T) * ith_size,
570  (char*) (solutionData + bias));
571  bias += ith_size;
572  }
573  T * solutionDataIter = solutionData;
574  for (int i = 0; i < sol.size(); ++i) {
575  sol[i] = *solutionDataIter++;
576  }
577  delete[] solutionData;
578  }
579 
580  template<class T, class MV, class OP>
582  Teuchos::RCP<const Teuchos::Comm<int> > Comm) {
583  //sends the part of the solution to the root thread (with PID = 0)
584  int MyPID = Comm->getRank();
585  int NumProc = Comm->getSize();
586  int globalSize = A_->getRowMap()->getGlobalNumElements();
587 
588  // compute local data sizes
589  concepts::Sequence<int> localSizes(NumProc);
590  int restsize = globalSize;
591  for(int i = 0; i < NumProc; ++i)
592  restsize -= (localSizes[i] = restsize / (NumProc - i));
593  DEBUGL(0, "localSizes = " << localSizes);
594 
595  //calculate local data size
596  int localSize = localSizes[MyPID];
597 
598  Comm->send(sizeof(T) * localSize,
599  (const char*) (this->getLHS()->get1dViewNonConst()).get(), 0);
600  }
601 
602 } /* namespace concepts */
603 #endif /* BELOSLINEARPROBLEM_HH_ */
BelosLinProb()
Default Constructor.
Definition: belosLinProb.hh:30
Teuchos::RCP< Tpetra::CrsMatrix< T, int, int > > getCrsMat()
Getter for CRS matrix used for preconditoner.
void setCrsMat(Teuchos::RCP< Tpetra::CrsMatrix< T, int, int > > A)
Setter for CRS matrix.
Teuchos::RCP< Tpetra::CrsMatrix< T, int, int > > A_
matrix of the problem
uint size() const
Definition: vector.hh:147
#define DEBUGL(doit, msg)
Decorator that decorates the Class Belos::LinearProblem<T, MV, OP> with interfaces to Concepts Sparse...
Definition: belosLinProb.hh:26
unsigned int row() const
Row.
virtual ~BelosLinProb()
Default Destructor.
Definition: belosLinProb.hh:35
Sequence with operations, output operator, and method of the particular element types.
Definition: sequence.hh:39
void writeSolution(Vector< T > &vec, Teuchos::RCP< const Teuchos::Comm< int > > comm)
Copies the solution vector of this problem in a concepts::Vector If started parallel this method shou...
void setConceptsRHS(const Vector< T > &rhs, Teuchos::RCP< const Teuchos::Comm< int > > comm)
Copies the informations of a concepts::Vector into a Tpetra::Multivector and sets it to the rhs vecto...
unsigned int col() const
Column.
const_iterator begin(uint row=0) const
Constant iterator over the elements, standing at position (row,c), where row is the given row number ...
STL like iterator for hashed sparse matrices.
const_iterator end() const
Last entrance of the particular order.
Basic namespace for Concepts-2.
Definition: pml_formula.h:16
Page URL: http://wiki.math.ethz.ch/bin/view/Concepts/WebHome
21 August 2020
© 2020 Eidgenössische Technische Hochschule Zürich