Zoltan2 Version of the Day
AlltoAll.cpp
Go to the documentation of this file.
00001 // @HEADER
00002 //
00003 // ***********************************************************************
00004 //
00005 //   Zoltan2: A package of combinatorial algorithms for scientific computing
00006 //                  Copyright 2012 Sandia Corporation
00007 //
00008 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00009 // the U.S. Government retains certain rights in this software.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are
00013 // met:
00014 //
00015 // 1. Redistributions of source code must retain the above copyright
00016 // notice, this list of conditions and the following disclaimer.
00017 //
00018 // 2. Redistributions in binary form must reproduce the above copyright
00019 // notice, this list of conditions and the following disclaimer in the
00020 // documentation and/or other materials provided with the distribution.
00021 //
00022 // 3. Neither the name of the Corporation nor the names of the
00023 // contributors may be used to endorse or promote products derived from
00024 // this software without specific prior written permission.
00025 //
00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037 //
00038 // Questions? Contact Karen Devine      (kddevin@sandia.gov)
00039 //                    Erik Boman        (egboman@sandia.gov)
00040 //                    Siva Rajamanickam (srajama@sandia.gov)
00041 //
00042 // ***********************************************************************
00043 //
00044 // @HEADER
00045 
00046 // TODO: doxygen comments
00047 //     make this a real unit test that gives helpful information if it fails
00048 //     and uses different template values
00049 
00050 #include <Zoltan2_Environment.hpp>   
00051 #include <Zoltan2_AlltoAll.hpp>   
00052 #include <Zoltan2_TestHelpers.hpp>   
00053 
00054 #include <iostream>
00055 #include <algorithm>
00056 #include <vector>
00057 #include <string>
00058 
00059 #include <Teuchos_RCP.hpp>   
00060 #include <Teuchos_ArrayRCP.hpp>   
00061 #include <Teuchos_Comm.hpp>   
00062 #include <Teuchos_DefaultComm.hpp>   
00063 
00064 using namespace std;
00065 
00066 int main(int argc, char *argv[])
00067 {
00068   Teuchos::GlobalMPISession session(&argc, &argv);
00069   Teuchos::RCP<const Teuchos::Comm<int> > comm = 
00070     Teuchos::DefaultComm<int>::getComm();
00071 
00072   int rank = comm->getRank();
00073   int nprocs = comm->getSize();
00074 
00075   Teuchos::RCP<const Zoltan2::Environment> envPtr = 
00076     Teuchos::rcp(new Zoltan2::Environment);
00077 
00078   int errcode = 0;
00079 
00080   if (!errcode){
00081 
00082     // test of Zoltan2::AlltoAllv (different sized messages) using a Scalar type
00083 
00084     int myMsgSizeBase=rank*nprocs + 1;
00085     Array<int> sendCount(nprocs, 0);
00086     Array<int> recvCount(nprocs, 0);
00087     long totalOut = 0;
00088 
00089     for (int p=0; p < nprocs; p++){
00090       sendCount[p] = myMsgSizeBase + p;
00091       totalOut += sendCount[p];
00092     }
00093   
00094     Array<int> sendBuf(totalOut, 0);
00095   
00096     int *out = &(sendBuf[0]);
00097     for (int p=0; p < nprocs; p++){
00098       for (int i=0; i < sendCount[p]; i++){
00099         *out++ = p+rank;
00100       }
00101     }
00102   
00103     Teuchos::ArrayRCP<int> recvBuf;
00104     
00105     Zoltan2::AlltoAllv<int>(*comm, *envPtr,
00106                   sendBuf(),
00107                   sendCount(),
00108                   recvBuf,
00109                   recvCount());
00110 
00111     int *inBuf = recvBuf.get();
00112 
00113     for (int p=0; p < nprocs; p++){
00114       for (int i=0; i < recvCount[p]; i++){
00115         if (*inBuf++ != rank+p){
00116           errcode = 4;
00117           break;
00118         }
00119       }
00120     }
00121   }
00122 
00123   TEST_FAIL_AND_EXIT(*comm, errcode==0, "int", errcode);
00124 
00125   if (!errcode){
00126 
00127     // test of Zoltan2::AlltoAllv using strings - which can not
00128     //    be serialized by Teuchos.
00129     //  Rank p sends p messages to each process.
00130 
00131     int nstrings = nprocs * rank;
00132     string *sendStrings = NULL;
00133 
00134     if (nstrings > 0)
00135       sendStrings = new string [nstrings];
00136 
00137     ostringstream myMessage;
00138     myMessage << "message from process " << rank;
00139 
00140     for (int i=0; i < nstrings; i++)
00141       sendStrings[i] = myMessage.str();
00142 
00143     int *counts = new int [nprocs];
00144     for (int i=0; i < nprocs ; i++)
00145       counts[i] = rank;
00146 
00147     Teuchos::ArrayView<const string> sendBuf(sendStrings, nstrings);
00148     Teuchos::ArrayView<const int> sendCount(counts, nprocs);
00149     Teuchos::Array<int> recvCounts(nprocs, 0);
00150 
00151     Teuchos::ArrayRCP<string> recvBuf;
00152 
00153     Zoltan2::AlltoAllv<string>(*comm, *envPtr,
00154         sendBuf,    
00155         sendCount,   
00156         recvBuf,
00157         recvCounts());
00158 
00159     delete [] sendStrings;
00160     delete [] counts;
00161   
00162     int next = 0;
00163     for (int i=0; i < nprocs; i++){
00164       if (recvCounts[i] != i){
00165         errcode = 5;
00166         break;
00167       }
00168       ostringstream msg;
00169       msg << "message from process " << i;
00170       for (int j=0; j < recvCounts[i]; j++){
00171         if (recvBuf[next++] != msg.str()){
00172           errcode = 6;
00173           break;
00174         }
00175       }
00176     }
00177   }
00178 
00179   TEST_FAIL_AND_EXIT(*comm, errcode==0, "strings", errcode);
00180 
00181   if (rank == 0){
00182     if (errcode)
00183       std::cout << "FAIL" << std::endl;
00184     else
00185       std::cout << "PASS" << std::endl;
00186   }
00187 
00188   return errcode;
00189 }