Galois
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
AtomicHelpers.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 
20 #pragma once
21 #include <atomic>
22 #include <algorithm>
23 #include <vector>
24 
25 #include "galois/config.h"
26 
27 namespace galois {
29 template <typename Ty>
30 const Ty atomicMax(std::atomic<Ty>& a, const Ty b) {
31  Ty old_a = a;
32  // if old value is less than new value, atomically exchange
33  while (old_a < b &&
34  !a.compare_exchange_weak(old_a, b, std::memory_order_relaxed))
35  ;
36  return old_a;
37 }
38 
39 template <typename Ty>
40 const Ty max(std::atomic<Ty>& a, const Ty& b) {
41  Ty old_a = a;
42 
43  if (a < b) {
44  a = b;
45  }
46  return old_a;
47 }
48 
49 template <typename Ty>
50 const Ty max(Ty& a, const Ty& b) {
51  Ty old_a = a;
52 
53  if (a < b) {
54  a = b;
55  }
56  return old_a;
57 }
58 
60 template <typename Ty>
61 const Ty atomicMin(std::atomic<Ty>& a, const Ty b) {
62  Ty old_a = a;
63  while (old_a > b &&
64  !a.compare_exchange_weak(old_a, b, std::memory_order_relaxed))
65  ;
66  return old_a;
67 }
68 
69 template <typename Ty>
70 const Ty min(std::atomic<Ty>& a, const Ty& b) {
71  Ty old_a = a;
72  if (a > b) {
73  a = b;
74  }
75  return old_a;
76 }
77 
78 template <typename Ty>
79 const Ty min(Ty& a, const Ty& b) {
80  Ty old_a = a;
81  if (a > b) {
82  a = b;
83  }
84  return old_a;
85 }
86 
88 template <typename Ty>
89 const Ty atomicAdd(std::atomic<Ty>& val, Ty delta) {
90  Ty old_val = val;
91  while (!val.compare_exchange_weak(old_val, old_val + delta,
92  std::memory_order_relaxed))
93  ;
94  return old_val;
95 }
96 
97 template <typename Ty>
98 const Ty add(std::atomic<Ty>& a, const Ty& b) {
99  Ty old_a = a;
100  a = a + b;
101  return old_a;
102 }
103 
104 template <typename Ty>
105 const Ty add(Ty& a, std::atomic<Ty>& b) {
106  Ty old_a = a;
107  a = a + b.load();
108  return old_a;
109 }
110 
111 template <typename Ty>
112 const Ty add(Ty& a, const Ty& b) {
113  Ty old_a = a;
114  a += b;
115  return old_a;
116 }
117 
122 template <typename Ty>
123 const Ty atomicSubtract(std::atomic<Ty>& val, Ty delta) {
124  Ty old_val = val;
125  while (!val.compare_exchange_weak(old_val, old_val - delta,
126  std::memory_order_relaxed))
127  ;
128  return old_val;
129 }
130 
131 template <typename Ty>
132 const Ty set(Ty& a, const Ty& b) {
133  a = b;
134  return a;
135 }
136 
137 template <typename Ty>
138 const Ty set(std::atomic<Ty>& a, const Ty& b) {
139  a = b;
140  return a;
141 }
142 
144 template <typename Ty>
145 const Ty pairWiseAvg(Ty a, Ty b) {
146  return (a + b) / 2.0;
147 }
148 
149 template <typename Ty>
150 void pairWiseAvg_vec(std::vector<Ty>& a_vec, std::vector<Ty>& b_vec) {
151  for (unsigned i = 0; i < a_vec.size(); ++i) {
152  a_vec[i] = (a_vec[i] + b_vec[i]) / 2.0;
153  }
154 }
155 
156 template <typename Ty>
157 void resetVec(Ty& a_arr) {
158  // std::for_each(a_arr.begin(), a_arr.end(),[](Ty &ele){ele = 0;} );
159  std::fill(a_arr.begin(), a_arr.end(), 0);
160 }
161 
162 template <typename Ty>
163 void pairWiseAvg_vec(Ty& a_arr, Ty& b_arr) {
164  for (unsigned i = 0; i < a_arr.size(); ++i) {
165  a_arr[i] = (a_arr[i] + b_arr[i]) / 2.0;
166  }
167 }
168 
169 template <typename Ty>
170 void addArray(Ty& a_arr, Ty& b_arr) {
171  for (unsigned i = 0; i < a_arr.size(); ++i) {
172  a_arr[i] = (a_arr[i] + b_arr[i]);
173  }
174 }
175 
176 template <typename Ty>
177 void resetVec(std::vector<Ty>& a_vec) {
178  std::for_each(a_vec.begin(), a_vec.end(), [](Ty& ele) { ele = 0; });
179 }
180 
181 // like std::inner_product
182 template <typename ItrTy, typename Ty>
183 Ty innerProduct(ItrTy a_begin, ItrTy a_end, ItrTy b_begin, Ty init_value) {
184  auto jj = b_begin;
185  for (auto ii = a_begin; ii != a_end; ++ii, ++jj) {
186  init_value += (*ii) * (*jj);
187  }
188  return init_value;
189 }
190 
191 // like std::inner_product
192 template <typename ItrTy, typename Ty>
193 Ty innerProduct(ItrTy& a_arr, ItrTy& b_arr, Ty init_value) {
194  auto jj = b_arr.begin();
195  for (auto ii = a_arr.begin(); ii != a_arr.end(); ++ii, ++jj) {
196  init_value += (*ii) * (*jj);
197  }
198  return init_value;
199 }
200 
201 template <typename Ty>
202 void reset(Ty& var, Ty val) {
203  var = val;
204 }
205 
206 template <typename Ty>
207 void reset(std::atomic<Ty>& var, Ty val) {
208  var = val;
209 }
210 } // end namespace galois
const Ty atomicAdd(std::atomic< Ty > &val, Ty delta)
galois::atomicAdd
Definition: AtomicHelpers.h:89
const Ty atomicMin(std::atomic< Ty > &a, const Ty b)
galois::atomicMin
Definition: AtomicHelpers.h:61
const Ty pairWiseAvg(Ty a, Ty b)
Pair Wise Average function.
Definition: AtomicHelpers.h:145
const Ty max(std::atomic< Ty > &a, const Ty &b)
Definition: AtomicHelpers.h:40
Ty innerProduct(ItrTy a_begin, ItrTy a_end, ItrTy b_begin, Ty init_value)
Definition: AtomicHelpers.h:183
void reset(Ty &var, Ty val)
Definition: AtomicHelpers.h:202
const Ty min(std::atomic< Ty > &a, const Ty &b)
Definition: AtomicHelpers.h:70
const Ty set(Ty &a, const Ty &b)
Definition: AtomicHelpers.h:132
const Ty add(std::atomic< Ty > &a, const Ty &b)
Definition: AtomicHelpers.h:98
const Ty atomicSubtract(std::atomic< Ty > &val, Ty delta)
atomic subtraction of delta (because atomicAdd with negative numbers implies a signed integer cast) ...
Definition: AtomicHelpers.h:123
void resetVec(Ty &a_arr)
Definition: AtomicHelpers.h:157
void for_each(const RangeFunc &rangeMaker, FunctionTy &&fn, const Args &...args)
Galois unordered set iterator.
Definition: Loops.h:52
const Ty atomicMax(std::atomic< Ty > &a, const Ty b)
galois::atomicMax + non-atomic max calls
Definition: AtomicHelpers.h:30
void pairWiseAvg_vec(std::vector< Ty > &a_vec, std::vector< Ty > &b_vec)
Definition: AtomicHelpers.h:150
void addArray(Ty &a_arr, Ty &b_arr)
Definition: AtomicHelpers.h:170