1 /* Copyright (c) 2007-2013. The SimGrid Team. All rights reserved. */
3 /* This program is free software; you can redistribute it and/or modify it
4 * under the terms of the license (GNU LGPL) which comes with this package. */
8 #include "xbt/sysdep.h" /* calloc, printf */
10 /* Create a log channel to have nice outputs. */
12 #include "xbt/asserts.h"
13 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, "Messages specific for this msg example");
17 double computation_amount;
21 static int worker_main(int argc, char *argv[])
23 struct worker_data *params = MSG_process_get_data(MSG_process_self());
24 double computation_amount = params->computation_amount;
27 double clock_sta = MSG_get_clock();
29 msg_task_t task = MSG_task_create("Task", computation_amount, 0, NULL);
30 MSG_task_execute(task);
31 MSG_task_destroy(task);
33 double clock_end = MSG_get_clock();
35 double duration = clock_end - clock_sta;
36 double flops_per_sec = computation_amount / duration;
38 XBT_INFO("%s: amount %f duration %f (%f flops/s)",
39 MSG_host_get_name(MSG_host_self()), computation_amount, duration, flops_per_sec);
52 static void test_one_task(msg_host_t hostA, double computation)
55 struct worker_data *params = xbt_new(struct worker_data, 1);
56 params->computation_amount = computation;
58 MSG_process_create("worker", worker_main, params, hostA);
64 static void test_two_tasks(msg_host_t hostA, msg_host_t hostB)
66 const double cpu_speed = MSG_get_host_speed(hostA);
67 xbt_assert(cpu_speed == MSG_get_host_speed(hostB));
68 const double computation_amount = cpu_speed * 10;
69 const char *hostA_name = MSG_host_get_name(hostA);
70 const char *hostB_name = MSG_host_get_name(hostB);
73 XBT_INFO("### Test: no bound for Task1@%s, no bound for Task2@%s", hostA_name, hostB_name);
74 launch_worker(hostA, "worker0", computation_amount, 0, 0);
75 launch_worker(hostB, "worker1", computation_amount, 0, 0);
78 MSG_process_sleep(1000);
81 XBT_INFO("### Test: 0 for Task1@%s, 0 for Task2@%s (i.e., unlimited)", hostA_name, hostB_name);
82 launch_worker(hostA, "worker0", computation_amount, 1, 0);
83 launch_worker(hostB, "worker1", computation_amount, 1, 0);
86 MSG_process_sleep(1000);
89 XBT_INFO("### Test: 50%% for Task1@%s, 50%% for Task2@%s", hostA_name, hostB_name);
90 launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed / 2);
91 launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 2);
94 MSG_process_sleep(1000);
97 XBT_INFO("### Test: 25%% for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name);
98 launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed / 4);
99 launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 4);
102 MSG_process_sleep(1000);
105 XBT_INFO("### Test: 75%% for Task1@%s, 100%% for Task2@%s", hostA_name, hostB_name);
106 launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed * 0.75);
107 launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed);
110 MSG_process_sleep(1000);
113 XBT_INFO("### Test: no bound for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name);
114 launch_worker(hostA, "worker0", computation_amount, 0, 0);
115 launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 4);
118 MSG_process_sleep(1000);
121 XBT_INFO("### Test: 75%% for Task1@%s, 25%% for Task2@%s", hostA_name, hostB_name);
122 launch_worker(hostA, "worker0", computation_amount, 1, cpu_speed * 0.75);
123 launch_worker(hostB, "worker1", computation_amount, 1, cpu_speed / 4);
126 MSG_process_sleep(1000);
130 static void test_pm(void)
132 xbt_dynar_t hosts_dynar = MSG_hosts_as_dynar();
133 msg_host_t pm0 = xbt_dynar_get_as(hosts_dynar, 0, msg_host_t);
134 msg_host_t pm1 = xbt_dynar_get_as(hosts_dynar, 1, msg_host_t);
135 msg_host_t pm2 = xbt_dynar_get_as(hosts_dynar, 2, msg_host_t);
137 const double cpu_speed = MSG_get_host_speed(pm0);
138 const double computation_amount = cpu_speed * 10;
141 XBT_INFO("# 1. Put a single task on each PM. ");
142 test_one_task(pm0, computation_amount);
143 MSG_process_sleep(100);
144 test_one_task(pm1, computation_amount);
145 MSG_process_sleep(100);
146 test_one_task(pm2, computation_amount);
149 MSG_process_sleep(100);
152 XBT_INFO("# 2. Put 2 tasks on each PM. ");
153 test_one_task(pm0, computation_amount);
154 test_one_task(pm0, computation_amount);
155 MSG_process_sleep(100);
157 test_one_task(pm1, computation_amount);
158 test_one_task(pm1, computation_amount);
159 MSG_process_sleep(100);
161 test_one_task(pm2, computation_amount);
162 test_one_task(pm2, computation_amount);
165 MSG_process_sleep(100);
168 XBT_INFO("# 3. Put 4 tasks on each PM. ");
169 test_one_task(pm0, computation_amount);
170 test_one_task(pm0, computation_amount);
171 test_one_task(pm0, computation_amount);
172 test_one_task(pm0, computation_amount);
173 MSG_process_sleep(100);
175 test_one_task(pm1, computation_amount);
176 test_one_task(pm1, computation_amount);
177 test_one_task(pm1, computation_amount);
178 test_one_task(pm1, computation_amount);
179 MSG_process_sleep(100);
181 test_one_task(pm2, computation_amount);
182 test_one_task(pm2, computation_amount);
183 test_one_task(pm2, computation_amount);
184 test_one_task(pm2, computation_amount);
187 MSG_process_sleep(100);
191 static void test_vm(void)
193 xbt_dynar_t hosts_dynar = MSG_hosts_as_dynar();
194 msg_host_t pm0 = xbt_dynar_get_as(hosts_dynar, 0, msg_host_t);
195 msg_host_t pm1 = xbt_dynar_get_as(hosts_dynar, 1, msg_host_t);
196 msg_host_t pm2 = xbt_dynar_get_as(hosts_dynar, 2, msg_host_t);
199 const double cpu_speed = MSG_get_host_speed(pm0);
200 const double computation_amount = cpu_speed * 10;
204 msg_host_t vm0 = MSG_vm_create_core(pm0, "vm0");
205 msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
206 msg_host_t vm2 = MSG_vm_create_core(pm2, "vm2");
208 XBT_INFO("# 1. Put a single task on each VM.");
209 test_one_task(vm0, computation_amount);
210 MSG_process_sleep(100);
212 test_one_task(vm1, computation_amount);
213 MSG_process_sleep(100);
215 test_one_task(vm2, computation_amount);
216 MSG_process_sleep(100);
225 msg_host_t vm0 = MSG_vm_create_core(pm0, "vm0");
226 msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
227 msg_host_t vm2 = MSG_vm_create_core(pm2, "vm2");
229 XBT_INFO("# 2. Put 2 tasks on each VM.");
230 test_one_task(vm0, computation_amount);
231 test_one_task(vm0, computation_amount);
232 MSG_process_sleep(100);
234 test_one_task(vm1, computation_amount);
235 test_one_task(vm1, computation_amount);
236 MSG_process_sleep(100);
238 test_one_task(vm2, computation_amount);
239 test_one_task(vm2, computation_amount);
240 MSG_process_sleep(100);
249 msg_host_t vm0 = MSG_vm_create_core(pm0, "vm0");
250 msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
251 msg_host_t vm2 = MSG_vm_create_core(pm2, "vm2");
253 XBT_INFO("# 3. Put a task on each VM, and put a task on its PM.");
254 test_one_task(vm0, computation_amount);
255 test_one_task(pm0, computation_amount);
256 MSG_process_sleep(100);
258 test_one_task(vm1, computation_amount);
259 test_one_task(pm1, computation_amount);
260 MSG_process_sleep(100);
262 test_one_task(vm2, computation_amount);
263 test_one_task(pm2, computation_amount);
264 MSG_process_sleep(100);
275 XBT_INFO("# 4. Put 2 VMs on a 1-core PM.");
276 msg_host_t vm0 = MSG_vm_create_core(pm0, "vm0");
277 msg_host_t vm1 = MSG_vm_create_core(pm0, "vm1");
279 test_one_task(vm0, computation_amount);
280 test_one_task(vm1, computation_amount);
281 MSG_process_sleep(100);
289 XBT_INFO("# 5. Put 2 VMs on a 2-core PM.");
290 msg_host_t vm0 = MSG_vm_create_core(pm1, "vm0");
291 msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
293 test_one_task(vm0, computation_amount);
294 test_one_task(vm1, computation_amount);
295 MSG_process_sleep(100);
303 XBT_INFO("# 6. Put 2 VMs on a 2-core PM and 1 task on the PM.");
304 msg_host_t vm0 = MSG_vm_create_core(pm1, "vm0");
305 msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
307 test_one_task(vm0, computation_amount);
308 test_one_task(vm1, computation_amount);
309 test_one_task(pm1, computation_amount);
310 MSG_process_sleep(100);
318 XBT_INFO("# 7. Put 2 VMs and 2 tasks on a 2-core PM. Put two tasks on one of the VMs.");
319 msg_host_t vm0 = MSG_vm_create_core(pm1, "vm0");
320 msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
321 test_one_task(pm1, computation_amount);
322 test_one_task(pm1, computation_amount);
324 /* Reduce computation_amount to make all tasks finish at the same time. Simplify results. */
325 test_one_task(vm0, computation_amount / 2);
326 test_one_task(vm0, computation_amount / 2);
327 test_one_task(vm1, computation_amount);
328 MSG_process_sleep(100);
336 XBT_INFO("# 8. Put 2 VMs and a task on a 2-core PM. Cap the load of VM1 at 50%%.");
337 /* This is a tricky case. The process schedular of the host OS may not work as expected. */
339 /* VM0 gets 50%. VM1 and VM2 get 75%, respectively. */
340 msg_host_t vm0 = MSG_vm_create_core(pm1, "vm0");
341 MSG_vm_set_bound(vm0, cpu_speed / 2);
342 msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
343 test_one_task(pm1, computation_amount);
345 test_one_task(vm0, computation_amount);
346 test_one_task(vm1, computation_amount);
348 MSG_process_sleep(100);
355 /* In all the above cases, tasks finish at the same time.
356 * TODO: more complex cases must be done.
362 XBT_INFO("# 8. Put 2 VMs and a task on a 2-core PM. Put two tasks on one of the VMs.");
363 msg_host_t vm0 = MSG_vm_create_core(pm1, "vm0");
364 msg_host_t vm1 = MSG_vm_create_core(pm1, "vm1");
366 test_one_task(vm0, computation_amount);
367 test_one_task(vm0, computation_amount);
368 test_one_task(vm1, computation_amount);
369 test_one_task(pm1, computation_amount);
370 MSG_process_sleep(100);
381 static int master_main(int argc, char *argv[])
383 XBT_INFO("=== Test PM ===");
388 XBT_INFO("=== Test VM ===");
398 int main(int argc, char *argv[])
400 /* Get the arguments */
401 MSG_init(&argc, argv);
403 /* load the platform file */
405 printf("Usage: %s examples/msg/cloud/multicore_plat.xml\n", argv[0]);
409 MSG_create_environment(argv[1]);
411 xbt_dynar_t hosts_dynar = MSG_hosts_as_dynar();
412 msg_host_t pm0 = xbt_dynar_get_as(hosts_dynar, 0, msg_host_t);
413 msg_host_t pm1 = xbt_dynar_get_as(hosts_dynar, 1, msg_host_t);
414 msg_host_t pm2 = xbt_dynar_get_as(hosts_dynar, 2, msg_host_t);
417 XBT_INFO("%s: %d core(s), %f flops/s per each", MSG_host_get_name(pm0), MSG_get_host_core(pm0), MSG_get_host_speed(pm0));
418 XBT_INFO("%s: %d core(s), %f flops/s per each", MSG_host_get_name(pm1), MSG_get_host_core(pm1), MSG_get_host_speed(pm1));
419 XBT_INFO("%s: %d core(s), %f flops/s per each", MSG_host_get_name(pm2), MSG_get_host_core(pm2), MSG_get_host_speed(pm2));
423 MSG_process_create("master", master_main, NULL, pm0);
428 int res = MSG_main();
429 XBT_INFO("Bye (simulation time %g)", MSG_get_clock());
432 return !(res == MSG_OK);