Zoltan2
XpetraMultiVectorInput.cpp
Go to the documentation of this file.
1 // @HEADER
2 //
3 // ***********************************************************************
4 //
5 // Zoltan2: A package of combinatorial algorithms for scientific computing
6 // Copyright 2012 Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
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 Karen Devine (kddevin@sandia.gov)
39 // Erik Boman (egboman@sandia.gov)
40 // Siva Rajamanickam (srajama@sandia.gov)
41 //
42 // ***********************************************************************
43 //
44 // @HEADER
45 // @HEADER
46 // ***********************************************************************
47 // Zoltan2: Sandia Partitioning Ordering & Coloring Library
48 // ***********************************************************************
49 
55 #include <string>
56 
58 #include <Zoltan2_InputTraits.hpp>
59 #include <Zoltan2_TestHelpers.hpp>
60 
61 #include <Teuchos_GlobalMPISession.hpp>
62 #include <Teuchos_DefaultComm.hpp>
63 #include <Teuchos_RCP.hpp>
64 #include <Teuchos_Comm.hpp>
65 #include <Teuchos_CommHelpers.hpp>
66 
67 using namespace std;
68 using Teuchos::RCP;
69 using Teuchos::rcp;
70 using Teuchos::rcp_const_cast;
71 using Teuchos::Comm;
72 using Teuchos::DefaultComm;
73 
74 typedef Tpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> tvector_t;
75 typedef Xpetra::MultiVector<zscalar_t, zlno_t, zgno_t, znode_t> xvector_t;
76 
77 template <typename User>
80  int wdim, zscalar_t **weights, int *strides)
81 {
82  RCP<const Comm<int> > comm = vector.getMap()->getComm();
83  int fail = 0, gfail=0;
84 
85  if (!fail && ia.getNumEntriesPerID() !=nvec)
86  fail = 42;
87 
88  if (!fail && ia.getNumWeightsPerID() !=wdim)
89  fail = 41;
90 
91  size_t length = vector.getLocalLength();
92 
93  if (!fail && ia.getLocalNumIDs() != length)
94  fail = 4;
95 
96  gfail = globalFail(comm, fail);
97 
98  if (!gfail){
99  const zgno_t *vtxIds=NULL;
100  const zscalar_t *vals=NULL;
101  int stride;
102 
103  size_t nvals = ia.getLocalNumIDs();
104  if (nvals != vector.getLocalLength())
105  fail = 8;
106 
107  ia.getIDsView(vtxIds);
108 
109  for (int v=0; v < nvec; v++){
110  ia.getEntriesView(vals, stride, v);
111 
112  if (!fail && stride != 1)
113  fail = 10;
114 
115  // TODO check the values returned
116  }
117 
118  gfail = globalFail(comm, fail);
119  }
120 
121  if (!gfail && wdim){
122  const zscalar_t *wgt =NULL;
123  int stride;
124 
125  for (int w=0; !fail && w < wdim; w++){
126  ia.getWeightsView(wgt, stride, w);
127 
128  if (!fail && stride != strides[w])
129  fail = 101;
130 
131  for (size_t v=0; !fail && v < vector.getLocalLength(); v++){
132  if (wgt[v*stride] != weights[w][v*stride])
133  fail=102;
134  }
135  }
136 
137  gfail = globalFail(comm, fail);
138  }
139 
140  return gfail;
141 }
142 
143 int main(int argc, char *argv[])
144 {
145  Teuchos::GlobalMPISession session(&argc, &argv);
146  RCP<const Comm<int> > comm = DefaultComm<int>::getComm();
147  int rank = comm->getRank();
148  int fail = 0, gfail=0;
149  bool aok = true;
150 
151  // Create object that can give us test Tpetra, Xpetra
152  // and Epetra vectors for testing.
153 
154  RCP<UserInputForTests> uinput;
155 
156  try{
157  uinput =
158  rcp(new UserInputForTests(testDataFilePath,std::string("simple"), comm, true));
159  }
160  catch(std::exception &e){
161  aok = false;
162  std::cout << e.what() << std::endl;
163  }
164  TEST_FAIL_AND_EXIT(*comm, aok, "input ", 1);
165 
166  RCP<tvector_t> tV; // original vector (for checking)
167  RCP<tvector_t> newV; // migrated vector
168 
169  int nVec = 2;
170 
171  tV = rcp(new tvector_t(uinput->getUITpetraCrsGraph()->getRowMap(), nVec));
172  tV->randomize();
173 
174  size_t vlen = tV->getLocalLength();
175 
176  // To test migration in the input adapter we need a Solution object.
177 
178  RCP<const Zoltan2::Environment> env = rcp(new Zoltan2::Environment);
179 
180  int nWeights = 1;
181 
184  typedef ia_t::part_t part_t;
185 
186  part_t *p = new part_t [vlen];
187  memset(p, 0, sizeof(part_t) * vlen);
188  ArrayRCP<part_t> solnParts(p, 0, vlen, true);
189 
190  soln_t solution(env, comm, nWeights);
191  solution.setParts(solnParts);
192 
193  std::vector<const zscalar_t *> emptyWeights;
194  std::vector<int> emptyStrides;
195 
197  // User object is Tpetra::MultiVector, no weights
198  if (!gfail){
199  RCP<const tvector_t> ctV = rcp_const_cast<const tvector_t>(tV);
200  RCP<Zoltan2::XpetraMultiVectorAdapter<tvector_t> > tVInput;
201 
202  try {
203  tVInput =
205  emptyWeights, emptyStrides));
206  }
207  catch (std::exception &e){
208  aok = false;
209  std::cout << e.what() << std::endl;
210  }
211  TEST_FAIL_AND_EXIT(*comm, aok, "XpetraMultiVectorAdapter ", 1);
212 
213  if (rank==0){
214  std::cout << "Constructed with ";
215  std::cout << "Tpetra::MultiVector" << std::endl;
216  }
217 
218  fail = verifyInputAdapter<tvector_t>(*tVInput, *tV, nVec, 0, NULL, NULL);
219 
220  gfail = globalFail(comm, fail);
221 
222  if (!gfail){
223  tvector_t *vMigrate = NULL;
224  try{
225  tVInput->applyPartitioningSolution(*tV, vMigrate, solution);
226  newV = rcp(vMigrate);
227  }
228  catch (std::exception &e){
229  fail = 11;
230  }
231 
232  gfail = globalFail(comm, fail);
233 
234  if (!gfail){
235  RCP<const tvector_t> cnewV = rcp_const_cast<const tvector_t>(newV);
236  RCP<Zoltan2::XpetraMultiVectorAdapter<tvector_t> > newInput;
237  try{
239  cnewV, emptyWeights, emptyStrides));
240  }
241  catch (std::exception &e){
242  aok = false;
243  std::cout << e.what() << std::endl;
244  }
245  TEST_FAIL_AND_EXIT(*comm, aok, "XpetraMultiVectorAdapter 2 ", 1);
246 
247  if (rank==0){
248  std::cout << "Constructed with ";
249  std::cout << "Tpetra::MultiVector migrated to proc 0" << std::endl;
250  }
251  fail = verifyInputAdapter<tvector_t>(*newInput, *newV, nVec, 0, NULL, NULL);
252  if (fail) fail += 100;
253  gfail = globalFail(comm, fail);
254  }
255  }
256  if (gfail){
257  printFailureCode(comm, fail);
258  }
259  }
260 
262  // User object is Xpetra::MultiVector
263  if (!gfail){
264  RCP<tvector_t> tMV =
265  rcp(new tvector_t(uinput->getUITpetraCrsGraph()->getRowMap(), nVec));
266  tMV->randomize();
267  RCP<xvector_t> xV = Zoltan2::XpetraTraits<tvector_t>::convertToXpetra(tMV);
268  RCP<const xvector_t> cxV = rcp_const_cast<const xvector_t>(xV);
269  RCP<Zoltan2::XpetraMultiVectorAdapter<xvector_t> > xVInput;
270 
271  try {
272  xVInput =
274  emptyWeights, emptyStrides));
275  }
276  catch (std::exception &e){
277  aok = false;
278  std::cout << e.what() << std::endl;
279  }
280  TEST_FAIL_AND_EXIT(*comm, aok, "XpetraMultiVectorAdapter 3 ", 1);
281 
282  if (rank==0){
283  std::cout << "Constructed with ";
284  std::cout << "Xpetra::MultiVector" << std::endl;
285  }
286  fail = verifyInputAdapter<xvector_t>(*xVInput, *tV, nVec, 0, NULL, NULL);
287 
288  gfail = globalFail(comm, fail);
289 
290  if (!gfail){
291  xvector_t *vMigrate =NULL;
292  try{
293  xVInput->applyPartitioningSolution(*xV, vMigrate, solution);
294  }
295  catch (std::exception &e){
296  fail = 11;
297  }
298 
299  gfail = globalFail(comm, fail);
300 
301  if (!gfail){
302  RCP<const xvector_t> cnewV(vMigrate);
303  RCP<Zoltan2::XpetraMultiVectorAdapter<xvector_t> > newInput;
304  try{
305  newInput =
307  cnewV, emptyWeights, emptyStrides));
308  }
309  catch (std::exception &e){
310  aok = false;
311  std::cout << e.what() << std::endl;
312  }
313  TEST_FAIL_AND_EXIT(*comm, aok, "XpetraMultiVectorAdapter 4 ", 1);
314 
315  if (rank==0){
316  std::cout << "Constructed with ";
317  std::cout << "Xpetra::MultiVector migrated to proc 0" << std::endl;
318  }
319  fail = verifyInputAdapter<xvector_t>(*newInput, *newV, nVec, 0, NULL, NULL);
320  if (fail) fail += 100;
321  gfail = globalFail(comm, fail);
322  }
323  }
324  if (gfail){
325  printFailureCode(comm, fail);
326  }
327  }
328 
329 #ifdef HAVE_EPETRA_DATA_TYPES
330  // User object is Epetra_MultiVector
332  typedef Epetra_MultiVector evector_t;
333  if (!gfail){
334  RCP<evector_t> eV =
335  rcp(new Epetra_MultiVector(uinput->getUIEpetraCrsGraph()->RowMap(),
336  nVec));
337  eV->Random();
338  RCP<const evector_t> ceV = rcp_const_cast<const evector_t>(eV);
339  RCP<Zoltan2::XpetraMultiVectorAdapter<evector_t> > eVInput;
340 
341  try {
342  eVInput =
344  emptyWeights, emptyStrides));
345  }
346  catch (std::exception &e){
347  aok = false;
348  std::cout << e.what() << std::endl;
349  }
350  TEST_FAIL_AND_EXIT(*comm, aok, "XpetraMultiVectorAdapter 5 ", 1);
351 
352  if (rank==0){
353  std::cout << "Constructed with ";
354  std::cout << "Epetra_MultiVector" << std::endl;
355  }
356  fail = verifyInputAdapter<evector_t>(*eVInput, *tV, nVec, 0, NULL, NULL);
357 
358  gfail = globalFail(comm, fail);
359 
360  if (!gfail){
361  evector_t *vMigrate =NULL;
362  try{
363  eVInput->applyPartitioningSolution(*eV, vMigrate, solution);
364  }
365  catch (std::exception &e){
366  fail = 11;
367  }
368 
369  gfail = globalFail(comm, fail);
370 
371  if (!gfail){
372  RCP<const evector_t> cnewV(vMigrate, true);
373  RCP<Zoltan2::XpetraMultiVectorAdapter<evector_t> > newInput;
374  try{
375  newInput =
377  emptyWeights, emptyStrides));
378  }
379  catch (std::exception &e){
380  aok = false;
381  std::cout << e.what() << std::endl;
382  }
383  TEST_FAIL_AND_EXIT(*comm, aok, "XpetraMultiVectorAdapter 6 ", 1);
384 
385  if (rank==0){
386  std::cout << "Constructed with ";
387  std::cout << "Epetra_MultiVector migrated to proc 0" << std::endl;
388  }
389  fail = verifyInputAdapter<evector_t>(*newInput, *newV, nVec, 0, NULL, NULL);
390  if (fail) fail += 100;
391  gfail = globalFail(comm, fail);
392  }
393  }
394  if (gfail){
395  printFailureCode(comm, fail);
396  }
397  }
398 #endif
399 
401  // DONE
402 
403  if (rank==0)
404  std::cout << "PASS" << std::endl;
405 }
int globalFail(const RCP< const Comm< int > > &comm, int fail)
double zscalar_t
#define TEST_FAIL_AND_EXIT(comm, ok, s, code)
static ArrayRCP< ArrayRCP< zscalar_t > > weights
Tpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > tvector_t
common code used by tests
static RCP< User > convertToXpetra(const RCP< User > &a)
Convert the object to its Xpetra wrapped version.
int verifyInputAdapter(Zoltan2::XpetraMultiVectorAdapter< User > &ia, tvector_t &vector, int nvec, int wdim, zscalar_t **weights, int *strides)
Defines the XpetraMultiVectorAdapter.
int getNumEntriesPerID() const
Return the number of vectors (typically one).
dictionary vals
Definition: xml2dox.py:186
A PartitioningSolution is a solution to a partitioning problem.
void getEntriesView(const scalar_t *&elements, int &stride, int idx=0) const
Provide a pointer to the elements of the specified vector.
Traits for application input objects.
The user parameters, debug, timing and memory profiling output objects, and error checking methods...
int getNumWeightsPerID() const
Returns the number of weights per object. Number of weights per object should be zero or greater...
An adapter for Xpetra::MultiVector.
static const std::string fail
int zgno_t
void printFailureCode(const RCP< const Comm< int > > &comm, int fail)
int main(int argc, char *argv[])
size_t getLocalNumIDs() const
Returns the number of objects on this process.
Xpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > xvector_t
void getWeightsView(const scalar_t *&weights, int &stride, int idx) const
Provide pointer to a weight array with stride.
std::string testDataFilePath(".")