42 #ifndef TPETRA_UTIL_HPP 43 #define TPETRA_UTIL_HPP 54 #include "Tpetra_ConfigDefs.hpp" 55 #include "Kokkos_DualView.hpp" 56 #include "Teuchos_Utils.hpp" 57 #include "Teuchos_Assert.hpp" 62 #if defined(HAVE_TPETRA_THROW_EFFICIENCY_WARNINGS) || defined(HAVE_TPETRA_PRINT_EFFICIENCY_WARNINGS) 63 #define TPETRA_EFFICIENCY_WARNING(throw_exception_test,Exception,msg) \ 98 const bool tpetraEfficiencyWarningTest = (throw_exception_test); \ 99 if (tpetraEfficiencyWarningTest) { \ 100 std::ostringstream errStream; \ 101 errStream << Teuchos::typeName(*this) << ":" << std::endl; \ 102 errStream << "Efficiency warning: " << #throw_exception_test << std::endl; \ 104 std::string err = errStream.str(); \ 105 if (TPETRA_PRINTS_EFFICIENCY_WARNINGS && tpetraEfficiencyWarningTest) { \ 106 std::cerr << err << std::endl; \ 108 TEUCHOS_TEST_FOR_EXCEPTION(TPETRA_THROWS_EFFICIENCY_WARNINGS && tpetraEfficiencyWarningTest, Exception, err); \ 112 #define TPETRA_EFFICIENCY_WARNING(throw_exception_test,Exception,msg) 149 #if defined(HAVE_TPETRA_THROW_ABUSE_WARNINGS) || defined(HAVE_TPETRA_PRINT_ABUSE_WARNINGS) 150 #define TPETRA_ABUSE_WARNING(throw_exception_test,Exception,msg) \ 153 std::ostringstream errStream; \ 154 errStream << Teuchos::typeName(*this) << msg; \ 155 std::string err = errStream.str(); \ 156 if (TPETRA_PRINTS_ABUSE_WARNINGS && (throw_exception_test)) { \ 157 std::cerr << err << std::endl; \ 159 TEUCHOS_TEST_FOR_EXCEPTION(TPETRA_THROWS_ABUSE_WARNINGS && (throw_exception_test), Exception, err); \ 162 #define TPETRA_ABUSE_WARNING(throw_exception_test,Exception,msg) 195 #define SHARED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm) \ 197 using Teuchos::outArg; \ 198 const int lcl_throw_exception = (throw_exception_test) ? Teuchos::rank(comm)+1 : 0; \ 200 Teuchos::reduceAll(comm,Teuchos::REDUCE_MAX,lcl_throw_exception,outArg(gbl_throw)); \ 201 TEUCHOS_TEST_FOR_EXCEPTION(gbl_throw,Exception, \ 202 msg << " Failure on at least one process, including process " << gbl_throw-1 << "." << std::endl); \ 205 #ifdef HAVE_TEUCHOS_DEBUG 206 #define SWITCHED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm) \ 209 SHARED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm); \ 212 #define SWITCHED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm) \ 215 TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg); \ 232 template<
typename MapType,
typename KeyArgType,
typename ValueArgType>
234 const KeyArgType & k,
235 const ValueArgType & v)
237 typename MapType::iterator lb = m.lower_bound(k);
238 if(lb != m.end() && !(m.key_comp()(k, lb->first))) {
243 typedef typename MapType::value_type MVT;
244 return(m.insert(lb, MVT(k, v)));
267 typedef typename std::iterator_traits<IT1>::difference_type DT;
268 DT myit = Teuchos::OrdinalTraits<DT>::one();
269 const DT sz = last - first;
270 for(;myit < sz; ++myit){
271 if(first[myit] < first[myit-1]){
289 IT pivot(first+(last-first)/2);
290 if(*first<=*pivot && *(last-1)<=*first) pivot=first;
291 else if(*(last-1)<=*pivot && *first<= *(last-1)) pivot = last-1;
309 template<
class IT1,
class IT2>
317 typename std::iterator_traits<IT1>::value_type piv(*pivot);
318 std::swap(*pivot, *(last1-1));
319 std::swap(first2[(pivot-first1)], *(last2-1));
321 for(IT1 it=first1; it!=last1-1; ++it){
323 std::swap(*store1, *it);
324 std::swap(first2[(store1-first1)], first2[(it-first1)]);
328 std::swap(*(last1-1), *store1);
329 std::swap(*(last2-1), first2[store1-first1]);
349 template<
class IT1,
class IT2,
class IT3>
359 typename std::iterator_traits<IT1>::value_type piv(*pivot);
360 std::swap(*pivot, *(last1-1));
361 std::swap(first2[(pivot-first1)], *(last2-1));
362 std::swap(first3[(pivot-first1)], *(last3-1));
364 for(IT1 it=first1; it!=last1-1; ++it){
366 std::swap(*store1, *it);
367 std::swap(first2[(store1-first1)], first2[(it-first1)]);
368 std::swap(first3[(store1-first1)], first3[(it-first1)]);
372 std::swap(*(last1-1), *store1);
373 std::swap(*(last2-1), first2[store1-first1]);
374 std::swap(*(last3-1), first3[store1-first1]);
388 template<
class IT1,
class IT2>
395 typedef typename std::iterator_traits<IT1>::difference_type DT;
396 DT DT1 = Teuchos::OrdinalTraits<DT>::one();
397 if(last1-first1 > DT1){
398 IT1 pivot =
getPivot(first1, last1);
399 pivot =
partition2(first1, last1, first2, last2, pivot);
400 quicksort2(first1, pivot, first2, first2+(pivot-first1));
401 quicksort2(pivot+1, last1, first2+(pivot-first1)+1, last2);
417 template<
class IT1,
class IT2,
class IT3>
426 typedef typename std::iterator_traits<IT1>::difference_type DT;
427 DT DT1 = Teuchos::OrdinalTraits<DT>::one();
428 if(last1-first1 > DT1){
429 IT1 pivot =
getPivot(first1, last1);
430 pivot =
partition3(first1, last1, first2, last2, first3, last3, pivot);
431 quicksort3(first1, pivot, first2, first2+(pivot-first1), first3, first3+(pivot-first1));
432 quicksort3(pivot+1, last1, first2+(pivot-first1)+1, last2, first3+(pivot-first1)+1, last3);
442 template<
class IT1,
class IT2,
class IT3>
451 typedef typename std::iterator_traits<IT1>::difference_type DT;
452 DT n = last1 - first1;
454 DT z = Teuchos::OrdinalTraits<DT>::zero();
458 for (DT j = 0; j < max; j++)
460 for (DT k = j; k >= 0; k-=m)
462 if (first1[k+m] >= first1[k])
464 std::swap(first1[k+m], first1[k]);
465 std::swap(first2[k+m], first2[k]);
466 std::swap(first3[k+m], first3[k]);
479 template<
class IT1,
class IT2>
486 typedef typename std::iterator_traits<IT1>::difference_type DT;
487 DT n = last1 - first1;
489 DT z = Teuchos::OrdinalTraits<DT>::zero();
493 for (DT j = 0; j < max; j++)
495 for (DT k = j; k >= 0; k-=m)
497 if (first1[k+m] >= first1[k])
499 std::swap(first1[k+m], first1[k]);
500 std::swap(first2[k+m], first2[k]);
528 template<
class IT1,
class IT2>
529 void sort2(
const IT1 &first1,
const IT1 &last1,
const IT2 &first2) {
534 if(SortDetails::isAlreadySorted(first1, last1)){
537 SortDetails::sh_sort2(first1, last1, first2, first2+(last1-first1));
538 #ifdef HAVE_TPETRA_DEBUG 539 if(!SortDetails::isAlreadySorted(first1, last1)){
540 std::cout <<
"Trouble: sort() did not sort !!" << std::endl;
562 template<
class IT1,
class IT2,
class IT3>
563 void sort3(
const IT1 &first1,
const IT1 &last1,
const IT2 &first2,
570 if(SortDetails::isAlreadySorted(first1, last1)){
573 SortDetails::sh_sort3(first1, last1, first2, first2+(last1-first1), first3,
574 first3+(last1-first1));
576 #ifdef HAVE_TPETRA_DEBUG 577 if(!SortDetails::isAlreadySorted(first1, last1)){
578 std::cout <<
" Trouble sort did not actually sort... !!!!!!" <<
628 template<
class IT1,
class IT2>
630 merge2 (IT1& indResultOut, IT2& valResultOut,
631 IT1 indBeg, IT1 indEnd,
632 IT2 valBeg, IT2 valEnd)
634 if (indBeg == indEnd) {
635 indResultOut = indBeg;
636 valResultOut = valBeg;
639 IT1 indResult = indBeg;
640 IT2 valResult = valBeg;
641 if (indBeg != indEnd) {
644 while (indBeg != indEnd) {
645 if (*indResult == *indBeg) {
646 *valResult += *valBeg;
648 *(++indResult) = *indBeg;
649 *(++valResult) = *valBeg;
664 indResultOut = indResult;
665 valResultOut = valResult;
717 template<
class IT1,
class IT2,
class BinaryFunction>
719 merge2 (IT1& indResultOut, IT2& valResultOut,
720 IT1 indBeg, IT1 indEnd,
721 IT2 valBeg, IT2 valEnd,
724 if (indBeg == indEnd) {
725 indResultOut = indBeg;
726 valResultOut = valBeg;
729 IT1 indResult = indBeg;
730 IT2 valResult = valBeg;
731 if (indBeg != indEnd) {
734 while (indBeg != indEnd) {
735 if (*indResult == *indBeg) {
736 *valResult = f (*valResult, *valBeg);
738 *(++indResult) = *indBeg;
739 *(++valResult) = *valBeg;
749 indResultOut = indResult;
750 valResultOut = valResult;
783 template<
class KeyInputIterType,
class ValueInputIterType,
784 class KeyOutputIterType,
class ValueOutputIterType,
785 class BinaryFunction>
788 ValueInputIterType valBeg1, ValueInputIterType valEnd1,
789 KeyInputIterType keyBeg2, KeyInputIterType keyEnd2,
790 ValueInputIterType valBeg2, ValueInputIterType valEnd2,
791 KeyOutputIterType keyOut, ValueOutputIterType valOut,
794 while (keyBeg1 != keyEnd1 && keyBeg2 != keyEnd2) {
795 if (*keyBeg1 < *keyBeg2) {
796 *keyOut++ = *keyBeg1++;
797 *valOut++ = *valBeg1++;
798 }
else if (*keyBeg1 > *keyBeg2) {
799 *keyOut++ = *keyBeg2++;
800 *valOut++ = *valBeg2++;
802 *keyOut++ = *keyBeg1;
803 *valOut++ = f (*valBeg1, *valBeg2);
811 std::copy (keyBeg1, keyEnd1, keyOut);
812 std::copy (valBeg1, valEnd1, valOut);
813 std::copy (keyBeg2, keyEnd2, keyOut);
814 std::copy (valBeg2, valEnd2, valOut);
817 template<
class KeyInputIterType>
819 keyMergeCount (KeyInputIterType keyBeg1, KeyInputIterType keyEnd1,
820 KeyInputIterType keyBeg2, KeyInputIterType keyEnd2)
823 while (keyBeg1 != keyEnd1 && keyBeg2 != keyEnd2) {
824 if (*keyBeg1 < *keyBeg2) {
826 }
else if (*keyBeg1 > *keyBeg2) {
835 count +=
static_cast<size_t> (keyEnd1 - keyBeg1) +
836 static_cast<size_t> (keyEnd2 - keyBeg2);
861 congruent (
const Teuchos::Comm<int>& comm1,
862 const Teuchos::Comm<int>& comm2);
873 template<
class DualViewType>
874 Teuchos::ArrayView<typename DualViewType::t_dev::value_type>
877 static_assert (static_cast<int> (DualViewType::t_dev::rank) == 1,
878 "The input DualView must have rank 1.");
879 TEUCHOS_TEST_FOR_EXCEPTION
880 (x.template need_sync<Kokkos::HostSpace> (), std::logic_error,
"The " 881 "input Kokkos::DualView was most recently modified on device, but this " 882 "function needs the host view of the data to be the most recently " 885 auto x_host = x.template view<Kokkos::HostSpace> ();
886 typedef typename DualViewType::t_dev::value_type value_type;
887 return Teuchos::ArrayView<value_type> (x_host.ptr_on_device (),
888 x_host.dimension_0 ());
907 template<
class T,
class DT>
908 Kokkos::DualView<T*, DT>
911 const bool leaveOnHost)
913 using Kokkos::MemoryUnmanaged;
914 typedef typename DT::memory_space DMS;
915 typedef Kokkos::HostSpace HMS;
917 const size_t len =
static_cast<size_t> (x_av.size ());
918 Kokkos::View<const T*, HMS, MemoryUnmanaged> x_in (x_av.getRawPtr (), len);
919 Kokkos::DualView<T*, DT> x_out (label, len);
921 x_out.template modify<HMS> ();
925 x_out.template modify<DMS> ();
934 #endif // TPETRA_UTIL_HPP bool congruent(const Teuchos::Comm< int > &comm1, const Teuchos::Comm< int > &comm2)
Whether the two communicators are congruent.
Namespace Tpetra contains the class and methods constituting the Tpetra library.
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...
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.
IT1 partition2(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT2 &last2, const IT1 &pivot)
Partition operation for quicksort2().
void deep_copy(MultiVector< DS, DL, DG, DN, dstClassic > &dst, const MultiVector< SS, SL, SG, SN, srcClassic > &src)
Copy the contents of the MultiVector src into dst.
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...
Implementation details of Tpetra.
void sh_sort3(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT2 &last2, const IT3 &first3, const IT3 &last3)
Sort the first array using shell sort, and apply the resulting permutation to the second and third ar...
void merge2(IT1 &indResultOut, IT2 &valResultOut, IT1 indBeg, IT1 indEnd, IT2 valBeg, IT2 valEnd)
Merge values in place, additively, with the same index.
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...
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...
IT getPivot(const IT &first, const IT &last)
Determines the pivot point as part of the quicksort routine.
MapType::iterator efficientAddOrUpdate(MapType &m, const KeyArgType &k, const ValueArgType &v)
Efficiently insert or replace an entry in an std::map.
void sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2)
Sort the first array, and apply the resulting permutation to the second array.
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.
Implementation details of sort routines used by Tpetra.
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().
bool isAlreadySorted(const IT1 &first, const IT1 &last)
Determines whether or not a random access sequence is already sorted.
void sh_sort2(const IT1 &first1, const IT1 &last1, const IT2 &first2, const IT2 &last2)
Sort the first array using shell sort, and apply the resulting permutation to the second array...