Tpetra parallel linear algebra  Version of the Day
Tpetra_Util.hpp
Go to the documentation of this file.
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 // ************************************************************************
38 // @HEADER
39 
40 #ifndef TPETRA_UTIL_HPP
41 #define TPETRA_UTIL_HPP
42 
52 #include "Tpetra_ConfigDefs.hpp"
53 #include "Kokkos_DualView.hpp"
54 #include "KokkosCompat_View.hpp"
55 #include "Teuchos_Assert.hpp"
56 #include "Teuchos_CommHelpers.hpp"
57 #include "Teuchos_OrdinalTraits.hpp"
58 #include "Teuchos_TypeNameTraits.hpp"
59 #include "Teuchos_Utils.hpp"
60 #include <algorithm>
61 #include <iterator>
62 #include <memory>
63 #include <ostream>
64 #include <sstream>
65 
66 #if defined(HAVE_TPETRA_THROW_EFFICIENCY_WARNINGS) || defined(HAVE_TPETRA_PRINT_EFFICIENCY_WARNINGS)
100 #define TPETRA_EFFICIENCY_WARNING(throw_exception_test,Exception,msg) \
101 { \
102  const bool tpetraEfficiencyWarningTest = (throw_exception_test); \
103  if (tpetraEfficiencyWarningTest) { \
104  std::ostringstream errStream; \
105  errStream << Teuchos::typeName(*this) << ":" << std::endl; \
106  errStream << "Efficiency warning: " << #throw_exception_test << std::endl; \
107  errStream << msg; \
108  std::string err = errStream.str(); \
109  if (TPETRA_PRINTS_EFFICIENCY_WARNINGS && tpetraEfficiencyWarningTest) { \
110  std::cerr << err << std::endl; \
111  } \
112  TEUCHOS_TEST_FOR_EXCEPTION(TPETRA_THROWS_EFFICIENCY_WARNINGS && tpetraEfficiencyWarningTest, Exception, err); \
113  } \
114 }
115 #else
149 #define TPETRA_EFFICIENCY_WARNING(throw_exception_test,Exception,msg)
150 #endif
151 
152 // handle an abuse warning, according to HAVE_TPETRA_THROW_ABUSE_WARNINGS and HAVE_TPETRA_PRINT_ABUSE_WARNINGS
153 #if defined(HAVE_TPETRA_THROW_ABUSE_WARNINGS) || defined(HAVE_TPETRA_PRINT_ABUSE_WARNINGS)
155 #define TPETRA_ABUSE_WARNING(throw_exception_test,Exception,msg) \
156 { \
157  std::ostringstream errStream; \
158  errStream << Teuchos::typeName(*this) << msg; \
159  std::string err = errStream.str(); \
160  if (TPETRA_PRINTS_ABUSE_WARNINGS && (throw_exception_test)) { \
161  std::cerr << err << std::endl; \
162  } \
163  TEUCHOS_TEST_FOR_EXCEPTION(TPETRA_THROWS_ABUSE_WARNINGS && (throw_exception_test), Exception, err); \
164 }
165 #else
167 #define TPETRA_ABUSE_WARNING(throw_exception_test,Exception,msg)
168 #endif
169 
199 #define SHARED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm) \
200 { \
201  using Teuchos::outArg; \
202  const int lcl_throw_exception = (throw_exception_test) ? Teuchos::rank(comm)+1 : 0; \
203  int gbl_throw; \
204  Teuchos::reduceAll(comm,Teuchos::REDUCE_MAX,lcl_throw_exception,outArg(gbl_throw)); \
205  TEUCHOS_TEST_FOR_EXCEPTION(gbl_throw,Exception, \
206  msg << " Failure on at least one process, including process " << gbl_throw-1 << "." << std::endl); \
207 }
208 
209 #ifdef HAVE_TEUCHOS_DEBUG
211 #define SWITCHED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm) \
212 { \
213  SHARED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm); \
214 }
215 #else
217 #define SWITCHED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm) \
218 { \
219  TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg); \
220 }
221 #endif
222 
223 namespace Tpetra {
224 
236  template<typename MapType, typename KeyArgType, typename ValueArgType>
237  typename MapType::iterator efficientAddOrUpdate(MapType& m,
238  const KeyArgType & k,
239  const ValueArgType & v)
240  {
241  typename MapType::iterator lb = m.lower_bound(k);
242  if(lb != m.end() && !(m.key_comp()(k, lb->first))) {
243  lb->second = v;
244  return(lb);
245  }
246  else {
247  typedef typename MapType::value_type MVT;
248  return(m.insert(lb, MVT(k, v)));
249  }
250  }
251 
259  namespace SortDetails {
260 
269  template<class IT1>
270  bool isAlreadySorted(const IT1& first, const IT1& last){
271  typedef typename std::iterator_traits<IT1>::difference_type DT;
272  DT myit = Teuchos::OrdinalTraits<DT>::one();
273  const DT sz = last - first;
274  for(;myit < sz; ++myit){
275  if(first[myit] < first[myit-1]){
276  return false;
277  }
278  }
279  return true;
280  }
281 
291  template<class IT>
292  IT getPivot(const IT& first, const IT& last){
293  IT pivot(first+(last-first)/2);
294  if(*first<=*pivot && *(last-1)<=*first) pivot=first;
295  else if(*(last-1)<=*pivot && *first<= *(last-1)) pivot = last-1;
296  return pivot;
297  }
298 
313  template<class IT1, class IT2>
315  const IT1& first1,
316  const IT1& last1,
317  const IT2& first2,
318  const IT2& last2,
319  const IT1& pivot)
320  {
321  typename std::iterator_traits<IT1>::value_type piv(*pivot);
322  std::swap(*pivot, *(last1-1));
323  std::swap(first2[(pivot-first1)], *(last2-1));
324  IT1 store1=first1;
325  for(IT1 it=first1; it!=last1-1; ++it){
326  if(*it<=piv){
327  std::swap(*store1, *it);
328  std::swap(first2[(store1-first1)], first2[(it-first1)]);
329  ++store1;
330  }
331  }
332  std::swap(*(last1-1), *store1);
333  std::swap(*(last2-1), first2[store1-first1]);
334  return store1;
335  }
336 
353  template<class IT1, class IT2, class IT3>
355  const IT1& first1,
356  const IT1& last1,
357  const IT2& first2,
358  const IT2& last2,
359  const IT3& first3,
360  const IT3& last3,
361  const IT1& pivot)
362  {
363  typename std::iterator_traits<IT1>::value_type piv(*pivot);
364  std::swap(*pivot, *(last1-1));
365  std::swap(first2[(pivot-first1)], *(last2-1));
366  std::swap(first3[(pivot-first1)], *(last3-1));
367  IT1 store1=first1;
368  for(IT1 it=first1; it!=last1-1; ++it){
369  if(*it<=piv){
370  std::swap(*store1, *it);
371  std::swap(first2[(store1-first1)], first2[(it-first1)]);
372  std::swap(first3[(store1-first1)], first3[(it-first1)]);
373  ++store1;
374  }
375  }
376  std::swap(*(last1-1), *store1);
377  std::swap(*(last2-1), first2[store1-first1]);
378  std::swap(*(last3-1), first3[store1-first1]);
379  return store1;
380  }
381 
392  template<class IT1, class IT2>
394  const IT1& first1,
395  const IT1& last1,
396  const IT2& first2,
397  const IT2& last2)
398  {
399  typedef typename std::iterator_traits<IT1>::difference_type DT;
400  DT DT1 = Teuchos::OrdinalTraits<DT>::one();
401  if(last1-first1 > DT1){
402  IT1 pivot = getPivot(first1, last1);
403  pivot = partition2(first1, last1, first2, last2, pivot);
404  quicksort2(first1, pivot, first2, first2+(pivot-first1));
405  quicksort2(pivot+1, last1, first2+(pivot-first1)+1, last2);
406  }
407  }
408 
421  template<class IT1, class IT2, class IT3>
423  const IT1& first1,
424  const IT1& last1,
425  const IT2& first2,
426  const IT2& last2,
427  const IT3& first3,
428  const IT3& last3)
429  {
430  typedef typename std::iterator_traits<IT1>::difference_type DT;
431  DT DT1 = Teuchos::OrdinalTraits<DT>::one();
432  if(last1-first1 > DT1){
433  IT1 pivot = getPivot(first1, last1);
434  pivot = partition3(first1, last1, first2, last2, first3, last3, pivot);
435  quicksort3(first1, pivot, first2, first2+(pivot-first1), first3, first3+(pivot-first1));
436  quicksort3(pivot+1, last1, first2+(pivot-first1)+1, last2, first3+(pivot-first1)+1, last3);
437  }
438  }
439 
446  template<class IT1, class IT2, class IT3>
447  void sh_sort3(
448  const IT1& first1,
449  const IT1& last1,
450  const IT2& first2,
451  const IT2& /* last2 */,
452  const IT3& first3,
453  const IT3& /* last3 */)
454  {
455  typedef typename std::iterator_traits<IT1>::difference_type DT;
456  DT n = last1 - first1;
457  DT m = n / 2;
458  DT z = Teuchos::OrdinalTraits<DT>::zero();
459  while (m > z)
460  {
461  DT max = n - m;
462  for (DT j = 0; j < max; j++)
463  {
464  for (DT k = j; k >= 0; k-=m)
465  {
466  if (first1[k+m] >= first1[k])
467  break;
468  std::swap(first1[k+m], first1[k]);
469  std::swap(first2[k+m], first2[k]);
470  std::swap(first3[k+m], first3[k]);
471  }
472  }
473  m = m/2;
474  }
475  }
476 
483  template<class IT1, class IT2>
484  void sh_sort2(
485  const IT1& first1,
486  const IT1& last1,
487  const IT2& first2,
488  const IT2& /* last2 */)
489  {
490  typedef typename std::iterator_traits<IT1>::difference_type DT;
491  DT n = last1 - first1;
492  DT m = n / 2;
493  DT z = Teuchos::OrdinalTraits<DT>::zero();
494  while (m > z)
495  {
496  DT max = n - m;
497  for (DT j = 0; j < max; j++)
498  {
499  for (DT k = j; k >= 0; k-=m)
500  {
501  if (first1[k+m] >= first1[k])
502  break;
503  std::swap(first1[k+m], first1[k]);
504  std::swap(first2[k+m], first2[k]);
505  }
506  }
507  m = m/2;
508  }
509  }
510 
511  } //end namespace SortDetails
512 
513 
532  template<class IT1, class IT2>
533  void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2) {
534  // Quicksort uses best-case N log N time whether or not the input
535  // data is sorted. However, the common case in Tpetra is that the
536  // input data are sorted, so we first check whether this is the
537  // case before reverting to Quicksort.
538  if(SortDetails::isAlreadySorted(first1, last1)){
539  return;
540  }
541  SortDetails::sh_sort2(first1, last1, first2, first2+(last1-first1));
542 #ifdef HAVE_TPETRA_DEBUG
543  if(!SortDetails::isAlreadySorted(first1, last1)){
544  std::cout << "Trouble: sort() did not sort !!" << std::endl;
545  return;
546  }
547 #endif
548  }
549 
550 
567  template<class View1, class View2>
568  void sort2(View1 &view1, const size_t &size, View2 &view2) {
569  // NOTE: This assumes the view is host-accessible.
570 
571  // Wrap the views as rcps (this happens to preserve the reference counting, but that doesn't really matter here)
572  Teuchos::ArrayRCP<typename View1::non_const_value_type> view1_rcp = Kokkos::Compat::persistingView(view1, 0, size);
573  Teuchos::ArrayRCP<typename View2::non_const_value_type> view2_rcp = Kokkos::Compat::persistingView(view2, 0, size);
574 
575  sort2(view1_rcp.begin(),view1_rcp.end(),view2_rcp.begin());
576  }
577 
586  template<class View>
587  void sort(View &view, const size_t &size) {
588  // NOTE: This assumes the view is host-accessible.
589 
590  // Wrap the view as rcps (this happens to preserve the reference counting, but that doesn't really matter here)
591  Teuchos::ArrayRCP<typename View::non_const_value_type> view_rcp = Kokkos::Compat::persistingView(view, 0, size);
592 
593  std::sort(view_rcp.begin(),view_rcp.end());
594  }
595 
604  template<class View>
605  void reverse_sort(View &view, const size_t &size) {
606  // NOTE: This assumes the view is host-accessible.
607  // Wrap the view as rcps (this happens to preserve the reference counting, but that doesn't really matter here)
608  Teuchos::ArrayRCP<typename View::non_const_value_type> view_rcp = Kokkos::Compat::persistingView(view, 0, size);
609 
610  std::sort(view_rcp.rbegin(),view_rcp.rend());
611  }
612 
613 
614 
615 
631  template<class IT1, class IT2, class IT3>
632  void sort3(const IT1 &first1, const IT1 &last1, const IT2 &first2,
633  const IT3 &first3)
634  {
635  // Quicksort uses best-case N log N time whether or not the input
636  // data is sorted. However, the common case in Tpetra is that the
637  // input data are sorted, so we first check whether this is the
638  // case before reverting to Quicksort.
639  if(SortDetails::isAlreadySorted(first1, last1)){
640  return;
641  }
642  SortDetails::sh_sort3(first1, last1, first2, first2+(last1-first1), first3,
643  first3+(last1-first1));
644 
645 #ifdef HAVE_TPETRA_DEBUG
646  if(!SortDetails::isAlreadySorted(first1, last1)){
647  std::cout << " Trouble sort did not actually sort... !!!!!!" <<
648  std::endl;
649  return;
650  }
651 #endif
652  }
653 
697  template<class IT1, class IT2>
698  void
699  merge2 (IT1& indResultOut, IT2& valResultOut,
700  IT1 indBeg, IT1 indEnd,
701  IT2 valBeg, IT2 /* valEnd */)
702  {
703  if (indBeg == indEnd) {
704  indResultOut = indBeg; // It's allowed for indResultOut to alias indEnd
705  valResultOut = valBeg; // It's allowed for valResultOut to alias valEnd
706  }
707  else {
708  IT1 indResult = indBeg;
709  IT2 valResult = valBeg;
710  if (indBeg != indEnd) {
711  ++indBeg;
712  ++valBeg;
713  while (indBeg != indEnd) {
714  if (*indResult == *indBeg) { // adjacent column indices equal
715  *valResult += *valBeg; // merge entries by adding their values together
716  } else { // adjacent column indices not equal
717  *(++indResult) = *indBeg; // shift over the index
718  *(++valResult) = *valBeg; // shift over the value
719  }
720  ++indBeg;
721  ++valBeg;
722  }
723  ++indResult; // exclusive end of merged result
724  ++valResult; // exclusive end of merged result
725 
726  // mfh 24 Feb 2014: Setting these is technically correct, but
727  // since the resulting variables aren't used after this point,
728  // it may result in a build error.
729  //
730  // indEnd = indResult;
731  // valEnd = valResult;
732  }
733  indResultOut = indResult;
734  valResultOut = valResult;
735  }
736  }
737 
786  template<class IT1, class IT2, class BinaryFunction>
787  void
788  merge2 (IT1& indResultOut, IT2& valResultOut,
789  IT1 indBeg, IT1 indEnd,
790  IT2 valBeg, IT2 valEnd,
791  BinaryFunction f)
792  {
793  if (indBeg == indEnd) {
794  indResultOut = indBeg; // It's allowed for indResultOut to alias indEnd
795  valResultOut = valBeg; // It's allowed for valResultOut to alias valEnd
796  }
797  else {
798  IT1 indResult = indBeg;
799  IT2 valResult = valBeg;
800  if (indBeg != indEnd) {
801  ++indBeg;
802  ++valBeg;
803  while (indBeg != indEnd) {
804  if (*indResult == *indBeg) { // adjacent column indices equal
805  *valResult = f (*valResult, *valBeg); // merge entries via values
806  } else { // adjacent column indices not equal
807  *(++indResult) = *indBeg; // shift over the index
808  *(++valResult) = *valBeg; // shift over the value
809  }
810  ++indBeg;
811  ++valBeg;
812  }
813  ++indResult; // exclusive end of merged result
814  ++valResult; // exclusive end of merged result
815  indEnd = indResult;
816  valEnd = valResult;
817  }
818  indResultOut = indResult;
819  valResultOut = valResult;
820  }
821  }
822 
823 
852  template<class KeyInputIterType, class ValueInputIterType,
853  class KeyOutputIterType, class ValueOutputIterType,
854  class BinaryFunction>
855  void
856  keyValueMerge (KeyInputIterType keyBeg1, KeyInputIterType keyEnd1,
857  ValueInputIterType valBeg1, ValueInputIterType valEnd1,
858  KeyInputIterType keyBeg2, KeyInputIterType keyEnd2,
859  ValueInputIterType valBeg2, ValueInputIterType valEnd2,
860  KeyOutputIterType keyOut, ValueOutputIterType valOut,
861  BinaryFunction f)
862  {
863  while (keyBeg1 != keyEnd1 && keyBeg2 != keyEnd2) {
864  if (*keyBeg1 < *keyBeg2) {
865  *keyOut++ = *keyBeg1++;
866  *valOut++ = *valBeg1++;
867  } else if (*keyBeg1 > *keyBeg2) {
868  *keyOut++ = *keyBeg2++;
869  *valOut++ = *valBeg2++;
870  } else { // *keyBeg1 == *keyBeg2
871  *keyOut++ = *keyBeg1;
872  *valOut++ = f (*valBeg1, *valBeg2);
873  ++keyBeg1;
874  ++valBeg1;
875  ++keyBeg2;
876  ++valBeg2;
877  }
878  }
879  // At most one of the two sequences will be nonempty.
880  std::copy (keyBeg1, keyEnd1, keyOut);
881  std::copy (valBeg1, valEnd1, valOut);
882  std::copy (keyBeg2, keyEnd2, keyOut);
883  std::copy (valBeg2, valEnd2, valOut);
884  }
885 
886  template<class KeyInputIterType>
887  size_t
888  keyMergeCount (KeyInputIterType keyBeg1, KeyInputIterType keyEnd1,
889  KeyInputIterType keyBeg2, KeyInputIterType keyEnd2)
890  {
891  size_t count = 0;
892  while (keyBeg1 != keyEnd1 && keyBeg2 != keyEnd2) {
893  if (*keyBeg1 < *keyBeg2) {
894  ++keyBeg1;
895  } else if (*keyBeg1 > *keyBeg2) {
896  ++keyBeg2;
897  } else { // *keyBeg1 == *keyBeg2
898  ++keyBeg1;
899  ++keyBeg2;
900  }
901  ++count;
902  }
903  // At most one of the two sequences will be nonempty.
904  count += static_cast<size_t> (keyEnd1 - keyBeg1) +
905  static_cast<size_t> (keyEnd2 - keyBeg2);
906  return count;
907  }
908 
909  namespace Details {
929  bool
930  congruent (const Teuchos::Comm<int>& comm1,
931  const Teuchos::Comm<int>& comm2);
932 
942  template<class DualViewType>
943  Teuchos::ArrayView<typename DualViewType::t_dev::value_type>
944  getArrayViewFromDualView (const DualViewType& x)
945  {
946  static_assert (static_cast<int> (DualViewType::t_dev::rank) == 1,
947  "The input DualView must have rank 1.");
948  TEUCHOS_TEST_FOR_EXCEPTION
949  (x.need_sync_host (), std::logic_error, "The "
950  "input Kokkos::DualView was most recently modified on device, but this "
951  "function needs the host view of the data to be the most recently "
952  "modified.");
953 
954  auto x_host = x.view_host ();
955  typedef typename DualViewType::t_dev::value_type value_type;
956  // mfh 15 Jan 2019: In debug mode, Teuchos::ArrayView's
957  // constructor throws if the pointer is nonnull but the length
958  // is nonpositive.
959  const auto len = x_host.extent (0);
960  return Teuchos::ArrayView<value_type> (len != 0 ? x_host.data () : nullptr,
961  len);
962  }
963 
980  template<class T, class DT>
981  Kokkos::DualView<T*, DT>
982  getDualViewCopyFromArrayView (const Teuchos::ArrayView<const T>& x_av,
983  const char label[],
984  const bool leaveOnHost)
985  {
986  using Kokkos::MemoryUnmanaged;
987  typedef typename DT::memory_space DMS;
988  typedef Kokkos::HostSpace HMS;
989 
990  const size_t len = static_cast<size_t> (x_av.size ());
991  Kokkos::View<const T*, HMS, MemoryUnmanaged> x_in (x_av.getRawPtr (), len);
992  Kokkos::DualView<T*, DT> x_out (label, len);
993  if (leaveOnHost) {
994  x_out.modify_host ();
995  Kokkos::deep_copy (x_out.view_host (), x_in);
996  }
997  else {
998  x_out.template modify<DMS> ();
999  Kokkos::deep_copy (x_out.template view<DMS> (), x_in);
1000  }
1001  return x_out;
1002  }
1003 
1011  template<class DualViewType>
1012  std::string dualViewStatusToString (const DualViewType& dv, const char name[])
1013  {
1014  const auto host = dv.need_sync_device();
1015  const auto dev = dv.need_sync_host();
1016 
1017  std::ostringstream os;
1018  os << name << ": {size: " << dv.extent (0)
1019  << ", sync: {host: " << host << ", dev: " << dev << "}";
1020  return os.str ();
1021  }
1022 
1027  template<class ArrayType>
1028  void
1029  verbosePrintArray(std::ostream& out,
1030  const ArrayType& x,
1031  const char name[],
1032  const size_t maxNumToPrint)
1033  {
1034  out << name << ": [";
1035 
1036  const size_t numEnt(x.size());
1037  if (maxNumToPrint == 0) {
1038  if (numEnt != 0) {
1039  out << "...";
1040  }
1041  }
1042  else {
1043  const size_t numToPrint = numEnt > maxNumToPrint ?
1044  maxNumToPrint : numEnt;
1045  size_t k = 0;
1046  for ( ; k < numToPrint; ++k) {
1047  out << x[k];
1048  if (k + size_t(1) < numToPrint) {
1049  out << ", ";
1050  }
1051  }
1052  if (k < numEnt) {
1053  out << ", ...";
1054  }
1055  }
1056  out << "]";
1057  }
1058 
1062  std::unique_ptr<std::string>
1063  createPrefix(const int myRank,
1064  const char prefix[]);
1065 
1073  std::unique_ptr<std::string>
1074  createPrefix(const Teuchos::Comm<int>* comm,
1075  const char functionName[]);
1076 
1083  std::unique_ptr<std::string>
1084  createPrefix(const Teuchos::Comm<int>*,
1085  const char className[],
1086  const char methodName[]);
1087 
1088  } // namespace Details
1089 } // namespace Tpetra
1090 
1091 #endif // TPETRA_UTIL_HPP
void sh_sort3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT2 &, const IT3 &first3, const IT3 &)
Sort the first array using shell sort, and apply the resulting permutation to the second and third ar...
IT1 partition2(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT2 &last2, const IT1 &pivot)
Partition operation for quicksort2().
void quicksort2(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT2 &last2)
Sort the first array using Quicksort, and apply the resulting permutation to the second array.
IT getPivot(const IT &first, const IT &last)
Determines the pivot point as part of the quicksort routine.
IT1 partition3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT2 &last2, const IT3 &first3, const IT3 &last3, const IT1 &pivot)
Partition operation for quicksort3().
void sh_sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT2 &)
Sort the first array using shell sort, and apply the resulting permutation to the second array.
bool isAlreadySorted(const IT1 &first, const IT1 &last)
Determines whether or not a random access sequence is already sorted.
void quicksort3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT2 &last2, const IT3 &first3, const IT3 &last3)
Sort the first array using Quicksort, and apply the resulting permutation to the second and third arr...
Implementation details of Tpetra.
Implementation details of sort routines used by Tpetra.
void verbosePrintArray(std::ostream &out, const ArrayType &x, const char name[], const size_t maxNumToPrint)
Print min(x.size(), maxNumToPrint) entries of x.
std::unique_ptr< std::string > createPrefix(const int myRank, const char prefix[])
Create string prefix for each line of verbose output.
bool congruent(const Teuchos::Comm< int > &comm1, const Teuchos::Comm< int > &comm2)
Whether the two communicators are congruent.
Definition: Tpetra_Util.cpp:64
Kokkos::DualView< T *, DT > getDualViewCopyFromArrayView(const Teuchos::ArrayView< const T > &x_av, const char label[], const bool leaveOnHost)
Get a 1-D Kokkos::DualView which is a deep copy of the input Teuchos::ArrayView (which views host mem...
std::string dualViewStatusToString(const DualViewType &dv, const char name[])
Return the status of the given Kokkos::DualView, as a human-readable string.
Teuchos::ArrayView< typename DualViewType::t_dev::value_type > getArrayViewFromDualView(const DualViewType &x)
Get a Teuchos::ArrayView which views the host Kokkos::View of the input 1-D Kokkos::DualView.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
void sort(View &view, const size_t &size)
Convenience wrapper for std::sort for host-accessible views.
void deep_copy(MultiVector< DS, DL, DG, DN > &dst, const MultiVector< SS, SL, SG, SN > &src)
Copy the contents of the MultiVector src into dst.
void sort3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT3 &first3)
Sort the first array, and apply the same permutation to the second and third arrays.
void reverse_sort(View &view, const size_t &size)
Convenience wrapper for a reversed std::sort for host-accessible views.
void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2)
Sort the first array, and apply the resulting permutation to the second array.
MapType::iterator efficientAddOrUpdate(MapType &m, const KeyArgType &k, const ValueArgType &v)
Efficiently insert or replace an entry in an std::map.
void merge2(IT1 &indResultOut, IT2 &valResultOut, IT1 indBeg, IT1 indEnd, IT2 valBeg, IT2)
Merge values in place, additively, with the same index.
void keyValueMerge(KeyInputIterType keyBeg1, KeyInputIterType keyEnd1, ValueInputIterType valBeg1, ValueInputIterType valEnd1, KeyInputIterType keyBeg2, KeyInputIterType keyEnd2, ValueInputIterType valBeg2, ValueInputIterType valEnd2, KeyOutputIterType keyOut, ValueOutputIterType valOut, BinaryFunction f)
Merge two sorted (by keys) sequences of unique (key,value) pairs by combining pairs with equal keys.