Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
6288b5b508ffbed136904ee1028b5d473704c0ef
[simgrid.git] / src / surf / platf_generator.c
1
2
3 #include "simgrid/platf_generator.h"
4 #include "platf_generator_private.h"
5 #include "xbt.h"
6 #include "xbt/RngStream.h"
7 #include <math.h>
8
9 static xbt_graph_t platform_graph = NULL;
10
11 static RngStream rng_stream = NULL;
12
13 static unsigned long last_link_id = 0;
14
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;
19 }
20
21 void platf_random_seed(unsigned long seed[6]) {
22
23   if(rng_stream == NULL) {
24     //stream not created yet, we do it now
25     rng_stream = RngStream_CreateStream(NULL);
26   }
27   if(seed != NULL) {
28     RngStream_SetSeed(rng_stream, seed);
29   }
30 }
31
32 void platf_graph_init(unsigned long node_count) {
33   unsigned long i;
34   platform_graph = xbt_graph_new_graph(FALSE, NULL);
35   if(rng_stream == NULL) {
36     rng_stream = RngStream_CreateStream(NULL);
37   }
38
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);
42     node_data->id = i+1;
43     node_data->x = 0;
44     node_data->y = 0;
45     node_data->degree = 0;
46     node_data->kind = ROUTER;
47     xbt_graph_new_node(platform_graph, (void*) node_data);
48   }
49
50   last_link_id = 0;
51
52 }
53
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);
59   node1_data->degree++;
60   node2_data->degree++;
61
62   unsigned long *link_id = xbt_new(unsigned long, 1);
63   *link_id = ++last_link_id;
64
65   xbt_graph_new_edge(platform_graph, node1, node2, (void*)link_id);
66 }
67
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;
71   double delta_x;
72   double delta_y;
73   double distance;
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);
79   return distance;
80 }
81
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;
86   unsigned int i;
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);
93   }
94 }
95
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;
100   unsigned int i;
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*/);
107   }
108 }
109
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;
115   unsigned int i;
116
117   dynar_nodes = xbt_graph_get_nodes(platform_graph);
118   xbt_dynar_foreach(dynar_nodes, i, graph_node) {
119     if(i==0) {
120       //Ok, we get the first node, let's keep it somewhere...
121       first_node = graph_node;
122     } else {
123       //All the other nodes are connected to the first one
124       platf_node_connect(graph_node, first_node);
125     }
126   }
127 }
128
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;
134   unsigned int i;
135
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);
140     }
141     old_node = graph_node;
142   }
143 }
144
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;
151   unsigned int i;
152
153   dynar_nodes = xbt_graph_get_nodes(platform_graph);
154   xbt_dynar_foreach(dynar_nodes, i, graph_node) {
155     if(i == 0) {
156       // this is the first node, let's keep it somewhere
157       first_node = graph_node;
158     } else {
159       //connect each node to the previous one
160       platf_node_connect(graph_node, old_node);
161     }
162     old_node = graph_node;
163   }
164   //we still have to connect the first and the last node together
165   platf_node_connect(first_node, graph_node);
166 }
167
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;
173   unsigned int i,j;
174
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);
179     }
180   }
181 }
182
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;
189   unsigned int i,j;
190
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) {
194       if(j>=i)
195         break;
196       if(RngStream_RandU01(rng_stream) < alpha) {
197         platf_node_connect(first_node, second_node);
198       }
199     }
200   }
201 }
202
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;
209   unsigned int i,j;
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) {
214       if(j>=i)
215         break;
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);
219       }
220     }
221   }
222 }
223
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));
228 }
229
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));
234 }
235
236
237 /* Functions used to generate interesting random values */
238
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
244   if (res>max) {
245     return max;
246   }
247   return res;
248 }