Zoltan2
Loading...
Searching...
No Matches
TpetraRowGraphInputKokkos.cpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Zoltan2: A package of combinatorial algorithms for scientific computing
4//
5// Copyright 2012 NTESS and the Zoltan2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10//
11// Basic testing of Zoltan2::TpetraRowGraphAdapter
21
22#include <Teuchos_Comm.hpp>
23#include <Teuchos_CommHelpers.hpp>
24#include <Teuchos_DefaultComm.hpp>
25#include <Teuchos_RCP.hpp>
26#include <cstdlib>
27#include <stdexcept>
28
29using Teuchos::Comm;
30using Teuchos::RCP;
31using Teuchos::rcp;
32using Teuchos::rcp_const_cast;
33using Teuchos::rcp_dynamic_cast;
34
35using ztcrsgraph_t = Tpetra::CrsGraph<zlno_t, zgno_t, znode_t>;
36using ztrowgraph_t = Tpetra::RowGraph<zlno_t, zgno_t, znode_t>;
38using device_t = typename node_t::device_type;
42 typename rowAdapter_t::ConstWeightsHostView1D::execution_space;
43
44template <typename offset_t>
45void printGraph(RCP<const Comm<int>> &comm, zlno_t nvtx, const zgno_t *vtxIds,
46 const offset_t *offsets, const zgno_t *edgeIds) {
47 int rank = comm->getRank();
48 int nprocs = comm->getSize();
49 comm->barrier();
50 for (int p = 0; p < nprocs; p++) {
51 if (p == rank) {
52 std::cout << rank << ":" << std::endl;
53 for (zlno_t i = 0; i < nvtx; i++) {
54 std::cout << " vertex " << vtxIds[i] << ": ";
55 for (offset_t j = offsets[i]; j < offsets[i + 1]; j++) {
56 std::cout << edgeIds[j] << " ";
57 }
58 std::cout << std::endl;
59 }
60 std::cout.flush();
61 }
62 comm->barrier();
63 }
64 comm->barrier();
65}
66
67template <typename adapter_t, typename graph_t>
68void TestGraphIds(adapter_t &ia, graph_t &graph) {
69
70 using idsHost_t = typename adapter_t::ConstIdsHostView;
71 using offsetsHost_t = typename adapter_t::ConstOffsetsHostView;
72 using localInds_t =
73 typename adapter_t::user_t::nonconst_local_inds_host_view_type;
74
75 const auto nvtx = graph.getLocalNumRows();
76 const auto nedges = graph.getLocalNumEntries();
77 const auto maxNumEntries = graph.getLocalMaxNumRowEntries();
78
79 typename adapter_t::Base::ConstIdsHostView adjIdsHost_("adjIdsHost_", nedges);
80 typename adapter_t::Base::ConstOffsetsHostView offsHost_("offsHost_",
81 nvtx + 1);
82
83 localInds_t nbors("nbors", maxNumEntries);
84
85 for (size_t v = 0; v < nvtx; v++) {
86 size_t numColInds = 0;
87 graph.getLocalRowCopy(v, nbors, numColInds);
88
89 offsHost_(v + 1) = offsHost_(v) + numColInds;
90 for (size_t e = offsHost_(v), i = 0; e < offsHost_(v + 1); e++) {
91 adjIdsHost_(e) = graph.getColMap()->getGlobalElement(nbors(i++));
92 }
93 }
94
95 idsHost_t vtxIdsHost;
96 ia.getVertexIDsHostView(vtxIdsHost);
97
98 const auto graphIDS = graph.getRowMap()->getLocalElementList();
99
100 Z2_TEST_COMPARE_ARRAYS(graphIDS, vtxIdsHost);
101
102 idsHost_t adjIdsHost;
103 offsetsHost_t offsetsHost;
104 ia.getEdgesHostView(offsetsHost, adjIdsHost);
105
106 Z2_TEST_COMPARE_ARRAYS(adjIdsHost_, adjIdsHost);
107 Z2_TEST_COMPARE_ARRAYS(offsHost_, offsetsHost);
108}
109
110template <typename adapter_t, typename graph_t>
111void verifyInputAdapter(adapter_t &ia, graph_t &graph) {
112 using idsDevice_t = typename adapter_t::ConstIdsDeviceView;
113 using idsHost_t = typename adapter_t::ConstIdsHostView;
114 using offsetsDevice_t = typename adapter_t::ConstOffsetsDeviceView;
115 using offsetsHost_t = typename adapter_t::ConstOffsetsHostView;
116 using weightsDevice_t = typename adapter_t::WeightsDeviceView1D;
117 using weightsHost_t = typename adapter_t::WeightsHostView1D;
118
119 const auto nVtx = ia.getLocalNumIDs();
120
121 Z2_TEST_EQUALITY(ia.getLocalNumVertices(), graph.getLocalNumRows());
122 Z2_TEST_EQUALITY(ia.getLocalNumEdges(), graph.getLocalNumEntries());
123
127
128 idsDevice_t vtxIdsDevice;
129 ia.getVertexIDsDeviceView(vtxIdsDevice);
130 idsHost_t vtxIdsHost;
131 ia.getVertexIDsHostView(vtxIdsHost);
132
133 Z2_TEST_DEVICE_HOST_VIEWS(vtxIdsDevice, vtxIdsHost);
134
138
139 idsDevice_t adjIdsDevice;
140 offsetsDevice_t offsetsDevice;
141
142 ia.getEdgesDeviceView(offsetsDevice, adjIdsDevice);
143
144 idsHost_t adjIdsHost;
145 offsetsHost_t offsetsHost;
146 ia.getEdgesHostView(offsetsHost, adjIdsHost);
147
148 Z2_TEST_DEVICE_HOST_VIEWS(adjIdsDevice, adjIdsHost);
149 Z2_TEST_DEVICE_HOST_VIEWS(offsetsDevice, offsetsHost);
150
154 Z2_TEST_THROW(ia.setVertexWeightsDevice(
155 typename adapter_t::ConstWeightsDeviceView1D{}, 50),
156 std::runtime_error);
157
158 weightsDevice_t wgts0("wgts0", nVtx);
159 Kokkos::parallel_for(
160 nVtx, KOKKOS_LAMBDA(const int idx) { wgts0(idx) = idx * 2; });
161 Kokkos::fence();
162
163 Z2_TEST_NOTHROW(ia.setVertexWeightsDevice(wgts0, 0));
164
165 // Don't reuse the same View, since we don't copy the values,
166 // we just assign the View (increase use count)
167 weightsDevice_t wgts1("wgts1", nVtx);
168 Kokkos::parallel_for(
169 nVtx, KOKKOS_LAMBDA(const int idx) { wgts1(idx) = idx * 3; });
170
171 Z2_TEST_NOTHROW(ia.setVertexWeightsDevice(wgts1, 1));
172
176 {
177 weightsDevice_t weightsDevice;
178 Z2_TEST_NOTHROW(ia.getVertexWeightsDeviceView(weightsDevice, 0));
179
180 weightsHost_t weightsHost;
181 Z2_TEST_NOTHROW(ia.getVertexWeightsHostView(weightsHost, 0));
182
183 Z2_TEST_DEVICE_HOST_VIEWS(weightsDevice, weightsHost);
184
185 Z2_TEST_DEVICE_HOST_VIEWS(wgts0, weightsHost);
186 }
187 {
188 weightsDevice_t weightsDevice;
189 Z2_TEST_NOTHROW(ia.getVertexWeightsDeviceView(weightsDevice, 1));
190
191 weightsHost_t weightsHost;
192 Z2_TEST_NOTHROW(ia.getVertexWeightsHostView(weightsHost, 1));
193
194 Z2_TEST_DEVICE_HOST_VIEWS(weightsDevice, weightsHost);
195
196 Z2_TEST_DEVICE_HOST_VIEWS(wgts1, weightsHost);
197 }
198 {
199 weightsDevice_t wgtsDevice;
200 Z2_TEST_THROW(ia.getVertexWeightsDeviceView(wgtsDevice, 2),
201 std::runtime_error);
202
203 weightsHost_t wgtsHost;
204 Z2_TEST_THROW(ia.getVertexWeightsHostView(wgtsHost, 2), std::runtime_error);
205 }
206
207 TestGraphIds(ia, graph);
208}
209
210int main(int narg, char *arg[]) {
212 using rowPart_t = rowAdapter_t::part_t;
213
215 using crsPart_t = crsAdapter_t::part_t;
216
217 Tpetra::ScopeGuard tscope(&narg, &arg);
218 const auto comm = Tpetra::getDefaultComm();
219
220 try {
221 Teuchos::ParameterList params;
222 params.set("input file", "simple");
223 params.set("file type", "Chaco");
224
225 auto uinput = rcp(new UserInputForTests(params, comm));
226
227 // Input crs graph and row graph cast from it.
228 const auto crsGraph = uinput->getUITpetraCrsGraph();
229 const auto rowGraph = rcp_dynamic_cast<ztrowgraph_t>(crsGraph);
230
231 const auto nvtx = rowGraph->getLocalNumRows();
232
233 // To test migration in the input adapter we need a Solution object.
234 const auto env = rcp(new Zoltan2::Environment(comm));
235
236 const int nWeights = 2;
237
239 // User object is Tpetra::CrsGraph
241 {
242 PrintFromRoot("Input adapter for Tpetra::CrsGraph");
243
244 auto tpetraCrsGraphInput = rcp(new crsAdapter_t(crsGraph, nWeights));
245
246 verifyInputAdapter(*tpetraCrsGraphInput, *crsGraph);
247
248 ztcrsgraph_t *mMigrate = NULL;
249 crsPart_t *p = new crsPart_t[nvtx];
250 memset(p, 0, sizeof(crsPart_t) * nvtx);
251 ArrayRCP<crsPart_t> solnParts(p, 0, nvtx, true);
252
253 crsSoln_t solution(env, comm, nWeights);
254 solution.setParts(solnParts);
255 tpetraCrsGraphInput->applyPartitioningSolution(*crsGraph, mMigrate,
256 solution);
257 const auto newG = rcp(mMigrate);
258
259 auto cnewG = rcp_const_cast<const ztcrsgraph_t>(newG);
260 auto newInput = rcp(new crsAdapter_t(cnewG, nWeights));
261
262 PrintFromRoot("Input adapter for Tpetra::RowGraph migrated to proc 0");
263
264 verifyInputAdapter(*newInput, *newG);
265 }
266
268 // User object is Tpetra::RowGraph
270 {
271 PrintFromRoot("Input adapter for Tpetra::RowGraph");
272
273 auto tpetraRowGraphInput = rcp(new rowAdapter_t(rowGraph, nWeights));
274
275 verifyInputAdapter(*tpetraRowGraphInput, *crsGraph);
276
277 rowPart_t *p = new rowPart_t[nvtx];
278 memset(p, 0, sizeof(rowPart_t) * nvtx);
279 ArrayRCP<rowPart_t> solnParts(p, 0, nvtx, true);
280
281 rowSoln_t solution(env, comm, nWeights);
282 solution.setParts(solnParts);
283
284 ztrowgraph_t *mMigrate = NULL;
285 tpetraRowGraphInput->applyPartitioningSolution(*crsGraph, mMigrate,
286 solution);
287 const auto newG = rcp(mMigrate);
288
289 auto cnewG = rcp_const_cast<const ztrowgraph_t>(newG);
290 auto newInput = rcp(new rowAdapter_t(cnewG, nWeights));
291
292 PrintFromRoot("Input adapter for Tpetra::RowGraph migrated to proc 0");
293
294 verifyInputAdapter(*newInput, *newG);
295 }
296 } catch (std::exception &e) {
297 std::cout << e.what() << std::endl;
298 return EXIT_FAILURE;
299 }
300
301 PrintFromRoot("PASS");
302}
typename node_t::device_type device_t
typename crsAdapter_t::ConstWeightsHostView1D::execution_space execspace_t
typename Zoltan2::InputTraits< ztcrsmatrix_t >::node_t node_t
void verifyInputAdapter(adapter_t &ia, graph_t &graph)
void printGraph(RCP< const Comm< int > > &comm, zlno_t nvtx, const zgno_t *vtxIds, const offset_t *offsets, const zgno_t *edgeIds)
Zoltan2::TpetraRowGraphAdapter< ztrowgraph_t > rowAdapter_t
void TestGraphIds(adapter_t &ia, graph_t &graph)
Zoltan2::TpetraCrsGraphAdapter< ztcrsgraph_t > crsAdapter_t
Tpetra::RowGraph< zlno_t, zgno_t, znode_t > ztrowgraph_t
Tpetra::CrsGraph< zlno_t, zgno_t, znode_t > ztcrsgraph_t
Traits for application input objects.
common code used by tests
void PrintFromRoot(const std::string &message)
Tpetra::Map ::local_ordinal_type zlno_t
#define Z2_TEST_DEVICE_HOST_VIEWS(deviceView, hostView)
#define Z2_TEST_THROW(code, ExceptType)
#define Z2_TEST_COMPARE_ARRAYS(val1, val2)
#define Z2_TEST_EQUALITY(val1, val2)
Tpetra::Map ::global_ordinal_type zgno_t
#define Z2_TEST_NOTHROW(code)
Defines TpetraCrsGraphAdapter class.
Defines TpetraRowGraphAdapter class.
int main()
typename InputTraits< User >::part_t part_t
The user parameters, debug, timing and memory profiling output objects, and error checking methods.
A PartitioningSolution is a solution to a partitioning problem.
Provides access for Zoltan2 to Tpetra::CrsGraph data.
Provides access for Zoltan2 to Tpetra::CrsMatrix data.
Provides access for Zoltan2 to Tpetra::RowGraph data.
default_node_t node_t
The Kokkos node type. This is only meaningful for users of Tpetra objects.