Teuchos_CommHelpers.hpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //                    Teuchos: Common Tools Package
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
00028 
00029 #ifndef TEUCHOS_COMM_HELPERS_HPP
00030 #define TEUCHOS_COMM_HELPERS_HPP
00031 
00032 #include "Teuchos_Comm.hpp"
00033 #include "Teuchos_CommUtilities.hpp"
00034 #include "Teuchos_SerializationTraitsHelpers.hpp"
00035 #include "Teuchos_ReductionOpHelpers.hpp"
00036 #include "Teuchos_SerializerHelpers.hpp"
00037 #include "Teuchos_ScalarTraits.hpp"
00038 #include "Teuchos_OrdinalTraits.hpp"
00039 #include "Teuchos_Array.hpp"
00040 #include "Teuchos_TypeNameTraits.hpp"
00041 #include "Teuchos_Workspace.hpp"
00042 #include "Teuchos_as.hpp"
00043 
00044 
00045 namespace Teuchos {
00046 
00047 
00048 //
00049 // Teuchos::Comm Helper Functions
00050 //
00051 
00057 enum EReductionType {
00058   REDUCE_SUM, 
00059   REDUCE_MIN, 
00060   REDUCE_MAX, 
00061   REDUCE_AND 
00062 };
00063 
00068 inline
00069 const char* toString( const EReductionType reductType )
00070 {
00071   switch(reductType) {
00072     case REDUCE_SUM: return "REDUCE_SUM";
00073     case REDUCE_MIN: return "REDUCE_MIN";
00074     case REDUCE_MAX: return "REDUCE_MAX";
00075     case REDUCE_AND: return "REDUCE_AND";
00076     default: TEST_FOR_EXCEPT(true);
00077   }
00078   return 0; // Will never be called
00079 }
00080 
00085 template<typename Ordinal>
00086 int rank(const Comm<Ordinal>& comm);
00087 
00092 template<typename Ordinal>
00093 int size(const Comm<Ordinal>& comm);
00094 
00099 template<typename Ordinal>
00100 void barrier(const Comm<Ordinal>& comm);
00101 
00106 template<typename Ordinal, typename Packet>
00107 void broadcast(
00108   const Comm<Ordinal>& comm,
00109   const int rootRank,
00110   const Ordinal count, Packet buffer[]
00111   );
00112 
00117 template<typename Ordinal, typename Packet>
00118 void broadcast(
00119   const Comm<Ordinal>& comm,
00120   const int rootRank,
00121   const ArrayView<Packet> &buffer
00122   );
00123 
00128 template<typename Ordinal, typename Packet>
00129 void broadcast(
00130   const Comm<Ordinal>& comm,
00131   const int rootRank, Packet *object
00132   );
00133 
00138 template<typename Ordinal, typename Packet>
00139 void broadcast(
00140   const Comm<Ordinal>& comm,
00141   const int rootRank, const Ptr<Packet> &object
00142   );
00143 
00148 template<typename Ordinal, typename Packet>
00149 void broadcast(
00150   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00151   const int rootRank, const Ordinal count, Packet*const buffer[]
00152   );
00153 
00159 template<typename Ordinal, typename Packet>
00160 void gatherAll(
00161   const Comm<Ordinal>& comm,
00162   const Ordinal sendCount, const Packet sendBuffer[],
00163   const Ordinal recvCount, Packet recvBuffer[]
00164   );
00165 
00171 template<typename Ordinal, typename Packet>
00172 void gatherAll(
00173   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00174   const Ordinal sendCount, const Packet*const sendBuffer[],
00175   const Ordinal recvCount, Packet*const recvBuffer[]
00176   );
00177 
00183 template<typename Ordinal, typename Packet>
00184 void reduceAll(
00185   const Comm<Ordinal>& comm, const ValueTypeReductionOp<Ordinal,Packet> &reductOp,
00186   const Ordinal count, const Packet sendBuffer[], Packet globalReducts[]
00187   );
00188 
00194 template<typename Ordinal, typename Packet>
00195 void reduceAll(
00196   const Comm<Ordinal>& comm, const EReductionType reductType,
00197   const Ordinal count, const Packet sendBuffer[], Packet globalReducts[]
00198   );
00199 
00205 template<typename Ordinal, typename Packet>
00206 void reduceAll(
00207   const Comm<Ordinal>& comm, const EReductionType reductType,
00208   const Packet &send, Packet *globalReduct
00209   );
00210 
00216 template<typename Ordinal, typename Packet>
00217 void reduceAll(
00218   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00219   const ReferenceTypeReductionOp<Ordinal,Packet> &reductOp,
00220   const Ordinal count, const Packet*const sendBuffer[], Packet*const globalReducts[]
00221   );
00222 
00228 template<typename Ordinal, typename Packet>
00229 void reduceAllAndScatter(
00230   const Comm<Ordinal>& comm, const ValueTypeReductionOp<Ordinal,Packet> &reductOp,
00231   const Ordinal sendCount, const Packet sendBuffer[] ,
00232   const Ordinal recvCounts[], Packet myGlobalReducts[]
00233   );
00234 
00240 template<typename Ordinal, typename Packet>
00241 void reduceAllAndScatter(
00242   const Comm<Ordinal>& comm, const EReductionType reductType,
00243   const Ordinal sendCount, const Packet sendBuffer[] ,
00244   const Ordinal recvCounts[], Packet myGlobalReducts[]
00245   );
00246 
00252 template<typename Ordinal, typename Packet>
00253 void reduceAllAndScatter(
00254   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00255   const ReferenceTypeReductionOp<Ordinal,Packet> &reductOp,
00256   const Ordinal sendCount, const Packet*const sendBuffer[] ,
00257   const Ordinal recvCounts[], Packet*const myGlobalReducts[]
00258   );
00259 
00265 template<typename Ordinal, typename Packet>
00266 void scan(
00267   const Comm<Ordinal>& comm, const ValueTypeReductionOp<Ordinal,Packet> &reductOp,
00268   const Ordinal count, const Packet sendBuffer[], Packet scanReducts[]
00269   );
00270 
00276 template<typename Ordinal, typename Packet>
00277 void scan(
00278   const Comm<Ordinal>& comm, const EReductionType reductType,
00279   const Ordinal count, const Packet sendBuffer[], Packet scanReducts[]
00280   );
00281 
00287 template<typename Ordinal, typename Packet>
00288 void scan(
00289   const Comm<Ordinal>& comm, const EReductionType reductType,
00290   const Packet &send, Packet *scanReduct
00291   );
00292 
00298 template<typename Ordinal, typename Packet>
00299 void scan(
00300   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00301   const ReferenceTypeReductionOp<Ordinal,Packet> &reductOp,
00302   const Ordinal count, const Packet*const sendBuffer[], Packet*const scanReducts[]
00303   );
00304 
00309 template<typename Ordinal, typename Packet>
00310 void send(
00311   const Comm<Ordinal>& comm,
00312   const Ordinal count, const Packet sendBuffer[], const int destRank
00313   );
00314 
00319 template<typename Ordinal, typename Packet>
00320 void send(
00321   const Comm<Ordinal>& comm,
00322   const Packet &send, const int destRank
00323   );
00324 
00331 template<typename Ordinal, typename Packet>
00332 void send(
00333   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00334   const Ordinal count, const Packet*const sendBuffer[], const int destRank
00335   );
00336 
00341 template<typename Ordinal, typename Packet>
00342 int receive(
00343   const Comm<Ordinal>& comm,
00344   const int sourceRank, const Ordinal count, Packet recvBuffer[] 
00345   );
00346 
00351 template<typename Ordinal, typename Packet>
00352 int receive(
00353   const Comm<Ordinal>& comm,
00354   const int sourceRank, Packet *recv 
00355   );
00356 
00361 template<typename Ordinal, typename Packet>
00362 int receive(
00363   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00364   const int sourceRank, const Ordinal count, Packet*const recvBuffer[] 
00365   );
00366 
00372 template<typename Ordinal, typename Packet>
00373 void readySend(
00374   const Comm<Ordinal>& comm,
00375   const ArrayView<const Packet> &sendBuffer,
00376   const int destRank
00377   );
00378 
00383 template<typename Ordinal, typename Packet>
00384 void readySend(
00385   const Comm<Ordinal>& comm,
00386   const Packet &send,
00387   const int destRank
00388   );
00389 
00394 template<typename Ordinal, typename Packet>
00395 RCP<CommRequest> isend(
00396   const Comm<Ordinal>& comm,
00397   const ArrayRCP<const Packet> &sendBuffer,
00398   const int destRank
00399   );
00400 
00401 
00406 template<typename Ordinal, typename Packet>
00407 RCP<CommRequest> isend(
00408   const Comm<Ordinal>& comm,
00409   const RCP<const Packet> &send,
00410   const int destRank
00411   );
00412 
00413 
00414 // 2008/07/29: rabartl: ToDo: Add reference semantics version of isend!
00415 
00416 
00421 template<typename Ordinal, typename Packet>
00422 RCP<CommRequest> ireceive(
00423   const Comm<Ordinal>& comm,
00424   const ArrayRCP<Packet> &recvBuffer,
00425   const int sourceRank
00426   );
00427 
00428 
00433 template<typename Ordinal, typename Packet>
00434 RCP<CommRequest> ireceive(
00435   const Comm<Ordinal>& comm,
00436   const RCP<Packet> &recv,
00437   const int sourceRank
00438   );
00439 
00440 
00441 // 2008/07/29: rabartl: ToDo: Add reference semantics version of ireceive!
00442 
00443 
00451 template<typename Ordinal>
00452 void waitAll(
00453   const Comm<Ordinal>& comm,
00454   const ArrayView<RCP<CommRequest> > &requests
00455   );
00456 
00464 template<typename Ordinal>
00465 void wait(
00466   const Comm<Ordinal>& comm,
00467   const Ptr<RCP<CommRequest> > &request
00468   );
00469 
00470 
00471 //
00472 // Standard reduction subclasses for objects that use value semantics
00473 //
00474 
00475 
00480 template<typename Ordinal, typename Packet>
00481 class SumValueReductionOp : public ValueTypeReductionOp<Ordinal,Packet>
00482 {
00483 public:
00485   void reduce(
00486     const Ordinal count,
00487     const Packet inBuffer[],
00488     Packet inoutBuffer[]
00489     ) const;
00490 };
00491 
00492 
00501 template<typename Ordinal, typename Packet>
00502 class MinValueReductionOp : public ValueTypeReductionOp<Ordinal,Packet>
00503 {
00504 public:
00506   void reduce(
00507     const Ordinal count,
00508     const Packet inBuffer[],
00509     Packet inoutBuffer[]
00510     ) const;
00511 };
00512 
00513 
00522 template<typename Ordinal, typename Packet>
00523 class MaxValueReductionOp : public ValueTypeReductionOp<Ordinal,Packet>
00524 {
00525 public:
00527   void reduce(
00528     const Ordinal count,
00529     const Packet inBuffer[],
00530     Packet inoutBuffer[]
00531     ) const;
00532 };
00533 
00534 
00539 template<typename Ordinal, typename Packet>
00540 class ANDValueReductionOp : public ValueTypeReductionOp<Ordinal,Packet>
00541 {
00542 public:
00544   void reduce(
00545     const Ordinal count,
00546     const Packet inBuffer[],
00547     Packet inoutBuffer[]
00548     ) const;
00549 };
00550 
00551 
00552 // ////////////////////////////////////////////////////////////
00553 // Implementation details (not for geneal users to mess with)
00554 
00555 
00556 //
00557 // ReductionOp Utilities
00558 //
00559 
00560 
00561 namespace MixMaxUtilities {
00562 
00563 
00564 template<bool isComparable, typename Ordinal, typename Packet>
00565 class Min {};
00566 
00567 
00568 template<typename Ordinal, typename Packet>
00569 class Min<true,Ordinal,Packet> {
00570 public:
00571   static void min(
00572     const Ordinal count,
00573     const Packet inBuffer[],
00574     Packet inoutBuffer[]
00575     )
00576     {
00577       for( int i = 0; i < count; ++i )
00578         inoutBuffer[i] = TEUCHOS_MIN(inoutBuffer[i],inBuffer[i]);
00579     }
00580 };
00581 
00582 
00583 template<typename Ordinal, typename Packet>
00584 class Min<false,Ordinal,Packet> {
00585 public:
00586   static void min(
00587     const Ordinal,
00588     const Packet[],
00589     Packet[]
00590     )
00591     {
00592       TEST_FOR_EXCEPTION(
00593         true,std::logic_error,
00594         "Error, the type "<<TypeNameTraits<Packet>::name()
00595         <<" does not support comparison operations!"
00596         );
00597     }
00598 };
00599 
00600 
00601 template<bool isComparable, typename Ordinal, typename Packet>
00602 class Max {};
00603 
00604 
00605 template<typename Ordinal, typename Packet>
00606 class Max<true,Ordinal,Packet> {
00607 public:
00608   static void max(
00609     const Ordinal count,
00610     const Packet inBuffer[],
00611     Packet inoutBuffer[]
00612     )
00613     {
00614       for( int i = 0; i < count; ++i )
00615         inoutBuffer[i] = TEUCHOS_MAX(inoutBuffer[i],inBuffer[i]);
00616     }
00617 };
00618 
00619 
00620 template<typename Ordinal, typename Packet>
00621 class Max<false,Ordinal,Packet> {
00622 public:
00623   static void max(
00624     const Ordinal,
00625     const Packet[],
00626     Packet[]
00627     )
00628     {
00629       TEST_FOR_EXCEPTION(
00630         true,std::logic_error,
00631         "Error, the type "<<TypeNameTraits<Packet>::name()
00632         <<" does not support comparison operations!"
00633         );
00634     }
00635 };
00636 
00637 
00638 template<bool isComparable, typename Ordinal, typename Packet>
00639 class AND {};
00640 
00641 
00642 template<typename Ordinal, typename Packet>
00643 class AND<true,Ordinal,Packet> {
00644 public:
00645   static void andOp(
00646     const Ordinal count,
00647     const Packet inBuffer[],
00648     Packet inoutBuffer[]
00649     )
00650     {
00651       for( int i = 0; i < count; ++i )
00652         inoutBuffer[i] = inoutBuffer[i] && inBuffer[i];
00653     }
00654 };
00655 
00656 
00657 template<typename Ordinal, typename Packet>
00658 class AND<false,Ordinal,Packet> {
00659 public:
00660   static void andOp(
00661     const Ordinal,
00662     const Packet[],
00663     Packet[]
00664     )
00665     {
00666       TEST_FOR_EXCEPTION(
00667         true,std::logic_error,
00668         "Error, the type "<<TypeNameTraits<Packet>::name()
00669         <<" does not support logical AND operations!"
00670         );
00671     }
00672 };
00673 
00674 
00675 } // namespace MixMaxUtilities
00676 
00677 
00678 template<typename Ordinal, typename Packet>
00679 void SumValueReductionOp<Ordinal,Packet>::reduce(
00680   const Ordinal count,
00681   const Packet inBuffer[],
00682   Packet inoutBuffer[]
00683   ) const
00684 {
00685   for( int i = 0; i < count; ++i )
00686     inoutBuffer[i] += inBuffer[i];
00687 }
00688 
00689 
00690 template<typename Ordinal, typename Packet>
00691 void MinValueReductionOp<Ordinal,Packet>::reduce(
00692   const Ordinal count,
00693   const Packet inBuffer[],
00694   Packet inoutBuffer[]
00695   ) const
00696 {
00697   typedef ScalarTraits<Packet> ST;
00698   MixMaxUtilities::Min<ST::isComparable,Ordinal,Packet>::min(
00699     count,inBuffer,inoutBuffer
00700     );
00701 }
00702 
00703 
00704 template<typename Ordinal, typename Packet>
00705 void MaxValueReductionOp<Ordinal,Packet>::reduce(
00706   const Ordinal count,
00707   const Packet inBuffer[],
00708   Packet inoutBuffer[]
00709   ) const
00710 {
00711   typedef ScalarTraits<Packet> ST;
00712   MixMaxUtilities::Max<ST::isComparable,Ordinal,Packet>::max(
00713     count,inBuffer,inoutBuffer
00714     );
00715 }
00716 
00717 
00718 template<typename Ordinal, typename Packet>
00719 void ANDValueReductionOp<Ordinal,Packet>::reduce(
00720   const Ordinal count,
00721   const Packet inBuffer[],
00722   Packet inoutBuffer[]
00723   ) const
00724 {
00725   typedef ScalarTraits<Packet> ST;
00726   MixMaxUtilities::AND<ST::isComparable,Ordinal,Packet>::andOp(
00727     count,inBuffer,inoutBuffer
00728     );
00729 }
00730 
00731 
00732 } // namespace Teuchos
00733 
00734 
00735 // //////////////////////////
00736 // Template implemenations
00737 
00738 
00739 //
00740 // ReductionOp utilities
00741 //
00742 
00743 
00744 namespace Teuchos {
00745 
00746 
00747 // Not for the general user to use! I am returning a raw ReducionOp* pointer
00748 // to avoid the overhead of using RCP. However, given the use case
00749 // this is just fine since I can just use std::auto_ptr to make sure things
00750 // are deleted correctly.
00751 template<typename Ordinal, typename Packet>
00752 ValueTypeReductionOp<Ordinal,Packet>*
00753 createOp( const EReductionType reductType )
00754 {
00755   typedef ScalarTraits<Packet> ST;
00756   switch(reductType) {
00757     case REDUCE_SUM: {
00758       return new SumValueReductionOp<Ordinal,Packet>();
00759       break;
00760     }
00761     case REDUCE_MIN: {
00762       TEST_FOR_EXCEPT(!ST::isComparable);
00763       return new MinValueReductionOp<Ordinal,Packet>();
00764       break;
00765     }
00766     case REDUCE_MAX: {
00767       TEST_FOR_EXCEPT(!ST::isComparable);
00768       return new MaxValueReductionOp<Ordinal,Packet>();
00769       break;
00770     }
00771     case REDUCE_AND: {
00772       return new ANDValueReductionOp<Ordinal, Packet>();
00773       break;
00774     }
00775     default:
00776       TEST_FOR_EXCEPT(true);
00777   }
00778   return 0; // Will never be called!
00779 }
00780 
00781 
00782 } // namespace Teuchos
00783 
00784 
00785 //
00786 // Teuchos::Comm wrapper functions
00787 //
00788 
00789 
00790 template<typename Ordinal>
00791 int Teuchos::rank(const Comm<Ordinal>& comm)
00792 {
00793   return comm.getRank();
00794 }
00795 
00796 
00797 template<typename Ordinal>
00798 int Teuchos::size(const Comm<Ordinal>& comm)
00799 {
00800   return comm.getSize();
00801 }
00802 
00803 
00804 template<typename Ordinal>
00805 void Teuchos::barrier(const Comm<Ordinal>& comm)
00806 {
00807   TEUCHOS_COMM_TIME_MONITOR(
00808     "Teuchos::CommHelpers: barrier<"
00809     <<OrdinalTraits<Ordinal>::name()
00810     <<">()"
00811     );
00812   comm.barrier();
00813 }
00814 
00815 
00816 template<typename Ordinal, typename Packet>
00817 void Teuchos::broadcast(
00818   const Comm<Ordinal>& comm,
00819   const int rootRank, const Ordinal count, Packet buffer[]
00820   )
00821 {
00822   TEUCHOS_COMM_TIME_MONITOR(
00823     "Teuchos::CommHelpers: broadcast<"
00824     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
00825     <<">( value type )"
00826     );
00827   ValueTypeSerializationBuffer<Ordinal,Packet>
00828     charBuffer(count,buffer);
00829   comm.broadcast(
00830     rootRank,charBuffer.getBytes(),charBuffer.getCharBuffer()
00831     );
00832 }
00833 
00834 
00835 template<typename Ordinal, typename Packet>
00836 void Teuchos::broadcast(
00837   const Comm<Ordinal>& comm,
00838   const int rootRank,
00839   const ArrayView<Packet> &buffer
00840   )
00841 {
00842   broadcast<Ordinal, Packet>(comm, rootRank, buffer.size(), buffer.getRawPtr() );
00843 }
00844 
00845 
00846 template<typename Ordinal, typename Packet>
00847 void Teuchos::broadcast(
00848   const Comm<Ordinal>& comm,
00849   const int rootRank, Packet *object
00850   )
00851 {
00852   broadcast<Ordinal,Packet>(comm,rootRank,1,object);
00853 }
00854 
00855 
00856 template<typename Ordinal, typename Packet>
00857 void Teuchos::broadcast(
00858   const Comm<Ordinal>& comm,
00859   const int rootRank, const Ptr<Packet> &object
00860   )
00861 {
00862   broadcast<Ordinal,Packet>(comm,rootRank,1,object.getRawPtr());
00863 }
00864 
00865 
00866 template<typename Ordinal, typename Packet>
00867 void Teuchos::broadcast(
00868   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00869   const int rootRank, const Ordinal count, Packet*const buffer[]
00870   )
00871 {
00872   TEUCHOS_COMM_TIME_MONITOR(
00873     "Teuchos::CommHelpers: broadcast<"
00874     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
00875     <<">( reference type )"
00876     );
00877   ReferenceTypeSerializationBuffer<Ordinal,Packet>
00878     charBuffer(serializer,count,buffer);
00879   comm.broadcast(
00880     rootRank,charBuffer.getBytes(),charBuffer.getCharBuffer()
00881     );
00882 }
00883 
00884 
00885 template<typename Ordinal, typename Packet>
00886 void Teuchos::gatherAll(
00887   const Comm<Ordinal>& comm,
00888   const Ordinal sendCount, const Packet sendBuffer[],
00889   const Ordinal recvCount, Packet recvBuffer[]
00890   )
00891 {
00892   TEUCHOS_COMM_TIME_MONITOR(
00893     "Teuchos::CommHelpers: gatherAll<"
00894     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
00895     <<">( value type )"
00896     );
00897   ConstValueTypeSerializationBuffer<Ordinal,Packet>
00898     charSendBuffer(sendCount,sendBuffer);
00899   ValueTypeSerializationBuffer<Ordinal,Packet>
00900     charRecvBuffer(recvCount,recvBuffer);
00901   comm.gatherAll(
00902     charSendBuffer.getBytes(),charSendBuffer.getCharBuffer()
00903     ,charRecvBuffer.getBytes(),charRecvBuffer.getCharBuffer()
00904     );
00905 }
00906 
00907 
00908 template<typename Ordinal, typename Packet>
00909 void Teuchos::gatherAll(
00910   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00911   const Ordinal sendCount, const Packet*const sendBuffer[],
00912   const Ordinal recvCount, Packet*const recvBuffer[]
00913   )
00914 {
00915   TEST_FOR_EXCEPT(true); // ToDo: Implement and test when needed!
00916 }
00917 
00918 
00919 template<typename Ordinal, typename Packet>
00920 void Teuchos::reduceAll(
00921   const Comm<Ordinal>& comm, const ValueTypeReductionOp<Ordinal,Packet> &reductOp
00922   ,const Ordinal count, const Packet sendBuffer[], Packet globalReducts[]
00923   )
00924 {
00925   TEUCHOS_COMM_TIME_MONITOR(
00926     "Teuchos::CommHelpers: reduceAll<"
00927     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
00928     <<">( value type, user-defined op )"
00929     );
00930   ConstValueTypeSerializationBuffer<Ordinal,Packet>
00931     charSendBuffer(count,sendBuffer);
00932   ValueTypeSerializationBuffer<Ordinal,Packet>
00933     charGlobalReducts(count,globalReducts);
00934   CharToValueTypeReductionOp<Ordinal,Packet>
00935     charReductOp(rcp(&reductOp,false));
00936   comm.reduceAll(
00937     charReductOp,charSendBuffer.getBytes(),charSendBuffer.getCharBuffer()
00938     ,charGlobalReducts.getCharBuffer()
00939     );
00940 }
00941 
00942 
00943 template<typename Ordinal, typename Packet>
00944 void Teuchos::reduceAll(
00945   const Comm<Ordinal>& comm, const EReductionType reductType,
00946   const Ordinal count, const Packet sendBuffer[], Packet globalReducts[]
00947   )
00948 {
00949   TEUCHOS_COMM_TIME_MONITOR(
00950     "Teuchos::CommHelpers: reduceAll<"
00951     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
00952     <<">( value type, "<<toString(reductType)<<" )"
00953     );
00954   std::auto_ptr<ValueTypeReductionOp<Ordinal,Packet> >
00955     reductOp(createOp<Ordinal,Packet>(reductType));
00956   reduceAll(comm,*reductOp,count,sendBuffer,globalReducts);
00957 }
00958 
00959 
00960 template<typename Ordinal, typename Packet>
00961 void Teuchos::reduceAll(
00962   const Comm<Ordinal>& comm, const EReductionType reductType
00963   ,const Packet &send, Packet *globalReduct
00964   )
00965 {
00966   reduceAll<Ordinal,Packet>(comm,reductType,1,&send,globalReduct);
00967 }
00968 
00969 
00970 template<typename Ordinal, typename Packet>
00971 void Teuchos::reduceAll(
00972   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00973   const ReferenceTypeReductionOp<Ordinal,Packet> &reductOp,
00974   const Ordinal count, const Packet*const sendBuffer[], Packet*const globalReducts[]
00975   )
00976 {
00977   TEUCHOS_COMM_TIME_MONITOR(
00978     "Teuchos::CommHelpers: reduceAll<"
00979     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
00980     <<">( reference type )"
00981     );
00982   ConstReferenceTypeSerializationBuffer<Ordinal,Packet>
00983     charSendBuffer(serializer,count,sendBuffer);
00984   ReferenceTypeSerializationBuffer<Ordinal,Packet>
00985     charGlobalReducts(serializer,count,globalReducts);
00986   CharToReferenceTypeReductionOp<Ordinal,Packet>
00987     charReductOp(rcp(&serializer,false),rcp(&reductOp,false));
00988   comm.reduceAll(
00989     charReductOp,charSendBuffer.getBytes(),charSendBuffer.getCharBuffer()
00990     ,charGlobalReducts.getCharBuffer()
00991     );
00992 }
00993 
00994 
00995 template<typename Ordinal, typename Packet>
00996 void Teuchos::reduceAllAndScatter(
00997   const Comm<Ordinal>& comm, const ValueTypeReductionOp<Ordinal,Packet> &reductOp,
00998   const Ordinal sendCount, const Packet sendBuffer[] ,
00999   const Ordinal recvCounts[], Packet myGlobalReducts[]
01000   )
01001 {
01002 
01003   TEUCHOS_COMM_TIME_MONITOR(
01004     "Teuchos::CommHelpers: reduceAllAndScatter<"
01005     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01006     <<">( value type, user-defined op )"
01007     );
01008 
01009   const Ordinal size = Teuchos::size(comm);
01010   const Ordinal rank = Teuchos::rank(comm);
01011 
01012 #ifdef TEUCHOS_DEBUG
01013   Ordinal sumRecvCounts = 0;
01014   for( Ordinal i = 0; i < size; ++i )
01015     sumRecvCounts += recvCounts[i];
01016   TEST_FOR_EXCEPT(!(sumRecvCounts==sendCount));
01017 #endif
01018 
01019   ConstValueTypeSerializationBuffer<Ordinal,Packet>
01020     charSendBuffer(sendCount,sendBuffer);
01021   ValueTypeSerializationBuffer<Ordinal,Packet>
01022     charMyGlobalReducts(recvCounts[rank], myGlobalReducts);
01023   CharToValueTypeReductionOp<Ordinal,Packet>
01024     charReductOp(rcp(&reductOp,false));
01025 
01026   const Ordinal
01027     packetSize = charSendBuffer.getBytes()/sendCount;
01028 
01029   WorkspaceStore* wss = get_default_workspace_store().get();
01030   Workspace<Ordinal> charRecvCounts(wss, size);
01031   for (Ordinal k = 0; k < size; ++k) {
01032     charRecvCounts[k] = as<Ordinal>(recvCounts[k] * packetSize);
01033   }
01034  
01035   comm.reduceAllAndScatter(
01036     charReductOp, charSendBuffer.getBytes(), charSendBuffer.getCharBuffer(),
01037     &charRecvCounts[0], charMyGlobalReducts.getCharBuffer()
01038     );
01039 
01040 }
01041 
01042 
01043 template<typename Ordinal, typename Packet>
01044 void Teuchos::reduceAllAndScatter(
01045   const Comm<Ordinal>& comm, const EReductionType reductType,
01046   const Ordinal sendCount, const Packet sendBuffer[] ,
01047   const Ordinal recvCounts[], Packet myGlobalReducts[]
01048   )
01049 {
01050   TEUCHOS_COMM_TIME_MONITOR(
01051     "Teuchos::CommHelpers: reduceAllAndScatter<"
01052     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01053     <<">( value type, "<<toString(reductType)<<" )"
01054     );
01055   std::auto_ptr<ValueTypeReductionOp<Ordinal,Packet> >
01056     reductOp(createOp<Ordinal,Packet>(reductType));
01057   reduceAllAndScatter(
01058     comm, *reductOp, sendCount, sendBuffer, recvCounts, myGlobalReducts
01059     );
01060 }
01061 
01062 
01063 template<typename Ordinal, typename Packet>
01064 void Teuchos::reduceAllAndScatter(
01065   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
01066   const ReferenceTypeReductionOp<Ordinal,Packet> &reductOp,
01067   const Ordinal sendCount, const Packet*const sendBuffer[],
01068   const Ordinal recvCounts[], Packet*const myGlobalReducts[]
01069   )
01070 {
01071   TEST_FOR_EXCEPT(true); // ToDo: Implement and test when needed!
01072 }
01073 
01074 
01075 template<typename Ordinal, typename Packet>
01076 void Teuchos::scan(
01077   const Comm<Ordinal>& comm, const ValueTypeReductionOp<Ordinal,Packet> &reductOp,
01078   const Ordinal count, const Packet sendBuffer[], Packet scanReducts[]
01079   )
01080 {
01081   TEUCHOS_COMM_TIME_MONITOR(
01082     "Teuchos::CommHelpers: scan<"
01083     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01084     <<">( value type, user-defined op )"
01085     );
01086   ConstValueTypeSerializationBuffer<Ordinal,Packet>
01087     charSendBuffer(count,sendBuffer);
01088   ValueTypeSerializationBuffer<Ordinal,Packet>
01089     charScanReducts(count,scanReducts);
01090   CharToValueTypeReductionOp<Ordinal,Packet>
01091     charReductOp(rcp(&reductOp,false));
01092   comm.scan(
01093     charReductOp,charSendBuffer.getBytes(),charSendBuffer.getCharBuffer()
01094     ,charScanReducts.getCharBuffer()
01095     );
01096 }
01097 
01098 
01099 template<typename Ordinal, typename Packet>
01100 void Teuchos::scan(
01101   const Comm<Ordinal>& comm, const EReductionType reductType,
01102   const Ordinal count, const Packet sendBuffer[], Packet scanReducts[]
01103   )
01104 {
01105   TEUCHOS_COMM_TIME_MONITOR(
01106     "Teuchos::CommHelpers: scan<"
01107     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01108     <<">( value type, "<<toString(reductType)<<" )"
01109     );
01110   std::auto_ptr<ValueTypeReductionOp<Ordinal,Packet> >
01111     reductOp(createOp<Ordinal,Packet>(reductType));
01112   scan(comm,*reductOp,count,sendBuffer,scanReducts);
01113 }
01114 
01115 
01116 template<typename Ordinal, typename Packet>
01117 void Teuchos::scan(
01118   const Comm<Ordinal>& comm, const EReductionType reductType,
01119   const Packet &send, Packet *globalReduct
01120   )
01121 {
01122   scan<Ordinal,Packet>(comm,reductType,1,&send,globalReduct);
01123 }
01124 
01125 
01126 template<typename Ordinal, typename Packet>
01127 void Teuchos::scan(
01128   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
01129   const ReferenceTypeReductionOp<Ordinal,Packet> &reductOp,
01130   const Ordinal count, const Packet*const sendBuffer[], Packet*const scanReducts[]
01131   )
01132 {
01133   TEST_FOR_EXCEPT(true); // ToDo: Implement and test when needed!
01134 }
01135 
01136 
01137 template<typename Ordinal, typename Packet>
01138 void Teuchos::send(
01139   const Comm<Ordinal>& comm,
01140   const Ordinal count, const Packet sendBuffer[], const int destRank
01141   )
01142 {
01143   TEUCHOS_COMM_TIME_MONITOR(
01144     "Teuchos::CommHelpers: send<"
01145     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01146     <<">( value type )"
01147     );
01148   ConstValueTypeSerializationBuffer<Ordinal,Packet>
01149     charSendBuffer(count,sendBuffer);
01150   comm.send(
01151     charSendBuffer.getBytes(),charSendBuffer.getCharBuffer()
01152     ,destRank
01153     );
01154 }
01155 
01156 
01157 template<typename Ordinal, typename Packet>
01158 void Teuchos::send(
01159   const Comm<Ordinal>& comm,
01160   const Packet &send, const int destRank
01161   )
01162 {
01163   Teuchos::send<Ordinal,Packet>(comm,1,&send,destRank);
01164 }
01165 
01166 
01167 template<typename Ordinal, typename Packet>
01168 void Teuchos::send(
01169   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
01170   const Ordinal count, const Packet*const sendBuffer[], const int destRank
01171   )
01172 {
01173   TEST_FOR_EXCEPT(true); // ToDo: Implement and test when needed!
01174 }
01175 
01176 template<typename Ordinal, typename Packet>
01177 int Teuchos::receive(
01178   const Comm<Ordinal>& comm,
01179   const int sourceRank, const Ordinal count, Packet recvBuffer[] 
01180   )
01181 {
01182   TEUCHOS_COMM_TIME_MONITOR(
01183     "Teuchos::CommHelpers: receive<"
01184     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01185     <<">( value type )"
01186     );
01187   ValueTypeSerializationBuffer<Ordinal,Packet>
01188     charRecvBuffer(count,recvBuffer);
01189   return comm.receive(
01190     sourceRank
01191     ,charRecvBuffer.getBytes(),charRecvBuffer.getCharBuffer()
01192     );
01193 }
01194 
01195 
01196 template<typename Ordinal, typename Packet>
01197 int Teuchos::receive(
01198   const Comm<Ordinal>& comm,
01199   const int sourceRank, Packet *recv 
01200   )
01201 {
01202   return Teuchos::receive<Ordinal,Packet>(comm,sourceRank,1,recv);
01203 }
01204 
01205 
01206 template<typename Ordinal, typename Packet>
01207 int Teuchos::receive(
01208   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
01209   const int sourceRank, const Ordinal count, Packet*const recvBuffer[] 
01210   )
01211 {
01212   TEST_FOR_EXCEPT(true); // ToDo: Implement and test when needed!
01213 }
01214 
01215 
01216 template<typename Ordinal, typename Packet>
01217 void Teuchos::readySend(
01218   const Comm<Ordinal>& comm,
01219   const ArrayView<const Packet> &sendBuffer,
01220   const int destRank
01221   )
01222 {
01223   TEUCHOS_COMM_TIME_MONITOR(
01224     "Teuchos::CommHelpers: readySend<"
01225     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01226     <<">( value type )"
01227     );
01228   ConstValueTypeSerializationBuffer<Ordinal,Packet>
01229     charSendBuffer(sendBuffer.size(), sendBuffer.getRawPtr());
01230   comm.readySend( charSendBuffer.getCharBufferView(), destRank );
01231 }
01232 
01233 
01234 template<typename Ordinal, typename Packet>
01235 void Teuchos::readySend(
01236   const Comm<Ordinal>& comm,
01237   const Packet &send,
01238   const int destRank
01239   )
01240 {
01241   readySend<Ordinal, Packet>( comm, arrayView(&send,1), destRank );
01242 }
01243 
01244 
01245 template<typename Ordinal, typename Packet>
01246 Teuchos::RCP<Teuchos::CommRequest>
01247 Teuchos::isend(
01248   const Comm<Ordinal>& comm,
01249   const ArrayRCP<const Packet> &sendBuffer,
01250   const int destRank
01251   )
01252 {
01253   TEUCHOS_COMM_TIME_MONITOR(
01254     "Teuchos::CommHelpers: isend<"
01255     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01256     <<">( value type )"
01257     );
01258   ConstValueTypeSerializationBuffer<Ordinal,Packet>
01259     charSendBuffer(sendBuffer.size(), sendBuffer.getRawPtr());
01260   RCP<CommRequest> commRequest = comm.isend(
01261     charSendBuffer.getCharBufferView(), destRank );
01262   set_extra_data( sendBuffer, "buffer", &commRequest );
01263   return commRequest;
01264 }
01265 
01266 
01267 template<typename Ordinal, typename Packet>
01268 Teuchos::RCP<Teuchos::CommRequest>
01269 Teuchos::isend(
01270   const Comm<Ordinal>& comm,
01271   const RCP<const Packet> &send,
01272   const int destRank
01273   )
01274 {
01275   const ArrayRCP<const Packet> sendBuffer =
01276     arcpWithEmbeddedObj( send.get(), 0, 1, send, false );
01277   // 2008/07/29: rabartl: Above: I need to write a helper function to create
01278   // new ArrayRCP object given a single object to copy.
01279   return isend<Ordinal, Packet>( comm, sendBuffer, destRank );
01280 }
01281 
01282 
01283 template<typename Ordinal, typename Packet>
01284 Teuchos::RCP<Teuchos::CommRequest>
01285 Teuchos::ireceive(
01286   const Comm<Ordinal>& comm,
01287   const ArrayRCP<Packet> &recvBuffer,
01288   const int sourceRank
01289   )
01290 {
01291   typedef std::pair<RCP<CommRequest>, ArrayRCP<const Packet> > comm_buffer_pair_t;
01292   TEUCHOS_COMM_TIME_MONITOR(
01293     "Teuchos::CommHelpers: ireceive<"
01294     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01295     <<">( value type )"
01296     );
01297   ValueTypeSerializationBuffer<Ordinal,Packet>
01298     charRecvBuffer(recvBuffer.size(), recvBuffer.getRawPtr());
01299   RCP<CommRequest> commRequest = comm.ireceive(
01300     charRecvBuffer.getCharBufferView(), sourceRank );
01301   set_extra_data( recvBuffer, "buffer", &commRequest );
01302   return commRequest;
01303 }
01304 
01305 
01306 template<typename Ordinal, typename Packet>
01307 Teuchos::RCP<Teuchos::CommRequest>
01308 Teuchos::ireceive(
01309   const Comm<Ordinal>& comm,
01310   const RCP<Packet> &recv,
01311   const int sourceRank
01312   )
01313 {
01314   const ArrayRCP<Packet> recvBuffer =
01315     arcpWithEmbeddedObj( recv.get(), 0, 1, recv, false );
01316   // 2008/07/29: rabartl: Above: I need to write a helper function to create
01317   // new ArrayRCP object given a single object to copy.
01318   return ireceive<Ordinal, Packet>( comm, recvBuffer, sourceRank );
01319 }
01320 
01321 
01322 template<typename Ordinal>
01323 void Teuchos::waitAll(
01324   const Comm<Ordinal>& comm,
01325   const ArrayView<RCP<CommRequest> > &requests
01326   )
01327 {
01328   comm.waitAll(requests);
01329 }
01330 
01331 
01332 template<typename Ordinal>
01333 void Teuchos::wait(
01334   const Comm<Ordinal>& comm,
01335   const Ptr<RCP<CommRequest> > &request
01336   )
01337 {
01338   comm.wait(request);
01339   // NOTE: This will release the ArrayRCP to the buffer of data!
01340 }
01341 
01342 
01343 #endif // TEUCHOS_COMM_HELPERS_HPP

Generated on Wed May 12 21:40:31 2010 for Teuchos - Trilinos Tools Package by  doxygen 1.4.7