53 template <
typename Packet>
54 ostream & operator<< (ostream& os, const pair<Packet, Packet>& arg)
56 os <<
"(" << arg.first <<
"," << arg.second <<
")";
72 using Teuchos::MpiComm;
73 using Teuchos::outArg;
77 using Teuchos::waitAll;
88 typedef ArrayRCP<int>::size_type size_type;
90 RCP<const Comm<int> > comm =
rcp (
new MpiComm<int> (MPI_COMM_WORLD));
91 const int myRank = comm->getRank ();
92 const int numProcs = comm->getSize ();
100 out <<
"numProcs == 1, test passes trivially." << endl;
103 out <<
"Test setup" << endl;
107 int leftNeighbor = (myRank - 1) % numProcs;
108 int rightNeighbor = (myRank + 1) % numProcs;
110 if (leftNeighbor < 0) {
111 leftNeighbor += numProcs;
113 if (rightNeighbor < 0) {
114 rightNeighbor += numProcs;
116 Array<int> expectedSourceRanks (2);
117 expectedSourceRanks[0] = leftNeighbor;
118 expectedSourceRanks[1] = rightNeighbor;
119 std::sort (expectedSourceRanks.begin (), expectedSourceRanks.end ());
122 ArrayRCP<int> recvBuf (2);
123 ArrayRCP<int> leftRecvBuf = recvBuf.persistingView (0, 1);
124 ArrayRCP<int> rightRecvBuf = recvBuf.persistingView (1, 1);
127 Array<int> sendBuf (2);
128 ArrayView<int> leftSendBuf = sendBuf.view (0, 1);
129 ArrayView<int> rightSendBuf = sendBuf.view (1, 1);
134 out <<
"Round 1 of messages" << endl;
140 for (size_type k = 0; k < recvBuf.size (); ++k) {
145 for (size_type k = 0; k < sendBuf.size (); ++k) {
146 sendBuf[k] = myRank + tag1;
150 Array<RCP<CommRequest<int> > > requests (2);
155 send<int, int> (leftSendBuf.getRawPtr (), as<int> (leftSendBuf.size ()),
156 leftNeighbor, tag1, *comm);
157 send<int, int> (rightSendBuf.getRawPtr (), as<int> (rightSendBuf.size ()),
158 rightNeighbor, tag1, *comm);
161 Array<RCP<CommStatus<int> > > statuses (2);
162 waitAll (*comm, requests (), statuses ());
165 Array<int> sourceRanks (2);
166 for (size_type k = 0; k < 2; ++k) {
167 sourceRanks[k] = statuses[k]->getSourceRank ();
169 std::sort (sourceRanks.begin (), sourceRanks.end ());
170 TEST_EQUALITY( sourceRanks.size (), expectedSourceRanks.size () );
171 for (size_type k = 0; k < sourceRanks.size (); ++k) {
176 for (size_type k = 0; k < statuses.size (); ++k) {
187 out <<
"Round 2 of messages" << endl;
190 const int tag2 = 100;
193 for (size_type k = 0; k < recvBuf.size (); ++k) {
198 for (size_type k = 0; k < sendBuf.size (); ++k) {
199 sendBuf[k] = myRank + tag2;
207 send<int, int> (leftSendBuf.getRawPtr (), as<int> (leftSendBuf.size ()),
208 leftNeighbor, tag2, *comm);
209 send<int, int> (rightSendBuf.getRawPtr (), as<int> (rightSendBuf.size ()),
210 rightNeighbor, tag2, *comm);
213 waitAll (*comm, requests (), statuses ());
216 for (size_type k = 0; k < 2; ++k) {
217 sourceRanks[k] = statuses[k]->getSourceRank ();
219 std::sort (sourceRanks.begin (), sourceRanks.end ());
220 TEST_EQUALITY( sourceRanks.size (), expectedSourceRanks.size () );
221 for (size_type k = 0; k < sourceRanks.size (); ++k) {
226 for (size_type k = 0; k < statuses.size (); ++k) {
237 out <<
"Round 3 of messages" << endl;
242 const int tag3 = tag1;
245 for (size_type k = 0; k < recvBuf.size (); ++k) {
250 for (size_type k = 0; k < sendBuf.size (); ++k) {
251 sendBuf[k] = myRank + tag3;
259 send<int, int> (leftSendBuf.getRawPtr (), as<int> (leftSendBuf.size ()),
260 leftNeighbor, tag3, *comm);
261 send<int, int> (rightSendBuf.getRawPtr (), as<int> (rightSendBuf.size ()),
262 rightNeighbor, tag3, *comm);
265 waitAll (*comm, requests (), statuses ());
268 for (size_type k = 0; k < 2; ++k) {
269 sourceRanks[k] = statuses[k]->getSourceRank ();
271 std::sort (sourceRanks.begin (), sourceRanks.end ());
272 TEST_EQUALITY( sourceRanks.size (), expectedSourceRanks.size () );
273 for (size_type k = 0; k < sourceRanks.size (); ++k) {
278 for (size_type k = 0; k < statuses.size (); ++k) {
289 out <<
"Final check" << endl;
295 out <<
"All processes successfully completed this test." << endl;
301 typedef ArrayRCP<int>::size_type size_type;
303 RCP<const Comm<int> > comm =
rcp (
new MpiComm<int> (MPI_COMM_WORLD));
304 const int myRank = comm->getRank ();
305 const int numProcs = comm->getSize ();
313 out <<
"numProcs == 1, test passes trivially." << endl;
316 out <<
"Test setup" << endl;
320 int leftNeighbor = (myRank - 1) % numProcs;
321 int rightNeighbor = (myRank + 1) % numProcs;
323 if (leftNeighbor < 0) {
324 leftNeighbor += numProcs;
326 if (rightNeighbor < 0) {
327 rightNeighbor += numProcs;
329 Array<int> expectedSourceRanks (2);
330 expectedSourceRanks[0] = leftNeighbor;
331 expectedSourceRanks[1] = rightNeighbor;
332 std::sort (expectedSourceRanks.begin (), expectedSourceRanks.end ());
335 ArrayRCP<int> recvBuf (2);
336 ArrayRCP<int> leftRecvBuf = recvBuf.persistingView (0, 1);
337 ArrayRCP<int> rightRecvBuf = recvBuf.persistingView (1, 1);
340 ArrayRCP<int> sendBuf (2);
341 ArrayRCP<int> leftSendBuf = sendBuf.persistingView (0, 1);
342 ArrayRCP<int> rightSendBuf = sendBuf.persistingView (1, 1);
345 Array<RCP<CommRequest<int> > > requests (4);
349 Array<RCP<CommStatus<int> > > statuses (4);
354 out <<
"Round 1 of messages" << endl;
357 const int tag1 = 101;
360 for (size_type k = 0; k < recvBuf.size (); ++k) {
365 for (size_type k = 0; k < sendBuf.size (); ++k) {
366 sendBuf[k] = myRank + tag1;
374 requests[2] =
isend<int, int> (leftSendBuf, leftNeighbor, tag1, *comm);
375 requests[3] =
isend<int, int> (rightSendBuf, rightNeighbor, tag1, *comm);
378 waitAll (*comm, requests (), statuses ());
381 for (size_type k = 0; k < 2; ++k) {
392 out <<
"Round 2 of messages" << endl;
395 const int tag2 = 202;
398 for (size_type k = 0; k < recvBuf.size (); ++k) {
403 for (size_type k = 0; k < sendBuf.size (); ++k) {
404 sendBuf[k] = myRank + tag2;
412 requests[2] =
isend<int, int> (leftSendBuf, leftNeighbor, tag2, *comm);
413 requests[3] =
isend<int, int> (rightSendBuf, rightNeighbor, tag2, *comm);
416 waitAll (*comm, requests (), statuses ());
419 for (size_type k = 0; k < 2; ++k) {
430 out <<
"Round 3 of messages" << endl;
435 const int tag3 = tag1;
438 for (size_type k = 0; k < recvBuf.size (); ++k) {
443 for (size_type k = 0; k < sendBuf.size (); ++k) {
444 sendBuf[k] = myRank + tag3;
452 requests[2] =
isend<int, int> (leftSendBuf, leftNeighbor, tag3, *comm);
453 requests[3] =
isend<int, int> (rightSendBuf, rightNeighbor, tag3, *comm);
456 waitAll (*comm, requests (), statuses ());
459 for (size_type k = 0; k < 2; ++k) {
470 out <<
"Final check" << endl;
476 out <<
"All processes successfully completed this test." << endl;
RCP< T > rcp(const boost::shared_ptr< T > &sptr)
Conversion function that takes in a boost::shared_ptr object and spits out a Teuchos::RCP object...
void addOutputSetupOptions(const bool &addOutputSetupOptions)
Set if options will be automatically added to setup Teuchos::VerboseObjectBase::getDefaultOStream().
static CommandLineProcessor & getCLP()
Return the CLP to add options to.
#define TEST_EQUALITY(v1, v2)
Assert the equality of v1 and v2.
#define TEUCHOS_UNIT_TEST(TEST_GROUP, TEST_NAME)
Macro for defining a (non-templated) unit test.
void send< int, int >(const Comm< int > &comm, const int count, const int sendBuffer[], const int destRank)
TEUCHOS_DEPRECATED RCP< T > rcp(T *p, Dealloc_T dealloc, bool owns_mem)
Deprecated.
void waitAll(const Comm< Ordinal > &comm, const ArrayView< RCP< CommRequest< Ordinal > > > &requests)
Wait for an array of Teuchos::CommRequest objects.
Implementation of Teuchos wrappers for MPI.
Encapsulation of the result of a receive (blocking or nonblocking).
void send(const Packet sendBuffer[], const Ordinal count, const int destRank, const int tag, const Comm< Ordinal > &comm)
Variant of send() that takes a tag (and restores the correct order of arguments). ...
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
TEUCHOSCOMM_LIB_DLL_EXPORT RCP< CommRequest< int > > isend< int, int >(const ArrayRCP< const int > &sendBuffer, const int destRank, const int tag, const Comm< int > &comm)
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).
RCP< Teuchos::CommRequest< int > > ireceive< int, int >(const Comm< int > &comm, const ArrayRCP< int > &recvBuffer, const int sourceRank)
Abstract interface for distributed-memory communication.
RCP< Teuchos::CommRequest< int > > isend(const ArrayRCP< const double > &sendBuffer, const int destRank, const int tag, const Comm< int > &comm)
Smart reference counting pointer class for automatic garbage collection.
Encapsulation of a pending nonblocking communication operation.
Definition of Teuchos::as, for conversions between types.
Class that helps parse command line input arguments from (argc,argv[]) and set options.
Reference-counted smart pointer for managing arrays.
Replacement for std::vector that is compatible with the Teuchos Memory Management classes...