HILA
Loading...
Searching...
No Matches
map_node_layout.cpp
1/// This routine uses internal MPI (or other) commands to remap the
2/// node numbers so that the communications should be optimised.
3///
4/// Implements two calls,
5/// int remap(int i) : given "computed" node index i, returns true mpi rank
6/// the input i is the logical node index, runs fastest to directions x,y,z,(t)
7/// must be compatible with node_rank layout!
8///
9/// int inverse_remap(int i) : inverse of above
10///
11/// Used especially in transformation coordinate -> node_rank, in
12/// lattice_struct::node_rank in
13
14
15#include "plumbing/defs.h"
16#include "plumbing/lattice.h"
17
18#if defined(NODE_LAYOUT_TRIVIAL)
19
20////////////////////////////////////////////////////////////////////
21// This is the trivial version, so that the order is unmodified
22////////////////////////////////////////////////////////////////////
23
25 hila::out0 << "Node remapping: NODE_LAYOUT_TRIVIAL (no reordering)\n";
26 lattice->nodes.map_array = nullptr;
27 lattice->nodes.map_inverse = nullptr;
28}
29
30int lattice_struct::allnodes::remap(int i) const {
31 return i;
32}
33
34int lattice_struct::allnodes::inverse_remap(int i) const {
35 return i;
36}
37
38
39#elif defined(NODE_LAYOUT_BLOCK)
40
41////////////////////////////////////////////////////////////////////
42// Arrange nodes so that NODE_LAYOUT_BLOCK nodes are "close"
43//
44// For example, in 2d and NODE_LAYOUT_BLOCK = 4 the MPI indices run as
45//
46// 1 2 | 5 6 | 9 10
47// 3 4 | 7 8 | 11 12
48// -----+-------+------
49// 13 14 | 17 18 | 21 22
50// 15 16 | 19 20 | 23 24
51//
52////////////////////////////////////////////////////////////////////
53
55
56 hila::out0 << "Node remapping: NODE_LAYOUT_BLOCK with blocksize " << NODE_LAYOUT_BLOCK << '\n';
57
58 // let us allow only factors of 5,3 and 2 in NODE_LAYOUT_BLOCK
59 CoordinateVector blocksize;
60 CoordinateVector blockdivs = lattice->nodes.n_divisions;
61 int nblocks = NODE_LAYOUT_BLOCK;
62 blocksize.fill(1);
63
64 bool found = true;
65 while (found && nblocks > 1) {
66
67 found = false; // if not divisible stop trying
68 foralldir(d) {
69 // divide directions one by one
70 int div;
71 for (div = 2; div <= 5; div++)
72 if (nblocks % div == 0 && blockdivs[d] % div == 0)
73 break;
74 if (div <= 5) {
75 blocksize[d] *= div;
76 blockdivs[d] /= div;
77 nblocks /= div;
78 found = true;
79 }
80 }
81 }
82
83 hila::out0 << "Node block size " << blocksize << " block division " << blockdivs << '\n';
84
85 // now blocksize tells us how many nodes to each direction in block
86 // these are taken in order
87
88 this->map_array = (int *)memalloc(this->number * sizeof(int));
89 this->map_inverse = (int *)memalloc(this->number * sizeof(int));
90 // nodes.map_inverse = nullptr;
91
92 nblocks = 1;
93 foralldir(d) nblocks *= blocksize[d];
94
95 // Loop over the "logical" node indices (i.e.)
96
97 for (int i = 0; i < this->number; i++) {
98 // lcoord is the coordinate of the logical node,
99 // bcoord the block coord and icoord coord inside block
100 CoordinateVector lcoord, bcoord, icoord;
101 int idiv = i;
102 foralldir(d) {
103 lcoord[d] = idiv % this->n_divisions[d];
104 idiv /= this->n_divisions[d];
105
106 bcoord[d] = lcoord[d] / blocksize[d];
107 icoord[d] = lcoord[d] % blocksize[d];
108 }
109
110 // ii - index within a block
111 // bi - index of a block
112 int ii, bi, im, bm;
113 ii = bi = 0;
114 im = bm = 1;
115 foralldir(d) {
116 ii += icoord[d] * im;
117 im *= blocksize[d];
118
119 bi += bcoord[d] * bm;
120 bm *= blockdivs[d];
121 }
122
123 // hila::out0 << lcoord << bcoord << icoord << '\n';
124 // hila::out0 << "ii " << ii << " bi " << bi << '\n';
125
126 this->map_array[i] = bi * nblocks + ii;
127 this->map_inverse[bi * nblocks + ii] = i;
128 }
129}
130
131/// And the call interface for remapping
132
134 assert( i >= 0 && i < hila::number_of_nodes());
135 return this->map_array[i];
136}
137
138int lattice_struct::allnodes::inverse_remap(int i) const {
139 assert( i >= 0 && i < hila::number_of_nodes());
140 return this->map_inverse[i];
141}
142
143
144#else
145
146NODE_LAYOUT_BLOCK or NODE_LAYOUT_TRIVIAL must be defined
147
148#endif
const auto & fill(const S rhs)
Matrix fill.
Definition matrix.h:1022
#define foralldir(d)
Macro to loop over (all) Direction(s)
Definition coordinates.h:80
This file defines all includes for HILA.
int number_of_nodes()
how many nodes there are
Definition com_mpi.cpp:248
std::ostream out0
This writes output only from main process (node 0)
#define NODE_LAYOUT_BLOCK
Definition params.h:63
int remap(int i) const
And the call interface for remapping.