Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
[surf] Triggers the destructed callbacks on the full object
[simgrid.git] / src / surf / network_smpi.cpp
1 /* Copyright (c) 2013-2015. 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 <cstddef>
8
9 #include <algorithm>
10
11 #include <xbt/log.h>
12
13 #include "network_smpi.hpp"
14 #include "simgrid/sg_config.h"
15
16 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network);
17
18 xbt_dynar_t smpi_bw_factor = NULL;
19 xbt_dynar_t smpi_lat_factor = NULL;
20
21 typedef struct s_smpi_factor *smpi_factor_t;
22 typedef struct s_smpi_factor {
23   long factor;
24   double value;
25 } s_smpi_factor_t;
26
27 xbt_dict_t gap_lookup = NULL;
28
29 static int factor_cmp(const void *pa, const void *pb)
30 {
31  return (((s_smpi_factor_t*)pa)->factor > ((s_smpi_factor_t*)pb)->factor) ? 1 :
32          (((s_smpi_factor_t*)pa)->factor < ((s_smpi_factor_t*)pb)->factor) ? -1 : 0;
33 }
34
35
36 static xbt_dynar_t parse_factor(const char *smpi_coef_string)
37 {
38   char *value = NULL;
39   unsigned int iter = 0;
40   s_smpi_factor_t fact;
41   xbt_dynar_t smpi_factor, radical_elements, radical_elements2 = NULL;
42
43   smpi_factor = xbt_dynar_new(sizeof(s_smpi_factor_t), NULL);
44   radical_elements = xbt_str_split(smpi_coef_string, ";");
45   xbt_dynar_foreach(radical_elements, iter, value) {
46
47     radical_elements2 = xbt_str_split(value, ":");
48     if (xbt_dynar_length(radical_elements2) != 2)
49       surf_parse_error("Malformed radical for smpi factor!");
50     fact.factor = atol(xbt_dynar_get_as(radical_elements2, 0, char *));
51     fact.value = atof(xbt_dynar_get_as(radical_elements2, 1, char *));
52     xbt_dynar_push_as(smpi_factor, s_smpi_factor_t, fact);
53     XBT_DEBUG("smpi_factor:\t%ld : %f", fact.factor, fact.value);
54     xbt_dynar_free(&radical_elements2);
55   }
56   xbt_dynar_free(&radical_elements);
57   iter=0;
58   xbt_dynar_sort(smpi_factor, &factor_cmp);
59   xbt_dynar_foreach(smpi_factor, iter, fact) {
60     XBT_DEBUG("ordered smpi_factor:\t%ld : %f", fact.factor, fact.value);
61
62   }
63   return smpi_factor;
64 }
65
66 /*********
67  * Model *
68  *********/
69
70 /************************************************************************/
71 /* New model based on LV08 and experimental results of MPI ping-pongs   */
72 /************************************************************************/
73 /* @Inproceedings{smpi_ipdps, */
74 /*  author={Pierre-Nicolas Clauss and Mark Stillwell and Stéphane Genaud and Frédéric Suter and Henri Casanova and Martin Quinson}, */
75 /*  title={Single Node On-Line Simulation of {MPI} Applications with SMPI}, */
76 /*  booktitle={25th IEEE International Parallel and Distributed Processing Symposium (IPDPS'11)}, */
77 /*  address={Anchorage (Alaska) USA}, */
78 /*  month=may, */
79 /*  year={2011} */
80 /*  } */
81 void surf_network_model_init_SMPI(void)
82 {
83
84   if (surf_network_model)
85     return;
86   surf_network_model = new simgrid::surf::NetworkSmpiModel();
87   net_define_callbacks();
88   xbt_dynar_push(all_existing_models, &surf_network_model);
89
90   xbt_cfg_setdefault_double(_sg_cfg_set, "network/sender_gap", 10e-6);
91   xbt_cfg_setdefault_double(_sg_cfg_set, "network/weight_S", 8775);
92 }
93
94 namespace simgrid {
95 namespace surf {
96
97 NetworkSmpiModel::NetworkSmpiModel()
98  : NetworkCm02Model() {
99         m_haveGap=true;
100 }
101
102 NetworkSmpiModel::~NetworkSmpiModel(){
103   if (gap_lookup) {
104     xbt_dict_free(&gap_lookup);
105   }
106   if (smpi_bw_factor) {
107     xbt_dynar_free(&smpi_bw_factor);
108     smpi_bw_factor = NULL;
109   }
110   if (smpi_lat_factor) {
111     xbt_dynar_free(&smpi_lat_factor);
112     smpi_lat_factor = NULL;
113   }
114 }
115
116 void NetworkSmpiModel::gapAppend(double size, Link* link, NetworkAction *act)
117 {
118   const char *src = link->getName();
119   xbt_fifo_t fifo;
120   NetworkCm02Action *action= static_cast<NetworkCm02Action*>(act);
121
122   if (sg_sender_gap > 0.0) {
123     if (!gap_lookup) {
124       gap_lookup = xbt_dict_new_homogeneous(NULL);
125     }
126     fifo = (xbt_fifo_t) xbt_dict_get_or_null(gap_lookup, src);
127     action->m_senderGap = 0.0;
128     if (fifo && xbt_fifo_size(fifo) > 0) {
129       /* Compute gap from last send */
130       /*last_action =
131           (surf_action_network_CM02_t)
132           xbt_fifo_get_item_content(xbt_fifo_get_last_item(fifo));*/
133      // bw = net_get_link_bandwidth(link);
134       action->m_senderGap = sg_sender_gap;
135         /*  max(sg_sender_gap,last_action->sender.size / bw);*/
136       action->m_latency += action->m_senderGap;
137     }
138     /* Append action as last send */
139     /*action->sender.link_name = link->lmm_resource.generic_resource.name;
140     fifo =
141         (xbt_fifo_t) xbt_dict_get_or_null(gap_lookup,
142                                           action->sender.link_name);
143     if (!fifo) {
144       fifo = xbt_fifo_new();
145       xbt_dict_set(gap_lookup, action->sender.link_name, fifo, NULL);
146     }
147     action->sender.fifo_item = xbt_fifo_push(fifo, action);*/
148     action->m_senderSize = size;
149   }
150 }
151
152 void NetworkSmpiModel::gapRemove(Action *lmm_action)
153 {
154   xbt_fifo_t fifo;
155   size_t size;
156   NetworkCm02Action *action = static_cast<NetworkCm02Action*>(lmm_action);
157
158   if (sg_sender_gap > 0.0 && action->p_senderLinkName
159       && action->p_senderFifoItem) {
160     fifo =
161         (xbt_fifo_t) xbt_dict_get_or_null(gap_lookup,
162                                           action->p_senderLinkName);
163     xbt_fifo_remove_item(fifo, action->p_senderFifoItem);
164     size = xbt_fifo_size(fifo);
165     if (size == 0) {
166       xbt_fifo_free(fifo);
167       xbt_dict_remove(gap_lookup, action->p_senderLinkName);
168       size = xbt_dict_length(gap_lookup);
169       if (size == 0) {
170         xbt_dict_free(&gap_lookup);
171       }
172     }
173   }
174 }
175
176 double NetworkSmpiModel::bandwidthFactor(double size)
177 {
178   if (!smpi_bw_factor)
179     smpi_bw_factor =
180         parse_factor(sg_cfg_get_string("smpi/bw_factor"));
181
182   unsigned int iter = 0;
183   s_smpi_factor_t fact;
184   double current=1.0;
185   xbt_dynar_foreach(smpi_bw_factor, iter, fact) {
186     if (size <= fact.factor) {
187       XBT_DEBUG("%f <= %ld return %f", size, fact.factor, current);
188       return current;
189     }else
190       current=fact.value;
191   }
192   XBT_DEBUG("%f > %ld return %f", size, fact.factor, current);
193
194   return current;
195 }
196
197 double NetworkSmpiModel::latencyFactor(double size)
198 {
199   if (!smpi_lat_factor)
200     smpi_lat_factor =
201         parse_factor(sg_cfg_get_string("smpi/lat_factor"));
202
203   unsigned int iter = 0;
204   s_smpi_factor_t fact;
205   double current=1.0;
206   xbt_dynar_foreach(smpi_lat_factor, iter, fact) {
207     if (size <= fact.factor) {
208       XBT_DEBUG("%f <= %ld return %f", size, fact.factor, current);
209       return current;
210     }else
211       current=fact.value;
212   }
213   XBT_DEBUG("%f > %ld return %f", size, fact.factor, current);
214
215   return current;
216 }
217
218 double NetworkSmpiModel::bandwidthConstraint(double rate, double bound, double size)
219 {
220   return rate < 0 ? bound : std::min(bound, rate * bandwidthFactor(size));
221 }
222
223 /************
224  * Resource *
225  ************/
226
227
228
229 /**********
230  * Action *
231  **********/
232
233 }
234 }