HILA
Loading...
Searching...
No Matches
shuffle.h
1
2#ifndef SHUFFLE_H_
3#define SHUFFLE_H_
4
5#include "hila.h"
6
7//
8
9namespace hila {
10struct dir_and_parity {
11 Direction direction;
12 Parity parity;
13};
14
15
16//////////////////////////////////////////////////////////////////////////
17/// Shuffle an existing std::array or std::vector to random order
18/// The type T should be trivially copyable, and "lightweight" - does extra copies
19///
20
21template <typename T,
22 std::enable_if_t<hila::is_std_array<T>::value || hila::is_std_vector<T>::value, int> = 0>
23void shuffle(T &arr) {
24 // go backwards in array, swap with random earlier element incl. itself
25 for (int j = arr.size() - 1; j > 0; j--) {
26 int i = (j + 1) * hila::random(); // rand from 0 to j inclusive
27 if (i != j)
28 std::swap(arr[i], arr[j]);
29 }
30}
31
32///////////////////////////////////////////////////////////////////////////////
33/// Function returning all directions and parities as shuffled to random order.
34/// Return type is std::array<dir_and_parity,2*NDIM>,
35///
36/// Use case is in Gauge heatbath/overrelax updates, to randomize order.
37/// Synchronizes with all MPI nodes, i.e. all ranks will have the same content.
38/// Function marked inline in order to avoid ODR
39///
40/// Typical use: no need to declare std::array
41///
42/// for (const auto & s : hila::shuffle_directions_and_parities()) {
43/// update_parity_dir(U, s.parity, s.direction);
44/// }
45///
46/// Can also be assigned, i.e.
47/// auto shuffled = hila::shuffle_directions_and_parities();
48
50 std::array<struct dir_and_parity, 2 * NDIM> arr;
51
52 int i = 0;
53 foralldir(d) {
54 for (Parity p : {EVEN, ODD}) {
55 arr[i].direction = d;
56 arr[i].parity = p;
57 i++;
58 }
59 }
60 shuffle(arr);
61 hila::broadcast(arr); // sync with all nodes
62 return arr;
63}
64
65///////////////////////////////////////////////////////////////////////////////
66/// Shuffling directions and parities separately with functions
67///
68/// std::array<Direction,NDIM> hila::shuffle_directions()
69/// std::array<Parity,2> hila::shuffle_parities()
70///
71/// Thus, (almost) the same operation as above with shuffle_directions_and_parities()
72/// can be done with
73///
74/// for (const Direction d : hila::shuffle_directions()) {
75/// for (const Parity p : hila::shuffle_parities()) {
76/// update_parity_dir(U, p, d);
77/// }
78/// }
79///
80/// This does more MPI synchronization than the shuffle_directions_and_parities()
81///
82
83inline auto shuffle_directions() {
84 std::array<Direction, NDIM> arr;
85
86 int i = 0;
87 foralldir(d) {
88 arr[i] = d;
89 i++;
90 }
91
92 shuffle(arr);
93 hila::broadcast(arr); // sync with all nodes
94 return arr;
95}
96
97inline auto shuffle_parities() {
98 std::array<Parity, 2> arr;
99
100 arr[0] = EVEN;
101 arr[1] = ODD;
102
103 shuffle(arr);
104 hila::broadcast(arr); // sync with all nodes
105 return arr;
106}
107
108
109} // namespace hila
110
111#endif
Parity
Parity enum with values EVEN, ODD, ALL; refers to parity of the site. Parity of site (x,...
constexpr Parity EVEN
bit pattern: 001
#define foralldir(d)
Macro to loop over (all) Direction(s)
Definition coordinates.h:78
constexpr Parity ODD
bit pattern: 010
Direction
Enumerator for direction that assigns integer to direction to be interpreted as unit vector.
Definition coordinates.h:34
Implement hila::swap for gauge fields.
Definition array.h:981
auto shuffle_directions_and_parities()
Definition shuffle.h:49
double random()
Real valued uniform random number generator.
Definition hila_gpu.cpp:118
T broadcast(T &var, int rank=0)
Broadcast the value of var to all MPI ranks from rank (default=0).
Definition com_mpi.h:153
auto shuffle_directions()
Definition shuffle.h:83
void shuffle(T &arr)
Definition shuffle.h:23