Tpetra parallel linear algebra Version of the Day
Loading...
Searching...
No Matches
Tpetra_Util.hpp
Go to the documentation of this file.
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#ifndef TPETRA_UTIL_HPP
11#define TPETRA_UTIL_HPP
12
22#include "Tpetra_ConfigDefs.hpp"
23#include "Kokkos_DualView.hpp"
24#include "KokkosCompat_View.hpp"
25#include "Teuchos_Assert.hpp"
26#include "Teuchos_CommHelpers.hpp"
27#include "Teuchos_OrdinalTraits.hpp"
28#include "Teuchos_TypeNameTraits.hpp"
29#include "Teuchos_Utils.hpp"
30#include <numeric>
31#include <algorithm>
32#include <iterator>
33#include <memory>
34#include <ostream>
35#include <sstream>
36
37#if defined(HAVE_TPETRA_PRINT_EFFICIENCY_WARNINGS)
62#define TPETRA_EFFICIENCY_WARNING(throw_exception_test, msg) \
63 { \
64 const bool tpetraEfficiencyWarningTest = (throw_exception_test); \
65 if (tpetraEfficiencyWarningTest) { \
66 std::ostringstream errStream; \
67 errStream << Teuchos::typeName(*this) << ":" << std::endl; \
68 errStream << "Efficiency warning: " << #throw_exception_test << std::endl; \
69 errStream << msg; \
70 std::string err = errStream.str(); \
71 if (TPETRA_PRINTS_EFFICIENCY_WARNINGS && tpetraEfficiencyWarningTest) { \
72 std::cerr << err << std::endl; \
73 } \
74 } \
75 }
76#else
101#define TPETRA_EFFICIENCY_WARNING(throw_exception_test, msg)
102#endif
103
104// handle an abuse warning, according to HAVE_TPETRA_THROW_ABUSE_WARNINGS and HAVE_TPETRA_PRINT_ABUSE_WARNINGS
105#if defined(HAVE_TPETRA_THROW_ABUSE_WARNINGS) || defined(HAVE_TPETRA_PRINT_ABUSE_WARNINGS)
107#define TPETRA_ABUSE_WARNING(throw_exception_test, Exception, msg) \
108 { \
109 std::ostringstream errStream; \
110 errStream << Teuchos::typeName(*this) << msg; \
111 std::string err = errStream.str(); \
112 if (TPETRA_PRINTS_ABUSE_WARNINGS && (throw_exception_test)) { \
113 std::cerr << err << std::endl; \
114 } \
115 TEUCHOS_TEST_FOR_EXCEPTION(TPETRA_THROWS_ABUSE_WARNINGS && (throw_exception_test), Exception, err); \
116 }
117#else
119#define TPETRA_ABUSE_WARNING(throw_exception_test, Exception, msg)
120#endif
121
151#define SHARED_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg, comm) \
152 { \
153 using Teuchos::outArg; \
154 const int lcl_throw_exception = (throw_exception_test) ? Teuchos::rank(comm) + 1 : 0; \
155 int gbl_throw; \
156 Teuchos::reduceAll(comm, Teuchos::REDUCE_MAX, lcl_throw_exception, outArg(gbl_throw)); \
157 TEUCHOS_TEST_FOR_EXCEPTION(gbl_throw, Exception, \
158 msg << " Failure on at least one process, including process " << gbl_throw - 1 << "." << std::endl); \
159 }
160
161namespace Tpetra {
162
174template <typename MapType, typename KeyArgType, typename ValueArgType>
175typename MapType::iterator efficientAddOrUpdate(MapType& m,
176 const KeyArgType& k,
177 const ValueArgType& v) {
178 typename MapType::iterator lb = m.lower_bound(k);
179 if (lb != m.end() && !(m.key_comp()(k, lb->first))) {
180 lb->second = v;
181 return (lb);
182 } else {
183 typedef typename MapType::value_type MVT;
184 return (m.insert(lb, MVT(k, v)));
185 }
186}
187
195namespace SortDetails {
196
205template <class IT1>
206bool isAlreadySorted(const IT1& first, const IT1& last) {
207 typedef typename std::iterator_traits<IT1>::difference_type DT;
208 DT myit = Teuchos::OrdinalTraits<DT>::one();
209 const DT sz = last - first;
210 for (; myit < sz; ++myit) {
211 if (first[myit] < first[myit - 1]) {
212 return false;
213 }
214 }
215 return true;
216}
217
227template <class IT>
228IT getPivot(const IT& first, const IT& last) {
229 IT pivot(first + (last - first) / 2);
230 if (*first <= *pivot && *(last - 1) <= *first)
231 pivot = first;
232 else if (*(last - 1) <= *pivot && *first <= *(last - 1))
233 pivot = last - 1;
234 return pivot;
235}
236
251template <class IT1, class IT2>
253 const IT1& first1,
254 const IT1& last1,
255 const IT2& first2,
256 const IT2& last2,
257 const IT1& pivot) {
258 typename std::iterator_traits<IT1>::value_type piv(*pivot);
259 std::swap(*pivot, *(last1 - 1));
260 std::swap(first2[(pivot - first1)], *(last2 - 1));
261 IT1 store1 = first1;
262 for (IT1 it = first1; it != last1 - 1; ++it) {
263 if (*it <= piv) {
264 std::swap(*store1, *it);
265 std::swap(first2[(store1 - first1)], first2[(it - first1)]);
266 ++store1;
267 }
268 }
269 std::swap(*(last1 - 1), *store1);
270 std::swap(*(last2 - 1), first2[store1 - first1]);
271 return store1;
272}
273
290template <class IT1, class IT2, class IT3>
292 const IT1& first1,
293 const IT1& last1,
294 const IT2& first2,
295 const IT2& last2,
296 const IT3& first3,
297 const IT3& last3,
298 const IT1& pivot) {
299 typename std::iterator_traits<IT1>::value_type piv(*pivot);
300 std::swap(*pivot, *(last1 - 1));
301 std::swap(first2[(pivot - first1)], *(last2 - 1));
302 std::swap(first3[(pivot - first1)], *(last3 - 1));
303 IT1 store1 = first1;
304 for (IT1 it = first1; it != last1 - 1; ++it) {
305 if (*it <= piv) {
306 std::swap(*store1, *it);
307 std::swap(first2[(store1 - first1)], first2[(it - first1)]);
308 std::swap(first3[(store1 - first1)], first3[(it - first1)]);
309 ++store1;
310 }
311 }
312 std::swap(*(last1 - 1), *store1);
313 std::swap(*(last2 - 1), first2[store1 - first1]);
314 std::swap(*(last3 - 1), first3[store1 - first1]);
315 return store1;
316}
317
328template <class IT1, class IT2>
330 const IT1& first1,
331 const IT1& last1,
332 const IT2& first2,
333 const IT2& last2) {
334 typedef typename std::iterator_traits<IT1>::difference_type DT;
335 DT DT1 = Teuchos::OrdinalTraits<DT>::one();
336 if (last1 - first1 > DT1) {
340 quicksort2(pivot + 1, last1, first2 + (pivot - first1) + 1, last2);
341 }
342}
343
356template <class IT1, class IT2, class IT3>
358 const IT1& first1,
359 const IT1& last1,
360 const IT2& first2,
361 const IT2& last2,
362 const IT3& first3,
363 const IT3& last3) {
364 typedef typename std::iterator_traits<IT1>::difference_type DT;
365 DT DT1 = Teuchos::OrdinalTraits<DT>::one();
366 if (last1 - first1 > DT1) {
370 quicksort3(pivot + 1, last1, first2 + (pivot - first1) + 1, last2, first3 + (pivot - first1) + 1, last3);
371 }
372}
373
380template <class IT1, class IT2, class IT3>
382 const IT1& first1,
383 const IT1& last1,
384 const IT2& first2,
385 const IT2& /* last2 */,
386 const IT3& first3,
387 const IT3& /* last3 */) {
388 typedef typename std::iterator_traits<IT1>::difference_type DT;
389 DT n = last1 - first1;
390 DT m = n / 2;
391 DT z = Teuchos::OrdinalTraits<DT>::zero();
392 while (m > z) {
393 DT max = n - m;
394 for (DT j = 0; j < max; j++) {
395 for (DT k = j; k >= 0; k -= m) {
396 if (first1[k + m] >= first1[k])
397 break;
398 std::swap(first1[k + m], first1[k]);
399 std::swap(first2[k + m], first2[k]);
400 std::swap(first3[k + m], first3[k]);
401 }
402 }
403 m = m / 2;
404 }
405}
406
413template <class IT1, class IT2>
415 const IT1& first1,
416 const IT1& last1,
417 const IT2& first2,
418 const IT2& /* last2 */) {
419 typedef typename std::iterator_traits<IT1>::difference_type DT;
420 DT n = last1 - first1;
421 DT m = n / 2;
422 DT z = Teuchos::OrdinalTraits<DT>::zero();
423 while (m > z) {
424 DT max = n - m;
425 for (DT j = 0; j < max; j++) {
426 for (DT k = j; k >= 0; k -= m) {
427 if (first1[k + m] >= first1[k])
428 break;
429 std::swap(first1[k + m], first1[k]);
430 std::swap(first2[k + m], first2[k]);
431 }
432 }
433 m = m / 2;
434 }
435}
436
441template <typename IT1>
442std::vector<typename std::iterator_traits<IT1>::difference_type> sort_indexes(IT1 first, IT1 last) {
443 typedef typename std::iterator_traits<IT1>::difference_type DT;
444
445 DT length = last - first;
446 std::vector<DT> idx(length);
447 std::iota(idx.begin(), idx.end(), 0);
448
449 std::stable_sort(idx.begin(), idx.end(),
450 [&first](size_t i1, size_t i2) { return first[i1] < first[i2]; });
451
452 return idx;
453}
454
458template <typename IT1, typename IT2>
460 IT1 first,
461 IT1 last,
462 IT2 indices) {
463 typedef typename std::iterator_traits<IT1>::difference_type DT;
464 typedef typename std::iterator_traits<IT1>::value_type T;
465
466 DT n = last - first;
467
468 Kokkos::View<T*, Kokkos::HostSpace> tmp(Kokkos::view_alloc(Kokkos::WithoutInitializing, "tmp"), n);
469
470 Kokkos::parallel_for("apply_permutation_1",
471 Kokkos::RangePolicy<Kokkos::DefaultHostExecutionSpace>(0, n),
472 [=](const int j) {
473 tmp(j) = first[indices[j]];
474 });
475 Kokkos::parallel_for("apply_permutation_2",
476 Kokkos::RangePolicy<Kokkos::DefaultHostExecutionSpace>(0, n),
477 [=](const int j) {
478 first[j] = tmp(j);
479 });
480}
481
488template <class IT1, class IT2>
489void std_sort2(const IT1& first1,
490 const IT1& last1,
491 const IT2& first2,
492 const IT2& last2) {
493 auto indices = sort_indexes(first1, last1);
494 apply_permutation(first1, last1, indices);
495 apply_permutation(first2, last2, indices);
496}
497
504template <class IT1, class IT2, class IT3>
506 const IT1& first1,
507 const IT1& last1,
508 const IT2& first2,
509 const IT2& last2,
510 const IT3& first3,
511 const IT3& last3) {
512 auto indices = sort_indexes(first1, last1);
513 apply_permutation(first1, last1, indices);
514 apply_permutation(first2, last2, indices);
515 apply_permutation(first3, last3, indices);
516}
517
518} // end namespace SortDetails
519
538template <class IT1, class IT2>
539void sort2(const IT1& first1, const IT1& last1, const IT2& first2, const bool stableSort = false) {
540 // Quicksort uses best-case N log N time whether or not the input
541 // data is sorted. However, the common case in Tpetra is that the
542 // input data are sorted, so we first check whether this is the
543 // case before reverting to Quicksort.
544 if (SortDetails::isAlreadySorted(first1, last1)) {
545 return;
546 }
547 if (stableSort)
548 SortDetails::std_sort2(first1, last1, first2, first2 + (last1 - first1));
549 else
550 SortDetails::sh_sort2(first1, last1, first2, first2 + (last1 - first1));
551#ifdef HAVE_TPETRA_DEBUG
552 if (!SortDetails::isAlreadySorted(first1, last1)) {
553 std::cout << "Trouble: sort() did not sort !!" << std::endl;
554 return;
555 }
556#endif
557}
558
575template <class View1, class View2>
576void sort2(View1& view1, const size_t& size, View2& view2) {
577 // NOTE: This assumes the view is host-accessible.
578
579 // Wrap the views as rcps (this happens to preserve the reference counting, but that doesn't really matter here)
580 Teuchos::ArrayRCP<typename View1::non_const_value_type> view1_rcp = Kokkos::Compat::persistingView(view1, 0, size);
581 Teuchos::ArrayRCP<typename View2::non_const_value_type> view2_rcp = Kokkos::Compat::persistingView(view2, 0, size);
582
583 sort2(view1_rcp.begin(), view1_rcp.end(), view2_rcp.begin());
584}
585
594template <class View>
595void sort(View& view, const size_t& size) {
596 // NOTE: This assumes the view is host-accessible.
597
598 // Wrap the view as rcps (this happens to preserve the reference counting, but that doesn't really matter here)
599 Teuchos::ArrayRCP<typename View::non_const_value_type> view_rcp = Kokkos::Compat::persistingView(view, 0, size);
600
601 std::sort(view_rcp.begin(), view_rcp.end());
602}
603
612template <class View>
613void reverse_sort(View& view, const size_t& size) {
614 // NOTE: This assumes the view is host-accessible.
615 // Wrap the view as rcps (this happens to preserve the reference counting, but that doesn't really matter here)
616 Teuchos::ArrayRCP<typename View::non_const_value_type> view_rcp = Kokkos::Compat::persistingView(view, 0, size);
617
618 std::sort(view_rcp.rbegin(), view_rcp.rend());
619}
620
636template <class IT1, class IT2, class IT3>
637void sort3(const IT1& first1, const IT1& last1, const IT2& first2,
638 const IT3& first3, const bool stableSort = false) {
639 // Quicksort uses best-case N log N time whether or not the input
640 // data is sorted. However, the common case in Tpetra is that the
641 // input data are sorted, so we first check whether this is the
642 // case before reverting to Quicksort.
643 if (SortDetails::isAlreadySorted(first1, last1)) {
644 return;
645 }
646 if (stableSort)
647 SortDetails::std_sort3(first1, last1, first2, first2 + (last1 - first1), first3,
648 first3 + (last1 - first1));
649 else
650 SortDetails::sh_sort3(first1, last1, first2, first2 + (last1 - first1), first3,
651 first3 + (last1 - first1));
652#ifdef HAVE_TPETRA_DEBUG
653 if (!SortDetails::isAlreadySorted(first1, last1)) {
654 std::cout << " Trouble sort did not actually sort... !!!!!!" << std::endl;
655 return;
656 }
657#endif
658}
659
703template <class IT1, class IT2>
706 IT2 valBeg, IT2 /* valEnd */) {
707 if (indBeg == indEnd) {
708 indResultOut = indBeg; // It's allowed for indResultOut to alias indEnd
709 valResultOut = valBeg; // It's allowed for valResultOut to alias valEnd
710 } else {
713 if (indBeg != indEnd) {
714 ++indBeg;
715 ++valBeg;
716 while (indBeg != indEnd) {
717 if (*indResult == *indBeg) { // adjacent column indices equal
718 *valResult += *valBeg; // merge entries by adding their values together
719 } else { // adjacent column indices not equal
720 *(++indResult) = *indBeg; // shift over the index
721 *(++valResult) = *valBeg; // shift over the value
722 }
723 ++indBeg;
724 ++valBeg;
725 }
726 ++indResult; // exclusive end of merged result
727 ++valResult; // exclusive end of merged result
728
729 // mfh 24 Feb 2014: Setting these is technically correct, but
730 // since the resulting variables aren't used after this point,
731 // it may result in a build error.
732 //
733 // indEnd = indResult;
734 // valEnd = valResult;
735 }
738 }
739}
740
789template <class IT1, class IT2, class BinaryFunction>
794 if (indBeg == indEnd) {
795 indResultOut = indBeg; // It's allowed for indResultOut to alias indEnd
796 valResultOut = valBeg; // It's allowed for valResultOut to alias valEnd
797 } else {
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
817 }
820 }
821}
822
851template <class KeyInputIterType, class ValueInputIterType,
852 class KeyOutputIterType, class ValueOutputIterType,
853 class BinaryFunction>
860 while (keyBeg1 != keyEnd1 && keyBeg2 != keyEnd2) {
861 if (*keyBeg1 < *keyBeg2) {
862 *keyOut++ = *keyBeg1++;
863 *valOut++ = *valBeg1++;
864 } else if (*keyBeg1 > *keyBeg2) {
865 *keyOut++ = *keyBeg2++;
866 *valOut++ = *valBeg2++;
867 } else { // *keyBeg1 == *keyBeg2
868 *keyOut++ = *keyBeg1;
869 *valOut++ = f(*valBeg1, *valBeg2);
870 ++keyBeg1;
871 ++valBeg1;
872 ++keyBeg2;
873 ++valBeg2;
874 }
875 }
876 // At most one of the two sequences will be nonempty.
877 std::copy(keyBeg1, keyEnd1, keyOut);
878 std::copy(valBeg1, valEnd1, valOut);
879 std::copy(keyBeg2, keyEnd2, keyOut);
880 std::copy(valBeg2, valEnd2, valOut);
881}
882
883template <class KeyInputIterType>
884size_t
885keyMergeCount(KeyInputIterType keyBeg1, KeyInputIterType keyEnd1,
886 KeyInputIterType keyBeg2, KeyInputIterType keyEnd2) {
887 size_t count = 0;
888 while (keyBeg1 != keyEnd1 && keyBeg2 != keyEnd2) {
889 if (*keyBeg1 < *keyBeg2) {
890 ++keyBeg1;
891 } else if (*keyBeg1 > *keyBeg2) {
892 ++keyBeg2;
893 } else { // *keyBeg1 == *keyBeg2
894 ++keyBeg1;
895 ++keyBeg2;
896 }
897 ++count;
898 }
899 // At most one of the two sequences will be nonempty.
900 count += static_cast<size_t>(keyEnd1 - keyBeg1) +
901 static_cast<size_t>(keyEnd2 - keyBeg2);
902 return count;
903}
904
905namespace Details {
925bool congruent(const Teuchos::Comm<int>& comm1,
926 const Teuchos::Comm<int>& comm2);
927
937template <class DualViewType>
938Teuchos::ArrayView<typename DualViewType::t_dev::value_type>
940 static_assert(static_cast<int>(DualViewType::t_dev::rank) == 1,
941 "The input DualView must have rank 1.");
942 TEUCHOS_TEST_FOR_EXCEPTION(x.need_sync_host(), std::logic_error,
943 "The "
944 "input Kokkos::DualView was most recently modified on device, but this "
945 "function needs the host view of the data to be the most recently "
946 "modified.");
947
948 auto x_host = x.view_host();
949 typedef typename DualViewType::t_dev::value_type value_type;
950 // mfh 15 Jan 2019: In debug mode, Teuchos::ArrayView's
951 // constructor throws if the pointer is nonnull but the length
952 // is nonpositive.
953 const auto len = x_host.extent(0);
954 return Teuchos::ArrayView<value_type>(len != 0 ? x_host.data() : nullptr,
955 len);
956}
957
974template <class T, class DT>
975Kokkos::DualView<T*, DT>
976getDualViewCopyFromArrayView(const Teuchos::ArrayView<const T>& x_av,
977 const char label[],
978 const bool leaveOnHost) {
979 using Kokkos::MemoryUnmanaged;
980 typedef typename DT::memory_space DMS;
981 typedef typename DT::execution_space execution_space;
982 typedef Kokkos::HostSpace HMS;
983
984 const size_t len = static_cast<size_t>(x_av.size());
985 Kokkos::View<const T*, HMS, MemoryUnmanaged> x_in(x_av.getRawPtr(), len);
986 Kokkos::DualView<T*, DT> x_out(label, len);
987 if (leaveOnHost) {
988 x_out.modify_host();
989 // DEEP_COPY REVIEW - NOT TESTED FOR CUDA BUILD
990 Kokkos::deep_copy(x_out.view_host(), x_in);
991 } else {
992 x_out.template modify<DMS>();
993 // DEEP_COPY REVIEW - HOST-TO-DEVICE
994 Kokkos::deep_copy(execution_space(), x_out.template view<DMS>(), x_in);
995 }
996 return x_out;
997}
998
1006template <class DualViewType>
1007std::string dualViewStatusToString(const DualViewType& dv, const char name[]) {
1008 const auto host = dv.need_sync_device();
1009 const auto dev = dv.need_sync_host();
1010
1011 std::ostringstream os;
1012 os << name << ": {size: " << dv.extent(0)
1013 << ", sync: {host: " << host << ", dev: " << dev << "}";
1014 return os.str();
1015}
1016
1021template <class ArrayType>
1022void verbosePrintArray(std::ostream& out,
1023 const ArrayType& x,
1024 const char name[],
1025 const size_t maxNumToPrint) {
1026 out << name << ": [";
1027
1028 const size_t numEnt(x.size());
1029 if (maxNumToPrint == 0) {
1030 if (numEnt != 0) {
1031 out << "...";
1032 }
1033 } else {
1034 const size_t numToPrint = numEnt > maxNumToPrint ? maxNumToPrint : numEnt;
1035 size_t k = 0;
1036 for (; k < numToPrint; ++k) {
1037 out << x[k];
1038 if (k + size_t(1) < numToPrint) {
1039 out << ", ";
1040 }
1041 }
1042 if (k < numEnt) {
1043 out << ", ...";
1044 }
1045 }
1046 out << "]";
1047}
1048
1052std::unique_ptr<std::string>
1053createPrefix(const int myRank,
1054 const char prefix[]);
1055
1063std::unique_ptr<std::string>
1064createPrefix(const Teuchos::Comm<int>* comm,
1065 const char functionName[]);
1066
1073std::unique_ptr<std::string>
1074createPrefix(const Teuchos::Comm<int>*,
1075 const char className[],
1076 const char methodName[]);
1077
1078} // namespace Details
1079} // namespace Tpetra
1080
1081#endif // TPETRA_UTIL_HPP
void std_sort3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT2 &last2, const IT3 &first3, const IT3 &last3)
Sort the first array using std sort, and apply the resulting permutation to the second and third arra...
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...
void std_sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT2 &last2)
Sort the first array using std sort, and apply the resulting permutation to the second array.
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.
void apply_permutation(IT1 first, IT1 last, IT2 indices)
Apply a permutation of the ordering of an array in place.
IT getPivot(const IT &first, const IT &last)
Determines the pivot point as part of the quicksort routine.
std::vector< typename std::iterator_traits< IT1 >::difference_type > sort_indexes(IT1 first, IT1 last)
Compute the permutation of the ordering that sorts the array using a stable sort.
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...
Struct that holds views of the contents of a CrsMatrix.
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.
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.
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.
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.
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 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, const bool stableSort=false)
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.
void sort3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT3 &first3, const bool stableSort=false)
Sort the first array, and apply the same permutation to the second and third arrays.