Zoltan2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Zoltan2_TPLTraits.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 
46 #ifndef _ZOLTAN2_TPLTRAITS_HPP_
47 #define _ZOLTAN2_TPLTRAITS_HPP_
48 
49 #include <Teuchos_RCP.hpp>
50 #include <Teuchos_ArrayView.hpp>
51 #include <Teuchos_as.hpp>
52 #include <Zoltan2_Standards.hpp>
53 #include <Zoltan2_Environment.hpp>
54 
55 #include <zoltan_types.h>
56 
62 
63 namespace Zoltan2 {
64 
66 // General case: first_t and second_t differ //
68 
69 template <typename first_t, typename second_t>
70 struct TPL_Traits {
71 
72  static inline bool OK_TO_CAST()
73  {
74  // Return true if pointer to first_t can be used as pointer to second_t
75  return ((sizeof(first_t) == sizeof(second_t)) &&
76  (std::numeric_limits<first_t>::is_signed ==
77  std::numeric_limits<second_t>::is_signed));
78  }
79 
80  static inline void ASSIGN(first_t &a, second_t b)
81  {
82  // Assign a = b; make sure first_t is large enough to accept second_t.
83  try {
84  a = Teuchos::asSafe<first_t, second_t>(b);
85  }
86  catch (std::exception &e) {
87  throw std::runtime_error(
88  "TPL_Traits: Value too large for TPL index type. "
89  "Rebuild TPL with larger index type or rebuild without the TPL.");
90  }
91  }
92 
93  static inline void ASSIGN_ARRAY(first_t **a, ArrayView<second_t> &b)
94  {
95  // Allocate array a; copy b values into a.
96  size_t size = b.size();
97  if (size > 0) {
98  *a = new first_t[size];
99  for (size_t i = 0; i < size; i++) ASSIGN((*a)[i], b[i]);
100  }
101  else {
102  *a = NULL;
103  // Note: the Scotch manual says that if any rank has a non-NULL array,
104  // every process must have a non-NULL array. In practice,
105  // however, this condition is not needed for the arrays we use.
106  // For now, we'll set these arrays to NULL. We could allocate
107  // a dummy value here if needed. KDD 1/23/14
108  // Note: ParMETIS would likely prefer a dummy value as well. It does
109  // not like NULL adjcny array. KDD 10/7/14
110  }
111  }
112 
113  static inline void SAVE_ARRAYRCP(ArrayRCP<first_t> *a, second_t *b,
114  size_t size)
115  {
116  // Allocate array tmp; copy size values of b into tmp;
117  // save tmp as ArrayRCP a
118  if (size > 0) {
119  first_t *tmp = new first_t[size];
120  for (size_t i = 0; i < size; i++) ASSIGN(tmp[i], b[i]);
121  *a = arcp(tmp, 0, size, true);
122  }
123  else {
124  *a = Teuchos::null;
125  }
126  }
127 
128  static inline void DELETE_ARRAY(first_t **a)
129  {
130  // Delete the copy made in ASSIGN_ARRAY.
131  delete [] *a;
132  }
133 };
134 
136 // Special case: second_t == first_t //
137 // No error checking or copies //
139 
140 template <typename first_t>
141 struct TPL_Traits<first_t, first_t> {
142 
143  static inline bool OK_TO_CAST() {return true;}
144 
145  static inline void ASSIGN(first_t &a, first_t b) { a = b; }
146 
147  static inline void ASSIGN_ARRAY(first_t **a, ArrayView<first_t> &b)
148  {
149  if (b.size() > 0)
150  *a = b.getRawPtr();
151  else
152  *a = NULL;
153  // Note: the Scotch manual says that if any rank has a non-NULL array,
154  // every process must have a non-NULL array. In practice,
155  // however, this condition is not needed for the arrays we use.
156  // For now, we'll set these arrays to NULL. We could allocate
157  // a dummy value here if needed. KDD 1/23/14
158  }
159 
160  static inline void SAVE_ARRAYRCP(ArrayRCP<first_t> *a, first_t *b,
161  size_t size)
162  {
163  // Return in a an ArrayRCP of b.
164  if (size > 0)
165  *a = arcp(b, 0, size, true);
166  else
167  *a = Teuchos::null;
168  }
169 
170  static inline void DELETE_ARRAY(first_t **a) { }
171 };
172 
174 // Special case: first_t == Zoltan ZOLTAN_ID_PTR //
176 
177 template <typename second_t>
178 struct TPL_Traits<ZOLTAN_ID_PTR, second_t> {
179 
180  // Copy the data bitwise INTO the array of ZOLTAN_ID_TYPE
181  // We assume that any memory pointed to by ZOLTAN_ID_PTR is
182  // big enough to hold the bits of second_t -- that is, that
183  // the ZOLTAN_ID_PTR's memory correctly accomodates Zoltan's
184  // num_gid_entries or num_lid_entries
185 
186  static const int NUM_ID = ((sizeof(second_t) / sizeof(ZOLTAN_ID_TYPE) > 0)
187  ? (sizeof(second_t) / sizeof(ZOLTAN_ID_TYPE))
188  : 1);
189 
190  static inline bool OK_TO_CAST()
191  {
192  // There may be cases where if it OK to cast a pointer to a
193  // second_t to a ZOLTAN_ID_PTR, but the semantics of this
194  // function ask whether a pointer to a second_t can be cast
195  // to a pointer to a ZOLTAN_ID_PTR. Thus, the answer is "no."
196  return false;
197  }
198 
199  static inline void ASSIGN(ZOLTAN_ID_PTR &a, second_t b)
200  {
201  switch (NUM_ID) {
202  case 1:
203  a[0] = static_cast<ZOLTAN_ID_TYPE>(b);
204  break;
205  case 2: {
206  ZOLTAN_ID_TYPE *ptr = (ZOLTAN_ID_TYPE *)(&b);
207  a[0] = ptr[0];
208  a[1] = ptr[1];
209  break;
210  }
211  default: {
212  ZOLTAN_ID_TYPE *ptr = (ZOLTAN_ID_TYPE *)(&b);
213  for (int i = 0; i < NUM_ID; i++) a[i] = ptr[i];
214  }
215  }
216  }
217 
218  static inline void ASSIGN_ARRAY(ZOLTAN_ID_PTR *a, ArrayView<second_t> &b)
219  {
220  // Allocate array a; copy b values into a.
221  size_t size = b.size();
222  if (size > 0) {
223  if (NUM_ID == 1) {
224  // Don't have to make a new copy
225  *a = reinterpret_cast<ZOLTAN_ID_PTR> (b.getRawPtr());
226  }
227  else {
228  *a = new ZOLTAN_ID_TYPE[size*NUM_ID];
229  for (size_t i = 0; i < size; i++) {
230  ZOLTAN_ID_PTR tmp = &((*a)[i*NUM_ID]);
231  ASSIGN(tmp, b[i]);
232  }
233  }
234  }
235  else {
236  *a = NULL;
237  }
238  }
239 
240  static inline void SAVE_ARRAYRCP(ArrayRCP<ZOLTAN_ID_PTR> *a, second_t *b,
241  size_t size)
242  {
243  throw std::runtime_error(
244  "TPL_Traits::SAVE_ARRAYRCP<ZOLTAN_ID_PTR,second_t> "
245  "is not implemented.");
246  }
247 
248  static inline void DELETE_ARRAY(ZOLTAN_ID_PTR *a)
249  {
250  // Delete the copy made in ASSIGN_ARRAY.
251  if (NUM_ID != 1)
252  delete [] *a;
253  }
254 };
255 
257 // Special case: second_t == Zoltan ZOLTAN_ID_PTR //
259 
260 template <typename first_t>
261 struct TPL_Traits<first_t, ZOLTAN_ID_PTR> {
262 
263  // Copy the data bitwise FROM the array of ZOLTAN_ID_TYPE
264 
266 
267  static inline bool OK_TO_CAST()
268  {
269  // There may be cases where if it OK to cast a pointer to a
270  // first_t to a ZOLTAN_ID_PTR, but the semantics of this
271  // function ask whether a pointer to a first_t can be cast
272  // to a pointer to a ZOLTAN_ID_PTR. Thus, the answer is "no."
273  return false;
274  }
275 
276  static inline void ASSIGN(first_t &a, ZOLTAN_ID_PTR b)
277  {
278  switch (NUM_ID) {
279  case 1:
280  a = static_cast<first_t>(b[0]);
281  break;
282  default:
283  first_t *tmp = (first_t *) b;
284  a = *tmp;
285  }
286  }
287 
288  static inline void ASSIGN_ARRAY(first_t *a, ArrayView<ZOLTAN_ID_PTR> &b)
289  {
290  throw std::runtime_error(
291  "TPL_Traits::ASSIGN_ARRAY<first_t,ZOLTAN_ID_PTR> "
292  "is not implemented.");
293  }
294 
295  static inline void SAVE_ARRAYRCP(ArrayRCP<first_t> *a, ZOLTAN_ID_PTR b,
296  size_t size)
297  {
298  // Here, size * NUM_ID == length of b; that is, size is the number of
299  // objects in b.
300  // Return in a an ArrayRCP of b.
301  if (size > 0) {
302  if (NUM_ID == 1)
303  *a = arcp(b, 0, size, true); // Don't have to make a new copy
304  else {
305  first_t *tmp = new first_t[size];
306  for (size_t i = 0; i < size; i++) ASSIGN(tmp[i], &(b[i*NUM_ID]));
307  *a = arcp(tmp, 0, size, true);
308  }
309  }
310  else {
311  *a = Teuchos::null;
312  }
313  }
314 
315  static inline void DELETE_ARRAY(first_t **a)
316  {
317  // Delete the copy made in ASSIGN_ARRAY.
318  if (NUM_ID != 1)
319  delete [] *a;
320  }
321 };
322 
323 } // namespace Zoltan2
324 
325 #endif
static void ASSIGN(ZOLTAN_ID_PTR &a, second_t b)
static void SAVE_ARRAYRCP(ArrayRCP< ZOLTAN_ID_PTR > *a, second_t *b, size_t size)
static void ASSIGN_ARRAY(first_t **a, ArrayView< first_t > &b)
static void SAVE_ARRAYRCP(ArrayRCP< first_t > *a, second_t *b, size_t size)
static void ASSIGN_ARRAY(first_t *a, ArrayView< ZOLTAN_ID_PTR > &b)
static void SAVE_ARRAYRCP(ArrayRCP< first_t > *a, first_t *b, size_t size)
static void ASSIGN(first_t &a, second_t b)
static void ASSIGN(first_t &a, ZOLTAN_ID_PTR b)
static void ASSIGN_ARRAY(ZOLTAN_ID_PTR *a, ArrayView< second_t > &b)
Gathering definitions used in software development.
Defines the Environment class.
static void ASSIGN_ARRAY(first_t **a, ArrayView< second_t > &b)
static void SAVE_ARRAYRCP(ArrayRCP< first_t > *a, ZOLTAN_ID_PTR b, size_t size)
static void ASSIGN(first_t &a, first_t b)
static void DELETE_ARRAY(first_t **a)