From 03a16acd38dfaa266986de5d73f4a90c0ddbfeb1 Mon Sep 17 00:00:00 2001 From: Arnaud Giersch Date: Wed, 31 Aug 2011 22:04:55 +0200 Subject: [PATCH] Enforce integer initial load when integer transfers are activated. --- BUGS | 10 ---------- deployment.cpp | 31 +++++++++++++++++++++++++++++-- main.cpp | 6 ++++++ process.cpp | 7 +++++++ 4 files changed, 42 insertions(+), 12 deletions(-) diff --git a/BUGS b/BUGS index 3a1a2a4..040cfc3 100644 --- a/BUGS +++ b/BUGS @@ -1,14 +1,4 @@ ======================================================================== -En mode entier (-Z), aucune vérification n'est faite sur la charge -totale, ni sur la répartition initiale! - -Il faut vérifier, et arrondir et émettre un warning dans le cas contraire : -- que la charge totale est entière, dans main.cpp ; -- au début de chaque process que la charge initiale est entière. - -Il faut également s'assurer que la répartition aléatoire produit une -distribution entière. - ======================================================================== ##### RESOLVED BUGS COME AFTER THIS #################################### ======================================================================== diff --git a/deployment.cpp b/deployment.cpp index 8f52806..2befb00 100644 --- a/deployment.cpp +++ b/deployment.cpp @@ -63,8 +63,35 @@ void deployment_generator::distribute_load() std::accumulate(loads.begin(), loads.end(), 0.0); std::transform(loads.begin(), loads.end(), loads.begin(), std::bind(std::multiplies(), _1, factor)); - for (unsigned i = 0 ; i < hosts.size() ; ++i) - set_load(i, loads[i]); + if (opt::integer_transfer) { + // round the loads + std::vector iloads(hosts.size()); + std::transform(loads.begin(), loads.end(), iloads.begin(), round); + // compute the differences between each load and its rounded value + std::vector diffs(hosts.size()); + std::transform(loads.begin(), loads.end(), iloads.begin(), + diffs.begin(), std::minus()); + // compute the absolute values of the diffs + std::vector adiffs(hosts.size()); + std::transform(diffs.begin(), diffs.end(), adiffs.begin(), fabs); + // find i, index of the element farthest from its rounded value + unsigned i; + i = std::max_element(adiffs.begin(), adiffs.end()) - adiffs.begin(); + // remove element i from diffs, and compute the residual part... + diffs[i] = diffs.back(); + diffs.pop_back(); + double residue = std::accumulate(diffs.begin(), diffs.end(), 0.0); + // ... and compute element i (rounded to avoid numerical errors) + iloads[i] = fabs(round(loads[i] + residue)); + // final sanity check + xbt_assert(opt::auto_depl::load == + std::accumulate(iloads.begin(), iloads.end(), 0.0)); + for (unsigned i = 0 ; i < hosts.size() ; ++i) + set_load(i, iloads[i]); + } else { + for (unsigned i = 0 ; i < hosts.size() ; ++i) + set_load(i, loads[i]); + } } void deployment_generator::deploy() diff --git a/main.cpp b/main.cpp index 61dfd42..80a43d9 100644 --- a/main.cpp +++ b/main.cpp @@ -251,6 +251,12 @@ int main(int argc, char* argv[]) } else if (opt::auto_depl::load < 0.0) opt::auto_depl::load = -opt::auto_depl::load * opt::auto_depl::nhosts; + double iload = trunc(opt::auto_depl::load); + if (opt::integer_transfer && opt::auto_depl::load != iload) { + XBT_WARN("Total load %g is not an integer. Truncate it.", + opt::auto_depl::load); + opt::auto_depl::load = iload; + } MY_launch_application(); // it is already opt::* aware... } else { MSG_launch_application(opt::deployment_file.c_str()); diff --git a/process.cpp b/process.cpp index 193c87b..e6ae2ab 100644 --- a/process.cpp +++ b/process.cpp @@ -37,6 +37,13 @@ process::process(int argc, char* argv[]) if (argc < 2 || !(std::istringstream(argv[1]) >> real_load)) throw std::invalid_argument("bad or missing initial load parameter"); + double iload = trunc(real_load); + if (opt::integer_transfer && real_load != iload) { + XBT_WARN("Initial load %g is not an integer. Truncate it.", + real_load); + real_load = iload; + } + neigh.assign(argv + 2, argv + argc); pneigh.reserve(neigh.size()); -- 2.39.5