Logo AND Algorithmique Numérique Distribuée

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