Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
TpetraRowGraphInputKokkos.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 // Basic testing of Zoltan2::TpetraRowGraphAdapter
52 #include <Zoltan2_InputTraits.hpp>
53 #include <Zoltan2_TestHelpers.hpp>
56 
57 #include <Teuchos_Comm.hpp>
58 #include <Teuchos_CommHelpers.hpp>
59 #include <Teuchos_DefaultComm.hpp>
60 #include <Teuchos_RCP.hpp>
61 #include <cstdlib>
62 #include <stdexcept>
63 
64 using Teuchos::Comm;
65 using Teuchos::RCP;
66 using Teuchos::rcp;
67 using Teuchos::rcp_const_cast;
68 using Teuchos::rcp_dynamic_cast;
69 
70 using ztcrsgraph_t = Tpetra::CrsGraph<zlno_t, zgno_t, znode_t>;
71 using ztrowgraph_t = Tpetra::RowGraph<zlno_t, zgno_t, znode_t>;
73 using device_t = typename node_t::device_type;
76 using execspace_t =
77  typename rowAdapter_t::ConstWeightsHostView1D::execution_space;
78 
79 template <typename offset_t>
80 void printGraph(RCP<const Comm<int>> &comm, zlno_t nvtx, const zgno_t *vtxIds,
81  const offset_t *offsets, const zgno_t *edgeIds) {
82  int rank = comm->getRank();
83  int nprocs = comm->getSize();
84  comm->barrier();
85  for (int p = 0; p < nprocs; p++) {
86  if (p == rank) {
87  std::cout << rank << ":" << std::endl;
88  for (zlno_t i = 0; i < nvtx; i++) {
89  std::cout << " vertex " << vtxIds[i] << ": ";
90  for (offset_t j = offsets[i]; j < offsets[i + 1]; j++) {
91  std::cout << edgeIds[j] << " ";
92  }
93  std::cout << std::endl;
94  }
95  std::cout.flush();
96  }
97  comm->barrier();
98  }
99  comm->barrier();
100 }
101 
102 template <typename adapter_t, typename graph_t>
103 void TestGraphIds(adapter_t &ia, graph_t &graph) {
104 
105  using idsHost_t = typename adapter_t::ConstIdsHostView;
106  using offsetsHost_t = typename adapter_t::ConstOffsetsHostView;
107  using localInds_t =
108  typename adapter_t::user_t::nonconst_local_inds_host_view_type;
109 
110  const auto nvtx = graph.getLocalNumRows();
111  const auto nedges = graph.getLocalNumEntries();
112  const auto maxNumEntries = graph.getLocalMaxNumRowEntries();
113 
114  typename adapter_t::Base::ConstIdsHostView adjIdsHost_("adjIdsHost_", nedges);
115  typename adapter_t::Base::ConstOffsetsHostView offsHost_("offsHost_",
116  nvtx + 1);
117 
118  localInds_t nbors("nbors", maxNumEntries);
119 
120  for (size_t v = 0; v < nvtx; v++) {
121  size_t numColInds = 0;
122  graph.getLocalRowCopy(v, nbors, numColInds);
123 
124  offsHost_(v + 1) = offsHost_(v) + numColInds;
125  for (size_t e = offsHost_(v), i = 0; e < offsHost_(v + 1); e++) {
126  adjIdsHost_(e) = graph.getColMap()->getGlobalElement(nbors(i++));
127  }
128  }
129 
130  idsHost_t vtxIdsHost;
131  ia.getVertexIDsHostView(vtxIdsHost);
132 
133  const auto graphIDS = graph.getRowMap()->getLocalElementList();
134 
135  Z2_TEST_COMPARE_ARRAYS(graphIDS, vtxIdsHost);
136 
137  idsHost_t adjIdsHost;
138  offsetsHost_t offsetsHost;
139  ia.getEdgesHostView(offsetsHost, adjIdsHost);
140 
141  Z2_TEST_COMPARE_ARRAYS(adjIdsHost_, adjIdsHost);
142  Z2_TEST_COMPARE_ARRAYS(offsHost_, offsetsHost);
143 }
144 
145 template <typename adapter_t, typename graph_t>
146 void verifyInputAdapter(adapter_t &ia, graph_t &graph) {
147  using idsDevice_t = typename adapter_t::ConstIdsDeviceView;
148  using idsHost_t = typename adapter_t::ConstIdsHostView;
149  using offsetsDevice_t = typename adapter_t::ConstOffsetsDeviceView;
150  using offsetsHost_t = typename adapter_t::ConstOffsetsHostView;
151  using weightsDevice_t = typename adapter_t::WeightsDeviceView1D;
152  using weightsHost_t = typename adapter_t::WeightsHostView1D;
153 
154  const auto nVtx = ia.getLocalNumIDs();
155 
156  Z2_TEST_EQUALITY(ia.getLocalNumVertices(), graph.getLocalNumRows());
157  Z2_TEST_EQUALITY(ia.getLocalNumEdges(), graph.getLocalNumEntries());
158 
162 
163  idsDevice_t vtxIdsDevice;
164  ia.getVertexIDsDeviceView(vtxIdsDevice);
165  idsHost_t vtxIdsHost;
166  ia.getVertexIDsHostView(vtxIdsHost);
167 
168  Z2_TEST_DEVICE_HOST_VIEWS(vtxIdsDevice, vtxIdsHost);
169 
173 
174  idsDevice_t adjIdsDevice;
175  offsetsDevice_t offsetsDevice;
176 
177  ia.getEdgesDeviceView(offsetsDevice, adjIdsDevice);
178 
179  idsHost_t adjIdsHost;
180  offsetsHost_t offsetsHost;
181  ia.getEdgesHostView(offsetsHost, adjIdsHost);
182 
183  Z2_TEST_DEVICE_HOST_VIEWS(adjIdsDevice, adjIdsHost);
184  Z2_TEST_DEVICE_HOST_VIEWS(offsetsDevice, offsetsHost);
185 
189  Z2_TEST_THROW(ia.setVertexWeightsDevice(
190  typename adapter_t::ConstWeightsDeviceView1D{}, 50),
191  std::runtime_error);
192 
193  weightsDevice_t wgts0("wgts0", nVtx);
194  Kokkos::parallel_for(
195  nVtx, KOKKOS_LAMBDA(const int idx) { wgts0(idx) = idx * 2; });
196  Kokkos::fence();
197 
198  Z2_TEST_NOTHROW(ia.setVertexWeightsDevice(wgts0, 0));
199 
200  // Don't reuse the same View, since we don't copy the values,
201  // we just assign the View (increase use count)
202  weightsDevice_t wgts1("wgts1", nVtx);
203  Kokkos::parallel_for(
204  nVtx, KOKKOS_LAMBDA(const int idx) { wgts1(idx) = idx * 3; });
205 
206  Z2_TEST_NOTHROW(ia.setVertexWeightsDevice(wgts1, 1));
207 
211  {
212  weightsDevice_t weightsDevice;
213  Z2_TEST_NOTHROW(ia.getVertexWeightsDeviceView(weightsDevice, 0));
214 
215  weightsHost_t weightsHost;
216  Z2_TEST_NOTHROW(ia.getVertexWeightsHostView(weightsHost, 0));
217 
218  Z2_TEST_DEVICE_HOST_VIEWS(weightsDevice, weightsHost);
219 
220  Z2_TEST_DEVICE_HOST_VIEWS(wgts0, weightsHost);
221  }
222  {
223  weightsDevice_t weightsDevice;
224  Z2_TEST_NOTHROW(ia.getVertexWeightsDeviceView(weightsDevice, 1));
225 
226  weightsHost_t weightsHost;
227  Z2_TEST_NOTHROW(ia.getVertexWeightsHostView(weightsHost, 1));
228 
229  Z2_TEST_DEVICE_HOST_VIEWS(weightsDevice, weightsHost);
230 
231  Z2_TEST_DEVICE_HOST_VIEWS(wgts1, weightsHost);
232  }
233  {
234  weightsDevice_t wgtsDevice;
235  Z2_TEST_THROW(ia.getVertexWeightsDeviceView(wgtsDevice, 2),
236  std::runtime_error);
237 
238  weightsHost_t wgtsHost;
239  Z2_TEST_THROW(ia.getVertexWeightsHostView(wgtsHost, 2), std::runtime_error);
240  }
241 
242  TestGraphIds(ia, graph);
243 }
244 
245 int main(int narg, char *arg[]) {
247  using rowPart_t = rowAdapter_t::part_t;
248 
250  using crsPart_t = crsAdapter_t::part_t;
251 
252  Tpetra::ScopeGuard tscope(&narg, &arg);
253  const auto comm = Tpetra::getDefaultComm();
254 
255  try {
256  Teuchos::ParameterList params;
257  params.set("input file", "simple");
258  params.set("file type", "Chaco");
259 
260  auto uinput = rcp(new UserInputForTests(params, comm));
261 
262  // Input crs graph and row graph cast from it.
263  const auto crsGraph = uinput->getUITpetraCrsGraph();
264  const auto rowGraph = rcp_dynamic_cast<ztrowgraph_t>(crsGraph);
265 
266  const auto nvtx = rowGraph->getLocalNumRows();
267 
268  // To test migration in the input adapter we need a Solution object.
269  const auto env = rcp(new Zoltan2::Environment(comm));
270 
271  const int nWeights = 2;
272 
274  // User object is Tpetra::CrsGraph
276  {
277  PrintFromRoot("Input adapter for Tpetra::CrsGraph");
278 
279  auto tpetraCrsGraphInput = rcp(new crsAdapter_t(crsGraph, nWeights));
280 
281  verifyInputAdapter(*tpetraCrsGraphInput, *crsGraph);
282 
283  ztcrsgraph_t *mMigrate = NULL;
284  crsPart_t *p = new crsPart_t[nvtx];
285  memset(p, 0, sizeof(crsPart_t) * nvtx);
286  ArrayRCP<crsPart_t> solnParts(p, 0, nvtx, true);
287 
288  crsSoln_t solution(env, comm, nWeights);
289  solution.setParts(solnParts);
290  tpetraCrsGraphInput->applyPartitioningSolution(*crsGraph, mMigrate,
291  solution);
292  const auto newG = rcp(mMigrate);
293 
294  auto cnewG = rcp_const_cast<const ztcrsgraph_t>(newG);
295  auto newInput = rcp(new crsAdapter_t(cnewG, nWeights));
296 
297  PrintFromRoot("Input adapter for Tpetra::RowGraph migrated to proc 0");
298 
299  verifyInputAdapter(*newInput, *newG);
300  }
301 
303  // User object is Tpetra::RowGraph
305  {
306  PrintFromRoot("Input adapter for Tpetra::RowGraph");
307 
308  auto tpetraRowGraphInput = rcp(new rowAdapter_t(rowGraph, nWeights));
309 
310  verifyInputAdapter(*tpetraRowGraphInput, *crsGraph);
311 
312  rowPart_t *p = new rowPart_t[nvtx];
313  memset(p, 0, sizeof(rowPart_t) * nvtx);
314  ArrayRCP<rowPart_t> solnParts(p, 0, nvtx, true);
315 
316  rowSoln_t solution(env, comm, nWeights);
317  solution.setParts(solnParts);
318 
319  ztrowgraph_t *mMigrate = NULL;
320  tpetraRowGraphInput->applyPartitioningSolution(*crsGraph, mMigrate,
321  solution);
322  const auto newG = rcp(mMigrate);
323 
324  auto cnewG = rcp_const_cast<const ztrowgraph_t>(newG);
325  auto newInput = rcp(new rowAdapter_t(cnewG, nWeights));
326 
327  PrintFromRoot("Input adapter for Tpetra::RowGraph migrated to proc 0");
328 
329  verifyInputAdapter(*newInput, *newG);
330  }
331  } catch (std::exception &e) {
332  std::cout << e.what() << std::endl;
333  return EXIT_FAILURE;
334  }
335 
336  PrintFromRoot("PASS");
337 }
void verifyInputAdapter(adapter_t &ia, matrix_t &matrix)
void TestGraphIds(adapter_t &ia, graph_t &graph)
void PrintFromRoot(const std::string &message)
typename crsAdapter_t::ConstWeightsHostView1D::execution_space execspace_t
Defines TpetraRowGraphAdapter class.
typename node_t::device_type device_t
Defines TpetraCrsGraphAdapter class.
Provides access for Zoltan2 to Tpetra::CrsMatrix data.
typename Zoltan2::InputTraits< ztcrsmatrix_t >::node_t node_t
Provides access for Zoltan2 to Tpetra::CrsGraph data.
int main(int narg, char **arg)
Definition: coloring1.cpp:199
common code used by tests
typename InputTraits< User >::part_t part_t
#define Z2_TEST_COMPARE_ARRAYS(val1, val2)
void printGraph(RCP< const Comm< int > > &comm, zlno_t nvtx, const zgno_t *vtxIds, const offset_t *offsets, const zgno_t *edgeIds)
Tpetra::RowGraph< zlno_t, zgno_t, znode_t > ztrowgraph_t
A PartitioningSolution is a solution to a partitioning problem.
#define Z2_TEST_DEVICE_HOST_VIEWS(deviceView, hostView)
#define Z2_TEST_EQUALITY(val1, val2)
Tpetra::CrsGraph< zlno_t, zgno_t, znode_t > ztcrsgraph_t
Traits for application input objects.
The user parameters, debug, timing and memory profiling output objects, and error checking methods...
Zoltan2::TpetraCrsMatrixAdapter< ztcrsmatrix_t > crsAdapter_t
Tpetra::Map::local_ordinal_type zlno_t
default_node_t node_t
The Kokkos node type. This is only meaningful for users of Tpetra objects.
#define Z2_TEST_THROW(code, ExceptType)
Tpetra::Map::global_ordinal_type zgno_t
#define Z2_TEST_NOTHROW(code)
Zoltan2::TpetraRowGraphAdapter< ztrowgraph_t > rowAdapter_t
Provides access for Zoltan2 to Tpetra::RowGraph data.