From: Paul Bédaride Date: Wed, 23 Jan 2013 14:18:51 +0000 (+0100) Subject: Add the msg tutorial of Arnauld Legrand to doxygen X-Git-Tag: v3_9_rc1~68 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/cae4f3ce3a29af78349034eaa7206185fa66ebef?hp=f84cfe8277f2b62f9caff0052fea73eb468e26a5 Add the msg tutorial of Arnauld Legrand to doxygen --- diff --git a/buildtools/Cmake/DefinePackages.cmake b/buildtools/Cmake/DefinePackages.cmake index 56fd828081..9c58bb2f7a 100644 --- a/buildtools/Cmake/DefinePackages.cmake +++ b/buildtools/Cmake/DefinePackages.cmake @@ -588,6 +588,7 @@ set(DOC_TOOLS # these files get copied automatically to the html documentation set(DOC_IMG ${CMAKE_HOME_DIRECTORY}/doc/simgrid.css + ${CMAKE_HOME_DIRECTORY}/doc/sc3-description.png ${CMAKE_HOME_DIRECTORY}/doc/webcruft/Paje_MSG_screenshot.jpg ${CMAKE_HOME_DIRECTORY}/doc/webcruft/Paje_MSG_screenshot_thn.jpg ${CMAKE_HOME_DIRECTORY}/doc/webcruft/SGicon.gif diff --git a/buildtools/Cmake/GenerateDoc.cmake b/buildtools/Cmake/GenerateDoc.cmake index 72a2e456db..9b06ae06f2 100644 --- a/buildtools/Cmake/GenerateDoc.cmake +++ b/buildtools/Cmake/GenerateDoc.cmake @@ -49,6 +49,8 @@ if(DOXYGEN_PATH) ADD_CUSTOM_COMMAND(TARGET simgrid_documentation COMMAND ${FIG2DEV_PATH}/fig2dev -Lmap ${CMAKE_HOME_DIRECTORY}/doc/shared/fig/simgrid_modules.fig | perl -pe 's/imagemap/simgrid_modules/g'| perl -pe 's/ ${CMAKE_HOME_DIRECTORY}/doc/simgrid_modules.map + COMMAND pwd + COMMAND ${CMAKE_COMMAND} -E tar cvzf html/msg-tuto-src.tgz msg-tuto-src/ COMMAND ${CMAKE_COMMAND} -E echo "XX Run doxygen" COMMAND ${DOXYGEN_PATH}/doxygen Doxyfile COMMAND ${CMAKE_COMMAND} -E echo "XX Generate the index files" diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index f6d0b20457..7b4be67932 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -708,7 +708,6 @@ INPUT = doxygen/index.doc \ INPUT += @top_srcdir@/examples/msg/sendrecv/sendrecv.c \ @top_srcdir@/examples/msg/masterslave/masterslave_forwarder.c \ - @top_srcdir@/examples/msg/masterslave/masterslave_console.c \ @top_srcdir@/examples/msg/migration \ @top_srcdir@/examples/msg/suspend \ @top_srcdir@/examples/msg/properties \ diff --git a/doc/doxygen/introduction.doc b/doc/doxygen/introduction.doc index 62d52bdbae..6b2fa097a3 100644 --- a/doc/doxygen/introduction.doc +++ b/doc/doxygen/introduction.doc @@ -1,12 +1,6 @@ /*! @page introduction Introduction to SimGrid -This page does not really exist yet. In the meanwhile, please refer -to the tutorials -on the project web page, looking for the -SimGrid -101 tutorial. - -SimGrid is a toolkit +[SimGrid](http://simgrid.gforge.inria.fr/) is a toolkit that provides core functionalities for the simulation of distributed applications in heterogeneous distributed environments. @@ -15,4 +9,486 @@ distributed and parallel application scheduling on distributed computing platforms ranging from simple network of workstations to Computational Grids. -*/ \ No newline at end of file +# Scenario +The goal of this practical session is to illustrate various usage of +the MSG interface. To this end we will use the following simple setting: + +> Assume we have a (possibly large) bunch of (possibly large) data to +> process and which originally reside on a server (a.k.a. master). For +> sake of simplicity, we assume all input file require the same amount +> of computation. We assume the server can be helped by a (possibly +> large) set of worker machines. What is the best way to organize the +> computations ? + +Although this looks like a very simple setting it raises several +interesting questions: + +- Which algorithm should the master use to send workload? + + The most obvious algorithm would be to send tasks to workers in a + round-robin fashion. This is the initial code we provide you. + + A less obvious one but probably more efficient would be to set up + a request mechanism where client first ask for tasks, which allows + the server to decide which request to answer and possibly to send + the tasks to the fastest machines. Maybe you can think of a + smarter mechanism... + +- How much tasks should the client ask for? + + Indeed, if we set up a request mechanism and that workers only + send request whenever they have no more task to process, they are + likely to be poorly exploited since they will have to wait for the + master to consider their request and for the input data to be + transferred. A client should thus probably request a pool of tasks + but if it requests too much task, it is likely to lead to a poor + load-balancing... + +- How is the quality of such algorithm dependent on the platform + characteristics? on the task characteristics? + + Whenever the input communication time is very small compared to + processing time and workers are homogeneous, it is likely that the + round-robin algorithm performs very well. Would it still hold true + when transfer time is not negligible and the platform is, say, + a volunteer computing system ? + +- The network topology interconnecting the master and the workers + may be quite complicated. How does such topology impact the + previous result? + + When data transfers are the bottleneck, it is likely that a good + modeling of the platform becomes essential, in which case, you may + want to be able to account for complex platform topologies. + +- Do the algorithms depend on a perfect knowledge of this + topology? + + Should we still use a flat master worker deployment or should we + use a + +- How is such algorithm sensitive to external workload variation? + + What if bandwidth, latency and power can vary with no warning? + Shouldn't you study whether your algorithm is sensitive to such + load variations? + +- Although an algorithm may be more efficient than another, how + does it interfere with other applications? + + As you can see, this very simple setting may need to evolve way + beyond what you initially imagined. + +
Premature optimization is the root of all evil. -- D.E.Knuth
+ + Furthermore, writing your own simulator is much harder that what you + may imagine. This is why should rely on an established and flexible + one. + +The following figure is a screenshot of [triva][fn:1] visualizing a [SimGrid +simulation][fn:2] of two master worker applications (one in light gray and +the other in dark gray) running in concurrence and showing resource +usage over a long period of time. + +![Test](./sc3-description.png) + +# Prerequisites + +## Tutorials + +A lot of information on how to install and use Simgrid are +available on the [online documentation][fn:4] and in the tutorials: + +- http://simgrid.gforge.inria.fr/tutorials/simgrid-use-101.pdf +- http://simgrid.gforge.inria.fr/tutorials/simgrid-tracing-101.pdf +- http://simgrid.gforge.inria.fr/tutorials/simgrid-platf-101.pdf + +## Installing SimGrid + + sudo apt-get install simgrid + +This tutorial requires simgrid 3.8 at last so you may need to get +the [debian package](http://packages.debian.org/unstable/main/simgrid). Here is a shortcut: + +- AMD64: http://ftp.de.debian.org/debian/pool/main/s/simgrid/simgrid_3.8.1-2_amd64.deb +- i386: http://ftp.de.debian.org/debian/pool/main/s/simgrid/simgrid_3.8.1-2_i386.deb + +Then + +~~~~{.sh} +sudo dpkg -i simgrid_3.8*.deb +~~~~ + +# Recommended Steps + +## Installing Viva + +This [software][fn:1] will be useful to make fancy graph or treemap +visualizations and get a better understanding of simulations. You +will first need to install pajeng: + +~~~~{.sh} +sudo apt-get install git cmake build-essential libqt4-dev libboost-dev freeglut3-dev ; +git clone https://github.com/schnorr/pajeng.git +cd pajeng && mkdir -p build && cd build && cmake ../ -DCMAKE_INSTALL_PREFIX=$HOME && make -j install +cd ../../ +~~~~ + +Then you can install viva. + +~~~~{.sh} +sudo apt-get install libboost-dev libconfig++-dev libconfig8-dev libgtk2.0-dev freeglut3-dev +git clone https://github.com/schnorr/viva.git +cd viva && mkdir -p build_graph && cd build_graph && cmake ../ -DTUPI_LIBRARY=ON -DVIVA=ON -DCMAKE_INSTALL_PREFIX=$HOME && make -j install +cd ../../ +~~~~ + +## Installing Paje + +This [software][fn:5] provides a Gantt-chart visualization. + +~~~~{.sh} +sudo apt-get install paje.app +~~~~ + +## Installing Vite + +This software provides a [Gantt-chart visualization][fn:6]. + +~~~~{.sh} +sudo apt-get install vite +~~~~ + +# Let's get Started +## Setting up and Compiling. + +The corresponding archive with all source files and platform files +can be obtained [here](msg-tuto-src.tgz). + +~~~~{.sh} +tar zxf msg-tuto.tgz +cd msg-tuto/src +make +~~~~ + +As you can see, there is already a nice Makefile that compiles +everything for you. Now the tiny example has been compiled and it +can be easily run as follows: + +~~~~{.sh} +./masterworker0 platforms/platform.xml deployment0.xml 2>&1 +~~~~ + +If you create a single self-content C-file named foo.c, the +corresponding program will be simply compiled and linked with +SimGrid by typing: + +~~~~{.sh} +make foo +~~~~ + +For a more "fancy" output, you can try: + +~~~~{.sh} +./masterworker0 platforms/platform.xml deployment0.xml 2>&1 | simgrid-colorizer +~~~~ + +For a really fancy output, you should use [viva/triva][fn:1]: + +~~~~{.sh} +./masterworker0 platforms/platform.xml deployment0.xml --cfg=tracing:1\ + --cfg=tracing/uncategorized:1 --cfg=viva/uncategorized:uncat.plist +LANG=C ; viva simgrid.trace uncat.plist +~~~~ + +For a more classical Gantt-Chart visualization, you can produce a +[Paje][fn:5] trace: + +~~~~{.sh} +./masterworker0 platforms/platform.xml deployment0.xml --cfg=tracing:1 \ + --cfg=tracing/msg/process:1 +LANG=C ; Paje simgrid.trace +~~~~ + +Alternatively, you can use [vite][fn:6]. + +~~~~{.sh} +./masterworker0 platforms/platform.xml deployment0.xml --cfg=tracing:1\ + --cfg=tracing/msg/process:1 --cfg=tracing/basic:1 +vite simgrid.trace +~~~~ + +## Getting Rid of Workers in the Deployment File + +In the previous example, the deployment file `deployment0.xml` +is tightly connected to the platform file `platform.xml` and a +worker process is launched on each host: + +~~~~{.xml} + + + + + + + + + + + + + + + + + + + + + +~~~~ + +This is ok as the platform is rather small but will be painful when +using larger platforms. Instead, modify the simulator +`masterworker0.c` into `masterworker1.c` so that the master +launches a worker process on all the other machines at startup. The +new deployment file `deployment1.xml` should thus now simply be: + +~~~~{.xml} + + + + + + + + + + +~~~~ + +To this end you may need the following MSG functions, whose +behavior is described in the [online documentation](http://simgrid.gforge.inria.fr/simgrid/3.8.1/ref_guide/html/index.html) (hint: use the +search field to access directly the function you are looking for): + +~~~~{.c} +int MSG_get_host_number (void) +xbt_dynar_t MSG_hosts_as_dynar(void); +void * xbt_dynar_to_array (xbt_dynar_t dynar); +msg_process_t MSG_process_create(const char *name, xbt_main_func_t code, + void *data, msg_host_t host); +~~~~ + +Note that it may avoid bugs later to avoid launching a worker on +the master host so you probably want to remove it from the host +list. + +The `data` field of the `MSG_process_create` can be used to pass +a channel name that will be private between master +and workers (e.g., `master_name:worker_name`). Adding the +`master_name` in the channel name will allow to easily have several +masters and a worker per master on each machine. To this end, you +may need to use the following functions: + +~~~~{.c} +msg_host_t MSG_host_self(void); +const char * MSG_host_get_name(msg_host_t host); +msg_process_t MSG_process_self(void); +void * MSG_process_get_data(msg_process_t process); +~~~~ + +Again, you should check the [online documentation](http://simgrid.gforge.inria.fr/simgrid/3.8.1/ref_guide/html/index.html) +for more information. If you are not too much familiar with string +manipulation in C, you may want to use the following functions + +~~~~{.c} +char *strcpy(char *dest, const char *src); +char *strcat(char *dest, const char *src); +~~~~ + +## Setting up a Time Limit Mechanism + +In the current version, the number of tasks is defined in the +worker arguments. Hence, tasks are created at the very beginning of +the simulation. Instead, create tasks as needed and provide a time +limit indicating when it stops sending tasks. To this end, you will +obviously need to know what time it is[fn:7]: + +~~~~{.c} +double MSG_get_clock(void); +~~~~ + +Otherwise, a quite effective way of terminating the simulation +would be to use some of the following function[fn:7]: + +~~~~{.c} +void MSG_process_kill(msg_process_t process); +int MSG_process_killall(int reset_PIDs); +~~~~ + +Anyway, the new deployment `deployment2.xml` file should thus look +like this: + +~~~~{.xml} + + + + + + + + + +~~~~ + +It may also be a good idea to transform most of the `XBT_INFO` into +`XBT_DEBUG` (e.g., keep the information on the total number of +tasks processed). These debug messages can be activated as follows: + +~~~~{.sh} +./masterworker2 platforms/platform.xml deployment2.xml --log=msg_test.thres:debug +~~~~ + +## Using the Tracing Mechanism + +SimGrid can trace all resource consumption and the outcome can be +displayed with viva as illustrated [[*Setting%20up%20and%20Compiling.][here]]. However, when several +masters are deployed, it is hard to understand what happens. + +~~~~{.xml} + + + + + + + + + + + + + + + + + + + +~~~~ + +So let's use categories to track more precisely who does what and +when[fn:7]. + +~~~~{.c} +void TRACE_category(const char *category); +void MSG_task_set_category (msg_task_t task, const char *category); +~~~~ + +The outcome can then be visualized as follows: + +~~~~{.sh} +./masterworker3 platforms/platform.xml deployment3.xml --cfg=tracing:1\ + --cfg=tracing/categorized:1 --cfg=viva/categorized:viva_cat.plist +LANG=C; viva simgrid.trace viva_cat.plist +~~~~ + +Right now, you should realize that nothing is behaving like you +expect. Most workers are idle even though input data are ridiculous +and there are several masters deployed on the platform. Using a +Gantt-chart visualization may help: + +~~~~{.sh} +./masterworker3 platforms/platform.xml deployment3.xml --cfg=tracing:1 \ + --cfg=tracing/msg/process:1 +LANG=C; Paje simgrid.trace +~~~~ + +OK, so it should now be obvious that round robin is actually +very bad. + +## Improving the Scheduling + +Instead of a round-robin scheduling, let's implement a first-come +first-served mechanism. To this end, workers need to send a tiny +request first. A possible way to implement such a request with MSG +is to send on a specific channel (e.g., the name of the master +name) a task with payload 0 and whose attached data is the worker +name. This way, the master can keep track of which workers are idle +and willing to work. + +To know whether it has pending requests, the master can use the +following function[fn:7]: + +~~~~{.c} +int MSG_task_listen(const char *alias); +~~~~ + +If so, it should get the request and push the corresponding host +into a dynar so that they can later be retrieved when sending a +real task[fn:7]. + +~~~~{.c} +xbt_dynar_t xbt_dynar_new(const unsigned long elm_size, + void_f_pvoid_t const free_f); +void xbt_dynar_push(xbt_dynar_t const dynar, const void *src); +void xbt_dynar_shift(xbt_dynar_t const dynar, void *const dst); +unsigned long xbt_dynar_length(const xbt_dynar_t dynar); +~~~~ + +As you will soon realize, with such simple mechanisms, simple +deadlocks will soon appear. They can easily be removed with a +simple polling mechanism, hence the need for the following +function[fn:7]: + +~~~~{.c} +msg_error_t MSG_process_sleep(double nb_sec); +~~~~ + +As you should quickly realize, on the simple previous example, it +will double the throughput of the platform but will be quite +ineffective when input size of the tasks is not negligible anymore. + +From this, many things can easily be added. For example, you could: +- add a performance measurement mechanism; +- enable the master to make smart scheduling choices using + measurement information; +- allow workers to have several pending requests so as to overlap + communication and computations as much as possible; +- ... + +## Using More Elaborate Platforms + +SimGrid offers a rather powerful platform modeling mechanism. The +`src/platform/` repository comprises a variety of platform ranging +from simple ones to quite elaborated ones. Associated to a good +visualization tool to ensure your simulation is meaningful, they +can allow you to study to which extent your algorithm scales... + +What is the largest number of tasks requiring 50e6 flops and 1e5 +bytes that you manage to distribute and process in one hour on +`g5k.xml` (you should use `deployment_general.xml`)? + +# Points to improve for the next time + +- Propose equivalent exercises and skeleton in java. +- Propose a virtualbox image with everything (simgrid, paje, viva, + ...) already set up. +- Ease the installation on mac OS X (binary installer) and + windows. +- Explain that programming in C or java and having a working + development environment is a prerequisite. + +[fn:1]: http://triva.gforge.inria.fr/index.html +[fn:2]: http://hal.inria.fr/inria-00529569 +[fn:3]: http://hal.inria.fr/hal-00738321 +[fn:4]: http://simgrid.gforge.inria.fr/documentation.html +[fn:5]: http://paje.sourceforge.net/ +[fn:6]: http://vite.gforge.inria.fr/ +[fn:7]: http://simgrid.gforge.inria.fr/simgrid/3.8.1/ref_guide/html/index.html + + + + + +*/ diff --git a/doc/msg-tuto-src/deployment0.xml b/doc/msg-tuto-src/deployment0.xml new file mode 100644 index 0000000000..6d7bae7db8 --- /dev/null +++ b/doc/msg-tuto-src/deployment0.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/msg-tuto-src/deployment1.xml b/doc/msg-tuto-src/deployment1.xml new file mode 100644 index 0000000000..5d8fae4b67 --- /dev/null +++ b/doc/msg-tuto-src/deployment1.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/doc/msg-tuto-src/deployment2.xml b/doc/msg-tuto-src/deployment2.xml new file mode 100644 index 0000000000..fce6c1bc27 --- /dev/null +++ b/doc/msg-tuto-src/deployment2.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/doc/msg-tuto-src/deployment3.xml b/doc/msg-tuto-src/deployment3.xml new file mode 100644 index 0000000000..52ca7213d0 --- /dev/null +++ b/doc/msg-tuto-src/deployment3.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/doc/msg-tuto-src/deployment_general.xml b/doc/msg-tuto-src/deployment_general.xml new file mode 100644 index 0000000000..0f9c44b3a2 --- /dev/null +++ b/doc/msg-tuto-src/deployment_general.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/doc/msg-tuto-src/masterworker0.c b/doc/msg-tuto-src/masterworker0.c new file mode 100644 index 0000000000..519d031281 --- /dev/null +++ b/doc/msg-tuto-src/masterworker0.c @@ -0,0 +1,157 @@ +/* Copyright (c) 2007, 2008, 2009, 2010. 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 +#include "msg/msg.h" /* Yeah! If you want to use msg, you need to include msg/msg.h */ +#include "xbt/sysdep.h" /* calloc, printf */ + +/* Create a log channel to have nice outputs. */ +#include "xbt/log.h" +#include "xbt/asserts.h" +XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, + "Messages specific for this msg example"); + +int master(int argc, char *argv[]); +int worker(int argc, char *argv[]); +msg_error_t test_all(const char *platform_file, + const char *application_file); + +#define FINALIZE ((void*)221297) /* a magic number to tell people to stop working */ + +/** Emitter function */ +int master(int argc, char *argv[]) +{ + int workers_count = 0; + msg_host_t *workers = NULL; + msg_task_t *todo = NULL; + int number_of_tasks = 0; + double task_comp_size = 0; + double task_comm_size = 0; + + int i; + + _XBT_GNUC_UNUSED int res = sscanf(argv[1], "%d", &number_of_tasks); + xbt_assert(res,"Invalid argument %s\n", argv[1]); + 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]); + + { /* Task creation */ + char sprintf_buffer[64]; + + todo = xbt_new0(msg_task_t, number_of_tasks); + + for (i = 0; i < number_of_tasks; i++) { + sprintf(sprintf_buffer, "Task_%d", i); + todo[i] = + MSG_task_create(sprintf_buffer, task_comp_size, task_comm_size, + NULL); + } + } + + { /* Process organisation */ + workers_count = argc - 4; + workers = xbt_new0(msg_host_t, workers_count); + + for (i = 4; i < argc; i++) { + workers[i - 4] = MSG_get_host_by_name(argv[i]); + xbt_assert(workers[i - 4] != NULL, "Unknown host %s. Stopping Now! ", + argv[i]); + } + } + + XBT_INFO("Got %d workers and %d tasks to process", workers_count, + number_of_tasks); + + for (i = 0; i < number_of_tasks; i++) { + XBT_INFO("Sending \"%s\" to \"%s\"", + todo[i]->name, MSG_host_get_name(workers[i % workers_count])); + if (MSG_host_self() == workers[i % workers_count]) { + XBT_INFO("Hey ! It's me ! :)"); + } + + MSG_task_send(todo[i], MSG_host_get_name(workers[i % workers_count])); + XBT_INFO("Sent"); + } + + XBT_INFO + ("All tasks have been dispatched. Let's tell everybody the computation is over."); + for (i = 0; i < workers_count; i++) { + msg_task_t finalize = MSG_task_create("finalize", 0, 0, FINALIZE); + MSG_task_send(finalize, MSG_host_get_name(workers[i])); + } + + XBT_INFO("Goodbye now!"); + free(workers); + free(todo); + return 0; +} /* end_of_master */ + +/** Receiver function */ +int worker(int argc, char *argv[]) +{ + msg_task_t task = NULL; + _XBT_GNUC_UNUSED int res; + while (1) { + res = MSG_task_receive(&(task),MSG_host_get_name(MSG_host_self())); + xbt_assert(res == MSG_OK, "MSG_task_receive 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_worker */ + +/** Test function */ +msg_error_t test_all(const char *platform_file, + const char *application_file) +{ + msg_error_t res = MSG_OK; + + { /* Simulation setting */ + MSG_create_environment(platform_file); + } + { /* Application deployment */ + MSG_function_register("master", master); + MSG_function_register("worker", worker); + MSG_launch_application(application_file); + } + res = MSG_main(); + + XBT_INFO("Simulation time %g", MSG_get_clock()); + return res; +} /* end_of_test_all */ + + +/** Main function */ +int main(int argc, char *argv[]) +{ + msg_error_t res = MSG_OK; + + MSG_init(&argc, 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]); + + if (res == MSG_OK) + return 0; + else + return 1; +} /* end_of_main */ diff --git a/doc/msg-tuto-src/masterworker1.c b/doc/msg-tuto-src/masterworker1.c new file mode 100644 index 0000000000..eb9123241a --- /dev/null +++ b/doc/msg-tuto-src/masterworker1.c @@ -0,0 +1,179 @@ +/* Copyright (c) 2007, 2008, 2009, 2010. 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 +#include "msg/msg.h" /* Yeah! If you want to use msg, you need to include msg/msg.h */ +#include "xbt/sysdep.h" /* calloc, printf */ + +/* Create a log channel to have nice outputs. */ +#include "xbt/log.h" +#include "xbt/asserts.h" +XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, + "Messages specific for this msg example"); + +int master(int argc, char *argv[]); +int worker(int argc, char *argv[]); +msg_error_t test_all(const char *platform_file, + const char *application_file); + +#define FINALIZE ((void*)221297) /* a magic number to tell people to stop working */ + +static char * build_channel_name(char *buffer, const char *sender, const char* receiver) +{ + strcpy(buffer, sender); + strcat(buffer, ":"); + strcat(buffer, receiver); + return buffer; +} + +/** Emitter function */ +int master(int argc, char *argv[]) +{ + int workers_count = 0; + msg_host_t *workers = NULL; + msg_task_t *todo = NULL; + msg_host_t host_self = MSG_host_self(); + char *master_name = (char *) MSG_host_get_name(host_self); + int number_of_tasks = 0; + double task_comp_size = 0; + double task_comm_size = 0; + char channel[1024]; + + int i; + + _XBT_GNUC_UNUSED int res = sscanf(argv[1], "%d", &number_of_tasks); + xbt_assert(res,"Invalid argument %s\n", argv[1]); + 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]); + + { /* Task creation */ + char sprintf_buffer[64]; + + todo = xbt_new0(msg_task_t, number_of_tasks); + + for (i = 0; i < number_of_tasks; i++) { + sprintf(sprintf_buffer, "Task_%d", i); + todo[i] = + MSG_task_create(sprintf_buffer, task_comp_size, task_comm_size, + NULL); + } + } + + { /* Process organisation */ + workers_count = MSG_get_host_number(); + workers = xbt_dynar_to_array(MSG_hosts_as_dynar()); + + for (i = 0; i < workers_count; i++) + if(host_self == workers[i]) { + workers[i] = workers[workers_count-1]; + workers_count--; + break; + } + + for (i = 0; i < workers_count; i++) + MSG_process_create("worker", worker, master_name, workers[i]); + } + + XBT_INFO("Got %d workers and %d tasks to process", workers_count, + number_of_tasks); + + for (i = 0; i < number_of_tasks; i++) { + build_channel_name(channel,master_name, + MSG_host_get_name(workers[i % workers_count])); + + XBT_INFO("Sending \"%s\" to channel \"%s\"", todo[i]->name, channel); + + MSG_task_send(todo[i], channel); + XBT_INFO("Sent"); + } + + XBT_INFO + ("All tasks have been dispatched. Let's tell everybody the computation is over."); + for (i = 0; i < workers_count; i++) { + msg_task_t finalize = MSG_task_create("finalize", 0, 0, FINALIZE); + MSG_task_send(finalize, build_channel_name(channel,master_name, + MSG_host_get_name(workers[i % workers_count]))); + } + + XBT_INFO("Goodbye now!"); + free(workers); + free(todo); + return 0; +} /* end_of_master */ + +/** Receiver function */ +int worker(int argc, char *argv[]) +{ + msg_task_t task = NULL; + _XBT_GNUC_UNUSED int res; + char channel[1024]; + + build_channel_name(channel,MSG_process_get_data(MSG_process_self()), + MSG_host_get_name(MSG_host_self())); + + XBT_INFO("Receiving on channel \"%s\"", channel); + + while (1) { + res = MSG_task_receive(&(task),channel); + xbt_assert(res == MSG_OK, "MSG_task_receive 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_worker */ + +/** Test function */ +msg_error_t test_all(const char *platform_file, + const char *application_file) +{ + msg_error_t res = MSG_OK; + + { /* Simulation setting */ + MSG_create_environment(platform_file); + } + { /* Application deployment */ + MSG_function_register("master", master); + MSG_function_register("worker", worker); + MSG_launch_application(application_file); + } + res = MSG_main(); + + XBT_INFO("Simulation time %g", MSG_get_clock()); + return res; +} /* end_of_test_all */ + + +/** Main function */ +int main(int argc, char *argv[]) +{ + msg_error_t res = MSG_OK; + + MSG_init(&argc, 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]); + + if (res == MSG_OK) + return 0; + else + return 1; +} /* end_of_main */ diff --git a/doc/msg-tuto-src/masterworker2.c b/doc/msg-tuto-src/masterworker2.c new file mode 100644 index 0000000000..f86a47dcb9 --- /dev/null +++ b/doc/msg-tuto-src/masterworker2.c @@ -0,0 +1,176 @@ +/* Copyright (c) 2007, 2008, 2009, 2010. 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 +#include "msg/msg.h" /* Yeah! If you want to use msg, you need to include msg/msg.h */ +#include "xbt/sysdep.h" /* calloc, printf */ + +/* Create a log channel to have nice outputs. */ +#include "xbt/log.h" +#include "xbt/asserts.h" +XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, + "Messages specific for this msg example"); + +int master(int argc, char *argv[]); +int worker(int argc, char *argv[]); +msg_error_t test_all(const char *platform_file, + const char *application_file); + +#define FINALIZE ((void*)221297) /* a magic number to tell people to stop working */ + +static char * build_channel_name(char *buffer, const char *sender, const char* receiver) +{ + strcpy(buffer, sender); + strcat(buffer, ":"); + strcat(buffer, receiver); + return buffer; +} + +/** Emitter function */ +int master(int argc, char *argv[]) +{ + int workers_count = 0; + msg_host_t *workers = NULL; + msg_task_t *todo = NULL; + msg_host_t host_self = MSG_host_self(); + char *master_name = (char *) MSG_host_get_name(host_self); + double task_comp_size = 0; + double task_comm_size = 0; + char channel[1024]; + double timeout = -1; + + int i; + + _XBT_GNUC_UNUSED int res = sscanf(argv[1], "%lg", &timeout); + xbt_assert(res,"Invalid argument %s\n", argv[1]); + 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]); + + { /* Process organisation */ + workers_count = MSG_get_host_number(); + workers = xbt_dynar_to_array(MSG_hosts_as_dynar()); + + for (i = 0; i < workers_count; i++) + if(host_self == workers[i]) { + workers[i] = workers[workers_count-1]; + workers_count--; + break; + } + + for (i = 0; i < workers_count; i++) + MSG_process_create("worker", worker, master_name, workers[i]); + } + + XBT_INFO("Got %d workers and will send tasks for %g seconds!", + workers_count, timeout); + + for (i = 0; 1; i++) { + char sprintf_buffer[64]; + msg_task_t task = NULL; + + if(MSG_get_clock()>timeout) break; + + sprintf(sprintf_buffer, "Task_%d", i); + task = MSG_task_create(sprintf_buffer, task_comp_size, task_comm_size, + NULL); + + build_channel_name(channel,master_name, + MSG_host_get_name(workers[i % workers_count])); + + XBT_DEBUG("Sending \"%s\" to channel \"%s\"", task->name, channel); + MSG_task_send(task, channel); + XBT_DEBUG("Sent"); + } + + int task_num = i; + + XBT_DEBUG + ("All tasks have been dispatched. Let's tell everybody the computation is over."); + for (i = 0; i < workers_count; i++) { + msg_task_t finalize = MSG_task_create("finalize", 0, 0, FINALIZE); + MSG_task_send(finalize, build_channel_name(channel,master_name, + MSG_host_get_name(workers[i % workers_count]))); + } + + XBT_INFO("Sent %d tasks in total!", task_num); + free(workers); + free(todo); + return 0; +} /* end_of_master */ + +/** Receiver function */ +int worker(int argc, char *argv[]) +{ + msg_task_t task = NULL; + _XBT_GNUC_UNUSED int res; + char channel[1024]; + + build_channel_name(channel,MSG_process_get_data(MSG_process_self()), + MSG_host_get_name(MSG_host_self())); + + XBT_DEBUG("Receiving on channel \"%s\"", channel); + + while (1) { + res = MSG_task_receive(&(task),channel); + xbt_assert(res == MSG_OK, "MSG_task_receive failed"); + + XBT_DEBUG("Received \"%s\"", MSG_task_get_name(task)); + if (!strcmp(MSG_task_get_name(task), "finalize")) { + MSG_task_destroy(task); + break; + } + + XBT_DEBUG("Processing \"%s\"", MSG_task_get_name(task)); + MSG_task_execute(task); + XBT_DEBUG("\"%s\" done", MSG_task_get_name(task)); + MSG_task_destroy(task); + task = NULL; + } + XBT_DEBUG("I'm done. See you!"); + return 0; +} /* end_of_worker */ + +/** Test function */ +msg_error_t test_all(const char *platform_file, + const char *application_file) +{ + msg_error_t res = MSG_OK; + + { /* Simulation setting */ + MSG_create_environment(platform_file); + } + { /* Application deployment */ + MSG_function_register("master", master); + MSG_function_register("worker", worker); + MSG_launch_application(application_file); + } + res = MSG_main(); + + XBT_INFO("Simulation time %g", MSG_get_clock()); + return res; +} /* end_of_test_all */ + + +/** Main function */ +int main(int argc, char *argv[]) +{ + msg_error_t res = MSG_OK; + + MSG_init(&argc, 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]); + + if (res == MSG_OK) + return 0; + else + return 1; +} /* end_of_main */ diff --git a/doc/msg-tuto-src/masterworker3.c b/doc/msg-tuto-src/masterworker3.c new file mode 100644 index 0000000000..ca2bee393c --- /dev/null +++ b/doc/msg-tuto-src/masterworker3.c @@ -0,0 +1,179 @@ +/* Copyright (c) 2007, 2008, 2009, 2010. 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 +#include "msg/msg.h" /* Yeah! If you want to use msg, you need to include msg/msg.h */ +#include "xbt/sysdep.h" /* calloc, printf */ + +/* Create a log channel to have nice outputs. */ +#include "xbt/log.h" +#include "xbt/asserts.h" +XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, + "Messages specific for this msg example"); + +int master(int argc, char *argv[]); +int worker(int argc, char *argv[]); +msg_error_t test_all(const char *platform_file, + const char *application_file); + +#define FINALIZE ((void*)221297) /* a magic number to tell people to stop working */ + +static char * build_channel_name(char *buffer, const char *sender, const char* receiver) +{ + strcpy(buffer, sender); + strcat(buffer, ":"); + strcat(buffer, receiver); + return buffer; +} + +/** Emitter function */ +int master(int argc, char *argv[]) +{ + int workers_count = 0; + msg_host_t *workers = NULL; + msg_task_t *todo = NULL; + msg_host_t host_self = MSG_host_self(); + char *master_name = (char *) MSG_host_get_name(host_self); + double task_comp_size = 0; + double task_comm_size = 0; + char channel[1024]; + double timeout = -1; + + int i; + + TRACE_category(master_name); + + _XBT_GNUC_UNUSED int res = sscanf(argv[1], "%lg", &timeout); + xbt_assert(res,"Invalid argument %s\n", argv[1]); + 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]); + + { /* Process organisation */ + workers_count = MSG_get_host_number(); + workers = xbt_dynar_to_array(MSG_hosts_as_dynar()); + + for (i = 0; i < workers_count; i++) + if(host_self == workers[i]) { + workers[i] = workers[workers_count-1]; + workers_count--; + break; + } + + for (i = 0; i < workers_count; i++) + MSG_process_create("worker", worker, master_name, workers[i]); + } + + XBT_INFO("Got %d workers and will send tasks for %g seconds!", + workers_count, timeout); + + for (i = 0; 1; i++) { + char sprintf_buffer[64]; + msg_task_t task = NULL; + + if(MSG_get_clock()>timeout) break; + + sprintf(sprintf_buffer, "Task_%d", i); + task = MSG_task_create(sprintf_buffer, task_comp_size, task_comm_size, + NULL); + MSG_task_set_category(task, master_name); + + build_channel_name(channel,master_name, + MSG_host_get_name(workers[i % workers_count])); + + XBT_DEBUG("Sending \"%s\" to channel \"%s\"", task->name, channel); + MSG_task_send(task, channel); + XBT_DEBUG("Sent"); + } + + int task_num = i; + + XBT_DEBUG + ("All tasks have been dispatched. Let's tell everybody the computation is over."); + for (i = 0; i < workers_count; i++) { + msg_task_t finalize = MSG_task_create("finalize", 0, 0, FINALIZE); + MSG_task_send(finalize, build_channel_name(channel,master_name, + MSG_host_get_name(workers[i % workers_count]))); + } + + XBT_INFO("Sent %d tasks in total!", task_num); + free(workers); + free(todo); + return 0; +} /* end_of_master */ + +/** Receiver function */ +int worker(int argc, char *argv[]) +{ + msg_task_t task = NULL; + _XBT_GNUC_UNUSED int res; + char channel[1024]; + + build_channel_name(channel,MSG_process_get_data(MSG_process_self()), + MSG_host_get_name(MSG_host_self())); + + XBT_DEBUG("Receiving on channel \"%s\"", channel); + + while (1) { + res = MSG_task_receive(&(task),channel); + xbt_assert(res == MSG_OK, "MSG_task_get failed"); + + XBT_DEBUG("Received \"%s\"", MSG_task_get_name(task)); + if (!strcmp(MSG_task_get_name(task), "finalize")) { + MSG_task_destroy(task); + break; + } + + XBT_DEBUG("Processing \"%s\"", MSG_task_get_name(task)); + MSG_task_execute(task); + XBT_DEBUG("\"%s\" done", MSG_task_get_name(task)); + MSG_task_destroy(task); + task = NULL; + } + XBT_DEBUG("I'm done. See you!"); + return 0; +} /* end_of_worker */ + +/** Test function */ +msg_error_t test_all(const char *platform_file, + const char *application_file) +{ + msg_error_t res = MSG_OK; + + { /* Simulation setting */ + MSG_create_environment(platform_file); + } + { /* Application deployment */ + MSG_function_register("master", master); + MSG_function_register("worker", worker); + MSG_launch_application(application_file); + } + res = MSG_main(); + + XBT_INFO("Simulation time %g", MSG_get_clock()); + return res; +} /* end_of_test_all */ + + +/** Main function */ +int main(int argc, char *argv[]) +{ + msg_error_t res = MSG_OK; + + MSG_init(&argc, 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]); + + if (res == MSG_OK) + return 0; + else + return 1; +} /* end_of_main */ diff --git a/doc/msg-tuto-src/masterworker4.c b/doc/msg-tuto-src/masterworker4.c new file mode 100644 index 0000000000..24456d6258 --- /dev/null +++ b/doc/msg-tuto-src/masterworker4.c @@ -0,0 +1,209 @@ +/* Copyright (c) 2007, 2008, 2009, 2010. 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 +#include "msg/msg.h" /* Yeah! If you want to use msg, you need to include msg/msg.h */ +#include "xbt/sysdep.h" /* calloc, printf */ + +/* Create a log channel to have nice outputs. */ +#include "xbt/log.h" +#include "xbt/asserts.h" +XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, + "Messages specific for this msg example"); + +int master(int argc, char *argv[]); +int worker(int argc, char *argv[]); +msg_error_t test_all(const char *platform_file, + const char *application_file); + +#define FINALIZE ((void*)221297) /* a magic number to tell people to stop working */ + +static char * build_channel_name(char *buffer, const char *sender, const char* receiver) +{ + strcpy(buffer, sender); + strcat(buffer, ":"); + strcat(buffer, receiver); + return buffer; +} + +/** Emitter function */ +int master(int argc, char *argv[]) +{ + int workers_count = 0; + msg_host_t *workers = NULL; + msg_task_t *todo = NULL; + msg_host_t host_self = MSG_host_self(); + char *master_name = (char *) MSG_host_get_name(host_self); + double task_comp_size = 0; + double task_comm_size = 0; + char channel[1024]; + double timeout = -1; + + int i; + + TRACE_category(master_name); + + _XBT_GNUC_UNUSED int res = sscanf(argv[1], "%lg", &timeout); + xbt_assert(res,"Invalid argument %s\n", argv[1]); + 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]); + + { /* Process organisation */ + workers_count = MSG_get_host_number(); + workers = xbt_dynar_to_array(MSG_hosts_as_dynar()); + + for (i = 0; i < workers_count; i++) + if(host_self == workers[i]) { + workers[i] = workers[workers_count-1]; + workers_count--; + break; + } + + for (i = 0; i < workers_count; i++) + MSG_process_create("worker", worker, master_name, workers[i]); + } + + XBT_INFO("Got %d workers and will send tasks for %g seconds!", + workers_count, timeout); + xbt_dynar_t idle_hosts = xbt_dynar_new(sizeof(msg_host_t), NULL); + msg_host_t request_host = NULL; + + for (i = 0; 1;) { + char sprintf_buffer[64]; + msg_task_t task = NULL; + + msg_task_t request = NULL; + while(MSG_task_listen(master_name)) { + res = MSG_task_receive(&(request),master_name); + xbt_assert(res == MSG_OK, "MSG_task_receive failed"); + request_host = MSG_task_get_data(request); + xbt_dynar_push(idle_hosts, &request_host); + MSG_task_destroy(request); + request = NULL; + } + + if(MSG_get_clock()>timeout) { + if(xbt_dynar_length(idle_hosts) == workers_count) break; + else { + MSG_process_sleep(.1); + continue; + } + } + + if(xbt_dynar_length(idle_hosts)<=0) { + /* No request. Let's wait... */ + MSG_process_sleep(.1); + continue; + } + + sprintf(sprintf_buffer, "Task_%d", i); + task = MSG_task_create(sprintf_buffer, task_comp_size, task_comm_size, + NULL); + MSG_task_set_category(task, master_name); + + xbt_dynar_shift(idle_hosts, &request_host); + + build_channel_name(channel,master_name, MSG_host_get_name(request_host)); + + XBT_DEBUG("Sending \"%s\" to channel \"%s\"", task->name, channel); + MSG_task_send(task, channel); + XBT_DEBUG("Sent"); + i++; + } + + int task_num = i; + + XBT_DEBUG + ("All tasks have been dispatched. Let's tell everybody the computation is over."); + for (i = 0; i < workers_count; i++) { + msg_task_t finalize = MSG_task_create("finalize", 0, 0, FINALIZE); + MSG_task_send(finalize, build_channel_name(channel,master_name, + MSG_host_get_name(workers[i % workers_count]))); + } + + XBT_INFO("Sent %d tasks in total!", task_num); + free(workers); + free(todo); + return 0; +} /* end_of_master */ + +/** Receiver function */ +int worker(int argc, char *argv[]) +{ + msg_task_t task = NULL; + _XBT_GNUC_UNUSED int res; + char channel[1024]; + + const char *my_master = MSG_process_get_data(MSG_process_self()); + build_channel_name(channel, my_master, MSG_host_get_name(MSG_host_self())); + + XBT_DEBUG("Receiving on channel \"%s\"", channel); + + while (1) { + /* Send a request */ + msg_task_t request = MSG_task_create("request", 0, 0, MSG_host_self()); + MSG_task_send(request, my_master); + + res = MSG_task_receive(&(task),channel); + xbt_assert(res == MSG_OK, "MSG_task_receive failed"); + + XBT_DEBUG("Received \"%s\"", MSG_task_get_name(task)); + if (!strcmp(MSG_task_get_name(task), "finalize")) { + MSG_task_destroy(task); + break; + } + + XBT_DEBUG("Processing \"%s\"", MSG_task_get_name(task)); + MSG_task_execute(task); + XBT_DEBUG("\"%s\" done", MSG_task_get_name(task)); + MSG_task_destroy(task); + task = NULL; + } + XBT_DEBUG("I'm done. See you!"); + return 0; +} /* end_of_worker */ + +/** Test function */ +msg_error_t test_all(const char *platform_file, + const char *application_file) +{ + msg_error_t res = MSG_OK; + + { /* Simulation setting */ + MSG_create_environment(platform_file); + } + { /* Application deployment */ + MSG_function_register("master", master); + MSG_function_register("worker", worker); + MSG_launch_application(application_file); + } + res = MSG_main(); + + XBT_INFO("Simulation time %g", MSG_get_clock()); + return res; +} /* end_of_test_all */ + + +/** Main function */ +int main(int argc, char *argv[]) +{ + msg_error_t res = MSG_OK; + + MSG_init(&argc, 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]); + + if (res == MSG_OK) + return 0; + else + return 1; +} /* end_of_main */ diff --git a/doc/msg-tuto-src/platforms/cloud.xml b/doc/msg-tuto-src/platforms/cloud.xml new file mode 100644 index 0000000000..df5a88231c --- /dev/null +++ b/doc/msg-tuto-src/platforms/cloud.xml @@ -0,0 +1,158 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/msg-tuto-src/platforms/g5k.xml b/doc/msg-tuto-src/platforms/g5k.xml new file mode 100644 index 0000000000..9d20e6c973 --- /dev/null +++ b/doc/msg-tuto-src/platforms/g5k.xml @@ -0,0 +1,565 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/msg-tuto-src/platforms/griffon.xml b/doc/msg-tuto-src/platforms/griffon.xml new file mode 100644 index 0000000000..1ecc49831a --- /dev/null +++ b/doc/msg-tuto-src/platforms/griffon.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/msg-tuto-src/platforms/peers.xml b/doc/msg-tuto-src/platforms/peers.xml new file mode 100644 index 0000000000..5158ac2ba3 --- /dev/null +++ b/doc/msg-tuto-src/platforms/peers.xml @@ -0,0 +1,7510 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/msg-tuto-src/platforms/platform.xml b/doc/msg-tuto-src/platforms/platform.xml new file mode 100644 index 0000000000..81a1d91fa3 --- /dev/null +++ b/doc/msg-tuto-src/platforms/platform.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/sc3-description.png b/doc/sc3-description.png new file mode 100644 index 0000000000..0f6aed680b Binary files /dev/null and b/doc/sc3-description.png differ