Tpetra parallel linear algebra  Version of the Day
Tpetra_Experimental_BlockMultiVector_def.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 #ifndef TPETRA_EXPERIMENTAL_BLOCKMULTIVECTOR_DEF_HPP
43 #define TPETRA_EXPERIMENTAL_BLOCKMULTIVECTOR_DEF_HPP
44 
45 #include "Tpetra_Experimental_BlockMultiVector_decl.hpp"
46 
47 namespace { // anonymous
48 
60  template<class MultiVectorType>
61  struct RawPtrFromMultiVector {
62  typedef typename MultiVectorType::impl_scalar_type impl_scalar_type;
63 
64  static impl_scalar_type* getRawPtr (MultiVectorType& X) {
65  typedef typename MultiVectorType::dual_view_type dual_view_type;
66  typedef typename dual_view_type::t_host::memory_space host_memory_space;
67 
68  // We're getting a nonconst View, so mark the MultiVector as
69  // modified on the host. This will throw an exception if the
70  // MultiVector is already modified on the host.
71  X.template modify<host_memory_space> ();
72 
73  dual_view_type X_view = X.getDualView ();
74  impl_scalar_type* X_raw = X_view.h_view.ptr_on_device ();
75  return X_raw;
76  }
77  };
78 
91  template<class S, class LO, class GO, class N>
93  getRawPtrFromMultiVector (Tpetra::MultiVector<S, LO, GO, N>& X) {
95  return RawPtrFromMultiVector<MV>::getRawPtr (X);
96  }
97 
98 } // namespace (anonymous)
99 
100 namespace Tpetra {
101 namespace Experimental {
102 
103 template<class Scalar, class LO, class GO, class Node>
104 typename BlockMultiVector<Scalar, LO, GO, Node>::mv_type
105 BlockMultiVector<Scalar, LO, GO, Node>::
106 getMultiVectorView ()
107 {
108  // Make sure that mv_ has view semantics.
109  mv_.setCopyOrView (Teuchos::View);
110  // Now the one-argument copy constructor will make a shallow copy,
111  // and those view semantics will persist in all of its offspring.
112  return mv_;
113 }
114 
115 template<class Scalar, class LO, class GO, class Node>
116 Teuchos::RCP<const BlockMultiVector<Scalar, LO, GO, Node> >
119 {
121  const BMV* src_bmv = dynamic_cast<const BMV*> (&src);
122  TEUCHOS_TEST_FOR_EXCEPTION(
123  src_bmv == NULL, std::invalid_argument, "Tpetra::Experimental::"
124  "BlockMultiVector: The source object of an Import or Export to a "
125  "BlockMultiVector, must also be a BlockMultiVector.");
126  return Teuchos::rcp (src_bmv, false); // nonowning RCP
127 }
128 
129 template<class Scalar, class LO, class GO, class Node>
131 BlockMultiVector (const map_type& meshMap,
132  const LO blockSize,
133  const LO numVecs) :
134  dist_object_type (Teuchos::rcp (new map_type (meshMap))), // shallow copy
135  meshMap_ (meshMap),
136  pointMap_ (makePointMap (meshMap, blockSize)),
137  mv_ (Teuchos::rcpFromRef (pointMap_), numVecs), // nonowning RCP is OK, since pointMap_ won't go away
138  mvData_ (getRawPtrFromMultiVector (mv_)),
139  blockSize_ (blockSize)
140 {
141  // Make sure that mv_ has view semantics.
142  mv_.setCopyOrView (Teuchos::View);
143 }
144 
145 template<class Scalar, class LO, class GO, class Node>
147 BlockMultiVector (const map_type& meshMap,
148  const map_type& pointMap,
149  const LO blockSize,
150  const LO numVecs) :
151  dist_object_type (Teuchos::rcp (new map_type (meshMap))), // shallow copy
152  meshMap_ (meshMap),
153  pointMap_ (pointMap),
154  mv_ (Teuchos::rcpFromRef (pointMap_), numVecs),
155  mvData_ (getRawPtrFromMultiVector (mv_)),
156  blockSize_ (blockSize)
157 {
158  // Make sure that mv_ has view semantics.
159  mv_.setCopyOrView (Teuchos::View);
160 }
161 
162 template<class Scalar, class LO, class GO, class Node>
165  const map_type& meshMap,
166  const LO blockSize) :
167  dist_object_type (Teuchos::rcp (new map_type (meshMap))), // shallow copy
168  meshMap_ (meshMap),
169  mvData_ (NULL), // just for now
170  blockSize_ (blockSize)
171 {
172  using Teuchos::RCP;
173 
174  if (X_mv.getCopyOrView () == Teuchos::View) {
175  // The input MultiVector has view semantics, so assignment just
176  // does a shallow copy.
177  mv_ = X_mv;
178  }
179  else if (X_mv.getCopyOrView () == Teuchos::Copy) {
180  // The input MultiVector has copy semantics. We can't change
181  // that, but we can make a view of the input MultiVector and
182  // change the view to have view semantics. (That sounds silly;
183  // shouldn't views always have view semantics? but remember that
184  // "view semantics" just governs the default behavior of the copy
185  // constructor and assignment operator.)
186  RCP<const mv_type> X_view_const;
187  const size_t numCols = X_mv.getNumVectors ();
188  if (numCols == 0) {
189  Teuchos::Array<size_t> cols (0); // view will have zero columns
190  X_view_const = X_mv.subView (cols ());
191  } else { // Range1D is an inclusive range
192  X_view_const = X_mv.subView (Teuchos::Range1D (0, numCols-1));
193  }
194  TEUCHOS_TEST_FOR_EXCEPTION(
195  X_view_const.is_null (), std::logic_error, "Tpetra::Experimental::"
196  "BlockMultiVector constructor: X_mv.subView(...) returned null. This "
197  "should never happen. Please report this bug to the Tpetra developers.");
198 
199  // It's perfectly OK to cast away const here. Those view methods
200  // should be marked const anyway, because views can't change the
201  // allocation (just the entries themselves).
202  RCP<mv_type> X_view = Teuchos::rcp_const_cast<mv_type> (X_view_const);
203  X_view->setCopyOrView (Teuchos::View);
204  TEUCHOS_TEST_FOR_EXCEPTION(
205  X_view->getCopyOrView () != Teuchos::View, std::logic_error, "Tpetra::"
206  "Experimental::BlockMultiVector constructor: We just set a MultiVector "
207  "to have view semantics, but it claims that it doesn't have view "
208  "semantics. This should never happen. "
209  "Please report this bug to the Tpetra developers.");
210  mv_ = *X_view; // MultiVector::operator= does a shallow copy here
211  }
212 
213  // At this point, mv_ has been assigned, so we can ignore X_mv.
214  Teuchos::RCP<const map_type> pointMap = mv_.getMap ();
215  if (! pointMap.is_null ()) {
216  pointMap_ = *pointMap; // Map::operator= also does a shallow copy
217  }
218  mvData_ = getRawPtrFromMultiVector (mv_);
219 }
220 
221 template<class Scalar, class LO, class GO, class Node>
224  dist_object_type (Teuchos::null),
225  mvData_ (NULL),
226  blockSize_ (0)
227 {
228  // Make sure that mv_ has view semantics.
229  mv_.setCopyOrView (Teuchos::View);
230 }
231 
232 template<class Scalar, class LO, class GO, class Node>
235 makePointMap (const map_type& meshMap, const LO blockSize)
236 {
237  typedef Tpetra::global_size_t GST;
238  typedef typename Teuchos::ArrayView<const GO>::size_type size_type;
239 
240  const GST gblNumMeshMapInds =
241  static_cast<GST> (meshMap.getGlobalNumElements ());
242  const size_t lclNumMeshMapIndices =
243  static_cast<size_t> (meshMap.getNodeNumElements ());
244  const GST gblNumPointMapInds =
245  gblNumMeshMapInds * static_cast<GST> (blockSize);
246  const size_t lclNumPointMapInds =
247  lclNumMeshMapIndices * static_cast<size_t> (blockSize);
248  const GO indexBase = meshMap.getIndexBase ();
249 
250  if (meshMap.isContiguous ()) {
251  return map_type (gblNumPointMapInds, lclNumPointMapInds, indexBase,
252  meshMap.getComm (), meshMap.getNode ());
253  }
254  else {
255  // "Hilbert's Hotel" trick: multiply each process' GIDs by
256  // blockSize, and fill in. That ensures correctness even if the
257  // mesh Map is overlapping.
258  Teuchos::ArrayView<const GO> lclMeshGblInds = meshMap.getNodeElementList ();
259  const size_type lclNumMeshGblInds = lclMeshGblInds.size ();
260  Teuchos::Array<GO> lclPointGblInds (lclNumPointMapInds);
261  for (size_type g = 0; g < lclNumMeshGblInds; ++g) {
262  const GO meshGid = lclMeshGblInds[g];
263  const GO pointGidStart = indexBase +
264  (meshGid - indexBase) * static_cast<GO> (blockSize);
265  const size_type offset = g * static_cast<size_type> (blockSize);
266  for (LO k = 0; k < blockSize; ++k) {
267  const GO pointGid = pointGidStart + static_cast<GO> (k);
268  lclPointGblInds[offset + static_cast<size_type> (k)] = pointGid;
269  }
270  }
271  return map_type (gblNumPointMapInds, lclPointGblInds (), indexBase,
272  meshMap.getComm (), meshMap.getNode ());
273  }
274 }
275 
276 
277 template<class Scalar, class LO, class GO, class Node>
278 void
280 replaceLocalValuesImpl (const LO localRowIndex,
281  const LO colIndex,
282  const Scalar vals[]) const
283 {
284  little_vec_type X_dst = getLocalBlock (localRowIndex, colIndex);
285  const LO strideX = 1;
286  const_little_vec_type X_src (reinterpret_cast<const impl_scalar_type*> (vals),
287  getBlockSize (), strideX);
288  X_dst.assign (X_src);
289 }
290 
291 
292 template<class Scalar, class LO, class GO, class Node>
293 bool
295 replaceLocalValues (const LO localRowIndex,
296  const LO colIndex,
297  const Scalar vals[]) const
298 {
299  if (! meshMap_.isNodeLocalElement (localRowIndex)) {
300  return false;
301  } else {
302  replaceLocalValuesImpl (localRowIndex, colIndex, vals);
303  return true;
304  }
305 }
306 
307 template<class Scalar, class LO, class GO, class Node>
308 bool
310 replaceGlobalValues (const GO globalRowIndex,
311  const LO colIndex,
312  const Scalar vals[]) const
313 {
314  const LO localRowIndex = meshMap_.getLocalElement (globalRowIndex);
315  if (localRowIndex == Teuchos::OrdinalTraits<LO>::invalid ()) {
316  return false;
317  } else {
318  replaceLocalValuesImpl (localRowIndex, colIndex, vals);
319  return true;
320  }
321 }
322 
323 template<class Scalar, class LO, class GO, class Node>
324 void
326 sumIntoLocalValuesImpl (const LO localRowIndex,
327  const LO colIndex,
328  const Scalar vals[]) const
329 {
330  little_vec_type X_dst = getLocalBlock (localRowIndex, colIndex);
331  const LO strideX = 1;
332  const_little_vec_type X_src (reinterpret_cast<const impl_scalar_type*> (vals),
333  getBlockSize (), strideX);
334  X_dst.update (STS::one (), X_src);
335 }
336 
337 template<class Scalar, class LO, class GO, class Node>
338 bool
340 sumIntoLocalValues (const LO localRowIndex,
341  const LO colIndex,
342  const Scalar vals[]) const
343 {
344  if (! meshMap_.isNodeLocalElement (localRowIndex)) {
345  return false;
346  } else {
347  sumIntoLocalValuesImpl (localRowIndex, colIndex, vals);
348  return true;
349  }
350 }
351 
352 template<class Scalar, class LO, class GO, class Node>
353 bool
355 sumIntoGlobalValues (const GO globalRowIndex,
356  const LO colIndex,
357  const Scalar vals[]) const
358 {
359  const LO localRowIndex = meshMap_.getLocalElement (globalRowIndex);
360  if (localRowIndex == Teuchos::OrdinalTraits<LO>::invalid ()) {
361  return false;
362  } else {
363  sumIntoLocalValuesImpl (localRowIndex, colIndex, vals);
364  return true;
365  }
366 }
367 
368 template<class Scalar, class LO, class GO, class Node>
369 bool
371 getLocalRowView (const LO localRowIndex, const LO colIndex, Scalar*& vals) const
372 {
373  if (! meshMap_.isNodeLocalElement (localRowIndex)) {
374  return false;
375  } else {
376  little_vec_type X_ij = getLocalBlock (localRowIndex, colIndex);
377  vals = reinterpret_cast<Scalar*> (X_ij.getRawPtr ());
378  return true;
379  }
380 }
381 
382 template<class Scalar, class LO, class GO, class Node>
383 bool
385 getGlobalRowView (const GO globalRowIndex, const LO colIndex, Scalar*& vals) const
386 {
387  const LO localRowIndex = meshMap_.getLocalElement (globalRowIndex);
388  if (localRowIndex == Teuchos::OrdinalTraits<LO>::invalid ()) {
389  return false;
390  } else {
391  little_vec_type X_ij = getLocalBlock (localRowIndex, colIndex);
392  vals = reinterpret_cast<Scalar*> (X_ij.getRawPtr ());
393  return true;
394  }
395 }
396 
397 template<class Scalar, class LO, class GO, class Node>
400 getLocalBlock (const LO localRowIndex,
401  const LO colIndex) const
402 {
403  if (! isValidLocalMeshIndex (localRowIndex)) {
404  return little_vec_type (NULL, 0, 0);
405  } else {
406  const LO strideX = this->getStrideX ();
407  const size_t blockSize = getBlockSize ();
408  const size_t offset = colIndex * this->getStrideY () +
409  localRowIndex * blockSize * strideX;
410  impl_scalar_type* blockRaw = this->getRawPtr () + offset;
411  return little_vec_type (blockRaw, blockSize, strideX);
412  }
413 }
414 
415 template<class Scalar, class LO, class GO, class Node>
416 Teuchos::RCP<const typename BlockMultiVector<Scalar, LO, GO, Node>::mv_type>
419 {
420  using Teuchos::rcp;
421  using Teuchos::rcpFromRef;
422 
423  // The source object of an Import or Export must be a
424  // BlockMultiVector or MultiVector (a Vector is a MultiVector). Try
425  // them in that order; one must succeed. Note that the target of
426  // the Import or Export calls checkSizes in DistObject's doTransfer.
428  const this_type* srcBlkVec = dynamic_cast<const this_type*> (&src);
429  if (srcBlkVec == NULL) {
430  const mv_type* srcMultiVec = dynamic_cast<const mv_type*> (&src);
431  if (srcMultiVec == NULL) {
432  // FIXME (mfh 05 May 2014) Tpetra::MultiVector's operator=
433  // currently does a shallow copy by default. This is why we
434  // return by RCP, rather than by value.
435  return rcp (new mv_type ());
436  } else { // src is a MultiVector
437  return rcp (srcMultiVec, false); // nonowning RCP
438  }
439  } else { // src is a BlockMultiVector
440  return rcpFromRef (srcBlkVec->mv_); // nonowning RCP
441  }
442 }
443 
444 template<class Scalar, class LO, class GO, class Node>
447 {
448  return ! getMultiVectorFromSrcDistObject (src).is_null ();
449 }
450 
451 template<class Scalar, class LO, class GO, class Node>
454  size_t numSameIDs,
455  const Teuchos::ArrayView<const LO>& permuteToLIDs,
456  const Teuchos::ArrayView<const LO>& permuteFromLIDs)
457 {
458  const char tfecfFuncName[] = "copyAndPermute: ";
459  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
460  permuteToLIDs.size() != permuteFromLIDs.size(), std::runtime_error,
461  "permuteToLIDs and permuteFromLIDs must have the same size."
462  << std::endl << "permuteToLIDs.size() = " << permuteToLIDs.size ()
463  << " != permuteFromLIDs.size() = " << permuteFromLIDs.size () << ".");
464 
466  Teuchos::RCP<const BMV> srcAsBmvPtr = getBlockMultiVectorFromSrcDistObject (src);
467  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
468  srcAsBmvPtr.is_null (), std::invalid_argument,
469  "The source of an Import or Export to a BlockMultiVector "
470  "must also be a BlockMultiVector.");
471  const BMV& srcAsBmv = *srcAsBmvPtr;
472 
473  // FIXME (mfh 23 Apr 2014) This implementation is sequential and
474  // assumes UVM.
475 
476  const LO numVecs = getNumVectors ();
477  const LO numSame = static_cast<LO> (numSameIDs);
478  for (LO j = 0; j < numVecs; ++j) {
479  for (LO lclRow = 0; lclRow < numSame; ++lclRow) {
480  getLocalBlock (lclRow, j).assign (srcAsBmv.getLocalBlock (lclRow, j));
481  }
482  }
483 
484  // FIXME (mfh 20 June 2012) For an Export with duplicate GIDs on the
485  // same process, this merges their values by replacement of the last
486  // encountered GID, not by the specified merge rule (such as ADD).
487  const LO numPermuteLIDs = static_cast<LO> (permuteToLIDs.size ());
488  for (LO j = 0; j < numVecs; ++j) {
489  for (LO k = numSame; k < numPermuteLIDs; ++k) {
490  getLocalBlock (permuteToLIDs[k], j).assign (srcAsBmv.getLocalBlock (permuteFromLIDs[k], j));
491  }
492  }
493 }
494 
495 template<class Scalar, class LO, class GO, class Node>
498  const Teuchos::ArrayView<const LO>& exportLIDs,
499  Teuchos::Array<impl_scalar_type>& exports,
500  const Teuchos::ArrayView<size_t>& /* numPacketsPerLID */,
501  size_t& constantNumPackets,
502  Tpetra::Distributor& /* distor */)
503 {
505  typedef typename Teuchos::ArrayView<const LO>::size_type size_type;
506  const char tfecfFuncName[] = "packAndPrepare: ";
507 
508  Teuchos::RCP<const BMV> srcAsBmvPtr = getBlockMultiVectorFromSrcDistObject (src);
509  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
510  srcAsBmvPtr.is_null (), std::invalid_argument,
511  "The source of an Import or Export to a BlockMultiVector "
512  "must also be a BlockMultiVector.");
513  const BMV& srcAsBmv = *srcAsBmvPtr;
514 
515  const LO numVecs = getNumVectors ();
516  const LO blockSize = getBlockSize ();
517 
518  // Number of things to pack per LID is the block size, times the
519  // number of columns. Input LIDs correspond to the mesh points, not
520  // the degrees of freedom (DOFs).
521  constantNumPackets =
522  static_cast<size_t> (blockSize) * static_cast<size_t> (numVecs);
523  const size_type numMeshLIDs = exportLIDs.size ();
524 
525  const size_type requiredExportsSize = numMeshLIDs *
526  static_cast<size_type> (blockSize) * static_cast<size_type> (numVecs);
527  exports.resize (requiredExportsSize);
528 
529  try {
530  size_type curExportPos = 0;
531  for (size_type meshLidIndex = 0; meshLidIndex < numMeshLIDs; ++meshLidIndex) {
532  for (LO j = 0; j < numVecs; ++j, curExportPos += blockSize) {
533  const LO meshLid = exportLIDs[meshLidIndex];
534  impl_scalar_type* const curExportPtr = &exports[curExportPos];
535  little_vec_type X_dst (curExportPtr, blockSize, 1);
536  little_vec_type X_src = srcAsBmv.getLocalBlock (meshLid, j);
537 
538  X_dst.assign (X_src);
539  }
540  }
541  } catch (std::exception& e) {
542  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
543  true, std::logic_error, "Oh no! packAndPrepare on Process "
544  << meshMap_.getComm ()->getRank () << " raised the following exception: "
545  << e.what ());
546  }
547 }
548 
549 template<class Scalar, class LO, class GO, class Node>
551 unpackAndCombine (const Teuchos::ArrayView<const LO>& importLIDs,
552  const Teuchos::ArrayView<const impl_scalar_type>& imports,
553  const Teuchos::ArrayView<size_t>& numPacketsPerLID,
554  size_t constantNumPackets,
555  Tpetra::Distributor& distor,
557 {
558  typedef typename Teuchos::ArrayView<const LO>::size_type size_type;
559  const char tfecfFuncName[] = "unpackAndCombine: ";
560 
561  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
562  CM != ADD && CM != REPLACE && CM != INSERT && CM != ABSMAX && CM != ZERO,
563  std::invalid_argument, "Invalid CombineMode: " << CM << ". Valid "
564  "CombineMode values are ADD, REPLACE, INSERT, ABSMAX, and ZERO.");
565 
566  if (CM == ZERO) {
567  return; // Combining does nothing, so we don't have to combine anything.
568  }
569 
570  // Number of things to pack per LID is the block size.
571  // Input LIDs correspond to the mesh points, not the DOFs.
572  const size_type numMeshLIDs = importLIDs.size ();
573  const LO blockSize = getBlockSize ();
574  const LO numVecs = getNumVectors ();
575 
576  const size_type requiredImportsSize = numMeshLIDs *
577  static_cast<size_type> (blockSize) * static_cast<size_type> (numVecs);
578  TEUCHOS_TEST_FOR_EXCEPTION_CLASS_FUNC(
579  imports.size () < requiredImportsSize, std::logic_error,
580  ": imports.size () = " << imports.size ()
581  << " < requiredImportsSize = " << requiredImportsSize << ".");
582 
583  size_type curImportPos = 0;
584  for (size_type meshLidIndex = 0; meshLidIndex < numMeshLIDs; ++meshLidIndex) {
585  for (LO j = 0; j < numVecs; ++j, curImportPos += blockSize) {
586  const LO meshLid = importLIDs[meshLidIndex];
587  const impl_scalar_type* const curImportPtr = &imports[curImportPos];
588 
589  const_little_vec_type X_src (curImportPtr, blockSize, 1);
590  little_vec_type X_dst = getLocalBlock (meshLid, j);
591 
592  if (CM == INSERT || CM == REPLACE) {
593  X_dst.assign (X_src);
594  } else if (CM == ADD) {
595  X_dst.update (STS::one (), X_src);
596  } else if (CM == ABSMAX) {
597  X_dst.absmax (X_src);
598  }
599  }
600  }
601 }
602 
603 template<class Scalar, class LO, class GO, class Node>
605 putScalar (const Scalar& val)
606 {
607  getMultiVectorView ().putScalar (val);
608 }
609 
610 template<class Scalar, class LO, class GO, class Node>
612 scale (const Scalar& val)
613 {
614  getMultiVectorView ().scale (val);
615 }
616 
617 } // namespace Experimental
618 } // namespace Tpetra
619 
620 //
621 // Explicit instantiation macro
622 //
623 // Must be expanded from within the Tpetra namespace!
624 //
625 #define TPETRA_EXPERIMENTAL_BLOCKMULTIVECTOR_INSTANT(S,LO,GO,NODE) \
626  template class Experimental::BlockMultiVector< S, LO, GO, NODE >;
627 
628 #endif // TPETRA_EXPERIMENTAL_BLOCKMULTIVECTOR_DEF_HPP
void scale(const Scalar &alpha)
Scale in place: this = alpha*this.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
mv_type mv_
The Tpetra::MultiVector used to represent the data.
bool isContiguous() const
True if this Map is distributed contiguously, else false.
void putScalar(const Scalar &val)
Fill all entries with the given value val.
mv_type getMultiVectorView()
Get a Tpetra::MultiVector that views this BlockMultiVector&#39;s data.
Tpetra::Map< LO, GO, Node > map_type
The specialization of Tpetra::Map that this class uses.
bool replaceGlobalValues(const GO globalRowIndex, const LO colIndex, const Scalar vals[]) const
Replace all values at the given mesh point, using a global index.
void setCopyOrView(const Teuchos::DataAccess copyOrView)
Set whether this has copy (copyOrView = Teuchos::Copy) or view (copyOrView = Teuchos::View) semantics...
One or more distributed dense vectors.
bool sumIntoGlobalValues(const GO globalRowIndex, const LO colIndex, const Scalar vals[]) const
Sum into all values at the given mesh point, using a global index.
MultiVector for multiple degrees of freedom per mesh point.
GlobalOrdinal getIndexBase() const
The index base for this Map.
static map_type makePointMap(const map_type &meshMap, const LO blockSize)
Create and return the point Map corresponding to the given mesh Map and block size.
Teuchos::RCP< const Teuchos::Comm< int > > getComm() const
Accessors for the Teuchos::Comm and Kokkos Node objects.
virtual void unpackAndCombine(const Teuchos::ArrayView< const LO > &importLIDs, const Teuchos::ArrayView< const impl_scalar_type > &imports, const Teuchos::ArrayView< size_t > &numPacketsPerLID, size_t constantNumPackets, Tpetra::Distributor &distor, Tpetra::CombineMode CM)
Perform any unpacking and combining after communication.
void assign(const LittleVectorType &X) const
*this := X.
void scale(const Scalar &val)
Multiply all entries in place by the given value val.
little_vec_type getLocalBlock(const LO localRowIndex, const LO colIndex) const
Get a view of the degrees of freedom at the given mesh point.
bool isNodeLocalElement(LocalOrdinal localIndex) const
Whether the given local index is valid for this Map on the calling process.
LO getBlockSize() const
Get the number of degrees of freedom per mesh point.
size_t global_size_t
Global size_t object.
Insert new values that don&#39;t currently exist.
impl_scalar_type * getRawPtr() const
Raw pointer to the MultiVector&#39;s data.
Scalar * getRawPtr() const
Pointer to the block&#39;s entries.
Nonowning view of a set of degrees of freedom corresponding to a mesh point in a block vector or mult...
LO getNumVectors() const
Get the number of columns (vectors) in the BlockMultiVector.
Sets up and executes a communication plan for a Tpetra DistObject.
CombineMode
Rule for combining data in an Import or Export.
Sum new values into existing values.
Teuchos::RCP< Node > getNode() const
Get this Map&#39;s Node object.
bool getLocalRowView(const LO localRowIndex, const LO colIndex, Scalar *&vals) const
Get a writeable view of the entries at the given mesh point, using a local index. ...
Replace old value with maximum of magnitudes of old and new values.
Abstract base class for objects that can be the source of an Import or Export operation.
bool isValidLocalMeshIndex(const LO meshLocalIndex) const
True if and only if meshLocalIndex is a valid local index in the mesh Map.
Replace existing values with new values.
Replace old values with zero.
Teuchos::DataAccess getCopyOrView() const
Get whether this has copy (copyOrView = Teuchos::Copy) or view (copyOrView = Teuchos::View) semantics...
void putScalar(const Scalar &value)
Set all values in the multivector with the given value.
Kokkos::Details::ArithTraits< Scalar >::val_type impl_scalar_type
The type used internally in place of Scalar.
LocalOrdinal getLocalElement(GlobalOrdinal globalIndex) const
The local index corresponding to the given global index.
Teuchos::ArrayView< const GlobalOrdinal > getNodeElementList() const
Return a view of the global indices owned by this process.
virtual bool checkSizes(const Tpetra::SrcDistObject &source)
Compare the source and target (this) objects for compatibility.
size_t getNodeNumElements() const
The number of elements belonging to the calling process.
LittleVector< impl_scalar_type, LO > little_vec_type
"Block view" of all degrees of freedom at a mesh point, for a single column of the MultiVector...
size_t getStrideY() const
Stride between consecutive local entries in the same row.
virtual void copyAndPermute(const Tpetra::SrcDistObject &source, size_t numSameIDs, const Teuchos::ArrayView< const LO > &permuteToLIDs, const Teuchos::ArrayView< const LO > &permuteFromLIDs)
Perform copies and permutations that are local to this process.
void update(const Scalar &alpha, const LittleVectorType &X) const
*this := *this + alpha * X.
size_t getNumVectors() const
Number of columns in the multivector.
virtual Teuchos::RCP< const map_type > getMap() const
The Map describing the parallel distribution of this object.
void absmax(const LittleVectorType &X) const
(*this)(i,j) := max(abs((*this)(i,j)), abs(X(i,j))) for all (i,j).
bool replaceLocalValues(const LO localRowIndex, const LO colIndex, const Scalar vals[]) const
Replace all values at the given mesh point, using local row and column indices.
Teuchos::RCP< const MultiVector< Scalar, LocalOrdinal, GlobalOrdinal, Node, classic > > subView(const Teuchos::Range1D &colRng) const
Return a const MultiVector with const views of selected columns.
size_t getStrideX() const
Stride between consecutive local entries in the same column.
virtual void packAndPrepare(const Tpetra::SrcDistObject &source, const Teuchos::ArrayView< const LO > &exportLIDs, Teuchos::Array< impl_scalar_type > &exports, const Teuchos::ArrayView< size_t > &numPacketsPerLID, size_t &constantNumPackets, Tpetra::Distributor &distor)
Perform any packing or preparation required for communication.
bool sumIntoLocalValues(const LO localRowIndex, const LO colIndex, const Scalar vals[]) const
Sum into all values at the given mesh point, using a local index.
global_size_t getGlobalNumElements() const
The number of elements in this Map.
bool getGlobalRowView(const GO globalRowIndex, const LO colIndex, Scalar *&vals) const
Get a writeable view of the entries at the given mesh point, using a global index.