Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Machine.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 // Testing Zoltan2::MachineRepresentation
47 
49 #include <Zoltan2_TestHelpers.hpp>
50 #include <Teuchos_DefaultComm.hpp>
51 
52 template <typename nCoord_t, typename part_t>
53 int checkAllCoords(const Teuchos::Comm<int> &comm,
55 {
56  // Verify that getAllMachineCoordinatesView returns the same values
57  // as individual calls by rank.
58  // Verify that returned coordinates lie within the extent of the coordinates.
59 
60  int fail = 0;
61  const int failval = 100000000;
62 
63  int np = comm.getSize();
64  int me = comm.getRank();
65 
66  int dim = mach.getMachineDim();
67  int *nxyz = new int[dim];
68 
69  nCoord_t *xyz = new nCoord_t[dim];
70 
71  nCoord_t **allCoords;
72 
73  bool haveExtent = mach.getMachineExtent(nxyz);
74 
75  if (mach.getAllMachineCoordinatesView(allCoords)) {
76 
77  // Check all ranks
78  for (int i = 0; i < np; i++) {
79  if (mach.getMachineCoordinate(i, xyz)) {
80  if (me == 0) std::cout << "RANK " << i << " COORD ";
81  for (int d = 0; d < dim; d++) {
82  if (me == 0) std::cout << " " << xyz[d];
83  if (xyz[d] != allCoords[d][i]) fail = failval;
84  if (haveExtent && (xyz[d] < 0 || xyz[d] >= nxyz[d])) fail = failval;
85  }
86  if (me == 0) std::cout << std::endl;
87  }
88  else {
89  std::cout << "Rank " << me
90  << " getMachineCoordinate failed " << std::endl;
91  fail = failval; // getMachineCoordinate failed
92  }
93  }
94  if (fail == failval) {
95  std::cout << "Rank " << me
96  << " Invalid coordinates from getAllMachineCoordinatesView or "
97  << "getMachineCoordinate" << std::endl;
98  }
99 
100  // Check my rank
101  if (mach.getMyMachineCoordinate(xyz)) {
102  for (int d = 0; d < dim; d++)
103  if (xyz[d] != allCoords[d][me]) fail = failval;
104  }
105  else {
106  fail = failval; // getMyMachineCoordinate failed
107  std::cout << "Rank " << me
108  << "getMyMachineCoordinates failed" << std::endl;
109  }
110  }
111  else {
112  fail = failval; // couldn't retrieve coordinates
113  std::cout << "Rank " << me
114  << "couldn't retrieve coordinates with "
115  << "getAllMachineCoordinatesView" << std::endl;
116  }
117 
118  delete [] xyz;
119  delete [] nxyz;
120 
121  return fail;
122 }
123 
125 int checkErrorCode(const Teuchos::Comm<int> &comm, int code)
126 {
127  int rank = comm.getRank();
128  if (code > 0)
129  std::cerr << "Proc " << rank << " error: " << code << std::endl;
130  comm.barrier();
131 
132  // Will return 1 if any process has a non-zero code
133  TEST_FAIL_AND_RETURN_VALUE(comm, code==0, "TEST FAILED", 1);
134 
135  return 0;
136 }
137 
139 
140 int main(int narg, char *arg[])
141 {
142  Tpetra::ScopeGuard tscope(&narg, &arg);
143  Teuchos::RCP<const Teuchos::Comm<int> > comm = Tpetra::getDefaultComm();
144 
145  int me = comm->getRank();
146  int np = comm->getSize();
147  //char *name = "node0"; Causes compiler warnings. Do weirdness.
148  char node0[6] = {'n', 'o', 'd', 'e', '0', '\0'};
149  char *name = node0;
150  int fail = 0;
151 
152  typedef zlno_t ncoord_t;
153  typedef zlno_t part_t;
154 
155  Teuchos::ParameterList pl;
156 
158 
159  // Tests that all machines should pass
160  if (mach.getNumRanks() != np) fail += 1;
161 
162  if (mach.hasMachineCoordinates())
163  fail += checkAllCoords<ncoord_t,part_t>(*comm, mach);
164 
165  if (checkErrorCode(*comm, fail))
166  return 1;
167 
168 #if defined(HAVE_ZOLTAN2_LDMS)
169  { // Add tests specific to LDMS
170  if (me == 0 ) std::cout << "LDMS Topology" << std::endl;
171  if (checkErrorCode(*comm, fail))
172  return 1;
173  }
174 #elif defined(HAVE_ZOLTAN2_RCALIB)
175  {
176  if (me == 0 ) std::cout << "RCALIB Topology" << std::endl;
177  // Add tests specific to RCA
178  if (checkErrorCode(*comm, fail))
179  return 1;
180  }
181 #elif defined(HAVE_ZOLTAN2_TOPOMANAGER)
182  {
183  if (me == 0 ) std::cout << "TOPOMANAGER Topology" << std::endl;
184  // Add tests specific to TopoMgr
185  if (checkErrorCode(*comm, fail))
186  return 1;
187  }
188 #elif defined(HAVE_ZOLTAN2_BGQTEST)
189  {
190  if (me == 0 ) std::cout << "BGQTEST Topology" << std::endl;
191  // Add tests specific to BGQ
192  if (checkErrorCode(*comm, fail))
193  return 1;
194  }
195 #else
196  {
197  if (me == 0 ) std::cout << "TEST Topology" << std::endl;
198  // Tests specific to MachineForTesting
199  if (mach.getMachineDim() != 3) {
200  std::cout << "Error: Dimension != 3" << std::endl;
201  fail += 10;
202  }
203 
204  int nxyz[3];
205  if (!mach.getMachineExtent(nxyz)) {
206  std::cout << "Error: getMachineExtent failed" << std::endl;
207  fail += 100;
208  }
209  if (nxyz[0] != np || nxyz[1] != 2*np || nxyz[2] != 3*np) {
210  // Depends on ficticious extent in Zoltan2_MachineForTesting.hpp
211  std::cout << "Error: incorrect MachineExtent" << std::endl;
212  fail += 1000;
213  }
214 
215  ncoord_t xyz[3];
216 
217  // Depends on ficticious coordinates in Zoltan2_MachineForTesting.hpp
218  ncoord_t xyz_expected[3] = {me, np, np+1};
219 
220  if (!mach.getMyMachineCoordinate(xyz)) {
221  std::cout << "Error: getMyMachineCoordinate failed" << std::endl;
222  fail += 1000;
223  }
224 
225  if ((xyz[0] != xyz_expected[0]) ||
226  (xyz[1] != xyz_expected[1]) ||
227  (xyz[2] != xyz_expected[2])) {
228  std::cout << "Error: incorrect MyMachineCoordinate" << std::endl;
229  fail += 10000;
230  }
231 
232  // MachineForTesting cannot retrieve coords by node name
233  if (mach.getMachineCoordinate(name, xyz)) {
234  std::cout << "Error: getMachineCoordinate failed" << std::endl;
235  fail += 10000000;
236  }
237 
238  if (checkErrorCode(*comm, fail))
239  return 1;
240  }
241 #endif
242 
243  if (me == 0) std::cout << "PASS" << std::endl;
244 
245  return 0;
246 }
int main(int narg, char *arg[])
int zlno_t
common code used by tests
int checkErrorCode(Teuchos::RCP< const Teuchos::Comm< int > > &comm, int code)
Definition: Environment.cpp:63
bool getMachineCoordinate(const int rank, pcoord_t *xyz) const
getCoordinate function set the machine coordinate xyz of any rank process return true if coordinates ...
SparseMatrixAdapter_t::part_t part_t
int getMachineDim() const
returns the dimension (number of coords per node) in the machine
bool getAllMachineCoordinatesView(pcoord_t **&allCoords) const
getProcDim function set the coordinates of all ranks allCoords[i][j], i=0,...,getMachineDim(), j=0,...,getNumRanks(), is the i-th dimensional coordinate for rank j. return true if coordinates are available for all ranks
int getNumRanks() const
return the number of ranks.
MachineRepresentation Class Base class for representing machine coordinates, networks, etc.
static const std::string fail
#define TEST_FAIL_AND_RETURN_VALUE(comm, ok, s, rc)
bool hasMachineCoordinates() const
indicates whether or not the machine has coordinates
bool getMyMachineCoordinate(pcoord_t *xyz) const
getMyCoordinate function set the machine coordinate xyz of the current process return true if current...
int checkAllCoords(const Teuchos::Comm< int > &comm, const Zoltan2::MachineRepresentation< nCoord_t, part_t > &mach)
Definition: Machine.cpp:53
bool getMachineExtent(int *nxyz) const
sets the number of unique coordinates in each machine dimension