DefaultMpiComm_UnitTests.cpp

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

Generated on Tue Oct 20 10:13:59 2009 for Teuchos Package Browser (Single Doxygen Collection) by  doxygen 1.6.1