Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
MatrixAdapter.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 of GraphAdapter built from Xpetra matrix input adapters.
47 //
48 
53 #include "Kokkos_StaticCrsGraph.hpp"
54 #include "Kokkos_UnorderedMap.hpp"
56 #include <Zoltan2_InputTraits.hpp>
57 #include <Zoltan2_TestHelpers.hpp>
60 
61 #include <bitset>
62 #include <iostream>
63 #include <string>
64 
65 #include <Teuchos_ArrayView.hpp>
66 #include <Teuchos_Comm.hpp>
67 #include <Teuchos_DefaultComm.hpp>
68 #include <Teuchos_TestingHelpers.hpp>
69 
70 using Teuchos::ArrayView;
71 using Teuchos::Comm;
72 using Teuchos::RCP;
73 using Teuchos::rcp;
74 using Teuchos::rcp_const_cast;
75 using Teuchos::rcp_dynamic_cast;
76 
78 
79 using tcrsMatrix_t = Tpetra::CrsMatrix<zscalar_t, zlno_t, zgno_t, znode_t>;
80 using trowMatrix_t = Tpetra::RowMatrix<zscalar_t, zlno_t, zgno_t, znode_t>;
81 using tmap_t = Tpetra::Map<zlno_t, zgno_t, znode_t>;
82 
87 
89 int main(int narg, char *arg[]) {
90  Tpetra::ScopeGuard tscope(&narg, &arg);
91  Teuchos::RCP<const Teuchos::Comm<int>> comm = Tpetra::getDefaultComm();
92 
93  int rank = comm->getRank();
94 
95  int nVtxWeights = 2;
96  int nnzWgtIdx = -1;
97  std::string fname("simple");
98 
99  if (rank == 0)
100  std::cout << "TESTING base case (global)" << std::endl;
101 
102  // Input generator
103  UserInputForTests *uinput;
104 
105  uinput = new UserInputForTests(testDataFilePath, fname, comm, true);
106 
107  RCP<tcrsMatrix_t> M = uinput->getUITpetraCrsMatrix();
108  RCP<trowMatrix_t> trM = rcp_dynamic_cast<trowMatrix_t>(M);
109  RCP<const trowMatrix_t> ctrM = rcp_const_cast<const trowMatrix_t>(trM);
110  zlno_t nLocalRows = M->getLocalNumRows();
111  std::cout << "nLocalRows: " << nLocalRows << std::endl;
112 
113  // Weights:
114  zscalar_t **rowWeights = nullptr;
115  // create as many 1-D weights views as nVtxWeights
117  nLocalRows);
119  nLocalRows);
120 
121  auto wgts0Host = Kokkos::create_mirror_view(wgts0);
122  auto wgts1Host = Kokkos::create_mirror_view(wgts1);
123 
124  for (zlno_t i = 0; i < nLocalRows; i++) {
125  wgts0Host(i) = i;
126  wgts1Host(i) = 200000 + i;
127  }
128 
129  if (nVtxWeights > 0) {
130  rowWeights = new zscalar_t *[nVtxWeights];
131  for (int i = 0; i < nVtxWeights; i++) {
132  if (nnzWgtIdx == i) {
133  rowWeights[i] = nullptr;
134  } else {
135  rowWeights[i] = new zscalar_t[nLocalRows];
136  for (zlno_t j = 0; j < nLocalRows; j++) {
137  rowWeights[i][j] = 200000 * i + j;
138  }
139  }
140  }
141  }
142 
143  Kokkos::deep_copy(wgts0, wgts0Host);
144  Kokkos::deep_copy(wgts1, wgts1Host);
145 
146  tRowMAdapter_t tmi(ctrM, nVtxWeights);
147  for (int i = 0; i < nVtxWeights; i++) {
148  tmi.setWeights(rowWeights[i], 1, i);
149  }
150  tmi.setRowWeightsDevice(wgts0, 0);
151  tmi.setRowWeightsDevice(wgts1, 1);
152 
153  simpleVAdapter_t *via = nullptr;
154 
155  // Set up some fake input
156  zscalar_t **coords = nullptr;
157  int coordDim = 3;
158 
159  if (coordDim > 0) {
160  coords = new zscalar_t *[coordDim];
161  for (int i = 0; i < coordDim; i++) {
162  coords[i] = new zscalar_t[nLocalRows];
163  for (zlno_t j = 0; j < nLocalRows; j++) {
164  coords[i][j] = 100000 * i + j;
165  }
166  }
167  }
168 
169  zgno_t *gids = nullptr;
170  if (coordDim > 0) {
171  gids = new zgno_t[nLocalRows];
172  for (zlno_t i = 0; i < nLocalRows; i++)
173  gids[i] = M->getRowMap()->getGlobalElement(i);
174  via = new simpleVAdapter_t(nLocalRows, gids, coords[0],
175  (coordDim > 1 ? coords[1] : nullptr),
176  (coordDim > 2 ? coords[2] : nullptr), 1, 1, 1);
177  tmi.setCoordinateInput(via);
178  }
179 
180  // TEST of getIDsView, getIDsKokkosView, getRowIDsView, getRowIDsHostView and
181  // getRowIDsDeviceView
182 
183  const zgno_t *ids;
184  const zgno_t *rowIds;
188 
189  tmi.getIDsView(ids);
190  tmi.getRowIDsView(rowIds);
191  tmi.getIDsKokkosView(kIds);
192  auto kIdsHost = Kokkos::create_mirror_view(kIds);
193  Kokkos::deep_copy(kIdsHost, kIds);
194 
195  tmi.getRowIDsHostView(kHostIds);
196  tmi.getRowIDsDeviceView(kDeviceIds);
197 
198  auto kDeviceIdsHost = Kokkos::create_mirror_view(kDeviceIds);
199  Kokkos::deep_copy(kDeviceIdsHost, kDeviceIds);
200 
201  bool success = true;
202  for (size_t i = 0; i < tmi.getLocalNumIDs(); ++i) {
203  TEUCHOS_TEST_EQUALITY(ids[i], kIdsHost(i), std::cout, success);
204  TEUCHOS_TEST_EQUALITY(ids[i], rowIds[i], std::cout, success);
205  TEUCHOS_TEST_EQUALITY(kIdsHost(i), kHostIds(i), std::cout, success);
206  TEUCHOS_TEST_EQUALITY(kIdsHost(i), kDeviceIdsHost(i), std::cout, success);
207  }
208  TEST_FAIL_AND_EXIT(*comm, success, "ids != vertexIds != kIds", 1)
209 
210  // TEST of getCRSView, getCRSHostView and getCRSDeviceView
211  // const zoffset_t *offsets;
212  ArrayRCP<const zoffset_t> offsets;
213  ArrayRCP<const zgno_t> colIds;
218  tmi.getCRSView(offsets, colIds);
219  tmi.getCRSHostView(kHostOffsets, kHostColIds);
220  tmi.getCRSDeviceView(kDeviceOffsets, kDeviceColIds);
221 
222  auto kDeviceColIdsHost = Kokkos::create_mirror_view(kDeviceColIds);
223  Kokkos::deep_copy(kDeviceColIdsHost, kDeviceColIds);
224 
225  auto kDeviceOffsetsHost = Kokkos::create_mirror_view(kDeviceOffsets);
226  Kokkos::deep_copy(kDeviceOffsetsHost, kDeviceOffsets);
227 
228  for (int i = 0; success && i < colIds.size(); i++) {
229  TEUCHOS_TEST_EQUALITY(colIds[i], kHostColIds(i), std::cout, success);
230  TEUCHOS_TEST_EQUALITY(colIds[i], kDeviceColIdsHost(i), std::cout, success);
231  }
232  TEST_FAIL_AND_EXIT(*comm, success, "colIds != kHostColIds != kDeviceColIds",
233  1)
234 
235  for (int i = 0; success && i < offsets.size(); i++) {
236  TEUCHOS_TEST_EQUALITY(offsets[i], kHostOffsets(i), std::cout, success);
237  TEUCHOS_TEST_EQUALITY(offsets[i], kDeviceOffsetsHost(i), std::cout,
238  success);
239  }
240  TEST_FAIL_AND_EXIT(*comm, success,
241  "offsets != kHostOffsets != kDeviceOffsets", 1)
242 
243  ArrayRCP<const zscalar_t> values;
246 
247  tmi.getCRSView(offsets, colIds, values);
248  tmi.getCRSHostView(kHostOffsets, kHostColIds, kHostValues);
249  tmi.getCRSDeviceView(kDeviceOffsets, kDeviceColIds, kDeviceValues);
250  auto kDeviceValuesHost = Kokkos::create_mirror_view(kDeviceValues);
251  Kokkos::deep_copy(kDeviceValuesHost, kDeviceValues);
252 
253  for (int i = 0; success && i < colIds.size(); i++) {
254  TEUCHOS_TEST_EQUALITY(colIds[i], kHostColIds(i), std::cout, success);
255  TEUCHOS_TEST_EQUALITY(colIds[i], kDeviceColIdsHost(i), std::cout, success);
256  }
257  TEST_FAIL_AND_EXIT(*comm, success, "colIds != kHostColIds != kDeviceColIds",
258  1)
259 
260  for (int i = 0; success && i < offsets.size(); i++) {
261  TEUCHOS_TEST_EQUALITY(offsets[i], kHostOffsets(i), std::cout, success);
262  TEUCHOS_TEST_EQUALITY(offsets[i], kDeviceOffsetsHost(i), std::cout,
263  success);
264  }
265  TEST_FAIL_AND_EXIT(*comm, success,
266  "offsets != kHostOffsets != kDeviceOffsets", 1)
267 
268  for (int i = 0; success && i < values.size(); i++) {
269  TEUCHOS_TEST_EQUALITY(values[i], kHostValues(i), std::cout, success);
270  TEUCHOS_TEST_EQUALITY(values[i], kDeviceValuesHost(i), std::cout, success);
271  }
272  TEST_FAIL_AND_EXIT(*comm, success, "values != kHostValues != kDeviceValues",
273  1)
274 
275  // TEST of getRowWeightsView, getRowWeightsHost0View and
276  // getRowWeightsDeviceView
277 
282 
283  tmi.getRowWeightsHostView(weightsHost0, 0);
284  tmi.getRowWeightsDeviceView(weightsDevice0, 0);
285 
286  tmi.getRowWeightsHostView(weightsHost1, 1);
287  tmi.getRowWeightsDeviceView(weightsDevice1, 1);
288 
289  auto hostWeightsDevice0 = Kokkos::create_mirror_view(weightsDevice0);
290  Kokkos::deep_copy(hostWeightsDevice0, weightsDevice0);
291 
292  auto hostWeightsDevice1 = Kokkos::create_mirror_view(weightsDevice1);
293  Kokkos::deep_copy(hostWeightsDevice1, weightsDevice1);
294 
295  for (int w = 0; success && w < nVtxWeights; w++) {
296  const zscalar_t *wgts;
297 
298  Kokkos::View<zscalar_t *, typename znode_t::device_type> wkgts;
299  int stride;
300  tmi.getRowWeightsView(wgts, stride, w);
301 
302  if (w == 0) {
303 
304  for (zlno_t i = 0; success && i < nLocalRows; ++i) {
305  TEUCHOS_TEST_EQUALITY(wgts[stride * i], weightsHost0(i), std::cout,
306  success);
307  TEUCHOS_TEST_EQUALITY(wgts[stride * i], hostWeightsDevice0(i), std::cout,
308  success);
309  }
310  } else {
311  for (zlno_t i = 0; success && i < nLocalRows; ++i) {
312  TEUCHOS_TEST_EQUALITY(wgts[stride * i], weightsHost1(i), std::cout,
313  success);
314  TEUCHOS_TEST_EQUALITY(wgts[stride * i], hostWeightsDevice1(i), std::cout,
315  success);
316  }
317  }
318  }
319  TEST_FAIL_AND_EXIT(*comm, success, "wgts != vwgts != wkgts", 1)
320 
321  // TEST of useNumNonzerosAsRowWeight, useNumNonzerosAsRowWeightHost and
322  // useNumNonzerosAsRowWeightDevice
323  // for (int w = 0; success && w < nVtxWeights; w++) {
324  // TEUCHOS_TEST_EQUALITY(tmi.useNumNonzerosAsRowWeight(w),
325  // tmi.useNumNonzerosAsRowWeightHost(w), std::cout,
326  // success);
327  // TEUCHOS_TEST_EQUALITY(tmi.useNumNonzerosAsRowWeight(w),
328  // tmi.useNumNonzerosAsRowWeightDevice(w), std::cout,
329  // success);
330  // }
331  // TEST_FAIL_AND_EXIT(
332  // *comm, success,
333  // "useNumNonzerosAsRowWeight != useNumNonzerosAsRowWeightHost != "
334  // "useNumNonzerosAsRowWeightDevice",
335  // 1)
336 
337  // clean
338  if (nVtxWeights > 0) {
339  for (int i = 0; i < nVtxWeights; i++) {
340  if (rowWeights[i])
341  delete[] rowWeights[i];
342  }
343  delete[] rowWeights;
344  }
345 
346  if (coordDim > 0) {
347  delete via;
348  delete[] gids;
349  for (int i = 0; i < coordDim; i++) {
350  if (coords[i])
351  delete[] coords[i];
352  }
353  delete[] coords;
354  }
355 
356  delete uinput;
357 
358  if (rank == 0)
359  std::cout << "PASS" << std::endl;
360 
361  return 0;
362 }
typename baseMAdapter_t::offset_t zoffset_t
typename Zoltan2::TpetraRowMatrixAdapter< trowMatrix_t, simpleUser_t > tRowMAdapter_t
MatrixAdapter defines the adapter interface for matrices.
RCP< tcrsMatrix_t > getUITpetraCrsMatrix()
Kokkos::View< scalar_t *, device_t > WeightsDeviceView1D
#define TEST_FAIL_AND_EXIT(comm, ok, s, code)
int main(int narg, char **arg)
Definition: coloring1.cpp:199
common code used by tests
Kokkos::View< const gno_t *, device_t > ConstIdsDeviceView
typename ConstScalarsDeviceView::HostMirror ConstScalarsHostView
Provides access for Zoltan2 to Tpetra::RowMatrix data.
list fname
Begin.
Definition: validXML.py:19
Defines the XpetraCrsMatrixAdapter class.
Kokkos::View< const scalar_t *, device_t > ConstScalarsDeviceView
Zoltan2::BasicVectorAdapter< simpleUser_t > simpleVAdapter_t
typename ConstOffsetsDeviceView::HostMirror ConstOffsetsHostView
typename ConstIdsDeviceView::HostMirror ConstIdsHostView
BasicVectorAdapter represents a vector (plus optional weights) supplied by the user as pointers to st...
Traits for application input objects.
Defines the TpetraRowMatrixAdapter class.
Tpetra::Map::local_ordinal_type zlno_t
Tpetra::CrsMatrix< zscalar_t, zlno_t, zgno_t, znode_t > tcrsMatrix_t
Tpetra::Map< zlno_t, zgno_t, znode_t > tmap_t
typename InputTraits< User >::offset_t offset_t
typename WeightsDeviceView1D::HostMirror WeightsHostView1D
float zscalar_t
Defines the BasicVectorAdapter class.
Kokkos::View< const offset_t *, device_t > ConstOffsetsDeviceView
Tpetra::Map::global_ordinal_type zgno_t
Tpetra::RowMatrix< zscalar_t, zlno_t, zgno_t, znode_t > trowMatrix_t
std::string testDataFilePath(".")