Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
c2939600a23e6574a76ea418a7610d999b757f92
[simgrid.git] / src / simdag / sd_workstation.c
1 #include "private.h"
2 #include "simdag/simdag.h"
3 #include "xbt/dict.h"
4 #include "xbt/sysdep.h"
5 #include "surf/surf.h"
6
7 /* Creates a workstation and registers it in SD.
8  */
9 SD_workstation_t __SD_workstation_create(void *surf_workstation, void *data) {
10   SD_CHECK_INIT_DONE();
11   xbt_assert0(surf_workstation != NULL, "surf_workstation is NULL !");
12
13   SD_workstation_t workstation = xbt_new0(s_SD_workstation_t, 1);
14   workstation->surf_workstation = surf_workstation;
15   workstation->data = data; /* user data */
16   
17   const char *name = SD_workstation_get_name(workstation);
18   xbt_dict_set(sd_global->workstations, name, workstation, __SD_workstation_destroy); /* add the workstation to the dictionary */
19   sd_global->workstation_count++;
20
21   return workstation;
22 }
23
24 /**
25  * \brief Returns a workstation given its name
26  *
27  * If there is no such workstation, the function returns \c NULL.
28  *
29  * \param name workstation name
30  * \return the workstation, or \c NULL if there is no such workstation
31  */
32 SD_workstation_t SD_workstation_get_by_name(const char *name) {
33   SD_CHECK_INIT_DONE();
34
35   xbt_assert0(name != NULL, "Invalid parameter");
36
37   return xbt_dict_get_or_null(sd_global->workstations, name);
38 }
39
40 /**
41  * \brief Returns the workstation list
42  *
43  * Use SD_workstation_get_number() to know the array size.
44  *
45  * \return an array of \ref SD_workstation_t containing all workstations
46  * \see SD_workstation_get_number()
47  */
48 const SD_workstation_t*  SD_workstation_get_list(void) {
49   SD_CHECK_INIT_DONE();
50   xbt_assert0(SD_workstation_get_number() > 0, "There is no workstation!");
51
52   SD_workstation_t *array = sd_global->workstation_list;
53   xbt_dict_cursor_t cursor;
54   char *key;
55   void *data;
56   int i;
57
58   if (array == NULL) { /* this is the first time the function is called */
59     array = xbt_new0(SD_workstation_t, sd_global->workstation_count);
60   
61     i = 0;
62     xbt_dict_foreach(sd_global->workstations, cursor, key, data) {
63       array[i++] = (SD_workstation_t) data;
64     }
65   }
66   return array;
67 }
68
69 /**
70  * \brief Returns the number of workstations
71  *
72  * \return the number of existing workstations
73  * \see SD_workstation_get_list()
74  */
75 int SD_workstation_get_number(void) {
76   SD_CHECK_INIT_DONE();
77   return sd_global->workstation_count;
78 }
79
80 /**
81  * \brief Returns the user data of a workstation
82  *
83  * \param workstation a workstation
84  * \return the user data associated with this workstation (can be \c NULL)
85  * \see SD_workstation_set_data()
86  */
87 void* SD_workstation_get_data(SD_workstation_t workstation) {
88   SD_CHECK_INIT_DONE();
89   xbt_assert0(workstation != NULL, "Invalid parameter");
90   return workstation->data;
91 }
92
93 /**
94  * \brief Sets the user data of a workstation
95  *
96  * The new data can be \c NULL. The old data should have been freed first
97  * if it was not \c NULL.
98  *
99  * \param workstation a workstation
100  * \param data the new data you want to associate with this workstation
101  * \see SD_workstation_get_data()
102  */
103 void SD_workstation_set_data(SD_workstation_t workstation, void *data) {
104   SD_CHECK_INIT_DONE();
105   xbt_assert0(workstation != NULL, "Invalid parameter");
106   workstation->data = data;
107 }
108
109 /**
110  * \brief Returns the name of a workstation
111  *
112  * \param workstation a workstation
113  * \return the name of this workstation (cannot be \c NULL)
114  */
115 const char* SD_workstation_get_name(SD_workstation_t workstation) {
116   SD_CHECK_INIT_DONE();
117   xbt_assert0(workstation != NULL, "Invalid parameter");
118   return surf_workstation_resource->common_public->get_resource_name(workstation->surf_workstation);
119 }
120
121 /**
122  * \brief Returns the route between two workstations
123  *
124  * Use SD_workstation_route_get_size() to know the array size. Don't forget to free the array after use.
125  *
126  * \param src a workstation
127  * \param dst another workstation
128  * \return a new array of \ref SD_link_t representating the route between these two workstations
129  * \see SD_workstation_route_get_size(), SD_link_t
130  */
131 SD_link_t* SD_workstation_route_get_list(SD_workstation_t src, SD_workstation_t dst) {
132   SD_CHECK_INIT_DONE();
133
134   void *surf_src = src->surf_workstation;
135   void *surf_dst = dst->surf_workstation;
136
137   const void **surf_route = surf_workstation_resource->extension_public->get_route(surf_src, surf_dst);
138   int route_size = surf_workstation_resource->extension_public->get_route_size(surf_src, surf_dst);
139
140   SD_link_t* route = xbt_new0(SD_link_t, route_size);
141   const char *link_name;
142   int i;
143   for (i = 0; i < route_size; i++) {
144     link_name = surf_workstation_resource->extension_public->get_link_name(surf_route[i]);
145     route[i] = xbt_dict_get(sd_global->links, link_name);
146   }
147
148   return route;
149 }
150
151 /**
152  * \brief Returns the number of links on the route between two workstations
153  *
154  * \param src a workstation
155  * \param dst another workstation
156  * \return the number of links on the route between these two workstations
157  * \see SD_workstation_route_get_list()
158  */
159 int SD_workstation_route_get_size(SD_workstation_t src, SD_workstation_t dst) {
160   SD_CHECK_INIT_DONE();
161   return surf_workstation_resource->extension_public->
162     get_route_size(src->surf_workstation, dst->surf_workstation);
163 }
164
165 /**
166  * \brief Returns the total power of a workstation
167  *
168  * \param workstation a workstation
169  * \return the total power of this workstation
170  * \see SD_workstation_get_available_power()
171  */
172 double SD_workstation_get_power(SD_workstation_t workstation) {
173   SD_CHECK_INIT_DONE();
174   xbt_assert0(workstation != NULL, "Invalid parameter");
175   return surf_workstation_resource->extension_public->get_speed(workstation->surf_workstation, 1.0);
176 }
177
178 /**
179  * \brief Returns the proportion of available power in a workstation
180  *
181  * \param workstation a workstation
182  * \return the proportion of power currently available in this workstation (normally a number between 0 and 1)
183  * \see SD_workstation_get_power()
184  */
185 double SD_workstation_get_available_power(SD_workstation_t workstation) {
186   SD_CHECK_INIT_DONE();
187   xbt_assert0(workstation != NULL, "Invalid parameter");
188   return surf_workstation_resource->extension_public->get_available_speed(workstation->surf_workstation);
189 }
190
191 /**
192  * \brief Returns an approximative estimated time for the given computation amount on a workstation
193  *
194  * \param workstation a workstation
195  * \param computation_amount the computation amount you want to evaluate (in flops)
196  * \return an approximative astimated computation time for the given computation amount on this workstation (in seconds)
197  */
198 double SD_workstation_get_computation_time(SD_workstation_t workstation, double computation_amount) {
199   SD_CHECK_INIT_DONE();
200   xbt_assert0(workstation != NULL, "Invalid parameter");
201   xbt_assert0(computation_amount >= 0, "computation_amount must be greater than or equal to zero");
202   return computation_amount / SD_workstation_get_power(workstation);
203 }
204
205 /**
206  * \brief Returns the latency of the route between two workstations, i.e. the sum of all link latencies
207  * between the workstations.
208  *
209  * \param src the first workstation
210  * \param dst the second workstation
211  * \return the latency of the route between the two workstations (in seconds)
212  */
213 double SD_workstation_route_get_latency(SD_workstation_t src, SD_workstation_t dst) {
214   SD_CHECK_INIT_DONE();
215   xbt_assert0(src != NULL && dst != NULL, "Invalid parameter");
216   SD_link_t *links = SD_workstation_route_get_list(src, dst);
217   int nb_links = SD_workstation_route_get_size(src, dst);
218   double latency = 0.0;
219   int i;
220   
221   for (i = 0; i < nb_links; i++) {
222     latency += SD_link_get_current_latency(links[i]);
223   }
224
225   free(links);
226   return latency;
227 }
228
229 /**
230  * \brief Returns the bandwidth of the route between two workstations, i.e. the minimum link bandwidth of all
231  * between the workstations.
232  *
233  * \param src the first workstation
234  * \param dst the second workstation
235  * \return the bandwidth of the route between the two workstations (in bytes/second)
236  */
237 double SD_workstation_route_get_bandwidth(SD_workstation_t src, SD_workstation_t dst) {
238   SD_CHECK_INIT_DONE();
239   xbt_assert0(src != NULL && dst != NULL, "Invalid parameter");
240   SD_link_t *links = SD_workstation_route_get_list(src, dst);
241   int nb_links = SD_workstation_route_get_size(src, dst);
242   double bandwidth, min_bandwidth = -1.0;
243   int i;
244   
245   for (i = 0; i < nb_links; i++) {
246     bandwidth = SD_link_get_current_bandwidth(links[i]);
247     if (bandwidth < min_bandwidth || min_bandwidth == -1.0)
248       min_bandwidth = bandwidth;
249   }
250
251   free(links);
252   return min_bandwidth;
253 }
254
255 /**
256  * \brief Returns an approximative estimated time for the given
257  * communication amount between two workstations
258  *
259  * \param src the first workstation
260  * \param dst the second workstation
261  * \param communication_amount the communication amount you want to evaluate (in bytes)
262  * \return an approximative astimated computation time for the given communication amount
263  * between the workstations (in seconds)
264  */
265 double SD_workstation_route_get_communication_time(SD_workstation_t src, SD_workstation_t dst,
266                                                    double communication_amount) {
267   /* total time = latency + transmission time of the slowest link
268      transmission time of a link = communication amount / link bandwidth */
269   SD_CHECK_INIT_DONE();
270   xbt_assert0(src != NULL && dst != NULL, "Invalid parameter");
271   xbt_assert0(communication_amount >= 0, "communication_amount must be greater than or equal to zero");
272
273   SD_link_t *links;
274   int nb_links;
275   double bandwidth, min_bandwidth;
276   double latency;
277   int i;
278   
279   if (communication_amount == 0.0)
280     return 0.0;
281
282   links = SD_workstation_route_get_list(src, dst);
283   nb_links = SD_workstation_route_get_size(src, dst);
284   min_bandwidth = -1.0;
285   latency = 0;
286
287   for (i = 0; i < nb_links; i++) {
288     latency += SD_link_get_current_latency(links[i]);
289     bandwidth = SD_link_get_current_bandwidth(links[i]);
290     if (bandwidth < min_bandwidth || min_bandwidth == -1.0)
291       min_bandwidth = bandwidth;
292   }
293
294   return latency + (communication_amount / min_bandwidth);
295 }
296
297 /* Destroys a workstation.
298  */
299 void __SD_workstation_destroy(void *workstation) {
300   SD_CHECK_INIT_DONE();
301   xbt_assert0(workstation != NULL, "Invalid parameter");
302   /* workstation->surf_workstation is freed by surf_exit and workstation->data is freed by the user */
303   xbt_free(workstation);
304 }