Zoltan2
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 typedef Kokkos::View<gno_t *, typename node_t::device_type> view_t;
144 view_t non_const_ids = view_t("ptr_ids", getLocalNumIDs());
145 typename view_t::HostMirror host_ids = Kokkos::create_mirror_view(non_const_ids);
146 for(size_t i = 0; i < this->getLocalNumIDs(); ++i) {
147 host_ids(i) = ptr_ids[i];
148 }
149 Kokkos::deep_copy(non_const_ids, host_ids);
150 ids = non_const_ids;
151 }
152
154 // * \param wgt on return a pointer to the weights for this idx
155 // * \param stride on return, the value such that
156 // * the \t nth weight should be found at <tt> wgt[n*stride] </tt>.
157 // * \param idx the weight index, zero or greater
158 // * This function or getWeightsKokkosView must be implemented in
159 // * derived adapter if getNumWeightsPerID > 0.
160 // * This function should not be called if getNumWeightsPerID is zero.
161 // */
162 virtual void getWeightsView(const scalar_t *&wgt, int &stride,
163 int idx = 0) const {
164 // If adapter does not define getWeightsView, getWeightsKokkosView is called.
165 // If adapter does not define getWeightsKokkosView, getWeightsView is called.
166 // Allows forward and backwards compatibility.
167 Kokkos::View<scalar_t **, typename node_t::device_type> kokkos_wgts_2d;
168 getWeightsKokkosView(kokkos_wgts_2d);
169 Kokkos::View<scalar_t *, typename node_t::device_type> kokkos_wgts;
170 wgt = Kokkos::subview(kokkos_wgts_2d, Kokkos::ALL, idx).data();
171 stride = 1;
172 }
173
175 // * \param wgt on return a Kokkos view of the weights for this idx
176 // * This function or getWeightsView must be implemented in
177 // * derived adapter if getNumWeightsPerID > 0.
178 // * This function should not be called if getNumWeightsPerID is zero.
179 // */
180 virtual void getWeightsKokkosView(Kokkos::View<scalar_t **,
181 typename node_t::device_type> & wgt) const {
182 // If adapter does not define getWeightsKokkosView, getWeightsView is called.
183 // If adapter does not define getWeightsView, getWeightsKokkosView is called.
184 // Allows forward and backwards compatibility.
185 wgt = Kokkos::View<scalar_t **, typename node_t::device_type>(
187 typename Kokkos::View<scalar_t **, typename node_t::device_type>::HostMirror
188 host_wgt = Kokkos::create_mirror_view(wgt);
189 for(int j = 0; j < this->getNumWeightsPerID(); ++j) {
190 const scalar_t * ptr_wgts;
191 int stride;
192 getWeightsView(ptr_wgts, stride, j);
193 size_t i = 0;
194 for(size_t n = 0; n < this->getLocalNumIDs() * stride; n += stride) {
195 host_wgt(i++,j) = ptr_wgts[n];
196 }
197 }
198 Kokkos::deep_copy(wgt, host_wgt);
199 }
200
210 void getPartsView(const part_t *&inputPart) const {
211 // Default behavior: return NULL for inputPart array;
212 // assume input part == rank
213 inputPart = NULL;
214 }
215
233 template <typename Adapter>
234 void applyPartitioningSolution(const User &in, User *&out,
235 const PartitioningSolution<Adapter> &solution) const {
237 }
238
239protected:
240
241 // Write Chaco-formatted graph and assign files echoing adapter input
242 // This routine is serial and may be slow; use it only for debugging
243 // This function does not write edge info to the graph file, as the
244 // BaseAdapter does not know about edge info; it writes
245 // only the Chaco header and vertex weights (if applicable).
246 void generateWeightFileOnly(const char* fileprefix,
247 const Teuchos::Comm<int> &comm) const;
248
249};
250
251template <typename User>
253 const char *fileprefix,
254 const Teuchos::Comm<int> &comm
255) const
256{
257 int np = comm.getSize();
258 int me = comm.getRank();
259
260 size_t nLocalIDs = this->getLocalNumIDs();
261
262 // Write .graph file: header and weights only (no edges)
263 // Adapters with edges have to implement their own generateFiles function
264 // to provide edge info.
265 {
266 // append suffix to filename
267 std::string filenamestr = fileprefix;
268 filenamestr = filenamestr + ".graph";
269 const char *filename = filenamestr.c_str();
270
271 size_t nGlobalIDs;
272 Teuchos::reduceAll(comm, Teuchos::REDUCE_SUM, 1, &nLocalIDs, &nGlobalIDs);
273
274 int nWgts = this->getNumWeightsPerID();
275
276 for (int p = 0; p < np; p++) {
277
278 // Is it this processor's turn to write to files?
279 if (me == p) {
280
281 std::ofstream fp;
282
283 if (me == 0) {
284 // open file for writing
285 fp.open(filename, std::ios::out);
286 // write Chaco header info
287 // this function assumes no edges
288 fp << nGlobalIDs << " " << 0 << " "
289 << (nWgts ? "010" : "000") << " "
290 << (nWgts > 1 ? std::to_string(nWgts) : " ") << std::endl;
291 }
292 else {
293 // open file for appending
294 fp.open(filename, std::ios::app);
295 }
296
297 if (nWgts) {
298
299 // get weight data
300 const scalar_t **wgts = new const scalar_t *[nWgts];
301 int *strides = new int[nWgts];
302 for (int n = 0; n < nWgts; n++)
303 getWeightsView(wgts[n], strides[n], n);
304
305 // write weights to file
306 for (size_t i = 0; i < nLocalIDs; i++) {
307 for (int n = 0; n < nWgts; n++)
308 fp << wgts[n][i*strides[n]] << " ";
309 fp << "\n";
310 }
311
312 delete [] strides;
313 delete [] wgts;
314 }
315
316 fp.close();
317 }
318
319 comm.barrier();
320 }
321 }
322
323 // write assignments file
324 {
325 std::string filenamestr = fileprefix;
326 filenamestr = filenamestr + ".assign";
327 const char *filename = filenamestr.c_str();
328
329 for (int p = 0; p < np; p++) {
330
331 // Is it this processor's turn to write to files?
332 if (me == p) {
333
334 std::ofstream fp;
335
336 if (me == 0) {
337 // open file for writing
338 fp.open(filename, std::ios::out);
339 }
340 else {
341 // open file for appending
342 fp.open(filename, std::ios::app);
343 }
344
345 const part_t *parts;
346 this->getPartsView(parts);
347
348 for (size_t i = 0; i < nLocalIDs; i++) {
349 fp << (parts != NULL ? parts[i] : me) << "\n";
350 }
351 fp.close();
352 }
353
354 comm.barrier();
355 }
356 }
357}
358
359} //namespace Zoltan2
360
361#endif
#define Z2_THROW_NOT_IMPLEMENTED
Traits for application input objects.
Defines the PartitioningSolution class.
Gathering definitions used in software development.
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.
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.