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