Teuchos Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
DefaultMpiComm_UnitTests.cpp
Go to the documentation of this file.
1/*
2// @HEADER
3// ***********************************************************************
4//
5// Teuchos: Common Tools Package
6// Copyright (2004) Sandia Corporation
7//
8// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
9// license for use of this work by or on behalf of the U.S. Government.
10//
11// Redistribution and use in source and binary forms, with or without
12// modification, are permitted provided that the following conditions are
13// met:
14//
15// 1. Redistributions of source code must retain the above copyright
16// notice, this list of conditions and the following disclaimer.
17//
18// 2. Redistributions in binary form must reproduce the above copyright
19// notice, this list of conditions and the following disclaimer in the
20// documentation and/or other materials provided with the distribution.
21//
22// 3. Neither the name of the Corporation nor the names of the
23// contributors may be used to endorse or promote products derived from
24// this software without specific prior written permission.
25//
26// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37//
38// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
39//
40// ***********************************************************************
41// @HEADER
42*/
43
45
46
51#include "Teuchos_getConst.hpp"
52#include "Teuchos_as.hpp"
53
54#ifdef HAVE_TEUCHOS_MPI
56#endif
57
58#ifdef HAVE_TEUCHOS_QD
59# include <qd/dd_real.h>
60#endif
61
62namespace std {
63
64
65template <typename Packet>
66ostream & operator<< ( ostream& os, const pair<Packet, Packet>& arg)
67{
68 os << "(" << arg.first << "," << arg.second << ")";
69 return os;
70}
71
72
73} // namespace std
74
75
76namespace Teuchos {
77
78
79template<typename Packet>
80struct ScalarTraits<std::pair<Packet,Packet> >
81{
83 typedef std::pair<typename PST::magnitudeType, typename PST::magnitudeType> magnitudeType;
84 static const bool isComplex = PST::isComplex;
85 static const bool isComparable = PST::isComparable;
86 static const bool hasMachineParameters = PST::hasMachineParameters;
87 // Not defined: eps(), sfmin(), base(), prec(), t(), rnd(), emin(), rmin(), emax(), rmax()
88 static inline magnitudeType magnitude(std::pair<Packet,Packet> a) { return std::pair<Packet,Packet>( PST::magnitude(a.first), PST::magnitude(a.second) ); }
89 static inline std::pair<Packet,Packet> zero() { return std::pair<Packet,Packet>(PST::zero(),PST::zero()); }
90 static inline std::pair<Packet,Packet> one() { return std::pair<Packet,Packet>(PST::one(), PST::one()); }
91 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) ); }
92 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) ); }
93 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) ); }
94 static inline bool isnaninf(std::pair<Packet,Packet> x) { return PST::isnaninf(x.first) || PST::isnaninf(x.second); }
95 static inline void seedrandom(unsigned int s) { PST::seedrandom(s); }
96 static inline std::pair<Packet,Packet> random() { return std::pair<Packet,Packet>( PST::random(), PST::random() ); }
97 static inline std::string name() { return "std::pair<" + Teuchos::TypeNameTraits<Packet>::name() + "," + Teuchos::TypeNameTraits<Packet>::name() + ">"; }
98 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)); }
99 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) ); }
100};
101
102template<class Packet, class ConvertToPacket>
103class ValueTypeConversionTraits<std::pair<Packet,Packet>, ConvertToPacket> {
104public:
105 static std::pair<Packet,Packet> convert( const ConvertToPacket t )
106 {
107 return std::pair<Packet,Packet>(t,t);
108 }
109 static std::pair<Packet,Packet> safeConvert( const ConvertToPacket t )
110 {
111 return std::pair<Packet,Packet>(t,t);
112 }
113};
114
115
116} // namespace Teuchos
117
118
119namespace {
120
121
122using Teuchos::as;
123using Teuchos::RCP;
124using Teuchos::rcp;
125using Teuchos::Array;
126using Teuchos::Comm;
130using Teuchos::outArg;
131
132
133bool testMpi = true;
134
135
136double errorTolSlack = 1e+1;
137
138
139
141{
142
144
145 clp.addOutputSetupOptions(true);
146
147 clp.setOption(
148 "test-mpi", "test-serial", &testMpi,
149 "Test MPI (if available) or force test of serial. In a serial build,"
150 " this option is ignored and a serial comm is always used." );
151
152 clp.setOption(
153 "error-tol-slack", &errorTolSlack,
154 "Slack off of machine epsilon used to check test results" );
155
156}
157
158
159template<class Ordinal>
160RCP<const Comm<Ordinal> > getDefaultComm()
161{
162 if (testMpi) {
163 return DefaultComm<Ordinal>::getComm();
164 }
166}
167
168
169TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL( DefaultMpiComm, basic, Ordinal )
170{
171 RCP<const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
172 out << "comm = " << Teuchos::describe(*comm);
173 TEST_EQUALITY( size(*comm), GlobalMPISession::getNProc() );
174}
175
176
177#ifdef HAVE_TEUCHOS_MPI
178
179
180TEUCHOS_UNIT_TEST( DefaultMpiComm, getRawMpiComm )
181{
182 ECHO(MPI_Comm rawMpiComm = MPI_COMM_WORLD);
183 ECHO(const RCP<const Comm<int> > comm =
184 Teuchos::createMpiComm<int>(Teuchos::opaqueWrapper(rawMpiComm)));
185 out << "comm = " << Teuchos::describe(*comm);
186 ECHO(MPI_Comm rawMpiComm2 = Teuchos::getRawMpiComm<int>(*comm));
187 TEST_EQUALITY( rawMpiComm2, rawMpiComm );
188}
189
190
191TEUCHOS_UNIT_TEST( DefaultMpiComm, getRawMpiCommWithTag )
192{
193 ECHO(MPI_Comm rawMpiComm = MPI_COMM_WORLD);
194 ECHO(const RCP<const Comm<int> > comm =
195 Teuchos::createMpiComm<int>(Teuchos::opaqueWrapper(rawMpiComm), 123));
196 out << "comm = " << Teuchos::describe(*comm);
197 ECHO(MPI_Comm rawMpiComm2 = Teuchos::getRawMpiComm<int>(*comm));
198 TEST_EQUALITY( rawMpiComm2, rawMpiComm );
199 TEST_EQUALITY( comm->getTag(), 123);
200}
201
202
203#endif // HAVE_TEUCHOS_MPI
204
205
206TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( DefaultMpiComm, ReadySend1, Ordinal, Packet )
207{
208
209 using Teuchos::broadcast;
210 using Teuchos::readySend;
211 using Teuchos::wait;
212 using Teuchos::as;
213 using Teuchos::rcpFromRef;
214 using Teuchos::outArg;
215 using Teuchos::isend;
216 using Teuchos::ireceive;
217 using Teuchos::wait;
219 using Teuchos::is_null;
220 using Teuchos::arcp;
221 using Teuchos::arcpClone;
222 using Teuchos::rcp_dynamic_cast;
223 using Teuchos::ArrayRCP;
224 using Teuchos::ptr;
226 //typedef typename PT::magnitudeType PacketMag; // unused
227 //typedef Teuchos::ScalarTraits<PacketMag> PMT; // unused
228
229 RCP<const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
230 const Ordinal numProcs = size(*comm);
231 const Ordinal procRank = rank(*comm);
232
233 if (
234 numProcs == 1
235 &&
236 !is_null(rcp_dynamic_cast<const SerialComm<Ordinal> >(comm))
237 )
238 {
239 out << "\nThis is Teuchos::SerialComm which does not support readySend!\n";
240 return; // Pass!
241 }
242
243 PT::seedrandom(as<unsigned int>(procRank));
244 Packet origSendData = PT::random();
245 Packet origRecvData = PT::random();
246 broadcast<Ordinal, Packet>( *comm, 0, outArg(origSendData) );
247
248 Packet sendData = origSendData;
249 Packet recvData = origRecvData;
250
251 RCP<Teuchos::CommRequest<Ordinal> > recvRequest;
252
253 // Post non-block receive on proc 0
254 if (procRank == 0) {
255 // Post non-blocking receive from proc n-1
256 recvRequest = ireceive<Ordinal, Packet>(
257 *comm,
258 rcp(&recvData,false),
259 numProcs-1
260 );
261 }
262 barrier(*comm);
263
264 if (procRank == numProcs-1) {
265 // ready send from proc n-1 to proc 0
266 // send data in sendData
267 readySend<Ordinal, Packet>(
268 *comm,
269 sendData,
270 0
271 );
272 }
273 barrier(*comm);
274
275 if (procRank == 0) {
276 // wait for request on 0
277 wait( *comm, outArg(recvRequest) );
278 }
279 barrier(*comm);
280
281 // test that all procs have recvRequest == Teuchos::null
282 TEST_EQUALITY_CONST( recvRequest, Teuchos::null );
283
284 // proc 0 should have recvData == sendData
285 if (procRank == 0) {
286 TEST_EQUALITY( recvData, sendData );
287 }
288 // other procs should have recvData == origRecvData (i.e., unchanged)
289 else {
290 TEST_EQUALITY( recvData, origRecvData );
291 }
292 // all procs should have sendData == origSendData
293 TEST_EQUALITY( sendData, origSendData );
294
295 // All procs fail if any proc fails
296 int globalSuccess_int = -1;
297 reduceAll( *comm, Teuchos::REDUCE_SUM, success ? 0 : 1, outArg(globalSuccess_int) );
298 TEST_EQUALITY_CONST( globalSuccess_int, 0 );
299}
300
301
302TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( DefaultMpiComm, ReadySend, Ordinal, Packet )
303{
304
305 using Teuchos::broadcast;
306 using Teuchos::readySend;
307 using Teuchos::wait;
308 using Teuchos::as;
309 using Teuchos::rcpFromRef;
310 using Teuchos::outArg;
311 using Teuchos::isend;
312 using Teuchos::ireceive;
313 using Teuchos::wait;
315 using Teuchos::is_null;
316 using Teuchos::arcp;
317 using Teuchos::arcpClone;
318 using Teuchos::rcp_dynamic_cast;
319 using Teuchos::ArrayRCP;
321 //typedef typename PT::magnitudeType PacketMag; // unused
322 //typedef Teuchos::ScalarTraits<PacketMag> PMT; // unused
323
324 RCP<const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
325 const Ordinal numProcs = size(*comm);
326 const Ordinal procRank = rank(*comm);
327
328 if (
329 numProcs == 1
330 &&
331 !is_null(rcp_dynamic_cast<const SerialComm<Ordinal> >(comm))
332 )
333 {
334 out << "\nThis is Teuchos::SerialComm which does not support readySend!\n";
335 return; // Pass!
336 }
337
338 const int dataLen = 3;
339
340 const ArrayRCP<Packet> origSendData = arcp<Packet>(dataLen);
341 const ArrayRCP<Packet> origRecvData = arcp<Packet>(dataLen);
342 PT::seedrandom(as<unsigned int>(procRank));
343 for (int j = 0; j < dataLen; ++j) {
344 origSendData[j] = PT::random();
345 origRecvData[j] = PT::random();
346 }
347 broadcast<Ordinal, Packet>( *comm, 0, origSendData() );
348
349 const ArrayRCP<Packet> sendData = arcpClone<Packet>(origSendData());
350 const ArrayRCP<Packet> recvData = arcpClone<Packet>(origRecvData());
351
352 RCP<Teuchos::CommRequest<Ordinal> > recvRequest;
353
354 // both proc 0 and proc n-1 will post non-block receives, into recvData
355 // then proc 0 will initiate a ready-send to proc n-1; the latter will initiate a wait
356 // a barrier
357 // then proc n-1 will initiate a ready-send to proc 0 of the data from recvData; the latter will initiate a wait
358 // a barrier
359 // now both of these procs should have matching data in sendData and recvData
360
361 // Post non-block receive on both procs
362 if (procRank == 0) {
363 // Post non-blocking receive from proc n-1
364 recvRequest = ireceive<Ordinal, Packet>(
365 *comm,
366 recvData.persistingView(0, dataLen),
367 numProcs-1
368 );
369 }
370 else if (procRank == numProcs-1) {
371 // Post non-blocking receive from proc 0
372 recvRequest = ireceive<Ordinal, Packet>(
373 *comm,
374 recvData.persistingView(0, dataLen),
375 0
376 );
377 }
378 barrier(*comm);
379
380 if (procRank == 0) {
381 // ready send from proc 0 to proc n-1
382 // send data in sendData
383 readySend<Ordinal, Packet>(
384 *comm,
385 sendData(),
386 numProcs-1
387 );
388 }
389 else if (procRank == numProcs-1) {
390 // wait for request on proc n-1
391 wait( *comm, outArg(recvRequest) );
392 }
393 barrier(*comm);
394
395 if (procRank == 0) {
396 // wait for request on 0
397 wait( *comm, outArg(recvRequest) );
398 }
399 else if (procRank == numProcs-1) {
400 // ready send from proc n-1 to proc 0
401 // send data in recvData: THIS IS IMPORTANT: SEE ABOVE
402 readySend<Ordinal, Packet>(
403 *comm,
404 recvData(),
405 0
406 );
407 }
408 barrier(*comm);
409
410 // test that all procs (even non-participating) have recvRequest == Teuchos::null
411 TEST_EQUALITY_CONST( recvRequest, Teuchos::null );
412
413 // participating procs should have recvData == sendData
414 if (procRank == 0 || procRank == numProcs-1) {
415 TEST_COMPARE_ARRAYS( recvData, sendData );
416 }
417 // non-participating procs should have recvData == origRecvData (i.e., unchanged)
418 else {
419 TEST_COMPARE_ARRAYS( recvData, origRecvData );
420 }
421 // all procs should have sendData == origSendData
422 TEST_COMPARE_ARRAYS( sendData, origSendData );
423
424 // All procs fail if any proc fails
425 int globalSuccess_int = -1;
426 reduceAll( *comm, Teuchos::REDUCE_SUM, success ? 0 : 1, outArg(globalSuccess_int) );
427 TEST_EQUALITY_CONST( globalSuccess_int, 0 );
428}
429
430
431TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( DefaultMpiComm, NonblockingSendReceive, Ordinal, Packet )
432{
433 using Teuchos::as;
434 using Teuchos::rcpFromRef;
435 using Teuchos::outArg;
436 using Teuchos::isend;
437 using Teuchos::ireceive;
438 using Teuchos::wait;
440 using Teuchos::rcp_dynamic_cast;
441 using std::endl;
443
444 RCP<const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
445 const Ordinal numProcs = size(*comm);
446 const Ordinal procRank = rank(*comm);
447
448 if (
449 numProcs == 1
450 &&
451 !is_null(rcp_dynamic_cast<const SerialComm<Ordinal> >(comm))
452 )
453 {
454 out << "\nThis is Teuchos::SerialComm which does not yet support isend/ireceive!\n";
455 return; // Pass!
456 }
457
458 // Only use randomize on one proc and then broadcast
459 Packet orig_input_data = PT::random();
460 broadcast( *comm, 0, &orig_input_data );
461
462 const Packet orig_output_data = as<Packet>(-1);
463
464 const Packet input_data = orig_input_data;
465 Packet output_data = orig_output_data;
466
467 RCP<Teuchos::CommRequest<Ordinal> > recvRequest;
468 RCP<Teuchos::CommRequest<Ordinal> > sendRequest;
469
470 out << "Exchanging messages" << endl;
471
472 if (procRank == 0) {
473 // Create copy of data to make sure that persisting relationship is
474 // maintained!
475 sendRequest = isend<Ordinal, Packet>(
476 *comm, Teuchos::rcp(new Packet(input_data)), numProcs-1);
477 }
478 if (procRank == numProcs-1) {
479 // We will need to read output_data after wait(...) below
480 recvRequest = ireceive<Ordinal, Packet>(
481 *comm, rcpFromRef(output_data), 0);
482 }
483
484 out << "Waiting for messages" << endl;
485
486 if (procRank == 0) {
487 wait( *comm, outArg(sendRequest) );
488 }
489 if (procRank == numProcs-1) {
490 wait( *comm, outArg(recvRequest) );
491 }
492
493 TEST_EQUALITY_CONST( sendRequest, Teuchos::null );
494 TEST_EQUALITY_CONST( recvRequest, Teuchos::null );
495
496 out << "Testing message correctness" << endl;
497
498 if (procRank == numProcs-1) {
499 TEST_EQUALITY( output_data, input_data );
500 }
501 else {
502 TEST_EQUALITY( output_data, orig_output_data );
503 }
504 TEST_EQUALITY( input_data, orig_input_data );
505
506 // All procs fail if any proc fails
507 int globalSuccess_int = -1;
508 reduceAll( *comm, Teuchos::REDUCE_SUM, success ? 0 : 1, outArg(globalSuccess_int) );
509 TEST_EQUALITY_CONST( globalSuccess_int, 0 );
510}
511
512
513TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( DefaultMpiComm, NonblockingSendReceive_isReady_true, Ordinal, Packet )
514{
515 using Teuchos::as;
516 using Teuchos::rcpFromRef;
517 using Teuchos::outArg;
518 using Teuchos::isend;
519 using Teuchos::ireceive;
521 using Teuchos::rcp_dynamic_cast;
523
524 RCP<const Comm<Ordinal>> comm = getDefaultComm<Ordinal>();
525 const Ordinal numProcs = size(*comm);
526 const Ordinal procRank = rank(*comm);
527
528 if (numProcs == 1 && !is_null(rcp_dynamic_cast<const SerialComm<Ordinal>>(comm))) {
529 out << "\nThis is Teuchos::SerialComm which does not yet support isend/ireceive!\n";
530 return;
531 }
532
533 // Only use randomize on one proc and then broadcast
534 Packet input_data = PT::random();
535 broadcast(*comm, 0, &input_data);
536 Packet output_data = as<Packet>(-1);
537
538 const Ordinal sendRank = (procRank + 1) % numProcs;
539 const Ordinal recvRank = (procRank + numProcs - 1) % numProcs;
540
541 RCP<Teuchos::CommRequest<Ordinal>> recvRequest = ireceive<Ordinal, Packet>(*comm, rcpFromRef(output_data), recvRank);
542 RCP<Teuchos::CommRequest<Ordinal>> sendRequest = isend<Ordinal, Packet>(*comm, rcpFromRef(input_data), sendRank);
543
544 recvRequest->wait();
545 TEST_ASSERT(recvRequest->isReady());
546
547 // All procs fail if any proc fails
548 int globalSuccess_int = -1;
549 reduceAll(*comm, Teuchos::REDUCE_SUM, success ? 0 : 1, outArg(globalSuccess_int));
550 TEST_EQUALITY_CONST(globalSuccess_int, 0);
551}
552
553
554TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( DefaultMpiComm, NonblockingSendReceive_isReady_false, Ordinal, Packet )
555{
556 using Teuchos::as;
557 using Teuchos::rcpFromRef;
558 using Teuchos::outArg;
559 using Teuchos::ireceive;
561 using Teuchos::rcp_dynamic_cast;
562
563 RCP<const Comm<Ordinal>> comm = getDefaultComm<Ordinal>();
564 const Ordinal numProcs = size(*comm);
565 const Ordinal procRank = rank(*comm);
566
567 if (numProcs == 1 && !is_null(rcp_dynamic_cast<const SerialComm<Ordinal>>(comm))) {
568 out << "\nThis is Teuchos::SerialComm which does not yet support isend/ireceive!\n";
569 return;
570 }
571
572 Packet output_data = as<Packet>(-1);
573
574 RCP<Teuchos::CommRequest<Ordinal>> recvRequest;
575 const Ordinal recvRank = (procRank + numProcs - 1) % numProcs;
576
577 recvRequest = ireceive<Ordinal, Packet>(*comm, rcpFromRef(output_data), recvRank);
578 TEST_ASSERT(!recvRequest->isReady());
579
580 // All procs fail if any proc fails
581 int globalSuccess_int = -1;
582 reduceAll(*comm, Teuchos::REDUCE_SUM, success ? 0 : 1, outArg(globalSuccess_int));
583 TEST_EQUALITY_CONST(globalSuccess_int, 0);
584}
585
586
587template <class Ordinal>
588bool null_request_is_always_ready_if_mpi_available() {
589#ifdef HAVE_TEUCHOS_MPI
590 Teuchos::MpiCommRequestBase<Ordinal> nullRequest;
591 return nullRequest.isReady();
592#else
593 return true;
594#endif
595}
596
597TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( DefaultMpiComm, NonblockingSendReceive_isReady_nullIsTrue, Ordinal, Packet )
598{
599 using Teuchos::outArg;
600
601 RCP<const Comm<Ordinal>> comm = getDefaultComm<Ordinal>();
602 TEST_ASSERT(null_request_is_always_ready_if_mpi_available<Ordinal>());
603
604 // All procs fail if any proc fails
605 int globalSuccess_int = -1;
606 reduceAll(*comm, Teuchos::REDUCE_SUM, success ? 0 : 1, outArg(globalSuccess_int));
607 TEST_EQUALITY_CONST(globalSuccess_int, 0);
608}
609
610
611TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL( DefaultMpiComm, NonblockingSendReceiveSet, Ordinal, Packet )
612{
613 using Teuchos::as;
614 using Teuchos::rcpFromRef;
615 using Teuchos::outArg;
616 using Teuchos::arcp;
617 using Teuchos::arcpClone;
618 using Teuchos::ArrayRCP;
619 using Teuchos::isend;
620 using Teuchos::ireceive;
621 using Teuchos::wait;
622 using Teuchos::broadcast;
624 using Teuchos::rcp_dynamic_cast;
625 using std::cerr;
626 using std::endl;
628 //typedef typename PT::magnitudeType PacketMag; // unused
629 //typedef Teuchos::ScalarTraits<PacketMag> PMT; // unused
630
631 RCP<const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
632 const Ordinal numProcs = size(*comm);
633 const Ordinal procRank = rank(*comm);
634
635 if (
636 numProcs == 1
637 &&
638 !is_null(rcp_dynamic_cast<const SerialComm<Ordinal> >(comm))
639 )
640 {
641 out << "\nThis is Teuchos::SerialComm which does not yet support isend/ireceive!\n";
642 return; // Pass!
643 }
644
645 const int numSendRecv = 4;
646 const int sendLen = 3;
647
648 cerr << "Creating data" << endl;
649
650 const ArrayRCP<Packet> origInputData = arcp<Packet>(numSendRecv*sendLen);
651 const ArrayRCP<Packet> origOutputData = arcp<Packet>(numSendRecv*sendLen);
652 {
653 int offset = 0;
654 for (int i = 0; i < numSendRecv; ++i, offset += sendLen) {
655 const ArrayRCP<Packet> origInputData_i =
656 origInputData.persistingView(offset, sendLen);
657 const ArrayRCP<Packet> origOutputData_i =
658 origOutputData.persistingView(offset, sendLen);
659 for (int j = 0; j < sendLen; ++j) {
660 origInputData_i[j] = PT::random();
661 origOutputData_i[j] = PT::random();
662 }
663 }
664 }
665 cerr << "Broadcasting data" << endl;
666 broadcast<Ordinal, Packet>( *comm, 0, origInputData() );
667
668 const ArrayRCP<Packet> inputData = arcpClone<Packet>(origInputData());
669 const ArrayRCP<Packet> outputData = arcpClone<Packet>(origOutputData());
670
671 Array<RCP<Teuchos::CommRequest<Ordinal> > > recvRequests;
672 Array<RCP<Teuchos::CommRequest<Ordinal> > > sendRequests;
673
674 cerr << "Exchanging data" << endl;
675
676 // Send from proc 0 to proc numProcs-1
677 if (procRank == 0) {
678 // Create copy of data to make sure that persisting relationship is
679 // maintained!
680 int offset = 0;
681 for (int i = 0; i < numSendRecv; ++i, offset += sendLen) {
682 sendRequests.push_back(
683 isend<Ordinal, Packet>(
684 *comm,
685 arcpClone<Packet>(inputData(offset, sendLen)),
686 numProcs-1
687 )
688 );
689 }
690 }
691
692 // Receive from proc 0 on proc numProcs-1
693 if (procRank == numProcs-1) {
694 // We will need to read output_data after wait(...) below
695 int offset = 0;
696 for (int i = 0; i < numSendRecv; ++i, offset += sendLen) {
697 recvRequests.push_back(
698 ireceive<Ordinal, Packet>(
699 *comm, outputData.persistingView(offset, sendLen), 0
700 )
701 );
702 }
703 }
704
705 cerr << "Waiting on messages" << endl;
706
707 if (procRank == 0) {
708 waitAll( *comm, sendRequests() );
709 }
710 if (procRank == numProcs-1) {
711 waitAll( *comm, recvRequests() );
712 }
713
714 cerr << "Testing received data" << endl;
715
716 if (!sendRequests.empty()) {
717 for (int i = 0; i < numSendRecv; ++i) {
718 TEST_EQUALITY_CONST( sendRequests[i], Teuchos::null );
719 }
720 }
721
722 if (!recvRequests.empty()) {
723 for (int i = 0; i < numSendRecv; ++i) {
724 TEST_EQUALITY_CONST( recvRequests[i], Teuchos::null );
725 }
726 }
727 // ToDo: Write a test macro for this in one shot!
728
729 if (procRank == numProcs-1) {
730 TEST_COMPARE_ARRAYS( outputData, inputData );
731 }
732 else {
733 TEST_COMPARE_ARRAYS( outputData, origOutputData );
734 }
735 TEST_COMPARE_ARRAYS( inputData, origInputData );
736
737 // All procs fail if any proc fails
738 int globalSuccess_int = -1;
739 reduceAll( *comm, Teuchos::REDUCE_SUM, success ? 0 : 1, outArg(globalSuccess_int) );
740 TEST_EQUALITY_CONST( globalSuccess_int, 0 );
741
742}
743
744TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL(DefaultMpiComm, duplicate, Ordinal)
745{
746 RCP< const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
747 int initialRank = comm->getRank();
748 int initialSize = comm->getSize();
749
750 RCP< const Comm<Ordinal> > newComm = comm->duplicate();
751 TEST_EQUALITY(newComm->getSize(), initialSize);
752 TEST_EQUALITY(newComm->getRank(), initialRank);
753
754 // TODO Make sure the communication space is distinct.
755}
756
757TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL(DefaultMpiComm, split, Ordinal) {
758 RCP< const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
759 int initialRank = comm->getRank();
760 int initialSize = comm->getSize();
761
762 // Partition this communicator into two: one with the odd ranks and one with
763 // the even ones. Pass a common key for everyone to maintain the same
764 // ordering as in the initial communicator.
765 RCP< const Comm<Ordinal> > newComm = comm->split(initialRank % 2, 0);
766
767 // Check the size of the new communicator and my rank within it.
768 int halfSize = initialSize / 2;
769 int newSize = newComm->getSize();
770 int newRank = newComm->getRank();
771 if (initialSize % 2 == 0) {
772 TEST_EQUALITY(newSize, halfSize);
773 }
774 else {
775 TEST_EQUALITY(newSize, initialRank % 2 == 0 ? halfSize + 1 : halfSize);
776 }
777 TEST_EQUALITY(newRank, initialRank / 2);
778
779 // Negative color values get a null communicator.
780 RCP< const Comm<Ordinal> > shouldBeNull = comm->split(-1, 0);
781 TEST_ASSERT(shouldBeNull.is_null());
782}
783
784
785namespace {
786
787
788template<typename ValueType>
789class MonotoneSequence
790{
791 ValueType currentValue_;
792public:
793 typedef ValueType value_type;
794
795 MonotoneSequence(const value_type& initialValue) : currentValue_(initialValue)
796 {}
797
798 value_type operator()()
799 {
800 return currentValue_++;
801 }
802};
803
804
805} // namepsace
806
807
808TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL(DefaultMpiComm, createSubcommunicator, Ordinal) {
809 RCP< const Comm<Ordinal> > comm = getDefaultComm<Ordinal>();
810 int initialRank = comm->getRank();
811 int initialSize = comm->getSize();
812
813 // Create a new communicator that reverses all of the ranks.
814 std::vector< int > ranks(initialSize);
815 std::generate(ranks.begin(), ranks.end(), MonotoneSequence<int>(0));
816 std::reverse(ranks.begin(), ranks.end());
817 RCP< const Comm<Ordinal> > newComm = comm->createSubcommunicator(ranks);
818 TEST_EQUALITY(newComm->getSize(), initialSize);
819 int expectedNewRank = initialSize - initialRank - 1;
820 TEST_EQUALITY(newComm->getRank(), expectedNewRank);
821
822 // Processes that aren't in the group get a null communicator.
823 std::vector<int> rank0Only(1, 0);
824 RCP< const Comm<Ordinal> > rank0Comm = comm->createSubcommunicator(rank0Only);
825 // Original rank 0 should be valid, all others should be null.
826 if (initialRank == 0) {
827 TEST_ASSERT(rank0Comm.is_valid_ptr());
828 } else {
829 TEST_ASSERT(rank0Comm.is_null());
830 }
831}
832
833
834#ifdef HAVE_TEUCHOS_MPI
835
836
837TEUCHOS_UNIT_TEST(DefaultMpiComm, TagConsistency )
838{
839 using Teuchos::tuple; using Teuchos::inoutArg;
840
841 const Teuchos::RCP<const Teuchos::Comm<int> > defaultComm =
843 const int comm_size = defaultComm->getSize();
844 const int comm_rank = defaultComm->getRank();
845
846 // Must have at least two processes to run this test!
847 if (comm_size < 2) {
848 return;
849 }
850
851 // Create a subcomm that contains just two processes
852 const Teuchos::RCP<const Teuchos::Comm<int> > masterComm =
853 defaultComm->createSubcommunicator(tuple<int>(0, 1)());
854
855 if (comm_rank <= 1) {
856
857 const int masterComm_size = masterComm->getSize();
858 (void) masterComm_size; // Forestall "unused variable" warning.
859 const int masterComm_rank = masterComm->getRank();
860
861 // Split the main communicator into 2 overlapping groups
863 masterComm->createSubcommunicator(tuple<int>(0, 1)());
865 masterComm->createSubcommunicator(tuple<int>(0)());
866
867 // Create another communicator.
869 masterComm->createSubcommunicator(tuple<int>(0, 1)());
870
871 // Get my mpi tag for comm 3.
872 int my_tag = Teuchos::rcp_dynamic_cast<const Teuchos::MpiComm<int> >(
873 comm_3 )->getTag();
874
875 // Collect the tags for comm 3.
876 int tag1 = 0;
877 if (masterComm_rank == 0) { tag1 = my_tag; }
878 masterComm->barrier();
879 Teuchos::broadcast( *masterComm, 0, inoutArg(tag1) );
880
881 int tag2 = 0;
882 if (masterComm_rank == 1) { tag2 = my_tag; }
883 masterComm->barrier();
884 Teuchos::broadcast( *masterComm, 1, inoutArg(tag2) );
885
886 // This currently fails.
887 TEST_EQUALITY( tag1, tag2 );
888
889 }
890
891}
892
893
894#endif // HAVE_TEUCHOS_MPI
895
896
897//
898// Instantiations
899//
900
901
902#ifdef HAVE_TEUCHOS_COMPLEX
903# define UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(TEST_GROUP, TEST_NAME, ORDINAL)\
904 typedef std::complex<float> ComplexFloat; \
905 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT(TEST_GROUP, TEST_NAME, ORDINAL, ComplexFloat)
906# define UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(TEST_GROUP, TEST_NAME, ORDINAL)\
907 typedef std::complex<double> ComplexDouble; \
908 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT(TEST_GROUP, TEST_NAME, ORDINAL, ComplexDouble)
909#else
910# define UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(TEST_GROUP, TEST_NAME, ORDINAL)
911# define UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(TEST_GROUP, TEST_NAME, ORDINAL)
912#endif
913
914
915#define UNIT_TEST_GROUP_ORDINAL_PACKET( ORDINAL, PACKET ) \
916 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, NonblockingSendReceive, ORDINAL, PACKET ) \
917 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, NonblockingSendReceive_isReady_true, ORDINAL, PACKET ) \
918 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, NonblockingSendReceive_isReady_false, ORDINAL, PACKET ) \
919 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, NonblockingSendReceive_isReady_nullIsTrue, ORDINAL, PACKET ) \
920 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, NonblockingSendReceiveSet, ORDINAL, PACKET ) \
921 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, ReadySend1, ORDINAL, PACKET ) \
922 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, ReadySend, ORDINAL, PACKET )
923
924#ifdef HAVE_TEUCHOS_QD
925# define UNIT_TEST_GROUP_ORDINAL_QD(ORDINAL) \
926 UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, dd_real) \
927 UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, qd_real)
928#else
929# define UNIT_TEST_GROUP_ORDINAL_QD(ORDINAL)
930#endif
931
932#define UNIT_TEST_GROUP_ORDINAL_PAIROFPACKETS( ORDINAL, PAIROFPACKETS ) \
933 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, NonblockingSendReceive, ORDINAL, PAIROFPACKETS ) \
934 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, NonblockingSendReceive_isReady_true, ORDINAL, PAIROFPACKETS ) \
935 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, NonblockingSendReceive_isReady_false, ORDINAL, PAIROFPACKETS ) \
936 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, NonblockingSendReceive_isReady_nullIsTrue, ORDINAL, PAIROFPACKETS ) \
937 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, NonblockingSendReceiveSet, ORDINAL, PAIROFPACKETS ) \
938 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, ReadySend1, ORDINAL, PAIROFPACKETS ) \
939 TEUCHOS_UNIT_TEST_TEMPLATE_2_INSTANT( DefaultMpiComm, ReadySend, ORDINAL, PAIROFPACKETS )
940
941#define UNIT_TEST_GROUP_ORDINAL_SUBCOMMUNICATORS( ORDINAL ) \
942 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DefaultMpiComm, duplicate, ORDINAL ) \
943 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DefaultMpiComm, split, ORDINAL ) \
944 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DefaultMpiComm, createSubcommunicator, ORDINAL )
945
946
947typedef std::pair<short, short> PairOfShorts;
948typedef std::pair<int,int> PairOfInts;
949typedef std::pair<float,float> PairOfFloats;
950typedef std::pair<double,double> PairOfDoubles;
951
952
953// Uncomment this for really fast development cycles but make sure to comment
954// it back again before checking in so that we can test all the types.
955// #define FAST_DEVELOPMENT_UNIT_TEST_BUILD
956
957
958#ifdef FAST_DEVELOPMENT_UNIT_TEST_BUILD
959
960# define UNIT_TEST_GROUP_ORDINAL( ORDINAL ) \
961 UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, double) \
962 UNIT_TEST_GROUP_ORDINAL_PAIROFPACKETS(ORDINAL, PairOfDoubles) \
963
965
966#else // FAST_DEVELOPMENT_UNIT_TEST_BUILD
967
968# define UNIT_TEST_GROUP_ORDINAL( ORDINAL ) \
969 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DefaultMpiComm, basic, ORDINAL ) \
970 UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, short) \
971 UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, int) \
972 UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, float) \
973 UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, double) \
974 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, NonblockingSendReceive, ORDINAL) \
975 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, NonblockingSendReceive_isReady_true, ORDINAL) \
976 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, NonblockingSendReceive_isReady_false, ORDINAL) \
977 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, NonblockingSendReceive_isReady_nullIsTrue, ORDINAL) \
978 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, ReadySend1, ORDINAL) \
979 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, ReadySend, ORDINAL) \
980 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, NonblockingSendReceive, ORDINAL) \
981 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, NonblockingSendReceive_isReady_true, ORDINAL) \
982 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, NonblockingSendReceive_isReady_false, ORDINAL) \
983 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, NonblockingSendReceive_isReady_nullIsTrue, ORDINAL) \
984 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, ReadySend1, ORDINAL) \
985 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, ReadySend, ORDINAL) \
986 UNIT_TEST_GROUP_ORDINAL_SUBCOMMUNICATORS(ORDINAL)
987
988# define UNIT_TEST_GROUP_ORDINAL_WITH_PAIRS_AND_QD( ORDINAL ) \
989 TEUCHOS_UNIT_TEST_TEMPLATE_1_INSTANT( DefaultMpiComm, basic, ORDINAL ) \
990 UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, short) \
991 UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, int) \
992 UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, float) \
993 UNIT_TEST_GROUP_ORDINAL_PACKET(ORDINAL, double) \
994 UNIT_TEST_GROUP_ORDINAL_QD(ORDINAL) \
995 UNIT_TEST_GROUP_ORDINAL_PAIROFPACKETS(ORDINAL, PairOfShorts) \
996 UNIT_TEST_GROUP_ORDINAL_PAIROFPACKETS(ORDINAL, PairOfInts) \
997 UNIT_TEST_GROUP_ORDINAL_PAIROFPACKETS(ORDINAL, PairOfFloats) \
998 UNIT_TEST_GROUP_ORDINAL_PAIROFPACKETS(ORDINAL, PairOfDoubles) \
999 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, NonblockingSendReceive, ORDINAL) \
1000 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, NonblockingSendReceive_isReady_true, ORDINAL) \
1001 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, NonblockingSendReceive_isReady_false, ORDINAL) \
1002 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, NonblockingSendReceive_isReady_nullIsTrue, ORDINAL) \
1003 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, ReadySend1, ORDINAL) \
1004 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_FLOAT(DefaultMpiComm, ReadySend, ORDINAL) \
1005 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, NonblockingSendReceive, ORDINAL) \
1006 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, NonblockingSendReceive_isReady_true, ORDINAL) \
1007 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, NonblockingSendReceive_isReady_false, ORDINAL) \
1008 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, NonblockingSendReceive_isReady_nullIsTrue, ORDINAL) \
1009 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, ReadySend1, ORDINAL) \
1010 UNIT_TEST_TEMPLATE_2_INSTANT_COMPLEX_DOUBLE(DefaultMpiComm, ReadySend, ORDINAL)
1011
1012 typedef short int ShortInt;
1013 UNIT_TEST_GROUP_ORDINAL(ShortInt)
1015 typedef long int LongInt;
1016 UNIT_TEST_GROUP_ORDINAL(LongInt) // can't do QD with LongInt, one of the tests complains
1017
1018 typedef long long int LongLongInt;
1019 UNIT_TEST_GROUP_ORDINAL(LongLongInt)
1020
1021#endif // FAST_DEVELOPMENT_UNIT_TEST_BUILD
1022
1023
1024} // namespace
#define UNIT_TEST_GROUP_ORDINAL(ORDINAL)
#define UNIT_TEST_GROUP_ORDINAL_WITH_PAIRS_AND_QD(ORDINAL)
Implementation of Teuchos wrappers for MPI.
#define TEST_ASSERT(v1)
Assert the given statement is true.
#define TEST_EQUALITY_CONST(v1, v2)
Assert the equality of v1 and constant v2.
#define TEST_EQUALITY(v1, v2)
Assert the equality of v1 and v2.
#define TEST_COMPARE_ARRAYS(a1, a2)
Assert that a1.size()==a2.size() and a[i]==b[i], i=0....
#define ECHO(statement)
Echo the given statement before it is executed.
#define TEUCHOS_STATIC_SETUP()
Run setup code statically in a translation unit.
Unit testing support.
#define TEUCHOS_UNIT_TEST_TEMPLATE_1_DECL(TEST_GROUP, TEST_NAME, TYPE)
Macro for defining a templated unit test with one template parameter.
#define TEUCHOS_UNIT_TEST_TEMPLATE_2_DECL(TEST_GROUP, TEST_NAME, TYPE1, TYPE2)
Macro for defining a templated unit test with two template parameters.
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
Definition of Teuchos::as, for conversions between types.
Reference-counted smart pointer for managing arrays.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes.
Abstract interface for distributed-memory communication.
Class that helps parse command line input arguments from (argc,argv[]) and set options.
void addOutputSetupOptions(const bool &addOutputSetupOptions)
Set if options will be automatically added to setup Teuchos::VerboseObjectBase::getDefaultOStream().
void setOption(const char option_true[], const char option_false[], bool *option_val, const char documentation[]=NULL)
Set a boolean option.
Return a default global communicator appropriate for the build.
static Teuchos::RCP< const Comm< OrdinalType > > getComm()
Return the default global communicator.
Initialize, finalize, and query the global MPI session.
Smart reference counting pointer class for automatic garbage collection.
Concrete serial communicator subclass.
static CommandLineProcessor & getCLP()
Return the CLP to add options to.
Default traits class for all conversions between value types.
Definition: Teuchos_as.hpp:179
bool is_null(const boost::shared_ptr< T > &p)
Returns true if p.get()==NULL.
bool is_null(const std::shared_ptr< T > &p)
Returns true if p.get()==NULL.
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
void readySend(const Packet sendBuffer[], const Ordinal count, const int destRank, const int tag, const Comm< Ordinal > &comm)
Variant of readySend() that accepts a message tag.
RCP< Teuchos::CommRequest< int > > isend(const ArrayRCP< const double > &sendBuffer, const int destRank, const int tag, const Comm< int > &comm)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
RCP< CommRequest< Ordinal > > ireceive(const ArrayRCP< Packet > &recvBuffer, const int sourceRank, const int tag, const Comm< Ordinal > &comm)
Variant of ireceive that takes a tag argument (and restores the correct order of arguments).
Scalar defaultSmallNumber()
ostream & operator<<(ostream &os, const pair< Packet, Packet > &arg)
static magnitudeType magnitude(std::pair< Packet, Packet > a)
static std::pair< Packet, Packet > pow(std::pair< Packet, Packet > x, std::pair< Packet, Packet > y)
static std::pair< Packet, Packet > real(std::pair< Packet, Packet > x)
static bool isnaninf(std::pair< Packet, Packet > x)
std::pair< typename PST::magnitudeType, typename PST::magnitudeType > magnitudeType
static std::pair< Packet, Packet > conjugate(std::pair< Packet, Packet > x)
static std::pair< Packet, Packet > squareroot(std::pair< Packet, Packet > x)
static std::pair< Packet, Packet > imag(std::pair< Packet, Packet > x)
This structure defines some basic traits for a scalar field type.
static const bool isComparable
Determines if scalar type supports relational operators such as <, >, <=, >=.
static const bool hasMachineParameters
Determines if scalar type have machine-specific parameters (i.e. eps(), sfmin(), base(),...
static const bool isComplex
Determines if scalar type is std::complex.