examples/s4u/basic/s4u-basic_deployment
examples/s4u/basic/s4u-basic_function
examples/s4u/dht-chord/s4u-dht-chord
+examples/s4u/energy-link/s4u-energy-link
examples/s4u/io/s4u-io
examples/s4u/mutex/s4u-mutex
examples/s4u/plugin-hostload/s4u-plugin-hostload
else()
message(FATAL_ERROR
"The compiler ${CMAKE_CXX_COMPILER} (v${CMAKE_CXX_COMPILER_VERSION}) has no C++11 support. "
- "Please use a decent C++ compiler.")
+ "Please install a decent C++ compiler (remove CMakeCache.txt once it's installed).")
endif()
### And we need C11 standard, too
- Storage::getName() changed to return a std::string, use intead
Storage::getCname() to get a char*.
+ MSG
+ - Deprecate MSG_task_get_flops_amount(). Its semantic was weird:
+ before the start it returned the total amount of flops;
+ after it returned the ratio of remaining work. Split it:
+ MSG_task_get_initial_flops_amount() for first behavior
+ MSG_task_get_remaining_work_ratio() for the second one.
+ This fixes GitHub's #223 using PR #237. Thanks Michael Mercier.
+
XBT
- Define class simgrid::xbt::Path to manage file names.
- Removed unused functions:
- xbt/str.h: xbt_str_join()
- xbt/heap.h: use std::priority_queue or boost::heap instead
+ PLUGINS:
+ - New link_energy plugin for the consumption of the links.
+
XML
- Remove the undocumented/untested tag <include>
+ TRACE
+ - Remove viva specific tracing as the tool is no longer maintained
+
SimGrid (3.17) Released October 8 2017
The Drained Leaks release: (almost) no known leaks despite the tests.
means that SimGrid is developed by a vivid community of users and
developers. We hope that you will come and join us!
-SimGrid is the result of over 15 years of research from several
+SimGrid is the result of almost 20 years of research from several
groups, both in France and in the USA. It benefited of many funding
from various research instances, including the ANR, Inria, CNRS,
University of Lorraine, University of Hawai'i at Manoa, ENS Rennes and
- make -C org all sync
- git commit -a && git push
- Announce the release
+ - Document the tag on https://github.com/simgrid/simgrid/releases
- Mail the simgrid-user mailing list
- the NEWS chunk in the mail;
- the ChangeLog chunk as attachment
- Also mail some other lists (G5K users), with only the NEWS chunk
and the link to the download section
-- Release the debian package
+- Release the debian package
+- Update the simgrid/package.py for spack: https://github.com/solverstack/spack
- Create the template for the next release in ChangeLog and NEWS files
- Change the release number in CMakeLists.txt
Here is a `CMakeLists.txt` that you can use as a starting point for
your project. It builds two simulators from a given set of source files.
+You first need to copy the `FindSimGrid.cmake` (at the root of the
+SimGrid tree) into the `cmake/Modules` directory of your project.
+
@verbatim
project(MyFirstScheduler)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
+find_package(SimGrid REQUIRED)
+include_directories(${SimGrid_INCLUDE_DIR})
+
set(SIMULATOR_SOURCES main.c other.c util.c)
add_executable(my_simulator ${SIMULATOR_SOURCES})
-target_link_libraries(my_simulator simgrid)
+target_link_libraries(my_simulator ${SimGrid_LIBRARY})
set(OTHER_SOURCES blah.c bar.c foo.h)
add_executable(other_xp ${OTHER_SOURCES})
-target_link_libraries(other_xp simgrid)
+target_link_libraries(other_xp ${SimGrid_LIBRARY})
@endverbatim
@section install_yours_makefile Building your project with Makefile
tracing/filename
</b>:
A file with this name will be created to register the simulation. The file
- is in the Paje format and can be analyzed using Viva or Paje visualization
+ is in the Paje format and can be analyzed using Paje visualization
tools. More information can be found in these webpages:
- <a href="http://github.com/schnorr/viva/">http://github.com/schnorr/viva/</a>
<a href="http://github.com/schnorr/pajeng/">http://github.com/schnorr/pajeng/</a>
\verbatim
--cfg=tracing/filename:mytracefile.trace
TODO
\endverbatim
-\li <b>\c
-viva/categorized
-</b>:
- This option generates a graph configuration file for Viva considering
- categorized resource utilization.
-\verbatim
---cfg=viva/categorized:graph_categorized.plist
-\endverbatim
-
-\li <b>\c
-viva/uncategorized
-</b>:
- This option generates a graph configuration file for Viva considering
- uncategorized resource utilization.
-\verbatim
---cfg=viva/uncategorized:graph_uncategorized.plist
-\endverbatim
-
Please pass \verbatim --help-tracing \endverbatim to your simulator
for the updated list of tracing options.
--cfg=tracing:yes \
--cfg=tracing/uncategorized:yes \
--cfg=tracing/filename:mytracefile.trace \
- --cfg=viva/uncategorized:uncat.plist
\endverbatim
\li I want to trace only a subset of my MSG (or SimDAG) tasks.
--cfg=tracing:yes \
--cfg=tracing/categorized:yes \
--cfg=tracing/filename:mytracefile.trace \
- --cfg=viva/categorized:cat.plist
\endverbatim
file format</a>. Consider this option if you need to understand the
causality of your distributed simulation.
-- Visualize the behavior of your simulation with treemaps (specially
- if your simulation has a platform with several thousand resources),
- provided by the <a href="http://github.com/schnorr/viva/">Viva</a>
- visualization tool. See <a
- href="https://github.com/schnorr/viva/wiki">Viva's wiki</a> for
- further details on what is a treemap and how to use it.
-
-- Correlate the behavior of your simulator with the platform topology
- with an interactive, force-directed, and hierarchical graph
- visualization, provided by <a
- href="http://github.com/schnorr/viva/">Viva</a>. Check <a
- href="https://github.com/schnorr/viva/wiki">Viva's wiki</a> for
- further details. This <a
- href="http://hal.inria.fr/hal-00738321/">research report</a>,
- published at ISPASS 2013, has a detailed description of this
- visualization technique.
-
- You can also check our online <a
href="http://simgrid.gforge.inria.fr/tutorials.html"> tutorial
section</a> that contains a dedicated tutorial with several
href="http://lists.gforge.inria.fr/pipermail/simgrid-user/">mailing
list archive</a> for old messages regarding tracing and analysis.
-\subsection tracing_viva_analysis Viva Visualization Tool
-
-This subsection describe some of the concepts regarding the <a
-href="http://github.com/schnorr/viva/">Viva Visualization Tool</a> and
-its relation with SimGrid traces. You should refer to Viva's website
-for further details on all its visualization techniques.
-
-\subsubsection tracing_viva_time_slice Time Slice
-
-The analysis of a trace file using the tool always takes into account
-the concept of the <em>time-slice</em>. This concept means that what
-is being visualized in the screen is always calculated considering a
-specific time frame, with its beggining and end timestamp. The
-time-slice is configured by the user and can be changed dynamically
-through the window called <em>Time Interval</em> that is opened
-whenever a trace file is being analyzed. Users are capable to select
-the beggining and size of the time slice.
-
-\subsubsection tracing_viva_graph Hierarchical Graph View
-
-As stated above (see section \ref tracing_tracing_analyzing), one
-possibility to analyze SimGrid traces is to use Viva's graph view with
-a graph configuration to customize the graph according to the
-traces. A valid graph configuration (we are using the non-XML <a
-href="http://en.wikipedia.org/wiki/Property_list">Property List
-Format</a> to describe the configuration) can be created for any
-SimGrid-based simulator using the
-<em>--cfg=viva/uncategorized:graph_uncategorized.plist</em> or
-<em>--cfg=viva/categorized:graph_categorized.plist</em> (if the
-simulator defines resource utilization categories) when executing the
-simulation.
-
-\subsubsection basic_conf Basic Graph Configuration
-
-The basic description of the configuration is as follows:
-\verbatim
-{
- node = (LINK, HOST, );
- edge = (HOST-LINK, LINK-HOST, LINK-LINK, );
-\endverbatim
-
-The nodes of the graph will be created based on the <i>node</i>
-parameter, which in this case is the different <em>"HOST"</em>s and
-<em>"LINK"</em>s of the platform used to simulate. The <i>edge</i>
-parameter indicates that the edges of the graph will be created based
-on the <em>"HOST-LINK"</em>s, <em>"LINK-HOST"</em>s, and
-<em>"LINK-LINK"</em>s of the platform. After the definition of these
-two parameters, the configuration must detail how the nodes
-(<em>HOST</em>s and <em>LINK</em>s) should be drawn.
-
-For that, the configuration must have an entry for each of
-the types used. For <em>HOST</em>, as basic configuration, we have:
-
-\verbatim
- HOST = {
- type = square;
- size = power;
- values = (power_used);
- };
-\endverbatim
-
-The parameter <em>size</em> indicates which variable from the trace
-file will be used to define the size of the node HOST in the
-visualization. If the simulation was executed with availability
-traces, the size of the nodes will be changed according to these
-traces. The parameter <em>type</em> indicates which geometrical shape
-will be used to represent HOST, and the <em>values</em> parameter
-indicates which values from the trace will be used to fill the shape.
-
-For <em>LINK</em> we have:
-
-\verbatim
- LINK = {
- type = rhombus;
- size = bandwidth;
- values = (bandwidth_used);
- };
-}
-\endverbatim
-
-The same configuration parameters are used here: <em>type</em> (with a
-rhombus), the <em>size</em> (whose value is from trace's bandwidth
-variable) and the <em>values</em>.
-
-\subsubsection custom_graph Customizing the Graph Representation
-
-Viva is capable to handle a customized graph representation based on
-the variables present in the trace file. In the case of SimGrid, every
-time a category is created for tasks, two variables in the trace file
-are defined: one to indicate node utilization (how much power was used
-by that task category), and another to indicate link utilization (how
-much bandwidth was used by that category). For instance, if the user
-declares a category named <i>request</i>, there will be variables
-named <b>p</b><i>request</i> and a <b>b</b><i>request</i> (<b>p</b>
-for power and <b>b</b> for bandwidth). It is important to notice that
-the variable <i>prequest</i> in this case is only available for HOST,
-and <i>brequest</i> is only available for LINK. <b>Example</b>:
-suppose there are two categories for tasks: request and compute. To
-create a customized graph representation with a proportional
-separation of host and link utilization, use as configuration for HOST
-and LINK this:
-
-\verbatim
- HOST = {
- type = square;
- size = power;
- values = (prequest, pcomputation);
- };
- LINK = {
- type = rhombus;
- size = bandwidth;
- values = (brequest, bcomputation);
- };
-\endverbatim
-
-This configuration enables the analysis of resource utilization by MSG
-tasks through the identification of load-balancing issues and network
-bottlenecks, for instance.
-
*/
Several tools can be used to visualize the result of SimGrid
simulations and get a better understanding of simulations.
-- [viva][fn:1] will be useful to make fancy graph or treemap visualizations.
- [pajeng][fn:5] provides a Gantt-chart visualization.
- [Vite][fn:6] also provides a Gantt-chart visualization.
documentation of each software for more details.
~~~~{.sh}
-sudo apt-get install viva pajeng vite
+sudo apt-get install pajeng vite
~~~~
\section intro_start Let's get started
\c /opt/simgrid/bin/simgrid-colorizer. If you did not install it at all,
you can find it in <simgrid_root_directory>/bin/colorize.
-For a really fancy output, you should use [viva/triva][fn:1]:
-
-~~~~{.sh}
-./masterworker0 platforms/platform.xml deployment0.xml --cfg=tracing:yes \
- --cfg=tracing/uncategorized:yes --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:
+For a classical Gantt-Chart visualization, you can produce a [Paje][fn:5] trace:
~~~~{.sh}
./masterworker0 platforms/platform.xml deployment0.xml --cfg=tracing:yes \
## Using the Tracing Mechanism
SimGrid can trace all resource consumption and the outcome can be
-displayed with viva as illustrated in the section \ref intro_setup. However, when several
+displayed as illustrated in the section \ref intro_setup. However, when several
masters are deployed, it is hard to understand what happens.
~~~~{.xml}
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:yes\
- --cfg=tracing/categorized:yes --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:
+The outcome can then be visualized as a Gantt-chart as follows:
~~~~{.sh}
./masterworker3 platforms/platform.xml deployment3.xml --cfg=tracing:yes \
pajeng simgrid.trace
~~~~
-OK, so it should now be obvious that round robin is actually
-very bad.
+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. So it should now be obvious that round robin
+is actually very bad.
## Improving the Scheduling
\section intro_todo TODO: Points to improve for the next time
- Propose equivalent exercises and skeleton in java.
-- Propose a virtualbox image with everything (simgrid, pajeng, viva,
- ...) already set up.
+- Propose a virtualbox image with everything (simgrid, pajeng, ...) 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
\fB\-trace-resource\fR
Trace resource utilization.
.TP
-\fB\-trace-viva\fR
-Generate configuration for Viva's GraphView.
-.TP
\fB\-trace-file\fR <tracefile>
Name of the tracefile
/* initialize the MSG simulation. Must be done before anything else (even logging). */
Msg.init(args);
- String platf = args.length > 1 ? args[0] : "examples/java/platform.xml";
- String deploy = args.length > 1 ? args[1] : "examples/java/masterworker/masterworkerDeployment.xml";
+ String platf = args.length > 1 ? args[0] : "../platforms/small_platform.xml";
+ String deploy = args.length > 1 ? args[1] : "app/masterworker/masterworker.xml";
Msg.verb("Platform: "+platf+"; Deployment:"+deploy+"; Current directory: "+new File(".").getAbsolutePath());
public static void main(String[] args) {
Msg.init(args);
+ Msg.fileSystemInit();
if(args.length < 1) {
Msg.info("Usage : IO platform_file ");
Msg.info("example : IO ../platforms/storage/storage.xml ");
public static void main(String[] args) {
Msg.init(args);
+ Msg.fileSystemInit();
if(args.length < 1) {
Msg.info("Usage : Storage platform_file ");
Msg.info("example : Storage ../platforms/storage/storage.xml ");
Msg.init(args);
if(args.length < 2) {
Msg.info("Usage : Priority platform_file deployment_file");
- Msg.info("example : Priority ../platforms/platform.xml priorityDeployment.xml");
+ Msg.info("example : Priority ../platforms/small_platform.xml priority.xml");
System.exit(1);
}
to that are used to classify its tasks. When the program is executed,
the tracing mechanism registers the resource utilization of hosts
and links according to these categories. Recommanded options:
- @verbatim --cfg=tracing:yes --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes --cfg=viva/categorized:viva_cat.plist --cfg=viva/uncategorized:viva_uncat.plist
+ @verbatim --cfg=tracing:yes --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes
@endverbatim
- <b>Master Workers tracing</b>.
using several tracing features. It traces resource usage, sorted
out in several categories; Trace marks and user variables are also
used. Recommanded options:
- @verbatim --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes --cfg=viva/categorized:viva_cat.plist --cfg=viva/uncategorized:viva_uncat.plist
+ @verbatim --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes
@endverbatim
- <b>Process migration tracing</b>.
TODO: These tracing examples should be integrated in the examples to
not duplicate the C files. A full command line to see the result in
-the right tool (viva/vite/FrameSoc) should be given along with some
+the right tool (vite/FrameSoc) should be given along with some
screenshots.
@subsection msg_ex_tracing_user_variables Tracing user variables
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);
+ double task0_remain_prev = MSG_task_get_remaining_work_ratio(task0);
+ double task1_remain_prev = MSG_task_get_remaining_work_ratio(task1);
const double cpu_speed = MSG_host_get_speed(pm0);
for (int i = 0; i < 10; i++) {
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_remain_now = MSG_task_get_remaining_work_ratio(task0);
+ double task1_remain_now = MSG_task_get_remaining_work_ratio(task1);
double task0_flops_per_sec = task0_remain_prev - task0_remain_now;
double task1_flops_per_sec = task1_remain_prev - task1_remain_now;
while(MSG_get_clock()<100) {
if (atask != NULL)
- XBT_INFO("aTask remaining duration: %g", MSG_task_get_flops_amount(atask));
+ XBT_INFO("aTask remaining duration: %g", MSG_task_get_remaining_work_ratio(atask));
MSG_process_sleep(1);
}
// Run a task
start = MSG_get_clock();
msg_task_t task1 = MSG_task_create ("t1", 100E6, 0, NULL);
- XBT_INFO("Run a task of %.0E flops",MSG_task_get_flops_amount(task1));
+ XBT_INFO("Run a task of %.0E flops", MSG_task_get_initial_flops_amount(task1));
MSG_task_execute (task1);
MSG_task_destroy(task1);
XBT_INFO("Task done (duration: %.2f s). Current peak speed=%.0E flop/s; Current consumption: from %.0fW to %.0fW"
// Run a second task
start = MSG_get_clock();
task1 = MSG_task_create ("t2", 100E6, 0, NULL);
- XBT_INFO("Run a task of %.0E flops",MSG_task_get_flops_amount(task1));
+ XBT_INFO("Run a task of %.0E flops", MSG_task_get_initial_flops_amount(task1));
MSG_task_execute (task1);
MSG_task_destroy(task1);
XBT_INFO("Task done (duration: %.2f s). Current peak speed=%.0E flop/s; Energy dissipated=%.0f J",
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/msg.h"
+#include "simgrid/plugins/file_system.h"
XBT_LOG_NEW_DEFAULT_CATEGORY(io_file, "Messages specific for this io example");
int main(int argc, char **argv)
{
MSG_init(&argc, argv);
+ MSG_storage_file_system_init();
+
MSG_create_environment(argv[1]);
xbt_dynar_t hosts = MSG_hosts_as_dynar();
MSG_function_register("host", host);
$ ${bindir:=.}/io-file ${srcdir:=.}/storage/storage.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
> [ 0.000000] (0:maestro@) Number of host '4'
> [ 0.000000] (1:host@alice) Open file 'c:\Windows\setupact.log'
-> [ 0.000000] (2:host@bob) Open file '/home/doc/simgrid/examples/platforms/nancy.xml'
-> [ 0.000000] (3:host@carl) Open file '/home/doc/simgrid/examples/platforms/g5k_cabinets.xml'
> [ 0.000000] (1:host@alice) Capacity of the storage element 'c:\Windows\setupact.log' is stored on: 2391537133 / 536870912000
+> [ 0.000000] (2:host@bob) Open file '/home/doc/simgrid/examples/platforms/nancy.xml'
> [ 0.000000] (2:host@bob) Capacity of the storage element '/home/doc/simgrid/examples/platforms/nancy.xml' is stored on: 36933331 / 536870912000
+> [ 0.000000] (3:host@carl) Open file '/home/doc/simgrid/examples/platforms/g5k_cabinets.xml'
> [ 0.000000] (3:host@carl) Capacity of the storage element '/home/doc/simgrid/examples/platforms/g5k_cabinets.xml' is stored on: 36933331 / 536870912000
> [ 0.000000] (4:host@denise) File Descriptor information:
> Full path: '/home/doc/simgrid/examples/platforms/g5k.xml'
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/msg.h"
+#include "simgrid/plugins/file_system.h"
#define INMEGA (1024*1024)
msg_storage_t st;
MSG_init(&argc, argv);
+ MSG_storage_file_system_init();
+
MSG_create_environment(argv[1]);
MSG_function_register("host", host);
MSG_launch_application(argv[2]);
> [ 0.000000] (0@ ) Init: 12 MiB used on 'Disk1'
> [ 0.000000] (0@ ) Init: 2280 MiB used on 'Disk2'
> [ 0.000000] (1@alice) Opened file 'c:\Windows\setupact.log'
-> [ 0.000000] (2@ bob) Opened file '/scratch/lib/libsimgrid.so.3.6.2'
-> [ 0.000000] (3@ carl) Opened file '/scratch/lib/libsimgrid.so.3.6.2'
-> [ 0.000000] (4@ dave) Opened file 'c:\Windows\bootstat.dat'
> [ 0.000000] (1@alice) File Descriptor information:
> Full path: 'c:\Windows\setupact.log'
> Size: 101663
> Storage Id: 'Disk2'
> Storage Type: 'SATA-II_HDD'
> File Descriptor Id: 0
+> [ 0.000000] (1@alice) Try to read 101663 from 'c:\Windows\setupact.log'
+> [ 0.000000] (2@ bob) Opened file '/scratch/lib/libsimgrid.so.3.6.2'
> [ 0.000000] (2@ bob) File Descriptor information:
> Full path: '/scratch/lib/libsimgrid.so.3.6.2'
> Size: 12710497
> Storage Id: 'Disk1'
> Storage Type: 'SATA-II_HDD'
> File Descriptor Id: 0
+> [ 0.000000] (2@ bob) Try to read 12710497 from '/scratch/lib/libsimgrid.so.3.6.2'
+> [ 0.000000] (3@ carl) Opened file '/scratch/lib/libsimgrid.so.3.6.2'
> [ 0.000000] (3@ carl) File Descriptor information:
> Full path: '/scratch/lib/libsimgrid.so.3.6.2'
> Size: 12710497
> Storage Id: 'Disk1'
> Storage Type: 'SATA-II_HDD'
> File Descriptor Id: 0
+> [ 0.000000] (3@ carl) Try to read 12710497 from '/scratch/lib/libsimgrid.so.3.6.2'
+> [ 0.000000] (4@ dave) Opened file 'c:\Windows\bootstat.dat'
> [ 0.000000] (4@ dave) File Descriptor information:
> Full path: 'c:\Windows\bootstat.dat'
> Size: 67584
> Storage Id: 'Disk2'
> Storage Type: 'SATA-II_HDD'
> File Descriptor Id: 0
-> [ 0.000000] (1@alice) Try to read 101663 from 'c:\Windows\setupact.log'
-> [ 0.000000] (2@ bob) Try to read 12710497 from '/scratch/lib/libsimgrid.so.3.6.2'
-> [ 0.000000] (3@ carl) Try to read 12710497 from '/scratch/lib/libsimgrid.so.3.6.2'
> [ 0.000000] (4@ dave) Try to read 67584 from 'c:\Windows\bootstat.dat'
> [ 0.001469] (4@ dave) Have read 67584 from 'c:\Windows\bootstat.dat'. Offset is now at: 67584
> [ 0.001469] (4@ dave) Seek back to the begining of the stream...
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/msg.h"
+#include "simgrid/plugins/file_system.h"
XBT_LOG_NEW_DEFAULT_CATEGORY(storage,"Messages specific for this simulation");
int main(int argc, char *argv[])
{
MSG_init(&argc, argv);
+ MSG_storage_file_system_init();
+
MSG_create_environment(argv[1]);
MSG_function_register("host", host);
xbt_dynar_t hosts = MSG_hosts_as_dynar();
// Run a task
start = MSG_get_clock();
msg_task_t task1 = MSG_task_create("t1", 100E6, 0, NULL);
- XBT_INFO("Run a task of %.0E flops", MSG_task_get_flops_amount(task1));
+ XBT_INFO("Run a task of %.0E flops", MSG_task_get_initial_flops_amount(task1));
MSG_task_execute(task1);
MSG_task_destroy(task1);
// Run a second task
start = MSG_get_clock();
task1 = MSG_task_create("t2", 100E6, 0, NULL);
- XBT_INFO("Run a task of %.0E flops", MSG_task_get_flops_amount(task1));
+ XBT_INFO("Run a task of %.0E flops", MSG_task_get_initial_flops_amount(task1));
MSG_task_execute(task1);
MSG_task_destroy(task1);
XBT_INFO("Done working on my task; this took %.2fs; current peak speed: %.0E flop/s; number of flops computed so "
p Tracing multiple categories master/worker application
-$ $SG_TEST_EXENV ${bindir:=.}/trace-categories$EXEEXT --cfg=tracing:yes --cfg=tracing/buffer:yes --cfg=tracing/filename:categories.trace --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes --cfg=viva/categorized:categories.cat.plist --cfg=viva/uncategorized:categories.uncat.plist ${srcdir:=.}/small_platform.xml ${srcdir:=.}/../msg/app-masterworker/app-masterworker_d.xml
+$ $SG_TEST_EXENV ${bindir:=.}/trace-categories$EXEEXT --cfg=tracing:yes --cfg=tracing/buffer:yes --cfg=tracing/filename:categories.trace --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes ${srcdir:=.}/small_platform.xml ${srcdir:=.}/../msg/app-masterworker/app-masterworker_d.xml
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/buffer' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/filename' to 'categories.trace'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/categorized' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/uncategorized' to 'yes'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/categorized' to 'categories.cat.plist'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/uncategorized' to 'categories.uncat.plist'
-
-$ $SG_TEST_EXENV cat categories.cat.plist
-> node = ("LINK","HOST");
-> edge = ("0-LINK4-LINK4","0-LINK4-HOST1","0-HOST1-LINK4");
->
-> host = {
-> type = "square";
-> size = "power";
-> values = ("pcompute","pdata","pfinalize","prequest");
-> };
-> link = {
-> type = "rhombus";
-> size = "bandwidth";
-> values = ("bcompute","bdata","bfinalize","brequest");
-> };
-
-$ $SG_TEST_EXENV cat categories.uncat.plist
-> node = ("LINK","HOST");
-> edge = ("0-LINK4-LINK4","0-LINK4-HOST1","0-HOST1-LINK4");
->
-> host = {
-> type = "square";
-> size = "power";
-> values = ("power_used");
-> };
-> link = {
-> type = "rhombus";
-> size = "bandwidth";
-> values = ("bandwidth_used");
-> };
-
-$ rm -rf categories.trace categories.cat.plist categories.uncat.plist
-/* Copyright (c) 2010, 2012-2016. The SimGrid Team. All rights reserved. */
+/* Copyright (c) 2010, 2012-2017. 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. */
xbt_dynar_free (&link_variables);
}
- //create a customized viva graph configuration file
- FILE *fp = fopen ("viva_graph.plist", "w");
- if (fp == NULL){
- return 1;
- }
- fprintf (fp, "{\n node = (");
xbt_dynar_t nodes_type = TRACE_get_node_types ();
if (nodes_type){
XBT_INFO ("Node types in the trace:");
char *node_type;
xbt_dynar_foreach (nodes_type, cursor, node_type){
XBT_INFO ("%s", node_type);
- fprintf (fp, "%s, ", node_type);
}
xbt_dynar_free (&nodes_type);
}
- fprintf (fp, ");\n edge = (");
xbt_dynar_t edges_type = TRACE_get_edge_types ();
if (edges_type){
XBT_INFO ("Node types in the trace:");
char *edge_type;
xbt_dynar_foreach (edges_type, cursor, edge_type){
XBT_INFO ("%s", edge_type);
- fprintf (fp, "%s, ", edge_type);
}
xbt_dynar_free (&edges_type);
}
- fprintf (fp, ");\n");
- fprintf (fp, " host = {\n type = square;\n size = HDD_capacity; \n values = (HDD_utilization);\n };\n");
- fprintf (fp, " link = {\n type = rhombus;\n size = bandwidth;\n };\n");
- fprintf (fp, "}\n");
- fclose (fp);
return 0;
}
> [0.004078] [msg_test/INFO] 0-LINK3-HOST1
> [0.004078] [msg_test/INFO] 0-LINK3-LINK3
-$ rm -f viva_graph.plist
+$ rm -f simgrid.trace
p Not tracing user variables
$ $SG_TEST_EXENV ${bindir:=.}/trace-host-user-variables$EXEEXT ${srcdir:=.}/small_platform.xml ${srcdir:=.}/../msg/app-masterworker/app-masterworker_d.xml
-
-$ rm -f simgrid.trace viva_graph.plist
MSG_task_destroy(task);
break;
}
- //adding the value returned by MSG_task_get_compute_duration(task)
- //to the variable "task_computation"
- TRACE_host_variable_add(MSG_host_get_name(MSG_host_self()), "task_computation", MSG_task_get_flops_amount(task));
+ // adding the value returned by MSG_task_get_compute_duration(task) to the variable "task_computation"
+ TRACE_host_variable_add(MSG_host_get_name(MSG_host_self()), "task_computation",
+ MSG_task_get_initial_flops_amount(task));
MSG_task_execute(task);
MSG_task_destroy(task);
task = NULL;
#! ./tesh
p Tracing master/worker application
-$ $SG_TEST_EXENV ${bindir:=.}/trace-masterworker$EXEEXT --cfg=tracing:yes --cfg=tracing/buffer:yes --cfg=tracing/filename:trace-masterworker.trace --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes --cfg=viva/categorized:trace-masterworker.cat.plist --cfg=viva/uncategorized:trace-masterworker.uncat.plist ${srcdir:=.}/small_platform.xml ${srcdir:=.}/../msg/app-masterworker/app-masterworker_d.xml
+$ $SG_TEST_EXENV ${bindir:=.}/trace-masterworker$EXEEXT --cfg=tracing:yes --cfg=tracing/buffer:yes --cfg=tracing/filename:trace-masterworker.trace --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes ${srcdir:=.}/small_platform.xml ${srcdir:=.}/../msg/app-masterworker/app-masterworker_d.xml
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/buffer' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/filename' to 'trace-masterworker.trace'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/categorized' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/uncategorized' to 'yes'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/categorized' to 'trace-masterworker.cat.plist'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/uncategorized' to 'trace-masterworker.uncat.plist'
> [4.214821] [msg_trace_masterworker/INFO] Declared tracing categories:
> [4.214821] [msg_trace_masterworker/INFO] compute
> [4.214821] [msg_trace_masterworker/INFO] finalize
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/categorized' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/filename' to 'trace-masterworker.trace'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/uncategorized' to 'yes'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/categorized' to 'trace-masterworker.cat.plist'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/uncategorized' to 'trace-masterworker.uncat.plist'
> [4.214821] [msg_trace_masterworker/INFO] Declared tracing categories:
> [4.214821] [msg_trace_masterworker/INFO] compute
> [4.214821] [msg_trace_masterworker/INFO] finalize
$ $SG_TEST_EXENV ${bindir:=.}/trace-masterworker$EXEEXT ${srcdir:=.}/small_platform.xml ${srcdir:=.}/../msg/app-masterworker/app-masterworker_d.xml
p Testing tracing by process
-$ $SG_TEST_EXENV ${bindir:=.}/trace-masterworker$EXEEXT --cfg=tracing:yes --cfg=tracing/msg/process:yes --cfg=tracing/buffer:yes --cfg=tracing/filename:trace-masterworker.trace --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes --cfg=viva/categorized:trace-masterworker.cat.plist --cfg=viva/uncategorized:trace-masterworker.uncat.plist ${srcdir:=.}/small_platform.xml ${srcdir:=.}/../msg/app-masterworker/app-masterworker_d.xml
+$ $SG_TEST_EXENV ${bindir:=.}/trace-masterworker$EXEEXT --cfg=tracing:yes --cfg=tracing/msg/process:yes --cfg=tracing/buffer:yes --cfg=tracing/filename:trace-masterworker.trace --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes ${srcdir:=.}/small_platform.xml ${srcdir:=.}/../msg/app-masterworker/app-masterworker_d.xml
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/msg/process' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/buffer' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/filename' to 'trace-masterworker.trace'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/categorized' to 'yes'
> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'tracing/uncategorized' to 'yes'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/categorized' to 'trace-masterworker.cat.plist'
-> [0.000000] [xbt_cfg/INFO] Configuration change: Set 'viva/uncategorized' to 'trace-masterworker.uncat.plist'
> [4.214821] [msg_trace_masterworker/INFO] Declared tracing categories:
> [4.214821] [msg_trace_masterworker/INFO] compute
> [4.214821] [msg_trace_masterworker/INFO] finalize
> [4.214821] [msg_trace_masterworker/INFO] Declared marks:
> [4.214821] [msg_trace_masterworker/INFO] msmark
-$ $SG_TEST_EXENV cat trace-masterworker.uncat.plist
-> node = ("LINK","HOST");
-> edge = ("0-LINK13-LINK13","0-LINK13-HOST1","0-HOST1-LINK13");
->
-> host = {
-> type = "square";
-> size = "power";
-> values = ("power_used");
-> };
-> link = {
-> type = "rhombus";
-> size = "bandwidth";
-> values = ("bandwidth_used");
-> };
-$ $SG_TEST_EXENV cat trace-masterworker.cat.plist
-> node = ("LINK","HOST");
-> edge = ("0-LINK13-LINK13","0-LINK13-HOST1","0-HOST1-LINK13");
->
-> host = {
-> type = "square";
-> size = "power";
-> values = ("pcompute","pfinalize","preport","prequest");
-> };
-> link = {
-> type = "rhombus";
-> size = "bandwidth";
-> values = ("bcompute","bfinalize","breport","brequest");
-> };
-
-$ rm -rf trace-masterworker.trace trace-masterworker.cat.plist trace-masterworker.uncat.plist
+$ rm -rf trace-masterworker.trace
<prop id="tracing/uncategorized" value="yes"/>
<prop id="tracing/buffer" value="yes"/>
<prop id="tracing" value="yes"/>
- <prop id="viva/categorized" value="trace-masterworker.cat.plist"/>
<prop id="tracing/filename" value="trace-masterworker.trace"/>
- <prop id="viva/uncategorized" value="trace-masterworker.uncat.plist"/>
<prop id="tracing/categorized" value="yes"/>
</config>
<prop id="watt_per_state" value="100.0:200.0, 93.0:170.0, 90.0:150.0" />
<prop id="watt_off" value="10" />
</host>
-
- <link id="bus" bandwidth="100kBps" latency="0"/>
+
+ <link id="bus" bandwidth="100kBps" latency="0" sharing_policy="SHARED">
+<!-- REALISTIC VALUES <prop id="watt_range" value="10.3581:10.7479" /> -->
+<!-- IREALISTIC VALUES FOR THE TEST --> <prop id="watt_range" value="1:3" />
+ </link>
<route src="MyHost1" dst="MyHost2">
<link_ctn id="bus"/>
</route>
actor-create actor-daemon actor-execute actor-kill actor-lifetime actor-migration actor-suspend actor-priority
app-masterworker app-pingpong app-token-ring
async-wait async-waitany async-waitall
+ energy-link
plugin-hostload io mutex)
add_executable (s4u-${example} ${example}/s4u-${example}.cpp)
target_link_libraries(s4u-${example} simgrid)
actor-create actor-daemon actor-execute actor-kill actor-lifetime actor-migration actor-suspend
app-bittorrent app-masterworker app-pingpong app-token-ring
async-wait async-waitall async-waitany actor-priority
- dht-chord plugin-hostload io mutex)
+ dht-chord
+ energy-link
+ plugin-hostload io mutex)
ADD_TESH_FACTORIES(s4u-${example} "thread;ucontext;raw;boost" --setenv bindir=${CMAKE_CURRENT_BINARY_DIR}/${example} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --cd ${CMAKE_HOME_DIRECTORY}/examples/s4u/${example} s4u-${example}.tesh)
endforeach()
@ref examples/s4u/actor-create/s4u-actor-create_d.xml \n
Shows how to start your actors to populate your simulation.
- - <b>Ping Pong</b>: @ref examples/s4u/app-pingpong/s4u-app-pingpong.c\n
+ - <b>Ping Pong</b>: @ref examples/s4u/app-pingpong/s4u-app-pingpong.cpp\n
This simple example just sends one message back and forth.
The tesh file laying in the directory show how to start the simulator binary, highlighting how to pass options to
the simulators (as detailed in Section \ref options).
int main(int argc, char* argv[])
{
simgrid::s4u::Engine e(&argc, argv);
+ sg_storage_file_system_init();
xbt_assert(argc > 3, "Usage: %s platform_file deployment_file [action_files]\n"
"\texample: %s platform.xml deployment.xml actions # if all actions are in the same file\n"
--- /dev/null
+/* Copyright (c) 2017. 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/plugins/energy.h"
+#include "xbt/log.h"
+#include <simgrid/s4u.hpp>
+
+#include <random>
+
+/* Parameters of the random generation of the flow size */
+static const unsigned long int min_size = 1e6;
+static const unsigned long int max_size = 1e9;
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_app_energyconsumption, "Messages specific for this s4u example");
+
+static void sender(std::vector<std::string> args)
+{
+ xbt_assert(args.size() == 2, "The master function expects 2 arguments.");
+ int flow_amount = std::stoi(args.at(0));
+ double comm_size = std::stod(args.at(1));
+ XBT_INFO("Send %.0f bytes, in %d flows", comm_size, flow_amount);
+
+ simgrid::s4u::MailboxPtr mailbox = simgrid::s4u::Mailbox::byName(std::string("message"));
+
+ simgrid::s4u::this_actor::sleep_for(10);
+
+ /* - Send the task to the @ref worker */
+ char* payload = bprintf("%f", comm_size);
+
+ if (flow_amount == 1) {
+ mailbox->put(payload, comm_size);
+ } else {
+ // Start all comms in parallel
+ std::vector<simgrid::s4u::CommPtr> comms;
+ for (int i = 0; i < flow_amount; i++)
+ comms.push_back(mailbox->put_async(const_cast<char*>("message"), comm_size));
+
+ // And now, wait for all comms. Manually since wait_all is not part of this_actor yet
+ for (int i = 0; i < flow_amount; i++) {
+ simgrid::s4u::CommPtr comm = comms.at(i);
+ comm->wait();
+ }
+ comms.clear();
+ }
+ XBT_INFO("sender done.");
+}
+
+static void receiver(std::vector<std::string> args)
+{
+ int flow_amount = std::stoi(args.at(0));
+
+ XBT_INFO("Receiving %d flows ...", flow_amount);
+
+ simgrid::s4u::MailboxPtr mailbox = simgrid::s4u::Mailbox::byName(std::string("message"));
+
+ if (flow_amount == 1) {
+ void* res = mailbox->get();
+ xbt_free(res);
+ } else {
+ void* ignored;
+
+ // Start all comms in parallel
+ std::vector<simgrid::s4u::CommPtr> comms;
+ for (int i = 0; i < flow_amount; i++)
+ comms.push_back(mailbox->get_async(&ignored));
+
+ // And now, wait for all comms. Manually since wait_all is not part of this_actor yet
+ for (int i = 0; i < flow_amount; i++)
+ comms.at(i)->wait();
+ comms.clear();
+ }
+ XBT_INFO("receiver done.");
+}
+
+int main(int argc, char* argv[])
+{
+
+ simgrid::s4u::Engine e(&argc, argv);
+
+ /* Check if we got --NS3 on the command line, and activate ecofen if so */
+ bool NS3 = false;
+ for (int i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "--NS3") == 0)
+ NS3 = true;
+ if (NS3) // Found the --NS3 parameter previously; shift the rest of the line
+ argv[i] = argv[i + 1];
+ }
+ if (NS3) {
+ xbt_die("No Ecofen in this build");
+ // XBT_INFO("Activating the Ecofen energy plugin");
+ // ns3_link_energy_plugin_init();
+ // xbt_cfg_set_parse("network/model:NS3");
+ // argc -= 1; // We removed it from the parameters
+ } else {
+ XBT_INFO("Activating the SimGrid link energy plugin");
+ sg_link_energy_plugin_init();
+ }
+
+ xbt_assert(argc > 1, "\nUsage: %s platform_file [flowCount [datasize]] [--NS3]\n"
+ "\tExample: %s s4uplatform.xml \n"
+ "\tIf you add NS3 as last parameter, this will try to activate the ecofen plugin.\n"
+ "\tWithout it, it will use the SimGrid link energy plugin.\n",
+ argv[0], argv[0]);
+ e.loadPlatform(argv[1]);
+
+ /* prepare to launch the actors */
+ std::vector<std::string> argSender;
+ std::vector<std::string> argReceiver;
+ if (argc > 2) {
+ argSender.push_back(argv[2]); // Take the amount of flows from the command line
+ argReceiver.push_back(argv[2]);
+ } else {
+ argSender.push_back("1"); // Default value
+ argReceiver.push_back("1");
+ }
+ if (argc > 3) {
+ if (strcmp(argv[3], "random") == 0) { // We're asked to get a random size
+ /* Initialize the random number generator */
+ std::random_device rd;
+ std::default_random_engine generator(rd());
+
+ /* Distribution on which to apply the generator */
+ std::uniform_int_distribution<unsigned long int> distribution(min_size, max_size);
+
+ char* size = bprintf("%lu", distribution(generator));
+ argSender.push_back(std::string(size));
+ xbt_free(size);
+ } else { // Not "random" ? Then it should be the size to use
+ argSender.push_back(argv[3]); // Take the datasize from the command line
+ }
+ } else { // No parameter at all? Then use the default value
+ argSender.push_back("25000");
+ }
+ simgrid::s4u::Actor::createActor("sender", simgrid::s4u::Host::by_name("MyHost1"), sender, argSender);
+ simgrid::s4u::Actor::createActor("receiver", simgrid::s4u::Host::by_name("MyHost2"), receiver, argReceiver);
+
+ /* And now, launch the simulation */
+ e.run();
+
+ return 0;
+}
--- /dev/null
+#! ./tesh
+
+p Testing the mechanism for computing link energy consumption (using CM02 as a network model)
+
+$ ${bindir:=.}/s4u-energy-link$EXEEXT ${srcdir:=.}/../platforms/energy_platform.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=network/model:CM02 --cfg=network/crosstraffic:no
+> [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02'
+> [ 0.000000] (0:maestro@) Configuration change: Set 'network/crosstraffic' to 'no'
+> [ 0.000000] (0:maestro@) Activating the SimGrid link energy plugin
+> [ 0.000000] (1:sender@MyHost1) Send 25000 bytes, in 1 flows
+> [ 0.000000] (2:receiver@MyHost2) Receiving 1 flows ...
+> [ 10.250000] (2:receiver@MyHost2) receiver done.
+> [ 10.250000] (1:sender@MyHost1) sender done.
+> [ 10.250000] (0:maestro@) Link 'bus' total consumption: 10.750000
+> [ 10.250000] (0:maestro@) Total energy over all links: 10.750000
+
+p And now test with 500000 bytes
+
+$ ${bindir:=.}/s4u-energy-link$EXEEXT ${srcdir:=.}/../platforms/energy_platform.xml 1 50000000 "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" --cfg=network/model:CM02 --cfg=network/crosstraffic:no
+> [ 0.000000] (0:maestro@) Configuration change: Set 'network/model' to 'CM02'
+> [ 0.000000] (0:maestro@) Configuration change: Set 'network/crosstraffic' to 'no'
+> [ 0.000000] (0:maestro@) Activating the SimGrid link energy plugin
+> [ 0.000000] (1:sender@MyHost1) Send 50000000 bytes, in 1 flows
+> [ 0.000000] (2:receiver@MyHost2) Receiving 1 flows ...
+> [510.000000] (2:receiver@MyHost2) receiver done.
+> [510.000000] (1:sender@MyHost1) sender done.
+> [510.000000] (0:maestro@) Link 'bus' total consumption: 1510.000000
+> [510.000000] (0:maestro@) Total energy over all links: 1510.000000
+
int main(int argc, char **argv)
{
simgrid::s4u::Engine e(&argc, argv);
+ sg_storage_file_system_init();
e.loadPlatform("../../platforms/storage/storage.xml");
simgrid::s4u::Actor::createActor("host", simgrid::s4u::Host::by_name("denise"), MyHost());
e.run();
p Testing grouped tracing
$ ../../../smpi_script/bin/smpirun -trace -trace-grouped -trace-file smpi_trace.trace -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../platforms/small_platform.xml --cfg=path:${srcdir:=.}/../msg -np 3 ./smpi_trace_simple --log=smpi_kernel.thres:warning --log=xbt_cfg.thres:warning
-p Testing generation of viva configuration files
-$ ../../../smpi_script/bin/smpirun -trace -trace-resource -trace-viva -trace-file smpi_trace.trace -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../platforms/small_platform.xml --cfg=path:${srcdir:=.}/../msg --cfg=smpi/simulate-computation:no -np 3 ./smpi_trace_simple --log=smpi_kernel.thres:warning --log=xbt_cfg.thres:warning
-> [0.003952] [instr_config/INFO] No categories declared, ignoring generation of viva graph configuration
p Testing with parameters but without activating them with the safe switch (-trace)
-$ ../../../smpi_script/bin/smpirun -trace-resource -trace-viva -trace-file smpi_trace.trace -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../platforms/small_platform.xml --cfg=path:${srcdir:=.}/../msg -np 3 ./smpi_trace_simple --log=smpi_kernel.thres:warning --log=xbt_cfg.thres:warning
+$ ../../../smpi_script/bin/smpirun -trace-resource -trace-file smpi_trace.trace -hostfile ${srcdir:=.}/hostfile -platform ${srcdir:=.}/../platforms/small_platform.xml --cfg=path:${srcdir:=.}/../msg -np 3 ./smpi_trace_simple --log=smpi_kernel.thres:warning --log=xbt_cfg.thres:warning
-$ rm -f smpi_trace.trace smpi_uncat.plist smpi_cat.plist
+$ rm -f smpi_trace.trace
\ No newline at end of file
class HostImpl;
class StorageImpl;
class StorageType;
- class FileImpl;
}
namespace trace_mgr {
class trace;
typedef simgrid::simix::ActorImpl* smx_actor_t;
typedef simgrid::simix::MutexImpl* smx_mutex_t;
typedef simgrid::kernel::activity::MailboxImpl* smx_mailbox_t;
-typedef simgrid::surf::FileImpl* surf_file_t;
+typedef simgrid::surf::StorageImpl* surf_storage_t;
#else
typedef struct s_smx_actor* smx_actor_t;
typedef struct s_smx_mutex* smx_mutex_t;
typedef struct s_smx_mailbox* smx_mailbox_t;
-typedef struct s_surf_file* surf_file_t;
+typedef struct s_surf_storage* surf_storage_t;
#endif
XBT_PUBLIC(msg_error_t) MSG_process_sleep(double nb_sec);
XBT_PUBLIC(void) MSG_task_set_flops_amount(msg_task_t task, double flops_amount);
-XBT_PUBLIC(double) MSG_task_get_flops_amount(msg_task_t task);
+XBT_ATTRIB_DEPRECATED_v321("Use MSG_task_get_initial_flops_amount if you want to get initial amounts of flops, or "
+ "Use MSG_task_get_remaining_work_ratio to get task progress (in order "
+ "to compute progress in flops)") XBT_PUBLIC(double)
+ MSG_task_get_flops_amount(msg_task_t task);
+XBT_PUBLIC(double) MSG_task_get_initial_flops_amount(msg_task_t task);
+XBT_PUBLIC(double) MSG_task_get_remaining_work_ratio(msg_task_t task);
XBT_PUBLIC(void) MSG_task_set_bytes_amount(msg_task_t task, double bytes_amount);
+
XBT_PUBLIC(double) MSG_task_get_remaining_communication(msg_task_t task);
XBT_PUBLIC(int) MSG_task_is_latency_bounded(msg_task_t task);
XBT_PUBLIC(double) MSG_task_get_bytes_amount(msg_task_t task);
XBT_PUBLIC(double) sg_host_get_wattmax_at(sg_host_t host, int pstate);
XBT_PUBLIC(double) sg_host_get_current_consumption(sg_host_t host);
+XBT_PUBLIC(void) sg_link_energy_plugin_init();
+XBT_PUBLIC(double) sg_link_get_consumed_energy(sg_link_t link);
+
#define MSG_host_energy_plugin_init() sg_host_energy_plugin_init()
#define MSG_host_get_consumed_energy(host) sg_host_get_consumed_energy(host)
#define MSG_host_get_wattmin_at(host,pstate) sg_host_get_wattmin_at(host,pstate)
--- /dev/null
+/* Copyright (c) 2017. 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. */
+
+#ifndef SIMGRID_PLUGINS_FILE_SYSTEM_H_
+#define SIMGRID_PLUGINS_FILE_SYSTEM_H_
+
+#include <simgrid/forward.h>
+#include <xbt/base.h>
+
+SG_BEGIN_DECL()
+
+XBT_PUBLIC(void) sg_storage_file_system_init();
+
+#define MSG_storage_file_system_init() sg_storage_file_system_init()
+
+SG_END_DECL()
+
+#endif
* <!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd">
* <platform version="4">
*
- * <!-- Start a process called 'master' on the host called 'Tremblay' -->
- * <process host="Tremblay" function="master">
+ * <!-- Start an actor called 'master' on the host called 'Tremblay' -->
+ * <actor host="Tremblay" function="master">
* <!-- Here come the parameter that you want to feed to this instance of master -->
* <argument value="20"/> <!-- argv[1] -->
* <argument value="50000000"/> <!-- argv[2] -->
* <argument value="1000000"/> <!-- argv[3] -->
* <argument value="5"/> <!-- argv[4] -->
- * </process>
+ * </actor>
*
- * <!-- Start a process called 'worker' on the host called 'Jupiter' -->
- * <process host="Jupiter" function="worker"/> <!-- Don't provide any parameter ->>
+ * <!-- Start an actor called 'worker' on the host called 'Jupiter' -->
+ * <actor host="Jupiter" function="worker"/> <!-- Don't provide any parameter ->>
*
* </platform>
* @endcode
/** Create an actor using code
*
* Using this constructor, move-only type can be used. The consequence is
- * that we cannot copy the value and restart the process in its initial
+ * that we cannot copy the value and restart the actor in its initial
* state. In order to use auto-restart, an explicit `function` must be passed
* instead.
*/
static ActorPtr createActor(const char* name, s4u::Host* host, const char* function, std::vector<std::string> args);
// ***** Methods *****
- /** This actor will be automatically terminated when the last non-daemon process finishes **/
+ /** This actor will be automatically terminated when the last non-daemon actor finishes **/
void daemonize();
/** Retrieves the name of that actor as a C++ string */
/** Suspend an actor by suspending the task on which it was waiting for the completion. */
void suspend();
- /** Resume a suspended process by resuming the task on which it was waiting for the completion. */
+ /** Resume a suspended actor by resuming the task on which it was waiting for the completion. */
void resume();
- /** Returns true if the process is suspended. */
+ /** Returns true if the actor is suspended. */
int isSuspended();
/** If set to true, the actor will automatically restart when its host reboots */
void setAutoRestart(bool autorestart);
/** Add a function to the list of "on_exit" functions for the current actor. The on_exit functions are the functions
- * executed when your actor is killed. You should use them to free the data used by your process.
+ * executed when your actor is killed. You should use them to free the data used by your actor.
*/
void onExit(int_f_pvoid_pvoid_t fun, void* data);
/** @brief Returns the name of the current actor as a C string. */
XBT_PUBLIC(const char*) getCname();
-/** @brief Returns the name of the host on which the process is running. */
+/** @brief Returns the name of the host on which the actor is running. */
XBT_PUBLIC(Host*) getHost();
/** @brief Suspend the actor. */
size_t getHostCount();
void getHostList(std::vector<Host*> * whereTo);
+ size_t getLinkCount();
+ void getLinkList(std::vector<Link*> * list);
/** @brief Run the simulation */
void run();
#ifndef SIMGRID_S4U_FILE_HPP
#define SIMGRID_S4U_FILE_HPP
+#include "simgrid/plugins/file_system.h"
+#include <xbt/Extendable.hpp>
#include <xbt/base.h>
#include <simgrid/simix.h>
public:
File(std::string fullpath, void* userdata);
File(std::string fullpath, sg_host_t host, void* userdata);
- ~File();
+ ~File() = default;
/** Retrieves the path to the file */
- const char* getPath() { return path_.c_str(); }
+ const char* getPath() { return fullpath_.c_str(); }
/** Simulates a local read action. Returns the size of data actually read */
sg_size_t read(sg_size_t size);
/** Remove a file from disk */
int unlink();
- std::string storage_type;
- std::string storageId;
- std::string mount_point;
int desc_id = 0;
+ Storage* localStorage;
+ std::string mount_point_;
private:
- surf_file_t pimpl_ = nullptr;
+ sg_size_t size_;
std::string path_;
- void* userdata_ = nullptr;
+ std::string fullpath_;
+ sg_size_t current_position_ = SEEK_SET;
+ void* userdata_ = nullptr;
+};
+
+class FileSystemStorageExt {
+public:
+ static simgrid::xbt::Extension<simgrid::s4u::Storage, FileSystemStorageExt> EXTENSION_ID;
+ explicit FileSystemStorageExt(simgrid::s4u::Storage* ptr);
+ ~FileSystemStorageExt();
+ std::map<std::string, sg_size_t>* parseContent(std::string filename);
+ std::map<std::string, sg_size_t>* getContent() { return content_; }
+ sg_size_t getUsedSize() { return usedSize_; }
+ void decrUsedSize(sg_size_t size) { usedSize_ -= size; }
+ void incrUsedSize(sg_size_t size) { usedSize_ += size; }
+private:
+ std::map<std::string, sg_size_t>* content_;
+ sg_size_t usedSize_ = 0;
};
}
} // namespace simgrid::s4u
#define S4U_LINK_HPP_
#include <simgrid/link.h>
-#include <xbt/base.h>
-#include <xbt/signal.hpp>
-
#include <string>
#include <unordered_map>
+#include <xbt/Extendable.hpp>
+#include <xbt/base.h>
+#include <xbt/signal.hpp>
/***********
* Classes *
};
namespace s4u {
/** @brief A Link represents the network facilities between [hosts](\ref simgrid::s4u::Host) */
-XBT_PUBLIC_CLASS Link
+XBT_PUBLIC_CLASS Link : public simgrid::xbt::Extendable<Link>
{
friend simgrid::surf::LinkImpl;
*/
int sharingPolicy();
+ /** @brief Returns the current load (in flops per second) */
+ double getUsage();
+
/** @brief Check if the Link is used */
bool isUsed();
void setLatencyTrace(tmgr_trace_t trace); /*< setup the trace file with latency events (peak latency changes due to
external load). Trace must contain absolute values */
+ const char* getProperty(const char* key);
+ void setProperty(std::string key, std::string value);
+
/* The signals */
/** @brief Callback signal fired when a new Link is created */
static simgrid::xbt::signal<void(s4u::Link&)> onCreation;
#ifndef INCLUDE_SIMGRID_S4U_STORAGE_HPP_
#define INCLUDE_SIMGRID_S4U_STORAGE_HPP_
+#include "xbt/Extendable.hpp"
#include <map>
#include <simgrid/s4u/forward.hpp>
#include <simgrid/simix.h>
#include <xbt/base.h>
namespace simgrid {
+namespace xbt {
+extern template class XBT_PUBLIC() Extendable<simgrid::s4u::Storage>;
+}
namespace s4u {
XBT_ATTRIB_PUBLIC std::map<std::string, Storage*>* allStorages();
-XBT_PUBLIC_CLASS Storage
+XBT_PUBLIC_CLASS Storage : public simgrid::xbt::Extendable<Storage>
{
friend s4u::Engine;
friend simgrid::surf::StorageImpl;
sg_size_t getSize(); /** Retrieve the total amount of space of this storage element */
sg_size_t getSizeFree();
sg_size_t getSizeUsed();
+ void decrUsedSize(sg_size_t size);
+ void incrUsedSize(sg_size_t size);
std::map<std::string, std::string>* getProperties();
const char* getProperty(std::string key);
void setUserdata(void* data) { userdata_ = data; }
void* getUserdata() { return userdata_; }
+ sg_size_t read(sg_size_t size);
+ sg_size_t write(sg_size_t size);
surf::StorageImpl* getImpl() { return pimpl_; }
/* The signals */
XBT_PUBLIC(void) simcall_sem_acquire(smx_sem_t sem);
XBT_PUBLIC(void) simcall_sem_acquire_timeout(smx_sem_t sem, double max_duration);
-/***************************** File **********************************/
-XBT_PUBLIC(sg_size_t) simcall_file_read(surf_file_t fd, sg_size_t size);
-XBT_PUBLIC(sg_size_t) simcall_file_write(surf_file_t fd, sg_size_t size);
+/***************************** Storage **********************************/
+XBT_PUBLIC(sg_size_t) simcall_storage_read(surf_storage_t st, sg_size_t size);
+XBT_PUBLIC(sg_size_t) simcall_storage_write(surf_storage_t fd, sg_size_t size);
/************************** MC simcalls **********************************/
XBT_PUBLIC(int) simcall_mc_random(int min, int max);
};
typedef struct xbt_swag s_xbt_swag_t;
typedef struct xbt_swag* xbt_swag_t;
+typedef const struct xbt_swag* const_xbt_swag_t;
/**< A typical swag */
/* @} */
XBT_PUBLIC(void) xbt_swag_insert_at_tail(void *obj, xbt_swag_t swag);
XBT_PUBLIC(void *) xbt_swag_remove(void *obj, xbt_swag_t swag);
XBT_PUBLIC(void *) xbt_swag_extract(xbt_swag_t swag);
-XBT_PUBLIC(int) xbt_swag_size(xbt_swag_t swag);
+XBT_PUBLIC(int) xbt_swag_size(const_xbt_swag_t swag);
#define xbt_swag_getPrev(obj, offset) (((xbt_swag_hookup_t)(((char *) (obj)) + (offset)))->prev)
#define xbt_swag_getNext(obj, offset) (((xbt_swag_hookup_t)(((char *) (obj)) + (offset)))->next)
#define xbt_swag_belongs(obj, swag) (xbt_swag_getNext((obj), (swag)->offset) || (swag)->tail == (obj))
-static inline void *xbt_swag_getFirst(xbt_swag_t swag)
+static inline void *xbt_swag_getFirst(const_xbt_swag_t swag)
{
return (swag->head);
}
#include "simgrid/msg.h"
#include "simgrid/plugins/energy.h"
+#include "simgrid/plugins/file_system.h"
#include "simgrid/simix.h"
#include "simgrid/s4u/Host.hpp"
JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_energyInit() {
sg_host_energy_plugin_init();
}
+
+JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_fileSystemInit()
+{
+ sg_storage_file_system_init();
+}
} // extern "C"
/** Run a Java org.simgrid.msg.Process
JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_init(JNIEnv* env, jclass cls, jobjectArray jargs);
JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_energyInit();
+JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_fileSystemInit();
JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_debug(JNIEnv* env, jclass cls, jstring jargs);
JNIEXPORT void JNICALL Java_org_simgrid_msg_Msg_verb(JNIEnv* env, jclass cls, jstring jargs);
env->SetIntField(jprocess, jprocess_field_Process_ppid, (jint) MSG_process_get_PPID(process));
}
+JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_daemonize(JNIEnv* env, jobject jprocess)
+{
+ msg_process_t process = jprocess_to_native(jprocess, env);
+
+ if (not process) {
+ jxbt_throw_notbound(env, "process", jprocess);
+ return;
+ }
+
+ MSG_process_daemonize(process);
+}
+
JNIEXPORT jint JNICALL Java_org_simgrid_msg_Process_killAll(JNIEnv * env, jclass cls, jint jresetPID)
{
return (jint) MSG_process_killall((int) jresetPID);
/* Implement the Java API */
JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_create(JNIEnv* env, jobject jprocess_arg, jobject jhostname);
+JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_daemonize(JNIEnv* env, jobject jprocess);
JNIEXPORT jint JNICALL Java_org_simgrid_msg_Process_killAll(JNIEnv* env, jclass cls, jint jresetPID);
JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_fromPID(JNIEnv* env, jclass cls, jint pid);
JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_getProperty(JNIEnv* env, jobject jprocess, jobject jname);
jxbt_throw_notbound(env, "task", jtask);
return -1;
}
- return (jdouble) MSG_task_get_flops_amount(ptask);
+ return (jdouble)MSG_task_get_remaining_work_ratio(ptask);
}
JNIEXPORT void JNICALL Java_org_simgrid_msg_Task_setName(JNIEnv *env, jobject jtask, jobject jname) {
/** Tell the kernel that you want to use the energy plugin */
public static final native void energyInit();
+ public static final native void fileSystemInit();
/** Run the MSG simulation.
*
return (fabs(value1 - value2) < precision);
}
-extern "C" {
-
/** @{ @ingroup SURF_lmm */
/**
* @brief Create a new Linear MaxMim system
lmm_get_var_from_cnst_safe(lmm_system_t sys, lmm_constraint_t cnst, lmm_element_t* elem, lmm_element_t* nextelem,
int* numelem);
-/**
- * @brief Get the first active constraint of a system
- * @param sys A system
- * @return The first active constraint
- */
-XBT_PUBLIC(lmm_constraint_t) lmm_get_first_active_constraint(lmm_system_t sys);
-
-/**
- * @brief Get the next active constraint of a constraint in a system
- * @param sys A system
- * @param cnst An active constraint of the system
- *
- * @return The next active constraint
- */
-XBT_PUBLIC(lmm_constraint_t) lmm_get_next_active_constraint(lmm_system_t sys, lmm_constraint_t cnst);
-
/**
* @brief Get the data associated to a constraint
* @param cnst A constraint
XBT_PUBLIC(double) func_vegas_fpi(lmm_variable_t var, double x);
/** @} */
-}
#endif
#define OPT_TRACING_TOPOLOGY "tracing/platform/topology"
#define OPT_TRACING "tracing"
#define OPT_TRACING_UNCATEGORIZED "tracing/uncategorized"
-#define OPT_VIVA_CAT_CONF "viva/categorized"
-#define OPT_VIVA_UNCAT_CONF "viva/uncategorized"
static bool trace_enabled = false;
static bool trace_platform;
} else {
retval = 0;
- TRACE_generate_viva_uncat_conf();
- TRACE_generate_viva_cat_conf();
-
/* dump trace buffer */
TRACE_last_timestamp_to_dump = surf_get_clock();
TRACE_paje_dump_buffer(true);
return xbt_cfg_get_string(OPT_TRACING_FILENAME);
}
-std::string TRACE_get_viva_uncat_conf()
-{
- return xbt_cfg_get_string(OPT_VIVA_UNCAT_CONF);
-}
-
-std::string TRACE_get_viva_cat_conf()
-{
- return xbt_cfg_get_string(OPT_VIVA_CAT_CONF);
-}
-
void TRACE_global_init()
{
static bool is_initialised = false;
"The contents of the file are added to the top of the trace file as comment.");
xbt_cfg_register_int(OPT_TRACING_PRECISION, 6, nullptr, "Numerical precision used when timestamping events "
"(expressed in number of digits after decimal point)");
- /* Viva graph configuration for uncategorized tracing */
- xbt_cfg_register_string(OPT_VIVA_UNCAT_CONF, "", nullptr, "Viva Graph configuration file for uncategorized resource utilization traces.");
- xbt_cfg_register_string(OPT_VIVA_CAT_CONF, "", nullptr, "Viva Graph configuration file for categorized resource utilization traces.");
xbt_cfg_register_alias(OPT_TRACING_COMMENT_FILE,"tracing/comment_file");
xbt_cfg_register_alias(OPT_TRACING_DISABLE_DESTROY, "tracing/disable_destroy");
" It activates the uncategorized resource utilization tracing. Use it if\n"
" this simulator do not use tracing categories and resource use have to be\n"
" traced.", detailed);
- print_line (OPT_TRACING_FILENAME, "Filename to register traces",
- " A file with this name will be created to register the simulation. The file\n"
- " is in the Paje format and can be analyzed using Viva, Paje, and PajeNG visualization\n"
- " tools. More information can be found in these webpages:\n"
- " http://github.com/schnorr/viva/\n"
- " http://github.com/schnorr/pajeng/\n"
- " http://paje.sourceforge.net/", detailed);
+ print_line(OPT_TRACING_FILENAME, "Filename to register traces",
+ " A file with this name will be created to register the simulation. The file\n"
+ " is in the Paje format and can be analyzed using Paje, and PajeNG visualization\n"
+ " tools. More information can be found in these webpages:\n"
+ " http://github.com/schnorr/pajeng/\n"
+ " http://paje.sourceforge.net/",
+ detailed);
print_line (OPT_TRACING_SMPI, "Trace the MPI Interface (SMPI)",
" This option only has effect if this simulator is SMPI-based. Traces the MPI\n"
" interface and generates a trace that can be analyzed using Gantt-like\n"
" Use this to add a comment line to the top of the trace file.", detailed);
print_line (OPT_TRACING_COMMENT_FILE, "File contents added to trace file as comment.",
" Use this to add the contents of a file to the top of the trace file as comment.", detailed);
- print_line (OPT_VIVA_UNCAT_CONF, "Generate a graph configuration for Viva",
- " This option can be used in all types of simulators build with SimGrid\n"
- " to generate a uncategorized resource utilization graph to be used as\n"
- " configuration for the Viva visualization tool. This option\n"
- " can be used with tracing/categorized:1 and tracing:1 options to\n"
- " analyze an unmodified simulator before changing it to contain\n"
- " categories.", detailed);
- print_line (OPT_VIVA_CAT_CONF, "Generate an uncategorized graph configuration for Viva",
- " This option can be used if this simulator uses tracing categories\n"
- " in its code. The file specified by this option holds a graph configuration\n"
- " file for the Viva visualization tool that can be used to analyze a categorized\n"
- " resource utilization.", detailed);
print_line (OPT_TRACING_TOPOLOGY, "Register the platform topology as a graph",
" This option (enabled by default) can be used to disable the tracing of\n"
" the platform topology in the trace file. Sometimes, such task is really\n"
xbt_dynar_free (&types);
}
-static void output_categories(const char* name, FILE* file)
-{
- unsigned int i = created_categories.size();
- fprintf (file, " values = (");
- for (auto const& cat : created_categories) {
- --i;
- fprintf(file, "\"%s%s\"", name, cat.c_str());
- if (i > 0) {
- fprintf (file, ",");
- }else{
- fprintf (file, ");\n");
- }
- }
-}
-
-static void uncat_configuration (FILE *file)
-{
- //register NODE and EDGE types
- output_types ("node", TRACE_get_node_types(), file);
- output_types ("edge", TRACE_get_edge_types(), file);
- fprintf (file, "\n");
-
- //configuration for all nodes
- fprintf (file,
- " host = {\n"
- " type = \"square\";\n"
- " size = \"power\";\n"
- " values = (\"power_used\");\n"
- " };\n"
- " link = {\n"
- " type = \"rhombus\";\n"
- " size = \"bandwidth\";\n"
- " values = (\"bandwidth_used\");\n"
- " };\n");
- //close
-}
-
-static void cat_configuration (FILE *file)
-{
- //register NODE and EDGE types
- output_types ("node", TRACE_get_node_types(), file);
- output_types ("edge", TRACE_get_edge_types(), file);
- fprintf (file, "\n");
-
- //configuration for all nodes
- fprintf (file,
- " host = {\n"
- " type = \"square\";\n"
- " size = \"power\";\n");
- output_categories("p", file);
- fprintf (file,
- " };\n"
- " link = {\n"
- " type = \"rhombus\";\n"
- " size = \"bandwidth\";\n");
- output_categories("b", file);
- fprintf (file, " };\n");
- //close
-}
-
-static void generate_uncat_configuration (const char *output, const char *name, int brackets)
-{
- if (output && strlen(output) > 0){
- FILE *file = fopen (output, "w");
- if (file == nullptr){
- THROWF (system_error, 1, "Unable to open file (%s) for writing %s graph configuration (uncategorized).",
- output, name);
- }
-
- if (brackets)
- fprintf (file, "{\n");
- uncat_configuration (file);
- if (brackets)
- fprintf (file, "}\n");
- fclose (file);
- }
-}
-
-static void generate_cat_configuration (const char *output, const char *name, int brackets)
-{
- if (output && strlen(output) > 0){
- //check if we do have categories declared
- if (created_categories.empty()) {
- XBT_INFO("No categories declared, ignoring generation of %s graph configuration", name);
- return;
- }
-
- FILE *file = fopen (output, "w");
- if (file == nullptr){
- THROWF (system_error, 1, "Unable to open file (%s) for writing %s graph "
- "configuration (categorized).", output, name);
- }
-
- if (brackets) fprintf (file, "{\n");
- cat_configuration (file);
- if (brackets) fprintf (file, "}\n");
- fclose (file);
- }
-}
-
-void TRACE_generate_viva_uncat_conf ()
-{
- generate_uncat_configuration(TRACE_get_viva_uncat_conf().c_str(), "viva", 0);
-}
-
-void TRACE_generate_viva_cat_conf ()
-{
- generate_cat_configuration(TRACE_get_viva_cat_conf().c_str(), "viva", 0);
-}
-
static int previous_trace_state = -1;
void instr_pause_tracing ()
class StateEvent : public PajeEvent {
EntityValue* value;
std::string filename;
- int linenumber;
+ int linenumber = 0;
TIData* extra_ = nullptr;
public:
XBT_PRIVATE bool TRACE_basic();
XBT_PRIVATE bool TRACE_display_sizes();
XBT_PRIVATE int TRACE_precision();
-XBT_PRIVATE void TRACE_generate_viva_uncat_conf();
-XBT_PRIVATE void TRACE_generate_viva_cat_conf();
XBT_PRIVATE void instr_pause_tracing();
XBT_PRIVATE void instr_resume_tracing();
XBT_PRIVATE std::string TRACE_get_comment();
XBT_PRIVATE std::string TRACE_get_comment_file();
XBT_PRIVATE std::string TRACE_get_filename();
-XBT_PRIVATE std::string TRACE_get_viva_uncat_conf();
-XBT_PRIVATE std::string TRACE_get_viva_cat_conf();
#endif
{
for (smx_simcall_t const& simcall : simcalls) {
switch (simcall->call) {
- case SIMCALL_FILE_WRITE:
- simcall_file_write__set__result(simcall, surf_io->getCost());
- break;
- case SIMCALL_FILE_READ:
- simcall_file_read__set__result(simcall, surf_io->getCost());
- break;
- default:
- break;
+ case SIMCALL_STORAGE_WRITE:
+ simcall_storage_write__set__result(simcall, surf_io->getCost());
+ break;
+ case SIMCALL_STORAGE_READ:
+ simcall_storage_read__set__result(simcall, surf_io->getCost());
+ break;
+ default:
+ break;
}
}
"\t\tStorage Id: '%s'\n"
"\t\tStorage Type: '%s'\n"
"\t\tFile Descriptor Id: %d",
- fd->getPath(), fd->size(), fd->mount_point.c_str(), fd->storageId.c_str(), fd->storage_type.c_str(),
- fd->desc_id);
+ fd->getPath(), fd->size(), fd->mount_point_.c_str(), fd->localStorage->getCname(),
+ fd->localStorage->getType(), fd->desc_id);
}
/** \ingroup msg_file
return 0;
/* Find the host where the file is physically located and read it */
- msg_storage_t storage_src = simgrid::s4u::Storage::byName(fd->storageId);
+ msg_storage_t storage_src = fd->localStorage;
msg_host_t attached_host = storage_src->getHost();
read_size = fd->read(size);
return 0;
/* Find the host where the file is physically located (remote or local)*/
- msg_storage_t storage_src = simgrid::s4u::Storage::byName(fd->storageId);
+ msg_storage_t storage_src = fd->localStorage;
msg_host_t attached_host = storage_src->getHost();
if (strcmp(attached_host->getCname(), MSG_host_self()->getCname())) {
msg_error_t MSG_file_rcopy (msg_file_t file, msg_host_t host, const char* fullpath)
{
/* Find the host where the file is physically located and read it */
- msg_storage_t storage_src = simgrid::s4u::Storage::byName(file->storageId);
+ msg_storage_t storage_src = file->localStorage;
msg_host_t src_host = storage_src->getHost();
MSG_file_seek(file, 0, SEEK_SET);
sg_size_t read_size = file->read(file->size());
*/
XBT_PUBLIC(void) MSG_process_daemonize(msg_process_t process)
{
- simgrid::simix::kernelImmediate([process]() { process->getImpl()->daemonize(); });
+ process->daemonize();
}
/** @ingroup m_process_management
}
/** \ingroup m_task_management
- * \brief Returns the remaining amount of flops needed to execute a task #msg_task_t.
+ * \brief Returns a value in ]0,1[ that represent the task remaining work
+ * to do: starts at 1 and goes to 0. Returns 0 if not started or finished.
*
- * Once a task has been processed, this amount is set to 0. If you want, you can reset this value with
- * #MSG_task_set_flops_amount before restarting the task.
+ * It works for either parallel or sequential tasks.
+ * TODO: Improve this function by returning 1 if the task has not started
*/
+double MSG_task_get_remaining_work_ratio(msg_task_t task) {
+
+ xbt_assert((task != nullptr), "Cannot get information from a nullptr task");
+ if (task->simdata->compute) {
+ // Task in progress
+ return task->simdata->compute->remains();
+
+ //} else if ((MSG_task_get_flops_amount(task) == 0 and task->simdata->flops_parallel_amount == nullptr) //this is a sequential task
+ // or (task->simdata->flops_parallel_amount != nullptr and task->simdata->flops_parallel_amount == 0)) {
+ // // Task finished
+ // return 1;
+ } else {
+ // Task not started or finished
+ return 0;
+ }
+}
+
double MSG_task_get_flops_amount(msg_task_t task) {
if (task->simdata->compute) {
return task->simdata->compute->remains();
}
}
+/** \ingroup m_task_management
+ * \brief Returns the initial amount of flops needed to execute a task #msg_task_t.
+ *
+ * Once a task has been processed, this amount is set to 0. If you want, you can reset this value with
+ * #MSG_task_set_flops_amount before restarting the task.
+ *
+ * Warning: Only work for simple task, not parallel task.
+ */
+double MSG_task_get_initial_flops_amount(msg_task_t task) {
+ return task->simdata->flops_amount;
+}
+
/** \ingroup m_task_management
* \brief set the computation amount needed to process a task #msg_task_t.
*
for (auto const& elm : vm->pimpl_vm_->dp_objs) {
dirty_page_t dp = elm.second;
- double remaining = MSG_task_get_flops_amount(dp->task);
+ double remaining = MSG_task_get_remaining_work_ratio(dp->task);
dp->prev_clock = MSG_get_clock();
dp->prev_remaining = remaining;
XBT_DEBUG("%s@%s remaining %f", elm.first.c_str(), vm->getCname(), remaining);
for (auto const& elm : vm->pimpl_vm_->dp_objs) {
const std::string& key = elm.first;
dirty_page_t dp = elm.second;
- double remaining = MSG_task_get_flops_amount(dp->task);
+ double remaining = MSG_task_get_remaining_work_ratio(dp->task);
double clock = MSG_get_clock();
if (vm == nullptr)
return;
- double remaining = MSG_task_get_flops_amount(task);
+ double remaining = MSG_task_get_initial_flops_amount(task);
std::string key = simgrid::xbt::string_printf("%s-%p", task->name, task);
dirty_page_t dp = new s_dirty_page;
/* If we are in the middle of dirty page tracking, we record how much computation has been done until now, and keep
* the information for the lookup_() function that will called soon. */
if (vm->pimpl_vm_->dp_enabled) {
- double remaining = MSG_task_get_flops_amount(task);
+ double remaining = MSG_task_get_remaining_work_ratio(task);
double clock = MSG_get_clock();
double updated = get_computed(key, vm, dp, remaining, clock); // was host instead of vm
for (auto const& kv : host_list)
list->push_back(kv.second);
}
+/** @brief Returns the amount of links in the platform */
+size_t Engine::getLinkCount()
+{
+ return simgrid::surf::LinkImpl::linksCount();
+}
+/** @brief Fills the passed list with all hosts found in the platform */
+void Engine::getLinkList(std::vector<Link*>* list)
+{
+ simgrid::surf::LinkImpl::linksList(list);
+}
void Engine::run() {
if (MC_is_active()) {
#include "simgrid/s4u/Host.hpp"
#include "simgrid/s4u/Storage.hpp"
#include "simgrid/simix.hpp"
-#include "src/surf/FileImpl.hpp"
#include "src/surf/HostImpl.hpp"
+#include <algorithm>
+#include <boost/algorithm/string.hpp>
+#include <boost/algorithm/string/join.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <fstream>
+
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_file,"S4U files");
namespace simgrid {
namespace s4u {
+simgrid::xbt::Extension<s4u::Storage, FileSystemStorageExt> FileSystemStorageExt::EXTENSION_ID;
File::File(std::string fullpath, void* userdata) : File(fullpath, Host::current(), userdata){};
-File::File(std::string fullpath, sg_host_t host, void* userdata) : path_(fullpath), userdata_(userdata)
+File::File(std::string fullpath, sg_host_t host, void* userdata) : fullpath_(fullpath), userdata_(userdata)
{
// this cannot fail because we get a xbt_die if the mountpoint does not exist
Storage* st = nullptr;
size_t longest_prefix_length = 0;
- std::string path;
XBT_DEBUG("Search for storage name for '%s' on '%s'", fullpath.c_str(), host->getCname());
for (auto const& mnt : host->getMountedStorages()) {
XBT_DEBUG("See '%s'", mnt.first.c_str());
- mount_point = fullpath.substr(0, mnt.first.length());
+ mount_point_ = fullpath.substr(0, mnt.first.length());
- if (mount_point == mnt.first && mnt.first.length() > longest_prefix_length) {
+ if (mount_point_ == mnt.first && mnt.first.length() > longest_prefix_length) {
/* The current mount name is found in the full path and is bigger than the previous*/
longest_prefix_length = mnt.first.length();
st = mnt.second;
}
}
if (longest_prefix_length > 0) { /* Mount point found, split fullpath into mount_name and path+filename*/
- mount_point = fullpath.substr(0, longest_prefix_length);
- path = fullpath.substr(longest_prefix_length, fullpath.length());
+ mount_point_ = fullpath.substr(0, longest_prefix_length);
+ path_ = fullpath.substr(longest_prefix_length, fullpath.length());
} else
xbt_die("Can't find mount point for '%s' on '%s'", fullpath.c_str(), host->getCname());
- pimpl_ =
- simgrid::simix::kernelImmediate([this, st, path] { return new simgrid::surf::FileImpl(st, path, mount_point); });
- storage_type = st->getType();
- storageId = st->getName();
-}
-
-File::~File()
-{
- simgrid::simix::kernelImmediate([this] { delete pimpl_; });
+ localStorage = st;
+
+ XBT_DEBUG("\tOpen file '%s'", path_.c_str());
+ std::map<std::string, sg_size_t>* content = localStorage->getContent();
+ // if file does not exist create an empty file
+ auto sz = content->find(path_);
+ if (sz != content->end()) {
+ size_ = sz->second;
+ } else {
+ size_ = 0;
+ content->insert({path_, size_});
+ XBT_DEBUG("File '%s' was not found, file created.", path_.c_str());
+ }
}
sg_size_t File::read(sg_size_t size)
{
- return simcall_file_read(pimpl_, size);
+ XBT_DEBUG("READ %s on disk '%s'", getPath(), localStorage->getCname());
+ // if the current position is close to the end of the file, we may not be able to read the requested size
+ sg_size_t read_size = localStorage->read(std::min(size, size_ - current_position_));
+ current_position_ += read_size;
+ return read_size;
}
sg_size_t File::write(sg_size_t size)
{
- return simcall_file_write(pimpl_, size);
+ XBT_DEBUG("WRITE %s on disk '%s'. size '%llu/%llu'", getPath(), localStorage->getCname(), size, size_);
+ // If the storage is full before even starting to write
+ if (localStorage->getSizeUsed() >= localStorage->getSize())
+ return 0;
+ /* Substract the part of the file that might disappear from the used sized on the storage element */
+ localStorage->decrUsedSize(size_ - current_position_);
+
+ sg_size_t write_size = localStorage->write(size);
+ localStorage->incrUsedSize(write_size);
+
+ current_position_ += write_size;
+ size_ = current_position_;
+
+ localStorage->getContent()->erase(path_);
+ localStorage->getContent()->insert({path_, size_});
+
+ return write_size;
}
sg_size_t File::size()
{
- return simgrid::simix::kernelImmediate([this] { return pimpl_->size(); });
+ return size_;
}
-void File::seek(sg_offset_t pos)
+void File::seek(sg_offset_t offset)
{
- simgrid::simix::kernelImmediate([this, pos] { pimpl_->seek(pos, SEEK_SET); });
+ current_position_ = offset;
}
-void File::seek(sg_offset_t pos, int origin)
+void File::seek(sg_offset_t offset, int origin)
{
- simgrid::simix::kernelImmediate([this, pos, origin] { pimpl_->seek(pos, origin); });
+ switch (origin) {
+ case SEEK_SET:
+ current_position_ = offset;
+ break;
+ case SEEK_CUR:
+ current_position_ += offset;
+ break;
+ case SEEK_END:
+ current_position_ = size_ + offset;
+ break;
+ default:
+ break;
+ }
}
sg_size_t File::tell()
{
- return simgrid::simix::kernelImmediate([this] { return pimpl_->tell(); });
+ return current_position_;
}
void File::move(std::string fullpath)
{
- simgrid::simix::kernelImmediate([this, fullpath] { pimpl_->move(fullpath); });
+ /* Check if the new full path is on the same mount point */
+ if (not strncmp(mount_point_.c_str(), fullpath.c_str(), mount_point_.length())) {
+ std::map<std::string, sg_size_t>* content = localStorage->getContent();
+ auto sz = content->find(path_);
+ if (sz != content->end()) { // src file exists
+ sg_size_t new_size = sz->second;
+ content->erase(path_);
+ std::string path = fullpath.substr(mount_point_.length(), fullpath.length());
+ content->insert({path.c_str(), new_size});
+ XBT_DEBUG("Move file from %s to %s, size '%llu'", path_.c_str(), fullpath.c_str(), new_size);
+ } else {
+ XBT_WARN("File %s doesn't exist", path_.c_str());
+ }
+ } else {
+ XBT_WARN("New full path %s is not on the same mount point: %s.", fullpath.c_str(), mount_point_.c_str());
+ }
}
int File::unlink()
{
- return simgrid::simix::kernelImmediate([this] { return pimpl_->unlink(); });
+ /* Check if the file is on local storage */
+ if (localStorage->getContent()->find(path_) == localStorage->getContent()->end()) {
+ XBT_WARN("File %s is not on disk %s. Impossible to unlink", path_.c_str(), localStorage->getCname());
+ return -1;
+ } else {
+ XBT_DEBUG("UNLINK %s on disk '%s'", path_.c_str(), localStorage->getCname());
+ localStorage->decrUsedSize(size_);
+
+ // Remove the file from storage
+ localStorage->getContent()->erase(fullpath_);
+
+ return 0;
+ }
+}
+
+FileSystemStorageExt::FileSystemStorageExt(simgrid::s4u::Storage* ptr)
+{
+ content_ = parseContent(ptr->getImpl()->content_name);
+}
+
+FileSystemStorageExt::~FileSystemStorageExt()
+{
+ delete content_;
+}
+
+std::map<std::string, sg_size_t>* FileSystemStorageExt::parseContent(std::string filename)
+{
+ if (filename.empty())
+ return nullptr;
+
+ std::map<std::string, sg_size_t>* parse_content = new std::map<std::string, sg_size_t>();
+
+ std::ifstream* fs = surf_ifsopen(filename);
+
+ std::string line;
+ std::vector<std::string> tokens;
+ do {
+ std::getline(*fs, line);
+ boost::trim(line);
+ if (line.length() > 0) {
+ boost::split(tokens, line, boost::is_any_of(" \t"), boost::token_compress_on);
+ xbt_assert(tokens.size() == 2, "Parse error in %s: %s", filename.c_str(), line.c_str());
+ sg_size_t size = std::stoull(tokens.at(1));
+
+ usedSize_ += size;
+ parse_content->insert({tokens.front(), size});
+ }
+ } while (not fs->eof());
+ delete fs;
+ return parse_content;
+}
+}
+}
+
+using simgrid::s4u::FileSystemStorageExt;
+
+static void onStorageCreation(simgrid::s4u::Storage& st)
+{
+ st.extension_set(new FileSystemStorageExt(&st));
+}
+
+static void onStorageDestruction(simgrid::s4u::Storage& st)
+{
+ delete st.extension<FileSystemStorageExt>();
+}
+
+/* **************************** Public interface *************************** */
+SG_BEGIN_DECL()
+
+void sg_storage_file_system_init()
+{
+
+ if (FileSystemStorageExt::EXTENSION_ID.valid())
+ return;
+
+ FileSystemStorageExt::EXTENSION_ID = simgrid::s4u::Storage::extension_create<FileSystemStorageExt>();
+
+ simgrid::s4u::Storage::onCreation.connect(&onStorageCreation);
+ simgrid::s4u::Storage::onDestruction.connect(&onStorageDestruction);
}
-}} // namespace simgrid::s4u
+SG_END_DECL()
return this->pimpl_->sharingPolicy();
}
+double Link::getUsage()
+{
+ return lmm_constraint_get_usage(this->pimpl_->constraint());
+}
+
void Link::turnOn()
{
simgrid::simix::kernelImmediate([this]() {
});
}
+const char* Link::getProperty(const char* key)
+{
+ return this->pimpl_->getProperty(key);
+}
+void Link::setProperty(std::string key, std::string value)
+{
+ simgrid::simix::kernelImmediate([this, key, value] { this->pimpl_->setProperty(key, value); });
+}
+
/*************
* Callbacks *
*************/
/* 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 "../surf/StorageImpl.hpp"
+#include "simgrid/s4u/File.hpp"
#include "simgrid/s4u/Host.hpp"
#include "simgrid/s4u/Storage.hpp"
#include "simgrid/simix.hpp"
+#include "src/surf/StorageImpl.hpp"
#include <unordered_map>
namespace simgrid {
+namespace xbt {
+template class Extendable<simgrid::s4u::Storage>;
+}
+
namespace s4u {
std::map<std::string, Storage*>* allStorages()
sg_size_t Storage::getSizeFree()
{
- return simgrid::simix::kernelImmediate([this] { return pimpl_->getFreeSize(); });
+ FileSystemStorageExt* file_system = extension<FileSystemStorageExt>();
+
+ return pimpl_->getSize() - file_system->getUsedSize();
}
sg_size_t Storage::getSizeUsed()
{
- return simgrid::simix::kernelImmediate([this] { return pimpl_->getUsedSize(); });
+ FileSystemStorageExt* file_system = extension<FileSystemStorageExt>();
+ return file_system->getUsedSize();
+}
+
+void Storage::decrUsedSize(sg_size_t size)
+{
+ FileSystemStorageExt* file_system = extension<FileSystemStorageExt>();
+ file_system->decrUsedSize(size);
+}
+
+void Storage::incrUsedSize(sg_size_t size)
+{
+ FileSystemStorageExt* file_system = extension<FileSystemStorageExt>();
+ file_system->incrUsedSize(size);
}
sg_size_t Storage::getSize()
std::map<std::string, sg_size_t>* Storage::getContent()
{
- return simgrid::simix::kernelImmediate([this] { return pimpl_->getContent(); });
+ FileSystemStorageExt* file_system = extension<FileSystemStorageExt>();
+ return file_system->getContent();
+}
+
+sg_size_t Storage::read(sg_size_t size)
+{
+ return simcall_storage_read(pimpl_, size);
+}
+
+sg_size_t Storage::write(sg_size_t size)
+{
+ return simcall_storage_write(pimpl_, size);
}
/*************
* \ingroup simix_synchro_management
*
*/
-void simcall_cond_wait_timeout(smx_cond_t cond,
- smx_mutex_t mutex,
- double timeout)
+void simcall_cond_wait_timeout(smx_cond_t cond, smx_mutex_t mutex, double timeout)
{
xbt_assert(std::isfinite(timeout), "timeout is not finite!");
simcall_BODY_cond_wait_timeout(cond, mutex, timeout);
simcall_BODY_sem_acquire_timeout(sem, timeout);
}
-/**
- * \ingroup simix_file_management
- *
- */
-sg_size_t simcall_file_read(surf_file_t fd, sg_size_t size)
+sg_size_t simcall_storage_read(surf_storage_t st, sg_size_t size)
{
- return simcall_BODY_file_read(fd, size);
+ return simcall_BODY_storage_read(st, size);
}
-/**
- * \ingroup simix_file_management
- *
- */
-sg_size_t simcall_file_write(surf_file_t fd, sg_size_t size)
+sg_size_t simcall_storage_write(surf_storage_t st, sg_size_t size)
{
- return simcall_BODY_file_write(fd, size);
+ return simcall_BODY_storage_write(st, size);
}
void simcall_run_kernel(std::function<void()> const& code)
simgrid::simix::marshal<double>(simcall->args[1], arg);
}
-static inline surf_file_t simcall_file_read__get__fd(smx_simcall_t simcall)
+static inline surf_storage_t simcall_storage_read__get__st(smx_simcall_t simcall)
{
- return simgrid::simix::unmarshal<surf_file_t>(simcall->args[0]);
+ return simgrid::simix::unmarshal<surf_storage_t>(simcall->args[0]);
}
-static inline surf_file_t simcall_file_read__getraw__fd(smx_simcall_t simcall)
+static inline surf_storage_t simcall_storage_read__getraw__st(smx_simcall_t simcall)
{
- return simgrid::simix::unmarshal_raw<surf_file_t>(simcall->args[0]);
+ return simgrid::simix::unmarshal_raw<surf_storage_t>(simcall->args[0]);
}
-static inline void simcall_file_read__set__fd(smx_simcall_t simcall, surf_file_t arg)
+static inline void simcall_storage_read__set__st(smx_simcall_t simcall, surf_storage_t arg)
{
- simgrid::simix::marshal<surf_file_t>(simcall->args[0], arg);
+ simgrid::simix::marshal<surf_storage_t>(simcall->args[0], arg);
}
-static inline sg_size_t simcall_file_read__get__size(smx_simcall_t simcall)
+static inline sg_size_t simcall_storage_read__get__size(smx_simcall_t simcall)
{
return simgrid::simix::unmarshal<sg_size_t>(simcall->args[1]);
}
-static inline sg_size_t simcall_file_read__getraw__size(smx_simcall_t simcall)
+static inline sg_size_t simcall_storage_read__getraw__size(smx_simcall_t simcall)
{
return simgrid::simix::unmarshal_raw<sg_size_t>(simcall->args[1]);
}
-static inline void simcall_file_read__set__size(smx_simcall_t simcall, sg_size_t arg)
+static inline void simcall_storage_read__set__size(smx_simcall_t simcall, sg_size_t arg)
{
simgrid::simix::marshal<sg_size_t>(simcall->args[1], arg);
}
-static inline sg_size_t simcall_file_read__get__result(smx_simcall_t simcall)
+static inline sg_size_t simcall_storage_read__get__result(smx_simcall_t simcall)
{
return simgrid::simix::unmarshal<sg_size_t>(simcall->result);
}
-static inline sg_size_t simcall_file_read__getraw__result(smx_simcall_t simcall)
+static inline sg_size_t simcall_storage_read__getraw__result(smx_simcall_t simcall)
{
return simgrid::simix::unmarshal_raw<sg_size_t>(simcall->result);
}
-static inline void simcall_file_read__set__result(smx_simcall_t simcall, sg_size_t result)
+static inline void simcall_storage_read__set__result(smx_simcall_t simcall, sg_size_t result)
{
simgrid::simix::marshal<sg_size_t>(simcall->result, result);
}
-static inline surf_file_t simcall_file_write__get__fd(smx_simcall_t simcall)
+static inline surf_storage_t simcall_storage_write__get__st(smx_simcall_t simcall)
{
- return simgrid::simix::unmarshal<surf_file_t>(simcall->args[0]);
+ return simgrid::simix::unmarshal<surf_storage_t>(simcall->args[0]);
}
-static inline surf_file_t simcall_file_write__getraw__fd(smx_simcall_t simcall)
+static inline surf_storage_t simcall_storage_write__getraw__st(smx_simcall_t simcall)
{
- return simgrid::simix::unmarshal_raw<surf_file_t>(simcall->args[0]);
+ return simgrid::simix::unmarshal_raw<surf_storage_t>(simcall->args[0]);
}
-static inline void simcall_file_write__set__fd(smx_simcall_t simcall, surf_file_t arg)
+static inline void simcall_storage_write__set__st(smx_simcall_t simcall, surf_storage_t arg)
{
- simgrid::simix::marshal<surf_file_t>(simcall->args[0], arg);
+ simgrid::simix::marshal<surf_storage_t>(simcall->args[0], arg);
}
-static inline sg_size_t simcall_file_write__get__size(smx_simcall_t simcall)
+static inline sg_size_t simcall_storage_write__get__size(smx_simcall_t simcall)
{
return simgrid::simix::unmarshal<sg_size_t>(simcall->args[1]);
}
-static inline sg_size_t simcall_file_write__getraw__size(smx_simcall_t simcall)
+static inline sg_size_t simcall_storage_write__getraw__size(smx_simcall_t simcall)
{
return simgrid::simix::unmarshal_raw<sg_size_t>(simcall->args[1]);
}
-static inline void simcall_file_write__set__size(smx_simcall_t simcall, sg_size_t arg)
+static inline void simcall_storage_write__set__size(smx_simcall_t simcall, sg_size_t arg)
{
simgrid::simix::marshal<sg_size_t>(simcall->args[1], arg);
}
-static inline sg_size_t simcall_file_write__get__result(smx_simcall_t simcall)
+static inline sg_size_t simcall_storage_write__get__result(smx_simcall_t simcall)
{
return simgrid::simix::unmarshal<sg_size_t>(simcall->result);
}
-static inline sg_size_t simcall_file_write__getraw__result(smx_simcall_t simcall)
+static inline sg_size_t simcall_storage_write__getraw__result(smx_simcall_t simcall)
{
return simgrid::simix::unmarshal_raw<sg_size_t>(simcall->result);
}
-static inline void simcall_file_write__set__result(smx_simcall_t simcall, sg_size_t result)
+static inline void simcall_storage_write__set__result(smx_simcall_t simcall, sg_size_t result)
{
simgrid::simix::marshal<sg_size_t>(simcall->result, result);
}
XBT_PRIVATE void simcall_HANDLER_cond_wait_timeout(smx_simcall_t simcall, smx_cond_t cond, smx_mutex_t mutex, double timeout);
XBT_PRIVATE void simcall_HANDLER_sem_acquire(smx_simcall_t simcall, smx_sem_t sem);
XBT_PRIVATE void simcall_HANDLER_sem_acquire_timeout(smx_simcall_t simcall, smx_sem_t sem, double timeout);
-XBT_PRIVATE void simcall_HANDLER_file_read(smx_simcall_t simcall, surf_file_t fd, sg_size_t size);
-XBT_PRIVATE void simcall_HANDLER_file_write(smx_simcall_t simcall, surf_file_t fd, sg_size_t size);
+XBT_PRIVATE void simcall_HANDLER_storage_read(smx_simcall_t simcall, surf_storage_t st, sg_size_t size);
+XBT_PRIVATE void simcall_HANDLER_storage_write(smx_simcall_t simcall, surf_storage_t st, sg_size_t size);
XBT_PRIVATE int simcall_HANDLER_mc_random(smx_simcall_t simcall, int min, int max);
\ No newline at end of file
return simcall<void, smx_sem_t, double>(SIMCALL_SEM_ACQUIRE_TIMEOUT, sem, timeout);
}
-inline static sg_size_t simcall_BODY_file_read(surf_file_t fd, sg_size_t size)
+inline static sg_size_t simcall_BODY_storage_read(surf_storage_t st, sg_size_t size)
{
if (0) /* Go to that function to follow the code flow through the simcall barrier */
- simcall_HANDLER_file_read(&SIMIX_process_self()->simcall, fd, size);
- return simcall<sg_size_t, surf_file_t, sg_size_t>(SIMCALL_FILE_READ, fd, size);
+ simcall_HANDLER_storage_read(&SIMIX_process_self()->simcall, st, size);
+ return simcall<sg_size_t, surf_storage_t, sg_size_t>(SIMCALL_STORAGE_READ, st, size);
}
-inline static sg_size_t simcall_BODY_file_write(surf_file_t fd, sg_size_t size)
+inline static sg_size_t simcall_BODY_storage_write(surf_storage_t st, sg_size_t size)
{
if (0) /* Go to that function to follow the code flow through the simcall barrier */
- simcall_HANDLER_file_write(&SIMIX_process_self()->simcall, fd, size);
- return simcall<sg_size_t, surf_file_t, sg_size_t>(SIMCALL_FILE_WRITE, fd, size);
+ simcall_HANDLER_storage_write(&SIMIX_process_self()->simcall, st, size);
+ return simcall<sg_size_t, surf_storage_t, sg_size_t>(SIMCALL_STORAGE_WRITE, st, size);
}
inline static int simcall_BODY_mc_random(int min, int max)
SIMCALL_COND_BROADCAST,
SIMCALL_SEM_ACQUIRE,
SIMCALL_SEM_ACQUIRE_TIMEOUT,
- SIMCALL_FILE_READ,
- SIMCALL_FILE_WRITE,
+ SIMCALL_STORAGE_READ,
+ SIMCALL_STORAGE_WRITE,
SIMCALL_MC_RANDOM,
SIMCALL_SET_CATEGORY,
SIMCALL_RUN_KERNEL,
- SIMCALL_RUN_BLOCKING, NUM_SIMCALLS
+ SIMCALL_RUN_BLOCKING,
+ NUM_SIMCALLS
} e_smx_simcall_t;
"SIMCALL_COND_BROADCAST",
"SIMCALL_SEM_ACQUIRE",
"SIMCALL_SEM_ACQUIRE_TIMEOUT",
- "SIMCALL_FILE_READ",
- "SIMCALL_FILE_WRITE",
+ "SIMCALL_STORAGE_READ",
+ "SIMCALL_STORAGE_WRITE",
"SIMCALL_MC_RANDOM",
"SIMCALL_SET_CATEGORY",
"SIMCALL_RUN_KERNEL",
simcall_HANDLER_sem_acquire_timeout(simcall, simgrid::simix::unmarshal<smx_sem_t>(simcall->args[0]), simgrid::simix::unmarshal<double>(simcall->args[1]));
break;
-case SIMCALL_FILE_READ:
- simcall_HANDLER_file_read(simcall, simgrid::simix::unmarshal<surf_file_t>(simcall->args[0]), simgrid::simix::unmarshal<sg_size_t>(simcall->args[1]));
+case SIMCALL_STORAGE_READ:
+ simcall_HANDLER_storage_read(simcall, simgrid::simix::unmarshal<surf_storage_t>(simcall->args[0]),
+ simgrid::simix::unmarshal<sg_size_t>(simcall->args[1]));
break;
-case SIMCALL_FILE_WRITE:
- simcall_HANDLER_file_write(simcall, simgrid::simix::unmarshal<surf_file_t>(simcall->args[0]), simgrid::simix::unmarshal<sg_size_t>(simcall->args[1]));
+case SIMCALL_STORAGE_WRITE:
+ simcall_HANDLER_storage_write(simcall, simgrid::simix::unmarshal<surf_storage_t>(simcall->args[0]),
+ simgrid::simix::unmarshal<sg_size_t>(simcall->args[1]));
break;
case SIMCALL_MC_RANDOM:
void sem_acquire(smx_sem_t sem) [[block]];
void sem_acquire_timeout(smx_sem_t sem, double timeout) [[block]];
-sg_size_t file_read(surf_file_t fd, sg_size_t size) [[block]];
-sg_size_t file_write(surf_file_t fd, sg_size_t size) [[block]];
+sg_size_t storage_read(surf_storage_t st, sg_size_t size) [[block]];
+sg_size_t storage_write(surf_storage_t st, sg_size_t size) [[block]];
int mc_random(int min, int max);
void set_category(boost::intrusive_ptr<simgrid::kernel::activity::ActivityImpl> synchro, const char* category) [[nohandler]];
if (not host)
THROWF(arg_error, 0, "Host '%s' unknown", process_host);
process.host = process_host;
-
- process.argc = 1 + xbt_dynar_length(arguments);
- process.argv = static_cast<const char**>(xbt_new(const char*, process.argc + 1));
- process.argv[0] = xbt_strdup(process_function);
+ process.args.push_back(process_function);
/* add arguments */
unsigned int i;
char *arg;
xbt_dynar_foreach(arguments, i, arg) {
- process.argv[i + 1] = xbt_strdup(arg);
+ process.args.push_back(arg);
}
- process.argv[process.argc] = nullptr;
// Check we know how to handle this function name:
simgrid::simix::ActorCodeFactory& parse_code = SIMIX_get_actor_code_factory(process_function);
#include "simgrid/s4u/Host.hpp"
#include "simgrid/s4u/Storage.hpp"
-#include "src/surf/FileImpl.hpp"
#include "src/surf/HostImpl.hpp"
#include "src/surf/StorageImpl.hpp"
#include "surf/surf.hpp"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(simix_io, simix, "Logging specific to SIMIX (io)");
-//SIMIX FILE READ
-void simcall_HANDLER_file_read(smx_simcall_t simcall, surf_file_t fd, sg_size_t size)
+void simcall_HANDLER_storage_read(smx_simcall_t simcall, surf_storage_t st, sg_size_t size)
{
- smx_activity_t synchro = SIMIX_file_read(fd, size);
+ smx_activity_t synchro = SIMIX_storage_read(st, size);
synchro->simcalls.push_back(simcall);
simcall->issuer->waiting_synchro = synchro;
}
-smx_activity_t SIMIX_file_read(surf_file_t file, sg_size_t size)
+smx_activity_t SIMIX_storage_read(surf_storage_t st, sg_size_t size)
{
simgrid::kernel::activity::IoImpl* synchro = new simgrid::kernel::activity::IoImpl();
- synchro->surf_io = file->read(size);
+ synchro->surf_io = st->read(size);
synchro->surf_io->setData(synchro);
XBT_DEBUG("Create io synchro %p", synchro);
return synchro;
}
-//SIMIX FILE WRITE
-void simcall_HANDLER_file_write(smx_simcall_t simcall, surf_file_t fd, sg_size_t size)
+void simcall_HANDLER_storage_write(smx_simcall_t simcall, surf_storage_t st, sg_size_t size)
{
- smx_activity_t synchro = SIMIX_file_write(fd, size);
+ smx_activity_t synchro = SIMIX_storage_write(st, size);
synchro->simcalls.push_back(simcall);
simcall->issuer->waiting_synchro = synchro;
}
-smx_activity_t SIMIX_file_write(surf_file_t file, sg_size_t size)
+smx_activity_t SIMIX_storage_write(surf_storage_t st, sg_size_t size)
{
simgrid::kernel::activity::IoImpl* synchro = new simgrid::kernel::activity::IoImpl();
- synchro->surf_io = file->write(size);
+ synchro->surf_io = st->write(size);
synchro->surf_io->setData(synchro);
XBT_DEBUG("Create io synchro %p", synchro);
#include "popping_private.hpp"
#include "simgrid/simix.h"
-XBT_PRIVATE smx_activity_t SIMIX_file_read(surf_file_t fd, sg_size_t size);
-XBT_PRIVATE smx_activity_t SIMIX_file_write(surf_file_t fd, sg_size_t size);
+XBT_PRIVATE smx_activity_t SIMIX_storage_read(surf_storage_t fd, sg_size_t size);
+XBT_PRIVATE smx_activity_t SIMIX_storage_write(surf_storage_t fd, sg_size_t size);
XBT_PRIVATE void SIMIX_io_destroy(smx_activity_t synchro);
XBT_PRIVATE void SIMIX_io_finish(smx_activity_t synchro);
auto res = allocs.insert(std::make_pair(loc, shared_data_t()));
auto data = res.first;
if (res.second) {
- // The insertion did not take place.
+ // The new element was inserted.
// Generate a shared memory name from the address of the shared_data:
char shmname[32]; // cannot be longer than PSHMNAMLEN = 31 on Mac OS X (shm_open raises ENAMETOOLONG otherwise)
snprintf(shmname, 31, "/shmalloc%p", &*data);
"stop_offset (%zu) should be lower than its successor start offset (%zu)", stop_offset, shared_block_offsets[2*i_block+2]);
size_t start_block_offset = ALIGN_UP(start_offset, smpi_shared_malloc_blocksize);
size_t stop_block_offset = ALIGN_DOWN(stop_offset, smpi_shared_malloc_blocksize);
- for (unsigned block_id=0, i = start_block_offset / smpi_shared_malloc_blocksize; i < stop_block_offset / smpi_shared_malloc_blocksize; block_id++, i++) {
- XBT_DEBUG("\t\tglobal shared allocation, mmap block offset %u", block_id);
- void* pos = (void*)((unsigned long)mem + i * smpi_shared_malloc_blocksize);
+ for (size_t offset = start_block_offset; offset < stop_block_offset; offset += smpi_shared_malloc_blocksize) {
+ XBT_DEBUG("\t\tglobal shared allocation, mmap block offset %zx", offset);
+ void* pos = (void*)((unsigned long)mem + offset);
void* res = mmap(pos, smpi_shared_malloc_blocksize, PROT_READ | PROT_WRITE, mmap_flag,
huge_fd, 0);
xbt_assert(res == pos, "Could not map folded virtual memory (%s). Do you perhaps need to increase the "
-trace-comment-file <file> # put file contents on the top of the trace file as comment
-trace-grouped # group MPI processes by location
-trace-resource # trace resource utilization
- -trace-viva # generate configuration for Viva's GraphView
-trace-file <tracefile> # name of the tracefile (simgrid_smpi.trace)
-ext <value> # additional parameter (reserved)
TRACE_RESOURCE="true"
shift 1
;;
- "-trace-viva")
- TRACE_VIVA="true"
- shift 1
- ;;
"-keep-temps")
KEEP="true"
SIMOPTS="$SIMOPTS --cfg=smpi/keep-temps:yes"
if [ -n "${TRACE_RESOURCE}" ]; then
TRACEOPTIONS="${TRACEOPTIONS} --cfg=tracing/categorized:yes --cfg=tracing/uncategorized:yes"
fi
-
- if [ -n "${TRACE_VIVA}" ]; then
- TRACEOPTIONS="${TRACEOPTIONS} --cfg=viva/categorized:smpi_cat.plist --cfg=viva/uncategorized:smpi_uncat.plist"
- fi
fi
##---------------------- end SMPI TRACING OPTIONS ---------------------------------
+++ /dev/null
-/* Copyright (c) 2017. 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 "src/surf/FileImpl.hpp"
-#include "src/surf/StorageImpl.hpp"
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_file, surf, "Logging specific to the SURF file module");
-namespace simgrid {
-namespace surf {
-
-FileImpl::FileImpl(sg_storage_t st, std::string path, std::string mount) : path_(path), mount_point_(mount)
-{
- XBT_DEBUG("\tOpen file '%s'", path.c_str());
- location_ = st->getImpl();
- std::map<std::string, sg_size_t>* content = location_->getContent();
- // if file does not exist create an empty file
- auto sz = content->find(path);
- if (sz != content->end()) {
- size_ = sz->second;
- } else {
- size_ = 0;
- content->insert({path, size_});
- XBT_DEBUG("File '%s' was not found, file created.", path.c_str());
- }
-}
-
-Action* FileImpl::read(sg_size_t size)
-{
- XBT_DEBUG("READ %s on disk '%s'", getCname(), location_->getCname());
- if (current_position_ + size > size_) {
- if (current_position_ > size_) {
- size = 0;
- } else {
- size = size_ - current_position_;
- }
- current_position_ = size_;
- } else
- current_position_ += size;
-
- return location_->read(size);
-}
-
-Action* FileImpl::write(sg_size_t size)
-{
- XBT_DEBUG("WRITE %s on disk '%s'. size '%llu/%llu'", getCname(), location_->getCname(), size, size_);
-
- StorageAction* action = location_->write(size);
- action->file_ = this;
- /* Substract the part of the file that might disappear from the used sized on the storage element */
- location_->usedSize_ -= (size_ - current_position_);
- // If the storage is full before even starting to write
- if (location_->usedSize_ >= location_->getSize()) {
- action->setState(Action::State::failed);
- }
- return action;
-}
-
-int FileImpl::seek(sg_offset_t offset, int origin)
-{
- switch (origin) {
- case SEEK_SET:
- current_position_ = offset;
- return 0;
- case SEEK_CUR:
- current_position_ += offset;
- return 0;
- case SEEK_END:
- current_position_ = size_ + offset;
- return 0;
- default:
- return -1;
- }
-}
-
-int FileImpl::unlink()
-{
- /* Check if the file is on this storage */
- if (location_->getContent()->find(path_) == location_->getContent()->end()) {
- XBT_WARN("File %s is not on disk %s. Impossible to unlink", getCname(), location_->getCname());
- return -1;
- } else {
- XBT_DEBUG("UNLINK %s on disk '%s'", getCname(), location_->getCname());
- location_->usedSize_ -= size_;
-
- // Remove the file from storage
- location_->getContent()->erase(path_);
-
- return 0;
- }
-}
-
-void FileImpl::move(std::string fullpath)
-{
- /* Check if the new full path is on the same mount point */
- if (not strncmp(mount_point_.c_str(), fullpath.c_str(), mount_point_.size())) {
- std::map<std::string, sg_size_t>* content = location_->getContent();
- auto sz = content->find(path_);
- if (sz != content->end()) { // src file exists
- sg_size_t new_size = sz->second;
- content->erase(path_);
- std::string path = fullpath.substr(mount_point_.length(), fullpath.length());
- content->insert({path.c_str(), new_size});
- XBT_DEBUG("Move file from %s to %s, size '%llu'", path_.c_str(), fullpath.c_str(), new_size);
- } else {
- XBT_WARN("File %s doesn't exist", path_.c_str());
- }
- } else {
- XBT_WARN("New full path %s is not on the same mount point: %s.", fullpath.c_str(), mount_point_.c_str());
- }
-}
-}
-}
+++ /dev/null
-/* Copyright (c) 2017. 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. */
-
-#ifndef SRC_SURF_FILEIMPL_HPP_
-#define SRC_SURF_FILEIMPL_HPP_
-
-#include "surf/surf.hpp"
-#include <string>
-
-namespace simgrid {
-namespace surf {
-
-class FileImpl {
-public:
- FileImpl(sg_storage_t st, std::string path, std::string mount);
- ~FileImpl() = default;
-
- const std::string& getName() const { return path_; }
- const char* getCname() const { return path_.c_str(); }
- const char* mount() { return mount_point_.c_str(); }
- sg_size_t size() { return size_; }
- void setSize(sg_size_t size) { size_ = size; }
- void setPosition(sg_size_t size) { current_position_ = size; }
- void incrPosition(sg_size_t incr) { current_position_ += incr; }
- sg_size_t tell() { return current_position_; }
- int seek(sg_offset_t offset, int origin);
- int unlink();
- void move(std::string fullpath);
- Action* read(sg_size_t size);
- Action* write(sg_size_t size);
-
-private:
- StorageImpl* location_;
- std::string path_;
- std::string mount_point_;
- sg_size_t size_;
- sg_size_t current_position_ = SEEK_SET;
-};
-}
-}
-#endif /* SRC_SURF_FILEIMPL_HPP_ */
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "src/plugins/vm/VirtualMachineImpl.hpp"
-#include "src/surf/FileImpl.hpp"
#include <string>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_host, surf, "Logging specific to the SURF host module");
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "StorageImpl.hpp"
-
#include "surf_private.hpp"
-#include <algorithm>
-#include <boost/algorithm/string.hpp>
-#include <boost/algorithm/string/join.hpp>
-#include <boost/algorithm/string/split.hpp>
-#include <fstream>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_storage, surf, "Logging specific to the SURF storage module");
: Resource(model, name.c_str(), lmm_constraint_new(maxminSystem, this, std::max(bread, bwrite)))
, piface_(this)
, typeId_(type_id)
+ , content_name(content_name)
, size_(size)
, attach_(attach)
{
- content_ = parseContent(content_name);
- turnOn();
+ StorageImpl::turnOn();
XBT_DEBUG("Create resource with Bread '%f' Bwrite '%f' and Size '%llu'", bread, bwrite, size);
constraintRead_ = lmm_constraint_new(maxminSystem, this, bread);
constraintWrite_ = lmm_constraint_new(maxminSystem, this, bwrite);
StorageImpl::~StorageImpl()
{
storageDestructedCallbacks(this);
- if (content_ != nullptr)
- delete content_;
}
-std::map<std::string, sg_size_t>* StorageImpl::parseContent(std::string filename)
-{
- usedSize_ = 0;
- if (filename.empty())
- return nullptr;
-
- std::map<std::string, sg_size_t>* parse_content = new std::map<std::string, sg_size_t>();
-
- std::ifstream* fs = surf_ifsopen(filename);
-
- std::string line;
- std::vector<std::string> tokens;
- do {
- std::getline(*fs, line);
- boost::trim(line);
- if (line.length() > 0) {
- boost::split(tokens, line, boost::is_any_of(" \t"), boost::token_compress_on);
- xbt_assert(tokens.size() == 2, "Parse error in %s: %s", filename.c_str(), line.c_str());
- sg_size_t size = std::stoull(tokens.at(1));
-
- usedSize_ += size;
- parse_content->insert({tokens.front(), size});
- }
- } while (not fs->eof());
- delete fs;
- return parse_content;
-}
bool StorageImpl::isUsed()
{
}
}
-std::map<std::string, sg_size_t>* StorageImpl::getContent()
-{
- /* For the moment this action has no cost, but in the future we could take in account access latency of the disk */
- return content_;
-}
-
-sg_size_t StorageImpl::getFreeSize()
-{
- return size_ - usedSize_;
-}
-
-sg_size_t StorageImpl::getUsedSize()
-{
- return usedSize_;
-}
-
/**********
* Action *
**********/
* @brief Callbacks handler which emit the callbacks after Storage creation *
* @details Callback functions have the following signature: `void(Storage*)`
*/
-XBT_PUBLIC_DATA(simgrid::xbt::signal<void(simgrid::surf::StorageImpl*)>) storageCreatedCallbacks;
+XBT_PUBLIC_DATA(simgrid::xbt::signal<void(StorageImpl*)>) storageCreatedCallbacks;
/** @ingroup SURF_callbacks
* @brief Callbacks handler which emit the callbacks after Storage destruction *
* @details Callback functions have the following signature: `void(StoragePtr)`
*/
-XBT_PUBLIC_DATA(simgrid::xbt::signal<void(simgrid::surf::StorageImpl*)>) storageDestructedCallbacks;
+XBT_PUBLIC_DATA(simgrid::xbt::signal<void(StorageImpl*)>) storageDestructedCallbacks;
/** @ingroup SURF_callbacks
* @brief Callbacks handler which emit the callbacks after Storage State changed *
* @details Callback functions have the following signature: `void(StorageAction *action, int previouslyOn, int
* currentlyOn)`
*/
-XBT_PUBLIC_DATA(simgrid::xbt::signal<void(simgrid::surf::StorageImpl*, int, int)>) storageStateChangedCallbacks;
+XBT_PUBLIC_DATA(simgrid::xbt::signal<void(StorageImpl*, int, int)>) storageStateChangedCallbacks;
/** @ingroup SURF_callbacks
* @brief Callbacks handler which emit the callbacks after StorageAction State changed *
* @details Callback functions have the following signature: `void(StorageAction *action, simgrid::surf::Action::State
* old, simgrid::surf::Action::State current)`
*/
-XBT_PUBLIC_DATA(simgrid::xbt::signal<void(simgrid::surf::StorageAction*, simgrid::surf::Action::State,
- simgrid::surf::Action::State)>)
+XBT_PUBLIC_DATA(simgrid::xbt::signal<void(StorageAction*, Action::State, Action::State)>)
storageActionStateChangedCallbacks;
/*********
* @brief SURF storage interface class
* @details A Storage represent a storage unit (e.g.: hard drive, usb key)
*/
-class StorageImpl : public simgrid::surf::Resource, public simgrid::surf::PropertyHolder {
+class StorageImpl : public Resource, public PropertyHolder {
public:
/** @brief Storage constructor */
StorageImpl(Model* model, std::string name, lmm_system_t maxminSystem, double bread, double bwrite,
* @return The StorageAction corresponding to the writing
*/
virtual StorageAction* write(sg_size_t size) = 0;
-
- /**
- * @brief Get the content of the current Storage
- *
- * @return A map with path as keys and size in bytes as values
- */
- virtual std::map<std::string, sg_size_t>* getContent();
-
- /**
- * @brief Get the available size in bytes of the current Storage
- *
- * @return The available size in bytes of the current Storage
- */
- virtual sg_size_t getFreeSize();
-
- /**
- * @brief Get the used size in bytes of the current Storage
- *
- * @return The used size in bytes of the current Storage
- */
- virtual sg_size_t getUsedSize();
virtual sg_size_t getSize() { return size_; }
virtual std::string getHost() { return attach_; }
- std::map<std::string, sg_size_t>* parseContent(std::string filename);
static std::unordered_map<std::string, StorageImpl*>* storagesMap() { return StorageImpl::storages; }
lmm_constraint_t constraintWrite_; /* Constraint for maximum write bandwidth*/
std::string typeId_;
sg_size_t usedSize_ = 0;
+ std::string content_name;
private:
sg_size_t size_;
static std::unordered_map<std::string, StorageImpl*>* storages;
- std::map<std::string, sg_size_t>* content_;
// Name of the host to which this storage is attached. Only used at platform parsing time, then the interface stores
// the Host directly.
std::string attach_;
e_surf_action_storage_type_t type_;
StorageImpl* storage_;
- FileImpl* file_ = nullptr;
};
class StorageType {
//defining the last timestamp that we can safely dump to trace file
//without losing the event ascending order (considering all CPU's)
double smaller = -1;
- ActionList *actionSet = getRunningActionSet();
- ActionList::iterator it(actionSet->begin());
- ActionList::iterator itend(actionSet->end());
- for (; it != itend; ++it) {
- CpuAction *action = static_cast<CpuAction*>(&*it);
- if (smaller < 0 || action->getLastUpdate() < smaller)
- smaller = action->getLastUpdate();
+ for (Action const& action : *getRunningActionSet()) {
+ if (smaller < 0 || action.getLastUpdate() < smaller)
+ smaller = action.getLastUpdate();
}
if (smaller > 0) {
TRACE_last_timestamp_to_dump = smaller;
void CpuModel::updateActionsStateFull(double now, double delta)
{
- CpuAction *action = nullptr;
- ActionList *running_actions = getRunningActionSet();
- ActionList::iterator it(running_actions->begin());
- ActionList::iterator itNext = it;
- ActionList::iterator itend(running_actions->end());
- for (; it != itend; it = itNext) {
- ++itNext;
- action = static_cast<CpuAction*>(&*it);
+ for (auto it = std::begin(*getRunningActionSet()); it != std::end(*getRunningActionSet());) {
+ CpuAction& action = static_cast<CpuAction&>(*it);
+ ++it; // increment iterator here since the following calls to action.finish() may invalidate it
if (TRACE_is_enabled()) {
- Cpu *cpu = static_cast<Cpu*> (lmm_constraint_id(lmm_get_cnst_from_var(getMaxminSystem(), action->getVariable(), 0)) );
+ Cpu* cpu =
+ static_cast<Cpu*>(lmm_constraint_id(lmm_get_cnst_from_var(getMaxminSystem(), action.getVariable(), 0)));
- TRACE_surf_host_set_utilization(cpu->getCname(), action->getCategory(),
- lmm_variable_getvalue(action->getVariable()), now - delta, delta);
+ TRACE_surf_host_set_utilization(cpu->getCname(), action.getCategory(),
+ lmm_variable_getvalue(action.getVariable()), now - delta, delta);
TRACE_last_timestamp_to_dump = now - delta;
}
- action->updateRemains(lmm_variable_getvalue(action->getVariable()) * delta);
+ action.updateRemains(lmm_variable_getvalue(action.getVariable()) * delta);
- if (action->getMaxDuration() != NO_MAX_DURATION)
- action->updateMaxDuration(delta);
+ if (action.getMaxDuration() != NO_MAX_DURATION)
+ action.updateMaxDuration(delta);
- if (((action->getRemainsNoUpdate() <= 0) && (lmm_get_variable_weight(action->getVariable()) > 0)) ||
- ((action->getMaxDuration() != NO_MAX_DURATION) && (action->getMaxDuration() <= 0))) {
- action->finish(Action::State::done);
+ if (((action.getRemainsNoUpdate() <= 0) && (lmm_get_variable_weight(action.getVariable()) > 0)) ||
+ ((action.getMaxDuration() != NO_MAX_DURATION) && (action.getMaxDuration() <= 0))) {
+ action.finish(Action::State::done);
}
}
}
{
double min_action_duration = -1;
-/* iterates over modified cpus to update share resources */
- CpuTiList::iterator itend(modifiedCpu_->end());
- CpuTiList::iterator it(modifiedCpu_->begin());
- while (it != itend) {
- CpuTi *ti = &*it;
- ++it;
- ti->updateActionsFinishTime(now);
+ /* iterates over modified cpus to update share resources */
+ for (auto it = std::begin(*modifiedCpu_); it != std::end(*modifiedCpu_);) {
+ CpuTi& ti = *it;
+ ++it; // increment iterator here since the following call to ti.updateActionsFinishTime() may invalidate it
+ ti.updateActionsFinishTime(now);
}
-/* get the min next event if heap not empty */
+ /* get the min next event if heap not empty */
if (not actionHeapIsEmpty())
min_action_duration = actionHeapTopDate() - now;
double date = surf_get_clock();
/* put all action running on cpu to failed */
- ActionTiList::iterator itend(actionSet_->end());
- for (ActionTiList::iterator it(actionSet_->begin()); it != itend; ++it) {
- CpuTiAction *action = &*it;
- if (action->getState() == Action::State::running
- || action->getState() == Action::State::ready
- || action->getState() == Action::State::not_in_the_system) {
- action->setFinishTime(date);
- action->setState(Action::State::failed);
- action->heapRemove(model()->getActionHeap());
+ for (CpuTiAction& action : *actionSet_) {
+ if (action.getState() == Action::State::running || action.getState() == Action::State::ready ||
+ action.getState() == Action::State::not_in_the_system) {
+ action.setFinishTime(date);
+ action.setState(Action::State::failed);
+ action.heapRemove(model()->getActionHeap());
}
}
}
void CpuTi::updateActionsFinishTime(double now)
{
- CpuTiAction *action;
double sum_priority = 0.0;
double total_area;
/* update remaining amount of actions */
updateRemainingAmount(now);
- ActionTiList::iterator itend(actionSet_->end());
- for (ActionTiList::iterator it(actionSet_->begin()); it != itend; ++it) {
- action = &*it;
+ for (CpuTiAction const& action : *actionSet_) {
/* action not running, skip it */
- if (action->getStateSet() != surf_cpu_model_pm->getRunningActionSet())
+ if (action.getStateSet() != surf_cpu_model_pm->getRunningActionSet())
continue;
/* bogus priority, skip it */
- if (action->getPriority() <= 0)
+ if (action.getPriority() <= 0)
continue;
/* action suspended, skip it */
- if (action->suspended_ != 0)
+ if (action.suspended_ != 0)
continue;
- sum_priority += 1.0 / action->getPriority();
+ sum_priority += 1.0 / action.getPriority();
}
sumPriority_ = sum_priority;
- for (ActionTiList::iterator it(actionSet_->begin()); it != itend; ++it) {
- action = &*it;
+ for (CpuTiAction& action : *actionSet_) {
double min_finish = -1;
/* action not running, skip it */
- if (action->getStateSet() != surf_cpu_model_pm->getRunningActionSet())
+ if (action.getStateSet() != surf_cpu_model_pm->getRunningActionSet())
continue;
/* verify if the action is really running on cpu */
- if (action->suspended_ == 0 && action->getPriority() > 0) {
+ if (action.suspended_ == 0 && action.getPriority() > 0) {
/* total area needed to finish the action. Used in trace integration */
- total_area = (action->getRemains()) * sum_priority * action->getPriority();
+ total_area = (action.getRemains()) * sum_priority * action.getPriority();
total_area /= speed_.peak;
- action->setFinishTime(speedIntegratedTrace_->solve(now, total_area));
+ action.setFinishTime(speedIntegratedTrace_->solve(now, total_area));
/* verify which event will happen before (max_duration or finish time) */
- if (action->getMaxDuration() > NO_MAX_DURATION &&
- action->getStartTime() + action->getMaxDuration() < action->getFinishTime())
- min_finish = action->getStartTime() + action->getMaxDuration();
+ if (action.getMaxDuration() > NO_MAX_DURATION &&
+ action.getStartTime() + action.getMaxDuration() < action.getFinishTime())
+ min_finish = action.getStartTime() + action.getMaxDuration();
else
- min_finish = action->getFinishTime();
+ min_finish = action.getFinishTime();
} else {
/* put the max duration time on heap */
- if (action->getMaxDuration() > NO_MAX_DURATION)
- min_finish = action->getStartTime() + action->getMaxDuration();
+ if (action.getMaxDuration() > NO_MAX_DURATION)
+ min_finish = action.getStartTime() + action.getMaxDuration();
}
/* add in action heap */
if (min_finish > NO_MAX_DURATION)
- action->heapUpdate(model()->getActionHeap(), min_finish, NOTSET);
+ action.heapUpdate(model()->getActionHeap(), min_finish, NOTSET);
else
- action->heapRemove(model()->getActionHeap());
+ action.heapRemove(model()->getActionHeap());
XBT_DEBUG("Update finish time: Cpu(%s) Action: %p, Start Time: %f Finish Time: %f Max duration %f", getCname(),
- action, action->getStartTime(), action->getFinishTime(), action->getMaxDuration());
+ &action, action.getStartTime(), action.getFinishTime(), action.getMaxDuration());
}
/* remove from modified cpu */
modified(false);
/* compute the integration area */
double area_total = speedIntegratedTrace_->integrate(lastUpdate_, now) * speed_.peak;
XBT_DEBUG("Flops total: %f, Last update %f", area_total, lastUpdate_);
- ActionTiList::iterator itend(actionSet_->end());
- for (ActionTiList::iterator it(actionSet_->begin()); it != itend; ++it) {
- CpuTiAction *action = &*it;
+ for (CpuTiAction& action : *actionSet_) {
/* action not running, skip it */
- if (action->getStateSet() != model()->getRunningActionSet())
+ if (action.getStateSet() != model()->getRunningActionSet())
continue;
/* bogus priority, skip it */
- if (action->getPriority() <= 0)
+ if (action.getPriority() <= 0)
continue;
/* action suspended, skip it */
- if (action->suspended_ != 0)
+ if (action.suspended_ != 0)
continue;
/* action don't need update */
- if (action->getStartTime() >= now)
+ if (action.getStartTime() >= now)
continue;
/* skip action that are finishing now */
- if (action->getFinishTime() >= 0 && action->getFinishTime() <= now)
+ if (action.getFinishTime() >= 0 && action.getFinishTime() <= now)
continue;
/* update remaining */
- action->updateRemains(area_total / (sumPriority_ * action->getPriority()));
- XBT_DEBUG("Update remaining action(%p) remaining %f", action, action->getRemainsNoUpdate());
+ action.updateRemains(area_total / (sumPriority_ * action.getPriority()));
+ XBT_DEBUG("Update remaining action(%p) remaining %f", &action, action.getRemainsNoUpdate());
}
lastUpdate_ = now;
}
lmm_on_disabled_var(sys, elem.constraint);
}
- // Check if we can enable new variables going through the constraints where var was.
- // Do it after removing all elements, so the first disabled variables get priority over those with smaller requirement
- for (s_lmm_element_t& elem : var->cnsts) {
- if (xbt_swag_size(&(elem.constraint->disabled_element_set)))
- lmm_on_disabled_var(sys, elem.constraint);
- }
-
var->cnsts.clear();
lmm_check_concurrency(sys);
//A priori not a big performance issue, but we might do better by calling lmm_update_modified_set within the for loops
// (after doing the first for enabling==1, and before doing the last for disabling==1)
void lmm_enable_var(lmm_system_t sys, lmm_variable_t var){
- xbt_assert(lmm_can_enable_var(var));
+ xbt_assert(not XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug) || lmm_can_enable_var(var));
var->sharing_weight = var->staged_weight;
var->staged_weight = 0;
return xbt_swag_belongs(cnst, &(sys->active_constraint_set));
}
-inline lmm_constraint_t lmm_get_first_active_constraint(lmm_system_t sys)
-{
- return (lmm_constraint_t)xbt_swag_getFirst(&(sys->active_constraint_set));
-}
-
-inline lmm_constraint_t lmm_get_next_active_constraint(lmm_system_t sys, lmm_constraint_t cnst)
-{
- return (lmm_constraint_t)xbt_swag_getNext(cnst, (sys->active_constraint_set).offset);
-}
-
/** \brief Update the constraint set propagating recursively to other constraints so the system should not be entirely
* computed.
*
{
void* _elem;
- //TODOLATER: Why lmm_modified_set has been changed in git version 2392B5157...? Looks equivalent logically and less obvious..
xbt_swag_foreach(_elem, &cnst->enabled_element_set) {
lmm_variable_t var = ((lmm_element_t)_elem)->variable;
for (s_lmm_element_t const& elem : var->cnsts) {
}
maxminSystem_ = lmm_system_new(selectiveUpdate_);
- loopback_ = createLink("__loopback__", 498000000, 0.000015, SURF_LINK_FATPIPE);
+ loopback_ = NetworkCm02Model::createLink("__loopback__", 498000000, 0.000015, SURF_LINK_FATPIPE);
if (getUpdateMechanism() == UM_LAZY) {
modifiedSet_ = new ActionLmmList();
void NetworkCm02Model::updateActionsStateFull(double now, double delta)
{
- ActionList *running_actions = getRunningActionSet();
- ActionList::iterator it(running_actions->begin());
- ActionList::iterator itend(running_actions->end());
- while (it != itend) {
- NetworkCm02Action *action = static_cast<NetworkCm02Action*> (&*it);
- ++it;
- XBT_DEBUG("Something happened to action %p", action);
- double deltap = delta;
- if (action->latency_ > 0) {
- if (action->latency_ > deltap) {
- double_update(&(action->latency_), deltap, sg_surf_precision);
- deltap = 0.0;
- } else {
- double_update(&(deltap), action->latency_, sg_surf_precision);
- action->latency_ = 0.0;
- }
- if (action->latency_ <= 0.0 && not action->isSuspended())
- lmm_update_variable_weight(maxminSystem_, action->getVariable(), action->weight_);
- }
- if (TRACE_is_enabled()) {
- int n = lmm_get_number_of_cnst_from_var(maxminSystem_, action->getVariable());
- for (int i = 0; i < n; i++){
- lmm_constraint_t constraint = lmm_get_cnst_from_var(maxminSystem_, action->getVariable(), i);
-
- NetworkCm02Link* link = static_cast<NetworkCm02Link*>(lmm_constraint_id(constraint));
- TRACE_surf_link_set_utilization(link->getCname(), action->getCategory(),
- (lmm_variable_getvalue(action->getVariable()) *
- lmm_get_cnst_weight_from_var(maxminSystem_, action->getVariable(), i)),
- action->getLastUpdate(), now - action->getLastUpdate());
- }
+ for (auto it = std::begin(*getRunningActionSet()); it != std::end(*getRunningActionSet());) {
+ NetworkCm02Action& action = static_cast<NetworkCm02Action&>(*it);
+ ++it; // increment iterator here since the following calls to action.finish() may invalidate it
+ XBT_DEBUG("Something happened to action %p", &action);
+ double deltap = delta;
+ if (action.latency_ > 0) {
+ if (action.latency_ > deltap) {
+ double_update(&action.latency_, deltap, sg_surf_precision);
+ deltap = 0.0;
+ } else {
+ double_update(&deltap, action.latency_, sg_surf_precision);
+ action.latency_ = 0.0;
}
- if (not lmm_get_number_of_cnst_from_var(maxminSystem_, action->getVariable())) {
- /* There is actually no link used, hence an infinite bandwidth. This happens often when using models like
- * vivaldi. In such case, just make sure that the action completes immediately.
- */
- action->updateRemains(action->getRemains());
+ if (action.latency_ <= 0.0 && not action.isSuspended())
+ lmm_update_variable_weight(maxminSystem_, action.getVariable(), action.weight_);
+ }
+ if (TRACE_is_enabled()) {
+ int n = lmm_get_number_of_cnst_from_var(maxminSystem_, action.getVariable());
+ for (int i = 0; i < n; i++) {
+ lmm_constraint_t constraint = lmm_get_cnst_from_var(maxminSystem_, action.getVariable(), i);
+
+ NetworkCm02Link* link = static_cast<NetworkCm02Link*>(lmm_constraint_id(constraint));
+ TRACE_surf_link_set_utilization(link->getCname(), action.getCategory(),
+ (lmm_variable_getvalue(action.getVariable()) *
+ lmm_get_cnst_weight_from_var(maxminSystem_, action.getVariable(), i)),
+ action.getLastUpdate(), now - action.getLastUpdate());
}
- action->updateRemains(lmm_variable_getvalue(action->getVariable()) * delta);
+ }
+ if (not lmm_get_number_of_cnst_from_var(maxminSystem_, action.getVariable())) {
+ /* There is actually no link used, hence an infinite bandwidth. This happens often when using models like
+ * vivaldi. In such case, just make sure that the action completes immediately.
+ */
+ action.updateRemains(action.getRemains());
+ }
+ action.updateRemains(lmm_variable_getvalue(action.getVariable()) * delta);
- if (action->getMaxDuration() > NO_MAX_DURATION)
- action->updateMaxDuration(delta);
+ if (action.getMaxDuration() > NO_MAX_DURATION)
+ action.updateMaxDuration(delta);
- if (((action->getRemains() <= 0) && (lmm_get_variable_weight(action->getVariable()) > 0)) ||
- ((action->getMaxDuration() > NO_MAX_DURATION) && (action->getMaxDuration() <= 0))) {
- action->finish(Action::State::done);
+ if (((action.getRemains() <= 0) && (lmm_get_variable_weight(action.getVariable()) > 0)) ||
+ ((action.getMaxDuration() > NO_MAX_DURATION) && (action.getMaxDuration() <= 0))) {
+ action.finish(Action::State::done);
}
}
}
double NetworkConstantModel::nextOccuringEvent(double /*now*/)
{
double min = -1.0;
-
- ActionList* actionSet = getRunningActionSet();
- ActionList::iterator it(actionSet->begin());
- ActionList::iterator itend(actionSet->end());
- for (; it != itend; ++it) {
- NetworkConstantAction* action = static_cast<NetworkConstantAction*>(&*it);
- if (action->latency_ > 0 && (min < 0 || action->latency_ < min))
- min = action->latency_;
+ for (Action const& action : *getRunningActionSet()) {
+ const NetworkConstantAction& net_action = static_cast<const NetworkConstantAction&>(action);
+ if (net_action.latency_ > 0 && (min < 0 || net_action.latency_ < min))
+ min = net_action.latency_;
}
-
return min;
}
void NetworkConstantModel::updateActionsState(double /*now*/, double delta)
{
- NetworkConstantAction* action = nullptr;
- ActionList* actionSet = getRunningActionSet();
- ActionList::iterator it(actionSet->begin());
- ActionList::iterator itNext = it;
- ActionList::iterator itend(actionSet->end());
- for (; it != itend; it = itNext) {
- ++itNext;
- action = static_cast<NetworkConstantAction*>(&*it);
- if (action->latency_ > 0) {
- if (action->latency_ > delta) {
- double_update(&(action->latency_), delta, sg_surf_precision);
+ for (auto it = std::begin(*getRunningActionSet()); it != std::end(*getRunningActionSet());) {
+ NetworkConstantAction& action = static_cast<NetworkConstantAction&>(*it);
+ ++it; // increment iterator here since the following calls to action.finish() may invalidate it
+ if (action.latency_ > 0) {
+ if (action.latency_ > delta) {
+ double_update(&action.latency_, delta, sg_surf_precision);
} else {
- action->latency_ = 0.0;
+ action.latency_ = 0.0;
}
}
- action->updateRemains(action->getCost() * delta / action->initialLatency_);
- if (action->getMaxDuration() != NO_MAX_DURATION)
- action->updateMaxDuration(delta);
+ action.updateRemains(action.getCost() * delta / action.initialLatency_);
+ if (action.getMaxDuration() != NO_MAX_DURATION)
+ action.updateMaxDuration(delta);
- if ((action->getRemainsNoUpdate() <= 0) ||
- ((action->getMaxDuration() != NO_MAX_DURATION) && (action->getMaxDuration() <= 0))) {
- action->finish(Action::State::done);
+ if ((action.getRemainsNoUpdate() <= 0) ||
+ ((action.getMaxDuration() != NO_MAX_DURATION) && (action.getMaxDuration() <= 0))) {
+ action.finish(Action::State::done);
}
}
}
{
return links->size();
}
+ void LinkImpl::linksList(std::vector<s4u::Link*>* linkList)
+ {
+ for (auto const& kv : *links) {
+ linkList->push_back(&kv.second->piface_);
+ }
+ }
+
/** @brief Returns a list of all existing links */
LinkImpl** LinkImpl::linksList()
{
{
double minRes = Model::nextOccuringEventFull(now);
- for (auto it(getRunningActionSet()->begin()); it != getRunningActionSet()->end(); it++) {
- NetworkAction *action = static_cast<NetworkAction*>(&*it);
- if (action->latency_ > 0)
- minRes = (minRes < 0) ? action->latency_ : std::min(minRes, action->latency_);
+ for (Action const& action : *getRunningActionSet()) {
+ const NetworkAction& net_action = static_cast<const NetworkAction&>(action);
+ if (net_action.latency_ > 0)
+ minRes = (minRes < 0) ? net_action.latency_ : std::min(minRes, net_action.latency_);
}
XBT_DEBUG("Min of share resources %f", minRes);
static LinkImpl* byName(std::string name);
static int linksCount();
static LinkImpl** linksList();
+ static void linksList(std::vector<s4u::Link*>* linkList);
static void linksExit();
};
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_energy, surf, "Logging specific to the SURF energy plugin");
namespace simgrid {
-namespace energy {
+namespace plugin {
class PowerRange {
public:
{
xbt_assert(not power_range_watts_list.empty(), "No power range properties specified for host %s", host->getCname());
+ /*
+ * * Return watts_off if pstate == pstate_off
+ * * this happens when host is off
+ */
+ if (this->pstate == pstate_off) {
+ return watts_off;
+ }
+
/* min_power corresponds to the power consumed when only one core is active */
/* max_power is the power consumed at 100% cpu load */
auto range = power_range_watts_list.at(this->pstate);
}
}
-using simgrid::energy::HostEnergy;
+using simgrid::plugin::HostEnergy;
/* **************************** events callback *************************** */
static void onCreation(simgrid::s4u::Host& host)
using simgrid::plugin::HostLoad;
/* **************************** events callback *************************** */
-static void on_host_added(simgrid::s4u::Host& host)
-{
- if (dynamic_cast<simgrid::s4u::VirtualMachine*>(&host)) // Ignore virtual machines
- return;
- host.extension_set(new HostLoad(&host));
-}
-
/* This callback is fired either when the host changes its state (on/off) or its speed
* (because the user changed the pstate, or because of external trace events) */
static void onHostChange(simgrid::s4u::Host& host)
if (dynamic_cast<simgrid::s4u::VirtualMachine*>(&host)) // Ignore virtual machines
return;
- HostLoad* host_load = host.extension<HostLoad>();
- host_load->update();
+ host.extension<HostLoad>()->update();
}
/* This callback is called when an action (computation, idle, ...) terminates */
HostLoad::EXTENSION_ID = simgrid::s4u::Host::extension_create<HostLoad>();
- simgrid::s4u::Host::onCreation.connect(&on_host_added);
+ /* When attaching a callback into a signal, you can use a lambda as follows, or a regular function as done below */
+
+ simgrid::s4u::Host::onCreation.connect([](simgrid::s4u::Host& host) {
+ if (dynamic_cast<simgrid::s4u::VirtualMachine*>(&host)) // Ignore virtual machines
+ return;
+ host.extension_set(new HostLoad(&host));
+ });
+
simgrid::surf::CpuAction::onStateChange.connect(&onActionStateChange);
simgrid::s4u::Host::onStateChange.connect(&onHostChange);
simgrid::s4u::Host::onSpeedChange.connect(&onHostChange);
--- /dev/null
+/* Copyright (c) 2017. 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/plugins/energy.h"
+#include "simgrid/s4u/Engine.hpp"
+#include "simgrid/simix.hpp"
+#include "src/surf/network_interface.hpp"
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/algorithm/string/split.hpp>
+#include <map>
+#include <string>
+#include <utility>
+#include <vector>
+
+/** @addtogroup SURF_plugin_energy
+
+
+ This is the energy plugin, enabling to account for the dissipated energy in the simulated platform.
+
+ The energy consumption of a link depends directly on its current traffic load. Specify that consumption in your
+ platform file as follows:
+
+ \verbatim
+ <link id="SWITCH1" bandwidth="125000000" latency="5E-5" sharing_policy="SHARED" >
+ <prop id="watts" value="100.0:200.0" />
+ <prop id="watt_off" value="10" />
+ </link>
+ \endverbatim
+
+ The first property means that when your link is switched on, but without anything to do, it will dissipate 100 Watts.
+ If it's fully loaded, it will dissipate 200 Watts. If its load is at 50%, then it will dissipate 150 Watts.
+ The second property means that when your host is turned off, it will dissipate only 10 Watts (please note that these
+ values are arbitrary).
+
+ To simulate the energy-related elements, first call the simgrid#energy#sg_link_energy_plugin_init() before your
+ #MSG_init(),
+ and then use the following function to retrieve the consumption of a given link: MSG_link_get_consumed_energy().
+ */
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(link_energy, surf, "Logging specific to the SURF LinkEnergy plugin");
+
+namespace simgrid {
+namespace plugin {
+
+class LinkPowerRange {
+public:
+ double idle;
+ double busy;
+
+ LinkPowerRange(double idle, double busy) : idle(idle), busy(busy) {}
+};
+
+class LinkEnergy {
+public:
+ static simgrid::xbt::Extension<simgrid::s4u::Link, LinkEnergy> EXTENSION_ID;
+
+ explicit LinkEnergy(simgrid::s4u::Link* ptr);
+ ~LinkEnergy();
+
+ double getALinkTotalPower();
+ void initWattsRangeList();
+ double getTotalEnergy();
+ void update();
+
+private:
+ double getPower();
+
+ simgrid::s4u::Link* link{};
+
+ std::vector<LinkPowerRange> power_range_watts_list{};
+
+ double total_energy{0.0};
+ double last_updated{0.0}; /*< Timestamp of the last energy update event*/
+};
+
+simgrid::xbt::Extension<simgrid::s4u::Link, LinkEnergy> LinkEnergy::EXTENSION_ID;
+
+LinkEnergy::LinkEnergy(simgrid::s4u::Link* ptr) : link(ptr), last_updated(surf_get_clock())
+{
+}
+
+LinkEnergy::~LinkEnergy() = default;
+
+void LinkEnergy::update()
+{
+ double power = getPower();
+ double now = surf_get_clock();
+ total_energy += power * (now - last_updated);
+ last_updated = now;
+}
+
+void LinkEnergy::initWattsRangeList()
+{
+
+ if (!power_range_watts_list.empty())
+ return;
+
+ const char* all_power_values_str = this->link->getProperty("watt_range");
+
+ if (all_power_values_str == nullptr)
+ return;
+
+ std::vector<std::string> all_power_values;
+ boost::split(all_power_values, all_power_values_str, boost::is_any_of(","));
+
+ for (auto current_power_values_str : all_power_values) {
+ /* retrieve the power values associated */
+ std::vector<std::string> current_power_values;
+ boost::split(current_power_values, current_power_values_str, boost::is_any_of(":"));
+ xbt_assert(current_power_values.size() == 2, "Power properties incorrectly defined - "
+ "could not retrieve idle and busy power values for link %s",
+ this->link->getCname());
+
+ /* min_power corresponds to the idle power (link load = 0) */
+ /* max_power is the power consumed at 100% link load */
+ char* idle = bprintf("Invalid idle power value for link%s", this->link->getCname());
+ char* busy = bprintf("Invalid busy power value for %s", this->link->getCname());
+
+ double idleVal = xbt_str_parse_double((current_power_values.at(0)).c_str(), idle);
+
+ double busyVal = xbt_str_parse_double((current_power_values.at(1)).c_str(), busy);
+
+ this->power_range_watts_list.push_back(LinkPowerRange(idleVal, busyVal));
+
+ xbt_free(idle);
+ xbt_free(busy);
+ update();
+ }
+}
+
+double LinkEnergy::getPower()
+{
+
+ if (power_range_watts_list.empty())
+ return 0.0;
+
+ auto range = power_range_watts_list[0];
+
+ double busy = range.busy;
+ double idle = range.idle;
+
+ double power_slope = busy - idle;
+
+ double normalized_link_usage = link->getUsage() / link->bandwidth();
+ double dynamic_power = power_slope * normalized_link_usage;
+
+ return idle + dynamic_power;
+}
+
+double LinkEnergy::getTotalEnergy()
+{
+ update();
+ return this->total_energy;
+}
+}
+}
+
+using simgrid::plugin::LinkEnergy;
+
+/* **************************** events callback *************************** */
+static void onCreation(simgrid::s4u::Link& link)
+{
+ XBT_DEBUG("onCreation is called for link: %s", link.getCname());
+ link.extension_set(new LinkEnergy(&link));
+}
+
+static void onCommunicate(simgrid::surf::NetworkAction* action, simgrid::s4u::Host* src, simgrid::s4u::Host* dst)
+{
+ XBT_DEBUG("onCommunicate is called");
+ for (simgrid::surf::LinkImpl* link : action->links()) {
+
+ if (link == nullptr)
+ continue;
+
+ XBT_DEBUG("Update link %s", link->getCname());
+ // Get the link_energy extension for the relevant link
+ LinkEnergy* link_energy = link->piface_.extension<LinkEnergy>();
+ link_energy->initWattsRangeList();
+ link_energy->update();
+ }
+}
+
+static void onActionStateChange(simgrid::surf::NetworkAction* action)
+{
+ XBT_DEBUG("onActionStateChange is called");
+ for (simgrid::surf::LinkImpl* link : action->links()) {
+
+ if (link == nullptr)
+ continue;
+
+ // Get the link_energy extension for the relevant link
+ LinkEnergy* link_energy = link->piface_.extension<LinkEnergy>();
+ link_energy->update();
+ }
+}
+
+static void onLinkStateChange(simgrid::s4u::Link& link)
+{
+ XBT_DEBUG("onLinkStateChange is called for link: %s", link.getCname());
+
+ LinkEnergy* link_energy = link.extension<LinkEnergy>();
+ link_energy->update();
+}
+
+static void onLinkDestruction(simgrid::s4u::Link& link)
+{
+ XBT_DEBUG("onLinkDestruction is called for link: %s", link.getCname());
+
+ LinkEnergy* link_energy = link.extension<LinkEnergy>();
+ link_energy->update();
+}
+
+static void computeAndDisplayTotalEnergy()
+{
+ std::vector<simgrid::s4u::Link*> link_list;
+ simgrid::s4u::Engine::getInstance()->getLinkList(&link_list);
+ double total_energy = 0.0; // Total dissipated energy (whole platform)
+ for (const auto link : link_list) {
+ LinkEnergy* link_energy = link->extension<LinkEnergy>();
+
+ double a_link_total_energy = link_energy->getTotalEnergy();
+ total_energy += a_link_total_energy;
+ const char* name = link->getCname();
+ if (strcmp(name, "__loopback__"))
+ XBT_INFO("Link '%s' total consumption: %f", name, a_link_total_energy);
+ }
+
+ XBT_INFO("Total energy over all links: %f", total_energy);
+}
+
+static void onSimulationEnd()
+{
+ computeAndDisplayTotalEnergy();
+}
+/* **************************** Public interface *************************** */
+SG_BEGIN_DECL()
+/** \ingroup SURF_plugin_energy
+ * \brief Enable energy plugin
+ * \details Enable energy plugin to get joules consumption of each cpu. You should call this function before
+ * #MSG_init().
+ */
+void sg_link_energy_plugin_init()
+{
+
+ if (LinkEnergy::EXTENSION_ID.valid())
+ return;
+ LinkEnergy::EXTENSION_ID = simgrid::s4u::Link::extension_create<LinkEnergy>();
+
+ simgrid::s4u::Link::onCreation.connect(&onCreation);
+ simgrid::s4u::Link::onStateChange.connect(&onLinkStateChange);
+ simgrid::s4u::Link::onDestruction.connect(&onLinkDestruction);
+ simgrid::s4u::Link::onCommunicationStateChange.connect(&onActionStateChange);
+ simgrid::s4u::Link::onCommunicate.connect(&onCommunicate);
+ simgrid::s4u::onSimulationEnd.connect(&onSimulationEnd);
+}
+
+SG_END_DECL()
, hostModel_(hmodel)
{
maxminSystem_ = sys;
- loopback_ = createLink("__loopback__", 498000000, 0.000015, SURF_LINK_FATPIPE);
+ loopback_ = NetworkL07Model::createLink("__loopback__", 498000000, 0.000015, SURF_LINK_FATPIPE);
}
NetworkL07Model::~NetworkL07Model()
double HostL07Model::nextOccuringEvent(double now)
{
double min = HostModel::nextOccuringEventFull(now);
- ActionList::iterator it(getRunningActionSet()->begin());
- ActionList::iterator itend(getRunningActionSet()->end());
- for (; it != itend; ++it) {
- L07Action *action = static_cast<L07Action*>(&*it);
- if (action->latency_ > 0 && (min < 0 || action->latency_ < min)) {
- min = action->latency_;
- XBT_DEBUG("Updating min with %p (start %f): %f", action, action->getStartTime(), min);
+ for (Action const& action : *getRunningActionSet()) {
+ const L07Action& net_action = static_cast<const L07Action&>(action);
+ if (net_action.latency_ > 0 && (min < 0 || net_action.latency_ < min)) {
+ min = net_action.latency_;
+ XBT_DEBUG("Updating min with %p (start %f): %f", &net_action, net_action.getStartTime(), min);
}
}
XBT_DEBUG("min value: %f", min);
return min;
}
-void HostL07Model::updateActionsState(double /*now*/, double delta) {
-
- L07Action *action;
- ActionList *actionSet = getRunningActionSet();
- ActionList::iterator it(actionSet->begin());
- ActionList::iterator itNext = it;
- ActionList::iterator itend(actionSet->end());
-
- for (; it != itend; it = itNext) {
- ++itNext;
- action = static_cast<L07Action*>(&*it);
- if (action->latency_ > 0) {
- if (action->latency_ > delta) {
- double_update(&(action->latency_), delta, sg_surf_precision);
+void HostL07Model::updateActionsState(double /*now*/, double delta)
+{
+ for (auto it = std::begin(*getRunningActionSet()); it != std::end(*getRunningActionSet());) {
+ L07Action& action = static_cast<L07Action&>(*it);
+ ++it; // increment iterator here since the following calls to action.finish() may invalidate it
+ if (action.latency_ > 0) {
+ if (action.latency_ > delta) {
+ double_update(&(action.latency_), delta, sg_surf_precision);
} else {
- action->latency_ = 0.0;
+ action.latency_ = 0.0;
}
- if ((action->latency_ <= 0.0) && (action->isSuspended() == 0)) {
- action->updateBound();
- lmm_update_variable_weight(maxminSystem_, action->getVariable(), 1.0);
+ if ((action.latency_ <= 0.0) && (action.isSuspended() == 0)) {
+ action.updateBound();
+ lmm_update_variable_weight(maxminSystem_, action.getVariable(), 1.0);
}
}
- XBT_DEBUG("Action (%p) : remains (%g) updated by %g.",
- action, action->getRemains(), lmm_variable_getvalue(action->getVariable()) * delta);
- action->updateRemains(lmm_variable_getvalue(action->getVariable()) * delta);
+ XBT_DEBUG("Action (%p) : remains (%g) updated by %g.", &action, action.getRemains(),
+ lmm_variable_getvalue(action.getVariable()) * delta);
+ action.updateRemains(lmm_variable_getvalue(action.getVariable()) * delta);
- if (action->getMaxDuration() > NO_MAX_DURATION)
- action->updateMaxDuration(delta);
+ if (action.getMaxDuration() > NO_MAX_DURATION)
+ action.updateMaxDuration(delta);
- XBT_DEBUG("Action (%p) : remains (%g).", action, action->getRemains());
+ XBT_DEBUG("Action (%p) : remains (%g).", &action, action.getRemains());
/* In the next if cascade, the action can be finished either because:
* - The amount of remaining work reached 0
* If it's not done, it may have failed.
*/
- if (((action->getRemains() <= 0) && (lmm_get_variable_weight(action->getVariable()) > 0)) ||
- ((action->getMaxDuration() > NO_MAX_DURATION) && (action->getMaxDuration() <= 0))) {
- action->finish(Action::State::done);
+ if (((action.getRemains() <= 0) && (lmm_get_variable_weight(action.getVariable()) > 0)) ||
+ ((action.getMaxDuration() > NO_MAX_DURATION) && (action.getMaxDuration() <= 0))) {
+ action.finish(Action::State::done);
} else {
/* Need to check that none of the model has failed */
int i = 0;
- lmm_constraint_t cnst = lmm_get_cnst_from_var(maxminSystem_, action->getVariable(), i);
+ lmm_constraint_t cnst = lmm_get_cnst_from_var(maxminSystem_, action.getVariable(), i);
while (cnst != nullptr) {
i++;
void *constraint_id = lmm_constraint_id(cnst);
if (static_cast<simgrid::surf::Resource*>(constraint_id)->isOff()) {
- XBT_DEBUG("Action (%p) Failed!!", action);
- action->finish(Action::State::failed);
+ XBT_DEBUG("Action (%p) Failed!!", &action);
+ action.finish(Action::State::failed);
break;
}
- cnst = lmm_get_cnst_from_var(maxminSystem_, action->getVariable(), i);
+ cnst = lmm_get_cnst_from_var(maxminSystem_, action.getVariable(), i);
}
}
}
double kill_time = process->kill_time;
int auto_restart = process->on_failure == SURF_ACTOR_ON_FAILURE_DIE ? 0 : 1;
- std::vector<std::string> args(process->argv, process->argv + process->argc);
- std::function<void()> code = factory(std::move(args));
+ std::string process_name = process->args[0];
+ std::function<void()> code = factory(std::move(process->args));
std::shared_ptr<std::map<std::string, std::string>> properties(process->properties);
smx_process_arg_t arg = nullptr;
arg = new simgrid::simix::ProcessArg();
- arg->name = std::string(process->argv[0]);
+ arg->name = process_name;
arg->code = code;
arg->data = nullptr;
arg->host = host;
if (start_time > SIMIX_get_clock()) {
arg = new simgrid::simix::ProcessArg();
- arg->name = std::string(process->argv[0]);
+ arg->name = process_name;
arg->code = std::move(code);
arg->data = nullptr;
arg->host = host;
void StorageN11Model::updateActionsState(double /*now*/, double delta)
{
- ActionList *actionSet = getRunningActionSet();
- ActionList::iterator it(actionSet->begin());
- ActionList::iterator itend(actionSet->end());
- while (it != itend) {
- StorageAction *action = static_cast<StorageAction*>(&*it);
- ++it;
- double current_progress = lrint(lmm_variable_getvalue(action->getVariable()) * delta);
-
- action->updateRemains(current_progress);
- if (action->type_ == WRITE) {
- action->storage_->usedSize_ += current_progress;
- action->file_->incrPosition(current_progress);
- action->file_->setSize(action->file_->tell());
-
- action->storage_->getContent()->erase(action->file_->getCname());
- action->storage_->getContent()->insert({action->file_->getCname(), action->file_->size()});
- }
+ for (auto it = std::begin(*getRunningActionSet()); it != std::end(*getRunningActionSet());) {
+ StorageAction& action = static_cast<StorageAction&>(*it);
+ ++it; // increment iterator here since the following calls to action.finish() may invalidate it
+ action.updateRemains(lrint(lmm_variable_getvalue(action.getVariable()) * delta));
- if (action->getMaxDuration() > NO_MAX_DURATION)
- action->updateMaxDuration(delta);
+ if (action.getMaxDuration() > NO_MAX_DURATION)
+ action.updateMaxDuration(delta);
- if (action->getRemainsNoUpdate() > 0 && lmm_get_variable_weight(action->getVariable()) > 0 &&
- action->storage_->usedSize_ == action->storage_->getSize()) {
- action->finish(Action::State::failed);
- } else if (((action->getRemainsNoUpdate() <= 0) && (lmm_get_variable_weight(action->getVariable()) > 0)) ||
- ((action->getMaxDuration() > NO_MAX_DURATION) && (action->getMaxDuration() <= 0))) {
- action->finish(Action::State::done);
+ if (((action.getRemainsNoUpdate() <= 0) && (lmm_get_variable_weight(action.getVariable()) > 0)) ||
+ ((action.getMaxDuration() > NO_MAX_DURATION) && (action.getMaxDuration() <= 0))) {
+ action.finish(Action::State::done);
}
}
}
#include <xbt/base.h>
-#include "FileImpl.hpp"
#include "StorageImpl.hpp"
#ifndef STORAGE_N11_HPP_
double min = -1;
- for (auto it(getRunningActionSet()->begin()); it != getRunningActionSet()->end(); ++it) {
- Action *action = &*it;
- double value = lmm_variable_getvalue(action->getVariable());
+ for (Action& action : *getRunningActionSet()) {
+ double value = lmm_variable_getvalue(action.getVariable());
if (value > 0) {
- if (action->getRemains() > 0)
- value = action->getRemainsNoUpdate() / value;
+ if (action.getRemains() > 0)
+ value = action.getRemainsNoUpdate() / value;
else
value = 0.0;
if (min < 0 || value < min) {
min = value;
- XBT_DEBUG("Updating min (value) with %p: %f", action, min);
+ XBT_DEBUG("Updating min (value) with %p: %f", &action, min);
}
}
- if ((action->getMaxDuration() >= 0) && (min<0 || action->getMaxDuration() < min)) {
- min = action->getMaxDuration();
- XBT_DEBUG("Updating min (duration) with %p: %f", action, min);
+ if ((action.getMaxDuration() >= 0) && (min < 0 || action.getMaxDuration() < min)) {
+ min = action.getMaxDuration();
+ XBT_DEBUG("Updating min (duration) with %p: %f", &action, min);
}
}
XBT_DEBUG("min value : %f", min);
};
struct s_sg_platf_process_cbarg_t {
- const char** argv = nullptr;
- int argc = 0;
+ std::vector<std::string> args;
std::map<std::string, std::string>* properties = nullptr;
const char* host = nullptr;
const char* function = nullptr;
current_property_set = nullptr;
}
-static int argc;
-static char **argv;
+static std::vector<std::string> arguments;
void STag_surfxml_process()
{
void STag_surfxml_actor()
{
ZONE_TAG = 0;
- argc = 1;
- argv = xbt_new(char *, 1);
- argv[0] = xbt_strdup(A_surfxml_actor_function);
+ arguments.assign(1, A_surfxml_actor_function);
xbt_assert(current_property_set == nullptr, "Someone forgot to reset the property set to nullptr in its closing tag (or XML malformed)");
}
actor.properties = current_property_set;
current_property_set = nullptr;
- actor.argc = argc;
- actor.argv = (const char **)argv;
+ actor.args.swap(arguments);
actor.host = A_surfxml_actor_host;
actor.function = A_surfxml_actor_function;
actor.start_time = surf_parse_get_double(A_surfxml_actor_start___time);
}
sg_platf_new_process(&actor);
-
- for (int i = 0; i != argc; ++i)
- xbt_free(argv[i]);
- xbt_free(argv);
- argv = nullptr;
}
void STag_surfxml_argument(){
- argc++;
- argv = (char**)xbt_realloc(argv, (argc) * sizeof(char **));
- argv[(argc) - 1] = xbt_strdup(A_surfxml_argument_value);
+ arguments.push_back(A_surfxml_argument_value);
}
void STag_surfxml_model___prop(){
{
xbt_dynar_reset(dynar);
if (dynar)
- free(dynar->data);
+ xbt_free(dynar->data);
}
/** @brief Destructor of the structure not touching to the content
{
if (dynar && *dynar) {
xbt_dynar_t d = *dynar;
- free(d->data);
- free(d);
+ xbt_free(d->data);
+ xbt_free(d);
*dynar = nullptr;
}
}
xbt_dynar_shrink(dynar, 1);
memset(xbt_dynar_push_ptr(dynar), 0, dynar->elmsize);
res = dynar->data;
- free(dynar);
+ xbt_free(dynar);
return res;
}
snprintf(buf,1023, "%d", cpt);
xbt_dynar_shift(d, &s2);
xbt_test_assert(not strcmp(buf, s2), "The retrieved value is not the same than the injected one (%s!=%s)", buf, s2);
- free(s2);
+ xbt_free(s2);
}
xbt_dynar_free(&d); /* This code is used both as example and as regression test, so we try to */
xbt_dynar_free(&d); /* free the struct twice here to check that it's ok, but freeing it only once */
snprintf(buf,1023, "%d", cpt);
xbt_dynar_pop(d, &s2);
xbt_test_assert(not strcmp(buf, s2), "The retrieved value is not the same than the injected one (%s!=%s)", buf, s2);
- free(s2);
+ xbt_free(s2);
}
/* 4. Free the resources */
xbt_dynar_free(&d); /* This code is used both as example and as regression test, so we try to */
xbt_dynar_shift(d, &s2);
xbt_test_assert(not strcmp(buf, s2),
"The retrieved value is not the same than the injected one at the begining (%s!=%s)", buf, s2);
- free(s2);
+ xbt_free(s2);
}
for (int cpt = (NB_ELEM / 5) - 1; cpt >= 0; cpt--) {
snprintf(buf,1023, "%d", cpt);
xbt_dynar_shift(d, &s2);
xbt_test_assert(not strcmp(buf, s2),
"The retrieved value is not the same than the injected one in the middle (%s!=%s)", buf, s2);
- free(s2);
+ xbt_free(s2);
}
for (int cpt = NB_ELEM / 2; cpt < NB_ELEM; cpt++) {
snprintf(buf,1023, "%d", cpt);
xbt_dynar_shift(d, &s2);
xbt_test_assert(not strcmp(buf, s2),
"The retrieved value is not the same than the injected one at the end (%s!=%s)", buf, s2);
- free(s2);
+ xbt_free(s2);
}
xbt_dynar_free(&d); /* This code is used both as example and as regression test, so we try to */
xbt_dynar_free(&d); /* free the struct twice here to check that it's ok, but freeing it only once */
snprintf(buf,1023, "%d", cpt);
xbt_dynar_remove_at(d, 2 * (NB_ELEM / 5), &s2);
xbt_test_assert(not strcmp(buf, s2), "Remove a bad value. Got %s, expected %s", s2, buf);
- free(s2);
+ xbt_free(s2);
}
xbt_dynar_free(&d); /* end_of_doxygen */
}
void _xbt_throw(char* message, xbt_errcat_t errcat, int value, const char* file, int line, const char* func)
{
xbt_ex e(simgrid::xbt::ThrowPoint(file, line, func), message);
- free(message);
+ xbt_free(message);
e.category = errcat;
e.value = value;
throw e;
XBT_LOG_CONNECT(surf_cpu_cas);
XBT_LOG_CONNECT(surf_cpu_ti);
XBT_LOG_CONNECT(surf_energy);
- XBT_LOG_CONNECT(surf_file);
XBT_LOG_CONNECT(surf_kernel);
XBT_LOG_CONNECT(surf_lagrange);
XBT_LOG_CONNECT(surf_lagrange_dichotomy);
* \param swag a swag
* \return the number of objects in \a swag
*/
-inline int xbt_swag_size(xbt_swag_t swag)
+inline int xbt_swag_size(const_xbt_swag_t swag)
{
return (swag->count);
}
{
simgrid::xbt::installExceptionHandler();
- if (xbt_initialized) {
- xbt_initialized++;
+ xbt_initialized++;
+ if (xbt_initialized > 1) {
XBT_DEBUG("XBT has been initialized %d times.", xbt_initialized);
return;
}
}
/* these two functions belong to xbt/sysdep.h, which have no corresponding .c file */
-/** @brief like free, but you can be sure that it is a function */
+/** @brief like xbt_free, but you can be sure that it is a function */
void xbt_free_f(void *p)
{
- free(p);
+ xbt_free(p);
}
/** @brief should be given a pointer to pointer, and frees the second one */
void xbt_free_ref(void *d)
{
- free(*(void **) d);
+ xbt_free(*(void**)d);
}
/** @brief Kill the program in silence */
char *q=xbt_strdup(p);
xbt_dynar_push(res,&q);
}
- free(str_to_free);
+ xbt_free(str_to_free);
xbt_dynar_shrink(res, 0);
xbt_dynar_free(&parsed);
return res;
endforeach()
# CPP examples
-foreach(x task_destroy_cancel task_listen_from)
+foreach(x task_destroy_cancel task_listen_from task_progress)
add_executable (${x} ${x}/${x}.cpp)
target_link_libraries(${x} simgrid)
set_target_properties(${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${x})
${CMAKE_CURRENT_SOURCE_DIR}/trace_integration/test-hbp1-c1s1-c3s2.xml
${CMAKE_CURRENT_SOURCE_DIR}/trace_integration/test-hbp2.5-hbp1.5.xml PARENT_SCOPE)
-foreach(x get_sender host_on_off host_on_off_processes host_on_off_recv task_destroy_cancel task_listen_from trace_integration)
+foreach(x get_sender host_on_off host_on_off_processes host_on_off_recv
+ task_destroy_cancel task_listen_from task_progress trace_integration)
ADD_TESH_FACTORIES(tesh-msg-${x} "thread;ucontext;raw;boost" --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/msg/${x} --cd ${CMAKE_BINARY_DIR}/teshsuite/msg/${x} ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/${x}/${x}.tesh)
endforeach()
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/msg.h"
+#include "simgrid/plugins/file_system.h"
#include <xbt/replay.hpp>
XBT_LOG_NEW_DEFAULT_CATEGORY(storage_actions, "Messages specific for this example");
int main(int argc, char* argv[])
{
MSG_init(&argc, argv);
+ MSG_storage_file_system_init();
/* Explicit initialization of the action module is required */
MSG_action_init();
MSG_task_execute(task);
double end = MSG_get_clock();
XBT_INFO("Task \"%s\" done in %f (amount %f)", MSG_task_get_name(task), end - start,
- MSG_task_get_flops_amount(task));
+ MSG_task_get_remaining_work_ratio(task));
MSG_task_destroy(task);
}
--- /dev/null
+/* Copyright (c) 2010-2017. 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 <xbt/ex.hpp>
+#include "simgrid/msg.h"
+
+XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test, "Messages specific for this msg example");
+
+static std::vector<msg_task_t> tasks = std::vector<msg_task_t>();
+
+static int seq_task(int /*argc*/, char* /*argv*/ [])
+{
+ double task_comp_size = 5E7;
+ double task_comm_size = 1E6;
+ double progress = 0;
+
+ msg_task_t task = MSG_task_create("simple", task_comp_size, task_comm_size, NULL);
+ tasks.push_back(task);
+
+ XBT_INFO("get the progress of %s before the task starts", task->name);
+ progress = MSG_task_get_remaining_work_ratio(task);
+ xbt_assert(progress == 0, "Progress should be 0 not %f", progress);
+
+ XBT_INFO("Executing task: \"%s\"", task->name);
+ MSG_task_execute(task);
+
+ XBT_INFO("get the progress of %s after the task finishes", task->name);
+ progress = MSG_task_get_remaining_work_ratio(task);
+ xbt_assert(progress == 0, "Progress should be equal to 1 not %f", progress);
+
+ MSG_task_destroy(task);
+ XBT_INFO("Goodbye now!");
+ return 0;
+}
+
+static int par_task(int /*argc*/, char* /*argv*/ [])
+{
+ double * computation_amount = new double[2] {10E7, 10E7};
+ double * communication_amount = new double[4] {1E6, 1E6, 1E6, 1E6};
+ double progress = 0;
+
+ std::vector<msg_host_t> hosts_to_use = std::vector<msg_host_t>();
+ hosts_to_use.push_back(MSG_get_host_by_name("Tremblay"));
+ hosts_to_use.push_back(MSG_get_host_by_name("Jupiter"));
+
+ msg_task_t task = MSG_parallel_task_create("ptask", 2, hosts_to_use.data(), computation_amount, communication_amount, NULL);
+ tasks.push_back(task);
+
+ XBT_INFO("get the progress of %s before the task starts", task->name);
+ progress = MSG_task_get_remaining_work_ratio(task);
+ xbt_assert(progress == 0, "Progress should be 0 not %f", progress);
+
+ XBT_INFO("Executing task: \"%s\"", task->name);
+ MSG_parallel_task_execute(task);
+
+ XBT_INFO("get the progress of %s after the task finishes", task->name);
+ progress = MSG_task_get_remaining_work_ratio(task);
+ xbt_assert(progress == 0, "Progress should be equal to 1 not %f", progress);
+
+ MSG_task_destroy(task);
+ delete[] computation_amount;
+ delete[] communication_amount;
+
+ XBT_INFO("Goodbye now!");
+ return 0;
+}
+
+static int get_progress(int /*argc*/, char* /*argv*/ [])
+{
+ while (tasks.empty()) {
+ MSG_process_sleep(0.5);
+ }
+ double progress;
+ for(auto const& task: tasks) {
+ double progress_prev = 1;
+ for (int i = 0; i < 3; i++) {
+ MSG_process_sleep(0.2);
+ progress = MSG_task_get_remaining_work_ratio(task);
+ xbt_assert(progress >= 0 and progress < 1, "Progress should be in [0, 1[, and not %f", progress);
+ xbt_assert(progress < progress_prev, "Progress should decrease, not increase");
+ XBT_INFO("Progress of \"%s\": %f", task->name, progress);
+ progress_prev = progress;
+ }
+ }
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ MSG_init(&argc, argv);
+ MSG_config("host/model", "ptask_L07");
+ xbt_assert(argc == 2, "Usage: %s platform_file\n\tExample: %s ../examples/platforms/two_hosts.xml\n", argv[0], argv[0]);
+
+ MSG_create_environment(argv[1]);
+
+ MSG_process_create("sequential", seq_task, NULL, MSG_get_host_by_name("Tremblay"));
+
+ MSG_process_create("parallel", par_task, NULL, MSG_get_host_by_name("Tremblay"));
+
+ // Create a process to test in progress task
+ MSG_process_create("get_progress", get_progress, NULL, MSG_get_host_by_name("Tremblay"));
+
+ msg_error_t res = MSG_main();
+
+ XBT_INFO("Simulation time %g", MSG_get_clock());
+
+ return res != MSG_OK;
+}
--- /dev/null
+$ ./task_progress ${srcdir:=.}/../../../examples/platforms/small_platform.xml
+> [0.000000] [xbt_cfg/INFO] Switching to the L07 model to handle parallel tasks.
+> [Tremblay:sequential:(1) 0.000000] [msg_test/INFO] get the progress of simple before the task starts
+> [Tremblay:sequential:(1) 0.000000] [msg_test/INFO] Executing task: "simple"
+> [Tremblay:parallel:(2) 0.000000] [msg_test/INFO] get the progress of ptask before the task starts
+> [Tremblay:parallel:(2) 0.000000] [msg_test/INFO] Executing task: "ptask"
+> [Tremblay:get_progress:(3) 0.200000] [msg_test/INFO] Progress of "simple": 0.802376
+> [Tremblay:get_progress:(3) 0.400000] [msg_test/INFO] Progress of "simple": 0.606186
+> [Tremblay:get_progress:(3) 0.600000] [msg_test/INFO] Progress of "simple": 0.409996
+> [Tremblay:get_progress:(3) 0.800000] [msg_test/INFO] Progress of "ptask": 0.608337
+> [Tremblay:get_progress:(3) 1.000000] [msg_test/INFO] Progress of "ptask": 0.510242
+> [Tremblay:sequential:(1) 1.017958] [msg_test/INFO] get the progress of simple after the task finishes
+> [Tremblay:sequential:(1) 1.017958] [msg_test/INFO] Goodbye now!
+> [Tremblay:get_progress:(3) 1.200000] [msg_test/INFO] Progress of "ptask": 0.362543
+> [Tremblay:parallel:(2) 1.675180] [msg_test/INFO] get the progress of ptask after the task finishes
+> [Tremblay:parallel:(2) 1.675180] [msg_test/INFO] Goodbye now!
+> [1.675180] [msg_test/INFO] Simulation time 1.67518
+
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "simgrid/s4u.hpp"
-#include <unistd.h>
-
-#define FILENAME1 "/home/doc/simgrid/examples/platforms/g5k.xml"
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_test, "Messages specific for this s4u test");
static void host()
{
- char name[2048];
+ simgrid::s4u::Storage* storage = simgrid::s4u::Storage::byName("Disk1");
int id = simgrid::s4u::this_actor::getPid();
- snprintf(name, 2048, "%s%i", FILENAME1, id);
- simgrid::s4u::File* file = new simgrid::s4u::File(name, NULL);
XBT_INFO("process %d is writing!", id);
- file->write(3000000);
+ storage->write(3000000);
XBT_INFO("process %d goes to sleep for %d seconds", id, id);
simgrid::s4u::this_actor::sleep_for(id);
XBT_INFO("process %d is writing again!", id);
- file->write(3000000);
+ storage->write(3000000);
XBT_INFO("process %d goes to sleep for %d seconds", id, 6 - id);
simgrid::s4u::this_actor::sleep_for(6 - id);
XBT_INFO("process %d is reading!", id);
- file->seek(0);
- file->read(3000000);
+ storage->read(3000000);
XBT_INFO("process %d goes to sleep for %d seconds", id, id);
simgrid::s4u::this_actor::sleep_for(id);
XBT_INFO("process %d is reading again!", id);
- file->seek(0);
- file->read(3000000);
-
- XBT_INFO("process %d => Size of %s: %llu", id, name, file->size());
- // Close the file
- delete file;
+ storage->read(3000000);
}
int main(int argc, char** argv)
> [ 6.750000] (host@bob) process 4 goes to sleep for 4 seconds
> [ 6.750000] (host@bob) process 5 goes to sleep for 5 seconds
> [ 7.750000] (host@bob) process 1 is reading again!
-> [ 7.780000] (host@bob) process 1 => Size of /home/doc/simgrid/examples/platforms/g5k.xml1: 6000000
> [ 8.750000] (host@bob) process 2 is reading again!
-> [ 8.780000] (host@bob) process 2 => Size of /home/doc/simgrid/examples/platforms/g5k.xml2: 6000000
> [ 9.750000] (host@bob) process 3 is reading again!
-> [ 9.780000] (host@bob) process 3 => Size of /home/doc/simgrid/examples/platforms/g5k.xml3: 6000000
> [ 10.750000] (host@bob) process 4 is reading again!
-> [ 10.780000] (host@bob) process 4 => Size of /home/doc/simgrid/examples/platforms/g5k.xml4: 6000000
> [ 11.750000] (host@bob) process 5 is reading again!
-> [ 11.780000] (host@bob) process 5 => Size of /home/doc/simgrid/examples/platforms/g5k.xml5: 6000000
> [ 11.780000] (maestro@) Simulation time 11.78
int main(int argc, char* argv[])
{
simgrid::s4u::Engine e(&argc, argv);
+ sg_storage_file_system_init();
xbt_assert(argc == 2, "Usage: %s platform_file\n", argv[0]);
e.loadPlatform(argv[1]);
> [ 0.806104] (server@alice) 6217 bytes on 6217 bytes have been written by server on /sd1
> [ 1.207952] (server@alice) *** Storage info on alice ***
> [ 1.207952] (server@alice) Storage name: Disk2, mount name: c:
+> [ 1.207952] (server@alice) Free size: 534479367024 bytes
+> [ 1.207952] (server@alice) Used size: 2391544976 bytes
> [ 1.207952] (client@bob) *** GET/SET DATA for storage element: Disk1 ***
> [ 1.207952] (client@bob) Get data: '(null)'
> [ 1.207952] (client@bob) Set and get data: 'Some data'
-> [ 1.207952] (server@alice) Free size: 534479367024 bytes
-> [ 1.207952] (server@alice) Used size: 2391544976 bytes
> [ 1.207952] (server@alice) No property attached.
> [ 1.207952] (server@alice) *** Dump a storage element ***
> [ 1.207952] (server@alice) Print the content of the storage element: Disk2
simgrid::surf::ActionList* action_list = surf_cpu_model_pm->getFailedActionSet();
while (not action_list->empty()) {
- simgrid::surf::Action* action = &*action_list->begin();
+ simgrid::surf::Action& action = action_list->front();
XBT_INFO(" CPU Failed action");
- XBT_DEBUG("\t * Failed : %p", action);
- action->unref();
+ XBT_DEBUG("\t * Failed : %p", &action);
+ action.unref();
}
action_list = surf_cpu_model_pm->getDoneActionSet();
while (not action_list->empty()) {
- simgrid::surf::Action* action = &*action_list->begin();
+ simgrid::surf::Action& action = action_list->front();
XBT_INFO(" CPU Done action");
- XBT_DEBUG("\t * Done : %p", action);
- action->unref();
+ XBT_DEBUG("\t * Done : %p", &action);
+ action.unref();
}
action_list = surf_network_model->getFailedActionSet();
while (not action_list->empty()) {
- simgrid::surf::Action* action = &*action_list->begin();
+ simgrid::surf::Action& action = action_list->front();
XBT_INFO(" Network Failed action");
- XBT_DEBUG("\t * Failed : %p", action);
- action->unref();
+ XBT_DEBUG("\t * Failed : %p", &action);
+ action.unref();
}
action_list = surf_network_model->getDoneActionSet();
while (not action_list->empty()) {
- simgrid::surf::Action* action = &*action_list->begin();
+ simgrid::surf::Action& action = action_list->front();
XBT_INFO(" Network Done action");
- XBT_DEBUG("\t * Done : %p", action);
- action->unref();
+ XBT_DEBUG("\t * Done : %p", &action);
+ action.unref();
}
} while ((surf_network_model->getRunningActionSet()->size() ||
src/surf/xml/simgrid_dtd.c
src/surf/xml/surfxml_sax_cb.cpp
- src/surf/FileImpl.hpp
src/surf/StorageImpl.hpp
src/surf/storage_n11.hpp
src/surf/surf_interface.hpp
src/surf/cpu_interface.cpp
src/surf/cpu_ti.cpp
src/surf/fair_bottleneck.cpp
- src/surf/FileImpl.cpp
src/surf/instr_routing.cpp
src/surf/instr_surf.cpp
src/surf/lagrange.cpp
src/surf/network_constant.cpp
src/surf/network_interface.cpp
src/surf/plugins/host_energy.cpp
+ src/surf/plugins/link_energy.cpp
src/surf/plugins/host_load.cpp
src/surf/PropertyHolder.cpp
src/surf/sg_platf.cpp
set(headers_to_install
include/simgrid/chrono.hpp
include/simgrid/plugins/energy.h
+ include/simgrid/plugins/file_system.h
include/simgrid/plugins/load.h
include/simgrid/instr.h
include/simgrid/msg.h