|
Teuchos Package Browser (Single Doxygen Collection) Version of the Day
|
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
1.7.4