Zoltan 2 Version 0.5
CoordinateModel.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 // Testing of CoordinateModel
00047 //
00048 
00049 #include <Zoltan2_CoordinateModel.hpp>
00050 #include <Zoltan2_BasicCoordinateInput.hpp>
00051 #include <Zoltan2_TestHelpers.hpp>
00052 
00053 #include <set>
00054 #include <bitset>
00055 
00056 #include <Teuchos_Comm.hpp>
00057 #include <Teuchos_CommHelpers.hpp>
00058 #include <Teuchos_DefaultComm.hpp>
00059 #include <Teuchos_ArrayView.hpp>
00060 #include <Teuchos_OrdinalTraits.hpp>
00061 
00062 #include <Tpetra_CrsMatrix.hpp>
00063 
00064 using namespace std;
00065 using Teuchos::RCP;
00066 using Teuchos::Comm;
00067 using Teuchos::DefaultComm;
00068 using std::cout;
00069 using std::endl;
00070 
00071 void testCoordinateModel(std::string &fname, int weightDim,
00072   const RCP<const Comm<int> > &comm, bool consecutiveIds,
00073   bool nodeZeroHasAll, bool printInfo)
00074 {
00075   int fail = 0, gfail = 0;
00076 
00077   if (printInfo){
00078     cout << "Test: " << fname << endl;
00079     cout << "Weight dim: " << weightDim;
00080     cout << " want consec ids: " << consecutiveIds;
00081     cout << " proc 0 has all: " << nodeZeroHasAll;
00082     cout << endl;
00083   }
00084 
00086   // Input data
00088 
00089   typedef Tpetra::MultiVector<scalar_t, lno_t, gno_t, node_t> mv_t;
00090 
00091   RCP<UserInputForTests> uinput;
00092 
00093   try{
00094     uinput = rcp(new UserInputForTests(testDataFilePath, fname, comm, true));
00095   }
00096   catch(std::exception &e){
00097     fail=1;
00098   }
00099 
00100   TEST_FAIL_AND_EXIT(*comm, !fail, "input constructor", 1);
00101 
00102   RCP<mv_t> coords;
00103 
00104   try{
00105     coords = uinput->getCoordinates();
00106   }
00107   catch(std::exception &e){
00108     fail=2;
00109   }
00110 
00111   TEST_FAIL_AND_EXIT(*comm, !fail, "getting coordinates", 1);
00112 
00113   int coordDim = coords->getNumVectors();
00114 
00115   TEST_FAIL_AND_EXIT(*comm, coordDim <= 3, "dim 3 at most", 1);
00116 
00117   const scalar_t *x=NULL, *y=NULL, *z=NULL;
00118 
00119   x = coords->getData(0).getRawPtr();
00120   if (coordDim > 1){
00121     y = coords->getData(1).getRawPtr();
00122     if (coordDim > 2)
00123       z = coords->getData(2).getRawPtr();
00124   }
00125 
00126   // Are these coordinates correct
00127 
00128   int nLocalIds = coords->getLocalLength();
00129   ArrayView<const gno_t> idList = coords->getMap()->getNodeElementList();
00130 
00131   int nGlobalIds = 0;
00132   if (nodeZeroHasAll){
00133     if (comm->getRank() > 0){
00134       x = y = z = NULL;
00135       nLocalIds = 0;
00136     }
00137     else{
00138       nGlobalIds = nLocalIds;
00139     }
00140     Teuchos::broadcast<int, int>(*comm, 0, &nGlobalIds);
00141   }
00142   else{
00143     nGlobalIds = coords->getGlobalLength();
00144   }
00145 
00146   Array<ArrayRCP<const scalar_t> > coordWeights(weightDim);
00147 
00148   if (nLocalIds > 0){
00149     for (int wdim=0; wdim < weightDim; wdim++){
00150       scalar_t *w = new scalar_t [nLocalIds];
00151       for (int i=0; i < nLocalIds; i++){
00152         w[i] = ((i%2) + 1) + wdim;
00153       }
00154       coordWeights[wdim] = Teuchos::arcp(w, 0, nLocalIds);
00155     }
00156   }
00157 
00158 
00160   // Create a BasicCoordinateInput adapter object.
00162 
00163   typedef Zoltan2::BasicCoordinateInput<mv_t> ia_t;
00164   typedef Zoltan2::CoordinateInput<mv_t>      base_ia_t;
00165 
00166   RCP<ia_t> ia;
00167 
00168   if (weightDim == 0){   // use the simpler constructor
00169     try{
00170       ia = rcp(new ia_t(nLocalIds, idList.getRawPtr(), x, y, z));
00171     }
00172     catch(std::exception &e){
00173       fail=3;
00174     }
00175   }
00176   else{
00177     std::vector<const scalar_t *> values, weights;
00178     std::vector<int> valueStrides, weightStrides;  // default is 1
00179     values.push_back(x);
00180     if (y) {
00181       values.push_back(y);
00182       if (z) 
00183         values.push_back(z);
00184     }
00185     for (int wdim=0; wdim < weightDim; wdim++){
00186       weights.push_back(coordWeights[wdim].getRawPtr());
00187     }
00188 
00189     try{
00190       ia = rcp(new ia_t(nLocalIds, idList.getRawPtr(),
00191                values, valueStrides, weights, weightStrides));
00192     }
00193     catch(std::exception &e){
00194       fail=4;
00195     }
00196   }
00197 
00198   RCP<base_ia_t> base_ia = Teuchos::rcp_implicit_cast<base_ia_t>(ia);
00199 
00200   TEST_FAIL_AND_EXIT(*comm, !fail, "making input adapter", 1);
00201 
00203   // Create an CoordinateModel with this input
00205 
00206   typedef Zoltan2::StridedData<lno_t, scalar_t> input_t;
00207   typedef std::bitset<Zoltan2::NUM_MODEL_FLAGS> modelFlags_t;
00208   typedef Zoltan2::CoordinateModel<base_ia_t> model_t;
00209   modelFlags_t modelFlags;
00210 
00211   if (consecutiveIds)
00212     modelFlags.set(Zoltan2::IDS_MUST_BE_GLOBALLY_CONSECUTIVE);
00213 
00214   RCP<const Zoltan2::Environment> env = rcp(new Zoltan2::Environment);
00215   RCP<model_t> model;
00216   
00217 
00218   try{
00219     model = rcp(new model_t(base_ia.getRawPtr(), env, comm, modelFlags));
00220   }
00221   catch (std::exception &e){
00222     fail = 5;
00223   }
00224 
00225   TEST_FAIL_AND_EXIT(*comm, !fail, "making model", 1);
00226 
00227   // Test the CoordinateModel interface
00228 
00229   if (model->getCoordinateDim() != coordDim)
00230     fail = 6;
00231 
00232   if (!fail && model->getLocalNumCoordinates() != size_t(nLocalIds))
00233     fail = 7;
00234 
00235   if (!fail && model->getGlobalNumCoordinates() != size_t(nGlobalIds))
00236     fail = 8;
00237 
00238   if (!fail && model->getCoordinateWeightDim() !=  weightDim)
00239     fail = 9;
00240 
00241   gfail = globalFail(comm, fail);
00242 
00243   if (gfail)
00244     printFailureCode(comm, fail);
00245   
00246   ArrayView<const gno_t> gids;
00247   ArrayView<input_t> xyz;
00248   ArrayView<input_t> wgts;
00249   
00250   model->getCoordinates(gids, xyz, wgts);
00251 
00252   if (!fail && gids.size() != nLocalIds)
00253     fail = 10;
00254 
00255   for (int i=0; !fail && i < nLocalIds; i++){
00256     if (gids[i] != idList[i])
00257       fail = 11;
00258   }
00259 
00260   if (!fail && wgts.size() != weightDim)
00261     fail = 12;
00262 
00263   const scalar_t *vals[3] = {x, y, z};
00264 
00265   for (int dim=0; !fail && dim < coordDim; dim++){
00266     for (int i=0; !fail && i < nLocalIds; i++){
00267       if (xyz[dim][i] != vals[dim][i])
00268         fail = 13;
00269     }
00270   }
00271 
00272   for (int wdim=0; !fail && wdim < weightDim; wdim++){
00273     for (int i=0; !fail && i < nLocalIds; i++){
00274       if (wgts[wdim][i] != coordWeights[wdim][i])
00275         fail = 14;
00276     }
00277   }
00278 
00279   if (!fail && consecutiveIds){
00280     bool inARow = Zoltan2::IdentifierTraits<gno_t>::areConsecutive(
00281       gids.getRawPtr(), nLocalIds);
00282 
00283     if (!inARow)
00284       fail = 15;
00285   }
00286 
00287   gfail = globalFail(comm, fail);
00288 
00289   if (gfail)
00290     printFailureCode(comm, fail);
00291 }
00292 
00293 int main(int argc, char *argv[])
00294 {
00295   Teuchos::GlobalMPISession session(&argc, &argv);
00296   Teuchos::RCP<const Teuchos::Comm<int> > comm =
00297     Teuchos::DefaultComm<int>::getComm();
00298 
00299   int rank = comm->getRank();
00300   string fname("simple");   // reader will seek coord file
00301   bool wishConsecutiveIds = true;
00302 
00303   testCoordinateModel(fname, 0, comm, !wishConsecutiveIds, false, rank==0);
00304 
00305   testCoordinateModel(fname, 0, comm,  wishConsecutiveIds, false, rank==0);
00306 
00307   testCoordinateModel(fname, 1, comm, !wishConsecutiveIds, false, rank==0);
00308 
00309   testCoordinateModel(fname, 2, comm,  wishConsecutiveIds, false, rank==0);
00310 
00311   testCoordinateModel(fname, 0, comm, !wishConsecutiveIds, true, rank==0);
00312 
00313   testCoordinateModel(fname, 0, comm,  wishConsecutiveIds, true, rank==0);
00314 
00315   testCoordinateModel(fname, 1, comm, !wishConsecutiveIds, true, rank==0);
00316 
00317   testCoordinateModel(fname, 2, comm,  wishConsecutiveIds, true, rank==0);
00318 
00319   if (rank==0) cout << "PASS" << endl;
00320 
00321   return 0;
00322 }