- Note
- This page is under work – sorry for the inconvenience (FIXME).
SimGrid comes with many examples provided in the examples/ directory. Those examples are described in section MSG examples. Those examples are commented and should be easy to understand. for a first step into SimGrid we also provide some more detailed examples in the sections below.
You should also check our online tutorial section that contains a generic tutorial about using SimGrid.
Using MSG
You should also check our online tutorial section that contains a dedicated tutorial.
Here are some examples on how to use MSG, the most used API.
MSG comes with an extensive set of examples. It is sometimes difficult to find the one you need. This list aims at helping you finding the example from which you can learn what you want to.
Basic examples and features
Asynchronous communications
Simulation of asynchronous communications between a sender and a receiver using a realistic platform and an external description of the deployment.
Code of the application
Preliminary declarations
#include <stdio.h>
#include "simgrid/msg.h"
#include "xbt/sysdep.h"
#include "xbt/log.h"
#include "xbt/asserts.h"
"Messages specific for this msg example");
int sender(int argc, char *argv[]);
int receiver(int argc, char *argv[]);
const char *application_file);
Sender function
A host can send an an asynchronous message with MSG_task_isend()
. As this function is non-blocking, we have to call MSG_comm_test()
to know if the communication has finished and finally destroy it with a call to MSG_comm_destroy()
. It is also possible to call MSG_comm_wait()
which, is provides a shortcut.
C style arguments (argc/argv) are interpreted as:
- the number of tasks to distribute
- the computation size of each task
- the size of the files associated to each task
- a list of host that will accept those tasks.
- the time to sleep at the beginning of the function
- This time defined the process sleep time if time = 0 use of MSG_comm_wait() if time > 0 use of MSG_comm_test()
int sender(int argc, char *argv[])
{
long number_of_tasks = atol(argv[1]);
double task_comp_size = atof(argv[2]);
double task_comm_size = atof(argv[3]);
long receivers_count = atol(argv[4]);
double sleep_start_time = atof(argv[5]);
double sleep_test_time = atof(argv[6]);
XBT_INFO(
"sleep_start_time : %f , sleep_test_time : %f", sleep_start_time,
sleep_test_time);
int i;
for (i = 0; i < number_of_tasks; i++) {
char mailbox[256];
char sprintf_buffer[256];
sprintf(mailbox, "receiver-%ld", i % receivers_count);
sprintf(sprintf_buffer, "Task_%d", i);
task =
NULL);
XBT_INFO(
"Send to receiver-%ld Task_%d", i % receivers_count, i);
if (sleep_test_time == 0) {
} else {
};
}
}
for (i = 0; i < receivers_count; i++) {
char mailbox[80];
sprintf(mailbox, "receiver-%ld", i % receivers_count);
XBT_INFO(
"Send to receiver-%ld finalize", i % receivers_count);
if (sleep_test_time == 0) {
} else {
};
}
}
return 0;
}
Receiver function
This function executes tasks when it receives them. As the receiving is asynchronous we have to test the communication to know if it is completed or not with MSG_comm_test()
or wait for the completion MSG_comm_wait()
.
C style arguments (argc/argv) are interpreted as:
- the id to use for received the communication.
- the time to sleep at the beginning of the function
- This time defined the process sleep time if time = 0 use of MSG_comm_wait() if time > 0 use of MSG_comm_test()
int receiver(int argc, char *argv[])
{
int id = -1;
char mailbox[80];
double sleep_start_time = atof(argv[2]);
double sleep_test_time = atof(argv[3]);
XBT_INFO(
"sleep_start_time : %f , sleep_test_time : %f", sleep_start_time,
sleep_test_time);
XBT_ATTRIB_UNUSED int read;
read = sscanf(argv[1], "%d", &id);
"Invalid argument %s\n", argv[1]);
sprintf(mailbox, "receiver-%d", id);
while (1) {
if (sleep_test_time == 0) {
} else {
};
}
break;
}
task = NULL;
}
return 0;
}
Simulation core
This function is the core of the simulation and is divided only into 3 parts thanks to MSG_create_environment() and MSG_launch_application().
- Simulation settings : MSG_create_environment() creates a realistic environment
- Application deployment : create the processes on the right locations with MSG_launch_application()
- The simulation is run with MSG_main()
Its arguments are:
- platform_file: the name of a file containing an valid surfxml platform description.
- application_file: the name of a file containing a valid surfxml application description
const char *application_file)
{
{
}
{
}
return res;
}
Main function
This initializes MSG, runs a simulation, and free all data-structures created by MSG.
int main(int argc, char *argv[])
{
if (argc < 3) {
printf("Usage: %s platform_file deployment_file\n", argv[0]);
printf("example: %s msg_platform.xml msg_deployment.xml\n", argv[0]);
exit(1);
}
res = test_all(argv[1], argv[2]);
return 0;
else
return 1;
}
Waitall function for sender
The use of this function permit to send all messages and wait for the completion of all in one time.
int sender(int argc, char *argv[])
{
long number_of_tasks = atol(argv[1]);
double task_comp_size = atof(argv[2]);
double task_comm_size = atof(argv[3]);
long receivers_count = atol(argv[4]);
int i;
for (i = 0; i < number_of_tasks; i++) {
char mailbox[256];
char sprintf_buffer[256];
sprintf(mailbox, "receiver-%ld", i % receivers_count);
sprintf(sprintf_buffer, "Task_%d", i);
task =
NULL);
XBT_INFO(
"Send to receiver-%ld Task_%d", i % receivers_count, i);
}
for (i = 0; i < receivers_count; i++) {
char mailbox[80];
sprintf(mailbox, "receiver-%ld", i % receivers_count);
XBT_INFO(
"Send to receiver-%ld finalize", i % receivers_count);
}
for (i = 0; i < number_of_tasks + receivers_count; i++)
return 0;
}
Waitany function
The MSG_comm_waitany() function return the place of the first message send or receive from a xbt_dynar_t table.
From a sender
We can use this function to wait all sent messages.
int sender(int argc, char *argv[])
{
long number_of_tasks = atol(argv[1]);
double task_comp_size = atof(argv[2]);
double task_comm_size = atof(argv[3]);
long receivers_count = atol(argv[4]);
int diff_com = atol(argv[5]);
double coef = 0;
int i;
char mailbox[256];
char sprintf_buffer[256];
for (i = 0; i < number_of_tasks; i++) {
if (diff_com == 0)
coef = 1;
else
coef = (i + 1);
sprintf(mailbox, "receiver-%ld", (i % receivers_count));
sprintf(sprintf_buffer, "Task_%d", i);
task =
task_comm_size / coef, NULL);
XBT_INFO(
"Send to receiver-%ld %s comm_size %f", i % receivers_count,
sprintf_buffer, task_comm_size / coef);
}
}
sprintf(mailbox, "finalize");
for (i = 0; i < receivers_count; i++) {
task = NULL;
}
return 0;
}
From a receiver
We can also wait for the arrival of all messages.
int receiver(int argc, char *argv[])
{
int id = -1;
int i;
char mailbox[80];
int tasks = atof(argv[2]);
XBT_ATTRIB_UNUSED int read;
read = sscanf(argv[1], "%d", &id);
xbt_assert(read,
"Invalid argument %s\n", argv[1]);
sprintf(mailbox, "receiver-%d", id);
for (i = 0; i < tasks; i++) {
task[i] = NULL;
}
}
sprintf(mailbox, "finalize");
return 0;
}
Basic Master/Slaves
Simulation of a master-slave application using a realistic platform and an external description of the deployment.
Table of contents:
Preliminary declarations
#include <stdio.h>
#include "simgrid/msg.h"
#include "xbt/sysdep.h"
#include "xbt/log.h"
#include "xbt/asserts.h"
"Messages specific for this msg example");
int master(int argc, char *argv[]);
int slave(int argc, char *argv[]);
int forwarder(int argc, char *argv[]);
const char *application_file);
#define FINALIZE ((void*)221297)
int master(int argc, char *argv[])
{
int slaves_count = 0;
int number_of_tasks = 0;
double task_comp_size = 0;
double task_comm_size = 0;
int i;
XBT_ATTRIB_UNUSED int res = sscanf(argv[1], "%d", &number_of_tasks);
res = sscanf(argv[2], "%lg", &task_comp_size);
xbt_assert(res,
"Invalid argument %s\n", argv[2]);
res = sscanf(argv[3], "%lg", &task_comm_size);
xbt_assert(res,
"Invalid argument %s\n", argv[3]);
{
char sprintf_buffer[64];
for (i = 0; i < number_of_tasks; i++) {
sprintf(sprintf_buffer, "Task_%d", i);
todo[i] =
NULL);
}
Master code
This function has to be assigned to a msg_process_t that will behave as the master. It should not be called directly but either given as a parameter to MSG_process_create() or registered as a public function through MSG_function_register() and then automatically assigned to a process through MSG_launch_application().
C style arguments (argc/argv) are interpreted as:
- the number of tasks to distribute
- the computation size of each task
- the size of the files associated to each task
- a list of host that will accept those tasks.
Tasks are dumbly sent in a round-robin style.
}
{
slaves_count = argc - 4;
for (i = 4; i < argc; i++) {
xbt_assert(slaves[i - 4] != NULL,
"Unknown host %s. Stopping Now! ",
argv[i]);
}
}
XBT_INFO(
"Got %d slaves and %d tasks to process", slaves_count,
number_of_tasks);
for (i = 0; i < slaves_count; i++)
for (i = 0; i < number_of_tasks; i++) {
}
}
("All tasks have been dispatched. Let's tell everybody the computation is over.");
for (i = 0; i < slaves_count; i++) {
}
free(slaves);
free(todo);
return 0;
}
Slave code
This function has to be assigned to a msg_process_t that has to behave as a slave. Just like the master function (described in Master code), it should not be called directly.
This function keeps waiting for tasks and executes them as it receives them.
int slave(int argc, char *argv[])
{
XBT_ATTRIB_UNUSED int res;
while (1) {
break;
}
task = NULL;
}
return 0;
}
Forwarder code
This function has to be assigned to a msg_process_t that has to behave as a forwarder. Just like the master function (described in Master code), it should not be called directly.
C style arguments (argc/argv) are interpreted as a list of hosts that will accept those tasks.
This function keeps waiting for tasks and dispatches them to its slaves.
int forwarder(int argc, char *argv[])
{
int i;
int slaves_count;
{
slaves_count = argc - 1;
for (i = 1; i < argc; i++) {
if (slaves[i - 1] == NULL) {
XBT_INFO(
"Unknown host %s. Stopping Now! ", argv[i]);
abort();
}
}
}
i = 0;
while (1) {
int a;
("All tasks have been dispatched. Let's tell everybody the computation is over.");
for (i = 0; i < slaves_count; i++)
break;
}
i++;
} else {
}
}
return 0;
}
Simulation core
This function is the core of the simulation and is divided only into 3 parts thanks to MSG_create_environment() and MSG_launch_application().
- Simulation settings : MSG_create_environment() creates a realistic environment
- Application deployment : create the processes on the right locations with MSG_launch_application()
- The simulation is run with MSG_main()
Its arguments are:
- platform_file: the name of a file containing an valid surfxml platform description.
- application_file: the name of a file containing a valid surfxml application description
const char *application_file)
{
{
}
{
}
return res;
}
Main() function
This initializes MSG, runs a simulation, and free all data-structures created by MSG.
int main(int argc, char *argv[])
{
if (argc < 3) {
printf("Usage: %s platform_file deployment_file\n", argv[0]);
printf("example: %s msg_platform.xml msg_deployment.xml\n", argv[0]);
exit(1);
}
res = test_all(argv[1], argv[2]);
return 0;
else
return 1;
}
Helping files
Example of a deployment file
The following listing can be found in examples/msg/masterslave/deployment_masterslave_forwarder.xml
:
2 <!
DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
4 <
process host=
"Jacquelin" function=
"master">
6 <
argument value=
"5000000"/>
7 <
argument value=
"100000"/>
8 <
argument value=
"iRMX"/>
9 <
argument value=
"Casavant"/>
10 <
argument value=
"Bousquet"/>
11 <
argument value=
"Soucy"/>
12 <
argument value=
"Jackson"/>
14 <
process host=
"Jackson" function=
"forwarder">
15 <
argument value=
"Kuenning"/>
16 <
argument value=
"Browne"/>
17 <
argument value=
"Stephen"/>
19 <
process host=
"Casavant" function=
"forwarder">
20 <
argument value=
"Robert"/>
21 <
argument value=
"Sirois"/>
22 <
argument value=
"Monique"/>
24 <
process host=
"iRMX" function=
"slave"/>
25 <
process host=
"Bousquet" function=
"slave"/>
26 <
process host=
"Soucy" function=
"slave"/>
27 <
process host=
"Kuenning" function=
"slave"/>
28 <
process host=
"Browne" function=
"slave"/>
29 <
process host=
"Stephen" function=
"slave"/>
30 <
process host=
"Robert" function=
"slave"/>
31 <
process host=
"Sirois" function=
"slave"/>
32 <
process host=
"Monique" function=
"slave"/>
Example of a platform file
2 <!
DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
4 <
AS id=
"AS0" routing=
"Full">
6 <
host id=
"Tremblay" power=
"98.095Mf"/>
7 <
host id=
"Jupiter" power=
"76.296Mf"/>
8 <
host id=
"Fafard" power=
"76.296Mf"/>
9 <
host id=
"Ginette" power=
"48.492Mf"/>
10 <
host id=
"Bourassa" power=
"48.492Mf"/>
11 <
link id=
"6" bandwidth=
"41.279125MBps" latency=
"59.904us"/>
12 <
link id=
"3" bandwidth=
"34.285625MBps" latency=
"514.433us"/>
13 <
link id=
"7" bandwidth=
"11.618875MBps" latency=
"189.98us"/>
14 <
link id=
"9" bandwidth=
"7.20975MBps" latency=
"1.461517ms"/>
15 <
link id=
"2" bandwidth=
"118.6825MBps" latency=
"136.931us"/>
16 <
link id=
"8" bandwidth=
"8.158MBps" latency=
"270.544us"/>
17 <
link id=
"1" bandwidth=
"34.285625MBps" latency=
"514.433us"/>
18 <
link id=
"4" bandwidth=
"10.099625MBps" latency=
"479.78us"/>
19 <
link id=
"0" bandwidth=
"41.279125MBps" latency=
"59.904us"/>
20 <
link id=
"5" bandwidth=
"27.94625MBps" latency=
"278.066us"/>
21 <
link id=
"loopback" bandwidth=
"498MBps" latency=
"15us" sharing_policy=
"FATPIPE"/>
22 <
route src=
"Tremblay" dst=
"Tremblay"><
link_ctn id=
"loopback"/></
route>
23 <
route src=
"Jupiter" dst=
"Jupiter"><
link_ctn id=
"loopback"/></
route>
24 <
route src=
"Fafard" dst=
"Fafard"><
link_ctn id=
"loopback"/></
route>
25 <
route src=
"Ginette" dst=
"Ginette"><
link_ctn id=
"loopback"/></
route>
26 <
route src=
"Bourassa" dst=
"Bourassa"><
link_ctn id=
"loopback"/></
route>
27 <
route src=
"Tremblay" dst=
"Jupiter">
30 <
route src=
"Tremblay" dst=
"Fafard">
31 <
link_ctn id=
"4"/><
link_ctn id=
"3"/><
link_ctn id=
"2"/><
link_ctn id=
"0"/><
link_ctn id=
"1"/><
link_ctn id=
"8"/>
33 <
route src=
"Tremblay" dst=
"Ginette">
34 <
link_ctn id=
"4"/><
link_ctn id=
"3"/><
link_ctn id=
"5"/>
36 <
route src=
"Tremblay" dst=
"Bourassa">
37 <
link_ctn id=
"4"/><
link_ctn id=
"3"/><
link_ctn id=
"2"/><
link_ctn id=
"0"/><
link_ctn id=
"1"/><
link_ctn id=
"6"/><
link_ctn id=
"7"/>
39 <
route src=
"Jupiter" dst=
"Fafard">
40 <
link_ctn id=
"9"/><
link_ctn id=
"4"/><
link_ctn id=
"3"/><
link_ctn id=
"2"/><
link_ctn id=
"0"/><
link_ctn id=
"1"/><
link_ctn id=
"8"/>
42 <
route src=
"Jupiter" dst=
"Ginette">
43 <
link_ctn id=
"9"/><
link_ctn id=
"4"/><
link_ctn id=
"3"/><
link_ctn id=
"5"/>
45 <
route src=
"Jupiter" dst=
"Bourassa">
46 <
link_ctn id=
"9"/><
link_ctn id=
"4"/><
link_ctn id=
"3"/><
link_ctn id=
"2"/><
link_ctn id=
"0"/><
link_ctn id=
"1"/><
link_ctn id=
"6"/><
link_ctn id=
"7"/>
48 <
route src=
"Fafard" dst=
"Ginette">
49 <
link_ctn id=
"8"/><
link_ctn id=
"1"/><
link_ctn id=
"0"/><
link_ctn id=
"2"/><
link_ctn id=
"5"/>
51 <
route src=
"Fafard" dst=
"Bourassa">
52 <
link_ctn id=
"8"/><
link_ctn id=
"6"/><
link_ctn id=
"7"/>
54 <
route src=
"Ginette" dst=
"Bourassa">
55 <
link_ctn id=
"5"/><
link_ctn id=
"2"/><
link_ctn id=
"0"/><
link_ctn id=
"1"/><
link_ctn id=
"6"/><
link_ctn id=
"7"/>