Teuchos - Trilinos Tools Package Version of the Day
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 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00038 //
00039 // ***********************************************************************
00040 // @HEADER
00041 
00042 #ifndef TEUCHOS_COMM_HELPERS_HPP
00043 #define TEUCHOS_COMM_HELPERS_HPP
00044 
00045 #include "Teuchos_Comm.hpp"
00046 #include "Teuchos_CommUtilities.hpp"
00047 #include "Teuchos_SerializationTraitsHelpers.hpp"
00048 #include "Teuchos_ReductionOpHelpers.hpp"
00049 #include "Teuchos_SerializerHelpers.hpp"
00050 #include "Teuchos_ScalarTraits.hpp"
00051 #include "Teuchos_OrdinalTraits.hpp"
00052 #include "Teuchos_Array.hpp"
00053 #include "Teuchos_TypeNameTraits.hpp"
00054 #include "Teuchos_Workspace.hpp"
00055 #include "Teuchos_as.hpp"
00056 
00057 
00058 namespace Teuchos {
00059 
00060 
00061 //
00062 // Teuchos::Comm Helper Functions
00063 //
00064 
00070 enum EReductionType {
00071   REDUCE_SUM, 
00072   REDUCE_MIN, 
00073   REDUCE_MAX, 
00074   REDUCE_AND 
00075 };
00076 
00081 inline
00082 const char* toString( const EReductionType reductType )
00083 {
00084   switch(reductType) {
00085     case REDUCE_SUM: return "REDUCE_SUM";
00086     case REDUCE_MIN: return "REDUCE_MIN";
00087     case REDUCE_MAX: return "REDUCE_MAX";
00088     case REDUCE_AND: return "REDUCE_AND";
00089     default: TEST_FOR_EXCEPT(true);
00090   }
00091   return 0; // Will never be called
00092 }
00093 
00098 template<typename Ordinal>
00099 int rank(const Comm<Ordinal>& comm);
00100 
00105 template<typename Ordinal>
00106 int size(const Comm<Ordinal>& comm);
00107 
00112 template<typename Ordinal>
00113 void barrier(const Comm<Ordinal>& comm);
00114 
00119 template<typename Ordinal, typename Packet>
00120 void broadcast(
00121   const Comm<Ordinal>& comm,
00122   const int rootRank,
00123   const Ordinal count, Packet buffer[]
00124   );
00125 
00130 template<typename Ordinal, typename Packet>
00131 void broadcast(
00132   const Comm<Ordinal>& comm,
00133   const int rootRank,
00134   const ArrayView<Packet> &buffer
00135   );
00136 
00141 template<typename Ordinal, typename Packet>
00142 void broadcast(
00143   const Comm<Ordinal>& comm,
00144   const int rootRank, Packet *object
00145   );
00146 
00151 template<typename Ordinal, typename Packet>
00152 void broadcast(
00153   const Comm<Ordinal>& comm,
00154   const int rootRank, const Ptr<Packet> &object
00155   );
00156 
00161 template<typename Ordinal, typename Packet>
00162 void broadcast(
00163   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00164   const int rootRank, const Ordinal count, Packet*const buffer[]
00165   );
00166 
00171 template<typename Ordinal, typename Packet>
00172 void broadcast(
00173   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00174   const int rootRank, const ArrayView<const Ptr<Packet> > &buffer
00175   );
00176 
00182 template<typename Ordinal, typename Packet>
00183 void gatherAll(
00184   const Comm<Ordinal>& comm,
00185   const Ordinal sendCount, const Packet sendBuffer[],
00186   const Ordinal recvCount, Packet recvBuffer[]
00187   );
00188 
00194 template<typename Ordinal, typename Packet>
00195 void gatherAll(
00196   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00197   const Ordinal sendCount, const Packet*const sendBuffer[],
00198   const Ordinal recvCount, Packet*const recvBuffer[]
00199   );
00200 
00206 template<typename Ordinal, typename Packet>
00207 void reduceAll(
00208   const Comm<Ordinal>& comm, const ValueTypeReductionOp<Ordinal,Packet> &reductOp,
00209   const Ordinal count, const Packet sendBuffer[], Packet globalReducts[]
00210   );
00211 
00217 template<typename Ordinal, typename Packet>
00218 void reduceAll(
00219   const Comm<Ordinal>& comm, const EReductionType reductType,
00220   const Ordinal count, const Packet sendBuffer[], Packet globalReducts[]
00221   );
00222 
00228 template<typename Ordinal, typename Packet>
00229 void reduceAll(
00230   const Comm<Ordinal>& comm, const EReductionType reductType,
00231   const Packet &send, const Ptr<Packet> &globalReduct
00232   );
00233 
00235 template<typename Ordinal, typename Packet>
00236 TEUCHOS_DEPRECATED void reduceAll(
00237   const Comm<Ordinal>& comm, const EReductionType reductType,
00238   const Packet &send, Packet *globalReduct
00239   )
00240 {
00241   reduceAll<Ordinal,Packet>(comm, reductType, send, ptr(globalReduct));
00242 }
00243 
00249 template<typename Ordinal, typename Packet>
00250 void reduceAll(
00251   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00252   const ReferenceTypeReductionOp<Ordinal,Packet> &reductOp,
00253   const Ordinal count, const Packet*const sendBuffer[], Packet*const globalReducts[]
00254   );
00255 
00261 template<typename Ordinal, typename Packet>
00262 void reduceAllAndScatter(
00263   const Comm<Ordinal>& comm, const ValueTypeReductionOp<Ordinal,Packet> &reductOp,
00264   const Ordinal sendCount, const Packet sendBuffer[] ,
00265   const Ordinal recvCounts[], Packet myGlobalReducts[]
00266   );
00267 
00273 template<typename Ordinal, typename Packet>
00274 void reduceAllAndScatter(
00275   const Comm<Ordinal>& comm, const EReductionType reductType,
00276   const Ordinal sendCount, const Packet sendBuffer[] ,
00277   const Ordinal recvCounts[], Packet myGlobalReducts[]
00278   );
00279 
00285 template<typename Ordinal, typename Packet>
00286 void reduceAllAndScatter(
00287   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00288   const ReferenceTypeReductionOp<Ordinal,Packet> &reductOp,
00289   const Ordinal sendCount, const Packet*const sendBuffer[] ,
00290   const Ordinal recvCounts[], Packet*const myGlobalReducts[]
00291   );
00292 
00298 template<typename Ordinal, typename Packet>
00299 void scan(
00300   const Comm<Ordinal>& comm, const ValueTypeReductionOp<Ordinal,Packet> &reductOp,
00301   const Ordinal count, const Packet sendBuffer[], Packet scanReducts[]
00302   );
00303 
00309 template<typename Ordinal, typename Packet>
00310 void scan(
00311   const Comm<Ordinal>& comm, const EReductionType reductType,
00312   const Ordinal count, const Packet sendBuffer[], Packet scanReducts[]
00313   );
00314 
00320 template<typename Ordinal, typename Packet>
00321 void scan(
00322   const Comm<Ordinal>& comm, const EReductionType reductType,
00323   const Packet &send, const Ptr<Packet> &scanReduct
00324   );
00325 
00327 template<typename Ordinal, typename Packet>
00328 TEUCHOS_DEPRECATED void scan(
00329   const Comm<Ordinal>& comm, const EReductionType reductType,
00330   const Packet &send, Packet *scanReduct
00331   )
00332 {
00333   scan(comm, reductType, send, ptr(scanReduct));
00334 }
00335 
00341 template<typename Ordinal, typename Packet>
00342 void scan(
00343   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00344   const ReferenceTypeReductionOp<Ordinal,Packet> &reductOp,
00345   const Ordinal count, const Packet*const sendBuffer[], Packet*const scanReducts[]
00346   );
00347 
00352 template<typename Ordinal, typename Packet>
00353 void send(
00354   const Comm<Ordinal>& comm,
00355   const Ordinal count, const Packet sendBuffer[], const int destRank
00356   );
00357 
00362 template<typename Ordinal, typename Packet>
00363 void send(
00364   const Comm<Ordinal>& comm,
00365   const Packet &send, const int destRank
00366   );
00367 
00374 template<typename Ordinal, typename Packet>
00375 void send(
00376   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00377   const Ordinal count, const Packet*const sendBuffer[], const int destRank
00378   );
00379 
00384 template<typename Ordinal, typename Packet>
00385 int receive(
00386   const Comm<Ordinal>& comm,
00387   const int sourceRank, const Ordinal count, Packet recvBuffer[] 
00388   );
00389 
00394 template<typename Ordinal, typename Packet>
00395 int receive(
00396   const Comm<Ordinal>& comm,
00397   const int sourceRank, Packet *recv 
00398   );
00399 
00404 template<typename Ordinal, typename Packet>
00405 int receive(
00406   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00407   const int sourceRank, const Ordinal count, Packet*const recvBuffer[] 
00408   );
00409 
00415 template<typename Ordinal, typename Packet>
00416 void readySend(
00417   const Comm<Ordinal>& comm,
00418   const ArrayView<const Packet> &sendBuffer,
00419   const int destRank
00420   );
00421 
00426 template<typename Ordinal, typename Packet>
00427 void readySend(
00428   const Comm<Ordinal>& comm,
00429   const Packet &send,
00430   const int destRank
00431   );
00432 
00437 template<typename Ordinal, typename Packet>
00438 RCP<CommRequest> isend(
00439   const Comm<Ordinal>& comm,
00440   const ArrayRCP<const Packet> &sendBuffer,
00441   const int destRank
00442   );
00443 
00444 
00449 template<typename Ordinal, typename Packet>
00450 RCP<CommRequest> isend(
00451   const Comm<Ordinal>& comm,
00452   const RCP<const Packet> &send,
00453   const int destRank
00454   );
00455 
00456 
00457 // 2008/07/29: rabartl: ToDo: Add reference semantics version of isend!
00458 
00459 
00464 template<typename Ordinal, typename Packet>
00465 RCP<CommRequest> ireceive(
00466   const Comm<Ordinal>& comm,
00467   const ArrayRCP<Packet> &recvBuffer,
00468   const int sourceRank
00469   );
00470 
00471 
00476 template<typename Ordinal, typename Packet>
00477 RCP<CommRequest> ireceive(
00478   const Comm<Ordinal>& comm,
00479   const RCP<Packet> &recv,
00480   const int sourceRank
00481   );
00482 
00483 
00484 // 2008/07/29: rabartl: ToDo: Add reference semantics version of ireceive!
00485 
00486 
00494 template<typename Ordinal>
00495 void waitAll(
00496   const Comm<Ordinal>& comm,
00497   const ArrayView<RCP<CommRequest> > &requests
00498   );
00499 
00507 template<typename Ordinal>
00508 void wait(
00509   const Comm<Ordinal>& comm,
00510   const Ptr<RCP<CommRequest> > &request
00511   );
00512 
00513 
00514 //
00515 // Standard reduction subclasses for objects that use value semantics
00516 //
00517 
00518 
00523 template<typename Ordinal, typename Packet>
00524 class SumValueReductionOp : public ValueTypeReductionOp<Ordinal,Packet>
00525 {
00526 public:
00528   void reduce(
00529     const Ordinal count,
00530     const Packet inBuffer[],
00531     Packet inoutBuffer[]
00532     ) const;
00533 };
00534 
00535 
00544 template<typename Ordinal, typename Packet>
00545 class MinValueReductionOp : public ValueTypeReductionOp<Ordinal,Packet>
00546 {
00547 public:
00549   void reduce(
00550     const Ordinal count,
00551     const Packet inBuffer[],
00552     Packet inoutBuffer[]
00553     ) const;
00554 };
00555 
00556 
00565 template<typename Ordinal, typename Packet>
00566 class MaxValueReductionOp : public ValueTypeReductionOp<Ordinal,Packet>
00567 {
00568 public:
00570   void reduce(
00571     const Ordinal count,
00572     const Packet inBuffer[],
00573     Packet inoutBuffer[]
00574     ) const;
00575 };
00576 
00577 
00582 template<typename Ordinal, typename Packet>
00583 class ANDValueReductionOp : public ValueTypeReductionOp<Ordinal,Packet>
00584 {
00585 public:
00587   void reduce(
00588     const Ordinal count,
00589     const Packet inBuffer[],
00590     Packet inoutBuffer[]
00591     ) const;
00592 };
00593 
00594 
00595 // ////////////////////////////////////////////////////////////
00596 // Implementation details (not for geneal users to mess with)
00597 
00598 
00599 //
00600 // ReductionOp Utilities
00601 //
00602 
00603 
00604 namespace MixMaxUtilities {
00605 
00606 
00607 template<bool isComparable, typename Ordinal, typename Packet>
00608 class Min {};
00609 
00610 
00611 template<typename Ordinal, typename Packet>
00612 class Min<true,Ordinal,Packet> {
00613 public:
00614   static void min(
00615     const Ordinal count,
00616     const Packet inBuffer[],
00617     Packet inoutBuffer[]
00618     )
00619     {
00620       for( int i = 0; i < count; ++i )
00621         inoutBuffer[i] = TEUCHOS_MIN(inoutBuffer[i],inBuffer[i]);
00622     }
00623 };
00624 
00625 
00626 template<typename Ordinal, typename Packet>
00627 class Min<false,Ordinal,Packet> {
00628 public:
00629   static void min(
00630     const Ordinal,
00631     const Packet[],
00632     Packet[]
00633     )
00634     {
00635       TEST_FOR_EXCEPTION(
00636         true,std::logic_error,
00637         "Error, the type "<<TypeNameTraits<Packet>::name()
00638         <<" does not support comparison operations!"
00639         );
00640     }
00641 };
00642 
00643 
00644 template<bool isComparable, typename Ordinal, typename Packet>
00645 class Max {};
00646 
00647 
00648 template<typename Ordinal, typename Packet>
00649 class Max<true,Ordinal,Packet> {
00650 public:
00651   static void max(
00652     const Ordinal count,
00653     const Packet inBuffer[],
00654     Packet inoutBuffer[]
00655     )
00656     {
00657       for( int i = 0; i < count; ++i )
00658         inoutBuffer[i] = TEUCHOS_MAX(inoutBuffer[i],inBuffer[i]);
00659     }
00660 };
00661 
00662 
00663 template<typename Ordinal, typename Packet>
00664 class Max<false,Ordinal,Packet> {
00665 public:
00666   static void max(
00667     const Ordinal,
00668     const Packet[],
00669     Packet[]
00670     )
00671     {
00672       TEST_FOR_EXCEPTION(
00673         true,std::logic_error,
00674         "Error, the type "<<TypeNameTraits<Packet>::name()
00675         <<" does not support comparison operations!"
00676         );
00677     }
00678 };
00679 
00680 
00681 template<bool isComparable, typename Ordinal, typename Packet>
00682 class AND {};
00683 
00684 
00685 template<typename Ordinal, typename Packet>
00686 class AND<true,Ordinal,Packet> {
00687 public:
00688   static void andOp(
00689     const Ordinal count,
00690     const Packet inBuffer[],
00691     Packet inoutBuffer[]
00692     )
00693     {
00694       for( int i = 0; i < count; ++i )
00695         inoutBuffer[i] = inoutBuffer[i] && inBuffer[i];
00696     }
00697 };
00698 
00699 
00700 template<typename Ordinal, typename Packet>
00701 class AND<false,Ordinal,Packet> {
00702 public:
00703   static void andOp(
00704     const Ordinal,
00705     const Packet[],
00706     Packet[]
00707     )
00708     {
00709       TEST_FOR_EXCEPTION(
00710         true,std::logic_error,
00711         "Error, the type "<<TypeNameTraits<Packet>::name()
00712         <<" does not support logical AND operations!"
00713         );
00714     }
00715 };
00716 
00717 
00718 } // namespace MixMaxUtilities
00719 
00720 
00721 template<typename Ordinal, typename Packet>
00722 void SumValueReductionOp<Ordinal,Packet>::reduce(
00723   const Ordinal count,
00724   const Packet inBuffer[],
00725   Packet inoutBuffer[]
00726   ) const
00727 {
00728   for( int i = 0; i < count; ++i )
00729     inoutBuffer[i] += inBuffer[i];
00730 }
00731 
00732 
00733 template<typename Ordinal, typename Packet>
00734 void MinValueReductionOp<Ordinal,Packet>::reduce(
00735   const Ordinal count,
00736   const Packet inBuffer[],
00737   Packet inoutBuffer[]
00738   ) const
00739 {
00740   typedef ScalarTraits<Packet> ST;
00741   MixMaxUtilities::Min<ST::isComparable,Ordinal,Packet>::min(
00742     count,inBuffer,inoutBuffer
00743     );
00744 }
00745 
00746 
00747 template<typename Ordinal, typename Packet>
00748 void MaxValueReductionOp<Ordinal,Packet>::reduce(
00749   const Ordinal count,
00750   const Packet inBuffer[],
00751   Packet inoutBuffer[]
00752   ) const
00753 {
00754   typedef ScalarTraits<Packet> ST;
00755   MixMaxUtilities::Max<ST::isComparable,Ordinal,Packet>::max(
00756     count,inBuffer,inoutBuffer
00757     );
00758 }
00759 
00760 
00761 template<typename Ordinal, typename Packet>
00762 void ANDValueReductionOp<Ordinal,Packet>::reduce(
00763   const Ordinal count,
00764   const Packet inBuffer[],
00765   Packet inoutBuffer[]
00766   ) const
00767 {
00768   typedef ScalarTraits<Packet> ST;
00769   MixMaxUtilities::AND<ST::isComparable,Ordinal,Packet>::andOp(
00770     count,inBuffer,inoutBuffer
00771     );
00772 }
00773 
00774 
00775 } // namespace Teuchos
00776 
00777 
00778 // //////////////////////////
00779 // Template implemenations
00780 
00781 
00782 //
00783 // ReductionOp utilities
00784 //
00785 
00786 
00787 namespace Teuchos {
00788 
00789 
00790 // Not for the general user to use! I am returning a raw ReducionOp* pointer
00791 // to avoid the overhead of using RCP. However, given the use case
00792 // this is just fine since I can just use std::auto_ptr to make sure things
00793 // are deleted correctly.
00794 template<typename Ordinal, typename Packet>
00795 ValueTypeReductionOp<Ordinal,Packet>*
00796 createOp( const EReductionType reductType )
00797 {
00798   typedef ScalarTraits<Packet> ST;
00799   switch(reductType) {
00800     case REDUCE_SUM: {
00801       return new SumValueReductionOp<Ordinal,Packet>();
00802       break;
00803     }
00804     case REDUCE_MIN: {
00805       TEST_FOR_EXCEPT(!ST::isComparable);
00806       return new MinValueReductionOp<Ordinal,Packet>();
00807       break;
00808     }
00809     case REDUCE_MAX: {
00810       TEST_FOR_EXCEPT(!ST::isComparable);
00811       return new MaxValueReductionOp<Ordinal,Packet>();
00812       break;
00813     }
00814     case REDUCE_AND: {
00815       return new ANDValueReductionOp<Ordinal, Packet>();
00816       break;
00817     }
00818     default:
00819       TEST_FOR_EXCEPT(true);
00820   }
00821   return 0; // Will never be called!
00822 }
00823 
00824 
00825 } // namespace Teuchos
00826 
00827 
00828 //
00829 // Teuchos::Comm wrapper functions
00830 //
00831 
00832 
00833 template<typename Ordinal>
00834 int Teuchos::rank(const Comm<Ordinal>& comm)
00835 {
00836   return comm.getRank();
00837 }
00838 
00839 
00840 template<typename Ordinal>
00841 int Teuchos::size(const Comm<Ordinal>& comm)
00842 {
00843   return comm.getSize();
00844 }
00845 
00846 
00847 template<typename Ordinal>
00848 void Teuchos::barrier(const Comm<Ordinal>& comm)
00849 {
00850   TEUCHOS_COMM_TIME_MONITOR(
00851     "Teuchos::CommHelpers: barrier<"
00852     <<OrdinalTraits<Ordinal>::name()
00853     <<">()"
00854     );
00855   comm.barrier();
00856 }
00857 
00858 
00859 template<typename Ordinal, typename Packet>
00860 void Teuchos::broadcast(
00861   const Comm<Ordinal>& comm,
00862   const int rootRank, const Ordinal count, Packet buffer[]
00863   )
00864 {
00865   TEUCHOS_COMM_TIME_MONITOR(
00866     "Teuchos::CommHelpers: broadcast<"
00867     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
00868     <<">( value type )"
00869     );
00870   ValueTypeSerializationBuffer<Ordinal,Packet>
00871     charBuffer(count,buffer);
00872   comm.broadcast(
00873     rootRank,charBuffer.getBytes(),charBuffer.getCharBuffer()
00874     );
00875 }
00876 
00877 
00878 template<typename Ordinal, typename Packet>
00879 void Teuchos::broadcast(
00880   const Comm<Ordinal>& comm,
00881   const int rootRank,
00882   const ArrayView<Packet> &buffer
00883   )
00884 {
00885   broadcast<Ordinal, Packet>(comm, rootRank, buffer.size(), buffer.getRawPtr() );
00886 }
00887 
00888 
00889 template<typename Ordinal, typename Packet>
00890 void Teuchos::broadcast(
00891   const Comm<Ordinal>& comm,
00892   const int rootRank, Packet *object
00893   )
00894 {
00895   broadcast<Ordinal,Packet>(comm,rootRank,1,object);
00896 }
00897 
00898 
00899 template<typename Ordinal, typename Packet>
00900 void Teuchos::broadcast(
00901   const Comm<Ordinal>& comm,
00902   const int rootRank, const Ptr<Packet> &object
00903   )
00904 {
00905   broadcast<Ordinal,Packet>(comm,rootRank,1,object.getRawPtr());
00906 }
00907 
00908 
00909 template<typename Ordinal, typename Packet>
00910 void Teuchos::broadcast(
00911   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00912   const int rootRank, const Ordinal count, Packet*const buffer[]
00913   )
00914 {
00915   TEUCHOS_COMM_TIME_MONITOR(
00916     "Teuchos::CommHelpers: broadcast<"
00917     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
00918     <<">( reference type )"
00919     );
00920   ReferenceTypeSerializationBuffer<Ordinal,Packet>
00921     charBuffer(serializer, count, buffer);
00922   comm.broadcast(
00923     rootRank,charBuffer.getBytes(),charBuffer.getCharBuffer()
00924     );
00925 }
00926 
00927 
00928 template<typename Ordinal, typename Packet>
00929 void Teuchos::broadcast(
00930   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00931   const int rootRank, const ArrayView<const Ptr<Packet> > &buffer
00932   )
00933 {
00934   Array<Packet*> bufferPtrArray;
00935   for (int i = 0; i < buffer.size(); ++i) {
00936     bufferPtrArray.push_back(buffer[i].getRawPtr());
00937   }
00938   broadcast<Ordinal,Packet>(comm, serializer, rootRank,
00939     buffer.size(), bufferPtrArray.getRawPtr());
00940 }
00941 
00942 
00943 template<typename Ordinal, typename Packet>
00944 void Teuchos::gatherAll(
00945   const Comm<Ordinal>& comm,
00946   const Ordinal sendCount, const Packet sendBuffer[],
00947   const Ordinal recvCount, Packet recvBuffer[]
00948   )
00949 {
00950   TEUCHOS_COMM_TIME_MONITOR(
00951     "Teuchos::CommHelpers: gatherAll<"
00952     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
00953     <<">( value type )"
00954     );
00955   ConstValueTypeSerializationBuffer<Ordinal,Packet>
00956     charSendBuffer(sendCount,sendBuffer);
00957   ValueTypeSerializationBuffer<Ordinal,Packet>
00958     charRecvBuffer(recvCount,recvBuffer);
00959   comm.gatherAll(
00960     charSendBuffer.getBytes(),charSendBuffer.getCharBuffer()
00961     ,charRecvBuffer.getBytes(),charRecvBuffer.getCharBuffer()
00962     );
00963 }
00964 
00965 
00966 template<typename Ordinal, typename Packet>
00967 void Teuchos::gatherAll(
00968   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
00969   const Ordinal sendCount, const Packet*const sendBuffer[],
00970   const Ordinal recvCount, Packet*const recvBuffer[]
00971   )
00972 {
00973   TEST_FOR_EXCEPT(true); // ToDo: Implement and test when needed!
00974 }
00975 
00976 
00977 template<typename Ordinal, typename Packet>
00978 void Teuchos::reduceAll(
00979   const Comm<Ordinal>& comm, const ValueTypeReductionOp<Ordinal,Packet> &reductOp
00980   ,const Ordinal count, const Packet sendBuffer[], Packet globalReducts[]
00981   )
00982 {
00983   TEUCHOS_COMM_TIME_MONITOR(
00984     "Teuchos::CommHelpers: reduceAll<"
00985     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
00986     <<">( value type, user-defined op )"
00987     );
00988   ConstValueTypeSerializationBuffer<Ordinal,Packet>
00989     charSendBuffer(count,sendBuffer);
00990   ValueTypeSerializationBuffer<Ordinal,Packet>
00991     charGlobalReducts(count,globalReducts);
00992   CharToValueTypeReductionOp<Ordinal,Packet>
00993     charReductOp(rcp(&reductOp,false));
00994   comm.reduceAll(
00995     charReductOp,charSendBuffer.getBytes(),charSendBuffer.getCharBuffer()
00996     ,charGlobalReducts.getCharBuffer()
00997     );
00998 }
00999 
01000 
01001 template<typename Ordinal, typename Packet>
01002 void Teuchos::reduceAll(
01003   const Comm<Ordinal>& comm, const EReductionType reductType,
01004   const Ordinal count, const Packet sendBuffer[], Packet globalReducts[]
01005   )
01006 {
01007   TEUCHOS_COMM_TIME_MONITOR(
01008     "Teuchos::CommHelpers: reduceAll<"
01009     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01010     <<">( value type, "<<toString(reductType)<<" )"
01011     );
01012   std::auto_ptr<ValueTypeReductionOp<Ordinal,Packet> >
01013     reductOp(createOp<Ordinal,Packet>(reductType));
01014   reduceAll(comm,*reductOp,count,sendBuffer,globalReducts);
01015 }
01016 
01017 
01018 template<typename Ordinal, typename Packet>
01019 void Teuchos::reduceAll(
01020   const Comm<Ordinal>& comm, const EReductionType reductType
01021   ,const Packet &send, const Ptr<Packet> &globalReduct
01022   )
01023 {
01024   reduceAll<Ordinal,Packet>(comm, reductType, 1, &send, &*globalReduct);
01025 }
01026 
01027 
01028 template<typename Ordinal, typename Packet>
01029 void Teuchos::reduceAll(
01030   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
01031   const ReferenceTypeReductionOp<Ordinal,Packet> &reductOp,
01032   const Ordinal count, const Packet*const sendBuffer[], Packet*const globalReducts[]
01033   )
01034 {
01035   TEUCHOS_COMM_TIME_MONITOR(
01036     "Teuchos::CommHelpers: reduceAll<"
01037     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01038     <<">( reference type )"
01039     );
01040   ConstReferenceTypeSerializationBuffer<Ordinal,Packet>
01041     charSendBuffer(serializer,count,sendBuffer);
01042   ReferenceTypeSerializationBuffer<Ordinal,Packet>
01043     charGlobalReducts(serializer,count,globalReducts);
01044   CharToReferenceTypeReductionOp<Ordinal,Packet>
01045     charReductOp(rcp(&serializer,false),rcp(&reductOp,false));
01046   comm.reduceAll(
01047     charReductOp,charSendBuffer.getBytes(),charSendBuffer.getCharBuffer()
01048     ,charGlobalReducts.getCharBuffer()
01049     );
01050 }
01051 
01052 
01053 template<typename Ordinal, typename Packet>
01054 void Teuchos::reduceAllAndScatter(
01055   const Comm<Ordinal>& comm, const ValueTypeReductionOp<Ordinal,Packet> &reductOp,
01056   const Ordinal sendCount, const Packet sendBuffer[] ,
01057   const Ordinal recvCounts[], Packet myGlobalReducts[]
01058   )
01059 {
01060 
01061   TEUCHOS_COMM_TIME_MONITOR(
01062     "Teuchos::CommHelpers: reduceAllAndScatter<"
01063     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01064     <<">( value type, user-defined op )"
01065     );
01066 
01067   const Ordinal size = Teuchos::size(comm);
01068   const Ordinal rank = Teuchos::rank(comm);
01069 
01070 #ifdef TEUCHOS_DEBUG
01071   Ordinal sumRecvCounts = 0;
01072   for( Ordinal i = 0; i < size; ++i )
01073     sumRecvCounts += recvCounts[static_cast<ptrdiff_t>(i)];
01074   TEST_FOR_EXCEPT(!(sumRecvCounts==sendCount));
01075 #endif
01076 
01077   ConstValueTypeSerializationBuffer<Ordinal,Packet>
01078     charSendBuffer(sendCount,sendBuffer);
01079   ValueTypeSerializationBuffer<Ordinal,Packet>
01080     charMyGlobalReducts(recvCounts[static_cast<ptrdiff_t>(rank)], myGlobalReducts);
01081   CharToValueTypeReductionOp<Ordinal,Packet>
01082     charReductOp(rcp(&reductOp,false));
01083 
01084   const Ordinal
01085     packetSize = charSendBuffer.getBytes()/sendCount;
01086 
01087   WorkspaceStore* wss = get_default_workspace_store().get();
01088   Workspace<Ordinal> charRecvCounts(wss, size);
01089   for (Ordinal k = 0; k < size; ++k) {
01090     charRecvCounts[k] = as<Ordinal>(recvCounts[static_cast<ptrdiff_t>(k)] * packetSize);
01091   }
01092  
01093   comm.reduceAllAndScatter(
01094     charReductOp, charSendBuffer.getBytes(), charSendBuffer.getCharBuffer(),
01095     &charRecvCounts[0], charMyGlobalReducts.getCharBuffer()
01096     );
01097 
01098 }
01099 
01100 
01101 template<typename Ordinal, typename Packet>
01102 void Teuchos::reduceAllAndScatter(
01103   const Comm<Ordinal>& comm, const EReductionType reductType,
01104   const Ordinal sendCount, const Packet sendBuffer[] ,
01105   const Ordinal recvCounts[], Packet myGlobalReducts[]
01106   )
01107 {
01108   TEUCHOS_COMM_TIME_MONITOR(
01109     "Teuchos::CommHelpers: reduceAllAndScatter<"
01110     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01111     <<">( value type, "<<toString(reductType)<<" )"
01112     );
01113   std::auto_ptr<ValueTypeReductionOp<Ordinal,Packet> >
01114     reductOp(createOp<Ordinal,Packet>(reductType));
01115   reduceAllAndScatter(
01116     comm, *reductOp, sendCount, sendBuffer, recvCounts, myGlobalReducts
01117     );
01118 }
01119 
01120 
01121 template<typename Ordinal, typename Packet>
01122 void Teuchos::reduceAllAndScatter(
01123   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
01124   const ReferenceTypeReductionOp<Ordinal,Packet> &reductOp,
01125   const Ordinal sendCount, const Packet*const sendBuffer[],
01126   const Ordinal recvCounts[], Packet*const myGlobalReducts[]
01127   )
01128 {
01129   TEST_FOR_EXCEPT(true); // ToDo: Implement and test when needed!
01130 }
01131 
01132 
01133 template<typename Ordinal, typename Packet>
01134 void Teuchos::scan(
01135   const Comm<Ordinal>& comm, const ValueTypeReductionOp<Ordinal,Packet> &reductOp,
01136   const Ordinal count, const Packet sendBuffer[], Packet scanReducts[]
01137   )
01138 {
01139   TEUCHOS_COMM_TIME_MONITOR(
01140     "Teuchos::CommHelpers: scan<"
01141     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01142     <<">( value type, user-defined op )"
01143     );
01144   ConstValueTypeSerializationBuffer<Ordinal,Packet>
01145     charSendBuffer(count,sendBuffer);
01146   ValueTypeSerializationBuffer<Ordinal,Packet>
01147     charScanReducts(count,scanReducts);
01148   CharToValueTypeReductionOp<Ordinal,Packet>
01149     charReductOp(rcp(&reductOp,false));
01150   comm.scan(
01151     charReductOp,charSendBuffer.getBytes(),charSendBuffer.getCharBuffer()
01152     ,charScanReducts.getCharBuffer()
01153     );
01154 }
01155 
01156 
01157 template<typename Ordinal, typename Packet>
01158 void Teuchos::scan(
01159   const Comm<Ordinal>& comm, const EReductionType reductType,
01160   const Ordinal count, const Packet sendBuffer[], Packet scanReducts[]
01161   )
01162 {
01163   TEUCHOS_COMM_TIME_MONITOR(
01164     "Teuchos::CommHelpers: scan<"
01165     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01166     <<">( value type, "<<toString(reductType)<<" )"
01167     );
01168   std::auto_ptr<ValueTypeReductionOp<Ordinal,Packet> >
01169     reductOp(createOp<Ordinal,Packet>(reductType));
01170   scan(comm,*reductOp,count,sendBuffer,scanReducts);
01171 }
01172 
01173 
01174 template<typename Ordinal, typename Packet>
01175 void Teuchos::scan(
01176   const Comm<Ordinal>& comm, const EReductionType reductType,
01177   const Packet &send, const Ptr<Packet> &scanReduct
01178   )
01179 {
01180   scan<Ordinal,Packet>(comm, reductType, 1, &send, &*scanReduct);
01181 }
01182 
01183 
01184 template<typename Ordinal, typename Packet>
01185 void Teuchos::scan(
01186   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
01187   const ReferenceTypeReductionOp<Ordinal,Packet> &reductOp,
01188   const Ordinal count, const Packet*const sendBuffer[], Packet*const scanReducts[]
01189   )
01190 {
01191   TEST_FOR_EXCEPT(true); // ToDo: Implement and test when needed!
01192 }
01193 
01194 
01195 template<typename Ordinal, typename Packet>
01196 void Teuchos::send(
01197   const Comm<Ordinal>& comm,
01198   const Ordinal count, const Packet sendBuffer[], const int destRank
01199   )
01200 {
01201   TEUCHOS_COMM_TIME_MONITOR(
01202     "Teuchos::CommHelpers: send<"
01203     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01204     <<">( value type )"
01205     );
01206   ConstValueTypeSerializationBuffer<Ordinal,Packet>
01207     charSendBuffer(count,sendBuffer);
01208   comm.send(
01209     charSendBuffer.getBytes(),charSendBuffer.getCharBuffer()
01210     ,destRank
01211     );
01212 }
01213 
01214 
01215 template<typename Ordinal, typename Packet>
01216 void Teuchos::send(
01217   const Comm<Ordinal>& comm,
01218   const Packet &send, const int destRank
01219   )
01220 {
01221   Teuchos::send<Ordinal,Packet>(comm,1,&send,destRank);
01222 }
01223 
01224 
01225 template<typename Ordinal, typename Packet>
01226 void Teuchos::send(
01227   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
01228   const Ordinal count, const Packet*const sendBuffer[], const int destRank
01229   )
01230 {
01231   TEST_FOR_EXCEPT(true); // ToDo: Implement and test when needed!
01232 }
01233 
01234 template<typename Ordinal, typename Packet>
01235 int Teuchos::receive(
01236   const Comm<Ordinal>& comm,
01237   const int sourceRank, const Ordinal count, Packet recvBuffer[] 
01238   )
01239 {
01240   TEUCHOS_COMM_TIME_MONITOR(
01241     "Teuchos::CommHelpers: receive<"
01242     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01243     <<">( value type )"
01244     );
01245   ValueTypeSerializationBuffer<Ordinal,Packet>
01246     charRecvBuffer(count,recvBuffer);
01247   return comm.receive(
01248     sourceRank
01249     ,charRecvBuffer.getBytes(),charRecvBuffer.getCharBuffer()
01250     );
01251 }
01252 
01253 
01254 template<typename Ordinal, typename Packet>
01255 int Teuchos::receive(
01256   const Comm<Ordinal>& comm,
01257   const int sourceRank, Packet *recv 
01258   )
01259 {
01260   return Teuchos::receive<Ordinal,Packet>(comm,sourceRank,1,recv);
01261 }
01262 
01263 
01264 template<typename Ordinal, typename Packet>
01265 int Teuchos::receive(
01266   const Comm<Ordinal>& comm, const Serializer<Ordinal,Packet> &serializer,
01267   const int sourceRank, const Ordinal count, Packet*const recvBuffer[] 
01268   )
01269 {
01270   TEST_FOR_EXCEPT(true); // ToDo: Implement and test when needed!
01271 }
01272 
01273 
01274 template<typename Ordinal, typename Packet>
01275 void Teuchos::readySend(
01276   const Comm<Ordinal>& comm,
01277   const ArrayView<const Packet> &sendBuffer,
01278   const int destRank
01279   )
01280 {
01281   TEUCHOS_COMM_TIME_MONITOR(
01282     "Teuchos::CommHelpers: readySend<"
01283     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01284     <<">( value type )"
01285     );
01286   ConstValueTypeSerializationBuffer<Ordinal,Packet>
01287     charSendBuffer(sendBuffer.size(), sendBuffer.getRawPtr());
01288   comm.readySend( charSendBuffer.getCharBufferView(), destRank );
01289 }
01290 
01291 
01292 template<typename Ordinal, typename Packet>
01293 void Teuchos::readySend(
01294   const Comm<Ordinal>& comm,
01295   const Packet &send,
01296   const int destRank
01297   )
01298 {
01299   readySend<Ordinal, Packet>( comm, arrayView(&send,1), destRank );
01300 }
01301 
01302 
01303 template<typename Ordinal, typename Packet>
01304 Teuchos::RCP<Teuchos::CommRequest>
01305 Teuchos::isend(
01306   const Comm<Ordinal>& comm,
01307   const ArrayRCP<const Packet> &sendBuffer,
01308   const int destRank
01309   )
01310 {
01311   TEUCHOS_COMM_TIME_MONITOR(
01312     "Teuchos::CommHelpers: isend<"
01313     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01314     <<">( value type )"
01315     );
01316   ConstValueTypeSerializationBuffer<Ordinal,Packet>
01317     charSendBuffer(sendBuffer.size(), sendBuffer.getRawPtr());
01318   RCP<CommRequest> commRequest = comm.isend(
01319     charSendBuffer.getCharBufferView(), destRank );
01320   set_extra_data( sendBuffer, "buffer", inOutArg(commRequest) );
01321   return commRequest;
01322 }
01323 
01324 
01325 template<typename Ordinal, typename Packet>
01326 Teuchos::RCP<Teuchos::CommRequest>
01327 Teuchos::isend(
01328   const Comm<Ordinal>& comm,
01329   const RCP<const Packet> &send,
01330   const int destRank
01331   )
01332 {
01333   const ArrayRCP<const Packet> sendBuffer =
01334     arcpWithEmbeddedObj( send.get(), 0, 1, send, false );
01335   // 2008/07/29: rabartl: Above: I need to write a helper function to create
01336   // new ArrayRCP object given a single object to copy.
01337   return isend<Ordinal, Packet>( comm, sendBuffer, destRank );
01338 }
01339 
01340 
01341 template<typename Ordinal, typename Packet>
01342 Teuchos::RCP<Teuchos::CommRequest>
01343 Teuchos::ireceive(
01344   const Comm<Ordinal>& comm,
01345   const ArrayRCP<Packet> &recvBuffer,
01346   const int sourceRank
01347   )
01348 {
01349   typedef std::pair<RCP<CommRequest>, ArrayRCP<const Packet> > comm_buffer_pair_t;
01350   TEUCHOS_COMM_TIME_MONITOR(
01351     "Teuchos::CommHelpers: ireceive<"
01352     <<OrdinalTraits<Ordinal>::name()<<","<<TypeNameTraits<Packet>::name()
01353     <<">( value type )"
01354     );
01355   ValueTypeSerializationBuffer<Ordinal,Packet>
01356     charRecvBuffer(recvBuffer.size(), recvBuffer.getRawPtr());
01357   RCP<CommRequest> commRequest = comm.ireceive(
01358     charRecvBuffer.getCharBufferView(), sourceRank );
01359   set_extra_data( recvBuffer, "buffer", inOutArg(commRequest) );
01360   return commRequest;
01361 }
01362 
01363 
01364 template<typename Ordinal, typename Packet>
01365 Teuchos::RCP<Teuchos::CommRequest>
01366 Teuchos::ireceive(
01367   const Comm<Ordinal>& comm,
01368   const RCP<Packet> &recv,
01369   const int sourceRank
01370   )
01371 {
01372   const ArrayRCP<Packet> recvBuffer =
01373     arcpWithEmbeddedObj( recv.get(), 0, 1, recv, false );
01374   // 2008/07/29: rabartl: Above: I need to write a helper function to create
01375   // new ArrayRCP object given a single object to copy.
01376   return ireceive<Ordinal, Packet>( comm, recvBuffer, sourceRank );
01377 }
01378 
01379 
01380 template<typename Ordinal>
01381 void Teuchos::waitAll(
01382   const Comm<Ordinal>& comm,
01383   const ArrayView<RCP<CommRequest> > &requests
01384   )
01385 {
01386   comm.waitAll(requests);
01387 }
01388 
01389 
01390 template<typename Ordinal>
01391 void Teuchos::wait(
01392   const Comm<Ordinal>& comm,
01393   const Ptr<RCP<CommRequest> > &request
01394   )
01395 {
01396   comm.wait(request);
01397   // NOTE: This will release the ArrayRCP to the buffer of data!
01398 }
01399 
01400 
01401 #endif // TEUCHOS_COMM_HELPERS_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines