Zoltan2
XpetraVectorInput.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 //
46 
52 #include <string>
53 
55 #include <Zoltan2_InputTraits.hpp>
56 #include <Zoltan2_TestHelpers.hpp>
57 
58 #include <Teuchos_GlobalMPISession.hpp>
59 #include <Teuchos_DefaultComm.hpp>
60 #include <Teuchos_RCP.hpp>
61 #include <Teuchos_Comm.hpp>
62 #include <Teuchos_CommHelpers.hpp>
63 
64 using namespace std;
65 using Teuchos::RCP;
66 using Teuchos::rcp;
67 using Teuchos::rcp_const_cast;
68 using Teuchos::Comm;
69 using Teuchos::DefaultComm;
70 
71 typedef Tpetra::Vector<zscalar_t, zlno_t, zgno_t, znode_t> tvector_t;
72 typedef Xpetra::Vector<zscalar_t, zlno_t, zgno_t, znode_t> xvector_t;
73 
74 void printVector(RCP<const Comm<int> > &comm, zlno_t vlen,
75  const zgno_t *vtxIds, const zscalar_t *vals)
76 {
77  int rank = comm->getRank();
78  int nprocs = comm->getSize();
79  comm->barrier();
80  for (int p=0; p < nprocs; p++){
81  if (p == rank){
82  std::cout << rank << ":" << std::endl;
83  for (zlno_t i=0; i < vlen; i++){
84  std::cout << " " << vtxIds[i] << ": " << vals[i] << std::endl;
85  }
86  std::cout.flush();
87  }
88  comm->barrier();
89  }
90  comm->barrier();
91 }
92 
93 template <typename User>
95  Zoltan2::XpetraMultiVectorAdapter<User> &ia, tvector_t &vector, int wdim,
96  zscalar_t **weights, int *strides)
97 {
98  RCP<const Comm<int> > comm = vector.getMap()->getComm();
99  int fail = 0, gfail=0;
100 
101  if (!fail && ia.getNumEntriesPerID() !=1)
102  fail = 42;
103 
104  if (!fail && ia.getNumWeightsPerID() !=wdim)
105  fail = 41;
106 
107  if (!fail && ia.getLocalNumIDs() != vector.getLocalLength())
108  fail = 4;
109 
110  gfail = globalFail(comm, fail);
111 
112  if (!gfail){
113  const zgno_t *vtxIds=NULL;
114  const zscalar_t *vals=NULL;
115  int stride;
116 
117  size_t nvals = ia.getLocalNumIDs();
118  if (nvals != vector.getLocalLength())
119  fail = 8;
120 
121  ia.getIDsView(vtxIds);
122  ia.getEntriesView(vals, stride);
123 
124  if (!fail && stride != 1)
125  fail = 10;
126 
127  gfail = globalFail(comm, fail);
128 
129  if (gfail == 0){
130  printVector(comm, nvals, vtxIds, vals);
131  }
132  }
133 
134  if (!gfail && wdim){
135  const zscalar_t *wgt =NULL;
136  int stride;
137 
138  for (int w=0; !fail && w < wdim; w++){
139  ia.getWeightsView(wgt, stride, w);
140 
141  if (!fail && stride != strides[w])
142  fail = 101;
143 
144  for (size_t v=0; !fail && v < vector.getLocalLength(); v++){
145  if (wgt[v*stride] != weights[w][v*stride])
146  fail=102;
147  }
148  }
149 
150  gfail = globalFail(comm, fail);
151  }
152 
153  return gfail;
154 }
155 
156 int main(int argc, char *argv[])
157 {
158  Teuchos::GlobalMPISession session(&argc, &argv);
159  RCP<const Comm<int> > comm = DefaultComm<int>::getComm();
160  int rank = comm->getRank();
161  int fail = 0, gfail=0;
162  bool aok = true;
163 
164  // Create object that can give us test Tpetra, Xpetra
165  // and Epetra vectors for testing.
166 
167  RCP<UserInputForTests> uinput;
168 
169  try{
170  uinput =
171  rcp(new UserInputForTests(testDataFilePath,std::string("simple"), comm, true));
172  }
173  catch(std::exception &e){
174  aok = false;
175  std::cout << e.what() << std::endl;
176  }
177  TEST_FAIL_AND_EXIT(*comm, aok, "input ", 1);
178 
179  RCP<tvector_t> tV; // original vector (for checking)
180  RCP<tvector_t> newV; // migrated vector
181 
182  tV = rcp(new tvector_t(uinput->getUITpetraCrsGraph()->getRowMap()));
183  tV->randomize();
184  size_t vlen = tV->getLocalLength();
185 
186  // To test migration in the input adapter we need a Solution object.
187 
188  RCP<const Zoltan2::Environment> env = rcp(new Zoltan2::Environment);
189 
190  int nWeights = 1;
191 
193  typedef adapter_t::part_t part_t;
194 
195  part_t *p = new part_t [vlen];
196  memset(p, 0, sizeof(part_t) * vlen);
197  ArrayRCP<part_t> solnParts(p, 0, vlen, true);
198 
199  std::vector<const zscalar_t *> emptyWeights;
200  std::vector<int> emptyStrides;
201 
202  Zoltan2::PartitioningSolution<adapter_t> solution(env, comm, nWeights);
203  solution.setParts(solnParts);
204 
206  // User object is Tpetra::Vector, no weights
207  if (!gfail){
208  RCP<const tvector_t> ctV = rcp_const_cast<const tvector_t>(tV);
209  RCP<adapter_t> tVInput;
210 
211  try {
212  tVInput =
214  emptyWeights, emptyStrides));
215  }
216  catch (std::exception &e){
217  aok = false;
218  std::cout << e.what() << std::endl;
219  }
220  TEST_FAIL_AND_EXIT(*comm, aok, "XpetraMultiVectorAdapter ", 1);
221 
222  if (rank==0){
223  std::cout << "Constructed with ";
224  std::cout << "Tpetra::Vector" << std::endl;
225  }
226 
227  fail = verifyInputAdapter<tvector_t>(*tVInput, *tV, 0, NULL, NULL);
228 
229  gfail = globalFail(comm, fail);
230 
231  if (!gfail){
232  tvector_t *vMigrate = NULL;
233  try{
234  tVInput->applyPartitioningSolution(*tV, vMigrate, solution);
235  newV = rcp(vMigrate);
236  }
237  catch (std::exception &e){
238  fail = 11;
239  }
240 
241  gfail = globalFail(comm, fail);
242 
243  if (!gfail){
244  RCP<const tvector_t> cnewV = rcp_const_cast<const tvector_t>(newV);
245  RCP<Zoltan2::XpetraMultiVectorAdapter<tvector_t> > newInput;
246  try{
247  newInput = rcp(new Zoltan2::XpetraMultiVectorAdapter<tvector_t>(cnewV,
248  emptyWeights, emptyStrides));
249  }
250  catch (std::exception &e){
251  aok = false;
252  std::cout << e.what() << std::endl;
253  }
254  TEST_FAIL_AND_EXIT(*comm, aok, "XpetraMultiVectorAdapter 2 ", 1);
255 
256  if (rank==0){
257  std::cout << "Constructed with ";
258  std::cout << "Tpetra::Vector migrated to proc 0" << std::endl;
259  }
260  fail = verifyInputAdapter<tvector_t>(*newInput, *newV, 0, NULL, NULL);
261  if (fail) fail += 100;
262  gfail = globalFail(comm, fail);
263  }
264  }
265  if (gfail){
266  printFailureCode(comm, fail);
267  }
268  }
269 
271  // User object is Xpetra::Vector
272  if (!gfail){
273  RCP<tvector_t> xtV =
274  rcp(new tvector_t(uinput->getUITpetraCrsGraph()->getRowMap()));
275  xtV->randomize();
276  RCP<xvector_t> xV = Zoltan2::XpetraTraits<tvector_t>::convertToXpetra(xtV);
277  RCP<const xvector_t> cxV = rcp_const_cast<const xvector_t>(xV);
278  RCP<Zoltan2::XpetraMultiVectorAdapter<xvector_t> > xVInput;
279 
280  try {
281  xVInput =
283  emptyWeights, emptyStrides));
284  }
285  catch (std::exception &e){
286  aok = false;
287  std::cout << e.what() << std::endl;
288  }
289  TEST_FAIL_AND_EXIT(*comm, aok, "XpetraMultiVectorAdapter 3 ", 1);
290 
291  if (rank==0){
292  std::cout << "Constructed with ";
293  std::cout << "Xpetra::Vector" << std::endl;
294  }
295  fail = verifyInputAdapter<xvector_t>(*xVInput, *tV, 0, NULL, NULL);
296 
297  gfail = globalFail(comm, fail);
298 
299  if (!gfail){
300  xvector_t *vMigrate =NULL;
301  try{
302  xVInput->applyPartitioningSolution(*xV, vMigrate, solution);
303  }
304  catch (std::exception &e){
305  fail = 11;
306  }
307 
308  gfail = globalFail(comm, fail);
309 
310  if (!gfail){
311  RCP<const xvector_t> cnewV(vMigrate);
312  RCP<Zoltan2::XpetraMultiVectorAdapter<xvector_t> > newInput;
313  try{
314  newInput =
316  emptyWeights, emptyStrides));
317  }
318  catch (std::exception &e){
319  aok = false;
320  std::cout << e.what() << std::endl;
321  }
322  TEST_FAIL_AND_EXIT(*comm, aok, "XpetraMultiVectorAdapter 4 ", 1);
323 
324  if (rank==0){
325  std::cout << "Constructed with ";
326  std::cout << "Xpetra::Vector migrated to proc 0" << std::endl;
327  }
328  fail = verifyInputAdapter<xvector_t>(*newInput, *newV, 0, NULL, NULL);
329  if (fail) fail += 100;
330  gfail = globalFail(comm, fail);
331  }
332  }
333  if (gfail){
334  printFailureCode(comm, fail);
335  }
336  }
337 
338 #ifdef HAVE_EPETRA_DATA_TYPES
339  // User object is Epetra_Vector
341  typedef Epetra_Vector evector_t;
342  if (!gfail){
343  RCP<evector_t> eV =
344  rcp(new Epetra_Vector(uinput->getUIEpetraCrsGraph()->RowMap()));
345  eV->Random();
346  RCP<const evector_t> ceV = rcp_const_cast<const evector_t>(eV);
347  RCP<Zoltan2::XpetraMultiVectorAdapter<evector_t> > eVInput;
348 
349  try {
350  eVInput =
352  emptyWeights, emptyStrides));
353  }
354  catch (std::exception &e){
355  aok = false;
356  std::cout << e.what() << std::endl;
357  }
358  TEST_FAIL_AND_EXIT(*comm, aok, "XpetraMultiVectorAdapter 5 ", 1);
359 
360  if (rank==0){
361  std::cout << "Constructed with ";
362  std::cout << "Epetra_Vector" << std::endl;
363  }
364  fail = verifyInputAdapter<evector_t>(*eVInput, *tV, 0, NULL, NULL);
365 
366  gfail = globalFail(comm, fail);
367 
368  if (!gfail){
369  evector_t *vMigrate =NULL;
370  try{
371  eVInput->applyPartitioningSolution(*eV, vMigrate, solution);
372  }
373  catch (std::exception &e){
374  fail = 11;
375  }
376 
377  gfail = globalFail(comm, fail);
378 
379  if (!gfail){
380  RCP<const evector_t> cnewV(vMigrate, true);
381  RCP<Zoltan2::XpetraMultiVectorAdapter<evector_t> > newInput;
382  try{
383  newInput =
385  emptyWeights, emptyStrides));
386  }
387  catch (std::exception &e){
388  aok = false;
389  std::cout << e.what() << std::endl;
390  }
391  TEST_FAIL_AND_EXIT(*comm, aok, "XpetraMultiVectorAdapter 6 ", 1);
392 
393  if (rank==0){
394  std::cout << "Constructed with ";
395  std::cout << "Epetra_Vector migrated to proc 0" << std::endl;
396  }
397  fail = verifyInputAdapter<evector_t>(*newInput, *newV, 0, NULL, NULL);
398  if (fail) fail += 100;
399  gfail = globalFail(comm, fail);
400  }
401  }
402  if (gfail){
403  printFailureCode(comm, fail);
404  }
405  }
406 #endif
407 
409  // DONE
410 
411  if (rank==0)
412  std::cout << "PASS" << std::endl;
413 }
int globalFail(const RCP< const Comm< int > > &comm, int fail)
double zscalar_t
int main(int argc, char *argv[])
#define TEST_FAIL_AND_EXIT(comm, ok, s, code)
Tpetra::Vector< zscalar_t, zlno_t, zgno_t, znode_t > tvector_t
static ArrayRCP< ArrayRCP< zscalar_t > > weights
Tpetra::MultiVector< zscalar_t, zlno_t, zgno_t, znode_t > tvector_t
int zlno_t
common code used by tests
static RCP< User > convertToXpetra(const RCP< User > &a)
Convert the object to its Xpetra wrapped version.
Defines the XpetraMultiVectorAdapter.
int getNumEntriesPerID() const
Return the number of vectors (typically one).
int verifyInputAdapter(Zoltan2::XpetraMultiVectorAdapter< User > &ia, tvector_t &vector, int wdim, zscalar_t **weights, int *strides)
dictionary vals
Definition: xml2dox.py:186
Xpetra::Vector< zscalar_t, zlno_t, zgno_t, znode_t > xvector_t
A PartitioningSolution is a solution to a partitioning problem.
void printVector(RCP< const Comm< int > > &comm, zlno_t vlen, const zgno_t *vtxIds, const zscalar_t *vals)
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
void setParts(ArrayRCP< part_t > &partList)
The algorithm uses setParts to set the solution.
int zgno_t
void printFailureCode(const RCP< const Comm< int > > &comm, int fail)
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(".")