From c84be70247ff0b67d2a7bfd4ef66a93af381d630 Mon Sep 17 00:00:00 2001 From: Frederic Suter Date: Wed, 19 Feb 2020 15:36:17 +0100 Subject: [PATCH] convert cloud capping --- MANIFEST.in | 5 +- examples/c/CMakeLists.txt | 4 +- examples/c/cloud-capping/cloud-capping.c | 307 +++++++++++++++++ .../c}/cloud-capping/cloud-capping.tesh | 63 ++-- teshsuite/msg/CMakeLists.txt | 4 +- teshsuite/msg/cloud-capping/cloud-capping.c | 314 ------------------ 6 files changed, 346 insertions(+), 351 deletions(-) create mode 100644 examples/c/cloud-capping/cloud-capping.c rename {teshsuite/msg => examples/c}/cloud-capping/cloud-capping.tesh (87%) delete mode 100644 teshsuite/msg/cloud-capping/cloud-capping.c diff --git a/MANIFEST.in b/MANIFEST.in index 32a4b64c66..41cc56c044 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -45,6 +45,8 @@ include examples/c/async-waitall/async-waitall_d.xml include examples/c/async-waitany/async-waitany.c include examples/c/async-waitany/async-waitany.tesh include examples/c/async-waitany/async-waitany_d.xml +include examples/c/cloud-capping/cloud-capping.c +include examples/c/cloud-capping/cloud-capping.tesh include examples/c/cloud-simple/cloud-simple.c include examples/c/cloud-simple/cloud-simple.tesh include examples/c/energy-exec/energy-exec.c @@ -645,8 +647,6 @@ include teshsuite/msg/async-wait/async-wait2_d.xml include teshsuite/msg/async-wait/async-wait3_d.xml include teshsuite/msg/async-wait/async-wait4_d.xml include teshsuite/msg/async-wait/async-wait_d.xml -include teshsuite/msg/cloud-capping/cloud-capping.c -include teshsuite/msg/cloud-capping/cloud-capping.tesh include teshsuite/msg/cloud-migration/cloud-migration.c include teshsuite/msg/cloud-migration/cloud-migration.tesh include teshsuite/msg/cloud-two-tasks/cloud-two-tasks.c @@ -1979,6 +1979,7 @@ include include/simgrid/cond.h include include/simgrid/config.h.in include include/simgrid/disk.h include include/simgrid/engine.h +include include/simgrid/exec.h include include/simgrid/forward.h include include/simgrid/host.h include include/simgrid/instr.h diff --git a/examples/c/CMakeLists.txt b/examples/c/CMakeLists.txt index 97c3ad359a..0a473a0aef 100644 --- a/examples/c/CMakeLists.txt +++ b/examples/c/CMakeLists.txt @@ -2,7 +2,7 @@ foreach(x actor-create actor-daemon actor-exiting actor-join actor-kill actor-migrate actor-suspend actor-yield app-pingpong app-token-ring async-waitall async-waitany - cloud-simple + cloud-capping cloud-simple energy-exec io-disk-raw plugin-hostload) @@ -29,7 +29,7 @@ foreach(x actor-create actor-daemon actor-exiting actor-join actor-kill actor-migrate actor-suspend actor-yield app-pingpong app-token-ring async-waitall async-waitany - cloud-simple + cloud-capping cloud-simple energy-exec io-disk-raw plugin-hostload) diff --git a/examples/c/cloud-capping/cloud-capping.c b/examples/c/cloud-capping/cloud-capping.c new file mode 100644 index 0000000000..4073359f63 --- /dev/null +++ b/examples/c/cloud-capping/cloud-capping.c @@ -0,0 +1,307 @@ +/* Copyright (c) 2007-2020. The SimGrid Team. All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "simgrid/actor.h" +#include "simgrid/engine.h" +#include "simgrid/exec.h" +#include "simgrid/host.h" +#include "simgrid/plugins/live_migration.h" +#include "simgrid/vm.h" + +#include "xbt/asserts.h" +#include "xbt/log.h" +#include "xbt/str.h" + +XBT_LOG_NEW_DEFAULT_CATEGORY(cloud_capping, "Messages specific for this example"); + +static void worker_main(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[]) +{ + xbt_assert(argc == 4); + double computation_amount = xbt_str_parse_double(argv[1], "Invalid computation amount: %s"); + int use_bound = xbt_str_parse_int(argv[2], "Second parameter (use_bound) should be 0 or 1 but is: %s"); + double bound = xbt_str_parse_double(argv[3], "Invalid bound: %s"); + + double clock_sta = simgrid_get_clock(); + + sg_exec_t exec = sg_actor_exec_init(computation_amount); + if (use_bound) { + if (bound < 1e-12) /* close enough to 0 without any floating precision surprise */ + XBT_INFO("bound == 0 means no capping (i.e., unlimited)."); + sg_exec_set_bound(exec, bound); + } + sg_exec_wait(exec); + + double clock_end = simgrid_get_clock(); + double duration = clock_end - clock_sta; + double flops_per_sec = computation_amount / duration; + + if (use_bound) + XBT_INFO("bound to %f => duration %f (%f flops/s)", bound, duration, flops_per_sec); + else + XBT_INFO("not bound => duration %f (%f flops/s)", duration, flops_per_sec); +} + +static void launch_worker(sg_host_t host, const char* pr_name, double computation_amount, int use_bound, double bound) +{ + char* argv1 = bprintf("%f", computation_amount); + char* argv2 = bprintf("%d", use_bound); + char* argv3 = bprintf("%f", bound); + const char* argv[] = {pr_name, argv1, argv2, argv3, NULL}; + + sg_actor_t actor = sg_actor_init(pr_name, host); + sg_actor_start(actor, worker_main, 4, argv); + + free(argv1); + free(argv2); + free(argv3); +} + +static void worker_busy_loop(int argc, char* argv[]) +{ + char* name = argv[1]; + double speed = xbt_str_parse_double(argv[2], "Invalid speed value"); + double exec_remain_prev = 1e11; + + sg_exec_t exec = sg_actor_exec_async(exec_remain_prev); + for (int i = 0; i < 10; i++) { + if (speed > 0) { + double new_bound = (speed / 10) * i; + XBT_INFO("set bound of VM1 to %f", new_bound); + sg_vm_set_bound(((sg_vm_t)sg_actor_get_host(sg_actor_self())), new_bound); + } + sg_actor_sleep_for(100); + double exec_remain_now = sg_exec_get_remaining(exec); + double flops_per_sec = exec_remain_prev - exec_remain_now; + XBT_INFO("%s@%s: %.0f flops/s", name, sg_host_get_name(sg_actor_get_host(sg_actor_self())), flops_per_sec / 100); + exec_remain_prev = exec_remain_now; + sg_actor_sleep_for(1); + } + + sg_exec_wait(exec); +} + +static void test_dynamic_change() +{ + sg_host_t pm0 = sg_host_by_name("Fafard"); + + sg_vm_t vm0 = sg_vm_create_core(pm0, "VM0"); + sg_vm_t vm1 = sg_vm_create_core(pm0, "VM1"); + sg_vm_start(vm0); + sg_vm_start(vm1); + + int w0_argc = 3; + const char* w0_argv[] = {"worker0", "Task0", "-1.0", NULL}; + sg_actor_t w0 = sg_actor_init("worker0", (sg_host_t)vm0); + sg_actor_start(w0, worker_busy_loop, w0_argc, w0_argv); + + int w1_argc = 3; + char* speed = bprintf("%f", sg_host_speed(pm0)); + const char* w1_argv[] = {"worker1", "Task1", speed, NULL}; + + sg_actor_t w1 = sg_actor_init("worker1", (sg_host_t)vm1); + sg_actor_start(w1, worker_busy_loop, w1_argc, w1_argv); + + sg_actor_sleep_for(3000); // let the tasks end + + sg_vm_destroy(vm0); + sg_vm_destroy(vm1); + free(speed); +} + +static void test_one_task(sg_host_t hostA) +{ + const double cpu_speed = sg_host_speed(hostA); + const double computation_amount = cpu_speed * 10; + const char* hostA_name = sg_host_get_name(hostA); + + XBT_INFO("### Test: with/without MSG_task_set_bound"); + + XBT_INFO("### Test: no bound for Task1@%s", hostA_name); + launch_worker(hostA, "worker0", computation_amount, 0, 0); + + sg_actor_sleep_for(1000); + + XBT_INFO("### Test: 50%% for Task1@%s", hostA_name); + launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed / 2); + + sg_actor_sleep_for(1000); + + XBT_INFO("### Test: 33%% for Task1@%s", hostA_name); + launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed / 3); + + sg_actor_sleep_for(1000); + + XBT_INFO("### Test: zero for Task1@%s (i.e., unlimited)", hostA_name); + launch_worker(hostA, "worker0", computation_amount, 1, 0); + + sg_actor_sleep_for(1000); + + XBT_INFO("### Test: 200%% for Task1@%s (i.e., meaningless)", hostA_name); + launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed * 2); + + sg_actor_sleep_for(1000); +} + +static void test_two_tasks(sg_host_t hostA, sg_host_t hostB) +{ + const double cpu_speed = sg_host_speed(hostA); + xbt_assert(cpu_speed == sg_host_speed(hostB)); + const double computation_amount = cpu_speed * 10; + const char* hostA_name = sg_host_get_name(hostA); + const char* hostB_name = sg_host_get_name(hostB); + + XBT_INFO("### Test: no bound for Task1@%s, no bound for Task2@%s", hostA_name, hostB_name); + launch_worker(hostA, "worker0", computation_amount, 0, 0); + launch_worker(hostB, "worker1", computation_amount, 0, 0); + + sg_actor_sleep_for(1000); + + XBT_INFO("### Test: 0 for Task1@%s, 0 for Task2@%s (i.e., unlimited)", hostA_name, hostB_name); + launch_worker(hostA, "worker0", computation_amount, 1, 0); + launch_worker(hostB, "worker1", computation_amount, 1, 0); + + sg_actor_sleep_for(1000); + + XBT_INFO("### Test: 50%% for Task1@%s, 50%% for Task2@%s", hostA_name, hostB_name); + launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed / 2); + launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 2); + + sg_actor_sleep_for(1000); + + XBT_INFO("### Test: 25%% for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name); + launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed / 4); + launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 4); + + sg_actor_sleep_for(1000); + + XBT_INFO("### Test: 75%% for Task1@%s, 100%% for Task2@%s", hostA_name, hostB_name); + launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed * 0.75); + launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed); + + sg_actor_sleep_for(1000); + + XBT_INFO("### Test: no bound for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name); + launch_worker(hostA, "worker0", computation_amount, 0, 0); + launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 4); + + sg_actor_sleep_for(1000); + + XBT_INFO("### Test: 75%% for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name); + launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed * 0.75); + launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 4); + + sg_actor_sleep_for(1000); +} + +static void master_main(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[]) +{ + sg_host_t pm0 = sg_host_by_name("Fafard"); + sg_host_t pm1 = sg_host_by_name("Fafard"); + + XBT_INFO("# 1. Put a single task on a PM. "); + test_one_task(pm0); + XBT_INFO(" "); + + XBT_INFO("# 2. Put two tasks on a PM."); + test_two_tasks(pm0, pm0); + XBT_INFO(" "); + + sg_vm_t vm0 = sg_vm_create_core(pm0, "VM0"); + sg_vm_start(vm0); + + XBT_INFO("# 3. Put a single task on a VM. "); + test_one_task((sg_host_t)vm0); + XBT_INFO(" "); + + XBT_INFO("# 4. Put two tasks on a VM."); + test_two_tasks((sg_host_t)vm0, (sg_host_t)vm0); + XBT_INFO(" "); + + sg_vm_destroy(vm0); + + vm0 = sg_vm_create_core(pm0, "VM0"); + sg_vm_start(vm0); + + XBT_INFO("# 6. Put a task on a PM and a task on a VM."); + test_two_tasks(pm0, (sg_host_t)vm0); + XBT_INFO(" "); + + sg_vm_destroy(vm0); + + vm0 = sg_vm_create_core(pm0, "VM0"); + double cpu_speed = sg_host_speed(pm0); + sg_vm_set_bound(vm0, cpu_speed / 10); + sg_vm_start(vm0); + + XBT_INFO("# 7. Put a single task on the VM capped by 10%%."); + test_one_task((sg_host_t)vm0); + XBT_INFO(" "); + + XBT_INFO("# 8. Put two tasks on the VM capped by 10%%."); + test_two_tasks((sg_host_t)vm0, (sg_host_t)vm0); + XBT_INFO(" "); + + XBT_INFO("# 9. Put a task on a PM and a task on the VM capped by 10%%."); + test_two_tasks(pm0, (sg_host_t)vm0); + XBT_INFO(" "); + + sg_vm_destroy(vm0); + + vm0 = sg_vm_create_core(pm0, "VM0"); + + sg_vm_set_ramsize(vm0, 1e9); // 1GB + sg_vm_start(vm0); + + cpu_speed = sg_host_speed(pm0); + sg_vm_start(vm0); + + XBT_INFO("# 10. Test migration"); + const double computation_amount = cpu_speed * 10; + + XBT_INFO("# 10. (a) Put a task on a VM without any bound."); + launch_worker((sg_host_t)vm0, "worker0", computation_amount, 0, 0); + sg_actor_sleep_for(1000); + XBT_INFO(" "); + + XBT_INFO("# 10. (b) set 10%% bound to the VM, and then put a task on the VM."); + sg_vm_set_bound(vm0, cpu_speed / 10); + launch_worker((sg_host_t)vm0, "worker0", computation_amount, 0, 0); + sg_actor_sleep_for(1000); + XBT_INFO(" "); + + XBT_INFO("# 10. (c) migrate"); + sg_vm_migrate(vm0, pm1); + XBT_INFO(" "); + + XBT_INFO("# 10. (d) Put a task again on the VM."); + launch_worker((sg_host_t)vm0, "worker0", computation_amount, 0, 0); + sg_actor_sleep_for(1000); + XBT_INFO(" "); + + sg_vm_destroy(vm0); + + XBT_INFO("# 11. Change a bound dynamically."); + test_dynamic_change(); +} + +int main(int argc, char* argv[]) +{ + /* Get the arguments */ + simgrid_init(&argc, argv); + sg_vm_live_migration_plugin_init(); + + /* load the platform file */ + xbt_assert(argc == 2, "Usage: %s platform_file\n\tExample: %s ../platforms/small_platform.xml\n", argv[0], argv[0]); + + simgrid_load_platform(argv[1]); + + sg_actor_t actor = sg_actor_init("master_", sg_host_by_name("Fafard")); + sg_actor_start(actor, master_main, 0, NULL); + + simgrid_run(); + XBT_INFO("Bye (simulation time %g)", simgrid_get_clock()); + + return 0; +} diff --git a/teshsuite/msg/cloud-capping/cloud-capping.tesh b/examples/c/cloud-capping/cloud-capping.tesh similarity index 87% rename from teshsuite/msg/cloud-capping/cloud-capping.tesh rename to examples/c/cloud-capping/cloud-capping.tesh index b30353d115..bd2ffe48e6 100644 --- a/teshsuite/msg/cloud-capping/cloud-capping.tesh +++ b/examples/c/cloud-capping/cloud-capping.tesh @@ -1,4 +1,5 @@ -$ ${bindir:=.}/cloud-capping ${platfdir}/small_platform.xml --log=no_loc "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" +! output sort +$ ${bindir:=.}/cloud-capping-c ${platfdir}/small_platform.xml --log=no_loc "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" > [ 0.000000] (1:master_@Fafard) # 1. Put a single task on a PM. > [ 0.000000] (1:master_@Fafard) ### Test: with/without MSG_task_set_bound > [ 0.000000] (1:master_@Fafard) ### Test: no bound for Task1@Fafard @@ -179,34 +180,34 @@ $ ${bindir:=.}/cloud-capping ${platfdir}/small_platform.xml --log=no_loc "--log= > [52102.070722] (91:worker0@VM0) not bound => duration 100.000000 (7629600.000000 flops/s) > [53002.070722] (1:master_@Fafard) > [53002.070722] (1:master_@Fafard) # 11. Change a bound dynamically. -> [53002.070722] (1:master_@Fafard) set bound of VM1 to 0.000000 -> [53102.070722] (1:master_@Fafard) Task0@VM0: 38148000.000000 flops/s -> [53102.070722] (1:master_@Fafard) Task1@VM1: 38148000.000000 flops/s -> [53102.070722] (1:master_@Fafard) set bound of VM1 to 7629600.000000 -> [53202.070722] (1:master_@Fafard) Task0@VM0: 68666400.000000 flops/s -> [53202.070722] (1:master_@Fafard) Task1@VM1: 7629600.000000 flops/s -> [53202.070722] (1:master_@Fafard) set bound of VM1 to 15259200.000000 -> [53302.070722] (1:master_@Fafard) Task0@VM0: 61036800.000000 flops/s -> [53302.070722] (1:master_@Fafard) Task1@VM1: 15259200.000000 flops/s -> [53302.070722] (1:master_@Fafard) set bound of VM1 to 22888800.000000 -> [53402.070722] (1:master_@Fafard) Task0@VM0: 53407200.000000 flops/s -> [53402.070722] (1:master_@Fafard) Task1@VM1: 22888800.000000 flops/s -> [53402.070722] (1:master_@Fafard) set bound of VM1 to 30518400.000000 -> [53502.070722] (1:master_@Fafard) Task0@VM0: 45777600.000000 flops/s -> [53502.070722] (1:master_@Fafard) Task1@VM1: 30518400.000000 flops/s -> [53502.070722] (1:master_@Fafard) set bound of VM1 to 38148000.000000 -> [53602.070722] (1:master_@Fafard) Task0@VM0: 38148000.000000 flops/s -> [53602.070722] (1:master_@Fafard) Task1@VM1: 38148000.000000 flops/s -> [53602.070722] (1:master_@Fafard) set bound of VM1 to 45777600.000000 -> [53702.070722] (1:master_@Fafard) Task0@VM0: 38148000.000000 flops/s -> [53702.070722] (1:master_@Fafard) Task1@VM1: 38148000.000000 flops/s -> [53702.070722] (1:master_@Fafard) set bound of VM1 to 53407200.000000 -> [53802.070722] (1:master_@Fafard) Task0@VM0: 38148000.000000 flops/s -> [53802.070722] (1:master_@Fafard) Task1@VM1: 38148000.000000 flops/s -> [53802.070722] (1:master_@Fafard) set bound of VM1 to 61036800.000000 -> [53902.070722] (1:master_@Fafard) Task0@VM0: 38148000.000000 flops/s -> [53902.070722] (1:master_@Fafard) Task1@VM1: 38148000.000000 flops/s -> [53902.070722] (1:master_@Fafard) set bound of VM1 to 68666400.000000 -> [54002.070722] (1:master_@Fafard) Task0@VM0: 38148000.000000 flops/s -> [54002.070722] (1:master_@Fafard) Task1@VM1: 38148000.000000 flops/s +> [53002.070722] (93:worker1@VM1) set bound of VM1 to 0.000000 +> [53102.070722] (93:worker1@VM1) Task1@VM1: 38148000 flops/s +> [53102.070722] (92:worker0@VM0) Task0@VM0: 38148000 flops/s +> [53103.070722] (93:worker1@VM1) set bound of VM1 to 7629600.000000 +> [53203.070722] (93:worker1@VM1) Task1@VM1: 8011080 flops/s +> [53203.070722] (92:worker0@VM0) Task0@VM0: 69047880 flops/s +> [53204.070722] (93:worker1@VM1) set bound of VM1 to 15259200.000000 +> [53304.070722] (93:worker1@VM1) Task1@VM1: 15335496 flops/s +> [53304.070722] (92:worker0@VM0) Task0@VM0: 61723464 flops/s +> [53305.070722] (93:worker1@VM1) set bound of VM1 to 22888800.000000 +> [53405.070722] (93:worker1@VM1) Task1@VM1: 23041392 flops/s +> [53405.070722] (92:worker0@VM0) Task0@VM0: 54017568 flops/s +> [53406.070722] (93:worker1@VM1) set bound of VM1 to 30518400.000000 +> [53506.070722] (93:worker1@VM1) Task1@VM1: 30747288 flops/s +> [53506.070722] (92:worker0@VM0) Task0@VM0: 46311672 flops/s +> [53507.070722] (93:worker1@VM1) set bound of VM1 to 38148000.000000 +> [53607.070722] (93:worker1@VM1) Task1@VM1: 38453184 flops/s +> [53607.070722] (92:worker0@VM0) Task0@VM0: 38605776 flops/s +> [53608.070722] (93:worker1@VM1) set bound of VM1 to 45777600.000000 +> [53708.070722] (93:worker1@VM1) Task1@VM1: 38529480 flops/s +> [53708.070722] (92:worker0@VM0) Task0@VM0: 38529480 flops/s +> [53709.070722] (93:worker1@VM1) set bound of VM1 to 53407200.000000 +> [53809.070722] (93:worker1@VM1) Task1@VM1: 38529480 flops/s +> [53809.070722] (92:worker0@VM0) Task0@VM0: 38529480 flops/s +> [53810.070722] (93:worker1@VM1) set bound of VM1 to 61036800.000000 +> [53910.070722] (93:worker1@VM1) Task1@VM1: 38529480 flops/s +> [53910.070722] (92:worker0@VM0) Task0@VM0: 38529480 flops/s +> [53911.070722] (93:worker1@VM1) set bound of VM1 to 68666400.000000 +> [54011.070722] (93:worker1@VM1) Task1@VM1: 38529480 flops/s +> [54011.070722] (92:worker0@VM0) Task0@VM0: 38529480 flops/s > [56002.070722] (0:maestro@) Bye (simulation time 56002.1) diff --git a/teshsuite/msg/CMakeLists.txt b/teshsuite/msg/CMakeLists.txt index 4b4c944a45..9c3c9f0948 100644 --- a/teshsuite/msg/CMakeLists.txt +++ b/teshsuite/msg/CMakeLists.txt @@ -1,6 +1,6 @@ # C examples foreach(x async-wait - cloud-capping cloud-migration cloud-two-tasks + cloud-migration cloud-two-tasks get_sender host_on_off host_on_off_recv process-lifetime energy-ptask energy-pstate platform-properties @@ -87,7 +87,7 @@ if(enable_msg) foreach(x async-wait app-bittorrent app-chainsend - cloud-capping cloud-migration cloud-two-tasks + cloud-migration cloud-two-tasks energy-pstate host_on_off host_on_off_processes host_on_off_recv get_sender diff --git a/teshsuite/msg/cloud-capping/cloud-capping.c b/teshsuite/msg/cloud-capping/cloud-capping.c deleted file mode 100644 index 0e66bae4dd..0000000000 --- a/teshsuite/msg/cloud-capping/cloud-capping.c +++ /dev/null @@ -1,314 +0,0 @@ -/* Copyright (c) 2007-2020. The SimGrid Team. All rights reserved. */ - -/* This program is free software; you can redistribute it and/or modify it - * under the terms of the license (GNU LGPL) which comes with this package. */ - -#include "simgrid/msg.h" -#include "simgrid/plugins/live_migration.h" - -XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, "Messages specific for this msg example"); - -/** @addtogroup MSG_examples - * - * - cloud/bound.c: Demonstrates the use of @ref MSG_task_set_bound - */ - -static int worker_main(int argc, char* argv[]) -{ - xbt_assert(argc == 4); - double computation_amount = xbt_str_parse_double(argv[1], "Invalid computation amount: %s"); - int use_bound = xbt_str_parse_int(argv[2], "Second parameter (use_bound) should be 0 or 1 but is: %s"); - double bound = xbt_str_parse_double(argv[3], "Invalid bound: %s"); - - double clock_sta = MSG_get_clock(); - - msg_task_t task = MSG_task_create("Task", computation_amount, 0, NULL); - if (use_bound) - MSG_task_set_bound(task, bound); - MSG_task_execute(task); - MSG_task_destroy(task); - - double clock_end = MSG_get_clock(); - double duration = clock_end - clock_sta; - double flops_per_sec = computation_amount / duration; - - if (use_bound) - XBT_INFO("bound to %f => duration %f (%f flops/s)", bound, duration, flops_per_sec); - else - XBT_INFO("not bound => duration %f (%f flops/s)", duration, flops_per_sec); - - return 0; -} - -static void launch_worker(msg_host_t host, const char* pr_name, double computation_amount, int use_bound, double bound) -{ - char** argv = xbt_new(char*, 5); - argv[0] = xbt_strdup(pr_name); - argv[1] = bprintf("%f", computation_amount); - argv[2] = bprintf("%d", use_bound); - argv[3] = bprintf("%f", bound); - argv[4] = NULL; - - MSG_process_create_with_arguments(pr_name, worker_main, NULL, host, 4, argv); -} - -static int worker_busy_loop_main(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[]) -{ - msg_task_t* task = MSG_process_get_data(MSG_process_self()); - MSG_task_execute(*task); - MSG_task_destroy(*task); - - return 0; -} - -static void test_dynamic_change(void) -{ - const double DOUBLE_MAX = 1e11; - msg_host_t pm0 = MSG_host_by_name("Fafard"); - - msg_vm_t vm0 = MSG_vm_create_core(pm0, "VM0"); - msg_vm_t vm1 = MSG_vm_create_core(pm0, "VM1"); - MSG_vm_start(vm0); - MSG_vm_start(vm1); - - msg_task_t task0 = MSG_task_create("Task0", DOUBLE_MAX, 0, NULL); - msg_task_t task1 = MSG_task_create("Task1", DOUBLE_MAX, 0, NULL); - MSG_process_create("worker0", worker_busy_loop_main, &task0, (msg_host_t)vm0); - MSG_process_create("worker1", worker_busy_loop_main, &task1, (msg_host_t)vm1); - - double task0_remain_prev = MSG_task_get_flops_amount(task0); - double task1_remain_prev = MSG_task_get_flops_amount(task1); - - const double cpu_speed = MSG_host_get_speed(pm0); - for (int i = 0; i < 10; i++) { - double new_bound = (cpu_speed / 10) * i; - XBT_INFO("set bound of VM1 to %f", new_bound); - MSG_vm_set_bound(vm1, new_bound); - MSG_process_sleep(100); - - double task0_remain_now = MSG_task_get_flops_amount(task0); - double task1_remain_now = MSG_task_get_flops_amount(task1); - - double task0_flops_per_sec = task0_remain_prev - task0_remain_now; - double task1_flops_per_sec = task1_remain_prev - task1_remain_now; - - XBT_INFO("Task0@VM0: %f flops/s", task0_flops_per_sec / 100); - XBT_INFO("Task1@VM1: %f flops/s", task1_flops_per_sec / 100); - - task0_remain_prev = task0_remain_now; - task1_remain_prev = task1_remain_now; - } - - MSG_process_sleep(2000); // let the tasks end - - MSG_vm_destroy(vm0); - MSG_vm_destroy(vm1); -} - -static void test_one_task(msg_host_t hostA) -{ - const double cpu_speed = MSG_host_get_speed(hostA); - const double computation_amount = cpu_speed * 10; - const char* hostA_name = MSG_host_get_name(hostA); - - XBT_INFO("### Test: with/without MSG_task_set_bound"); - - XBT_INFO("### Test: no bound for Task1@%s", hostA_name); - launch_worker(hostA, "worker0", computation_amount, 0, 0); - - MSG_process_sleep(1000); - - XBT_INFO("### Test: 50%% for Task1@%s", hostA_name); - launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed / 2); - - MSG_process_sleep(1000); - - XBT_INFO("### Test: 33%% for Task1@%s", hostA_name); - launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed / 3); - - MSG_process_sleep(1000); - - XBT_INFO("### Test: zero for Task1@%s (i.e., unlimited)", hostA_name); - launch_worker(hostA, "worker0", computation_amount, 1, 0); - - MSG_process_sleep(1000); - - XBT_INFO("### Test: 200%% for Task1@%s (i.e., meaningless)", hostA_name); - launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed * 2); - - MSG_process_sleep(1000); -} - -static void test_two_tasks(msg_host_t hostA, msg_host_t hostB) -{ - const double cpu_speed = MSG_host_get_speed(hostA); - xbt_assert(cpu_speed == MSG_host_get_speed(hostB)); - const double computation_amount = cpu_speed * 10; - const char* hostA_name = MSG_host_get_name(hostA); - const char* hostB_name = MSG_host_get_name(hostB); - - XBT_INFO("### Test: no bound for Task1@%s, no bound for Task2@%s", hostA_name, hostB_name); - launch_worker(hostA, "worker0", computation_amount, 0, 0); - launch_worker(hostB, "worker1", computation_amount, 0, 0); - - MSG_process_sleep(1000); - - XBT_INFO("### Test: 0 for Task1@%s, 0 for Task2@%s (i.e., unlimited)", hostA_name, hostB_name); - launch_worker(hostA, "worker0", computation_amount, 1, 0); - launch_worker(hostB, "worker1", computation_amount, 1, 0); - - MSG_process_sleep(1000); - - XBT_INFO("### Test: 50%% for Task1@%s, 50%% for Task2@%s", hostA_name, hostB_name); - launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed / 2); - launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 2); - - MSG_process_sleep(1000); - - XBT_INFO("### Test: 25%% for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name); - launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed / 4); - launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 4); - - MSG_process_sleep(1000); - - XBT_INFO("### Test: 75%% for Task1@%s, 100%% for Task2@%s", hostA_name, hostB_name); - launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed * 0.75); - launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed); - - MSG_process_sleep(1000); - - XBT_INFO("### Test: no bound for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name); - launch_worker(hostA, "worker0", computation_amount, 0, 0); - launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 4); - - MSG_process_sleep(1000); - - XBT_INFO("### Test: 75%% for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name); - launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed * 0.75); - launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 4); - - MSG_process_sleep(1000); -} - -static int master_main(XBT_ATTRIB_UNUSED int argc, XBT_ATTRIB_UNUSED char* argv[]) -{ - msg_host_t pm0 = MSG_host_by_name("Fafard"); - msg_host_t pm1 = MSG_host_by_name("Fafard"); - - XBT_INFO("# 1. Put a single task on a PM. "); - test_one_task(pm0); - XBT_INFO(" "); - - XBT_INFO("# 2. Put two tasks on a PM."); - test_two_tasks(pm0, pm0); - XBT_INFO(" "); - - msg_vm_t vm0 = MSG_vm_create_core(pm0, "VM0"); - MSG_vm_start(vm0); - - XBT_INFO("# 3. Put a single task on a VM. "); - test_one_task((msg_host_t)vm0); - XBT_INFO(" "); - - XBT_INFO("# 4. Put two tasks on a VM."); - test_two_tasks((msg_host_t)vm0, (msg_host_t)vm0); - XBT_INFO(" "); - - MSG_vm_destroy(vm0); - - vm0 = MSG_vm_create_core(pm0, "VM0"); - MSG_vm_start(vm0); - - XBT_INFO("# 6. Put a task on a PM and a task on a VM."); - test_two_tasks(pm0, (msg_host_t)vm0); - XBT_INFO(" "); - - MSG_vm_destroy(vm0); - - vm0 = MSG_vm_create_core(pm0, "VM0"); - double cpu_speed = MSG_host_get_speed(pm0); - MSG_vm_set_bound(vm0, cpu_speed / 10); - MSG_vm_start(vm0); - - XBT_INFO("# 7. Put a single task on the VM capped by 10%%."); - test_one_task((msg_host_t)vm0); - XBT_INFO(" "); - - XBT_INFO("# 8. Put two tasks on the VM capped by 10%%."); - test_two_tasks((msg_host_t)vm0, (msg_host_t)vm0); - XBT_INFO(" "); - - XBT_INFO("# 9. Put a task on a PM and a task on the VM capped by 10%%."); - test_two_tasks(pm0, (msg_host_t)vm0); - XBT_INFO(" "); - - MSG_vm_destroy(vm0); - - vm0 = MSG_vm_create_core(pm0, "VM0"); - - MSG_vm_set_ramsize(vm0, 1e9); // 1GB - MSG_vm_start(vm0); - - cpu_speed = MSG_host_get_speed(pm0); - MSG_vm_start(vm0); - - XBT_INFO("# 10. Test migration"); - const double computation_amount = cpu_speed * 10; - - XBT_INFO("# 10. (a) Put a task on a VM without any bound."); - launch_worker((msg_host_t)vm0, "worker0", computation_amount, 0, 0); - MSG_process_sleep(1000); - XBT_INFO(" "); - - XBT_INFO("# 10. (b) set 10%% bound to the VM, and then put a task on the VM."); - MSG_vm_set_bound(vm0, cpu_speed / 10); - launch_worker((msg_host_t)vm0, "worker0", computation_amount, 0, 0); - MSG_process_sleep(1000); - XBT_INFO(" "); - - XBT_INFO("# 10. (c) migrate"); - MSG_vm_migrate(vm0, pm1); - XBT_INFO(" "); - - XBT_INFO("# 10. (d) Put a task again on the VM."); - launch_worker((msg_host_t)vm0, "worker0", computation_amount, 0, 0); - MSG_process_sleep(1000); - XBT_INFO(" "); - - MSG_vm_destroy(vm0); - - XBT_INFO("# 11. Change a bound dynamically."); - test_dynamic_change(); - - return 0; -} - -static void launch_master(msg_host_t host) -{ - const char* pr_name = "master_"; - char** argv = xbt_new(char*, 2); - argv[0] = xbt_strdup(pr_name); - argv[1] = NULL; - - MSG_process_create_with_arguments(pr_name, master_main, NULL, host, 1, argv); -} - -int main(int argc, char* argv[]) -{ - /* Get the arguments */ - MSG_init(&argc, argv); - MSG_vm_live_migration_plugin_init(); - - /* load the platform file */ - xbt_assert(argc == 2, "Usage: %s platform_file\n\tExample: %s ../platforms/small_platform.xml\n", argv[0], argv[0]); - - MSG_create_environment(argv[1]); - - msg_host_t pm0 = MSG_host_by_name("Fafard"); - launch_master(pm0); - - int res = MSG_main(); - XBT_INFO("Bye (simulation time %g)", MSG_get_clock()); - - return !(res == MSG_OK); -} -- 2.20.1