Teuchos Package Browser (Single Doxygen Collection) Version of the Day
DefaultMpiComm_UnitTests.cpp
Go to the documentation of this file.
00001 /*
00002 // @HEADER
00003 // ***********************************************************************
00004 //
00005 //                    Teuchos: Common Tools Package
00006 //                 Copyright (2004) Sandia Corporation
00007 //
00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00009 // license for use of this work by or on behalf of the U.S. Government.
00010 //
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA
00025 // Questions? Contact Michael A. Heroux (maherou@sandia.gov)
00026 //
00027 // ***********************************************************************
00028 // @HEADER
00029 */
00030 
00031 #include "Teuchos_UnitTestHarness.hpp"
00032 
00033 
00034 #include "Teuchos_DefaultSerialComm.hpp"
00035 #include "Teuchos_CommHelpers.hpp"
00036 #include "Teuchos_DefaultComm.hpp"
00037 #include "Teuchos_DefaultSerialComm.hpp"
00038 #include "Teuchos_getConst.hpp"
00039 #include "Teuchos_as.hpp"
00040 
00041 #ifdef HAVE_TEUCHOS_QD
00042 #include <qd/dd_real.h>
00043 #endif
00044 
00045 namespace std { 
00046 
00047 
00048 template <typename Packet>
00049 ostream & operator<< ( ostream& os, const pair<Packet, Packet>& arg)
00050 {
00051   os << "(" << arg.first << "," << arg.second << ")";
00052   return os;
00053 }
00054 
00055 
00056 } // namespace std
00057 
00058 
00059 namespace Teuchos {
00060 
00061 
00062 template<typename Packet>
00063 struct ScalarTraits<std::pair<Packet,Packet> >
00064 {
00065   typedef ScalarTraits<Packet> PST;
00066       typedef  std::pair<typename PST::magnitudeType, typename PST::magnitudeType> magnitudeType;
00067   static const bool isComplex = PST::isComplex;
00068   static const bool isComparable = PST::isComparable;
00069   static const bool hasMachineParameters = PST::hasMachineParameters;
00070   // Not defined: eps(), sfmin(), base(), prec(), t(), rnd(), emin(), rmin(), emax(), rmax()
00071   static inline magnitudeType magnitude(std::pair<Packet,Packet> a) { return std::pair<Packet,Packet>( PST::magnitude(a.first), PST::magnitude(a.second) ); }
00072   static inline std::pair<Packet,Packet> zero()  { return std::pair<Packet,Packet>(PST::zero(),PST::zero()); }
00073   static inline std::pair<Packet,Packet> one()   { return std::pair<Packet,Packet>(PST::one(), PST::one()); }
00074   static inline std::pair<Packet,Packet> conjugate(std::pair<Packet,Packet> x) { return std::pair<Packet,Packet>(PST::conjugate(x.first), PST::conjugate(x.second) ); }
00075   static inline std::pair<Packet,Packet> real(std::pair<Packet,Packet> x) { return std::pair<Packet,Packet>(PST::real(x.first), PST::real(x.second) ); }
00076   static inline std::pair<Packet,Packet> imag(std::pair<Packet,Packet> x) { return std::pair<Packet,Packet>(PST::imag(x.first), PST::imag(x.second) ); }
00077   static inline bool isnaninf(std::pair<Packet,Packet> x) { return PST::isnaninf(x.first) || PST::isnaninf(x.second); }
00078   static inline void seedrandom(unsigned int s) { PST::seedrandom(s); }
00079   static inline std::pair<Packet,Packet> random() { return std::pair<Packet,Packet>( PST::random(), PST::random() ); }
00080   static inline std::string name() { return "std::pair<" + Teuchos::TypeNameTraits<Packet>::name() + "," + Teuchos::TypeNameTraits<Packet>::name() + ">"; }
00081   static inline std::pair<Packet,Packet> squareroot(std::pair<Packet,Packet> x) { return std::pair<Packet,Packet>(PST::squareroot(x.first), PST::squareroot(x.second)); }
00082   static inline std::pair<Packet,Packet> pow(std::pair<Packet,Packet> x, std::pair<Packet,Packet> y) { return std::pair<Packet,Packet>( PST::pow(x.first,y.first), PST::pow(x.second,y.second) ); }
00083 };
00084 
00085 template<class Packet, class ConvertToPacket>
00086 class ValueTypeConversionTraits<std::pair<Packet,Packet>, ConvertToPacket> {
00087 public:
00088   static std::pair<Packet,Packet> convert( const ConvertToPacket t )
00089     {
00090       return std::pair<Packet,Packet>(t,t);
00091     }
00092   static std::pair<Packet,Packet> safeConvert( const ConvertToPacket t )
00093     {
00094       return std::pair<Packet,Packet>(t,t);
00095     }
00096 };
00097 
00098 
00099 } // namespace Teuchos
00100 
00101 
00102 namespace {
00103 
00104 
00105 using Teuchos::as;
00106 using Teuchos::RCP;
00107 using Teuchos::rcp;
00108 using Teuchos::Array;
00109 using Teuchos::Comm;
00110 using Teuchos::DefaultComm;
00111 using Teuchos::GlobalMPISession;
00112 using Teuchos::defaultSmallNumber;
00113 using Teuchos::outArg;
00114 
00115 
00116 bool testMpi = true;
00117 
00118 
00119 double errorTolSlack = 1e+1;
00120 
00121 
00122 
00123 TEUCHOS_STATIC_SETUP()
00124 {
00125 
00126   Teuchos::CommandLineProcessor &clp = Teuchos::UnitTestRepository::getCLP();
00127 
00128   clp.addOutputSetupOptions(true);
00129 
00130   clp.setOption(
00131     "test-mpi", "test-serial", &testMpi,
00132     "Test MPI (if available) or force test of serial.  In a serial build,"
00133     " this option is ignord and a serial comm is always used." );
00134 
00135   clp.setOption(
00136     "error-tol-slack", &errorTolSlack,
00137     "Slack off of machine epsilon used to check test results" );
00138 
00139 }
00140 
00141 
00142 template<class Ordinal>
00143 RCP<const Comm<Ordinal> > getDefaultComm()
00144 {
00145   if (testMpi) {
00146     return DefaultComm<Ordinal>::getComm();
00147   }
00148   return rcp(new Teuchos::SerialComm<Ordinal>);
00149 }
00150 
00151 
00152 TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DefaultMpiComm, basic, Ordinal )
00153 {
00154   RCP<const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
00155   out << "comm = " << Teuchos::describe(*comm);
00156   TEST_EQUALITY( size(*comm), GlobalMPISession::getNProc() );
00157 }
00158 
00159 
00160 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( DefaultMpiComm, reduceAllAndScatter_1, Ordinal, Packet )
00161 {
00162 
00163   typedef Teuchos::ScalarTraits<Packet> PT;
00164   typedef typename PT::magnitudeType PacketMag;
00165   typedef Teuchos::ScalarTraits<PacketMag> PMT;
00166 
00167   RCP<const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
00168   const Ordinal numProcs = size(*comm);
00169 
00170 #ifdef TEUCHOS_MPI_COMM_DUMP
00171   Teuchos::MpiComm<Ordinal>::show_dump = true;
00172 #endif
00173 
00174   Array<Packet> sendBuffer(as<Ordinal>(numProcs));
00175   for (Ordinal k = 0; k < numProcs; ++k) {
00176     sendBuffer[k] = as<Packet>(1);
00177   }
00178 
00179   Array<Ordinal> recvCounts(as<Ordinal>(numProcs), as<Ordinal>(1));
00180 
00181   Array<Packet> myGlobalReducts(1);
00182 
00183   Teuchos::reduceAllAndScatter<Ordinal,Packet>(
00184     *comm, Teuchos::REDUCE_SUM,
00185     as<Ordinal>(sendBuffer.size()), &sendBuffer[0],
00186     &recvCounts[0], &myGlobalReducts[0]
00187     );
00188 
00189   if (std::numeric_limits<Packet>::is_integer) {
00190     TEST_EQUALITY( myGlobalReducts[0], as<Packet>(numProcs) );
00191   }
00192   else {
00193     const PacketMag local_errorTolSlack = static_cast<PacketMag>(errorTolSlack);
00194     TEST_FLOATING_EQUALITY( myGlobalReducts[0], as<Packet>(numProcs),
00195       as<PacketMag>(defaultSmallNumber<PacketMag>() * local_errorTolSlack / (double)numProcs)
00196       );
00197   }
00198   
00199 }
00200 
00201 
00202 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( DefaultMpiComm, reduceAllAndScatter_2, Ordinal, Packet )
00203 {
00204 
00205   typedef Teuchos::ScalarTraits<Packet> PT;
00206   typedef typename PT::magnitudeType PacketMag;
00207   typedef Teuchos::ScalarTraits<PacketMag> PMT;
00208 
00209   RCP<const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
00210   const Ordinal numProcs = size(*comm);
00211   const Ordinal procRank = rank(*comm);
00212 
00213   Array<Packet> sendBuffer(as<Ordinal>(numProcs));
00214   for (Ordinal k = 0; k < numProcs; ++k) {
00215     sendBuffer[k] = as<Packet>(procRank + k);
00216   }
00217 
00218   Array<Ordinal> recvCounts(as<Ordinal>(numProcs), as<Ordinal>(1));
00219 
00220   Array<Packet> myGlobalReducts(1);
00221 
00222   Teuchos::reduceAllAndScatter<Ordinal,Packet>(
00223     *comm, Teuchos::REDUCE_SUM,
00224     as<Ordinal>(sendBuffer.size()), &sendBuffer[0],
00225     &recvCounts[0], &myGlobalReducts[0]
00226     );
00227 
00228   const Packet expectedMyGlobalReduct = as<Packet>(
00229     numProcs * procRank + ((numProcs - 1) * numProcs)/2 
00230     );
00231 
00232   if (std::numeric_limits<Packet>::is_integer) {
00233     TEST_EQUALITY( myGlobalReducts[0], expectedMyGlobalReduct );
00234   }
00235   else {
00236     const PacketMag local_errorTolSlack = static_cast<PacketMag>(errorTolSlack);
00237     TEST_FLOATING_EQUALITY( myGlobalReducts[0], expectedMyGlobalReduct,
00238       as<PacketMag>(defaultSmallNumber<PacketMag>() * local_errorTolSlack / (double)numProcs)
00239       );
00240   }
00241 
00242 }
00243 
00244 
00245 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( DefaultMpiComm, ReadySend1, Ordinal, Packet )
00246 {
00247 
00248   using Teuchos::broadcast;
00249   using Teuchos::readySend;
00250   using Teuchos::wait;
00251   using Teuchos::as;
00252   using Teuchos::rcpFromRef;
00253   using Teuchos::outArg;
00254   using Teuchos::isend;
00255   using Teuchos::ireceive;
00256   using Teuchos::wait;
00257   using Teuchos::SerialComm;
00258   using Teuchos::is_null;
00259   using Teuchos::arcp;
00260   using Teuchos::arcpClone;
00261   using Teuchos::rcp_dynamic_cast;
00262   using Teuchos::ArrayRCP;
00263   using Teuchos::ptr;
00264   typedef Teuchos::ScalarTraits<Packet> PT;
00265   typedef typename PT::magnitudeType PacketMag;
00266   typedef Teuchos::ScalarTraits<PacketMag> PMT;
00267 
00268   RCP<const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
00269   const Ordinal numProcs = size(*comm);
00270   const Ordinal procRank = rank(*comm);
00271 
00272   if (
00273     numProcs == 1
00274     &&
00275     !is_null(rcp_dynamic_cast<const SerialComm<Ordinal> >(comm))
00276     )
00277   {
00278     out << "\nThis is Teuchos::SerialComm which does not support readySend!\n";
00279     return; // Pass!
00280   }
00281 
00282   PT::seedrandom(as<unsigned int>(procRank));
00283   Packet origSendData = PT::random();
00284   Packet origRecvData = PT::random();
00285   broadcast<Ordinal, Packet>( *comm, 0, outArg(origSendData) );
00286 
00287   Packet sendData = origSendData;
00288   Packet recvData = origRecvData;
00289 
00290   RCP<Teuchos::CommRequest> recvRequest;
00291 
00292   // Post non-block receive on proc 0
00293   if (procRank == 0) {
00294     // Post non-blocking receive from proc n-1
00295     recvRequest = ireceive<Ordinal, Packet>(
00296         *comm,
00297         rcp(&recvData,false),
00298         numProcs-1
00299         );
00300   }
00301   barrier(*comm);
00302 
00303   if (procRank == numProcs-1) {
00304     // ready send from proc n-1 to proc 0
00305     // send data in sendData
00306     readySend<Ordinal, Packet>(
00307         *comm,
00308         sendData,
00309         0
00310         );
00311   }
00312   barrier(*comm);
00313 
00314   if (procRank == 0) {
00315     // wait for request on 0
00316     wait( *comm, outArg(recvRequest) );
00317   }
00318   barrier(*comm);
00319 
00320   // test that all procs have recvRequest == Teuchos::null
00321   TEST_EQUALITY_CONST( recvRequest, Teuchos::null );
00322 
00323   // proc 0 should have recvData == sendData
00324   if (procRank == 0) {
00325     TEST_EQUALITY( recvData, sendData );
00326   }
00327   // other procs should have recvData == origRecvData (i.e., unchanged)
00328   else {
00329     TEST_EQUALITY( recvData, origRecvData );
00330   }
00331   // all procs should have sendData == origSendData
00332   TEST_EQUALITY( sendData, origSendData );
00333 
00334   // All procs fail if any proc fails
00335   int globalSuccess_int = -1;
00336   reduceAll( *comm, Teuchos::REDUCE_SUM, success ? 0 : 1, outArg(globalSuccess_int) );
00337   TEST_EQUALITY_CONST( globalSuccess_int, 0 );
00338 }
00339 
00340 
00341 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( DefaultMpiComm, ReadySend, Ordinal, Packet )
00342 {
00343 
00344   using Teuchos::broadcast;
00345   using Teuchos::readySend;
00346   using Teuchos::wait;
00347   using Teuchos::as;
00348   using Teuchos::rcpFromRef;
00349   using Teuchos::outArg;
00350   using Teuchos::isend;
00351   using Teuchos::ireceive;
00352   using Teuchos::wait;
00353   using Teuchos::SerialComm;
00354   using Teuchos::is_null;
00355   using Teuchos::arcp;
00356   using Teuchos::arcpClone;
00357   using Teuchos::rcp_dynamic_cast;
00358   using Teuchos::ArrayRCP;
00359   typedef Teuchos::ScalarTraits<Packet> PT;
00360   typedef typename PT::magnitudeType PacketMag;
00361   typedef Teuchos::ScalarTraits<PacketMag> PMT;
00362 
00363   RCP<const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
00364   const Ordinal numProcs = size(*comm);
00365   const Ordinal procRank = rank(*comm);
00366 
00367   if (
00368     numProcs == 1
00369     &&
00370     !is_null(rcp_dynamic_cast<const SerialComm<Ordinal> >(comm))
00371     )
00372   {
00373     out << "\nThis is Teuchos::SerialComm which does not support readySend!\n";
00374     return; // Pass!
00375   }
00376 
00377   const int dataLen = 3;
00378 
00379   const ArrayRCP<Packet> origSendData = arcp<Packet>(dataLen);
00380   const ArrayRCP<Packet> origRecvData = arcp<Packet>(dataLen);
00381   PT::seedrandom(as<unsigned int>(procRank));
00382   for (int j = 0; j < dataLen; ++j) {
00383     origSendData[j] = PT::random();
00384     origRecvData[j] = PT::random();
00385   }
00386   broadcast<Ordinal, Packet>( *comm, 0, origSendData() );
00387 
00388   const ArrayRCP<Packet> sendData = arcpClone<Packet>(origSendData());
00389   const ArrayRCP<Packet> recvData = arcpClone<Packet>(origRecvData());
00390 
00391   RCP<Teuchos::CommRequest> recvRequest;
00392 
00393   // both proc 0 and proc n-1 will post non-block receives, into recvData
00394   // then proc 0 will initiate a ready-send to proc n-1; the latter will initiate a wait
00395   // a barrier
00396   // then proc n-1 will initiate a ready-send to proc 0 of the data from recvData; the latter will initiate a wait
00397   // a barrier
00398   // now both of these procs should have matching data in sendData and recvData
00399 
00400   // Post non-block receive on both procs
00401   if (procRank == 0) {
00402     // Post non-blocking receive from proc n-1
00403     recvRequest = ireceive<Ordinal, Packet>(
00404         *comm,
00405         recvData.persistingView(0, dataLen),
00406         numProcs-1
00407         );
00408   }
00409   else if (procRank == numProcs-1) {
00410     // Post non-blocking receive from proc 0
00411     recvRequest = ireceive<Ordinal, Packet>(
00412         *comm,
00413         recvData.persistingView(0, dataLen),
00414         0
00415         );
00416   }
00417   barrier(*comm);
00418 
00419   if (procRank == 0) {
00420     // ready send from proc 0 to proc n-1
00421     // send data in sendData
00422     readySend<Ordinal, Packet>(
00423         *comm,
00424         sendData(),
00425         numProcs-1
00426         );
00427   }
00428   else if (procRank == numProcs-1) {
00429     // wait for request on proc n-1
00430     wait( *comm, outArg(recvRequest) );
00431   }
00432   barrier(*comm);
00433 
00434   if (procRank == 0) {
00435     // wait for request on 0
00436     wait( *comm, outArg(recvRequest) );
00437   }
00438   else if (procRank == numProcs-1) {
00439     // ready send from proc n-1 to proc 0
00440     // send data in recvData: THIS IS IMPORTANT: SEE ABOVE
00441     readySend<Ordinal, Packet>(
00442         *comm,
00443         recvData(),
00444         0
00445         );
00446   }
00447   barrier(*comm);
00448 
00449   // test that all procs (even non-participating) have recvRequest == Teuchos::null
00450   TEST_EQUALITY_CONST( recvRequest, Teuchos::null );
00451 
00452   // participating procs should have recvData == sendData
00453   if (procRank == 0 || procRank == numProcs-1) {
00454     TEST_COMPARE_ARRAYS( recvData, sendData );
00455   }
00456   // non-participating procs should have recvData == origRecvData (i.e., unchanged)
00457   else {
00458     TEST_COMPARE_ARRAYS( recvData, origRecvData );
00459   }
00460   // all procs should have sendData == origSendData
00461   TEST_COMPARE_ARRAYS( sendData, origSendData );
00462 
00463   // All procs fail if any proc fails
00464   int globalSuccess_int = -1;
00465   reduceAll( *comm, Teuchos::REDUCE_SUM, success ? 0 : 1, outArg(globalSuccess_int) );
00466   TEST_EQUALITY_CONST( globalSuccess_int, 0 );
00467 }
00468 
00469 
00470 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( DefaultMpiComm, NonblockingSendReceive, Ordinal, Packet )
00471 {
00472 
00473   using Teuchos::as;
00474   using Teuchos::rcpFromRef;
00475   using Teuchos::outArg;
00476   using Teuchos::isend;
00477   using Teuchos::ireceive;
00478   using Teuchos::wait;
00479   using Teuchos::SerialComm;
00480   using Teuchos::rcp_dynamic_cast;
00481   typedef Teuchos::ScalarTraits<Packet> PT;
00482   typedef typename PT::magnitudeType PacketMag;
00483   typedef Teuchos::ScalarTraits<PacketMag> PMT;
00484 
00485   RCP<const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
00486   const Ordinal numProcs = size(*comm);
00487   const Ordinal procRank = rank(*comm);
00488 
00489   if (
00490     numProcs == 1
00491     &&
00492     !is_null(rcp_dynamic_cast<const SerialComm<Ordinal> >(comm))
00493     )
00494   {
00495     out << "\nThis is Teuchos::SerialComm which does not yet support isend/ireceive!\n";
00496     return; // Pass!
00497   }
00498 
00499   // Only use randomize on one proc and then broacast
00500   Packet orig_input_data = PT::random();
00501   broadcast( *comm, 0, &orig_input_data );
00502 
00503   const Packet orig_output_data = as<Packet>(-1);
00504 
00505   const Packet input_data = orig_input_data;
00506   Packet output_data = orig_output_data;
00507 
00508   RCP<Teuchos::CommRequest> recvRequest;
00509   RCP<Teuchos::CommRequest> sendRequest;
00510 
00511   if (procRank == 0) {
00512     // Create copy of data to make sure that persisting relationship is
00513     // maintained!
00514     sendRequest = isend<Ordinal, Packet>(
00515       *comm, Teuchos::rcp(new Packet(input_data)), numProcs-1);
00516   }
00517   if (procRank == numProcs-1) {
00518     // We will need to read output_data after wait(...) below
00519     recvRequest = ireceive<Ordinal, Packet>(
00520       *comm, rcpFromRef(output_data), 0);
00521   }
00522 
00523   if (procRank == 0) {
00524     wait( *comm, outArg(sendRequest) );
00525   }
00526   if (procRank == numProcs-1) {
00527     wait( *comm, outArg(recvRequest) );
00528   }
00529   
00530   TEST_EQUALITY_CONST( sendRequest, Teuchos::null );
00531   TEST_EQUALITY_CONST( recvRequest, Teuchos::null );
00532 
00533   if (procRank == numProcs-1) {
00534     TEST_EQUALITY( output_data, input_data );
00535   }
00536   else {
00537     TEST_EQUALITY( output_data, orig_output_data );
00538   }
00539   TEST_EQUALITY( input_data, orig_input_data );
00540 
00541   // All procs fail if any proc fails
00542   int globalSuccess_int = -1;
00543   reduceAll( *comm, Teuchos::REDUCE_SUM, success ? 0 : 1, outArg(globalSuccess_int) );
00544   TEST_EQUALITY_CONST( globalSuccess_int, 0 );
00545 
00546 }
00547 
00548 
00549 TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( DefaultMpiComm, NonblockingSendReceiveSet, Ordinal, Packet )
00550 {
00551 
00552   using Teuchos::as;
00553   using Teuchos::rcpFromRef;
00554   using Teuchos::outArg;
00555   using Teuchos::arcp;
00556   using Teuchos::arcpClone;
00557   using Teuchos::ArrayRCP;
00558   using Teuchos::isend;
00559   using Teuchos::ireceive;
00560   using Teuchos::wait;
00561   using Teuchos::broadcast;
00562   using Teuchos::SerialComm;
00563   using Teuchos::rcp_dynamic_cast;
00564   typedef Teuchos::ScalarTraits<Packet> PT;
00565   typedef typename PT::magnitudeType PacketMag;
00566   typedef Teuchos::ScalarTraits<PacketMag> PMT;
00567 
00568   RCP<const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
00569   const Ordinal numProcs = size(*comm);
00570   const Ordinal procRank = rank(*comm);
00571 
00572   if (
00573     numProcs == 1
00574     &&
00575     !is_null(rcp_dynamic_cast<const SerialComm<Ordinal> >(comm))
00576     )
00577   {
00578     out << "\nThis is Teuchos::SerialComm which does not yet support isend/ireceive!\n";
00579     return; // Pass!
00580   }
00581 
00582   const int numSendRecv = 4;
00583   const int sendLen = 3;
00584 
00585   const ArrayRCP<Packet> origInputData = arcp<Packet>(numSendRecv*sendLen);
00586   const ArrayRCP<Packet> origOutputData = arcp<Packet>(numSendRecv*sendLen);
00587   {
00588     int offset = 0;
00589     for (int i = 0; i < numSendRecv; ++i, offset += sendLen) {
00590       const ArrayRCP<Packet> origInputData_i =
00591         origInputData.persistingView(offset, sendLen); 
00592       const ArrayRCP<Packet> origOutputData_i =
00593         origOutputData.persistingView(offset, sendLen); 
00594       for (int j = 0; j < sendLen; ++j) {
00595         origInputData_i[j] = PT::random();
00596         origOutputData_i[j] = PT::random();
00597       }
00598     }
00599   }
00600   broadcast<Ordinal, Packet>( *comm, 0, origInputData() );
00601 
00602   const ArrayRCP<Packet> inputData = arcpClone<Packet>(origInputData());
00603   const ArrayRCP<Packet> outputData = arcpClone<Packet>(origOutputData());
00604 
00605   Array<RCP<Teuchos::CommRequest> > recvRequests;
00606   Array<RCP<Teuchos::CommRequest> > sendRequests;
00607 
00608   // Send from proc 0 to proc numProcs-1
00609   if (procRank == 0) {
00610     // Create copy of data to make sure that persisting relationship is
00611     // maintained!
00612     int offset = 0;
00613     for (int i = 0; i < numSendRecv; ++i, offset += sendLen) {
00614       sendRequests.push_back(
00615         isend<Ordinal, Packet>(
00616           *comm,
00617           arcpClone<Packet>(inputData(offset, sendLen)),
00618           numProcs-1
00619           )
00620         );
00621     }
00622   }
00623 
00624   // Receive from proc 0 on proc numProcs-1
00625   if (procRank == numProcs-1) {
00626     // We will need to read output_data after wait(...) below
00627     int offset = 0;
00628     for (int i = 0; i < numSendRecv; ++i, offset += sendLen) {
00629       recvRequests.push_back(
00630         ireceive<Ordinal, Packet>(
00631           *comm, outputData.persistingView(offset, sendLen), 0
00632           )
00633         );
00634     }
00635   }
00636 
00637   if (procRank == 0) {
00638     waitAll( *comm, sendRequests );
00639   }
00640   if (procRank == numProcs-1) {
00641     waitAll( *comm, recvRequests );
00642   }
00643 
00644   if (!sendRequests.empty()) {
00645     for (int i = 0; i < numSendRecv; ++i) {
00646       TEST_EQUALITY_CONST( sendRequests[i], Teuchos::null );
00647     }
00648   }
00649 
00650   if (!recvRequests.empty()) {
00651     for (int i = 0; i < numSendRecv; ++i) {
00652       TEST_EQUALITY_CONST( recvRequests[i], Teuchos::null );
00653     }
00654   }
00655   // ToDo: Write a test macro for this in one shot!
00656 
00657   if (procRank == numProcs-1) {
00658     TEST_COMPARE_ARRAYS( outputData, inputData );
00659   }
00660   else {
00661     TEST_COMPARE_ARRAYS( outputData, origOutputData );
00662   }
00663   TEST_COMPARE_ARRAYS( inputData, origInputData );
00664 
00665   // All procs fail if any proc fails
00666   int globalSuccess_int = -1;
00667   reduceAll( *comm, Teuchos::REDUCE_SUM, success ? 0 : 1, outArg(globalSuccess_int) );
00668   TEST_EQUALITY_CONST( globalSuccess_int, 0 );
00669 
00670 }
00671 
00672 
00673 //
00674 // Instantiations
00675 //
00676 
00677 
00678 #ifdef HAVE_TEUCHOS_COMPLEX
00679 #  define UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(TEST_GROUP, TEST_NAME, ORDINAL)\
00680      typedef std::complex<float> ComplexFloat; \
00681      TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT(TEST_GROUP, TEST_NAME, ORDINAL, ComplexFloat)
00682 #  define UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(TEST_GROUP, TEST_NAME, ORDINAL)\
00683      typedef std::complex<double> ComplexDouble; \
00684      TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT(TEST_GROUP, TEST_NAME, ORDINAL, ComplexDouble)
00685 #else
00686 #  define UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(TEST_GROUP, TEST_NAME, ORDINAL)
00687 #  define UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(TEST_GROUP, TEST_NAME, ORDINAL)
00688 #endif
00689 
00690 
00691 #define UNIT_TEST_GROUP_ORDINAL_PACKET( ORDINAL, PACKET ) \
00692   TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, reduceAllAndScatter_1, ORDINAL, PACKET ) \
00693   TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, reduceAllAndScatter_2, ORDINAL, PACKET ) \
00694   TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, NonblockingSendReceive, ORDINAL, PACKET ) \
00695   TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, NonblockingSendReceiveSet, ORDINAL, PACKET ) \
00696   TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, ReadySend1, ORDINAL, PACKET ) \
00697   TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, ReadySend, ORDINAL, PACKET )
00698 
00699 #ifdef HAVE_TEUCHOS_QD
00700 #  define UNIT_TEST_GROUP_ORDINAL_QD(ORDINAL) \
00701      UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, dd_real) \
00702      UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, qd_real)
00703 #else
00704 #  define UNIT_TEST_GROUP_ORDINAL_QD(ORDINAL)
00705 #endif
00706 
00707 #define UNIT_TEST_GROUP_ORDINAL_PAIROFPACKETS( ORDINAL, PAIROFPACKETS ) \
00708   TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, NonblockingSendReceive, ORDINAL, PAIROFPACKETS ) \
00709   TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, NonblockingSendReceiveSet, ORDINAL, PAIROFPACKETS ) \
00710   TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, ReadySend1, ORDINAL, PAIROFPACKETS ) \
00711   TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, ReadySend, ORDINAL, PAIROFPACKETS )
00712 
00713 
00714 typedef std::pair<short, short> PairOfShorts;
00715 typedef std::pair<int,int> PairOfInts;
00716 typedef std::pair<float,float> PairOfFloats;
00717 typedef std::pair<double,double> PairOfDoubles;
00718 
00719 
00720 // Uncomment this for really fast development cycles but make sure to comment
00721 // it back again before checking in so that we can test all the types.
00722 // #define FAST_DEVELOPMENT_UNIT_TEST_BUILD
00723 
00724 
00725 #ifdef FAST_DEVELOPMENT_UNIT_TEST_BUILD
00726 
00727 #  define UNIT_TEST_GROUP_ORDINAL( ORDINAL ) \
00728     UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, double) \
00729     UNIT_TEST_GROUP_ORDINAL_PAIROFPACKETS(ORDINAL, PairOfDoubles) \
00730 
00731   UNIT_TEST_GROUP_ORDINAL(int)
00732 
00733 #else // FAST_DEVELOPMENT_UNIT_TEST_BUILD
00734 
00735 #  define UNIT_TEST_GROUP_ORDINAL( ORDINAL ) \
00736     TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DefaultMpiComm, basic, ORDINAL ) \
00737     UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, short) \
00738     UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, int) \
00739     UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, float) \
00740     UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, double) \
00741     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, reduceAllAndScatter_1, ORDINAL) \
00742     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, reduceAllAndScatter_2, ORDINAL) \
00743     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, NonblockingSendReceive, ORDINAL) \
00744     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, ReadySend1, ORDINAL) \
00745     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, ReadySend, ORDINAL) \
00746     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, reduceAllAndScatter_1, ORDINAL) \
00747     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, reduceAllAndScatter_2, ORDINAL) \
00748     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, NonblockingSendReceive, ORDINAL) \
00749     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, ReadySend1, ORDINAL) \
00750     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, ReadySend, ORDINAL)
00751 
00752 #  define UNIT_TEST_GROUP_ORDINAL_WITH_PAIRS_AND_QD( ORDINAL ) \
00753     TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DefaultMpiComm, basic, ORDINAL ) \
00754     UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, short)      \
00755     UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, int) \
00756     UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, float) \
00757     UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, double) \
00758     UNIT_TEST_GROUP_ORDINAL_QD(ORDINAL) \
00759     UNIT_TEST_GROUP_ORDINAL_PAIROFPACKETS(ORDINAL, PairOfShorts) \
00760     UNIT_TEST_GROUP_ORDINAL_PAIROFPACKETS(ORDINAL, PairOfInts) \
00761     UNIT_TEST_GROUP_ORDINAL_PAIROFPACKETS(ORDINAL, PairOfFloats) \
00762     UNIT_TEST_GROUP_ORDINAL_PAIROFPACKETS(ORDINAL, PairOfDoubles) \
00763     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, reduceAllAndScatter_1, ORDINAL) \
00764     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, reduceAllAndScatter_2, ORDINAL) \
00765     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, NonblockingSendReceive, ORDINAL) \
00766     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, ReadySend1, ORDINAL) \
00767     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, ReadySend, ORDINAL) \
00768     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, reduceAllAndScatter_1, ORDINAL) \
00769     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, reduceAllAndScatter_2, ORDINAL) \
00770     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, NonblockingSendReceive, ORDINAL) \
00771     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, ReadySend1, ORDINAL) \
00772     UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, ReadySend, ORDINAL)
00773 
00774   typedef short int ShortInt;
00775   UNIT_TEST_GROUP_ORDINAL(ShortInt)
00776   UNIT_TEST_GROUP_ORDINAL_WITH_PAIRS_AND_QD(int)
00777   typedef long int LongInt;
00778   UNIT_TEST_GROUP_ORDINAL(LongInt) // can't do QD with LongInt, one of the tests complains
00779   
00780 #  ifdef HAVE_TEUCHOS_LONG_LONG_INT
00781   typedef long long int LongLongInt;
00782   UNIT_TEST_GROUP_ORDINAL(LongLongInt)
00783 #  endif
00784 
00785 #endif // FAST_DEVELOPMENT_UNIT_TEST_BUILD
00786 
00787 
00788 } // namespace
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines