The ROme OpTimistic Simulator  3.0.0
A General-Purpose Multithreaded Parallel/Distributed Simulation Platform
topology.c
Go to the documentation of this file.
1 
11 #include <lib/topology/topology.h>
12 
13 #include <core/intrinsics.h>
14 #include <lib/lib_internal.h>
15 
16 #include <math.h>
17 #include <memory.h>
18 
19 __attribute((weak)) struct topology_settings_t topology_settings;
20 
22 struct {
23  lp_id_t regions_cnt;
24  uint32_t edge;
25  enum _topology_geometry_t geometry;
26 } topology_global;
27 
33 {
34  if (!topology_settings.default_geometry &&
35  !topology_settings.out_of_topology)
36  // the strong symbol isn't defined: we aren't needed
37  return;
38 
39  // set default values
40  const lp_id_t regions_cnt = n_lps - topology_settings.out_of_topology;
41  topology_global.regions_cnt = regions_cnt;
42  topology_global.geometry = topology_settings.default_geometry;
43  // compute the edge value for topologies it makes sense for
44  unsigned edge;
45 
46  switch (topology_global.geometry) {
47  case TOPOLOGY_SQUARE:
48  case TOPOLOGY_HEXAGON:
49  case TOPOLOGY_TORUS:
50  edge = sqrt(regions_cnt);
51  // we make sure there are no "lonely" LPs
52  if (edge * edge != regions_cnt) {
53  log_log(LOG_FATAL, "Invalid number of regions for this topology geometry (must be a square number)\n");
54  exit(-1);
55  }
56  break;
57  default:
58  // the edge value is actually unused
59  edge = 0;
60  break;
61  }
62  // set the edge value
63  topology_global.edge = edge;
64 }
65 
66 __attribute__ ((pure)) lp_id_t RegionsCount(void)
67 {
68  return topology_global.regions_cnt;
69 }
70 
71 __attribute__ ((pure)) lp_id_t DirectionsCount(void)
72 {
73  switch (topology_global.geometry) {
74  case TOPOLOGY_MESH:
75  return topology_global.regions_cnt - 1;
76  case TOPOLOGY_HEXAGON:
77  return 6;
78  case TOPOLOGY_TORUS:
79  case TOPOLOGY_SQUARE:
80  return 4;
81  case TOPOLOGY_STAR:
82  return 2;
83  case TOPOLOGY_RING:
84  return 1;
85  case TOPOLOGY_BIDRING:
86  return 2;
87  }
88  return UINT_MAX;
89 }
90 
91 __attribute__ ((pure)) lp_id_t GetReceiver(lp_id_t from,
92  enum _direction_t direction)
93 {
94  const lp_id_t sender = from;
95  const uint32_t edge = topology_global.edge;
96  const lp_id_t regions_cnt = topology_global.regions_cnt;
97  unsigned x, y;
98 
99  if (unlikely(regions_cnt <= from))
100  return DIRECTION_INVALID;
101 
102  switch (topology_global.geometry) {
103 
104  case TOPOLOGY_HEXAGON:
105  y = sender / edge;
106  x = sender - y * edge;
107 
108  switch (direction) {
109  case DIRECTION_NW:
110  x += (y & 1U) - 1;
111  y -= 1;
112  break;
113  case DIRECTION_NE:
114  x += (y & 1U);
115  y -= 1;
116  break;
117  case DIRECTION_SW:
118  x += (y & 1U) - 1;
119  y += 1;
120  break;
121  case DIRECTION_SE:
122  x += (y & 1U);
123  y += 1;
124  break;
125  case DIRECTION_E:
126  x += 1;
127  break;
128  case DIRECTION_W:
129  x -= 1;
130  break;
131  default:
132  return DIRECTION_INVALID;
133  }
134  return (x < edge && y < edge) ? y * edge + x : DIRECTION_INVALID;
135 
136  case TOPOLOGY_SQUARE:
137  y = sender / edge;
138  x = sender - y * edge;
139 
140  switch (direction) {
141  case DIRECTION_N:
142  y -= 1;
143  break;
144  case DIRECTION_S:
145  y += 1;
146  break;
147  case DIRECTION_E:
148  x += 1;
149  break;
150  case DIRECTION_W:
151  x -= 1;
152  break;
153  default:
154  return DIRECTION_INVALID;
155  }
156  return (x < edge && y < edge) ? y * edge + x : DIRECTION_INVALID;
157 
158  case TOPOLOGY_TORUS:
159  y = sender / edge;
160  x = sender - y * edge;
161 
162  switch (direction) {
163  case DIRECTION_N:
164  y += edge - 1;
165  y %= edge;
166  break;
167  case DIRECTION_S:
168  y += 1;
169  y %= edge;
170  break;
171  case DIRECTION_E:
172  x += 1;
173  x %= edge;
174  break;
175  case DIRECTION_W:
176  x += edge - 1;
177  x %= edge;
178  break;
179  default:
180  return DIRECTION_INVALID;
181  }
182  return y * edge + x;
183 
184  case TOPOLOGY_MESH:
185  return likely((lp_id_t)direction < regions_cnt) ? direction : DIRECTION_INVALID;
186 
187  case TOPOLOGY_BIDRING:
188  switch (direction) {
189  case DIRECTION_N:
190  return (sender + 1) % regions_cnt;
191  case DIRECTION_S:
192  return (sender + regions_cnt - 1) % regions_cnt;
193  default:
194  return DIRECTION_INVALID;
195  }
196  case TOPOLOGY_RING:
197  return likely(direction == DIRECTION_N) ? direction : DIRECTION_INVALID;
198 
199  case TOPOLOGY_STAR:
200  if(sender) {
201  if(!direction)
202  return 0;
203  } else {
204  if((uint64_t)direction + 1 < regions_cnt)
205  return direction + 1;
206  }
207  }
208  return DIRECTION_INVALID;
209 }
210 
211 lp_id_t FindReceiver(void)
212 {
213  const lp_id_t dir_cnt = DirectionsCount();
214  const unsigned bits = 64 - intrinsics_clz(dir_cnt);
215  uint64_t rnd = RandomU64();
216  unsigned i = 64;
217  do {
218  lp_id_t dir = rnd & ((UINT64_C(1) << bits) - 1);
219  if (dir < dir_cnt) {
220  dir += 2 * (topology_global.geometry == TOPOLOGY_HEXAGON);
221  const lp_id_t ret = GetReceiver(lp_id_get(), dir);
222  if (ret != DIRECTION_INVALID)
223  return ret;
224  }
225 
226  if (likely((i -= bits) >= bits)) {
227  rnd >>= bits;
228  } else {
229  rnd = RandomU64();
230  i = 64;
231  }
232  } while(1);
233 }
topology_global_init
void topology_global_init(void)
Definition: topology.c:32
__attribute
__attribute((weak))
this is used to store the common characteristics of the topology
Definition: topology.c:19
topology.h
Topology library.
intrinsics_clz
#define intrinsics_clz(x)
Counts the leading zeros in a base 2 number.
Definition: intrinsics.h:47
TOPOLOGY_RING
@ TOPOLOGY_RING
a ring shaped topology walkable in a single direction
Definition: topology.h:23
n_lps
lp_id_t n_lps
The total number of LPs in the simulation.
Definition: core.c:13
DIRECTION_E
@ DIRECTION_E
East direction.
Definition: topology.h:33
DIRECTION_INVALID
@ DIRECTION_INVALID
A generic invalid direction.
Definition: topology.h:41
DIRECTION_SE
@ DIRECTION_SE
South-east direction.
Definition: topology.h:38
topology_settings_t::out_of_topology
lp_id_t out_of_topology
The minimum number of LPs needed for out of the topology logic.
Definition: topology.h:49
lib_internal.h
Internal core libraries.
DIRECTION_NW
@ DIRECTION_NW
North-west direction.
Definition: topology.h:37
DIRECTION_W
@ DIRECTION_W
West direction.
Definition: topology.h:34
log_log
#define log_log(lvl,...)
Produces a log.
Definition: log.h:49
TOPOLOGY_BIDRING
@ TOPOLOGY_BIDRING
a ring shaped topology
Definition: topology.h:24
DIRECTION_N
@ DIRECTION_N
North direction.
Definition: topology.h:31
TOPOLOGY_SQUARE
@ TOPOLOGY_SQUARE
square grid topology
Definition: topology.h:22
LOG_FATAL
#define LOG_FATAL
The logging level reserved to unexpected, fatal conditions.
Definition: log.h:35
_topology_geometry_t
_topology_geometry_t
Definition: topology.h:20
TOPOLOGY_MESH
@ TOPOLOGY_MESH
an arbitrary shaped topology
Definition: topology.h:27
TOPOLOGY_HEXAGON
@ TOPOLOGY_HEXAGON
hexagonal grid topology
Definition: topology.h:21
likely
#define likely(exp)
Optimize the branch as likely taken.
Definition: core.h:57
_direction_t
_direction_t
Definition: topology.h:30
lp_id_t
uint64_t lp_id_t
Used to uniquely identify LPs in the simulation.
Definition: core.h:75
TOPOLOGY_TORUS
@ TOPOLOGY_TORUS
a torus shaped grid topology (a wrapping around square topology)
Definition: topology.h:25
unlikely
#define unlikely(exp)
Optimize the branch as likely not taken.
Definition: core.h:59
DIRECTION_SW
@ DIRECTION_SW
South-west direction.
Definition: topology.h:36
intrinsics.h
Easier access to compiler extensions.
topology_settings_t::default_geometry
enum _topology_geometry_t default_geometry
The default geometry to use when nothing else is specified.
Definition: topology.h:47
TOPOLOGY_STAR
@ TOPOLOGY_STAR
a star shaped topology
Definition: topology.h:26
DIRECTION_S
@ DIRECTION_S
South direction.
Definition: topology.h:32
DIRECTION_NE
@ DIRECTION_NE
North-east direction.
Definition: topology.h:35
topology_settings_t
This is declared by the model to setup the topology module.
Definition: topology.h:45