19 template <
typename Packet>
20 ostream & operator<< (ostream& os, const pair<Packet, Packet>& arg)
22 os <<
"(" << arg.first <<
"," << arg.second <<
")";
38 using Teuchos::MpiComm;
39 using Teuchos::outArg;
43 using Teuchos::waitAll;
54 typedef ArrayRCP<int>::size_type size_type;
56 RCP<const Comm<int> > comm =
rcp (
new MpiComm<int> (MPI_COMM_WORLD));
57 const int myRank = comm->getRank ();
58 const int numProcs = comm->getSize ();
66 out <<
"numProcs == 1, test passes trivially." << endl;
69 out <<
"Test setup" << endl;
73 int leftNeighbor = (myRank - 1) % numProcs;
74 int rightNeighbor = (myRank + 1) % numProcs;
76 if (leftNeighbor < 0) {
77 leftNeighbor += numProcs;
79 if (rightNeighbor < 0) {
80 rightNeighbor += numProcs;
82 Array<int> expectedSourceRanks (2);
83 expectedSourceRanks[0] = leftNeighbor;
84 expectedSourceRanks[1] = rightNeighbor;
85 std::sort (expectedSourceRanks.begin (), expectedSourceRanks.end ());
88 ArrayRCP<int> recvBuf (2);
89 ArrayRCP<int> leftRecvBuf = recvBuf.persistingView (0, 1);
90 ArrayRCP<int> rightRecvBuf = recvBuf.persistingView (1, 1);
93 Array<int> sendBuf (2);
94 ArrayView<int> leftSendBuf = sendBuf.view (0, 1);
95 ArrayView<int> rightSendBuf = sendBuf.view (1, 1);
100 out <<
"Round 1 of messages" << endl;
106 for (size_type k = 0; k < recvBuf.size (); ++k) {
111 for (size_type k = 0; k < sendBuf.size (); ++k) {
112 sendBuf[k] = myRank + tag1;
116 Array<RCP<CommRequest<int> > > requests (2);
121 send<int, int> (leftSendBuf.getRawPtr (), as<int> (leftSendBuf.size ()),
122 leftNeighbor, tag1, *comm);
123 send<int, int> (rightSendBuf.getRawPtr (), as<int> (rightSendBuf.size ()),
124 rightNeighbor, tag1, *comm);
127 Array<RCP<CommStatus<int> > > statuses (2);
128 waitAll (*comm, requests (), statuses ());
131 Array<int> sourceRanks (2);
132 for (size_type k = 0; k < 2; ++k) {
133 sourceRanks[k] = statuses[k]->getSourceRank ();
135 std::sort (sourceRanks.begin (), sourceRanks.end ());
136 TEST_EQUALITY( sourceRanks.size (), expectedSourceRanks.size () );
137 for (size_type k = 0; k < sourceRanks.size (); ++k) {
142 for (size_type k = 0; k < statuses.size (); ++k) {
153 out <<
"Round 2 of messages" << endl;
156 const int tag2 = 100;
159 for (size_type k = 0; k < recvBuf.size (); ++k) {
164 for (size_type k = 0; k < sendBuf.size (); ++k) {
165 sendBuf[k] = myRank + tag2;
173 send<int, int> (leftSendBuf.getRawPtr (), as<int> (leftSendBuf.size ()),
174 leftNeighbor, tag2, *comm);
175 send<int, int> (rightSendBuf.getRawPtr (), as<int> (rightSendBuf.size ()),
176 rightNeighbor, tag2, *comm);
179 waitAll (*comm, requests (), statuses ());
182 for (size_type k = 0; k < 2; ++k) {
183 sourceRanks[k] = statuses[k]->getSourceRank ();
185 std::sort (sourceRanks.begin (), sourceRanks.end ());
186 TEST_EQUALITY( sourceRanks.size (), expectedSourceRanks.size () );
187 for (size_type k = 0; k < sourceRanks.size (); ++k) {
192 for (size_type k = 0; k < statuses.size (); ++k) {
203 out <<
"Round 3 of messages" << endl;
208 const int tag3 = tag1;
211 for (size_type k = 0; k < recvBuf.size (); ++k) {
216 for (size_type k = 0; k < sendBuf.size (); ++k) {
217 sendBuf[k] = myRank + tag3;
225 send<int, int> (leftSendBuf.getRawPtr (), as<int> (leftSendBuf.size ()),
226 leftNeighbor, tag3, *comm);
227 send<int, int> (rightSendBuf.getRawPtr (), as<int> (rightSendBuf.size ()),
228 rightNeighbor, tag3, *comm);
231 waitAll (*comm, requests (), statuses ());
234 for (size_type k = 0; k < 2; ++k) {
235 sourceRanks[k] = statuses[k]->getSourceRank ();
237 std::sort (sourceRanks.begin (), sourceRanks.end ());
238 TEST_EQUALITY( sourceRanks.size (), expectedSourceRanks.size () );
239 for (size_type k = 0; k < sourceRanks.size (); ++k) {
244 for (size_type k = 0; k < statuses.size (); ++k) {
255 out <<
"Final check" << endl;
261 out <<
"All processes successfully completed this test." << endl;
267 typedef ArrayRCP<int>::size_type size_type;
269 RCP<const Comm<int> > comm =
rcp (
new MpiComm<int> (MPI_COMM_WORLD));
270 const int myRank = comm->getRank ();
271 const int numProcs = comm->getSize ();
279 out <<
"numProcs == 1, test passes trivially." << endl;
282 out <<
"Test setup" << endl;
286 int leftNeighbor = (myRank - 1) % numProcs;
287 int rightNeighbor = (myRank + 1) % numProcs;
289 if (leftNeighbor < 0) {
290 leftNeighbor += numProcs;
292 if (rightNeighbor < 0) {
293 rightNeighbor += numProcs;
295 Array<int> expectedSourceRanks (2);
296 expectedSourceRanks[0] = leftNeighbor;
297 expectedSourceRanks[1] = rightNeighbor;
298 std::sort (expectedSourceRanks.begin (), expectedSourceRanks.end ());
301 ArrayRCP<int> recvBuf (2);
302 ArrayRCP<int> leftRecvBuf = recvBuf.persistingView (0, 1);
303 ArrayRCP<int> rightRecvBuf = recvBuf.persistingView (1, 1);
306 ArrayRCP<int> sendBuf (2);
307 ArrayRCP<int> leftSendBuf = sendBuf.persistingView (0, 1);
308 ArrayRCP<int> rightSendBuf = sendBuf.persistingView (1, 1);
311 Array<RCP<CommRequest<int> > > requests (4);
315 Array<RCP<CommStatus<int> > > statuses (4);
320 out <<
"Round 1 of messages" << endl;
323 const int tag1 = 101;
326 for (size_type k = 0; k < recvBuf.size (); ++k) {
331 for (size_type k = 0; k < sendBuf.size (); ++k) {
332 sendBuf[k] = myRank + tag1;
340 requests[2] =
isend<int, int> (leftSendBuf, leftNeighbor, tag1, *comm);
341 requests[3] =
isend<int, int> (rightSendBuf, rightNeighbor, tag1, *comm);
344 waitAll (*comm, requests (), statuses ());
347 for (size_type k = 0; k < 2; ++k) {
358 out <<
"Round 2 of messages" << endl;
361 const int tag2 = 202;
364 for (size_type k = 0; k < recvBuf.size (); ++k) {
369 for (size_type k = 0; k < sendBuf.size (); ++k) {
370 sendBuf[k] = myRank + tag2;
378 requests[2] =
isend<int, int> (leftSendBuf, leftNeighbor, tag2, *comm);
379 requests[3] =
isend<int, int> (rightSendBuf, rightNeighbor, tag2, *comm);
382 waitAll (*comm, requests (), statuses ());
385 for (size_type k = 0; k < 2; ++k) {
396 out <<
"Round 3 of messages" << endl;
401 const int tag3 = tag1;
404 for (size_type k = 0; k < recvBuf.size (); ++k) {
409 for (size_type k = 0; k < sendBuf.size (); ++k) {
410 sendBuf[k] = myRank + tag3;
418 requests[2] =
isend<int, int> (leftSendBuf, leftNeighbor, tag3, *comm);
419 requests[3] =
isend<int, int> (rightSendBuf, rightNeighbor, tag3, *comm);
422 waitAll (*comm, requests (), statuses ());
425 for (size_type k = 0; k < 2; ++k) {
436 out <<
"Final check" << endl;
442 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...