]>
Commit | Line | Data |
---|---|---|
3038054c BI |
1 | /* reducer_opxor.h -*- C++ -*- |
2 | * | |
2e01cda6 | 3 | * Copyright (C) 2009-2016, Intel Corporation |
3038054c BI |
4 | * All rights reserved. |
5 | * | |
3038054c BI |
6 | * Redistribution and use in source and binary forms, with or without |
7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | |
9 | * | |
10 | * * Redistributions of source code must retain the above copyright | |
11 | * notice, this list of conditions and the following disclaimer. | |
12 | * * Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in | |
14 | * the documentation and/or other materials provided with the | |
15 | * distribution. | |
16 | * * Neither the name of Intel Corporation nor the names of its | |
17 | * contributors may be used to endorse or promote products derived | |
18 | * from this software without specific prior written permission. | |
19 | * | |
3038054c BI |
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
24 | * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |
25 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | |
26 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | |
27 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | |
28 | * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY | |
30 | * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |
31 | * POSSIBILITY OF SUCH DAMAGE. | |
2e01cda6 IV |
32 | * |
33 | * ********************************************************************* | |
34 | * | |
35 | * PLEASE NOTE: This file is a downstream copy of a file mainitained in | |
36 | * a repository at cilkplus.org. Changes made to this file that are not | |
37 | * submitted through the contribution process detailed at | |
38 | * http://www.cilkplus.org/submit-cilk-contribution will be lost the next | |
39 | * time that a new version is released. Changes only submitted to the | |
40 | * GNU compiler collection or posted to the git repository at | |
41 | * https://bitbucket.org/intelcilkruntime/intel-cilk-runtime.git are | |
42 | * not tracked. | |
43 | * | |
44 | * We welcome your contributions to this open source project. Thank you | |
45 | * for your assistance in helping us improve Cilk Plus. | |
3038054c BI |
46 | */ |
47 | ||
48 | /** @file reducer_opxor.h | |
49 | * | |
50 | * @brief Defines classes for doing parallel bitwise or reductions. | |
51 | * | |
52 | * @ingroup ReducersXor | |
53 | * | |
54 | * @see ReducersXor | |
55 | */ | |
56 | ||
57 | #ifndef REDUCER_OPXOR_H_INCLUDED | |
58 | #define REDUCER_OPXOR_H_INCLUDED | |
59 | ||
60 | #include <cilk/reducer.h> | |
61 | ||
2e01cda6 | 62 | /** @defgroup ReducersXor Bitwise XOR Reducers |
3038054c | 63 | * |
2e01cda6 | 64 | * Bitwise XOR reducers allow the computation of the bitwise XOR of a set of |
3038054c BI |
65 | * values in parallel. |
66 | * | |
67 | * @ingroup Reducers | |
68 | * | |
2e01cda6 IV |
69 | * You should be familiar with @ref pagereducers "Intel(R) Cilk(TM) Plus reducers", |
70 | * described in file `reducers.md`, and particularly with @ref reducers_using, | |
71 | * before trying to use the information in this file. | |
3038054c BI |
72 | * |
73 | * @section redopxor_usage Usage Example | |
74 | * | |
75 | * cilk::reducer< cilk::op_xor<unsigned> > r; | |
76 | * cilk_for (int i = 0; i != N; ++i) { | |
77 | * *r ^= a[i]; | |
78 | * } | |
79 | * unsigned result; | |
80 | * r.move_out(result); | |
81 | * | |
82 | * @section redopxor_monoid The Monoid | |
83 | * | |
84 | * @subsection redopxor_monoid_values Value Set | |
85 | * | |
2e01cda6 | 86 | * The value set of a bitwise XOR reducer is the set of values of `Type`, which |
3038054c BI |
87 | * is expected to be a builtin integer type which has a representation as a |
88 | * sequence of bits (or something like it, such as `bool` or `std::bitset`). | |
89 | * | |
90 | * @subsection redopxor_monoid_operator Operator | |
91 | * | |
2e01cda6 | 92 | * The bitwise XOR operator is defined by the "`^`" binary operator on `Type`. |
3038054c BI |
93 | * |
94 | * @subsection redopxor_monoid_identity Identity | |
95 | * | |
2e01cda6 | 96 | * The identity value of the reducer is the value whose representation |
3038054c BI |
97 | * contains all 0-bits. This is expected to be the value of the default |
98 | * constructor `Type()`. | |
99 | * | |
100 | * @section redopxor_operations Operations | |
101 | * | |
102 | * @subsection redopxor_constructors Constructors | |
103 | * | |
104 | * reducer() // identity | |
105 | * reducer(const Type& value) | |
106 | * reducer(move_in(Type& variable)) | |
107 | * | |
108 | * @subsection redopxor_get_set Set and Get | |
109 | * | |
110 | * r.set_value(const Type& value) | |
111 | * const Type& = r.get_value() const | |
112 | * r.move_in(Type& variable) | |
113 | * r.move_out(Type& variable) | |
114 | * | |
115 | * @subsection redopxor_initial Initial Values | |
116 | * | |
2e01cda6 IV |
117 | * If a bitwise XOR reducer is constructed without an explicit initial value, |
118 | * then its initial value will be its identity value, as long as `Type` | |
3038054c BI |
119 | * satisfies the requirements of @ref redopxor_types. |
120 | * | |
121 | * @subsection redopxor_view_ops View Operations | |
122 | * | |
123 | * *r ^= a | |
124 | * *r = *r ^ a | |
125 | * *r = *r ^ a1 ^ a2 … ^ an | |
126 | * | |
127 | * @section redopxor_types Type and Operator Requirements | |
128 | * | |
129 | * `Type` must be `Copy Constructible`, `Default Constructible`, and | |
130 | * `Assignable`. | |
131 | * | |
2e01cda6 | 132 | * The operator "`^=`" must be defined on `Type`, with `x ^= a` having the |
3038054c BI |
133 | * same meaning as `x = x ^ a`. |
134 | * | |
135 | * The expression `Type()` must be a valid expression which yields the | |
136 | * identity value (the value of `Type` whose representation consists of all | |
137 | * 0-bits). | |
138 | * | |
2e01cda6 | 139 | * @section redopxor_in_c Bitwise XOR Reducers in C |
3038054c BI |
140 | * |
141 | * The @ref CILK_C_REDUCER_OPXOR and @ref CILK_C_REDUCER_OPXOR_TYPE macros can | |
2e01cda6 | 142 | * be used to do bitwise XOR reductions in C. For example: |
3038054c BI |
143 | * |
144 | * CILK_C_REDUCER_OPXOR(r, uint, 0); | |
145 | * CILK_C_REGISTER_REDUCER(r); | |
146 | * cilk_for(int i = 0; i != n; ++i) { | |
147 | * REDUCER_VIEW(r) ^= a[i]; | |
148 | * } | |
149 | * CILK_C_UNREGISTER_REDUCER(r); | |
150 | * printf("The bitwise XOR of the elements of a is %x\n", REDUCER_VIEW(r)); | |
151 | * | |
152 | * See @ref reducers_c_predefined. | |
153 | */ | |
154 | ||
155 | #ifdef __cplusplus | |
156 | ||
157 | namespace cilk { | |
158 | ||
2e01cda6 | 159 | /** The bitwise XOR reducer view class. |
3038054c | 160 | * |
2e01cda6 IV |
161 | * This is the view class for reducers created with |
162 | * `cilk::reducer< cilk::op_xor<Type> >`. It holds the accumulator variable | |
3038054c BI |
163 | * for the reduction, and allows only `xor` operations to be performed on it. |
164 | * | |
2e01cda6 IV |
165 | * @note The reducer "dereference" operation (`reducer::operator *()`) |
166 | * yields a reference to the view. Thus, for example, the view class's | |
3038054c BI |
167 | * `^=` operation would be used in an expression like `*r ^= a`, where |
168 | * `r` is an opmod reducer variable. | |
169 | * | |
170 | * @tparam Type The type of the contained accumulator variable. This will | |
171 | * be the value type of a monoid_with_view that is | |
172 | * instantiated with this view. | |
173 | * | |
174 | * @see ReducersXor | |
175 | * @see op_xor | |
176 | * | |
177 | * @ingroup ReducersXor | |
178 | */ | |
179 | template <typename Type> | |
180 | class op_xor_view : public scalar_view<Type> | |
181 | { | |
182 | typedef scalar_view<Type> base; | |
2e01cda6 | 183 | |
3038054c BI |
184 | public: |
185 | /** Class to represent the right-hand side of `*reducer = *reducer ^ value`. | |
186 | * | |
2e01cda6 | 187 | * The only assignment operator for the op_xor_view class takes an |
3038054c BI |
188 | * rhs_proxy as its operand. This results in the syntactic restriction |
189 | * that the only expressions that can be assigned to an op_xor_view are | |
2e01cda6 | 190 | * ones which generate an rhs_proxy - that is, expressions of the form |
3038054c BI |
191 | * `op_xor_view ^ value ... ^ value`. |
192 | * | |
193 | * @warning | |
2e01cda6 | 194 | * The lhs and rhs views in such an assignment must be the same; |
3038054c BI |
195 | * otherwise, the behavior will be undefined. (I.e., `v1 = v1 ^ x` is |
196 | * legal; `v1 = v2 ^ x` is illegal.) This condition will be checked with | |
197 | * a runtime assertion when compiled in debug mode. | |
198 | * | |
199 | * @see op_xor_view | |
200 | */ | |
201 | class rhs_proxy { | |
202 | friend class op_xor_view; | |
203 | ||
204 | const op_xor_view* m_view; | |
205 | Type m_value; | |
206 | ||
207 | // Constructor is invoked only from op_xor_view::operator^(). | |
208 | // | |
209 | rhs_proxy(const op_xor_view* view, const Type& value) : m_view(view), m_value(value) {} | |
210 | ||
211 | rhs_proxy& operator=(const rhs_proxy&); // Disable assignment operator | |
212 | rhs_proxy(); // Disable default constructor | |
213 | ||
214 | public: | |
2e01cda6 IV |
215 | /** bitwise XOR with an additional rhs value. If `v` is an op_xor_view |
216 | * and `a1` is a value, then the expression `v ^ a1` invokes the | |
217 | * view's `operator^()` to create an rhs_proxy for `(v, a1)`; then | |
218 | * `v ^ a1 ^ a2` invokes the rhs_proxy's `operator^()` to create a new | |
3038054c | 219 | * rhs_proxy for `(v, a1^a2)`. This allows the right-hand side of an |
2e01cda6 | 220 | * assignment to be not just `view ^ value`, but |
3038054c BI |
221 | ( `view ^ value ^ value ... ^ value`. The effect is that |
222 | * | |
223 | * v = v ^ a1 ^ a2 ... ^ an; | |
224 | * | |
225 | * is evaluated as | |
226 | * | |
227 | * v = v ^ (a1 ^ a2 ... ^ an); | |
228 | */ | |
229 | rhs_proxy& operator^(const Type& x) { m_value ^= x; return *this; } | |
230 | }; | |
231 | ||
232 | ||
233 | /** Default/identity constructor. This constructor initializes the | |
234 | * contained value to `Type()`. | |
235 | */ | |
236 | op_xor_view() : base() {} | |
237 | ||
238 | /** Construct with a specified initial value. | |
239 | */ | |
240 | explicit op_xor_view(const Type& v) : base(v) {} | |
2e01cda6 IV |
241 | |
242 | /** Reduces the views of two strands. | |
3038054c BI |
243 | * |
244 | * This function is invoked by the @ref op_xor monoid to combine the views | |
245 | * of two strands when the right strand merges with the left one. It | |
2e01cda6 | 246 | * "XORs" the value contained in the left-strand view by the value |
3038054c BI |
247 | * contained in the right-strand view, and leaves the value in the |
248 | * right-strand view undefined. | |
249 | * | |
250 | * @param right A pointer to the right-strand view. (`this` points to | |
251 | * the left-strand view.) | |
252 | * | |
253 | * @note Used only by the @ref op_xor monoid to implement the monoid | |
254 | * reduce operation. | |
255 | */ | |
256 | void reduce(op_xor_view* right) { this->m_value ^= right->m_value; } | |
2e01cda6 | 257 | |
3038054c BI |
258 | /** @name Accumulator variable updates. |
259 | * | |
2e01cda6 | 260 | * These functions support the various syntaxes for "XORing" the |
3038054c BI |
261 | * accumulator variable contained in the view with some value. |
262 | */ | |
2e01cda6 | 263 | ///@{ |
3038054c | 264 | |
2e01cda6 | 265 | /** Performs XOR operation between the accumulator variable and @a x. |
3038054c BI |
266 | */ |
267 | op_xor_view& operator^=(const Type& x) { this->m_value ^= x; return *this; } | |
268 | ||
2e01cda6 | 269 | /** Creates an object representing `*this ^ x`. |
3038054c BI |
270 | * |
271 | * @see rhs_proxy | |
272 | */ | |
273 | rhs_proxy operator^(const Type& x) const { return rhs_proxy(this, x); } | |
274 | ||
2e01cda6 | 275 | /** Assigns the result of a `view ^ value` expression to the view. Note that |
3038054c BI |
276 | * this is the only assignment operator for this class. |
277 | * | |
278 | * @see rhs_proxy | |
279 | */ | |
280 | op_xor_view& operator=(const rhs_proxy& rhs) { | |
281 | __CILKRTS_ASSERT(this == rhs.m_view); | |
282 | this->m_value ^= rhs.m_value; | |
283 | return *this; | |
284 | } | |
2e01cda6 IV |
285 | |
286 | ///@} | |
3038054c BI |
287 | }; |
288 | ||
2e01cda6 IV |
289 | /** Monoid class for bitwise XOR reductions. Instantiate the cilk::reducer |
290 | * template class with an op_xor monoid to create a bitwise XOR reducer | |
291 | * class. For example, to compute the bitwise XOR of a set of `unsigned long` | |
3038054c BI |
292 | * values: |
293 | * | |
294 | * cilk::reducer< cilk::op_xor<unsigned long> > r; | |
295 | * | |
296 | * @tparam Type The reducer value type. | |
297 | * @tparam Align If `false` (the default), reducers instantiated on this | |
2e01cda6 | 298 | * monoid will be naturally aligned (the Intel Cilk Plus library 1.0 |
3038054c | 299 | * behavior). If `true`, reducers instantiated on this monoid |
2e01cda6 IV |
300 | * will be cache-aligned for binary compatibility with |
301 | * reducers in Intel Cilk Plus library version 0.9. | |
3038054c BI |
302 | * |
303 | * @see ReducersXor | |
304 | * @see op_xor_view | |
305 | * | |
306 | * @ingroup ReducersXor | |
307 | */ | |
308 | template <typename Type, bool Align = false> | |
309 | struct op_xor : public monoid_with_view<op_xor_view<Type>, Align> {}; | |
310 | ||
2e01cda6 | 311 | /** Deprecated bitwise XOR reducer class. |
3038054c BI |
312 | * |
313 | * reducer_opxor is the same as @ref reducer<@ref op_xor>, except that | |
314 | * reducer_opxor is a proxy for the contained view, so that accumulator | |
315 | * variable update operations can be applied directly to the reducer. For | |
2e01cda6 IV |
316 | * example, a value is "XORed" with a `reducer<%op_xor>` with `*r ^= a`, but a |
317 | * value can be "XORed" with a `%reducer_opxor` with `r ^= a`. | |
3038054c BI |
318 | * |
319 | * @deprecated Users are strongly encouraged to use `reducer<monoid>` | |
2e01cda6 | 320 | * reducers rather than the old wrappers like reducer_opand. |
3038054c BI |
321 | * The `reducer<monoid>` reducers show the reducer/monoid/view |
322 | * architecture more clearly, are more consistent in their | |
323 | * implementation, and present a simpler model for new | |
324 | * user-implemented reducers. | |
325 | * | |
2e01cda6 | 326 | * @note Implicit conversions are provided between `%reducer_opxor` |
3038054c BI |
327 | * and `reducer<%op_xor>`. This allows incremental code |
328 | * conversion: old code that used `%reducer_opxor` can pass a | |
329 | * `%reducer_opxor` to a converted function that now expects a | |
330 | * pointer or reference to a `reducer<%op_xor>`, and vice | |
331 | * versa. | |
332 | * | |
333 | * @tparam Type The value type of the reducer. | |
334 | * | |
335 | * @see op_xor | |
336 | * @see reducer | |
337 | * @see ReducersXor | |
338 | * | |
339 | * @ingroup ReducersXor | |
340 | */ | |
341 | template <typename Type> | |
342 | class reducer_opxor : public reducer< op_xor<Type, true> > | |
343 | { | |
344 | typedef reducer< op_xor<Type, true> > base; | |
345 | using base::view; | |
346 | ||
347 | public: | |
348 | /// The view type for the reducer. | |
349 | typedef typename base::view_type view_type; | |
2e01cda6 IV |
350 | |
351 | /// The view's rhs proxy type. | |
3038054c | 352 | typedef typename view_type::rhs_proxy rhs_proxy; |
2e01cda6 | 353 | |
3038054c BI |
354 | /// The view type for the reducer. |
355 | typedef view_type View; | |
356 | ||
357 | /// The monoid type for the reducer. | |
358 | typedef typename base::monoid_type Monoid; | |
2e01cda6 | 359 | |
3038054c BI |
360 | /** @name Constructors |
361 | */ | |
2e01cda6 IV |
362 | ///@{ |
363 | ||
3038054c BI |
364 | /** Default (identity) constructor. |
365 | * | |
366 | * Constructs the wrapper with the default initial value of `Type()`. | |
367 | */ | |
368 | reducer_opxor() {} | |
369 | ||
370 | /** Value constructor. | |
371 | * | |
372 | * Constructs the wrapper with a specified initial value. | |
373 | */ | |
374 | explicit reducer_opxor(const Type& initial_value) : base(initial_value) {} | |
2e01cda6 IV |
375 | |
376 | ///@} | |
3038054c BI |
377 | |
378 | /** @name Forwarded functions | |
379 | * @details Functions that update the contained accumulator variable are | |
380 | * simply forwarded to the contained @ref op_and_view. */ | |
2e01cda6 | 381 | ///@{ |
3038054c BI |
382 | |
383 | /// @copydoc op_xor_view::operator^=(const Type&) | |
384 | reducer_opxor& operator^=(const Type& x) | |
385 | { | |
2e01cda6 | 386 | view() ^= x; return *this; |
3038054c | 387 | } |
2e01cda6 | 388 | |
3038054c BI |
389 | // The legacy definition of reducer_opxor::operator^() has different |
390 | // behavior and a different return type than this definition. The legacy | |
391 | // version is defined as a member function, so this new version is defined | |
2e01cda6 | 392 | // as a free function to give it a different signature, so that they won't |
3038054c BI |
393 | // end up sharing a single object file entry. |
394 | ||
395 | /// @copydoc op_xor_view::operator^(const Type&) const | |
396 | friend rhs_proxy operator^(const reducer_opxor& r, const Type& x) | |
2e01cda6 IV |
397 | { |
398 | return r.view() ^ x; | |
3038054c BI |
399 | } |
400 | ||
401 | /// @copydoc op_and_view::operator=(const rhs_proxy&) | |
402 | reducer_opxor& operator=(const rhs_proxy& temp) | |
403 | { | |
2e01cda6 | 404 | view() = temp; return *this; |
3038054c | 405 | } |
2e01cda6 | 406 | ///@} |
3038054c BI |
407 | |
408 | /** @name Dereference | |
409 | * @details Dereferencing a wrapper is a no-op. It simply returns the | |
410 | * wrapper. Combined with the rule that the wrapper forwards view | |
411 | * operations to its contained view, this means that view operations can | |
412 | * be written the same way on reducers and wrappers, which is convenient | |
413 | * for incrementally converting old code using wrappers to use reducers | |
414 | * instead. That is: | |
415 | * | |
416 | * reducer< op_and<int> > r; | |
417 | * *r &= a; // *r returns the view | |
418 | * // operator &= is a view member function | |
419 | * | |
420 | * reducer_opand<int> w; | |
421 | * *w &= a; // *w returns the wrapper | |
422 | * // operator &= is a wrapper member function that | |
423 | * // calls the corresponding view function | |
424 | */ | |
2e01cda6 | 425 | ///@{ |
3038054c BI |
426 | reducer_opxor& operator*() { return *this; } |
427 | reducer_opxor const& operator*() const { return *this; } | |
428 | ||
429 | reducer_opxor* operator->() { return this; } | |
430 | reducer_opxor const* operator->() const { return this; } | |
2e01cda6 IV |
431 | ///@} |
432 | ||
3038054c | 433 | /** @name Upcast |
2e01cda6 IV |
434 | * @details In Intel Cilk Plus library 0.9, reducers were always cache-aligned. |
435 | * In library 1.0, reducer cache alignment is optional. By default, | |
436 | * reducers are unaligned (i.e., just naturally aligned), but legacy | |
437 | * wrappers inherit from cache-aligned reducers for binary compatibility. | |
3038054c BI |
438 | * |
439 | * This means that a wrapper will automatically be upcast to its aligned | |
440 | * reducer base class. The following conversion operators provide | |
441 | * pseudo-upcasts to the corresponding unaligned reducer class. | |
442 | */ | |
2e01cda6 | 443 | ///@{ |
3038054c BI |
444 | operator reducer< op_xor<Type, false> >& () |
445 | { | |
446 | return *reinterpret_cast< reducer< op_xor<Type, false> >* >(this); | |
447 | } | |
448 | operator const reducer< op_xor<Type, false> >& () const | |
449 | { | |
450 | return *reinterpret_cast< const reducer< op_xor<Type, false> >* >(this); | |
451 | } | |
2e01cda6 IV |
452 | ///@} |
453 | ||
3038054c BI |
454 | }; |
455 | ||
456 | /// @cond internal | |
457 | /** Metafunction specialization for reducer conversion. | |
458 | * | |
2e01cda6 IV |
459 | * This specialization of the @ref legacy_reducer_downcast template class |
460 | * defined in reducer.h causes the `reducer< op_xor<Type> >` class to have an | |
3038054c BI |
461 | * `operator reducer_opxor<Type>& ()` conversion operator that statically |
462 | * downcasts the `reducer<op_xor>` to the corresponding `reducer_opxor` type. | |
463 | * (The reverse conversion, from `reducer_opxor` to `reducer<op_xor>`, is just | |
464 | * an upcast, which is provided for free by the language.) | |
465 | * | |
466 | * @ingroup ReducersXor | |
467 | */ | |
468 | template <typename Type, bool Align> | |
469 | struct legacy_reducer_downcast<reducer<op_xor<Type, Align> > > | |
470 | { | |
471 | typedef reducer_opxor<Type> type; | |
472 | }; | |
473 | /// @endcond | |
474 | ||
475 | } // namespace cilk | |
476 | ||
477 | #endif /* __cplusplus */ | |
478 | ||
479 | ||
480 | /** @ingroup ReducersXor | |
481 | */ | |
2e01cda6 | 482 | ///@{ |
3038054c BI |
483 | |
484 | /** @name C language reducer macros | |
485 | * | |
486 | * These macros are used to declare and work with op_xor reducers in C code. | |
487 | * | |
488 | * @see @ref page_reducers_in_c | |
489 | */ | |
2e01cda6 IV |
490 | ///@{ |
491 | ||
3038054c BI |
492 | __CILKRTS_BEGIN_EXTERN_C |
493 | ||
2e01cda6 | 494 | /** Declares OPXOR reducer type name. |
3038054c BI |
495 | * |
496 | * This macro expands into the identifier which is the name of the op_xor | |
497 | * reducer type for a specified numeric type. | |
498 | * | |
499 | * @param tn The @ref reducers_c_type_names "numeric type name" specifying | |
500 | * the type of the reducer. | |
501 | * | |
502 | * @see @ref reducers_c_predefined | |
503 | * @see ReducersXor | |
504 | */ | |
505 | #define CILK_C_REDUCER_OPXOR_TYPE(tn) \ | |
506 | __CILKRTS_MKIDENT(cilk_c_reducer_opxor_,tn) | |
507 | ||
2e01cda6 | 508 | /** Declares an op_xor reducer object. |
3038054c BI |
509 | * |
510 | * This macro expands into a declaration of an op_xor reducer object for a | |
511 | * specified numeric type. For example: | |
512 | * | |
513 | * CILK_C_REDUCER_OPXOR(my_reducer, ulong, 0); | |
514 | * | |
515 | * @param obj The variable name to be used for the declared reducer object. | |
516 | * @param tn The @ref reducers_c_type_names "numeric type name" specifying | |
517 | * the type of the reducer. | |
518 | * @param v The initial value for the reducer. (A value which can be | |
519 | * assigned to the numeric type represented by @a tn.) | |
520 | * | |
521 | * @see @ref reducers_c_predefined | |
522 | * @see ReducersXor | |
523 | */ | |
524 | #define CILK_C_REDUCER_OPXOR(obj,tn,v) \ | |
525 | CILK_C_REDUCER_OPXOR_TYPE(tn) obj = \ | |
526 | CILK_C_INIT_REDUCER(_Typeof(obj.value), \ | |
527 | __CILKRTS_MKIDENT(cilk_c_reducer_opxor_reduce_,tn), \ | |
528 | __CILKRTS_MKIDENT(cilk_c_reducer_opxor_identity_,tn), \ | |
529 | __cilkrts_hyperobject_noop_destroy, v) | |
530 | ||
531 | /// @cond internal | |
532 | ||
2e01cda6 | 533 | /** Declares the op_xor reducer functions for a numeric type. |
3038054c BI |
534 | * |
535 | * This macro expands into external function declarations for functions which | |
536 | * implement the reducer functionality for the op_xor reducer type for a | |
537 | * specified numeric type. | |
538 | * | |
539 | * @param t The value type of the reducer. | |
2e01cda6 | 540 | * @param tn The value "type name" identifier, used to construct the reducer |
3038054c BI |
541 | * type name, function names, etc. |
542 | */ | |
543 | #define CILK_C_REDUCER_OPXOR_DECLARATION(t,tn) \ | |
544 | typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPXOR_TYPE(tn); \ | |
545 | __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opxor,tn,l,r); \ | |
546 | __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opxor,tn); | |
2e01cda6 IV |
547 | |
548 | /** Defines the op_xor reducer functions for a numeric type. | |
3038054c BI |
549 | * |
550 | * This macro expands into function definitions for functions which implement | |
2e01cda6 | 551 | * the reducer functionality for the op_xor reducer type for a specified |
3038054c BI |
552 | * numeric type. |
553 | * | |
554 | * @param t The value type of the reducer. | |
2e01cda6 | 555 | * @param tn The value "type name" identifier, used to construct the reducer |
3038054c BI |
556 | * type name, function names, etc. |
557 | */ | |
558 | #define CILK_C_REDUCER_OPXOR_DEFINITION(t,tn) \ | |
559 | typedef CILK_C_DECLARE_REDUCER(t) CILK_C_REDUCER_OPXOR_TYPE(tn); \ | |
560 | __CILKRTS_DECLARE_REDUCER_REDUCE(cilk_c_reducer_opxor,tn,l,r) \ | |
561 | { *(t*)l ^= *(t*)r; } \ | |
562 | __CILKRTS_DECLARE_REDUCER_IDENTITY(cilk_c_reducer_opxor,tn) \ | |
563 | { *(t*)v = 0; } | |
2e01cda6 IV |
564 | |
565 | ///@{ | |
566 | /** @def CILK_C_REDUCER_OPXOR_INSTANCE | |
567 | * @brief Declares or defines implementation functions for a reducer type. | |
3038054c BI |
568 | * |
569 | * In the runtime source file c_reducers.c, the macro `CILK_C_DEFINE_REDUCERS` | |
570 | * will be defined, and this macro will generate reducer implementation | |
571 | * functions. Everywhere else, `CILK_C_DEFINE_REDUCERS` will be undefined, and | |
572 | * this macro will expand into external declarations for the functions. | |
573 | */ | |
574 | #ifdef CILK_C_DEFINE_REDUCERS | |
575 | # define CILK_C_REDUCER_OPXOR_INSTANCE(t,tn) \ | |
576 | CILK_C_REDUCER_OPXOR_DEFINITION(t,tn) | |
577 | #else | |
578 | # define CILK_C_REDUCER_OPXOR_INSTANCE(t,tn) \ | |
579 | CILK_C_REDUCER_OPXOR_DECLARATION(t,tn) | |
580 | #endif | |
2e01cda6 | 581 | ///@} |
3038054c | 582 | |
2e01cda6 | 583 | /* Declares or defines an instance of the reducer type and its functions for each |
3038054c BI |
584 | * numeric type. |
585 | */ | |
586 | CILK_C_REDUCER_OPXOR_INSTANCE(char, char) | |
587 | CILK_C_REDUCER_OPXOR_INSTANCE(unsigned char, uchar) | |
588 | CILK_C_REDUCER_OPXOR_INSTANCE(signed char, schar) | |
589 | CILK_C_REDUCER_OPXOR_INSTANCE(wchar_t, wchar_t) | |
590 | CILK_C_REDUCER_OPXOR_INSTANCE(short, short) | |
591 | CILK_C_REDUCER_OPXOR_INSTANCE(unsigned short, ushort) | |
592 | CILK_C_REDUCER_OPXOR_INSTANCE(int, int) | |
593 | CILK_C_REDUCER_OPXOR_INSTANCE(unsigned int, uint) | |
594 | CILK_C_REDUCER_OPXOR_INSTANCE(unsigned int, unsigned) /* alternate name */ | |
595 | CILK_C_REDUCER_OPXOR_INSTANCE(long, long) | |
596 | CILK_C_REDUCER_OPXOR_INSTANCE(unsigned long, ulong) | |
597 | CILK_C_REDUCER_OPXOR_INSTANCE(long long, longlong) | |
598 | CILK_C_REDUCER_OPXOR_INSTANCE(unsigned long long, ulonglong) | |
599 | ||
600 | //@endcond | |
601 | ||
602 | __CILKRTS_END_EXTERN_C | |
603 | ||
2e01cda6 | 604 | ///@} |
3038054c | 605 | |
2e01cda6 | 606 | ///@} |
3038054c BI |
607 | |
608 | #endif /* REDUCER_OPXOR_H_INCLUDED */ |