Zoltan2
Loading...
Searching...
No Matches
Zoltan2_Adapter.hpp
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
50#ifndef _ZOLTAN2_ADAPTER_HPP_
51#define _ZOLTAN2_ADAPTER_HPP_
52
53#include <Kokkos_Core.hpp>
54#include <Zoltan2_Standards.hpp>
57
58namespace Zoltan2 {
59
70};
71
82public:
83 virtual ~BaseAdapterRoot() {}; // required virtual declaration
84
90 virtual size_t getLocalNumIDs() const = 0;
91
97 virtual int getNumWeightsPerID() const { return 0; };
98};
99
100template <typename User>
102
103public:
110
113 virtual enum BaseAdapterType adapterType() const = 0;
114
117 virtual ~BaseAdapter() {};
118
123 virtual void getIDsView(const gno_t *&ids) const {
124 // If adapter does not define getIDsView, getIDsKokkosView is called.
125 // If adapter does not define getIDsKokkosView, getIDsView is called.
126 // Allows forward and backwards compatibility.
127 Kokkos::View<const gno_t *, typename node_t::device_type> kokkosIds;
128 getIDsKokkosView(kokkosIds);
129 ids = kokkosIds.data();
130 }
131
136 virtual void getIDsKokkosView(Kokkos::View<const gno_t *,
137 typename node_t::device_type> &ids) const {
138 // If adapter does not define getIDsView, getIDsKokkosView is called.
139 // If adapter does not define getIDsKokkosView, getIDsView is called.
140 // Allows forward and backwards compatibility.
141 const gno_t * ptr_ids;
142 getIDsView(ptr_ids);
143
144 typedef Kokkos::View<gno_t *, typename node_t::device_type> view_t;
145 view_t non_const_ids = view_t("ptr_ids", getLocalNumIDs());
146
147 auto host_ids = Kokkos::create_mirror_view(non_const_ids);
148 for(size_t i = 0; i < this->getLocalNumIDs(); ++i) {
149 host_ids(i) = ptr_ids[i];
150 }
151 Kokkos::deep_copy(non_const_ids, host_ids);
152 ids = non_const_ids;
153 }
154
156 // * \param wgt on return a pointer to the weights for this idx
157 // * \param stride on return, the value such that
158 // * the \t nth weight should be found at <tt> wgt[n*stride] </tt>.
159 // * \param idx the weight index, zero or greater
160 // * This function or getWeightsKokkosView must be implemented in
161 // * derived adapter if getNumWeightsPerID > 0.
162 // * This function should not be called if getNumWeightsPerID is zero.
163 // */
164 virtual void getWeightsView(const scalar_t *&wgt, int &stride,
165 int idx = 0) const {
166 // If adapter does not define getWeightsView, getWeightsKokkosView is called.
167 // If adapter does not define getWeightsKokkosView, getWeightsView is called.
168 // Allows forward and backwards compatibility.
169 Kokkos::View<scalar_t **, typename node_t::device_type> kokkos_wgts_2d;
170 getWeightsKokkosView(kokkos_wgts_2d);
171 Kokkos::View<scalar_t *, typename node_t::device_type> kokkos_wgts;
172 wgt = Kokkos::subview(kokkos_wgts_2d, Kokkos::ALL, idx).data();
173 stride = 1;
174 }
175
177 // * \param wgt on return a Kokkos view of the weights for this idx
178 // * This function or getWeightsView must be implemented in
179 // * derived adapter if getNumWeightsPerID > 0.
180 // * This function should not be called if getNumWeightsPerID is zero.
181 // */
182 virtual void getWeightsKokkosView(Kokkos::View<scalar_t **,
183 typename node_t::device_type> & wgt) const {
184 // If adapter does not define getWeightsKokkosView, getWeightsView is called.
185 // If adapter does not define getWeightsView, getWeightsKokkosView is called.
186 // Allows forward and backwards compatibility.
187 wgt = Kokkos::View<scalar_t **, typename node_t::device_type>(
189 typename Kokkos::View<scalar_t **, typename node_t::device_type>::HostMirror
190 host_wgt = Kokkos::create_mirror_view(wgt);
191 for(int j = 0; j < this->getNumWeightsPerID(); ++j) {
192 const scalar_t * ptr_wgts;
193 int stride;
194 getWeightsView(ptr_wgts, stride, j);
195 size_t i = 0;
196 for(size_t n = 0; n < this->getLocalNumIDs() * stride; n += stride) {
197 host_wgt(i++,j) = ptr_wgts[n];
198 }
199 }
200 Kokkos::deep_copy(wgt, host_wgt);
201 }
202
212 void getPartsView(const part_t *&inputPart) const {
213 // Default behavior: return NULL for inputPart array;
214 // assume input part == rank
215 inputPart = NULL;
216 }
217
235 template <typename Adapter>
236 void applyPartitioningSolution(const User &in, User *&out,
237 const PartitioningSolution<Adapter> &solution) const {
239 }
240
241protected:
242
243 // Write Chaco-formatted graph and assign files echoing adapter input
244 // This routine is serial and may be slow; use it only for debugging
245 // This function does not write edge info to the graph file, as the
246 // BaseAdapter does not know about edge info; it writes
247 // only the Chaco header and vertex weights (if applicable).
248 void generateWeightFileOnly(const char* fileprefix,
249 const Teuchos::Comm<int> &comm) const;
250
251};
252
253template <typename User>
254class AdapterWithCoords : public BaseAdapter<User>
255{
256public:
257 virtual void getCoordinatesView(const typename BaseAdapter<User>::scalar_t *&coords, int &stride, int coordDim) const = 0;
259 Kokkos::View<typename BaseAdapter<User>::scalar_t **, Kokkos::LayoutLeft, typename BaseAdapter<User>::node_t::device_type> &elements) const = 0;
260};
261
262// Forward declare
263template <typename User>
264class VectorAdapter;
265
266template <typename User, typename UserCoord=User>
268{
269public:
270 virtual void setCoordinateInput(VectorAdapter<UserCoord> *coordData) = 0;
272};
273
274template <typename User>
276 const char *fileprefix,
277 const Teuchos::Comm<int> &comm
278) const
279{
280 int np = comm.getSize();
281 int me = comm.getRank();
282
283 size_t nLocalIDs = this->getLocalNumIDs();
284
285 // Write .graph file: header and weights only (no edges)
286 // Adapters with edges have to implement their own generateFiles function
287 // to provide edge info.
288 {
289 // append suffix to filename
290 std::string filenamestr = fileprefix;
291 filenamestr = filenamestr + ".graph";
292 const char *filename = filenamestr.c_str();
293
294 size_t nGlobalIDs;
295 Teuchos::reduceAll(comm, Teuchos::REDUCE_SUM, 1, &nLocalIDs, &nGlobalIDs);
296
297 int nWgts = this->getNumWeightsPerID();
298
299 for (int p = 0; p < np; p++) {
300
301 // Is it this processor's turn to write to files?
302 if (me == p) {
303
304 std::ofstream fp;
305
306 if (me == 0) {
307 // open file for writing
308 fp.open(filename, std::ios::out);
309 // write Chaco header info
310 // this function assumes no edges
311 fp << nGlobalIDs << " " << 0 << " "
312 << (nWgts ? "010" : "000") << " "
313 << (nWgts > 1 ? std::to_string(nWgts) : " ") << std::endl;
314 }
315 else {
316 // open file for appending
317 fp.open(filename, std::ios::app);
318 }
319
320 if (nWgts) {
321
322 // get weight data
323 const scalar_t **wgts = new const scalar_t *[nWgts];
324 int *strides = new int[nWgts];
325 for (int n = 0; n < nWgts; n++)
326 getWeightsView(wgts[n], strides[n], n);
327
328 // write weights to file
329 for (size_t i = 0; i < nLocalIDs; i++) {
330 for (int n = 0; n < nWgts; n++)
331 fp << wgts[n][i*strides[n]] << " ";
332 fp << "\n";
333 }
334
335 delete [] strides;
336 delete [] wgts;
337 }
338
339 fp.close();
340 }
341
342 comm.barrier();
343 }
344 }
345
346 // write assignments file
347 {
348 std::string filenamestr = fileprefix;
349 filenamestr = filenamestr + ".assign";
350 const char *filename = filenamestr.c_str();
351
352 for (int p = 0; p < np; p++) {
353
354 // Is it this processor's turn to write to files?
355 if (me == p) {
356
357 std::ofstream fp;
358
359 if (me == 0) {
360 // open file for writing
361 fp.open(filename, std::ios::out);
362 }
363 else {
364 // open file for appending
365 fp.open(filename, std::ios::app);
366 }
367
368 const part_t *parts;
369 this->getPartsView(parts);
370
371 for (size_t i = 0; i < nLocalIDs; i++) {
372 fp << (parts != NULL ? parts[i] : me) << "\n";
373 }
374 fp.close();
375 }
376
377 comm.barrier();
378 }
379 }
380}
381
382} //namespace Zoltan2
383
384#endif
#define Z2_THROW_NOT_IMPLEMENTED
Traits for application input objects.
Defines the PartitioningSolution class.
Gathering definitions used in software development.
virtual VectorAdapter< UserCoord > * getCoordinateInput() const =0
virtual void setCoordinateInput(VectorAdapter< UserCoord > *coordData)=0
virtual void getCoordinatesKokkosView(Kokkos::View< typename BaseAdapter< User >::scalar_t **, Kokkos::LayoutLeft, typename BaseAdapter< User >::node_t::device_type > &elements) const =0
virtual void getCoordinatesView(const typename BaseAdapter< User >::scalar_t *&coords, int &stride, int coordDim) const =0
BaseAdapter defines methods required by all Adapters.
virtual int getNumWeightsPerID() const
Returns the number of weights per object. Number of weights per object should be zero or greater....
virtual size_t getLocalNumIDs() const =0
Returns the number of objects on this process.
InputTraits< User >::node_t node_t
void getPartsView(const part_t *&inputPart) const
Provide pointer to a weight array with stride.
InputTraits< User >::offset_t offset_t
InputTraits< User >::part_t part_t
InputTraits< User >::scalar_t scalar_t
void generateWeightFileOnly(const char *fileprefix, const Teuchos::Comm< int > &comm) const
virtual void getIDsView(const gno_t *&ids) const
Provide a pointer to this process' identifiers.
InputTraits< User >::lno_t lno_t
virtual ~BaseAdapter()
Destructor.
virtual void getIDsKokkosView(Kokkos::View< const gno_t *, typename node_t::device_type > &ids) const
Provide a Kokkos view to this process' identifiers.
virtual enum BaseAdapterType adapterType() const =0
Returns the type of adapter.
void applyPartitioningSolution(const User &in, User *&out, const PartitioningSolution< Adapter > &solution) const
Apply a PartitioningSolution to an input.
InputTraits< User >::gno_t gno_t
A PartitioningSolution is a solution to a partitioning problem.
VectorAdapter defines the interface for vector input.
Created by mbenlioglu on Aug 31, 2020.
BaseAdapterType
An enum to identify general types of adapters.
@ VectorAdapterType
vector data
@ InvalidAdapterType
unused value
@ GraphAdapterType
graph data
@ MatrixAdapterType
matrix data
@ MeshAdapterType
mesh data
@ IdentifierAdapterType
identifier data, just a list of IDs
default_offset_t offset_t
The data type to represent offsets.
default_gno_t gno_t
The ordinal type (e.g., int, long, int64_t) that can represent global counts and identifiers.
default_node_t node_t
The Kokkos node type. This is only meaningful for users of Tpetra objects.
default_lno_t lno_t
The ordinal type (e.g., int, long, int64_t) that represents local counts and local indices.
default_part_t part_t
The data type to represent part numbers.
default_scalar_t scalar_t
The data type for weights and coordinates.