SimGrid
Master/slave application using lua console

Simulation of a master-slave application using a realistic platform and an external description of the deployment via a lua script.

Table of contents:


Code of the application

Preliminary declarations

#include <stdio.h>
#include "msg/msg.h"            /* Yeah! If you want to use msg, you need to include msg/msg.h */
#include "surf/surfxml_parse.h" /* to override surf_parse and bypass the parser */

/* Create a log channel to have nice outputs. */
#include "xbt/log.h"
XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test,
                             "Messages specific for this msg example");
#define FINALIZE ((void*)221297)        /* a magic number to tell people to stop working */

int master(int argc, char *argv[]);
int slave(int argc, char *argv[]);
MSG_error_t test_all(const char *);

typedef enum {
  PORT_22 = 0,
  MAX_CHANNEL
} channel_t;

Master code

This function has to be assigned to a m_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_load_platform_script().

C style arguments (argc/argv) are interpreted as:

Tasks are dumbly sent in a round-robin style.

int master(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 slaves_count = atol(argv[4]);
  int i;

  XBT_INFO("Got %ld slaves and %ld tasks to process", slaves_count,
        number_of_tasks);
  for (i = 0; i < number_of_tasks; i++) {
    char mailbox[256];
    char sprintf_buffer[256];
    m_task_t task = NULL;

    sprintf(mailbox, "slave-%ld", i % slaves_count);
    sprintf(sprintf_buffer, "Task_%d", i);
    task =
        MSG_task_create(sprintf_buffer, task_comp_size, task_comm_size,
                        NULL);
    if (number_of_tasks < 10000 || i % 10000 == 0)
      XBT_INFO("Sending \"%s\" (of %ld) to mailbox \"%s\"", task->name,
            number_of_tasks, mailbox);
    MSG_task_send(task, mailbox);
  }

  XBT_INFO
      ("All tasks have been dispatched. Let's tell everybody the computation is over.");
  for (i = 0; i < slaves_count; i++) {
    char mailbox[80];

    sprintf(mailbox, "slave-%ld", i % slaves_count);
    m_task_t finalize = MSG_task_create("finalize", 0, 0, 0);
    MSG_task_send(finalize, mailbox);
  }

  XBT_INFO("Goodbye now!");
  return 0;
}                               /* end_of_master */

Slave code

This function has to be assigned to a m_process_t that has to behave as a slave. Just like the master fuction (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[])
{
  m_task_t task = NULL;
  int res;
  int id = -1;
  char mailbox[80];
  int read;

  read = sscanf(argv[1], "%d", &id);
  xbt_assert(read, "Invalid argument %s\n", argv[1]);

  sprintf(mailbox, "slave-%d", id);

  while (1) {
    res = MSG_task_receive(&(task), mailbox);
    xbt_assert(res == MSG_OK, "MSG_task_get failed");

    XBT_INFO("Received \"%s\"", MSG_task_get_name(task));
    if (!strcmp(MSG_task_get_name(task), "finalize")) {
      MSG_task_destroy(task);
      break;
    }

    XBT_INFO("Processing \"%s\"", MSG_task_get_name(task));
    MSG_task_execute(task);
    XBT_INFO("\"%s\" done", MSG_task_get_name(task));
    MSG_task_destroy(task);
    task = NULL;
  }
  XBT_INFO("I'm done. See you!");
  return 0;
}                               /* end_of_slave */

Simulation core

This function is the core of the simulation and is divided now only into 2 parts thanks to MSG_load_platform_script().

  1. Simulation settings and application deployment : MSG_load_platform_script() loads and creates a realistic environment and the agents on the right locations, described in the lua script file (see example below). Note that the use of this function require a lua installation on your machine.
  2. The simulation is run with MSG_main().

Its arguments are:

MSG_error_t test_all(const char *file)  //(void)
{
  MSG_error_t res = MSG_OK;
  /*  Simulation setting */
  MSG_set_channel_number(MAX_CHANNEL);
  /*start by registering functions before loading script */
  MSG_function_register("master", master);
  MSG_function_register("slave", slave);
  MSG_load_platform_script(file);

  res = MSG_main();

  XBT_INFO("Simulation time %g", MSG_get_clock());
  return res;
}                               /* end_of_test_all */

Main() function

This initializes MSG, runs a simulation, and free all data-structures created by MSG.

