Galois
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SyncStructures.h
Go to the documentation of this file.
1 /*
2  * This file belongs to the Galois project, a C++ library for exploiting
3  * parallelism. The code is being released under the terms of the 3-Clause BSD
4  * License (a copy is located in LICENSE.txt at the top-level directory).
5  *
6  * Copyright (C) 2018, The University of Texas at Austin. All rights reserved.
7  * UNIVERSITY EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES CONCERNING THIS
8  * SOFTWARE AND DOCUMENTATION, INCLUDING ANY WARRANTIES OF MERCHANTABILITY,
9  * FITNESS FOR ANY PARTICULAR PURPOSE, NON-INFRINGEMENT AND WARRANTIES OF
10  * PERFORMANCE, AND ANY WARRANTY THAT MIGHT OTHERWISE ARISE FROM COURSE OF
11  * DEALING OR USAGE OF TRADE. NO WARRANTY IS EITHER EXPRESS OR IMPLIED WITH
12  * RESPECT TO THE USE OF THE SOFTWARE OR DOCUMENTATION. Under no circumstances
13  * shall University be liable for incidental, special, indirect, direct or
14  * consequential damages or loss of profits, interruption of business, or
15  * related expenses which may arise from use of Software or Documentation,
16  * including but not limited to those resulting from defects in Software and/or
17  * Documentation, or loss or inaccuracy of data of any kind.
18  */
19 
27 #ifndef _SYNC_STRUCT_MACROS_
28 #define _SYNC_STRUCT_MACROS_
29 
30 #include <cstdint> // for uint types used below
31 #include <galois/AtomicHelpers.h> // for galois::max, min
32 #include <galois/runtime/DataCommMode.h> // for galois::max, min
33 #include <galois/gIO.h> // for GALOIS DIE
34 
36 // Field flag class
38 
39 namespace galois {
40 namespace runtime {
41 
49  BOTH_INVALID //< both source and destinations on bitvector are invalid
50 };
51 
53 bool src_invalid(BITVECTOR_STATUS bv_flag);
55 bool dst_invalid(BITVECTOR_STATUS bv_flag);
57 void make_src_invalid(BITVECTOR_STATUS* bv_flag);
59 void make_dst_invalid(BITVECTOR_STATUS* bv_flag);
60 
65 class FieldFlags {
66 private:
67  uint8_t _s2s;
68  uint8_t _s2d;
69  uint8_t _d2s;
70  uint8_t _d2d;
71 
72 public:
82  _s2s = false;
83  _s2d = false;
84  _d2s = false;
85  _d2d = false;
87  }
88 
90  bool src_to_src() const { return _s2s; }
91 
93  bool src_to_dst() const { return _s2d; }
94 
96  bool dst_to_src() const { return _d2s; }
97 
99  bool dst_to_dst() const { return _d2d; }
100 
102  void set_write_src() {
103  _s2s = true;
104  _s2d = true;
105  }
106 
108  void set_write_dst() {
109  _d2s = true;
110  _d2d = true;
111  }
112 
114  void set_write_any() {
115  _s2s = true;
116  _s2d = true;
117  _d2s = true;
118  _d2d = true;
119  }
120 
122  void clear_read_src() {
123  _s2s = false;
124  _d2s = false;
125  }
126 
128  void clear_read_dst() {
129  _s2d = false;
130  _d2d = false;
131  }
132 
134  void clear_read_any() {
135  _s2d = false;
136  _d2d = false;
137  _s2s = false;
138  _d2s = false;
139  }
140 
142  void clear_all() {
143  _s2s = false;
144  _s2d = false;
145  _d2s = false;
146  _d2d = false;
148  }
149 };
150 
151 } // end namespace runtime
152 } // end namespace galois
153 
155 // Reduce Add, Edges
157 #ifdef GALOIS_ENABLE_GPU
158 #define GALOIS_SYNC_STRUCTURE_ADD_EDGES(fieldtype) \
159  struct EdgeAddReduce { \
160  using ValTy = fieldtype; \
161  \
162  static ValTy extract(uint64_t edgeID, ValTy& edgeData) { \
163  if (personality == GPU_CUDA) \
164  return get_edge_cuda(cuda_ctx, edgeID); \
165  assert(personality == CPU); \
166  return edgeData; \
167  } \
168  \
169  static bool extract_batch(unsigned from_id, uint8_t* y, size_t* s, \
170  DataCommMode* data_mode) { \
171  if (personality == GPU_CUDA) { \
172  batch_get_edge_cuda(cuda_ctx, from_id, y, s, data_mode); \
173  return true; \
174  } \
175  assert(personality == CPU); \
176  return false; \
177  } \
178  \
179  static bool extract_batch(unsigned from_id, uint8_t* y) { \
180  if (personality == GPU_CUDA) { \
181  batch_get_edge_cuda(cuda_ctx, from_id, y); \
182  return true; \
183  } \
184  assert(personality == CPU); \
185  return false; \
186  } \
187  \
188  static bool extract_reset_batch(unsigned from_id, uint8_t* y, size_t* s, \
189  DataCommMode* data_mode) { \
190  if (personality == GPU_CUDA) { \
191  batch_get_reset_edge_cuda(cuda_ctx, from_id, y, s, data_mode, \
192  (ValTy)0); \
193  return true; \
194  } \
195  assert(personality == CPU); \
196  return false; \
197  } \
198  \
199  static bool extract_reset_batch(unsigned from_id, uint8_t* y) { \
200  if (personality == GPU_CUDA) { \
201  batch_get_reset_edge_cuda(cuda_ctx, from_id, y, (ValTy)0); \
202  return true; \
203  } \
204  assert(personality == CPU); \
205  return false; \
206  } \
207  \
208  static bool reduce(uint64_t edgeID, ValTy& edgeData, ValTy y) { \
209  if (personality == GPU_CUDA) { \
210  add_edge_cuda(cuda_ctx, edgeID, y); \
211  return true; \
212  } \
213  assert(personality == CPU); \
214  edgeData += y; \
215  return true; \
216  } \
217  \
218  static bool reduce_batch(unsigned from_id, uint8_t* y, \
219  DataCommMode data_mode) { \
220  if (personality == GPU_CUDA) { \
221  batch_add_edge_cuda(cuda_ctx, from_id, y, data_mode); \
222  return true; \
223  } \
224  assert(personality == CPU); \
225  return false; \
226  } \
227  \
228  static bool reduce_mirror_batch(unsigned from_id, uint8_t* y, \
229  DataCommMode data_mode) { \
230  if (personality == GPU_CUDA) { \
231  batch_add_mirror_edge_cuda(cuda_ctx, from_id, y, data_mode); \
232  return true; \
233  } \
234  assert(personality == CPU); \
235  return false; \
236  } \
237  \
238  static void reset(uint64_t edgeID, ValTy& edgeData) { \
239  if (personality == GPU_CUDA) { \
240  set_edge_cuda(cuda_ctx, edgeID, (ValTy)0); \
241  } \
242  assert(personality == CPU); \
243  edgeData = 0; \
244  } \
245  \
246  static bool reset_batch(size_t GALOIS_UNUSED(begin), \
247  size_t GALOIS_UNUSED(end)) { \
248  if (personality == GPU_CUDA) { \
249  batch_reset_edge_cuda(cuda_ctx, begin, end, (ValTy)0); \
250  return true; \
251  } \
252  assert(personality == CPU); \
253  return false; \
254  } \
255  \
256  static void setVal(uint64_t edgeID, ValTy& edgeData, ValTy y) { \
257  if (personality == GPU_CUDA) { \
258  set_edge_cuda(cuda_ctx, edgeID, (ValTy)0); \
259  } \
260  assert(personality == CPU); \
261  edgeData = y; \
262  } \
263  \
264  static bool setVal_batch(unsigned from_id, uint8_t* y, \
265  DataCommMode data_mode) { \
266  if (personality == GPU_CUDA) { \
267  batch_set_mirror_edge_cuda(cuda_ctx, from_id, y, data_mode); \
268  return true; \
269  } \
270  assert(personality == CPU); \
271  return false; \
272  } \
273  };
274 #else
275 #define GALOIS_SYNC_STRUCTURE_ADD_EDGES(fieldtype) \
276  struct EdgeAddReduce { \
277  using ValTy = fieldtype; \
278  \
279  static ValTy extract(uint64_t edgeID, ValTy& edgeData) { \
280  return edgeData; \
281  } \
282  \
283  static bool extract_batch(unsigned, uint8_t*, size_t*, DataCommMode*) { \
284  return false; \
285  } \
286  \
287  static bool extract_batch(unsigned, uint8_t*) { return false; } \
288  \
289  static bool extract_reset_batch(unsigned, uint8_t*, size_t*, \
290  DataCommMode*) { \
291  return false; \
292  } \
293  \
294  static bool extract_reset_batch(unsigned, uint8_t*) { return false; } \
295  \
296  static bool reduce(uint64_t edgeID, ValTy& edgeData, ValTy y) { \
297  edgeData += y; \
298  return true; \
299  } \
300  \
301  static bool reduce_batch(unsigned, uint8_t*, DataCommMode) { \
302  return false; \
303  } \
304  \
305  static bool reduce_mirror_batch(unsigned, uint8_t*, DataCommMode) { \
306  return false; \
307  } \
308  \
309  static void reset(uint64_t edgeID, ValTy& edgeData) { edgeData = 0; } \
310  \
311  static void setVal(uint64_t edgeID, ValTy& edgeData, ValTy y) { \
312  edgeData = y; \
313  } \
314  \
315  static bool setVal_batch(unsigned, uint8_t*, DataCommMode) { \
316  return false; \
317  } \
318  };
319 #endif
320 
331 #ifdef GALOIS_ENABLE_GPU
332 // GPU code included
333 #define GALOIS_SYNC_STRUCTURE_BITSET_EDGES \
334  struct Bitset_edges { \
335  static constexpr bool is_vector_bitset() { return false; } \
336  static bool is_valid() { return true; } \
337  \
338  static galois::DynamicBitSet& get() { \
339  if (personality == GPU_CUDA) \
340  get_bitset_edge_cuda(cuda_ctx, \
341  (uint64_t*)bitset_edges.get_vec().data()); \
342  return bitset_edges; \
343  } \
344  \
345  static void reset_range(size_t begin, size_t end) { \
346  if (personality == GPU_CUDA) { \
347  bitset_edge_reset_cuda(cuda_ctx, begin, end); \
348  } else { \
349  assert(personality == CPU); \
350  bitset_edges.reset(begin, end); \
351  } \
352  } \
353  }
354 #else
355 // no GPU code
356 #define GALOIS_SYNC_STRUCTURE_BITSET_EDGES \
357  struct Bitset_edges { \
358  static constexpr bool is_vector_bitset() { return false; } \
359  \
360  static constexpr bool is_valid() { return true; } \
361  \
362  static galois::DynamicBitSet& get() { return bitset_edges; } \
363  \
364  static void reset_range(size_t begin, size_t end) { \
365  bitset_edges.reset(begin, end); \
366  } \
367  }
368 #endif
369 
371 // Reduce Add
373 
377 #ifdef GALOIS_ENABLE_GPU
378 // GPU code included
379 #define GALOIS_SYNC_STRUCTURE_REDUCE_ADD(fieldname, fieldtype) \
380  struct Reduce_add_##fieldname { \
381  typedef fieldtype ValTy; \
382  \
383  static ValTy extract(uint32_t node_id, const struct NodeData& node) { \
384  if (personality == GPU_CUDA) \
385  return get_node_##fieldname##_cuda(cuda_ctx, node_id); \
386  assert(personality == CPU); \
387  return node.fieldname; \
388  } \
389  \
390  static bool extract_batch(unsigned from_id, uint8_t* y, size_t* s, \
391  DataCommMode* data_mode) { \
392  if (personality == GPU_CUDA) { \
393  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, data_mode); \
394  return true; \
395  } \
396  assert(personality == CPU); \
397  return false; \
398  } \
399  \
400  static bool extract_batch(unsigned from_id, uint8_t* y) { \
401  if (personality == GPU_CUDA) { \
402  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y); \
403  return true; \
404  } \
405  assert(personality == CPU); \
406  return false; \
407  } \
408  \
409  static bool extract_reset_batch(unsigned from_id, uint8_t* y, size_t* s, \
410  DataCommMode* data_mode) { \
411  if (personality == GPU_CUDA) { \
412  batch_get_reset_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, \
413  data_mode, (ValTy)0); \
414  return true; \
415  } \
416  assert(personality == CPU); \
417  return false; \
418  } \
419  \
420  static bool extract_reset_batch(unsigned from_id, uint8_t* y) { \
421  if (personality == GPU_CUDA) { \
422  batch_get_reset_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
423  (ValTy)0); \
424  return true; \
425  } \
426  assert(personality == CPU); \
427  return false; \
428  } \
429  \
430  static bool reset_batch(size_t begin, size_t end) { \
431  if (personality == GPU_CUDA) { \
432  batch_reset_node_##fieldname##_cuda(cuda_ctx, begin, end, (ValTy)0); \
433  return true; \
434  } \
435  assert(personality == CPU); \
436  return false; \
437  } \
438  \
439  static bool reduce(uint32_t node_id, struct NodeData& node, ValTy y) { \
440  if (personality == GPU_CUDA) { \
441  add_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
442  return true; \
443  } \
444  assert(personality == CPU); \
445  { \
446  galois::add(node.fieldname, y); \
447  return true; \
448  } \
449  } \
450  \
451  static bool reduce_batch(unsigned from_id, uint8_t* y, \
452  DataCommMode data_mode) { \
453  if (personality == GPU_CUDA) { \
454  batch_add_node_##fieldname##_cuda(cuda_ctx, from_id, y, data_mode); \
455  return true; \
456  } \
457  assert(personality == CPU); \
458  return false; \
459  } \
460  \
461  static bool reduce_mirror_batch(unsigned from_id, uint8_t* y, \
462  DataCommMode data_mode) { \
463  if (personality == GPU_CUDA) { \
464  batch_add_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
465  data_mode); \
466  return true; \
467  } \
468  assert(personality == CPU); \
469  return false; \
470  } \
471  \
472  static void reset(uint32_t node_id, struct NodeData& node) { \
473  if (personality == GPU_CUDA) { \
474  set_node_##fieldname##_cuda(cuda_ctx, node_id, (ValTy)0); \
475  } else if (personality == CPU) \
476  galois::set(node.fieldname, (ValTy)0); \
477  } \
478  \
479  static void setVal(uint32_t node_id, struct NodeData& node, ValTy y) { \
480  if (personality == GPU_CUDA) \
481  set_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
482  else if (personality == CPU) \
483  node.fieldname = y; \
484  } \
485  \
486  static bool setVal_batch(unsigned from_id, uint8_t* y, \
487  DataCommMode data_mode) { \
488  if (personality == GPU_CUDA) { \
489  batch_set_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
490  data_mode); \
491  return true; \
492  } \
493  assert(personality == CPU); \
494  return false; \
495  } \
496  }
497 #else
498 // Non-GPU code
499 #define GALOIS_SYNC_STRUCTURE_REDUCE_ADD(fieldname, fieldtype) \
500  struct Reduce_add_##fieldname { \
501  typedef fieldtype ValTy; \
502  \
503  static ValTy extract(uint32_t, const struct NodeData& node) { \
504  return node.fieldname; \
505  } \
506  \
507  static bool extract_batch(unsigned, uint8_t*, size_t*, DataCommMode*) { \
508  return false; \
509  } \
510  \
511  static bool extract_batch(unsigned, uint8_t*) { return false; } \
512  \
513  static bool extract_reset_batch(unsigned, uint8_t*, size_t*, \
514  DataCommMode*) { \
515  return false; \
516  } \
517  \
518  static bool extract_reset_batch(unsigned, uint8_t*) { return false; } \
519  \
520  static bool reset_batch(size_t, size_t) { return false; } \
521  \
522  static bool reduce(uint32_t, struct NodeData& node, ValTy y) { \
523  { \
524  galois::add(node.fieldname, y); \
525  return true; \
526  } \
527  } \
528  \
529  static bool reduce_batch(unsigned, uint8_t*, DataCommMode) { \
530  return false; \
531  } \
532  \
533  static bool reduce_mirror_batch(unsigned, uint8_t*, DataCommMode) { \
534  return false; \
535  } \
536  \
537  static void reset(uint32_t, struct NodeData& node) { \
538  galois::set(node.fieldname, (ValTy)0); \
539  } \
540  \
541  static void setVal(uint32_t, struct NodeData& node, ValTy y) { \
542  node.fieldname = y; \
543  } \
544  \
545  static bool setVal_batch(unsigned, uint8_t*, DataCommMode) { \
546  return false; \
547  } \
548  }
549 #endif
550 
555 #ifdef GALOIS_ENABLE_GPU
556 // GPU code included
557 #define GALOIS_SYNC_STRUCTURE_REDUCE_ADD_ARRAY(fieldname, fieldtype) \
558  struct Reduce_add_##fieldname { \
559  typedef fieldtype ValTy; \
560  \
561  static ValTy extract(uint32_t node_id, const struct NodeData& node) { \
562  if (personality == GPU_CUDA) \
563  return get_node_##fieldname##_cuda(cuda_ctx, node_id); \
564  assert(personality == CPU); \
565  return fieldname[node_id]; \
566  } \
567  \
568  static bool extract_batch(unsigned from_id, uint8_t* y, size_t* s, \
569  DataCommMode* data_mode) { \
570  if (personality == GPU_CUDA) { \
571  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, data_mode); \
572  return true; \
573  } \
574  assert(personality == CPU); \
575  return false; \
576  } \
577  \
578  static bool extract_batch(unsigned from_id, uint8_t* y) { \
579  if (personality == GPU_CUDA) { \
580  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y); \
581  return true; \
582  } \
583  assert(personality == CPU); \
584  return false; \
585  } \
586  \
587  static bool extract_reset_batch(unsigned from_id, uint8_t* y, size_t* s, \
588  DataCommMode* data_mode) { \
589  if (personality == GPU_CUDA) { \
590  batch_get_reset_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, \
591  data_mode, (ValTy)0); \
592  return true; \
593  } \
594  assert(personality == CPU); \
595  return false; \
596  } \
597  \
598  static bool extract_reset_batch(unsigned from_id, uint8_t* y) { \
599  if (personality == GPU_CUDA) { \
600  batch_get_reset_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
601  (ValTy)0); \
602  return true; \
603  } \
604  assert(personality == CPU); \
605  return false; \
606  } \
607  \
608  static bool reset_batch(size_t begin, size_t end) { \
609  if (personality == GPU_CUDA) { \
610  batch_reset_node_##fieldname##_cuda(cuda_ctx, begin, end, (ValTy)0); \
611  return true; \
612  } \
613  assert(personality == CPU); \
614  return false; \
615  } \
616  \
617  static bool reduce(uint32_t node_id, struct NodeData& GALOIS_UNUSED(node), \
618  ValTy y) { \
619  if (personality == GPU_CUDA) { \
620  add_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
621  return true; \
622  } \
623  assert(personality == CPU); \
624  { \
625  galois::add(fieldname[node_id], y); \
626  return true; \
627  } \
628  } \
629  \
630  static bool reduce_batch(unsigned from_id, uint8_t* y, \
631  DataCommMode data_mode) { \
632  if (personality == GPU_CUDA) { \
633  batch_add_node_##fieldname##_cuda(cuda_ctx, from_id, y, data_mode); \
634  return true; \
635  } \
636  assert(personality == CPU); \
637  return false; \
638  } \
639  \
640  static bool reduce_mirror_batch(unsigned from_id, uint8_t* y, \
641  DataCommMode data_mode) { \
642  if (personality == GPU_CUDA) { \
643  batch_add_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
644  data_mode); \
645  return true; \
646  } \
647  assert(personality == CPU); \
648  return false; \
649  } \
650  \
651  static void reset(uint32_t node_id, \
652  struct NodeData& GALOIS_UNUSED(node)) { \
653  if (personality == GPU_CUDA) { \
654  set_node_##fieldname##_cuda(cuda_ctx, node_id, (ValTy)0); \
655  } else if (personality == CPU) \
656  galois::set(fieldname[node_id], (ValTy)0); \
657  } \
658  \
659  static void setVal(uint32_t node_id, struct NodeData& GALOIS_UNUSED(node), \
660  ValTy y) { \
661  if (personality == GPU_CUDA) \
662  set_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
663  else if (personality == CPU) \
664  fieldname[node_id] = y; \
665  } \
666  \
667  static bool setVal_batch(unsigned from_id, uint8_t* y, \
668  DataCommMode data_mode) { \
669  if (personality == GPU_CUDA) { \
670  batch_set_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
671  data_mode); \
672  return true; \
673  } \
674  assert(personality == CPU); \
675  return false; \
676  } \
677  }
678 #else
679 // Non-GPU code
680 #define GALOIS_SYNC_STRUCTURE_REDUCE_ADD_ARRAY(fieldname, fieldtype) \
681  struct Reduce_add_##fieldname { \
682  typedef fieldtype ValTy; \
683  \
684  static ValTy extract(uint32_t node_id, const struct NodeData& node) { \
685  return fieldname[node_id]; \
686  } \
687  \
688  static bool extract_batch(unsigned from_id, uint8_t* y, size_t* s, \
689  DataCommMode* data_mode) { \
690  return false; \
691  } \
692  \
693  static bool extract_batch(unsigned from_id, uint8_t* y) { return false; } \
694  \
695  static bool extract_reset_batch(unsigned from_id, uint8_t* y, size_t* s, \
696  DataCommMode* data_mode) { \
697  return false; \
698  } \
699  \
700  static bool extract_reset_batch(unsigned from_id, uint8_t* y) { \
701  return false; \
702  } \
703  \
704  static bool reset_batch(size_t GALOIS_UNUSED(begin), \
705  size_t GALOIS_UNUSED(end)) { \
706  return false; \
707  } \
708  \
709  static bool reduce(uint32_t node_id, struct NodeData& GALOIS_UNUSED(node), \
710  ValTy y) { \
711  { \
712  galois::add(fieldname[node_id], y); \
713  return true; \
714  } \
715  } \
716  \
717  static bool reduce_batch(unsigned from_id, uint8_t* y, \
718  DataCommMode data_mode) { \
719  return false; \
720  } \
721  \
722  static bool reduce_mirror_batch(unsigned from_id, uint8_t* y, \
723  DataCommMode data_mode) { \
724  return false; \
725  } \
726  \
727  static void reset(uint32_t node_id, \
728  struct NodeData& GALOIS_UNUSED(node)) { \
729  galois::set(fieldname[node_id], (ValTy)0); \
730  } \
731  \
732  static void setVal(uint32_t node_id, struct NodeData& GALOIS_UNUSED(node), \
733  ValTy y) { \
734  fieldname[node_id] = y; \
735  } \
736  \
737  static bool setVal_batch(unsigned from_id, uint8_t* y, \
738  DataCommMode data_mode) { \
739  return false; \
740  } \
741  }
742 #endif
743 
745 // Reduce Set
747 
751 #ifdef GALOIS_ENABLE_GPU
752 // GPU code included
753 #define GALOIS_SYNC_STRUCTURE_REDUCE_SET(fieldname, fieldtype) \
754  struct Reduce_set_##fieldname { \
755  typedef fieldtype ValTy; \
756  \
757  static ValTy extract(uint32_t node_id, const struct NodeData& node) { \
758  if (personality == GPU_CUDA) \
759  return get_node_##fieldname##_cuda(cuda_ctx, node_id); \
760  assert(personality == CPU); \
761  return node.fieldname; \
762  } \
763  \
764  static bool extract_batch(unsigned from_id, uint8_t* y, size_t* s, \
765  DataCommMode* data_mode) { \
766  if (personality == GPU_CUDA) { \
767  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, data_mode); \
768  return true; \
769  } \
770  assert(personality == CPU); \
771  return false; \
772  } \
773  \
774  static bool extract_batch(unsigned from_id, uint8_t* y) { \
775  if (personality == GPU_CUDA) { \
776  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y); \
777  return true; \
778  } \
779  assert(personality == CPU); \
780  return false; \
781  } \
782  \
783  static bool extract_reset_batch(unsigned from_id, uint8_t* y, size_t* s, \
784  DataCommMode* data_mode) { \
785  if (personality == GPU_CUDA) { \
786  batch_get_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, \
787  data_mode); \
788  return true; \
789  } \
790  assert(personality == CPU); \
791  return false; \
792  } \
793  \
794  static bool extract_reset_batch(unsigned from_id, uint8_t* y) { \
795  if (personality == GPU_CUDA) { \
796  batch_get_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y); \
797  return true; \
798  } \
799  assert(personality == CPU); \
800  return false; \
801  } \
802  \
803  static bool reset_batch(size_t GALOIS_UNUSED(begin), \
804  size_t GALOIS_UNUSED(end)) { \
805  return true; \
806  } \
807  \
808  static bool reduce(uint32_t node_id, struct NodeData& node, ValTy y) { \
809  if (personality == GPU_CUDA) { \
810  set_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
811  return true; \
812  } \
813  assert(personality == CPU); \
814  { \
815  galois::set(node.fieldname, y); \
816  return true; \
817  } \
818  } \
819  \
820  static bool reduce_batch(unsigned from_id, uint8_t* y, \
821  DataCommMode data_mode) { \
822  if (personality == GPU_CUDA) { \
823  batch_set_node_##fieldname##_cuda(cuda_ctx, from_id, y, data_mode); \
824  return true; \
825  } \
826  assert(personality == CPU); \
827  return false; \
828  } \
829  \
830  static bool reduce_mirror_batch(unsigned from_id, uint8_t* y, \
831  DataCommMode data_mode) { \
832  if (personality == GPU_CUDA) { \
833  batch_set_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
834  data_mode); \
835  return true; \
836  } \
837  assert(personality == CPU); \
838  return false; \
839  } \
840  \
841  static void reset(uint32_t GALOIS_UNUSED(node_id), \
842  struct NodeData& GALOIS_UNUSED(node)) {} \
843  \
844  static void setVal(uint32_t node_id, struct NodeData& node, ValTy y) { \
845  if (personality == GPU_CUDA) \
846  set_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
847  else if (personality == CPU) \
848  node.fieldname = y; \
849  } \
850  \
851  static bool setVal_batch(unsigned from_id, uint8_t* y, \
852  DataCommMode data_mode) { \
853  if (personality == GPU_CUDA) { \
854  batch_set_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
855  data_mode); \
856  return true; \
857  } \
858  assert(personality == CPU); \
859  return false; \
860  } \
861  }
862 #else
863 // Non-GPU code
864 #define GALOIS_SYNC_STRUCTURE_REDUCE_SET(fieldname, fieldtype) \
865  struct Reduce_set_##fieldname { \
866  typedef fieldtype ValTy; \
867  \
868  static ValTy extract(uint32_t, const struct NodeData& node) { \
869  return node.fieldname; \
870  } \
871  \
872  static bool extract_batch(unsigned, uint8_t*, size_t*, DataCommMode*) { \
873  return false; \
874  } \
875  \
876  static bool extract_batch(unsigned, uint8_t*) { return false; } \
877  \
878  static bool extract_reset_batch(unsigned, uint8_t*, size_t*, \
879  DataCommMode*) { \
880  return false; \
881  } \
882  \
883  static bool extract_reset_batch(unsigned, uint8_t*) { return false; } \
884  \
885  static bool reset_batch(size_t, size_t) { return true; } \
886  \
887  static bool reduce(uint32_t, struct NodeData& node, ValTy y) { \
888  { \
889  galois::set(node.fieldname, y); \
890  return true; \
891  } \
892  } \
893  \
894  static bool reduce_batch(unsigned, uint8_t*, DataCommMode) { \
895  return false; \
896  } \
897  \
898  static bool reduce_mirror_batch(unsigned, uint8_t*, DataCommMode) { \
899  return false; \
900  } \
901  \
902  static void reset(uint32_t, struct NodeData&) {} \
903  \
904  static void setVal(uint32_t, struct NodeData& node, ValTy y) { \
905  node.fieldname = y; \
906  } \
907  \
908  static bool setVal_batch(unsigned, uint8_t*, DataCommMode) { \
909  return false; \
910  } \
911  }
912 #endif
913 
918 #ifdef GALOIS_ENABLE_GPU
919 // GPU code included
920 #define GALOIS_SYNC_STRUCTURE_REDUCE_SET_ARRAY(fieldname, fieldtype) \
921  struct Reduce_set_##fieldname { \
922  typedef fieldtype ValTy; \
923  \
924  static ValTy extract(uint32_t node_id, const struct NodeData& node) { \
925  if (personality == GPU_CUDA) \
926  return get_node_##fieldname##_cuda(cuda_ctx, node_id); \
927  assert(personality == CPU); \
928  return fieldname[node_id]; \
929  } \
930  \
931  static bool extract_batch(unsigned from_id, uint8_t* y, size_t* s, \
932  DataCommMode* data_mode) { \
933  if (personality == GPU_CUDA) { \
934  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, data_mode); \
935  return true; \
936  } \
937  assert(personality == CPU); \
938  return false; \
939  } \
940  \
941  static bool extract_batch(unsigned from_id, uint8_t* y) { \
942  if (personality == GPU_CUDA) { \
943  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y); \
944  return true; \
945  } \
946  assert(personality == CPU); \
947  return false; \
948  } \
949  \
950  static bool extract_reset_batch(unsigned from_id, uint8_t* y, size_t* s, \
951  DataCommMode* data_mode) { \
952  if (personality == GPU_CUDA) { \
953  batch_get_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, \
954  data_mode); \
955  return true; \
956  } \
957  assert(personality == CPU); \
958  return false; \
959  } \
960  \
961  static bool extract_reset_batch(unsigned from_id, uint8_t* y) { \
962  if (personality == GPU_CUDA) { \
963  batch_get_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y); \
964  return true; \
965  } \
966  assert(personality == CPU); \
967  return false; \
968  } \
969  \
970  static bool reset_batch(size_t GALOIS_UNUSED(begin), \
971  size_t GALOIS_UNUSED(end)) { \
972  return true; \
973  } \
974  \
975  static bool reduce(uint32_t node_id, struct NodeData& GALOIS_UNUSED(node), \
976  ValTy y) { \
977  if (personality == GPU_CUDA) { \
978  set_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
979  return true; \
980  } \
981  assert(personality == CPU); \
982  { \
983  galois::set(fieldname[node_id], y); \
984  return true; \
985  } \
986  } \
987  \
988  static bool reduce_batch(unsigned from_id, uint8_t* y, \
989  DataCommMode data_mode) { \
990  if (personality == GPU_CUDA) { \
991  batch_set_node_##fieldname##_cuda(cuda_ctx, from_id, y, data_mode); \
992  return true; \
993  } \
994  assert(personality == CPU); \
995  return false; \
996  } \
997  \
998  static bool reduce_mirror_batch(unsigned from_id, uint8_t* y, \
999  DataCommMode data_mode) { \
1000  if (personality == GPU_CUDA) { \
1001  batch_set_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
1002  data_mode); \
1003  return true; \
1004  } \
1005  assert(personality == CPU); \
1006  return false; \
1007  } \
1008  \
1009  static void reset(uint32_t GALOIS_UNUSED(node_id), \
1010  struct NodeData& GALOIS_UNUSED(node)) {} \
1011  \
1012  static void setVal(uint32_t node_id, struct NodeData& GALOIS_UNUSED(node), \
1013  ValTy y) { \
1014  if (personality == GPU_CUDA) \
1015  set_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
1016  else if (personality == CPU) \
1017  fieldname[node_id] = y; \
1018  } \
1019  \
1020  static bool setVal_batch(unsigned from_id, uint8_t* y, \
1021  DataCommMode data_mode) { \
1022  if (personality == GPU_CUDA) { \
1023  batch_set_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
1024  data_mode); \
1025  return true; \
1026  } \
1027  assert(personality == CPU); \
1028  return false; \
1029  } \
1030  }
1031 #else
1032 // Non-GPU code
1033 #define GALOIS_SYNC_STRUCTURE_REDUCE_SET_ARRAY(fieldname, fieldtype) \
1034  struct Reduce_set_##fieldname { \
1035  typedef fieldtype ValTy; \
1036  \
1037  static ValTy extract(uint32_t node_id, const struct NodeData& node) { \
1038  return fieldname[node_id]; \
1039  } \
1040  \
1041  static bool extract_batch(unsigned from_id, uint8_t* y, size_t* s, \
1042  DataCommMode* data_mode) { \
1043  return false; \
1044  } \
1045  \
1046  static bool extract_batch(unsigned from_id, uint8_t* y) { return false; } \
1047  \
1048  static bool extract_reset_batch(unsigned from_id, uint8_t* y, size_t* s, \
1049  DataCommMode* data_mode) { \
1050  return false; \
1051  } \
1052  \
1053  static bool extract_reset_batch(unsigned from_id, uint8_t* y) { \
1054  return false; \
1055  } \
1056  \
1057  static bool reset_batch(size_t GALOIS_UNUSED(begin), \
1058  size_t GALOIS_UNUSED(end)) { \
1059  return true; \
1060  } \
1061  \
1062  static bool reduce(uint32_t node_id, struct NodeData& GALOIS_UNUSED(node), \
1063  ValTy y) { \
1064  { \
1065  galois::set(fieldname[node_id], y); \
1066  return true; \
1067  } \
1068  } \
1069  \
1070  static bool reduce_batch(unsigned from_id, uint8_t* y, \
1071  DataCommMode data_mode) { \
1072  return false; \
1073  } \
1074  \
1075  static bool reduce_mirror_batch(unsigned from_id, uint8_t* y, \
1076  DataCommMode data_mode) { \
1077  return false; \
1078  } \
1079  \
1080  static void reset(uint32_t GALOIS_UNUSED(node_id), \
1081  struct NodeData& GALOIS_UNUSED(node)) {} \
1082  \
1083  static void setVal(uint32_t node_id, struct NodeData& GALOIS_UNUSED(node), \
1084  ValTy y) { \
1085  fieldname[node_id] = y; \
1086  } \
1087  \
1088  static bool setVal_batch(unsigned from_id, uint8_t* y, \
1089  DataCommMode data_mode) { \
1090  return false; \
1091  } \
1092  }
1093 #endif
1094 
1096 // Reduce Min
1098 
1102 #ifdef GALOIS_ENABLE_GPU
1103 // GPU code included
1104 #define GALOIS_SYNC_STRUCTURE_REDUCE_MIN(fieldname, fieldtype) \
1105  struct Reduce_min_##fieldname { \
1106  typedef fieldtype ValTy; \
1107  \
1108  static ValTy extract(uint32_t node_id, const struct NodeData& node) { \
1109  if (personality == GPU_CUDA) \
1110  return get_node_##fieldname##_cuda(cuda_ctx, node_id); \
1111  assert(personality == CPU); \
1112  return node.fieldname; \
1113  } \
1114  \
1115  static bool extract_batch(unsigned from_id, uint8_t* y, size_t* s, \
1116  DataCommMode* data_mode) { \
1117  if (personality == GPU_CUDA) { \
1118  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, data_mode); \
1119  return true; \
1120  } \
1121  assert(personality == CPU); \
1122  return false; \
1123  } \
1124  \
1125  static bool extract_batch(unsigned from_id, uint8_t* y) { \
1126  if (personality == GPU_CUDA) { \
1127  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y); \
1128  return true; \
1129  } \
1130  assert(personality == CPU); \
1131  return false; \
1132  } \
1133  \
1134  static bool extract_reset_batch(unsigned from_id, uint8_t* y, size_t* s, \
1135  DataCommMode* data_mode) { \
1136  if (personality == GPU_CUDA) { \
1137  batch_get_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, \
1138  data_mode); \
1139  return true; \
1140  } \
1141  assert(personality == CPU); \
1142  return false; \
1143  } \
1144  \
1145  static bool extract_reset_batch(unsigned from_id, uint8_t* y) { \
1146  if (personality == GPU_CUDA) { \
1147  batch_get_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y); \
1148  return true; \
1149  } \
1150  assert(personality == CPU); \
1151  return false; \
1152  } \
1153  \
1154  static bool reset_batch(size_t GALOIS_UNUSED(begin), \
1155  size_t GALOIS_UNUSED(end)) { \
1156  return true; \
1157  } \
1158  \
1159  static bool reduce(uint32_t node_id, struct NodeData& node, ValTy y) { \
1160  if (personality == GPU_CUDA) { \
1161  return y < min_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
1162  } \
1163  assert(personality == CPU); \
1164  { return y < galois::min(node.fieldname, y); } \
1165  } \
1166  \
1167  static bool reduce_batch(unsigned from_id, uint8_t* y, \
1168  DataCommMode data_mode) { \
1169  if (personality == GPU_CUDA) { \
1170  batch_min_node_##fieldname##_cuda(cuda_ctx, from_id, y, data_mode); \
1171  return true; \
1172  } \
1173  assert(personality == CPU); \
1174  return false; \
1175  } \
1176  \
1177  static bool reduce_mirror_batch(unsigned from_id, uint8_t* y, \
1178  DataCommMode data_mode) { \
1179  if (personality == GPU_CUDA) { \
1180  batch_min_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
1181  data_mode); \
1182  return true; \
1183  } \
1184  assert(personality == CPU); \
1185  return false; \
1186  } \
1187  \
1188  static void reset(uint32_t GALOIS_UNUSED(node_id), \
1189  struct NodeData& GALOIS_UNUSED(node)) {} \
1190  \
1191  static void setVal(uint32_t node_id, struct NodeData& node, ValTy y) { \
1192  if (personality == GPU_CUDA) \
1193  set_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
1194  else if (personality == CPU) \
1195  node.fieldname = y; \
1196  } \
1197  \
1198  static bool setVal_batch(unsigned from_id, uint8_t* y, \
1199  DataCommMode data_mode) { \
1200  if (personality == GPU_CUDA) { \
1201  batch_set_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
1202  data_mode); \
1203  return true; \
1204  } \
1205  assert(personality == CPU); \
1206  return false; \
1207  } \
1208  }
1209 #else
1210 // Non-GPU code
1211 #define GALOIS_SYNC_STRUCTURE_REDUCE_MIN(fieldname, fieldtype) \
1212  struct Reduce_min_##fieldname { \
1213  typedef fieldtype ValTy; \
1214  \
1215  static ValTy extract(uint32_t, const struct NodeData& node) { \
1216  return node.fieldname; \
1217  } \
1218  \
1219  static bool extract_batch(unsigned, uint8_t*, size_t*, DataCommMode*) { \
1220  return false; \
1221  } \
1222  \
1223  static bool extract_batch(unsigned, uint8_t*) { return false; } \
1224  \
1225  static bool extract_reset_batch(unsigned, uint8_t*, size_t*, \
1226  DataCommMode*) { \
1227  return false; \
1228  } \
1229  \
1230  static bool extract_reset_batch(unsigned, uint8_t*) { return false; } \
1231  \
1232  static bool reset_batch(size_t, size_t) { return true; } \
1233  \
1234  static bool reduce(uint32_t, struct NodeData& node, ValTy y) { \
1235  { return y < galois::min(node.fieldname, y); } \
1236  } \
1237  \
1238  static bool reduce_batch(unsigned, uint8_t*, DataCommMode) { \
1239  return false; \
1240  } \
1241  \
1242  static bool reduce_mirror_batch(unsigned, uint8_t*, DataCommMode) { \
1243  return false; \
1244  } \
1245  \
1246  static void reset(uint32_t, struct NodeData&) {} \
1247  \
1248  static void setVal(uint32_t, struct NodeData& node, ValTy y) { \
1249  node.fieldname = y; \
1250  } \
1251  \
1252  static bool setVal_batch(unsigned, uint8_t*, DataCommMode) { \
1253  return false; \
1254  } \
1255  }
1256 #endif
1257 
1259 // Reduce Max
1261 
1265 #ifdef GALOIS_ENABLE_GPU
1266 // GPU code included
1267 #define GALOIS_SYNC_STRUCTURE_REDUCE_MAX(fieldname, fieldtype) \
1268  struct Reduce_max_##fieldname { \
1269  typedef fieldtype ValTy; \
1270  \
1271  static ValTy extract(uint32_t node_id, const struct NodeData& node) { \
1272  if (personality == GPU_CUDA) \
1273  return get_node_##fieldname##_cuda(cuda_ctx, node_id); \
1274  assert(personality == CPU); \
1275  return node.fieldname; \
1276  } \
1277  \
1278  static bool extract_batch(unsigned from_id, uint8_t* y, size_t* s, \
1279  DataCommMode* data_mode) { \
1280  if (personality == GPU_CUDA) { \
1281  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, data_mode); \
1282  return true; \
1283  } \
1284  assert(personality == CPU); \
1285  return false; \
1286  } \
1287  \
1288  static bool extract_batch(unsigned from_id, uint8_t* y) { \
1289  if (personality == GPU_CUDA) { \
1290  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y); \
1291  return true; \
1292  } \
1293  assert(personality == CPU); \
1294  return false; \
1295  } \
1296  \
1297  static bool extract_reset_batch(unsigned from_id, uint8_t* y, size_t* s, \
1298  DataCommMode* data_mode) { \
1299  if (personality == GPU_CUDA) { \
1300  batch_get_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, \
1301  data_mode); \
1302  return true; \
1303  } \
1304  assert(personality == CPU); \
1305  return false; \
1306  } \
1307  \
1308  static bool extract_reset_batch(unsigned from_id, uint8_t* y) { \
1309  if (personality == GPU_CUDA) { \
1310  batch_get_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y); \
1311  return true; \
1312  } \
1313  assert(personality == CPU); \
1314  return false; \
1315  } \
1316  \
1317  static bool reset_batch(size_t GALOIS_UNUSED(begin), \
1318  size_t GALOIS_UNUSED(end)) { \
1319  return true; \
1320  } \
1321  \
1322  static bool reduce(uint32_t node_id, struct NodeData& node, ValTy y) { \
1323  if (personality == GPU_CUDA) { \
1324  return y > max_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
1325  } \
1326  assert(personality == CPU); \
1327  { return y > galois::max(node.fieldname, y); } \
1328  } \
1329  \
1330  static bool reduce_batch(unsigned from_id, uint8_t* y, \
1331  DataCommMode data_mode) { \
1332  if (personality == GPU_CUDA) { \
1333  batch_max_node_##fieldname##_cuda(cuda_ctx, from_id, y, data_mode); \
1334  return true; \
1335  } \
1336  assert(personality == CPU); \
1337  return false; \
1338  } \
1339  \
1340  static bool reduce_mirror_batch(unsigned from_id, uint8_t* y, \
1341  DataCommMode data_mode) { \
1342  if (personality == GPU_CUDA) { \
1343  batch_max_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
1344  data_mode); \
1345  return true; \
1346  } \
1347  assert(personality == CPU); \
1348  return false; \
1349  } \
1350  \
1351  static void reset(uint32_t GALOIS_UNUSED(node_id), \
1352  struct NodeData& GALOIS_UNUSED(node)) {} \
1353  \
1354  static void setVal(uint32_t node_id, struct NodeData& node, ValTy y) { \
1355  if (personality == GPU_CUDA) \
1356  set_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
1357  else if (personality == CPU) \
1358  node.fieldname = y; \
1359  } \
1360  \
1361  static bool setVal_batch(unsigned from_id, uint8_t* y, \
1362  DataCommMode data_mode) { \
1363  if (personality == GPU_CUDA) { \
1364  batch_set_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
1365  data_mode); \
1366  return true; \
1367  } \
1368  assert(personality == CPU); \
1369  return false; \
1370  } \
1371  }
1372 #else
1373 // Non-GPU code
1374 #define GALOIS_SYNC_STRUCTURE_REDUCE_MAX(fieldname, fieldtype) \
1375  struct Reduce_max_##fieldname { \
1376  typedef fieldtype ValTy; \
1377  \
1378  static ValTy extract(uint32_t node_id, const struct NodeData& node) { \
1379  return node.fieldname; \
1380  } \
1381  \
1382  static bool extract_batch(unsigned from_id, uint8_t* y, size_t* s, \
1383  DataCommMode* data_mode) { \
1384  return false; \
1385  } \
1386  \
1387  static bool extract_batch(unsigned from_id, uint8_t* y) { return false; } \
1388  \
1389  static bool extract_reset_batch(unsigned from_id, uint8_t* y, size_t* s, \
1390  DataCommMode* data_mode) { \
1391  return false; \
1392  } \
1393  \
1394  static bool extract_reset_batch(unsigned from_id, uint8_t* y) { \
1395  return false; \
1396  } \
1397  \
1398  static bool reset_batch(size_t GALOIS_UNUSED(begin), \
1399  size_t GALOIS_UNUSED(end)) { \
1400  return true; \
1401  } \
1402  \
1403  static bool reduce(uint32_t GALOIS_UNUSED(node_id), struct NodeData& node, \
1404  ValTy y) { \
1405  { return y > galois::max(node.fieldname, y); } \
1406  } \
1407  \
1408  static bool reduce_batch(unsigned from_id, uint8_t* y, \
1409  DataCommMode data_mode) { \
1410  return false; \
1411  } \
1412  \
1413  static bool reduce_mirror_batch(unsigned from_id, uint8_t* y, \
1414  DataCommMode data_mode) { \
1415  return false; \
1416  } \
1417  \
1418  static void reset(uint32_t GALOIS_UNUSED(node_id), \
1419  struct NodeData& GALOIS_UNUSED(node)) {} \
1420  \
1421  static void setVal(uint32_t GALOIS_UNUSED(node_id), struct NodeData& node, \
1422  ValTy y) { \
1423  node.fieldname = y; \
1424  } \
1425  \
1426  static bool setVal_batch(unsigned from_id, uint8_t* y, \
1427  DataCommMode data_mode) { \
1428  return false; \
1429  } \
1430  }
1431 #endif
1432 
1437 #ifdef GALOIS_ENABLE_GPU
1438 // GPU code included
1439 #define GALOIS_SYNC_STRUCTURE_REDUCE_MIN_ARRAY(fieldname, fieldtype) \
1440  struct Reduce_min_##fieldname { \
1441  typedef fieldtype ValTy; \
1442  \
1443  static ValTy extract(uint32_t node_id, const struct NodeData& node) { \
1444  if (personality == GPU_CUDA) \
1445  return get_node_##fieldname##_cuda(cuda_ctx, node_id); \
1446  assert(personality == CPU); \
1447  return fieldname[node_id]; \
1448  } \
1449  \
1450  static bool extract_batch(unsigned from_id, uint8_t* y, size_t* s, \
1451  DataCommMode* data_mode) { \
1452  if (personality == GPU_CUDA) { \
1453  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, data_mode); \
1454  return true; \
1455  } \
1456  assert(personality == CPU); \
1457  return false; \
1458  } \
1459  \
1460  static bool extract_batch(unsigned from_id, uint8_t* y) { \
1461  if (personality == GPU_CUDA) { \
1462  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y); \
1463  return true; \
1464  } \
1465  assert(personality == CPU); \
1466  return false; \
1467  } \
1468  \
1469  static bool extract_reset_batch(unsigned from_id, uint8_t* y, size_t* s, \
1470  DataCommMode* data_mode) { \
1471  if (personality == GPU_CUDA) { \
1472  batch_get_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, \
1473  data_mode); \
1474  return true; \
1475  } \
1476  assert(personality == CPU); \
1477  return false; \
1478  } \
1479  \
1480  static bool extract_reset_batch(unsigned from_id, uint8_t* y) { \
1481  if (personality == GPU_CUDA) { \
1482  batch_get_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y); \
1483  return true; \
1484  } \
1485  assert(personality == CPU); \
1486  return false; \
1487  } \
1488  \
1489  static bool reset_batch(size_t GALOIS_UNUSED(begin), \
1490  size_t GALOIS_UNUSED(end)) { \
1491  return true; \
1492  } \
1493  \
1494  static bool reduce(uint32_t node_id, struct NodeData& GALOIS_UNUSED(node), \
1495  ValTy y) { \
1496  if (personality == GPU_CUDA) { \
1497  return y < min_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
1498  } \
1499  assert(personality == CPU); \
1500  { return y < galois::min(fieldname[node_id], y); } \
1501  } \
1502  \
1503  static bool reduce_batch(unsigned from_id, uint8_t* y, \
1504  DataCommMode data_mode) { \
1505  if (personality == GPU_CUDA) { \
1506  batch_min_node_##fieldname##_cuda(cuda_ctx, from_id, y, data_mode); \
1507  return true; \
1508  } \
1509  assert(personality == CPU); \
1510  return false; \
1511  } \
1512  \
1513  static bool reduce_mirror_batch(unsigned from_id, uint8_t* y, \
1514  DataCommMode data_mode) { \
1515  if (personality == GPU_CUDA) { \
1516  batch_min_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
1517  data_mode); \
1518  return true; \
1519  } \
1520  assert(personality == CPU); \
1521  return false; \
1522  } \
1523  \
1524  static void reset(uint32_t GALOIS_UNUSED(node_id), \
1525  struct NodeData& GALOIS_UNUSED(node)) {} \
1526  \
1527  static void setVal(uint32_t node_id, struct NodeData& GALOIS_UNUSED(node), \
1528  ValTy y) { \
1529  if (personality == GPU_CUDA) \
1530  set_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
1531  else if (personality == CPU) \
1532  fieldname[node_id] = y; \
1533  } \
1534  \
1535  static bool setVal_batch(unsigned from_id, uint8_t* y, \
1536  DataCommMode data_mode) { \
1537  if (personality == GPU_CUDA) { \
1538  batch_set_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
1539  data_mode); \
1540  return true; \
1541  } \
1542  assert(personality == CPU); \
1543  return false; \
1544  } \
1545  }
1546 #else
1547 // Non-GPU code
1548 #define GALOIS_SYNC_STRUCTURE_REDUCE_MIN_ARRAY(fieldname, fieldtype) \
1549  struct Reduce_min_##fieldname { \
1550  typedef fieldtype ValTy; \
1551  \
1552  static ValTy extract(uint32_t node_id, const struct NodeData& node) { \
1553  return fieldname[node_id]; \
1554  } \
1555  \
1556  static bool extract_batch(unsigned from_id, uint8_t* y, size_t* s, \
1557  DataCommMode* data_mode) { \
1558  return false; \
1559  } \
1560  \
1561  static bool extract_batch(unsigned from_id, uint8_t* y) { return false; } \
1562  \
1563  static bool extract_reset_batch(unsigned from_id, uint8_t* y, size_t* s, \
1564  DataCommMode* data_mode) { \
1565  return false; \
1566  } \
1567  \
1568  static bool extract_reset_batch(unsigned from_id, uint8_t* y) { \
1569  return false; \
1570  } \
1571  \
1572  static bool reset_batch(size_t GALOIS_UNUSED(begin), \
1573  size_t GALOIS_UNUSED(end)) { \
1574  return true; \
1575  } \
1576  \
1577  static bool reduce(uint32_t node_id, struct NodeData& GALOIS_UNUSED(node), \
1578  ValTy y) { \
1579  { return y < galois::min(fieldname[node_id], y); } \
1580  } \
1581  \
1582  static bool reduce_batch(unsigned from_id, uint8_t* y, \
1583  DataCommMode data_mode) { \
1584  return false; \
1585  } \
1586  \
1587  static bool reduce_mirror_batch(unsigned from_id, uint8_t* y, \
1588  DataCommMode data_mode) { \
1589  return false; \
1590  } \
1591  \
1592  static void reset(uint32_t GALOIS_UNUSED(node_id), \
1593  struct NodeData& GALOIS_UNUSED(node)) {} \
1594  \
1595  static void setVal(uint32_t node_id, struct NodeData& GALOIS_UNUSED(node), \
1596  ValTy y) { \
1597  fieldname[node_id] = y; \
1598  } \
1599  \
1600  static bool setVal_batch(unsigned from_id, uint8_t* y, \
1601  DataCommMode data_mode) { \
1602  return false; \
1603  } \
1604  }
1605 #endif
1606 
1611 #ifdef GALOIS_ENABLE_GPU
1612 // GPU code included
1613 #define GALOIS_SYNC_STRUCTURE_REDUCE_PAIR_WISE_AVG_ARRAY(fieldname, fieldtype) \
1614  struct Reduce_pair_wise_avg_array_##fieldname { \
1615  typedef fieldtype ValTy; \
1616  \
1617  static ValTy extract(uint32_t node_id, const struct NodeData& node) { \
1618  if (personality == GPU_CUDA) \
1619  return get_node_##fieldname##_cuda(cuda_ctx, node_id); \
1620  assert(personality == CPU); \
1621  return node.fieldname; \
1622  } \
1623  \
1624  static bool extract_batch(unsigned from_id, uint8_t* y, size_t* s, \
1625  DataCommMode* data_mode) { \
1626  if (personality == GPU_CUDA) { \
1627  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, data_mode); \
1628  return true; \
1629  } \
1630  assert(personality == CPU); \
1631  return false; \
1632  } \
1633  \
1634  static bool extract_batch(unsigned from_id, uint8_t* y) { \
1635  if (personality == GPU_CUDA) { \
1636  batch_get_node_##fieldname##_cuda(cuda_ctx, from_id, y); \
1637  return true; \
1638  } \
1639  assert(personality == CPU); \
1640  return false; \
1641  } \
1642  \
1643  static bool extract_reset_batch(unsigned from_id, uint8_t* y, size_t* s, \
1644  DataCommMode* data_mode) { \
1645  if (personality == GPU_CUDA) { \
1646  batch_get_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, s, \
1647  data_mode); \
1648  return true; \
1649  } \
1650  assert(personality == CPU); \
1651  return false; \
1652  } \
1653  \
1654  static bool extract_reset_batch(unsigned from_id, uint8_t* y) { \
1655  if (personality == GPU_CUDA) { \
1656  batch_get_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y); \
1657  return true; \
1658  } \
1659  assert(personality == CPU); \
1660  return false; \
1661  } \
1662  \
1663  static bool reset_batch(size_t GALOIS_UNUSED(begin), \
1664  size_t GALOIS_UNUSED(end)) { \
1665  return false; \
1666  } \
1667  \
1668  static bool reduce(uint32_t node_id, struct NodeData& node, ValTy y) { \
1669  if (personality == GPU_CUDA) { \
1670  set_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
1671  return true; \
1672  } \
1673  assert(personality == CPU); \
1674  { \
1675  galois::pairWiseAvg_vec(node.fieldname, y); \
1676  return true; \
1677  } \
1678  } \
1679  \
1680  static bool reduce_batch(unsigned from_id, uint8_t* y, \
1681  DataCommMode data_mode) { \
1682  if (personality == GPU_CUDA) { \
1683  batch_set_node_##fieldname##_cuda(cuda_ctx, from_id, y, data_mode); \
1684  return true; \
1685  } \
1686  assert(personality == CPU); \
1687  return false; \
1688  } \
1689  \
1690  static bool reduce_mirror_batch(unsigned from_id, uint8_t* y, \
1691  DataCommMode data_mode) { \
1692  if (personality == GPU_CUDA) { \
1693  batch_set_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
1694  data_mode); \
1695  return true; \
1696  } \
1697  assert(personality == CPU); \
1698  return false; \
1699  } \
1700  \
1701  static void reset(uint32_t GALOIS_UNUSED(node_id), \
1702  struct NodeData& node) { \
1703  { galois::resetVec(node.fieldname); } \
1704  } \
1705  \
1706  static void setVal(uint32_t node_id, struct NodeData& node, ValTy y) { \
1707  if (personality == GPU_CUDA) \
1708  set_node_##fieldname##_cuda(cuda_ctx, node_id, y); \
1709  else if (personality == CPU) \
1710  node.fieldname = y; \
1711  } \
1712  \
1713  static bool setVal_batch(unsigned from_id, uint8_t* y, \
1714  DataCommMode data_mode) { \
1715  if (personality == GPU_CUDA) { \
1716  batch_set_mirror_node_##fieldname##_cuda(cuda_ctx, from_id, y, \
1717  data_mode); \
1718  return true; \
1719  } \
1720  assert(personality == CPU); \
1721  return false; \
1722  } \
1723  }
1724 #else
1725 // Non-GPU code
1726 #define GALOIS_SYNC_STRUCTURE_REDUCE_PAIR_WISE_AVG_ARRAY(fieldname, fieldtype) \
1727  struct Reduce_pair_wise_avg_array_##fieldname { \
1728  typedef fieldtype ValTy; \
1729  \
1730  static ValTy extract(uint32_t, const struct NodeData& node) { \
1731  return node.fieldname; \
1732  } \
1733  \
1734  static bool extract_batch(unsigned, uint8_t*, size_t*, DataCommMode*) { \
1735  return false; \
1736  } \
1737  \
1738  static bool extract_batch(unsigned, uint8_t*) { return false; } \
1739  \
1740  static bool extract_reset_batch(unsigned, uint8_t*, size_t*, \
1741  DataCommMode*) { \
1742  return false; \
1743  } \
1744  \
1745  static bool extract_reset_batch(unsigned, uint8_t*) { return false; } \
1746  \
1747  static bool reset_batch(size_t, size_t) { return false; } \
1748  \
1749  static bool reduce(uint32_t, struct NodeData& node, ValTy y) { \
1750  { \
1751  galois::pairWiseAvg_vec(node.fieldname, y); \
1752  return true; \
1753  } \
1754  } \
1755  \
1756  static bool reduce_batch(unsigned, uint8_t*, DataCommMode) { \
1757  return false; \
1758  } \
1759  \
1760  static bool reduce_mirror_batch(unsigned, uint8_t*, DataCommMode) { \
1761  return false; \
1762  } \
1763  \
1764  static void reset(uint32_t, struct NodeData& node) { \
1765  { galois::resetVec(node.fieldname); } \
1766  } \
1767  \
1768  static void setVal(uint32_t, struct NodeData& node, ValTy y) { \
1769  node.fieldname = y; \
1770  } \
1771  \
1772  static bool setVal_batch(unsigned, uint8_t*, DataCommMode) { \
1773  return false; \
1774  } \
1775  }
1776 #endif
1777 
1782 #define GALOIS_SYNC_STRUCTURE_REDUCE_PAIR_WISE_ADD_ARRAY(fieldname, fieldtype) \
1783  struct Reduce_pair_wise_add_array_##fieldname { \
1784  typedef fieldtype ValTy; \
1785  \
1786  static ValTy extract(uint32_t, const struct NodeData& node) { \
1787  return node.fieldname; \
1788  } \
1789  \
1790  static bool extract_batch(unsigned, uint8_t*, size_t*, DataCommMode*) { \
1791  return false; \
1792  } \
1793  \
1794  static bool extract_batch(unsigned, uint8_t*) { return false; } \
1795  \
1796  static bool extract_reset_batch(unsigned, uint8_t*, size_t*, \
1797  DataCommMode*) { \
1798  return false; \
1799  } \
1800  \
1801  static bool extract_reset_batch(unsigned, uint8_t*) { return false; } \
1802  \
1803  static bool reset_batch(size_t, size_t) { return false; } \
1804  \
1805  static bool reduce(uint32_t, struct NodeData& node, ValTy y) { \
1806  { \
1807  galois::addArray(node.fieldname, y); \
1808  return true; \
1809  } \
1810  } \
1811  \
1812  static bool reduce_batch(unsigned, uint8_t*, DataCommMode) { \
1813  return false; \
1814  } \
1815  \
1816  static bool reduce_mirror_batch(unsigned, uint8_t*, DataCommMode) { \
1817  return false; \
1818  } \
1819  \
1820  static void reset(uint32_t, struct NodeData& node) { \
1821  { galois::resetVec(node.fieldname); } \
1822  } \
1823  \
1824  static void setVal(uint32_t, struct NodeData& node, ValTy y) { \
1825  node.fieldname = y; \
1826  } \
1827  \
1828  static bool setVal_batch(unsigned, uint8_t*, DataCommMode) { \
1829  return false; \
1830  } \
1831  }
1832 
1837 #define GALOIS_SYNC_STRUCTURE_REDUCE_PAIR_WISE_ADD_ARRAY_SINGLE(fieldname, \
1838  fieldtype) \
1839  struct Reduce_pair_wise_add_array_single_##fieldname { \
1840  typedef fieldtype ValTy; \
1841  \
1842  static ValTy extract(uint32_t node_id, const struct NodeData& node, \
1843  unsigned vecIndex) { \
1844  return node.fieldname[vecIndex]; \
1845  } \
1846  \
1847  static bool extract_batch(unsigned from_id, uint8_t* y, size_t* s, \
1848  DataCommMode* data_mode) { \
1849  return false; \
1850  } \
1851  \
1852  static bool extract_batch(unsigned from_id, uint8_t* y) { return false; } \
1853  \
1854  static bool extract_reset_batch(unsigned, uint8_t*, size_t*, \
1855  DataCommMode*) { \
1856  return false; \
1857  } \
1858  \
1859  static bool extract_reset_batch(unsigned, uint8_t*) { return false; } \
1860  \
1861  static bool reset_batch(size_t GALOIS_UNUSED(begin), \
1862  size_t GALOIS_UNUSED(end)) { \
1863  return false; \
1864  } \
1865  \
1866  static bool reduce(uint32_t GALOIS_UNUSED(node_id), struct NodeData& node, \
1867  ValTy y, unsigned vecIndex) { \
1868  node.fieldname[vecIndex] = node.fieldname[vecIndex] + y; \
1869  return true; \
1870  } \
1871  \
1872  static bool reduce_batch(unsigned, uint8_t*, size_t, DataCommMode) { \
1873  return false; \
1874  } \
1875  \
1876  static bool reduce_mirror_batch(unsigned from_id, uint8_t* y, \
1877  DataCommMode data_mode) { \
1878  return false; \
1879  } \
1880  \
1881  static void reset(uint32_t GALOIS_UNUSED(node_id), struct NodeData& node, \
1882  unsigned vecIndex) { \
1883  node.fieldname[vecIndex] = 0; \
1884  } \
1885  \
1886  static void setVal(uint32_t GALOIS_UNUSED(node_id), struct NodeData& node, \
1887  ValTy y, unsigned vecIndex) { \
1888  node.fieldname[vecIndex] = y; \
1889  } \
1890  \
1891  static void setVal(uint32_t GALOIS_UNUSED(node_id), \
1892  struct NodeData& GALOIS_UNUSED(node), ValTy y) { \
1893  GALOIS_DIE("execution shouldn't get here; needs index arg"); \
1894  } \
1895  \
1896  static bool setVal_batch(unsigned uint8_t*, DataCommMode) { \
1897  return false; \
1898  } \
1899  }
1900 
1902 // Bitset struct
1904 
1915 #ifdef GALOIS_ENABLE_GPU
1916 // GPU code included
1917 #define GALOIS_SYNC_STRUCTURE_BITSET(fieldname) \
1918  struct Bitset_##fieldname { \
1919  static constexpr bool is_vector_bitset() { return false; } \
1920  static bool is_valid() { return true; } \
1921  \
1922  static galois::DynamicBitSet& get() { \
1923  if (personality == GPU_CUDA) \
1924  get_bitset_##fieldname##_cuda( \
1925  cuda_ctx, (uint64_t*)bitset_##fieldname.get_vec().data()); \
1926  return bitset_##fieldname; \
1927  } \
1928  \
1929  static void reset_range(size_t begin, size_t end) { \
1930  if (personality == GPU_CUDA) { \
1931  bitset_##fieldname##_reset_cuda(cuda_ctx, begin, end); \
1932  } else { \
1933  assert(personality == CPU); \
1934  bitset_##fieldname.reset(begin, end); \
1935  } \
1936  } \
1937  }
1938 #else
1939 // no GPU code
1940 #define GALOIS_SYNC_STRUCTURE_BITSET(fieldname) \
1941  struct Bitset_##fieldname { \
1942  static constexpr bool is_vector_bitset() { return false; } \
1943  \
1944  static constexpr bool is_valid() { return true; } \
1945  \
1946  static galois::DynamicBitSet& get() { return bitset_##fieldname; } \
1947  \
1948  static void reset_range(size_t begin, size_t end) { \
1949  bitset_##fieldname.reset(begin, end); \
1950  } \
1951  }
1952 #endif
1953 
1965 #define GALOIS_SYNC_STRUCTURE_VECTOR_BITSET(fieldname) \
1966  struct Bitset_##fieldname { \
1967  static unsigned numBitsets() { return vbitset_##fieldname.size(); } \
1968  \
1969  static constexpr bool is_vector_bitset() { return true; } \
1970  \
1971  static constexpr bool is_valid() { return true; } \
1972  \
1973  static galois::DynamicBitSet& get(unsigned i) { \
1974  return vbitset_##fieldname[i]; \
1975  } \
1976  \
1977  static void reset_range(size_t begin, size_t end) { \
1978  for (unsigned i = 0; i < vbitset_##fieldname.size(); i++) { \
1979  vbitset_##fieldname[i].reset(begin, end); \
1980  } \
1981  } \
1982  }
1983 
1984 #endif // header guard
BITVECTOR_STATUS bitvectorStatus
Status of the bitvector in terms of if it can be used to sync the field.
Definition: SyncStructures.h:76
bool src_to_src() const
Return true if src2src is set.
Definition: SyncStructures.h:90
void make_dst_invalid(BITVECTOR_STATUS *bv_flag)
Marks destinations invalid on passed in bitvector flag.
Definition: SyncStructures.cpp:54
void clear_read_dst()
Sets write dst flags to false.
Definition: SyncStructures.h:128
void set_write_dst()
Sets write dst flags to true.
Definition: SyncStructures.h:108
sources on bitvector are invalid
Definition: SyncStructures.h:47
destinations on bitvector are invalid
Definition: SyncStructures.h:48
void clear_read_any()
Sets all write flags to false.
Definition: SyncStructures.h:134
Contains the DataCommMode enumeration and a function that chooses a data comm mode based on its argum...
FieldFlags()
Field Flags constructor.
Definition: SyncStructures.h:81
bool src_invalid(BITVECTOR_STATUS bv_flag)
Return true if the sources are invalid in bitvector flag.
Definition: SyncStructures.cpp:30
void make_src_invalid(BITVECTOR_STATUS *bv_flag)
Marks sources invalid on passed in bitvector flag.
Definition: SyncStructures.cpp:40
bool src_to_dst() const
Return true if src2dst is set.
Definition: SyncStructures.h:93
none of the bitvector is invalid
Definition: SyncStructures.h:46
void set_write_any()
Sets all write flags to true.
Definition: SyncStructures.h:114
void clear_read_src()
Sets write src flags to false.
Definition: SyncStructures.h:122
Definition: SyncStructures.h:49
BITVECTOR_STATUS
Bitvector status enum specifying validness of certain things in bitvector.
Definition: SyncStructures.h:45
Each field has a FieldFlags object that indicates synchronization status of that field.
Definition: SyncStructures.h:65
bool dst_invalid(BITVECTOR_STATUS bv_flag)
Return true if the destinations are invalid in bitvector flag.
Definition: SyncStructures.cpp:35
void clear_all()
Sets all write flags to false and sets bitvector stats to none invalid.
Definition: SyncStructures.h:142
bool dst_to_dst() const
Return true if dst2dst is set.
Definition: SyncStructures.h:99
bool dst_to_src() const
Return true if dst2src is set.
Definition: SyncStructures.h:96
void set_write_src()
Sets write src flags to true.
Definition: SyncStructures.h:102