42 #ifndef TPETRA_UTIL_HPP
43 #define TPETRA_UTIL_HPP
54 #include "Tpetra_ConfigDefs.hpp"
55 #include "Kokkos_DualView.hpp"
56 #include "Teuchos_Assert.hpp"
57 #include "Teuchos_CommHelpers.hpp"
58 #include "Teuchos_OrdinalTraits.hpp"
59 #include "Teuchos_TypeNameTraits.hpp"
60 #include "Teuchos_Utils.hpp"
65 #if defined(HAVE_TPETRA_THROW_EFFICIENCY_WARNINGS) || defined(HAVE_TPETRA_PRINT_EFFICIENCY_WARNINGS)
66 #define TPETRA_EFFICIENCY_WARNING(throw_exception_test,Exception,msg) \
101 const bool tpetraEfficiencyWarningTest = (throw_exception_test); \
102 if (tpetraEfficiencyWarningTest) { \
103 std::ostringstream errStream; \
104 errStream << Teuchos::typeName(*this) << ":" << std::endl; \
105 errStream << "Efficiency warning: " << #throw_exception_test << std::endl; \
107 std::string err = errStream.str(); \
108 if (TPETRA_PRINTS_EFFICIENCY_WARNINGS && tpetraEfficiencyWarningTest) { \
109 std::cerr << err << std::endl; \
111 TEUCHOS_TEST_FOR_EXCEPTION(TPETRA_THROWS_EFFICIENCY_WARNINGS && tpetraEfficiencyWarningTest, Exception, err); \
115 #define TPETRA_EFFICIENCY_WARNING(throw_exception_test,Exception,msg)
152 #if defined(HAVE_TPETRA_THROW_ABUSE_WARNINGS) || defined(HAVE_TPETRA_PRINT_ABUSE_WARNINGS)
153 #define TPETRA_ABUSE_WARNING(throw_exception_test,Exception,msg) \
156 std::ostringstream errStream; \
157 errStream << Teuchos::typeName(*this) << msg; \
158 std::string err = errStream.str(); \
159 if (TPETRA_PRINTS_ABUSE_WARNINGS && (throw_exception_test)) { \
160 std::cerr << err << std::endl; \
162 TEUCHOS_TEST_FOR_EXCEPTION(TPETRA_THROWS_ABUSE_WARNINGS && (throw_exception_test), Exception, err); \
165 #define TPETRA_ABUSE_WARNING(throw_exception_test,Exception,msg)
198 #define SHARED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm) \
200 using Teuchos::outArg; \
201 const int lcl_throw_exception = (throw_exception_test) ? Teuchos::rank(comm)+1 : 0; \
203 Teuchos::reduceAll(comm,Teuchos::REDUCE_MAX,lcl_throw_exception,outArg(gbl_throw)); \
204 TEUCHOS_TEST_FOR_EXCEPTION(gbl_throw,Exception, \
205 msg << " Failure on at least one process, including process " << gbl_throw-1 << "." << std::endl); \
208 #ifdef HAVE_TEUCHOS_DEBUG
209 #define SWITCHED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm) \
212 SHARED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm); \
215 #define SWITCHED_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg,comm) \
218 TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test,Exception,msg); \
235 template<
typename MapType,
typename KeyArgType,
typename ValueArgType>
237 const KeyArgType & k,
238 const ValueArgType & v)
240 typename MapType::iterator lb = m.lower_bound(k);
241 if(lb != m.end() && !(m.key_comp()(k, lb->first))) {
246 typedef typename MapType::value_type MVT;
247 return(m.insert(lb, MVT(k, v)));
270 typedef typename std::iterator_traits<IT1>::difference_type DT;
271 DT myit = Teuchos::OrdinalTraits<DT>::one();
272 const DT sz = last - first;
273 for(;myit < sz; ++myit){
274 if(first[myit] < first[myit-1]){
292 IT pivot(first+(last-first)/2);
293 if(*first<=*pivot && *(last-1)<=*first) pivot=first;
294 else if(*(last-1)<=*pivot && *first<= *(last-1)) pivot = last-1;
312 template<
class IT1,
class IT2>
320 typename std::iterator_traits<IT1>::value_type piv(*pivot);
321 std::swap(*pivot, *(last1-1));
322 std::swap(first2[(pivot-first1)], *(last2-1));
324 for(IT1 it=first1; it!=last1-1; ++it){
326 std::swap(*store1, *it);
327 std::swap(first2[(store1-first1)], first2[(it-first1)]);
331 std::swap(*(last1-1), *store1);
332 std::swap(*(last2-1), first2[store1-first1]);
352 template<
class IT1,
class IT2,
class IT3>
362 typename std::iterator_traits<IT1>::value_type piv(*pivot);
363 std::swap(*pivot, *(last1-1));
364 std::swap(first2[(pivot-first1)], *(last2-1));
365 std::swap(first3[(pivot-first1)], *(last3-1));
367 for(IT1 it=first1; it!=last1-1; ++it){
369 std::swap(*store1, *it);
370 std::swap(first2[(store1-first1)], first2[(it-first1)]);
371 std::swap(first3[(store1-first1)], first3[(it-first1)]);
375 std::swap(*(last1-1), *store1);
376 std::swap(*(last2-1), first2[store1-first1]);
377 std::swap(*(last3-1), first3[store1-first1]);
391 template<
class IT1,
class IT2>
398 typedef typename std::iterator_traits<IT1>::difference_type DT;
399 DT DT1 = Teuchos::OrdinalTraits<DT>::one();
400 if(last1-first1 > DT1){
401 IT1 pivot =
getPivot(first1, last1);
402 pivot =
partition2(first1, last1, first2, last2, pivot);
403 quicksort2(first1, pivot, first2, first2+(pivot-first1));
404 quicksort2(pivot+1, last1, first2+(pivot-first1)+1, last2);
420 template<
class IT1,
class IT2,
class IT3>
429 typedef typename std::iterator_traits<IT1>::difference_type DT;
430 DT DT1 = Teuchos::OrdinalTraits<DT>::one();
431 if(last1-first1 > DT1){
432 IT1 pivot =
getPivot(first1, last1);
433 pivot =
partition3(first1, last1, first2, last2, first3, last3, pivot);
434 quicksort3(first1, pivot, first2, first2+(pivot-first1), first3, first3+(pivot-first1));
435 quicksort3(pivot+1, last1, first2+(pivot-first1)+1, last2, first3+(pivot-first1)+1, last3);
445 template<
class IT1,
class IT2,
class IT3>
454 typedef typename std::iterator_traits<IT1>::difference_type DT;
455 DT n = last1 - first1;
457 DT z = Teuchos::OrdinalTraits<DT>::zero();
461 for (DT j = 0; j < max; j++)
463 for (DT k = j; k >= 0; k-=m)
465 if (first1[k+m] >= first1[k])
467 std::swap(first1[k+m], first1[k]);
468 std::swap(first2[k+m], first2[k]);
469 std::swap(first3[k+m], first3[k]);
482 template<
class IT1,
class IT2>
489 typedef typename std::iterator_traits<IT1>::difference_type DT;
490 DT n = last1 - first1;
492 DT z = Teuchos::OrdinalTraits<DT>::zero();
496 for (DT j = 0; j < max; j++)
498 for (DT k = j; k >= 0; k-=m)
500 if (first1[k+m] >= first1[k])
502 std::swap(first1[k+m], first1[k]);
503 std::swap(first2[k+m], first2[k]);
531 template<
class IT1,
class IT2>
532 void sort2(
const IT1 &first1,
const IT1 &last1,
const IT2 &first2) {
537 if(SortDetails::isAlreadySorted(first1, last1)){
540 SortDetails::sh_sort2(first1, last1, first2, first2+(last1-first1));
541 #ifdef HAVE_TPETRA_DEBUG
542 if(!SortDetails::isAlreadySorted(first1, last1)){
543 std::cout <<
"Trouble: sort() did not sort !!" << std::endl;
565 template<
class IT1,
class IT2,
class IT3>
566 void sort3(
const IT1 &first1,
const IT1 &last1,
const IT2 &first2,
573 if(SortDetails::isAlreadySorted(first1, last1)){
576 SortDetails::sh_sort3(first1, last1, first2, first2+(last1-first1), first3,
577 first3+(last1-first1));
579 #ifdef HAVE_TPETRA_DEBUG
580 if(!SortDetails::isAlreadySorted(first1, last1)){
581 std::cout <<
" Trouble sort did not actually sort... !!!!!!" <<
631 template<
class IT1,
class IT2>
633 merge2 (IT1& indResultOut, IT2& valResultOut,
634 IT1 indBeg, IT1 indEnd,
635 IT2 valBeg, IT2 valEnd)
637 if (indBeg == indEnd) {
638 indResultOut = indBeg;
639 valResultOut = valBeg;
642 IT1 indResult = indBeg;
643 IT2 valResult = valBeg;
644 if (indBeg != indEnd) {
647 while (indBeg != indEnd) {
648 if (*indResult == *indBeg) {
649 *valResult += *valBeg;
651 *(++indResult) = *indBeg;
652 *(++valResult) = *valBeg;
667 indResultOut = indResult;
668 valResultOut = valResult;
720 template<
class IT1,
class IT2,
class BinaryFunction>
722 merge2 (IT1& indResultOut, IT2& valResultOut,
723 IT1 indBeg, IT1 indEnd,
724 IT2 valBeg, IT2 valEnd,
727 if (indBeg == indEnd) {
728 indResultOut = indBeg;
729 valResultOut = valBeg;
732 IT1 indResult = indBeg;
733 IT2 valResult = valBeg;
734 if (indBeg != indEnd) {
737 while (indBeg != indEnd) {
738 if (*indResult == *indBeg) {
739 *valResult = f (*valResult, *valBeg);
741 *(++indResult) = *indBeg;
742 *(++valResult) = *valBeg;
752 indResultOut = indResult;
753 valResultOut = valResult;
786 template<
class KeyInputIterType,
class ValueInputIterType,
787 class KeyOutputIterType,
class ValueOutputIterType,
788 class BinaryFunction>
791 ValueInputIterType valBeg1, ValueInputIterType valEnd1,
792 KeyInputIterType keyBeg2, KeyInputIterType keyEnd2,
793 ValueInputIterType valBeg2, ValueInputIterType valEnd2,
794 KeyOutputIterType keyOut, ValueOutputIterType valOut,
797 while (keyBeg1 != keyEnd1 && keyBeg2 != keyEnd2) {
798 if (*keyBeg1 < *keyBeg2) {
799 *keyOut++ = *keyBeg1++;
800 *valOut++ = *valBeg1++;
801 }
else if (*keyBeg1 > *keyBeg2) {
802 *keyOut++ = *keyBeg2++;
803 *valOut++ = *valBeg2++;
805 *keyOut++ = *keyBeg1;
806 *valOut++ = f (*valBeg1, *valBeg2);
814 std::copy (keyBeg1, keyEnd1, keyOut);
815 std::copy (valBeg1, valEnd1, valOut);
816 std::copy (keyBeg2, keyEnd2, keyOut);
817 std::copy (valBeg2, valEnd2, valOut);
820 template<
class KeyInputIterType>
822 keyMergeCount (KeyInputIterType keyBeg1, KeyInputIterType keyEnd1,
823 KeyInputIterType keyBeg2, KeyInputIterType keyEnd2)
826 while (keyBeg1 != keyEnd1 && keyBeg2 != keyEnd2) {
827 if (*keyBeg1 < *keyBeg2) {
829 }
else if (*keyBeg1 > *keyBeg2) {
838 count += static_cast<size_t> (keyEnd1 - keyBeg1) +
839 static_cast<size_t> (keyEnd2 - keyBeg2);
864 congruent (
const Teuchos::Comm<int>& comm1,
865 const Teuchos::Comm<int>& comm2);
876 template<
class DualViewType>
877 Teuchos::ArrayView<typename DualViewType::t_dev::value_type>
880 static_assert (static_cast<int> (DualViewType::t_dev::rank) == 1,
881 "The input DualView must have rank 1.");
882 TEUCHOS_TEST_FOR_EXCEPTION
883 (x.template need_sync<Kokkos::HostSpace> (), std::logic_error,
"The "
884 "input Kokkos::DualView was most recently modified on device, but this "
885 "function needs the host view of the data to be the most recently "
888 auto x_host = x.template view<Kokkos::HostSpace> ();
889 typedef typename DualViewType::t_dev::value_type value_type;
890 return Teuchos::ArrayView<value_type> (x_host.data (),
910 template<
class T,
class DT>
911 Kokkos::DualView<T*, DT>
914 const bool leaveOnHost)
916 using Kokkos::MemoryUnmanaged;
917 typedef typename DT::memory_space DMS;
918 typedef Kokkos::HostSpace HMS;
920 const size_t len = static_cast<size_t> (x_av.size ());
921 Kokkos::View<const T*, HMS, MemoryUnmanaged> x_in (x_av.getRawPtr (), len);
922 Kokkos::DualView<T*, DT> x_out (label, len);
924 x_out.template modify<HMS> ();
928 x_out.template modify<DMS> ();
941 template<
class DualViewType>
944 const auto host = dv.modified_host ();
945 const auto dev = dv.modified_host ();
947 std::ostringstream os;
948 os << name <<
": {size: " << dv.extent (0)
949 <<
", sync: {host: " << host <<
", dev: " << dev <<
"}";
956 #endif // TPETRA_UTIL_HPP