int main(int argc, char *argv[])
{
  MSG_error_t res = MSG_OK;

  MSG_global_init(&argc, argv);
  if (argc < 2) {
    printf("Usage: %s platform_script[.lua]\n", argv[0]);
    printf("example: %s platform_script.lua\n", argv[0]);
    exit(1);
  }
  res = test_all(argv[1]);
  MSG_clean();

  if (res == MSG_OK)
    return 0;
  else
    return 1;
}                               /* end_of_main */

Helping files

Example of platform script file

require "simgrid"

  simgrid.AS.new{id="AS0",mode="Full"}; 

  simgrid.AS.addHost{AS="AS0",id="Tremblay",power=98095000};
  simgrid.AS.addHost{AS="AS0",id="Jupiter",power=76296000};
  simgrid.AS.addHost{AS="AS0",id="Fafard",power=76296000};
  simgrid.AS.addHost{AS="AS0",id="Ginette",power=48492000};
  simgrid.AS.addHost{AS="AS0",id="Bourassa",power=48492000};

    -- create Links
  for i=10,0,-1 do
    simgrid.AS.addLink{AS="AS0",id=i,bandwidth=252750+ i*768,latency=0.000270544+i*0.087};   
  end
  -- simgrid.Route.new(src_id,des_id,links_nb,links_list)
   simgrid.AS.addRoute("AS0","Tremblay","Jupiter",{"1"});
   simgrid.AS.addRoute("AS0","Tremblay","Fafard",{"0","1","2","3","4","8"});
   simgrid.AS.addRoute("AS0","Tremblay","Ginette",{"3","4","5"});
   simgrid.AS.addRoute("AS0","Tremblay","Bourassa",{"0","1","3","2","4","6","7"});

   simgrid.AS.addRoute("AS0","Jupiter","Tremblay",{"1"});
   simgrid.AS.addRoute("AS0","Jupiter","Fafard",{"0","1","2","3","4","8","9"});
   simgrid.AS.addRoute("AS0","Jupiter","Ginette",{"3","4","5","9"});
   simgrid.AS.addRoute("AS0","Jupiter","Bourassa",{"0","1","2","3","4","6","7","9"});
 
   simgrid.AS.addRoute("AS0","Fafard","Tremblay",{"0","1","2","3","4","8"});
   simgrid.AS.addRoute("AS0","Fafard","Jupiter",{"0","1","2","3","4","8","9"});
   simgrid.AS.addRoute("AS0","Fafard","Ginette",{"0","1","2","5","8"});
   simgrid.AS.addRoute("AS0","Fafard","Bourassa",{"6","7","8"});
  
   simgrid.AS.addRoute("AS0","Ginette","Tremblay",{"3","4","5"});
   simgrid.AS.addRoute("AS0","Ginette","Jupiter",{"3","4","5","9"});
   simgrid.AS.addRoute("AS0","Ginette","Fafard",{"0","1","2","5","8"});
   simgrid.AS.addRoute("AS0","Ginette","Bourassa",{"0","1","2","5","6","7"});

   simgrid.AS.addRoute("AS0","Bourassa","Tremblay",{"0","1","3","2","4","6","7"});
   simgrid.AS.addRoute("AS0","Bourassa","Jupiter",{"0","1","2","3","4","6","7","9"});
   simgrid.AS.addRoute("AS0","Bourassa","Fafard",{"6","7","8"});
   simgrid.AS.addRoute("AS0","Bourassa","Ginette",{"0","1","2","5","6","7"});
  
   --Save Platform
   simgrid.msg_register_platform();

  --Set Application
   simgrid.Host.setFunction{host="Tremblay",fct="master",args="20,550000000,1000000,4"};
   simgrid.Host.setFunction{host="Bourassa",fct="slave",args="0"};
   simgrid.Host.setFunction{host="Jupiter",fct="slave",args="1"};
   simgrid.Host.setFunction{host="Fafard",fct="slave",args="2"};
   simgrid.Host.setFunction{host="Ginette",fct="slave",args="3"};
   
  --Save Application 
   simgrid.msg_register_application(); 



Back to the main Simgrid Documentation page The version of Simgrid documented here is v3.6.1.
Documentation of other versions can be found in their respective archive files (directory doc/html).
Generated for SimGridAPI by doxygen