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