Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Starting the SimDag revolution: Easter trimming
[simgrid.git] / src / simdag / sd_workstation.cpp
1 /* Copyright (c) 2006-2016. The SimGrid Team.
2  * All rights reserved.                                                     */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "src/surf/host_interface.hpp"
8 #include "src/simdag/simdag_private.h"
9 #include "simgrid/simdag.h"
10 #include <simgrid/s4u/host.hpp>
11 #include "xbt/dict.h"
12 #include "xbt/lib.h"
13 #include "xbt/sysdep.h"
14 #include "surf/surf.h"
15
16 XBT_LOG_NEW_DEFAULT_SUBCATEGORY(sd_workstation, sd,
17                                 "Logging specific to SimDag (workstation)");
18
19 /* Creates a workstation and registers it in SD.
20  */
21 SD_workstation_t __SD_workstation_create(const char *name)
22 {
23   sg_host_t sg_host = sg_host_by_name(name);
24   return sg_host;
25 }
26
27 /* Creates a storage and registers it in SD.
28  */
29 SD_storage_t __SD_storage_create(void *surf_storage, void *data)
30 {
31
32   SD_storage_priv_t storage;
33   const char *name;
34
35   storage = xbt_new(s_SD_storage_priv_t, 1);
36   storage->data = data;     /* user data */
37   name = surf_resource_name((surf_cpp_resource_t)surf_storage);
38   storage->host = (const char*)surf_storage_get_host( (surf_resource_t )surf_storage_resource_by_name(name));
39   xbt_lib_set(storage_lib,name, SD_STORAGE_LEVEL, storage);
40   return xbt_lib_get_elm_or_null(storage_lib, name);
41 }
42
43 /* Destroys a storage.
44  */
45 void __SD_storage_destroy(void *storage)
46 {
47   SD_storage_priv_t s;
48
49   s = (SD_storage_priv_t) storage;
50   xbt_free(s);
51 }
52
53 /**
54  * \brief Returns a workstation given its name
55  *
56  * If there is no such workstation, the function returns \c NULL.
57  *
58  * \param name workstation name
59  * \return the workstation, or \c NULL if there is no such workstation
60  */
61 SD_workstation_t SD_workstation_get_by_name(const char *name)
62 {
63   return sg_host_by_name(name);
64 }
65
66 /**
67  * \brief Returns the workstation list
68  *
69  * Use SD_workstation_get_number() to know the array size.
70  * 
71  * \return an array of \ref SD_workstation_t containing all workstations
72  * \remark The workstation order in the returned array is generally different from the workstation creation/declaration order in the XML platform (we use a hash table internally).
73  * \see SD_workstation_get_number()
74  */
75 const SD_workstation_t *SD_workstation_get_list(void) {
76   xbt_assert(SD_workstation_get_count() > 0, "There is no workstation!");
77
78   if (sd_global->workstation_list == NULL)     /* this is the first time the function is called */
79     sd_global->workstation_list = (SD_workstation_t*)xbt_dynar_to_array(sg_hosts_as_dynar());
80
81   return sd_global->workstation_list;
82 }
83
84 /**
85  * \brief Returns the number of workstations
86  *
87  * \return the number of existing workstations
88  * \see SD_workstation_get_list()
89  */
90 int SD_workstation_get_count(void)
91 {
92   return sg_host_count();
93 }
94
95 /**
96  * \brief Returns the user data of a workstation
97  *
98  * \param workstation a workstation
99  * \return the user data associated with this workstation (can be \c NULL)
100  * \see SD_workstation_set_data()
101  */
102 void *SD_workstation_get_data(SD_workstation_t workstation)
103 {
104   return sg_host_user(workstation);
105 }
106
107 /**
108  * \brief Sets the user data of a workstation
109  *
110  * The new data can be \c NULL. The old data should have been freed first
111  * if it was not \c NULL.
112  *
113  * \param workstation a workstation
114  * \param data the new data you want to associate with this workstation
115  * \see SD_workstation_get_data()
116  */
117 void SD_workstation_set_data(SD_workstation_t workstation, void *data)
118 {
119         sg_host_user_set(workstation, data);
120 }
121
122 /**
123  * \brief Returns the name of a workstation
124  *
125  * \param workstation a workstation
126  * \return the name of this workstation (cannot be \c NULL)
127  */
128 const char *SD_workstation_get_name(SD_workstation_t workstation)
129 {
130   return sg_host_get_name(workstation);
131 }
132
133 /**
134  * \brief Returns the value of a given workstation property
135  *
136  * \param ws a workstation
137  * \param name a property name
138  * \return value of a property (or NULL if property not set)
139  */
140 const char *SD_workstation_get_property_value(SD_workstation_t ws,
141                                               const char *name)
142 {
143   return (const char*) xbt_dict_get_or_null(SD_workstation_get_properties(ws), name);
144 }
145
146
147 /**
148  * \brief Returns a #xbt_dict_t consisting of the list of properties assigned to this workstation
149  *
150  * \param workstation a workstation
151  * \return the dictionary containing the properties associated with the workstation
152  */
153 xbt_dict_t SD_workstation_get_properties(SD_workstation_t workstation)
154 {
155   return sg_host_get_properties(workstation);
156 }
157
158
159 /** @brief Displays debugging informations about a workstation */
160 void SD_workstation_dump(SD_workstation_t ws)
161 {
162   xbt_dict_t props;
163   xbt_dict_cursor_t cursor=NULL;
164   char *key,*data;
165
166   XBT_INFO("Displaying workstation %s", SD_workstation_get_name(ws));
167   XBT_INFO("  - speed: %.0f", SD_workstation_get_speed(ws));
168   XBT_INFO("  - available speed: %.2f", SD_workstation_get_available_speed(ws));
169   props = SD_workstation_get_properties(ws);
170   
171   if (!xbt_dict_is_empty(props)){
172     XBT_INFO("  - properties:");
173
174     xbt_dict_foreach(props,cursor,key,data) {
175       XBT_INFO("    %s->%s",key,data);
176     }
177   }
178 }
179
180 /**
181  * \brief Returns the route between two workstations
182  *
183  * Use SD_route_get_size() to know the array size.
184  *
185  * \param src a workstation
186  * \param dst another workstation
187  * \return a new array of \ref SD_link_t representing the route between these two workstations
188  * \see SD_route_get_size(), SD_link_t
189  */
190 const SD_link_t *SD_route_get_list(SD_workstation_t src,
191                                    SD_workstation_t dst)
192 {
193   xbt_dynar_t surf_route;
194   void *surf_link;
195   unsigned int cpt;
196
197   if (sd_global->recyclable_route == NULL) {
198     /* first run */
199     sd_global->recyclable_route = xbt_new(SD_link_t, sg_link_count());
200   }
201
202   surf_route = surf_host_model_get_route((surf_host_model_t)surf_host_model, src, dst);
203
204   xbt_dynar_foreach(surf_route, cpt, surf_link) {
205     sd_global->recyclable_route[cpt] = (SD_link_t)surf_link;
206   }
207   return sd_global->recyclable_route;
208 }
209
210 /**
211  * \brief Returns the number of links on the route between two workstations
212  *
213  * \param src a workstation
214  * \param dst another workstation
215  * \return the number of links on the route between these two workstations
216  * \see SD_route_get_list()
217  */
218 int SD_route_get_size(SD_workstation_t src, SD_workstation_t dst)
219 {
220   return xbt_dynar_length(surf_host_model_get_route(
221                     (surf_host_model_t)surf_host_model, src, dst));
222 }
223
224 /**
225  * \brief Returns the total speed of a workstation
226  *
227  * \param workstation a workstation
228  * \return the total speed of this workstation
229  * \see SD_workstation_get_available_speed()
230  */
231 double SD_workstation_get_speed(SD_workstation_t workstation)
232 {
233   return workstation->speed();
234 }
235 /**
236  * \brief Returns the amount of cores of a workstation
237  *
238  * \param workstation a workstation
239  * \return the amount of cores of this workstation
240  */
241 int SD_workstation_get_cores(SD_workstation_t workstation) {
242   return workstation->core_count();
243 }
244
245 /**
246  * \brief Returns the proportion of available speed in a workstation
247  *
248  * \param workstation a workstation
249  * \return the proportion of speed currently available in this workstation (normally a number between 0 and 1)
250  * \see SD_workstation_get_speed()
251  */
252 double SD_workstation_get_available_speed(SD_workstation_t workstation)
253 {
254   return surf_host_get_available_speed(workstation);
255 }
256
257 /**
258  * \brief Returns an approximative estimated time for the given computation amount on a workstation
259  *
260  * \param workstation a workstation
261  * \param flops_amount the computation amount you want to evaluate (in flops)
262  * \return an approximative estimated computation time for the given computation amount on this workstation (in seconds)
263  */
264 double SD_workstation_get_computation_time(SD_workstation_t workstation,
265                                            double flops_amount)
266 {
267   xbt_assert(flops_amount >= 0,
268               "flops_amount must be greater than or equal to zero");
269   return flops_amount / SD_workstation_get_speed(workstation);
270 }
271
272 /**
273  * \brief Returns the latency of the route between two workstations.
274  *
275  * \param src the first workstation
276  * \param dst the second workstation
277  * \return the latency of the route between the two workstations (in seconds)
278  * \see SD_route_get_bandwidth()
279  */
280 double SD_route_get_latency(SD_workstation_t src, SD_workstation_t dst)
281 {
282   xbt_dynar_t route = NULL;
283   double latency = 0;
284
285   routing_platf->getRouteAndLatency(src->pimpl_netcard, dst->pimpl_netcard,
286                                     &route, &latency);
287
288   return latency;
289 }
290
291 /**
292  * \brief Returns the bandwidth of the route between two workstations,
293  * i.e. the minimum link bandwidth of all between the workstations.
294  *
295  * \param src the first workstation
296  * \param dst the second workstation
297  * \return the bandwidth of the route between the two workstations
298  * (in bytes/second)
299  * \see SD_route_get_latency()
300  */
301 double SD_route_get_bandwidth(SD_workstation_t src, SD_workstation_t dst)
302 {
303
304   const SD_link_t *links;
305   int nb_links;
306   double bandwidth;
307   double min_bandwidth;
308   int i;
309
310   links = SD_route_get_list(src, dst);
311   nb_links = SD_route_get_size(src, dst);
312   min_bandwidth = -1.0;
313
314   for (i = 0; i < nb_links; i++) {
315     bandwidth = sg_link_bandwidth(links[i]);
316     if (bandwidth < min_bandwidth || min_bandwidth == -1.0)
317       min_bandwidth = bandwidth;
318   }
319
320   return min_bandwidth;
321 }
322
323 /**
324  * \brief Returns an approximative estimated time for the given
325  * communication amount between two workstations
326  *
327  * \param src the first workstation
328  * \param dst the second workstation
329  * \param bytes_amount the communication amount you want to evaluate (in bytes)
330  * \return an approximative estimated communication time for the given bytes amount
331  * between the workstations (in seconds)
332  */
333 double SD_route_get_communication_time(SD_workstation_t src,
334                                        SD_workstation_t dst,
335                                        double bytes_amount)
336 {
337
338
339   /* total time = latency + transmission time of the slowest link
340      transmission time of a link = communication amount / link bandwidth */
341
342   const SD_link_t *links;
343   xbt_dynar_t route = NULL;
344   int nb_links;
345   double bandwidth, min_bandwidth;
346   double latency = 0;
347   int i;
348
349   xbt_assert(bytes_amount >= 0, "bytes_amount must be greater than or equal to zero");
350
351
352   if (bytes_amount == 0.0)
353     return 0.0;
354
355   routing_platf->getRouteAndLatency(src->pimpl_netcard, dst->pimpl_netcard,
356                                     &route, &latency);
357
358   links = SD_route_get_list(src, dst);
359   nb_links = SD_route_get_size(src, dst);
360   min_bandwidth = -1.0;
361
362   for (i = 0; i < nb_links; i++) {
363     bandwidth = sg_link_bandwidth(links[i]);
364     if (bandwidth < min_bandwidth || min_bandwidth == -1.0)
365       min_bandwidth = bandwidth;
366   }
367
368   return latency + (bytes_amount / min_bandwidth);
369 }
370
371 /**
372  * \brief Return the list of mounted storages on a workstation.
373  *
374  * \param workstation a workstation
375  * \return a dynar containing all mounted storages on the workstation
376  */
377 xbt_dict_t SD_workstation_get_mounted_storage_list(SD_workstation_t workstation){
378   return workstation->extension<simgrid::surf::Host>()->getMountedStorageList();
379 }
380
381 /**
382  * \brief Return the list of mounted storages on a workstation.
383  *
384  * \param workstation a workstation
385  * \return a dynar containing all mounted storages on the workstation
386  */
387 xbt_dynar_t SD_workstation_get_attached_storage_list(SD_workstation_t workstation){
388   return surf_host_get_attached_storage_list(workstation);
389 }
390
391 /**
392  * \brief Returns the host name the storage is attached to
393  *
394  * This functions checks whether a storage is a valid pointer or not and return its name.
395  */
396 const char *SD_storage_get_host(msg_storage_t storage) {
397   xbt_assert((storage != NULL), "Invalid parameters");
398   SD_storage_priv_t priv = SD_storage_priv(storage);
399   return priv->host;
400 }