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
539template <class IT1, class IT2>
540void sort2(const IT1& first1, const IT1& last1, const IT2& first2, const bool stableSort = false) {
541 // Quicksort uses best-case N log N time whether or not the input
542 // data is sorted. However, the common case in Tpetra is that the
543 // input data are sorted, so we first check whether this is the
544 // case before reverting to Quicksort.
545 if (SortDetails::isAlreadySorted(first1, last1)) {
546 return;
547 }
548 if (stableSort)
549 SortDetails::std_sort2(first1, last1, first2, first2 + (last1 - first1));
550 else
551 SortDetails::sh_sort2(first1, last1, first2, first2 + (last1 - first1));
552#ifdef HAVE_TPETRA_DEBUG
553 if (!SortDetails::isAlreadySorted(first1, last1)) {
554 std::cout << "Trouble: sort() did not sort !!" << std::endl;
555 return;
556 }
557#endif
558}
559
576template <class View1, class View2>
577void sort2(View1& view1, const size_t& size, View2& view2) {
578 // NOTE: This assumes the view is host-accessible.
579
580 // Wrap the views as rcps (this happens to preserve the reference counting, but that doesn't really matter here)
581 Teuchos::ArrayRCP<typename View1::non_const_value_type> view1_rcp = Kokkos::Compat::persistingView(view1, 0, size);
582 Teuchos::ArrayRCP<typename View2::non_const_value_type> view2_rcp = Kokkos::Compat::persistingView(view2, 0, size);
583
584 sort2(view1_rcp.begin(), view1_rcp.end(), view2_rcp.begin());
585}
586
595template <class View>
596void sort(View& view, const size_t& size) {
597 // NOTE: This assumes the view is host-accessible.
598
599 // Wrap the view as rcps (this happens to preserve the reference counting, but that doesn't really matter here)
600 Teuchos::ArrayRCP<typename View::non_const_value_type> view_rcp = Kokkos::Compat::persistingView(view, 0, size);
601
602 std::sort(view_rcp.begin(), view_rcp.end());
603}
604
613template <class View>
614void reverse_sort(View& view, const size_t& size) {
615 // NOTE: This assumes the view is host-accessible.
616 // Wrap the view as rcps (this happens to preserve the reference counting, but that doesn't really matter here)
617 Teuchos::ArrayRCP<typename View::non_const_value_type> view_rcp = Kokkos::Compat::persistingView(view, 0, size);
618
619 std::sort(view_rcp.rbegin(), view_rcp.rend());
620}
621
638template <class IT1, class IT2, class IT3>
639void sort3(const IT1& first1, const IT1& last1, const IT2& first2,
640 const IT3& first3, const bool stableSort = false) {
641 // Quicksort uses best-case N log N time whether or not the input
642 // data is sorted. However, the common case in Tpetra is that the
643 // input data are sorted, so we first check whether this is the
644 // case before reverting to Quicksort.
645 if (SortDetails::isAlreadySorted(first1, last1)) {
646 return;
647 }
648 if (stableSort)
649 SortDetails::std_sort3(first1, last1, first2, first2 + (last1 - first1), first3,
650 first3 + (last1 - first1));
651 else
652 SortDetails::sh_sort3(first1, last1, first2, first2 + (last1 - first1), first3,
653 first3 + (last1 - first1));
654#ifdef HAVE_TPETRA_DEBUG
655 if (!SortDetails::isAlreadySorted(first1, last1)) {
656 std::cout << " Trouble sort did not actually sort... !!!!!!" << std::endl;
657 return;
658 }
659#endif
660}
661
705template <class IT1, class IT2>
708 IT2 valBeg, IT2 /* valEnd */) {
709 if (indBeg == indEnd) {
710 indResultOut = indBeg; // It's allowed for indResultOut to alias indEnd
711 valResultOut = valBeg; // It's allowed for valResultOut to alias valEnd
712 } else {
715 if (indBeg != indEnd) {
716 ++indBeg;
717 ++valBeg;
718 while (indBeg != indEnd) {
719 if (*indResult == *indBeg) { // adjacent column indices equal
720 *valResult += *valBeg; // merge entries by adding their values together
721 } else { // adjacent column indices not equal
722 *(++indResult) = *indBeg; // shift over the index
723 *(++valResult) = *valBeg; // shift over the value
724 }
725 ++indBeg;
726 ++valBeg;
727 }
728 ++indResult; // exclusive end of merged result
729 ++valResult; // exclusive end of merged result
730
731 // mfh 24 Feb 2014: Setting these is technically correct, but
732 // since the resulting variables aren't used after this point,
733 // it may result in a build error.
734 //
735 // indEnd = indResult;
736 // valEnd = valResult;
737 }
740 }
741}
742
791template <class IT1, class IT2, class BinaryFunction>
796 if (indBeg == indEnd) {
797 indResultOut = indBeg; // It's allowed for indResultOut to alias indEnd
798 valResultOut = valBeg; // It's allowed for valResultOut to alias valEnd
799 } else {
802 if (indBeg != indEnd) {
803 ++indBeg;
804 ++valBeg;
805 while (indBeg != indEnd) {
806 if (*indResult == *indBeg) { // adjacent column indices equal
807 *valResult = f(*valResult, *valBeg); // merge entries via values
808 } else { // adjacent column indices not equal
809 *(++indResult) = *indBeg; // shift over the index
810 *(++valResult) = *valBeg; // shift over the value
811 }
812 ++indBeg;
813 ++valBeg;
814 }
815 ++indResult; // exclusive end of merged result
816 ++valResult; // exclusive end of merged result
819 }
822 }
823}
824
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
1018template <class ArrayType>
1019void verbosePrintArray(std::ostream& out,
1020 const ArrayType& x,
1021 const char name[],
1022 const size_t maxNumToPrint) {
1023 out << name << ": [";
1024
1025 const size_t numEnt(x.size());
1026 if (maxNumToPrint == 0) {
1027 if (numEnt != 0) {
1028 out << "...";
1029 }
1030 } else {
1031 const size_t numToPrint = numEnt > maxNumToPrint ? maxNumToPrint : numEnt;
1032 size_t k = 0;
1033 for (; k < numToPrint; ++k) {
1034 out << x[k];
1035 if (k + size_t(1) < numToPrint) {
1036 out << ", ";
1037 }
1038 }
1039 if (k < numEnt) {
1040 out << ", ...";
1041 }
1042 }
1043 out << "]";
1044}
1045
1049std::unique_ptr<std::string>
1050createPrefix(const int myRank,
1051 const char prefix[]);
1052
1060std::unique_ptr<std::string>
1061createPrefix(const Teuchos::Comm<int>* comm,
1062 const char functionName[]);
1063
1070std::unique_ptr<std::string>
1071createPrefix(const Teuchos::Comm<int>*,
1072 const char className[],
1073 const char methodName[]);
1074
1075} // namespace Details
1076} // namespace Tpetra
1077
1078#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.