3 #include "simgrid/platf_generator.h"
4 #include "platf_generator_private.h"
6 #include "xbt/RngStream.h"
9 static xbt_graph_t platform_graph = NULL;
11 static RngStream rng_stream = NULL;
13 static unsigned long last_link_id = 0;
15 xbt_graph_t platf_graph_get(void) {
16 // We need some debug, so let's add this function
17 // WARNING : shold be removed when it becomes useless
18 return platform_graph;
21 void platf_random_seed(unsigned long seed[6]) {
23 if(rng_stream == NULL) {
24 //stream not created yet, we do it now
25 rng_stream = RngStream_CreateStream(NULL);
28 RngStream_SetSeed(rng_stream, seed);
32 void platf_graph_init(unsigned long node_count) {
34 platform_graph = xbt_graph_new_graph(FALSE, NULL);
35 if(rng_stream == NULL) {
36 rng_stream = RngStream_CreateStream(NULL);
39 for(i=0 ; i<node_count ; i++) {
40 context_node_t node_data = NULL;
41 node_data = xbt_new(s_context_node_t, 1);
45 node_data->degree = 0;
46 node_data->kind = ROUTER;
47 xbt_graph_new_node(platform_graph, (void*) node_data);
54 void platf_node_connect(xbt_node_t node1, xbt_node_t node2) {
55 context_node_t node1_data;
56 context_node_t node2_data;
57 node1_data = (context_node_t) xbt_graph_node_get_data(node1);
58 node2_data = (context_node_t) xbt_graph_node_get_data(node2);
62 unsigned long *link_id = xbt_new(unsigned long, 1);
63 *link_id = ++last_link_id;
65 xbt_graph_new_edge(platform_graph, node1, node2, (void*)link_id);
68 double platf_node_distance(xbt_node_t node1, xbt_node_t node2) {
69 context_node_t node1_data;
70 context_node_t node2_data;
74 node1_data = (context_node_t) xbt_graph_node_get_data(node1);
75 node2_data = (context_node_t) xbt_graph_node_get_data(node2);
76 delta_x = node1_data->x - node2_data->x;
77 delta_y = node1_data->y - node2_data->y;
78 distance = sqrt(delta_x*delta_x + delta_y*delta_y);
82 void platf_graph_uniform(unsigned long node_count) {
83 xbt_dynar_t dynar_nodes = NULL;
84 xbt_node_t graph_node = NULL;
85 context_node_t node_data = NULL;
87 platf_graph_init(node_count);
88 dynar_nodes = xbt_graph_get_nodes(platform_graph);
89 xbt_dynar_foreach(dynar_nodes, i, graph_node) {
90 node_data = (context_node_t) xbt_graph_node_get_data(graph_node);
91 node_data->x = RngStream_RandU01(rng_stream);
92 node_data->y = RngStream_RandU01(rng_stream);
96 void platf_graph_heavytailed(unsigned long node_count) {
97 xbt_dynar_t dynar_nodes = NULL;
98 xbt_node_t graph_node = NULL;
99 context_node_t node_data = NULL;
101 platf_graph_init(node_count);
102 dynar_nodes = xbt_graph_get_nodes(platform_graph);
103 xbt_dynar_foreach(dynar_nodes, i, graph_node) {
104 node_data = (context_node_t) xbt_graph_node_get_data(graph_node);
105 node_data->x = random_pareto(0, 1, 1.0/*K*/, 10e9/*P*/, 1.0/*alpha*/);
106 node_data->y = random_pareto(0, 1, 1.0/*K*/, 10e9/*P*/, 1.0/*alpha*/);
110 void platf_graph_interconnect_star(void) {
111 /* All the nodes are connected to the first one */
112 xbt_dynar_t dynar_nodes = NULL;
113 xbt_node_t graph_node = NULL;
114 xbt_node_t first_node = NULL;
117 dynar_nodes = xbt_graph_get_nodes(platform_graph);
118 xbt_dynar_foreach(dynar_nodes, i, graph_node) {
120 //Ok, we get the first node, let's keep it somewhere...
121 first_node = graph_node;
123 //All the other nodes are connected to the first one
124 platf_node_connect(graph_node, first_node);
129 void platf_graph_interconnect_line(void) {
130 /* Node are connected to the previous and the next node, in a line */
131 xbt_dynar_t dynar_nodes = NULL;
132 xbt_node_t graph_node = NULL;
133 xbt_node_t old_node = NULL;
136 dynar_nodes = xbt_graph_get_nodes(platform_graph);
137 xbt_dynar_foreach(dynar_nodes, i, graph_node) {
138 if(old_node != NULL) {
139 platf_node_connect(graph_node, old_node);
141 old_node = graph_node;
145 void platf_graph_interconnect_ring(void) {
146 /* Create a simple topology where all nodes are connected along a ring */
147 xbt_dynar_t dynar_nodes = NULL;
148 xbt_node_t graph_node = NULL;
149 xbt_node_t old_node = NULL;
150 xbt_node_t first_node = NULL;
153 dynar_nodes = xbt_graph_get_nodes(platform_graph);
154 xbt_dynar_foreach(dynar_nodes, i, graph_node) {
156 // this is the first node, let's keep it somewhere
157 first_node = graph_node;
159 //connect each node to the previous one
160 platf_node_connect(graph_node, old_node);
162 old_node = graph_node;
164 //we still have to connect the first and the last node together
165 platf_node_connect(first_node, graph_node);
168 void platf_graph_interconnect_clique(void) {
169 /* Create a simple topology where all nodes are connected to each other, in a clique manner */
170 xbt_dynar_t dynar_nodes = NULL;
171 xbt_node_t first_node = NULL;
172 xbt_node_t second_node = NULL;
175 dynar_nodes = xbt_graph_get_nodes(platform_graph);
176 xbt_dynar_foreach(dynar_nodes, i, first_node) {
177 xbt_dynar_foreach(dynar_nodes, j, second_node) {
178 platf_node_connect(first_node, second_node);
183 void platf_graph_interconnect_uniform(double alpha) {
184 /* Creates a topology where the probability to connect two nodes is uniform (unrealistic, but simple)
185 alpha : Probability for two nodes to get connected */
186 xbt_dynar_t dynar_nodes = NULL;
187 xbt_node_t first_node = NULL;
188 xbt_node_t second_node = NULL;
191 dynar_nodes = xbt_graph_get_nodes(platform_graph);
192 xbt_dynar_foreach(dynar_nodes, i, first_node) {
193 xbt_dynar_foreach(dynar_nodes, j, second_node) {
196 if(RngStream_RandU01(rng_stream) < alpha) {
197 platf_node_connect(first_node, second_node);
203 void platf_graph_interconnect_exponential(double alpha) {
204 /* Create a topology where the probability follows an exponential law
205 Number of edges increases with alpha */
206 xbt_dynar_t dynar_nodes = NULL;
207 xbt_node_t first_node = NULL;
208 xbt_node_t second_node = NULL;
210 double L = sqrt(2.0); /* L = c*sqrt(2); c=side of placement square */
211 dynar_nodes = xbt_graph_get_nodes(platform_graph);
212 xbt_dynar_foreach(dynar_nodes, i, first_node) {
213 xbt_dynar_foreach(dynar_nodes, j, second_node) {
216 double d = platf_node_distance(first_node, second_node);
217 if(RngStream_RandU01(rng_stream) < alpha*exp(-d/(L-d))) {
218 platf_node_connect(first_node, second_node);
224 void platf_graph_promote_to_host(xbt_node_t node, sg_platf_host_cbarg_t parameters) {
225 context_node_t node_data = (context_node_t) xbt_graph_node_get_data(node);
226 node_data->kind = HOST;
227 memcpy(&(node_data->host_parameters), parameters, sizeof(s_sg_platf_host_cbarg_t));
230 void platf_graph_promote_to_cluster(xbt_node_t node, sg_platf_cluster_cbarg_t parameters) {
231 context_node_t node_data = (context_node_t) xbt_graph_node_get_data(node);
232 node_data->kind = CLUSTER;
233 memcpy(&(node_data->cluster_parameters), parameters, sizeof(s_sg_platf_cluster_cbarg_t));
237 /* Functions used to generate interesting random values */
239 double random_pareto(double min, double max, double K, double P, double ALPHA) {
240 double x = RngStream_RandU01(rng_stream);
241 double den = pow(1.0 - x + x*pow(K/P, ALPHA), 1.0/ALPHA);
242 double res = (1/den);
243 res += min - 1; // pareto is on [1, infinity) by default