examples/msg/process-migration/process-migration
examples/msg/process-startkilltime/process-startkilltime
examples/msg/process-suspend/process-suspend
-examples/msg/process-yield/process-yield
examples/msg/app-masterworker/app-masterworker
examples/msg/mc/bugged1
examples/msg/mc/bugged1_liveness
examples/s4u/actor-migration/s4u-actor-migration
examples/s4u/actor-priority/s4u-actor-priority
examples/s4u/actor-suspend/s4u-actor-suspend
+examples/s4u/actor-yield/s4u-actor-yield
examples/s4u/app-bittorrent/s4u-bittorrent
examples/s4u/app-masterworker/s4u-app-masterworker
examples/s4u/app-pingpong/s4u-app-pingpong
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
teshsuite/msg/listen_async/listen_async
teshsuite/msg/pid/pid
teshsuite/msg/process/process
+teshsuite/msg/process-yield/process-yield
teshsuite/msg/storage_client_server/storage_client_server
teshsuite/msg/task_destroy_cancel/task_destroy_cancel
teshsuite/msg/task_listen_from/task_listen_from
teshsuite/surf/maxmin_bench/maxmin_bench
teshsuite/surf/surf_usage/surf_usage
teshsuite/surf/surf_usage2/surf_usage2
-teshsuite/xbt/heap_bench/heap_bench
teshsuite/xbt/log_large/log_large
teshsuite/xbt/log_usage/log_usage
teshsuite/xbt/mallocator/mallocator
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/file.h: xbt_basename(), xbt_dirname(), xbt_getline()
- 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
.PHONY: clean
@endverbatim
-@section install_yours_javaexamples Building the Java examples in Eclipse
+@section install_yours_cppeclipsedevenv Develop in C++ with SimGrid with Eclipse
+
+If you wish to develop your plugin or modify SimGrid using Eclipse. You have to run cmake and import it as a Makefile project.
+
+Next you have to activate C++11 in your build settings, add -std=c++11 in the CDT GCC Built-in compiler settings.
+
+![Eclipse preference page.](eclipseScreenShot.png)
+
+@section install_yours_javaexample Building the Java examples in Eclipse
If you want to build our Java examples in Eclipse, get the whole
source code and open the archive on your disk. In Eclipse, select
- \ref XBT_dynar
- \ref XBT_dict
- \ref XBT_swag
- - \ref XBT_heap
- \ref XBT_misc
- \ref XBT_graph
/** @defgroup XBT_dynar Dynar: generic dynamic array */
/** @defgroup XBT_dict Dict: generic dictionnary */
/** @defgroup XBT_swag Swag: O(1) set datatype */
- /** @defgroup XBT_heap Heap: generic heap data structure */
/** @} */
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
XBT_log, \ref XBT_ex and \ref XBT_config.
XBT also encompass the following convenient C data structures:
-\ref XBT_dynar, \ref XBT_dict, \ref XBT_heap, and
+\ref XBT_dynar, \ref XBT_dict, and
\ref XBT_swag. The code is being migrated in C++ so you should probably want
to use standard C++ containers instead of them if possible.
\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());
int workersCount = Integer.parseInt(args[3]);
- Msg.info("Hello! Got "+ workersCount + " workers and "+tasksCount+" tasks to process");
+ Msg.info("Hello! My PID is "+getPID()+". Got "+ workersCount + " workers and "+tasksCount+" tasks to process");
for (int i = 0; i < tasksCount; i++) {
Task task = new Task("Task_" + i, taskComputeSize, taskCommunicateSize);
if ("finalize".equals(task.getName())) {
break;
}
- Msg.info("Received \"" + task.getName() + "\". Processing it.");
+ Msg.info("Received \"" + task.getName() + "\". Processing it (my pid is "+getPID()+").");
try {
task.execute();
} catch (TaskCancelledException e) {
$ java -classpath ${classpath:=.} app/masterworker/Main ${srcdir:=.}/../platforms/small_platform.xml ${srcdir:=.}/app/masterworker/masterworker.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
> [ 0.000000] (0:maestro@) Using regular java threads.
-> [ 0.000000] (1:app.masterworker.Master@Jacquelin) Hello! Got 7 workers and 5 tasks to process
-> [ 0.860026] (2:app.masterworker.Worker@Tremblay) Received "Task_0". Processing it.
-> [ 1.752187] (3:app.masterworker.Worker@Fafard) Received "Task_1". Processing it.
-> [ 1.757531] (4:app.masterworker.Worker@Bourassa) Received "Task_2". Processing it.
-> [ 2.806417] (5:app.masterworker.Worker@Boivin) Received "Task_3". Processing it.
-> [ 2.811761] (6:app.masterworker.Worker@Ginette) Received "Task_4". Processing it.
+> [ 0.000000] (1:app.masterworker.Master@Jacquelin) Hello! My PID is 1. Got 7 workers and 5 tasks to process
+> [ 0.860026] (2:app.masterworker.Worker@Tremblay) Received "Task_0". Processing it (my pid is 2).
+> [ 1.752187] (3:app.masterworker.Worker@Fafard) Received "Task_1". Processing it (my pid is 3).
+> [ 1.757531] (4:app.masterworker.Worker@Bourassa) Received "Task_2". Processing it (my pid is 4).
+> [ 2.806417] (5:app.masterworker.Worker@Boivin) Received "Task_3". Processing it (my pid is 5).
+> [ 2.811761] (6:app.masterworker.Worker@Ginette) Received "Task_4". Processing it (my pid is 6).
> [ 2.811761] (1:app.masterworker.Master@Jacquelin) All tasks have been dispatched. Let's tell everybody the computation is over.
> [ 3.671783] (2:app.masterworker.Worker@Tremblay) Received Finalize. I'm done. See you!
> [ 4.563940] (3:app.masterworker.Worker@Fafard) Received Finalize. I'm done. See you!
> [ 0.000000] (1:Sender@Boivin) Sending "Task_5" to "Jupiter"
> [ 0.000000] (1:Sender@Boivin) Sending "Task_6" to "Tremblay"
> [ 0.000000] (1:Sender@Boivin) All tasks have been (asynchronously) dispatched. Let's sleep for 20s so that nobody gets a message from a terminated process.
-> [ 1.933362] (2:Receiver@Bourassa) Received a task. I'm done. See you!
-> [ 1.933362] (4:Receiver@Ginette) Received a task. I'm done. See you!
> [ 1.933362] (6:Receiver@Jupiter) Received a task. I'm done. See you!
+> [ 1.933362] (4:Receiver@Ginette) Received a task. I'm done. See you!
+> [ 1.933362] (2:Receiver@Bourassa) Received a task. I'm done. See you!
> [ 2.449247] (7:Receiver@Tremblay) Received a task. I'm done. See you!
> [ 2.964768] (3:Receiver@Fafard) Received a task. I'm done. See you!
> [ 4.162002] (5:Receiver@Jacquelin) Received a task. I'm done. See you!
> [ 0.000000] (1:Sender@Boivin) Start the Sending 'Task_5' to 'Jupiter'
> [ 0.000000] (1:Sender@Boivin) Start the Sending 'Task_6' to 'Tremblay'
> [ 0.000000] (1:Sender@Boivin) All tasks have been (asynchronously) dispatched. Let's wait for their completion.
-> [ 1.933362] (2:Receiver@Bourassa) I got my task, good bye.
-> [ 1.933362] (4:Receiver@Ginette) I got my task, good bye.
> [ 1.933362] (6:Receiver@Jupiter) I got my task, good bye.
+> [ 1.933362] (4:Receiver@Ginette) I got my task, good bye.
+> [ 1.933362] (2:Receiver@Bourassa) I got my task, good bye.
> [ 2.449247] (7:Receiver@Tremblay) I got my task, good bye.
> [ 2.964768] (3:Receiver@Fafard) I got my task, good bye.
> [ 4.162002] (5:Receiver@Jacquelin) I got my task, good bye.
$ java -classpath ${classpath:=.} dht/chord/Main ${srcdir:=.}/../platforms/cluster.xml ${srcdir:=.}/dht/chord/chord.xml
> [0.000000] [java/INFO] Using regular java threads.
-> [1046.787586] [java/INFO] MSG_main finished; Cleaning up the simulation...
+> [1046.732943] [java/INFO] MSG_main finished; Cleaning up the simulation...
> [node-1.acme.org:dht.chord.Node:(2) 0.000000] [java/INFO] Joining the ring with id 366680 knowing node 42
> [node-2.acme.org:dht.chord.Node:(3) 0.000000] [java/INFO] Joining the ring with id 533744 knowing node 366680
> [node-3.acme.org:dht.chord.Node:(4) 0.000000] [java/INFO] Joining the ring with id 1319738 knowing node 42
> [MyHost1:energy VM runner:(1) 0.000000] [java/INFO] Create two tasks on Host3: both inside a VM
> [MyHost1:energy VM runner:(1) 0.000000] [java/INFO] Wait 5 seconds. The tasks are still running (they run for 3 seconds, but 2 tasks are co-located, so they run for 6 seconds)
> [MyHost1:energy VM runner:(1) 5.000000] [java/INFO] Wait another 5 seconds. The tasks stop at some point in between
-> [MyHost3:p31:(6) 6.000000] [java/INFO] This worker is done.
-> [MyHost3:p312:(7) 6.000000] [java/INFO] This worker is done.
> [MyHost2:p22:(5) 6.000000] [java/INFO] This worker is done.
+> [MyHost3:p312:(7) 6.000000] [java/INFO] This worker is done.
+> [MyHost3:p31:(6) 6.000000] [java/INFO] This worker is done.
> [vmHost1:p12:(3) 6.000000] [java/INFO] This worker is done.
-> [vmHost3:p21:(4) 6.000000] [java/INFO] This worker is done.
> [vmHost1:p11:(2) 6.000000] [java/INFO] This worker is done.
+> [vmHost3:p21:(4) 6.000000] [java/INFO] This worker is done.
> [10.000000] [surf_energy/INFO] Total energy consumption: 4320.000000 Joules (used hosts: 4320.000000 Joules; unused/idle hosts: 0.000000)
> [10.000000] [java/INFO] MSG_main finished; Cleaning up the simulation...
> [10.000000] [surf_energy/INFO] Energy consumption of host MyHost1: 1120.000000 Joules
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);
}
dht-pastry energy-consumption energy-onoff energy-pstate energy-ptask energy-vm platform-failures
io-file io-remote io-storage task-priority
plugin-hostload
- process-create process-daemon process-join process-kill process-migration process-suspend process-yield
+ process-create process-daemon process-join process-kill process-migration process-suspend
platform-properties process-startkilltime synchro-semaphore trace-categories
trace-route-user-variables trace-link-user-variables trace-masterworker trace-platform
trace-process-migration trace-host-user-variables)
endforeach()
foreach (file app-chainsend app-masterworker app-pingpong async-wait
- async-waitall async-waitany dht-kademlia dht-pastry io-remote platform-properties process-yield
+ async-waitall async-waitany dht-kademlia dht-pastry io-remote platform-properties
task-priority)
set(xml_files ${xml_files} ${CMAKE_CURRENT_SOURCE_DIR}/${file}/${file}_d.xml)
endforeach()
foreach(x app-chainsend app-masterworker app-pingpong app-token-ring
async-wait async-waitall async-waitany cloud-capping cloud-masterworker cloud-migration cloud-simple
cloud-two-tasks dht-pastry dht-kademlia platform-failures io-file io-remote io-storage task-priority
- process-create process-daemon process-join process-kill process-migration process-startkilltime process-suspend process-yield
+ process-create process-daemon process-join process-kill process-migration process-startkilltime process-suspend
platform-properties synchro-semaphore)
ADD_TESH_FACTORIES(msg-${x} "thread;ucontext;raw;boost" --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/${x} --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/platforms --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/${x} ${x}.tesh)
endforeach()
@ref examples/msg/process-migration/process-migration.c \n
Processes can move or be moved from a host to another with the @ref MSG_process_migrate function.
- - <b>Yielding to other processes</b>.
- @ref examples/msg/process-yield/process-yield.c\n
- The @ref MSG_process_yield function interrupts the execution of the
- current process, leaving a chance to run to the other processes
- that are ready to run at the exact same timestamp
-
- <b>Controling the process life cycle from the XML</b>.
@ref examples/msg/process-startkilltime/process-startkilltime.c \n
You can specify a start time and a kill time in the deployment
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
@example examples/msg/async-wait/async-wait.c
@example examples/msg/async-waitall/async-waitall.c
@example examples/msg/async-waitany/async-waitany.c
-@example examples/msg/async-yield/async-yield.c
@example examples/msg/process-create/process-create.c
@example examples/msg/process-suspend/process-suspend.c
> [ 10.000000] (3:receiver@Jupiter) Wait to receive task 1
> [ 10.000000] (3:receiver@Jupiter) Wait to receive task 2
> [ 10.423774] (2:receiver@Fafard) Processing "Task_4"
-> [ 10.469435] (3:receiver@Jupiter) Processing "Task_3"
+> [ 10.469435] (3:receiver@Jupiter) Processing "Task_5"
> [ 11.079116] (2:receiver@Fafard) "Task_4" done
> [ 11.079116] (2:receiver@Fafard) Processing "Task_0"
-> [ 11.124778] (3:receiver@Jupiter) "Task_3" done
+> [ 11.124778] (3:receiver@Jupiter) "Task_5" done
> [ 11.124778] (3:receiver@Jupiter) Processing "Task_1"
> [ 11.734459] (2:receiver@Fafard) "Task_0" done
> [ 11.734459] (2:receiver@Fafard) Processing "Task_2"
> [ 11.780120] (3:receiver@Jupiter) "Task_1" done
-> [ 11.780120] (3:receiver@Jupiter) Processing "Task_5"
+> [ 11.780120] (3:receiver@Jupiter) Processing "Task_3"
> [ 12.389801] (2:receiver@Fafard) "Task_2" done
> [ 12.415509] (2:receiver@Fafard) I'm done. See you!
-> [ 12.435462] (3:receiver@Jupiter) "Task_5" done
+> [ 12.435462] (3:receiver@Jupiter) "Task_3" done
> [ 12.454477] (0:maestro@) Simulation time 12.4545
> [ 12.454477] (1:sender@Tremblay) Goodbye now!
> [ 12.454477] (3:receiver@Jupiter) I'm done. See you!
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);
}
> [ 0.000000] (12:node@node-11.acme.org) Hi, I'm going to join the network with id 2047
> [ 0.000000] (13:node@node-12.acme.org) Hi, I'm going to join the network with id 4095
> [780.000000] ( 7:node@node-6.acme.org) 5/5 FIND_NODE have succeeded
-> [780.000000] ( 9:node@node-8.acme.org) 5/5 FIND_NODE have succeeded
-> [780.000000] ( 3:node@node-2.acme.org) 6/6 FIND_NODE have succeeded
+> [780.000000] ( 9:node@node-8.acme.org) 6/6 FIND_NODE have succeeded
+> [780.000000] ( 3:node@node-2.acme.org) 5/5 FIND_NODE have succeeded
> [780.000000] ( 2:node@node-1.acme.org) 6/6 FIND_NODE have succeeded
-> [780.000000] (11:node@node-10.acme.org) 5/5 FIND_NODE have succeeded
+> [780.000000] (11:node@node-10.acme.org) 6/6 FIND_NODE have succeeded
> [780.000000] ( 1:node@node-0.acme.org) 7/7 FIND_NODE have succeeded
> [780.000000] ( 5:node@node-4.acme.org) 6/6 FIND_NODE have succeeded
> [780.000000] (13:node@node-12.acme.org) 6/6 FIND_NODE have succeeded
// 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",
> [ 0.000000] (1:dvfs@MyHost1) Create two tasks on Host3: both inside a VM
> [ 0.000000] (1:dvfs@MyHost1) Wait 5 seconds. The tasks are still running (they run for 3 seconds, but 2 tasks are co-located, so they run for 6 seconds)
> [ 5.000000] (1:dvfs@MyHost1) Wait another 5 seconds. The tasks stop at some point in between
-> [ 6.000000] (6:p31@MyHost3) This worker is done.
-> [ 6.000000] (7:p32@MyHost3) This worker is done.
> [ 6.000000] (5:p22@MyHost2) This worker is done.
+> [ 6.000000] (7:p32@MyHost3) This worker is done.
+> [ 6.000000] (6:p31@MyHost3) This worker is done.
> [ 6.000000] (3:p12@vm_host1) This worker is done.
-> [ 6.000000] (4:p21@vm_host3) This worker is done.
> [ 6.000000] (2:p11@vm_host1) This worker is done.
+> [ 6.000000] (4:p21@vm_host3) This worker is done.
> [ 10.000000] (0:maestro@) Total energy consumption: 4320.000000 Joules (used hosts: 4320.000000 Joules; unused/idle hosts: 0.000000)
> [ 10.000000] (0:maestro@) Total simulation time: 10.00; Host2 and Host3 must have the exact same energy consumption; Host1 is multi-core and will differ.
> [ 10.000000] (0:maestro@) Energy consumption of host MyHost1: 1120.000000 Joules
* 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 "
+++ /dev/null
-#! ./tesh
-
-$ $SG_TEST_EXENV ${bindir:=.}/process-yield ${srcdir:=.}/small_platform_fatpipe.xml ${srcdir:=.}/../msg/process-yield/process-yield_d.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
-> [ 0.000000] (1:yielder@Tremblay) I yielded 10 times. Goodbye now!
-> [ 0.000000] (2:yielder@Ruby) I yielded 15 times. Goodbye now!
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>
foreach (example actions-comm actions-storage
- actor-create actor-daemon actor-execute actor-kill actor-lifetime actor-migration actor-suspend actor-priority
+ actor-create actor-daemon actor-execute actor-kill actor-lifetime actor-migration actor-suspend actor-priority actor-yield
app-masterworker app-pingpong app-token-ring energy-pstate
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)
${CMAKE_CURRENT_SOURCE_DIR}/energy-pstate/s4u-energy-pstate.tesh
${CMAKE_CURRENT_SOURCE_DIR}/actor-priority/s4u-actor-priority.tesh
${CMAKE_CURRENT_SOURCE_DIR}/actor-lifetime/s4u-actor-lifetime.tesh
+ ${CMAKE_CURRENT_SOURCE_DIR}/actor-priority/s4u-actor-priority.tesh
+ ${CMAKE_CURRENT_SOURCE_DIR}/actor-yield/s4u-actor-yield.tesh
${CMAKE_CURRENT_SOURCE_DIR}/async-wait/s4u-async-wait.tesh
${CMAKE_CURRENT_SOURCE_DIR}/async-waitany/s4u-async-waitany.tesh
${CMAKE_CURRENT_SOURCE_DIR}/async-waitall/s4u-async-waitall.tesh
${CMAKE_CURRENT_SOURCE_DIR}/actions-storage/s4u-actions-storage_d.xml
${CMAKE_CURRENT_SOURCE_DIR}/actor-create/s4u-actor-create_d.xml
${CMAKE_CURRENT_SOURCE_DIR}/actor-priority/s4u-actor-priority_d.xml
+ ${CMAKE_CURRENT_SOURCE_DIR}/actor-yield/s4u-actor-yield_d.xml
${CMAKE_CURRENT_SOURCE_DIR}/app-bittorrent/s4u-app-bittorrent_d.xml
${CMAKE_CURRENT_SOURCE_DIR}/app-masterworker/s4u-app-masterworker_d.xml
${CMAKE_CURRENT_SOURCE_DIR}/async-waitany/s4u-async-waitany_d.xml
${CMAKE_CURRENT_SOURCE_DIR}/README.doc PARENT_SCOPE)
foreach(example actions-comm actions-storage
- actor-create actor-daemon actor-execute actor-kill actor-lifetime actor-migration actor-suspend
+ actor-create actor-daemon actor-execute actor-kill actor-lifetime actor-migration actor-suspend actor-priority actor-yield
app-bittorrent app-masterworker app-pingpong app-token-ring energy-pstate
- async-wait async-waitall async-waitany actor-priority
- dht-chord plugin-hostload io mutex)
+ async-wait async-waitall async-waitany
+ 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).
pstate can be accessed/changed with @ref getPstateSpeed and @ref sg_host_set_pstate.
See also the platform XML file for have a details on how to declare the CPU capacity for each pstate.
+ - <b>Yielding to other actor</b>.
+ @ref examples/s4u/actor-yield/s4u-actor-yield.c\n
+ The simgrid::s4u::this_actor::yield() function interrupts the
+ execution of the current actor, leaving a chance to the other actors
+ that are ready to run at this timestamp.
+
@section s4u_ex_synchro Inter-Actor Synchronization
- <b>Mutex: </b> @ref examples/s4u/mutex/s4u-mutex.cpp \n
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/s4u.hpp"
+
+/* This example does not much: It just spans over-polite actor that yield a large amount
+ * of time before ending.
+ *
+ * This serves as an example for the simgrid::s4u::this_actor::yield() function, with which an actor can request
+ * to be rescheduled after the other actor that are ready at the current timestamp.
+ *
+ * It can also be used to benchmark our context-switching mechanism.
+ */
+XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_actor_yield, "Messages specific for this s4u example");
+/* Main function of the Yielder process */
+class yielder {
+ long number_of_yields;
+
+public:
+ explicit yielder(std::vector<std::string> args) { number_of_yields = std::stod(args[1]); }
+ void operator()()
+ {
+ for (int i = 0; i < number_of_yields; i++)
+ simgrid::s4u::this_actor::yield();
+ XBT_INFO("I yielded %ld times. Goodbye now!", number_of_yields);
+ }
+};
+
+int main(int argc, char* argv[])
+{
+ simgrid::s4u::Engine e(&argc, argv);
+
+ xbt_assert(argc > 2, "Usage: %s platform_file deployment_file\n"
+ "\tExample: %s platform.xml deployment.xml\n",
+ argv[0], argv[0]);
+
+ e.loadPlatform(argv[1]); /* - Load the platform description */
+ e.registerFunction<yielder>("yielder");
+
+ e.loadDeployment(argv[2]);
+
+ e.run(); /* - Run the simulation */
+
+ return 0;
+}
--- /dev/null
+#! ./tesh
+
+$ $SG_TEST_EXENV ${bindir:=.}/s4u-actor-yield ${srcdir:=.}/small_platform_fatpipe.xml ${srcdir:=.}/../s4u/actor-yield/s4u-actor-yield_d.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [ 0.000000] (1:yielder@Tremblay) I yielded 10 times. Goodbye now!
+> [ 0.000000] (2:yielder@Ruby) I yielded 15 times. Goodbye now!
/* 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 <algorithm>
#include <climits>
#include <xbt/ex.hpp>
#define BLOCK_SIZE 16384
/** Number of blocks asked by each request */
-#define BLOCKS_REQUESTED 2
+#define BLOCKS_REQUESTED 2UL
#define ENABLE_END_GAME_MODE 1
#define SLEEP_DURATION 1
xbt_assert(remote_peer->hasPiece(piece));
int block_index = getFirstMissingBlockFrom(piece);
if (block_index != -1) {
- int block_length = MIN(BLOCKS_REQUESTED, PIECES_BLOCKS - block_index);
+ int block_length = std::min(BLOCKS_REQUESTED, PIECES_BLOCKS - block_index);
XBT_DEBUG("Sending a REQUEST to %s for piece %u (%d,%d)", remote_peer->mailbox_->getCname(), piece, block_index,
block_length);
remote_peer->mailbox_
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "s4u-tracker.hpp"
+#include <algorithm>
#include <xbt/RngStream.h>
XBT_LOG_NEW_DEFAULT_CATEGORY(s4u_bt_tracker, "Messages specific for the tracker");
TrackerAnswer* ta = new TrackerAnswer(TRACKER_QUERY_INTERVAL);
std::set<int>::iterator next_peer;
int nb_known_peers = known_peers.size();
- int max_tries = MIN(MAXIMUM_PEERS, nb_known_peers);
+ int max_tries = std::min(MAXIMUM_PEERS, nb_known_peers);
int tried = 0;
while (tried < max_tries) {
do {
--- /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"));
+
+ /* Sleep a while before starting the example */
+ 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@) Total energy over all links: 10.750000
+> [ 10.250000] (0:maestro@) Energy consumption of link 'bus': 10.750000 Joules
+
+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@) Total energy over all links: 1510.000000
+> [510.000000] (0:maestro@) Energy consumption of link 'bus': 1510.000000 Joules
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();
> 13 0 2 3
> 5 6 2 action_bcast "0 0.78 0.39"
> 12 0 2 1 6
-> 12 0 2 3 6
> 12 0 2 2 6
+> 12 0 2 3 6
> 13 0 2 1
> 12 0 2 1 4
> 13 0.015036 2 2
> [0.000000] [msg_test/INFO] Initializing instance 1 of size 32
> [0.000000] [msg_test/INFO] Initializing instance 2 of size 32
> [0.000000] [smpi_kernel/INFO] You did not set the power of the host running the simulation. The timings will certainly not be accurate. Use the option "--cfg=smpi/host-speed:<flops>" to set its value.Check http://simgrid.org/simgrid/latest/doc/options.html#options_smpi_bench for more information.
-> [Jupiter:2:(52) 1140688.493796] [smpi_replay/INFO] Simulation time 1124371.141124
-> [1140688.493796] [msg_test/INFO] Simulation time 1.14069e+06
+> [Jupiter:2:(62) 1140698.106357] [smpi_replay/INFO] Simulation time 1124380.753685
+> [1140698.106357] [msg_test/INFO] Simulation time 1.1407e+06
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. */
+
+ void yield();
+
+ /** 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. */
XBT_PUBLIC(void) suspend();
+/** @brief yield the actor. */
+XBT_PUBLIC(void) yield();
+
/** @brief Resume the actor. */
XBT_PUBLIC(void) resume();
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);
#define MPI_WIN_SIZE -2
#define MPI_WIN_DISP_UNIT -3
-// FIXME : used nowhere...
-typedef enum MPIR_Combiner_enum{
- MPI_COMBINER_NAMED,
- MPI_COMBINER_DUP,
- MPI_COMBINER_CONTIGUOUS,
- MPI_COMBINER_VECTOR,
- MPI_COMBINER_HVECTOR_INTEGER,
- MPI_COMBINER_HVECTOR,
- MPI_COMBINER_INDEXED,
- MPI_COMBINER_HINDEXED_INTEGER,
- MPI_COMBINER_HINDEXED,
- MPI_COMBINER_INDEXED_BLOCK,
- MPI_COMBINER_STRUCT_INTEGER,
- MPI_COMBINER_STRUCT,
- MPI_COMBINER_SUBARRAY,
- MPI_COMBINER_DARRAY,
- MPI_COMBINER_F90_REAL,
- MPI_COMBINER_F90_COMPLEX,
- MPI_COMBINER_F90_INTEGER,
- MPI_COMBINER_RESIZED,
- MPI_COMBINER_HINDEXED_BLOCK
-}MPIR_Combiner_enum;
-
-
typedef ptrdiff_t MPI_Aint;
typedef long long MPI_Offset;
MPI_CALL(XBT_PUBLIC(int), MPI_Finalize, (void));
MPI_CALL(XBT_PUBLIC(int), MPI_Finalized, (int* flag));
MPI_CALL(XBT_PUBLIC(int), MPI_Init_thread, (int *argc, char ***argv, int required, int *provided));
+MPI_CALL(XBT_PUBLIC(int), MPI_Initialized, (int* flag));
MPI_CALL(XBT_PUBLIC(int), MPI_Query_thread, (int *provided));
MPI_CALL(XBT_PUBLIC(int), MPI_Is_thread_main, (int *flag));
+MPI_CALL(XBT_PUBLIC(int), MPI_Get_version, (int *version,int *subversion));
+MPI_CALL(XBT_PUBLIC(int), MPI_Get_library_version, (char *version,int *len));
+MPI_CALL(XBT_PUBLIC(int), MPI_Get_processor_name, (char *name, int *resultlen));
MPI_CALL(XBT_PUBLIC(int), MPI_Abort, (MPI_Comm comm, int errorcode));
+MPI_CALL(XBT_PUBLIC(int), MPI_Alloc_mem, (MPI_Aint size, MPI_Info info, void *baseptr));
+MPI_CALL(XBT_PUBLIC(int), MPI_Free_mem, (void *base));
MPI_CALL(XBT_PUBLIC(double), MPI_Wtime, (void));
MPI_CALL(XBT_PUBLIC(double), MPI_Wtick,(void));
+
MPI_CALL(XBT_PUBLIC(int), MPI_Address, (void *location, MPI_Aint * address));
MPI_CALL(XBT_PUBLIC(int), MPI_Get_address, (void *location, MPI_Aint * address));
+MPI_CALL(XBT_PUBLIC(int), MPI_Error_class, (int errorcode, int* errorclass));
+
+MPI_CALL(XBT_PUBLIC(int), MPI_Attr_delete, (MPI_Comm comm, int keyval));
+MPI_CALL(XBT_PUBLIC(int), MPI_Attr_get, (MPI_Comm comm, int keyval, void* attr_value, int* flag));
+MPI_CALL(XBT_PUBLIC(int), MPI_Attr_put, (MPI_Comm comm, int keyval, void* attr_value));
+MPI_CALL(XBT_PUBLIC(int), MPI_Keyval_create, (MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval,
+ void* extra_state));
+MPI_CALL(XBT_PUBLIC(int), MPI_Keyval_free, (int* keyval));
+
MPI_CALL(XBT_PUBLIC(int), MPI_Type_free, (MPI_Datatype * datatype));
MPI_CALL(XBT_PUBLIC(int), MPI_Type_size, (MPI_Datatype datatype, int *size));
MPI_CALL(XBT_PUBLIC(int), MPI_Type_size_x, (MPI_Datatype datatype, MPI_Count *size));
MPI_CALL(XBT_PUBLIC(int), MPI_Type_vector, (int count, int blocklen, int stride,
MPI_Datatype old_type, MPI_Datatype* newtype));
MPI_CALL(XBT_PUBLIC(int), MPI_Type_contiguous, (int count, MPI_Datatype old_type, MPI_Datatype* newtype));
-MPI_CALL(XBT_PUBLIC(int), MPI_Testall, (int count, MPI_Request* requests, int* flag, MPI_Status* statuses));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_create_resized ,(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent,
+ MPI_Datatype *newtype));
+MPI_CALL(XBT_PUBLIC(MPI_Datatype), MPI_Type_f2c,(MPI_Fint datatype));
+MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Type_c2f,(MPI_Datatype datatype));
+MPI_CALL(XBT_PUBLIC(int), MPI_Get_count, (MPI_Status * status, MPI_Datatype datatype, int *count));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_get_attr, (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_set_attr, (MPI_Datatype type, int type_keyval, void *att));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_delete_attr, (MPI_Datatype type, int comm_keyval));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_create_keyval,(MPI_Type_copy_attr_function* copy_fn,
+ MPI_Type_delete_attr_function* delete_fn, int* keyval, void* extra_state));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_free_keyval,(int* keyval));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_dup,(MPI_Datatype datatype,MPI_Datatype *newtype));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_set_name,(MPI_Datatype datatype, char * name));
+MPI_CALL(XBT_PUBLIC(int), MPI_Type_get_name,(MPI_Datatype datatype, char * name, int* len));
+
+
+MPI_CALL(XBT_PUBLIC(int), MPI_Pack, (void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount,
+ int* position, MPI_Comm comm));
+MPI_CALL(XBT_PUBLIC(int), MPI_Pack_size, (int incount, MPI_Datatype datatype, MPI_Comm comm, int* size));
+MPI_CALL(XBT_PUBLIC(int), MPI_Unpack, (void* inbuf, int insize, int* position, void* outbuf, int outcount,
+ MPI_Datatype type, MPI_Comm comm));
+
MPI_CALL(XBT_PUBLIC(int), MPI_Op_create, (MPI_User_function * function, int commute, MPI_Op * op));
MPI_CALL(XBT_PUBLIC(int), MPI_Op_free, (MPI_Op * op));
MPI_CALL(XBT_PUBLIC(int), MPI_Op_commutative, (MPI_Op op, int *commute));
+MPI_CALL(XBT_PUBLIC(MPI_Op), MPI_Op_f2c,(MPI_Fint op));
+MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Op_c2f,(MPI_Op op));
MPI_CALL(XBT_PUBLIC(int), MPI_Group_free, (MPI_Group * group));
MPI_CALL(XBT_PUBLIC(int), MPI_Group_size, (MPI_Group group, int *size));
MPI_CALL(XBT_PUBLIC(int), MPI_Group_excl, (MPI_Group group, int n, int *ranks, MPI_Group * newgroup));
MPI_CALL(XBT_PUBLIC(int), MPI_Group_range_incl, (MPI_Group group, int n, int ranges[][3], MPI_Group * newgroup));
MPI_CALL(XBT_PUBLIC(int), MPI_Group_range_excl, (MPI_Group group, int n, int ranges[][3], MPI_Group * newgroup));
+MPI_CALL(XBT_PUBLIC(MPI_Group), MPI_Group_f2c,(MPI_Fint group));
+MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Group_c2f,(MPI_Group group));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_rank, (MPI_Comm comm, int *rank));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_size, (MPI_Comm comm, int *size));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_get_name, (MPI_Comm comm, char* name, int* len));
-MPI_CALL(XBT_PUBLIC(int), MPI_Get_processor_name, (char *name, int *resultlen));
-MPI_CALL(XBT_PUBLIC(int), MPI_Get_count, (MPI_Status * status, MPI_Datatype datatype, int *count));
-
+MPI_CALL(XBT_PUBLIC(int), MPI_Comm_set_name, (MPI_Comm comm, char* name));
+MPI_CALL(XBT_PUBLIC(int), MPI_Comm_dup, (MPI_Comm comm, MPI_Comm * newcomm));
+MPI_CALL(XBT_PUBLIC(int), MPI_Comm_get_attr, (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag));
+MPI_CALL(XBT_PUBLIC(int), MPI_Comm_set_attr, (MPI_Comm comm, int comm_keyval, void *attribute_val));
+MPI_CALL(XBT_PUBLIC(int), MPI_Comm_delete_attr, (MPI_Comm comm, int comm_keyval));
+MPI_CALL(XBT_PUBLIC(int), MPI_Comm_create_keyval,(MPI_Comm_copy_attr_function* copy_fn,
+ MPI_Comm_delete_attr_function* delete_fn, int* keyval, void* extra_state));
+MPI_CALL(XBT_PUBLIC(int), MPI_Comm_free_keyval,(int* keyval));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_group, (MPI_Comm comm, MPI_Group * group));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_compare, (MPI_Comm comm1, MPI_Comm comm2, int *result));
-
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_create, (MPI_Comm comm, MPI_Group group, MPI_Comm * newcomm));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_create_group, (MPI_Comm comm, MPI_Group group, int tag, MPI_Comm * newcomm));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_free, (MPI_Comm * comm));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_disconnect, (MPI_Comm * comm));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_split, (MPI_Comm comm, int color, int key, MPI_Comm* comm_out));
+MPI_CALL(XBT_PUBLIC(MPI_Comm), MPI_Comm_f2c,(MPI_Fint comm));
+MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Comm_c2f,(MPI_Comm comm));
MPI_CALL(XBT_PUBLIC(int), MPI_Send_init, (void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm,
MPI_Request * request));
MPI_CALL(XBT_PUBLIC(int), MPI_Recv, (void *buf, int count, MPI_Datatype datatype, int src, int tag, MPI_Comm comm,
MPI_Status * status));
MPI_CALL(XBT_PUBLIC(int), MPI_Send, (void *buf, int count, MPI_Datatype datatype, int dst, int tag, MPI_Comm comm));
+MPI_CALL(XBT_PUBLIC(int), MPI_Ssend, (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm));
+MPI_CALL(XBT_PUBLIC(int), MPI_Ssend_init, (void* buf, int count, MPI_Datatype datatype, int dest, int tag,
+ MPI_Comm comm, MPI_Request* request));
+MPI_CALL(XBT_PUBLIC(int), MPI_Issend, (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm,
+ MPI_Request* request));
MPI_CALL(XBT_PUBLIC(int), MPI_Sendrecv, (void *sendbuf, int sendcount, MPI_Datatype sendtype, int dst, int sendtag,
void *recvbuf, int recvcount, MPI_Datatype recvtype, int src, int recvtag,
MPI_Comm comm, MPI_Status * status));
MPI_CALL(XBT_PUBLIC(int), MPI_Test, (MPI_Request * request, int *flag, MPI_Status* status));
MPI_CALL(XBT_PUBLIC(int), MPI_Testany, (int count, MPI_Request requests[], int *index, int *flag, MPI_Status * status));
+MPI_CALL(XBT_PUBLIC(int), MPI_Testall, (int count, MPI_Request* requests, int* flag, MPI_Status* statuses));
+MPI_CALL(XBT_PUBLIC(int), MPI_Testsome, (int incount, MPI_Request requests[], int *outcount, int *indices,
+ MPI_Status status[]));
MPI_CALL(XBT_PUBLIC(int), MPI_Wait, (MPI_Request * request, MPI_Status * status));
MPI_CALL(XBT_PUBLIC(int), MPI_Waitany, (int count, MPI_Request requests[], int *index, MPI_Status * status));
MPI_CALL(XBT_PUBLIC(int), MPI_Waitall, (int count, MPI_Request requests[], MPI_Status status[]));
MPI_CALL(XBT_PUBLIC(int), MPI_Waitsome, (int incount, MPI_Request requests[], int *outcount, int *indices,
MPI_Status status[]));
-MPI_CALL(XBT_PUBLIC(int), MPI_Testsome, (int incount, MPI_Request requests[], int *outcount, int *indices,
- MPI_Status status[]));
+MPI_CALL(XBT_PUBLIC(int), MPI_Iprobe, (int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status));
+MPI_CALL(XBT_PUBLIC(int), MPI_Probe, (int source, int tag, MPI_Comm comm, MPI_Status* status));
+MPI_CALL(XBT_PUBLIC(MPI_Request), MPI_Request_f2c,(MPI_Fint request));
+MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Request_c2f,(MPI_Request request));
+
MPI_CALL(XBT_PUBLIC(int), MPI_Bcast, (void *buf, int count, MPI_Datatype datatype, int root, MPI_Comm comm));
MPI_CALL(XBT_PUBLIC(int), MPI_Barrier, (MPI_Comm comm));
MPI_CALL(XBT_PUBLIC(int), MPI_Gather, (void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf,
MPI_Comm comm));
MPI_CALL(XBT_PUBLIC(int), MPI_Scan, (void *sendbuf, void *recvbuf, int count,MPI_Datatype datatype, MPI_Op op,
MPI_Comm comm));
+MPI_CALL(XBT_PUBLIC(int), MPI_Exscan,(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op,
+ MPI_Comm comm));
MPI_CALL(XBT_PUBLIC(int), MPI_Reduce_scatter, (void *sendbuf, void *recvbuf, int *recvcounts, MPI_Datatype datatype,
MPI_Op op, MPI_Comm comm));
MPI_CALL(XBT_PUBLIC(int), MPI_Reduce_scatter_block, (void *sendbuf, void *recvbuf, int recvcount, MPI_Datatype datatype,
int recvcount, MPI_Datatype recvtype, MPI_Comm comm));
MPI_CALL(XBT_PUBLIC(int), MPI_Alltoallv, (void *sendbuf, int *sendcounts, int *senddisps, MPI_Datatype sendtype,
void *recvbuf, int *recvcounts, int *recvdisps, MPI_Datatype recvtype, MPI_Comm comm));
-MPI_CALL(XBT_PUBLIC(int), MPI_Iprobe, (int source, int tag, MPI_Comm comm, int* flag, MPI_Status* status));
-MPI_CALL(XBT_PUBLIC(int), MPI_Probe, (int source, int tag, MPI_Comm comm, MPI_Status* status));
-MPI_CALL(XBT_PUBLIC(int), MPI_Get_version, (int *version,int *subversion));
-MPI_CALL(XBT_PUBLIC(int), MPI_Get_library_version, (char *version,int *len));
MPI_CALL(XBT_PUBLIC(int), MPI_Reduce_local,(void *inbuf, void *inoutbuf, int count, MPI_Datatype datatype, MPI_Op op));
+MPI_CALL(XBT_PUBLIC(int), MPI_Info_create,( MPI_Info *info));
+MPI_CALL(XBT_PUBLIC(int), MPI_Info_set,( MPI_Info info, char *key, char *value));
+MPI_CALL(XBT_PUBLIC(int), MPI_Info_get,(MPI_Info info,char *key,int valuelen, char *value, int *flag));
+MPI_CALL(XBT_PUBLIC(int), MPI_Info_free,( MPI_Info *info));
+MPI_CALL(XBT_PUBLIC(int), MPI_Info_delete,( MPI_Info info, char *key));
+MPI_CALL(XBT_PUBLIC(int), MPI_Info_dup,(MPI_Info info, MPI_Info *newinfo));
+MPI_CALL(XBT_PUBLIC(int), MPI_Info_get_nkeys,( MPI_Info info, int *nkeys));
+MPI_CALL(XBT_PUBLIC(int), MPI_Info_get_nthkey,( MPI_Info info, int n, char *key));
+MPI_CALL(XBT_PUBLIC(int), MPI_Info_get_valuelen,( MPI_Info info, char *key, int *valuelen, int *flag));
+MPI_CALL(XBT_PUBLIC(MPI_Info), MPI_Info_f2c,(MPI_Fint info));
+MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Info_c2f,(MPI_Info info));
+
MPI_CALL(XBT_PUBLIC(int), MPI_Win_free,( MPI_Win* win));
MPI_CALL(XBT_PUBLIC(int), MPI_Win_create,( void *base, MPI_Aint size, int disp_unit, MPI_Info info, MPI_Comm comm,
MPI_Win *win));
MPI_CALL(XBT_PUBLIC(int), MPI_Win_create_keyval,(MPI_Win_copy_attr_function* copy_fn,
MPI_Win_delete_attr_function* delete_fn, int* keyval, void* extra_state));
MPI_CALL(XBT_PUBLIC(int), MPI_Win_free_keyval,(int* keyval));
-
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_complete,(MPI_Win win));
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_post,(MPI_Group group, int assert, MPI_Win win));
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_start,(MPI_Group group, int assert, MPI_Win win));
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_wait,(MPI_Win win));
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_lock,(int lock_type, int rank, int assert, MPI_Win win));
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_lock_all,(int assert, MPI_Win win));
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_unlock,(int rank, MPI_Win win));
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_unlock_all,(MPI_Win win));
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_flush,(int rank, MPI_Win win));
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_flush_local,(int rank, MPI_Win win));
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_flush_all,(MPI_Win win));
+MPI_CALL(XBT_PUBLIC(int), MPI_Win_flush_local_all,(MPI_Win win));
+MPI_CALL(XBT_PUBLIC(MPI_Win), MPI_Win_f2c,(MPI_Fint win));
+MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Win_c2f,(MPI_Win win));
MPI_CALL(XBT_PUBLIC(int), MPI_Get,( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win));
MPI_CALL(XBT_PUBLIC(int), MPI_Get_accumulate,( void *origin_addr, int origin_count, MPI_Datatype origin_datatype,
void* result_addr, int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp,
int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win));
-
MPI_CALL(XBT_PUBLIC(int), MPI_Rget,( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
MPI_Aint target_disp, int target_count, MPI_Datatype target_datatype, MPI_Win win, MPI_Request* request));
MPI_CALL(XBT_PUBLIC(int), MPI_Rput,( void *origin_addr, int origin_count, MPI_Datatype origin_datatype, int target_rank,
MPI_CALL(XBT_PUBLIC(int), MPI_Rget_accumulate,( void *origin_addr, int origin_count, MPI_Datatype origin_datatype,
void* result_addr, int result_count, MPI_Datatype result_datatype, int target_rank, MPI_Aint target_disp,
int target_count, MPI_Datatype target_datatype, MPI_Op op, MPI_Win win, MPI_Request* request));
-
MPI_CALL(XBT_PUBLIC(int), MPI_Fetch_and_op,( void *origin_addr, void* result_addr, MPI_Datatype datatype,
int target_rank, MPI_Aint target_disp, MPI_Op op, MPI_Win win));
MPI_CALL(XBT_PUBLIC(int), MPI_Compare_and_swap, (void *origin_addr, void *compare_addr,
void *result_addr, MPI_Datatype datatype, int target_rank, MPI_Aint target_disp, MPI_Win win));
-MPI_CALL(XBT_PUBLIC(int), MPI_Alloc_mem, (MPI_Aint size, MPI_Info info, void *baseptr));
-MPI_CALL(XBT_PUBLIC(int), MPI_Free_mem, (void *base));
+MPI_CALL(XBT_PUBLIC(int), MPI_Cart_coords, (MPI_Comm comm, int rank, int maxdims, int* coords));
+MPI_CALL(XBT_PUBLIC(int), MPI_Cart_create, (MPI_Comm comm_old, int ndims, int* dims, int* periods, int reorder,
+ MPI_Comm* comm_cart));
+MPI_CALL(XBT_PUBLIC(int), MPI_Cart_get, (MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords));
+MPI_CALL(XBT_PUBLIC(int), MPI_Cart_rank, (MPI_Comm comm, int* coords, int* rank));
+MPI_CALL(XBT_PUBLIC(int), MPI_Cart_shift, (MPI_Comm comm, int direction, int displ, int* source, int* dest));
+MPI_CALL(XBT_PUBLIC(int), MPI_Cart_sub, (MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new));
+MPI_CALL(XBT_PUBLIC(int), MPI_Cartdim_get, (MPI_Comm comm, int* ndims));
+MPI_CALL(XBT_PUBLIC(int), MPI_Dims_create, (int nnodes, int ndims, int* dims));
-MPI_CALL(XBT_PUBLIC(MPI_Datatype), MPI_Type_f2c,(MPI_Fint datatype));
-MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Type_c2f,(MPI_Datatype datatype));
-MPI_CALL(XBT_PUBLIC(MPI_Group), MPI_Group_f2c,(MPI_Fint group));
-MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Group_c2f,(MPI_Group group));
-MPI_CALL(XBT_PUBLIC(MPI_Request), MPI_Request_f2c,(MPI_Fint request));
-MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Request_c2f,(MPI_Request request));
-MPI_CALL(XBT_PUBLIC(MPI_Win), MPI_Win_f2c,(MPI_Fint win));
-MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Win_c2f,(MPI_Win win));
-MPI_CALL(XBT_PUBLIC(MPI_Op), MPI_Op_f2c,(MPI_Fint op));
-MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Op_c2f,(MPI_Op op));
-MPI_CALL(XBT_PUBLIC(MPI_Comm), MPI_Comm_f2c,(MPI_Fint comm));
-MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Comm_c2f,(MPI_Comm comm));
//FIXME: these are not yet implemented
+typedef enum MPIR_Combiner_enum{
+ MPI_COMBINER_NAMED,
+ MPI_COMBINER_DUP,
+ MPI_COMBINER_CONTIGUOUS,
+ MPI_COMBINER_VECTOR,
+ MPI_COMBINER_HVECTOR_INTEGER,
+ MPI_COMBINER_HVECTOR,
+ MPI_COMBINER_INDEXED,
+ MPI_COMBINER_HINDEXED_INTEGER,
+ MPI_COMBINER_HINDEXED,
+ MPI_COMBINER_INDEXED_BLOCK,
+ MPI_COMBINER_STRUCT_INTEGER,
+ MPI_COMBINER_STRUCT,
+ MPI_COMBINER_SUBARRAY,
+ MPI_COMBINER_DARRAY,
+ MPI_COMBINER_F90_REAL,
+ MPI_COMBINER_F90_COMPLEX,
+ MPI_COMBINER_F90_INTEGER,
+ MPI_COMBINER_RESIZED,
+ MPI_COMBINER_HINDEXED_BLOCK
+}MPIR_Combiner_enum;
+
typedef void MPI_Handler_function(MPI_Comm*, int*, ...);
typedef void* MPI_Errhandler;
XBT_PUBLIC_DATA(MPI_Errhandler*) MPI_ERRORS_ARE_FATAL;
XBT_PUBLIC_DATA(MPI_Errhandler*) MPI_ERRHANDLER_NULL;
-MPI_CALL(XBT_PUBLIC(MPI_Info), MPI_Info_f2c,(MPI_Fint info));
-MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Info_c2f,(MPI_Info info));
MPI_CALL(XBT_PUBLIC(MPI_Errhandler), MPI_Errhandler_f2c,(MPI_Fint errhandler));
MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_Errhandler_c2f,(MPI_Errhandler errhandler));
-MPI_CALL(XBT_PUBLIC(int), MPI_Pack_size, (int incount, MPI_Datatype datatype, MPI_Comm comm, int* size));
-MPI_CALL(XBT_PUBLIC(int), MPI_Cart_coords, (MPI_Comm comm, int rank, int maxdims, int* coords));
-MPI_CALL(XBT_PUBLIC(int), MPI_Cart_create, (MPI_Comm comm_old, int ndims, int* dims, int* periods, int reorder,
- MPI_Comm* comm_cart));
-MPI_CALL(XBT_PUBLIC(int), MPI_Cart_get, (MPI_Comm comm, int maxdims, int* dims, int* periods, int* coords));
MPI_CALL(XBT_PUBLIC(int), MPI_Cart_map, (MPI_Comm comm_old, int ndims, int* dims, int* periods, int* newrank));
-MPI_CALL(XBT_PUBLIC(int), MPI_Cart_rank, (MPI_Comm comm, int* coords, int* rank));
-MPI_CALL(XBT_PUBLIC(int), MPI_Cart_shift, (MPI_Comm comm, int direction, int displ, int* source, int* dest));
-MPI_CALL(XBT_PUBLIC(int), MPI_Cart_sub, (MPI_Comm comm, int* remain_dims, MPI_Comm* comm_new));
-MPI_CALL(XBT_PUBLIC(int), MPI_Cartdim_get, (MPI_Comm comm, int* ndims));
MPI_CALL(XBT_PUBLIC(int), MPI_Graph_create, (MPI_Comm comm_old, int nnodes, int* index, int* edges, int reorder,
MPI_Comm* comm_graph));
MPI_CALL(XBT_PUBLIC(int), MPI_Graph_get, (MPI_Comm comm, int maxindex, int maxedges, int* index, int* edges));
MPI_CALL(XBT_PUBLIC(int), MPI_Graph_neighbors_count, (MPI_Comm comm, int rank, int* nneighbors));
MPI_CALL(XBT_PUBLIC(int), MPI_Graphdims_get, (MPI_Comm comm, int* nnodes, int* nedges));
MPI_CALL(XBT_PUBLIC(int), MPI_Topo_test, (MPI_Comm comm, int* top_type));
-MPI_CALL(XBT_PUBLIC(int), MPI_Error_class, (int errorcode, int* errorclass));
MPI_CALL(XBT_PUBLIC(int), MPI_Errhandler_create, (MPI_Handler_function* function, MPI_Errhandler* errhandler));
MPI_CALL(XBT_PUBLIC(int), MPI_Errhandler_free, (MPI_Errhandler* errhandler));
MPI_CALL(XBT_PUBLIC(int), MPI_Errhandler_get, (MPI_Comm comm, MPI_Errhandler* errhandler));
MPI_CALL(XBT_PUBLIC(int), MPI_Buffer_attach, (void* buffer, int size));
MPI_CALL(XBT_PUBLIC(int), MPI_Buffer_detach, (void* buffer, int* size));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_test_inter, (MPI_Comm comm, int* flag));
-MPI_CALL(XBT_PUBLIC(int), MPI_Comm_get_attr, (MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag));
-MPI_CALL(XBT_PUBLIC(int), MPI_Comm_set_attr, (MPI_Comm comm, int comm_keyval, void *attribute_val));
-MPI_CALL(XBT_PUBLIC(int), MPI_Comm_delete_attr, (MPI_Comm comm, int comm_keyval));
-MPI_CALL(XBT_PUBLIC(int), MPI_Comm_create_keyval,(MPI_Comm_copy_attr_function* copy_fn,
- MPI_Comm_delete_attr_function* delete_fn, int* keyval, void* extra_state));
-MPI_CALL(XBT_PUBLIC(int), MPI_Comm_free_keyval,(int* keyval));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_get_attr, (MPI_Datatype type, int type_keyval, void *attribute_val, int* flag));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_set_attr, (MPI_Datatype type, int type_keyval, void *att));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_delete_attr, (MPI_Datatype type, int comm_keyval));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_create_keyval,(MPI_Type_copy_attr_function* copy_fn,
- MPI_Type_delete_attr_function* delete_fn, int* keyval, void* extra_state));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_free_keyval,(int* keyval));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_dup,(MPI_Datatype datatype,MPI_Datatype *newtype));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_set_name,(MPI_Datatype datatype, char * name));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_get_name,(MPI_Datatype datatype, char * name, int* len));
-MPI_CALL(XBT_PUBLIC(int), MPI_Unpack, (void* inbuf, int insize, int* position, void* outbuf, int outcount,
- MPI_Datatype type, MPI_Comm comm));
-MPI_CALL(XBT_PUBLIC(int), MPI_Ssend, (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm));
-MPI_CALL(XBT_PUBLIC(int), MPI_Ssend_init, (void* buf, int count, MPI_Datatype datatype, int dest, int tag,
- MPI_Comm comm, MPI_Request* request));
MPI_CALL(XBT_PUBLIC(int), MPI_Intercomm_create, (MPI_Comm local_comm, int local_leader, MPI_Comm peer_comm,
int remote_leader, int tag, MPI_Comm* comm_out));
MPI_CALL(XBT_PUBLIC(int), MPI_Intercomm_merge, (MPI_Comm comm, int high, MPI_Comm* comm_out));
MPI_Request* request));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_remote_group, (MPI_Comm comm, MPI_Group* group));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_remote_size, (MPI_Comm comm, int* size));
-MPI_CALL(XBT_PUBLIC(int), MPI_Issend, (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm,
- MPI_Request* request));
-MPI_CALL(XBT_PUBLIC(int), MPI_Attr_delete, (MPI_Comm comm, int keyval));
-MPI_CALL(XBT_PUBLIC(int), MPI_Attr_get, (MPI_Comm comm, int keyval, void* attr_value, int* flag));
-MPI_CALL(XBT_PUBLIC(int), MPI_Attr_put, (MPI_Comm comm, int keyval, void* attr_value));
MPI_CALL(XBT_PUBLIC(int), MPI_Rsend, (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm));
MPI_CALL(XBT_PUBLIC(int), MPI_Rsend_init, (void* buf, int count, MPI_Datatype datatype, int dest, int tag,
MPI_Comm comm, MPI_Request* request));
MPI_CALL(XBT_PUBLIC(int), MPI_Irsend, (void* buf, int count, MPI_Datatype datatype, int dest, int tag, MPI_Comm comm,
MPI_Request* request));
-MPI_CALL(XBT_PUBLIC(int), MPI_Keyval_create, (MPI_Copy_function* copy_fn, MPI_Delete_function* delete_fn, int* keyval,
- void* extra_state));
-MPI_CALL(XBT_PUBLIC(int), MPI_Keyval_free, (int* keyval));
MPI_CALL(XBT_PUBLIC(int), MPI_Test_cancelled, (MPI_Status* status, int* flag));
-MPI_CALL(XBT_PUBLIC(int), MPI_Pack, (void* inbuf, int incount, MPI_Datatype type, void* outbuf, int outcount,
- int* position, MPI_Comm comm));
MPI_CALL(XBT_PUBLIC(int), MPI_Get_elements, (MPI_Status* status, MPI_Datatype datatype, int* elements));
-MPI_CALL(XBT_PUBLIC(int), MPI_Dims_create, (int nnodes, int ndims, int* dims));
-MPI_CALL(XBT_PUBLIC(int), MPI_Initialized, (int* flag));
MPI_CALL(XBT_PUBLIC(int), MPI_Pcontrol, (const int level, ... ));
-MPI_CALL(XBT_PUBLIC(int), MPI_Info_create,( MPI_Info *info));
-MPI_CALL(XBT_PUBLIC(int), MPI_Info_set,( MPI_Info info, char *key, char *value));
-MPI_CALL(XBT_PUBLIC(int), MPI_Info_get,(MPI_Info info,char *key,int valuelen, char *value, int *flag));
-MPI_CALL(XBT_PUBLIC(int), MPI_Info_free,( MPI_Info *info));
-MPI_CALL(XBT_PUBLIC(int), MPI_Info_delete,( MPI_Info info, char *key));
-MPI_CALL(XBT_PUBLIC(int), MPI_Info_dup,(MPI_Info info, MPI_Info *newinfo));
-MPI_CALL(XBT_PUBLIC(int), MPI_Info_get_nkeys,( MPI_Info info, int *nkeys));
-MPI_CALL(XBT_PUBLIC(int), MPI_Info_get_nthkey,( MPI_Info info, int n, char *key));
-MPI_CALL(XBT_PUBLIC(int), MPI_Info_get_valuelen,( MPI_Info info, char *key, int *valuelen, int *flag));
-
-
MPI_CALL(XBT_PUBLIC(int), MPI_Win_set_errhandler, (MPI_Win win, MPI_Errhandler errhandler));
MPI_CALL(XBT_PUBLIC(int), MPI_Type_get_envelope,(MPI_Datatype datatype,int *num_integers,int *num_addresses,
int *num_datatypes, int *combiner));
void *outbuf, MPI_Aint outcount, MPI_Aint *position));
MPI_CALL(XBT_PUBLIC(int), MPI_Unpack_external, (char *datarep, void *inbuf, MPI_Aint insize, MPI_Aint *position,
void *outbuf, int outcount, MPI_Datatype datatype));
-MPI_CALL(XBT_PUBLIC(int), MPI_Type_create_resized ,(MPI_Datatype oldtype,MPI_Aint lb, MPI_Aint extent,
- MPI_Datatype *newtype));
MPI_CALL(XBT_PUBLIC(int), MPI_Type_create_subarray,(int ndims,int *array_of_sizes, int *array_of_subsizes,
int *array_of_starts, int order, MPI_Datatype oldtype, MPI_Datatype *newtype));
MPI_CALL(XBT_PUBLIC(int), MPI_Type_match_size,(int typeclass,int size,MPI_Datatype *datatype));
MPI_CALL(XBT_PUBLIC(int), MPI_Alltoallw, ( void *sendbuf, int *sendcnts, int *sdispls, MPI_Datatype *sendtypes,
void *recvbuf, int *recvcnts, int *rdispls, MPI_Datatype *recvtypes, MPI_Comm comm));
-MPI_CALL(XBT_PUBLIC(int), MPI_Exscan,(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op,
- MPI_Comm comm));
-MPI_CALL(XBT_PUBLIC(int), MPI_Comm_set_name, (MPI_Comm comm, char* name));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_set_info, (MPI_Comm comm, MPI_Info info));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_get_info, (MPI_Comm comm, MPI_Info* info));
-MPI_CALL(XBT_PUBLIC(int), MPI_Comm_dup, (MPI_Comm comm, MPI_Comm * newcomm));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_dup_with_info,(MPI_Comm comm, MPI_Info info, MPI_Comm * newcomm));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_split_type,(MPI_Comm comm, int split_type, int key, MPI_Info info,
MPI_Comm *newcomm));
int* array_of_maxprocs, MPI_Info* array_of_info, int root,
MPI_Comm comm, MPI_Comm *intercomm, int* array_of_errcodes));
MPI_CALL(XBT_PUBLIC(int), MPI_Comm_get_parent,( MPI_Comm *parent));
-MPI_CALL(XBT_PUBLIC(int), MPI_Win_complete,(MPI_Win win));
-
-MPI_CALL(XBT_PUBLIC(int), MPI_Win_post,(MPI_Group group, int assert, MPI_Win win));
-MPI_CALL(XBT_PUBLIC(int), MPI_Win_start,(MPI_Group group, int assert, MPI_Win win));
MPI_CALL(XBT_PUBLIC(int), MPI_Win_test,(MPI_Win win, int *flag));
-MPI_CALL(XBT_PUBLIC(int), MPI_Win_wait,(MPI_Win win));
-
-MPI_CALL(XBT_PUBLIC(int), MPI_Win_lock,(int lock_type, int rank, int assert, MPI_Win win));
-MPI_CALL(XBT_PUBLIC(int), MPI_Win_lock_all,(int assert, MPI_Win win));
-MPI_CALL(XBT_PUBLIC(int), MPI_Win_unlock,(int rank, MPI_Win win));
-MPI_CALL(XBT_PUBLIC(int), MPI_Win_unlock_all,(MPI_Win win));
-
-MPI_CALL(XBT_PUBLIC(int), MPI_Win_flush,(int rank, MPI_Win win));
-MPI_CALL(XBT_PUBLIC(int), MPI_Win_flush_local,(int rank, MPI_Win win));
-MPI_CALL(XBT_PUBLIC(int), MPI_Win_flush_all,(MPI_Win win));
-MPI_CALL(XBT_PUBLIC(int), MPI_Win_flush_local_all,(MPI_Win win));
MPI_CALL(XBT_PUBLIC(MPI_Fint), MPI_File_c2f,(MPI_File file));
MPI_CALL(XBT_PUBLIC(MPI_File), MPI_File_f2c,(MPI_Fint file));
/** Fortran binding + -fsecond-underscore **/
XBT_PUBLIC(void) smpi_trace_set_call_location__(const char *file, int* line);
-#define SMPI_SAMPLE_LOCAL(iters,thres) for(smpi_sample_1(0, __FILE__, __LINE__, iters, thres); \
- smpi_sample_2(0, __FILE__, __LINE__); \
- smpi_sample_3(0, __FILE__, __LINE__))
-
-#define SMPI_SAMPLE_GLOBAL(iters,thres) for(smpi_sample_1(1, __FILE__, __LINE__, iters, thres); \
- smpi_sample_2(1, __FILE__, __LINE__); \
- smpi_sample_3(1, __FILE__, __LINE__))
+#define SMPI_SAMPLE_LOOP(global, iters, thres) \
+ for (smpi_sample_1(global, __FILE__, __LINE__, iters, thres); smpi_sample_2(global, __FILE__, __LINE__); \
+ smpi_sample_3(global, __FILE__, __LINE__))
+#define SMPI_SAMPLE_LOCAL(iters, thres) SMPI_SAMPLE_LOOP(0, iters, thres)
+#define SMPI_SAMPLE_GLOBAL(iters, thres) SMPI_SAMPLE_LOOP(1, iters, thres)
#define SMPI_SAMPLE_DELAY(duration) for(smpi_execute(duration); 0; )
#define SMPI_SAMPLE_FLOPS(flops) for(smpi_execute_flops(flops); 0; )
#include <xbt/dynar.h>
#include <xbt/dict.h>
#include <xbt/swag.h>
-#include <xbt/heap.h>
#include <xbt/parmap.h>
#include <xbt/config.h>
#ifndef XBT_ALGORITHM_HPP
#define XBT_ALGORITHM_HPP
+#include <utility>
+
namespace simgrid {
namespace xbt {
+++ /dev/null
-/* Copyright (c) 2004-2007, 2009-2011, 2013-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 XBT_HEAP_H
-#define XBT_HEAP_H
-
-#include "xbt/misc.h"
-#include "xbt/dynar.h" /* void_f_pvoid_t */
-
-SG_BEGIN_DECL()
-
-/** @addtogroup XBT_heap
- * @brief This section describes the API to generic heap with O(log(n)) access.
- *
- * @deprecated If you are using C++ you might want to use `std::priority_queue`
- * instead.
- *
- * @{
- */
-/* @brief heap datatype */
-typedef struct xbt_heap *xbt_heap_t;
-
-XBT_PUBLIC(xbt_heap_t) xbt_heap_new(int init_size, void_f_pvoid_t const free_func);
-XBT_PUBLIC(void) xbt_heap_free(xbt_heap_t H);
-XBT_PUBLIC(int) xbt_heap_size(xbt_heap_t H);
-
-XBT_PUBLIC(void) xbt_heap_push(xbt_heap_t H, void *content, double key);
-XBT_PUBLIC(void *) xbt_heap_pop(xbt_heap_t H);
-XBT_PUBLIC(void *) xbt_heap_rm_elm(xbt_heap_t H, void *content, double key);
-
-XBT_PUBLIC(double) xbt_heap_maxkey(xbt_heap_t H);
-XBT_PUBLIC(void *) xbt_heap_maxcontent(xbt_heap_t H);
-XBT_PUBLIC(void) xbt_heap_set_update_callback(xbt_heap_t H, void (*update_callback) (void*, int));
-XBT_PUBLIC(void *) xbt_heap_remove(xbt_heap_t H, int i);
-XBT_PUBLIC(void ) xbt_heap_update(xbt_heap_t H, int i, double key);
-
-/* @} */
-SG_END_DECL()
-
-#endif /* _XBT_HEAP_H */
*
* @ingroup XBT_str
*/
-std::string string_printf(const char *fmt, ...);
+XBT_PUBLIC(std::string) string_printf(const char* fmt, ...);
/** Create a C++ string from a C-style format
*
* @ingroup XBT_str
*/
-std::string string_vprintf(const char *fmt, va_list ap);
-
+XBT_PUBLIC(std::string) string_vprintf(const char* fmt, va_list ap);
}
}
};
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);
}
/** @brief Blocks onto the given condition variable */
XBT_PUBLIC(void) xbt_cond_wait(xbt_cond_t cond, xbt_mutex_t mutex);
-/** @brief Blocks onto the given condition variable, but only for the given amount of time. a timeout exception is
- * raised if it was impossible to acquire it in the given time frame */
-XBT_PUBLIC(void) xbt_cond_timedwait(xbt_cond_t cond, xbt_mutex_t mutex, double delay);
+/** @brief Blocks onto the given condition variable, but only for the given amount of time.
+ * @return 0 on success, 1 on timeout */
+XBT_PUBLIC(int) xbt_cond_timedwait(xbt_cond_t cond, xbt_mutex_t mutex, double delay);
/** @brief Signals the given mutex variable */
XBT_PUBLIC(void) xbt_cond_signal(xbt_cond_t cond);
/** @brief Broadcasts the given mutex variable */
-/* Copyright (c) 2016. The SimGrid Team.
+/* Copyright (c) 2016-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 XBT_UTILITY_HPP
+#define XBT_UTILITY_HPP
+
#include <tuple>
namespace simgrid {
namespace xbt {
+/** @brief Comparator class for using with std::priority_queue or boost::heap.
+ *
+ * Compare two std::pair by their first element (of type double), and return true when the first is greater than the
+ * second. Useful to have priority queues with the smallest element on top.
+ */
+template <class Pair> class HeapComparator {
+public:
+ bool operator()(const Pair& a, const Pair& b) const { return a.first > b.first; }
+};
+
// integer_sequence and friends from C++14
// We need them to implement `apply` from C++17.
}
}
+#endif
# This file is used to scan the project for issues automatically
-# Browse the result here: https://sonarqube.com/dashboard?id=simgrid
+# Browse the result here: https://sonarcloud.io/dashboard/?id=simgrid
sonar.projectKey=simgrid
sonar.projectName=SimGrid
#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);
return jprocess;
}
+JNIEXPORT jint JNICALL Java_org_simgrid_msg_Process_nativeGetPID(JNIEnv* env, jobject jprocess)
+{
+ msg_process_t process = jprocess_to_native(jprocess, env);
+ return MSG_process_get_PID(process);
+}
+
JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_getProperty(JNIEnv *env, jobject jprocess, jobject jname) {
msg_process_t process = jprocess_to_native(jprocess, env);
/* 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 jint JNICALL Java_org_simgrid_msg_Process_nativeGetPID(JNIEnv* env, jobject jprocess);
JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_getProperty(JNIEnv* env, jobject jprocess, jobject jname);
JNIEXPORT jobject JNICALL Java_org_simgrid_msg_Process_getCurrentProcess(JNIEnv* env, jclass cls);
JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_suspend(JNIEnv* env, jobject jprocess);
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.
*
/** Example launcher. You can use it or provide your own launcher, as you wish
* @param args
- * @throws MsgException
*/
public static void main(String[]args) {
/* initialize the MSG simulation. Must be done before anything else (even logging). */
*
*/
public int getPID() {
+ if (pid == -1) // Don't traverse the JNI barrier if you already have the answer
+ pid = nativeGetPID();
return pid;
}
+ // This should not be used: the PID is supposed to be initialized from the C directly when the actor is created,
+ // but this sometimes fail, so let's play nasty but safe here.
+ private native int nativeGetPID();
/**
* This method returns the PID of the parent of a process.
*
/**
* This method actually creates and run the process.
* It is a noop if the process is already launched.
- * @throws HostNotFoundException
*/
public final void start() {
if (bind == 0)
private Host currentHost;
private int coreAmount = 1;
- /** Create a `basic' VM (i.e. 1GB of RAM, other values are not taken into account). */
+ /**
+ * Create a `basic' VM : 1 core and 1GB of RAM.
+ * @param host Host node
+ * @param name name of the machine
+ */
public VM(Host host, String name) {
this(host,name, /*coreAmount*/1, 1024, 0, 0);
}
-
+
+ /**
+ * Create a VM without useless values (for humans)
+ * @param host Host node
+ * @param name name of the machine
+ * @param coreAmount the amount of cores of the VM
+ */
public VM(Host host, String name, int coreAmount) {
this(host,name, coreAmount, 1024, 0, 0);
}
+
+ /**
+ * Create a VM with 1 core
+ * @param host Host node
+ * @param name name of the machine
+ * @param ramSize size of the RAM that should be allocated (in MBytes)
+ * @param migNetSpeed (network bandwith allocated for migrations in MB/s, if you don't know put zero ;))
+ * @param dpIntensity (dirty page percentage according to migNetSpeed, [0-100], if you don't know put zero ;))
+ */
public VM(Host host, String name, int ramSize, int migNetSpeed, int dpIntensity){
this(host, name, /*coreAmount*/1, ramSize, migNetSpeed, dpIntensity);
}
* Create a VM
* @param host Host node
* @param name name of the machine
+ * @param coreAmount the amount of cores of the VM
* @param ramSize size of the RAM that should be allocated (in MBytes)
* @param migNetSpeed (network bandwith allocated for migrations in MB/s, if you don't know put zero ;))
* @param dpIntensity (dirty page percentage according to migNetSpeed, [0-100], if you don't know put zero ;))
/* 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 MAXMIN_DATATYPES_H
-#define MAXMIN_DATATYPES_H
+#ifndef MAXMIN_DATATYPES_HPP
+#define MAXMIN_DATATYPES_HPP
+namespace simgrid {
+namespace surf {
typedef struct s_lmm_element_t* lmm_element_t;
typedef struct s_lmm_variable_t* lmm_variable_t;
typedef struct s_lmm_constraint_t* lmm_constraint_t;
typedef struct s_lmm_constraint_light_t* lmm_constraint_light_t;
typedef struct s_lmm_system_t* lmm_system_t;
+}
+}
#endif
#define SURF_MAXMIN_HPP
#include "src/internal_config.h"
+#include "src/surf/surf_interface.hpp"
#include "surf/surf.hpp"
#include "xbt/asserts.h"
+#include "xbt/mallocator.h"
#include "xbt/misc.h"
+#include "xbt/swag.h"
#include <cmath>
+#include <limits>
+#include <vector>
+
+namespace simgrid {
+namespace surf {
/** @addtogroup SURF_lmm
* @details
* constraint.
*/
-XBT_PUBLIC_DATA(double) sg_maxmin_precision;
-XBT_PUBLIC_DATA(double) sg_surf_precision;
-XBT_PUBLIC_DATA(int) sg_concurrency_limit;
-
-static inline void double_update(double* variable, double value, double precision)
-{
- // printf("Updating %g -= %g +- %g\n",*variable,value,precision);
- // xbt_assert(value==0 || value>precision);
- // Check that precision is higher than the machine-dependent size of the mantissa. If not, brutal rounding may
- // happen, and the precision mechanism is not active...
- // xbt_assert(*variable< (2<<DBL_MANT_DIG)*precision && FLT_RADIX==2);
- *variable -= value;
- if (*variable < precision)
- *variable = 0.0;
-}
-
-static inline int double_positive(double value, double precision)
-{
- return (value > precision);
-}
-
-static inline int double_equals(double value1, double value2, double precision)
-{
- return (fabs(value1 - value2) < precision);
-}
-
-extern "C" {
-
/** @{ @ingroup SURF_lmm */
-/**
- * @brief Create a new Linear MaxMim system
- * @param selective_update whether we should do lazy updates
- */
-XBT_PUBLIC(lmm_system_t) lmm_system_new(bool selective_update);
-
-/**
- * @brief Free an existing Linear MaxMin system
- * @param sys The lmm system to free
- */
-XBT_PUBLIC(void) lmm_system_free(lmm_system_t sys);
-
-/**
- * @brief Create a new Linear MaxMin constraint
- * @param sys The system in which we add a constraint
- * @param id Data associated to the constraint (e.g.: a network link)
- * @param bound_value The bound value of the constraint
- */
-XBT_PUBLIC(lmm_constraint_t) lmm_constraint_new(lmm_system_t sys, void* id, double bound_value);
-
-/**
- * @brief Share a constraint
- * @param cnst The constraint to share
- */
-XBT_PUBLIC(void) lmm_constraint_shared(lmm_constraint_t cnst);
-
-/**
- * @brief Check if a constraint is shared (shared by default)
- * @param cnst The constraint to share
- * @return 1 if shared, 0 otherwise
- */
-XBT_PUBLIC(int) lmm_constraint_sharing_policy(lmm_constraint_t cnst);
-
-/**
- * @brief Free a constraint
- * @param sys The system associated to the constraint
- * @param cnst The constraint to free
- */
-XBT_PUBLIC(void) lmm_constraint_free(lmm_system_t sys, lmm_constraint_t cnst);
-
-/**
- * @brief Get the usage of the constraint after the last lmm solve
- * @param cnst A constraint
- * @return The usage of the constraint
- */
-XBT_PUBLIC(double) lmm_constraint_get_usage(lmm_constraint_t cnst);
-
-XBT_PUBLIC(int) lmm_constraint_get_variable_amount(lmm_constraint_t cnst);
-
-/**
- * @brief Sets the concurrency limit for this constraint
- * @param cnst A constraint
- * @param concurrency_limit The concurrency limit to use for this constraint
- */
-XBT_PUBLIC(void) lmm_constraint_concurrency_limit_set(lmm_constraint_t cnst, int concurrency_limit);
-
-/**
- * @brief Gets the concurrency limit for this constraint
- * @param cnst A constraint
- * @return The concurrency limit used by this constraint
- */
-XBT_PUBLIC(int) lmm_constraint_concurrency_limit_get(lmm_constraint_t cnst);
-
-/**
- * @brief Reset the concurrency maximum for a given variable (we will update the maximum to reflect constraint
- * evolution).
- * @param cnst A constraint
-*/
-XBT_PUBLIC(void) lmm_constraint_concurrency_maximum_reset(lmm_constraint_t cnst);
-
-/**
- * @brief Get the concurrency maximum for a given variable (which reflects constraint evolution).
- * @param cnst A constraint
- * @return the maximum concurrency of the constraint
- */
-XBT_PUBLIC(int) lmm_constraint_concurrency_maximum_get(lmm_constraint_t cnst);
-
-/**
- * @brief Create a new Linear MaxMin variable
- * @param sys The system in which we add a constaint
- * @param id Data associated to the variable (e.g.: a network communication)
- * @param weight_value The weight of the variable (0.0 if not used)
- * @param bound The maximum value of the variable (-1.0 if no maximum value)
- * @param number_of_constraints The maximum number of constraint to associate to the variable
- */
-XBT_PUBLIC(lmm_variable_t)
-lmm_variable_new(lmm_system_t sys, simgrid::surf::Action* id, double weight_value, double bound,
- int number_of_constraints);
-/**
- * @brief Free a variable
- * @param sys The system associated to the variable
- * @param var The variable to free
- */
-XBT_PUBLIC(void) lmm_variable_free(lmm_system_t sys, lmm_variable_t var);
-
-/**
- * @brief Get the value of the variable after the last lmm solve
- * @param var A variable
- * @return The value of the variable
- */
-XBT_PUBLIC(double) lmm_variable_getvalue(lmm_variable_t var);
-
-/**
- * @brief Get the maximum value of the variable (-1.0 if no maximum value)
- * @param var A variable
- * @return The bound of the variable
- */
-XBT_PUBLIC(double) lmm_variable_getbound(lmm_variable_t var);
-
-/**
- * @brief Set the concurrent share of the variable
- * @param var A variable
- * @param concurrency_share The new concurrency share
- */
-XBT_PUBLIC(void) lmm_variable_concurrency_share_set(lmm_variable_t var, short int concurrency_share);
-
-/**
- * @brief Remove a variable from a constraint
- * @param sys A system
- * @param cnst A constraint
- * @param var The variable to remove
- */
-XBT_PUBLIC(void) lmm_shrink(lmm_system_t sys, lmm_constraint_t cnst, lmm_variable_t var);
-
-/**
- * @brief Associate a variable to a constraint with a coefficient
- * @param sys A system
- * @param cnst A constraint
- * @param var A variable
- * @param value The coefficient associated to the variable in the constraint
- */
-XBT_PUBLIC(void) lmm_expand(lmm_system_t sys, lmm_constraint_t cnst, lmm_variable_t var, double value);
-
-/**
- * @brief Add value to the coefficient between a constraint and a variable or create one
- * @param sys A system
- * @param cnst A constraint
- * @param var A variable
- * @param value The value to add to the coefficient associated to the variable in the constraint
- */
-XBT_PUBLIC(void) lmm_expand_add(lmm_system_t sys, lmm_constraint_t cnst, lmm_variable_t var, double value);
-
-/**
- * @brief Get the numth constraint associated to the variable
- * @param sys The system associated to the variable (not used)
- * @param var A variable
- * @param num The rank of constraint we want to get
- * @return The numth constraint
- */
-XBT_PUBLIC(lmm_constraint_t) lmm_get_cnst_from_var(lmm_system_t sys, lmm_variable_t var, int num);
-
-/**
- * @brief Get the weigth of the numth constraint associated to the variable
- * @param sys The system associated to the variable (not used)
- * @param var A variable
- * @param num The rank of constraint we want to get
- * @return The numth constraint
- */
-XBT_PUBLIC(double) lmm_get_cnst_weight_from_var(lmm_system_t sys, lmm_variable_t var, int num);
-
-/**
- * @brief Get the number of constraint associated to a variable
- * @param sys The system associated to the variable (not used)
- * @param var A variable
- * @return The number of constraint associated to the variable
- */
-XBT_PUBLIC(int) lmm_get_number_of_cnst_from_var(lmm_system_t sys, lmm_variable_t var);
-
-/**
- * @brief Get a var associated to a constraint
- * @details Get the first variable of the next variable of elem if elem is not NULL
- * @param sys The system associated to the variable (not used)
- * @param cnst A constraint
- * @param elem A element of constraint of the constraint or NULL
- * @return A variable associated to a constraint
- */
-XBT_PUBLIC(lmm_variable_t) lmm_get_var_from_cnst(lmm_system_t sys, lmm_constraint_t cnst, lmm_element_t* elem);
-
-/**
- * @brief Get a var associated to a constraint
- * @details Get the first variable of the next variable of elem if elem is not NULL
- * @param cnst A constraint
- * @param elem A element of constraint of the constraint or NULL
- * @param nextelem A element of constraint of the constraint or NULL, the one after elem
- * @param numelem parameter representing the number of elements to go
- *
- * @return A variable associated to a constraint
- */
-XBT_PUBLIC(lmm_variable_t)
-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
- * @return The data associated to the constraint
- */
-XBT_PUBLIC(void*) lmm_constraint_id(lmm_constraint_t cnst);
-
-/**
- * @brief Get the data associated to a variable
- * @param var A variable
- * @return The data associated to the variable
- */
-XBT_PUBLIC(void*) lmm_variable_id(lmm_variable_t var);
-
-/**
- * @brief Update the value of element linking the constraint and the variable
- * @param sys A system
- * @param cnst A constraint
- * @param var A variable
- * @param value The new value
- */
-XBT_PUBLIC(void) lmm_update(lmm_system_t sys, lmm_constraint_t cnst, lmm_variable_t var, double value);
-
-/**
- * @brief Update the bound of a variable
- * @param sys A system
- * @param var A constraint
- * @param bound The new bound
- */
-XBT_PUBLIC(void) lmm_update_variable_bound(lmm_system_t sys, lmm_variable_t var, double bound);
-
-/**
- * @brief Update the weight of a variable
- * @param sys A system
- * @param var A variable
- * @param weight The new weight of the variable
- */
-XBT_PUBLIC(void) lmm_update_variable_weight(lmm_system_t sys, lmm_variable_t var, double weight);
-
-/**
- * @brief Get the weight of a variable
- * @param var A variable
- * @return The weight of the variable
- */
-XBT_PUBLIC(double) lmm_get_variable_weight(lmm_variable_t var);
-
-/**
- * @brief Update a constraint bound
- * @param sys A system
- * @param cnst A constraint
- * @param bound The new bound of the consrtaint
- */
-XBT_PUBLIC(void) lmm_update_constraint_bound(lmm_system_t sys, lmm_constraint_t cnst, double bound);
-
-/**
- * @brief [brief description]
- * @param sys A system
- * @param cnst A constraint
- * @return [description]
- */
-XBT_PUBLIC(int) lmm_constraint_used(lmm_system_t sys, lmm_constraint_t cnst);
-
-/**
- * @brief Print the lmm system
- * @param sys The lmm system to print
- */
-XBT_PUBLIC(void) lmm_print(lmm_system_t sys);
/**
* @brief Solve the lmm system
XBT_PUBLIC(double) func_vegas_fp(lmm_variable_t var, double x);
XBT_PUBLIC(double) func_vegas_fpi(lmm_variable_t var, double x);
+/**
+ * @brief LMM element
+ * Elements can be seen as glue between constraint objects and variable objects.
+ * Basically, each variable will have a set of elements, one for each constraint where it is involved.
+ * Then, it is used to list all variables involved in constraint through constraint's xxx_element_set lists, or
+ * vice-versa list all constraints for a given variable.
+ */
+XBT_PUBLIC_CLASS s_lmm_element_t {
+public:
+ int get_concurrency() const;
+ void decrease_concurrency();
+ void increase_concurrency();
+
+ void make_active();
+ void make_inactive();
+
+ /* hookup to constraint */
+ s_xbt_swag_hookup_t enabled_element_set_hookup;
+ s_xbt_swag_hookup_t disabled_element_set_hookup;
+ s_xbt_swag_hookup_t active_element_set_hookup;
+
+ lmm_constraint_t constraint;
+ lmm_variable_t variable;
+
+ // consumption_weight: impact of 1 byte or flop of your application onto the resource (in byte or flop)
+ // - if CPU, then probably 1.
+ // - If network, then 1 in forward direction and 0.05 backward for the ACKs
+ double consumption_weight;
+};
+
+struct s_lmm_constraint_light_t {
+ double remaining_over_usage;
+ lmm_constraint_t cnst;
+};
+
+/**
+ * @brief LMM constraint
+ * Each constraint contains several partially overlapping logical sets of elements:
+ * \li Disabled elements which variable's weight is zero. This variables are not at all processed by LMM, but eventually
+ * the corresponding action will enable it (at least this is the idea).
+ * \li Enabled elements which variable's weight is non-zero. They are utilized in some LMM functions.
+ * \li Active elements which variable's weight is non-zero (i.e. it is enabled) AND its element value is non-zero.
+ * LMM_solve iterates over active elements during resolution, dynamically making them active or unactive.
+ */
+XBT_PUBLIC_CLASS s_lmm_constraint_t {
+public:
+ s_lmm_constraint_t() = default;
+ s_lmm_constraint_t(void* id_value, double bound_value);
+
+ /** @brief Unshare a constraint. */
+ void unshare() { sharing_policy = 0; }
+
+ /**
+ * @brief Check if a constraint is shared (shared by default)
+ * @return 1 if shared, 0 otherwise
+ */
+ int get_sharing_policy() const { return sharing_policy; }
+
+ /**
+ * @brief Get the usage of the constraint after the last lmm solve
+ * @return The usage of the constraint
+ */
+ double get_usage() const;
+ int get_variable_amount() const;
+
+ /**
+ * @brief Sets the concurrency limit for this constraint
+ * @param concurrency_limit The concurrency limit to use for this constraint
+ */
+ void set_concurrency_limit(int limit)
+ {
+ xbt_assert(limit < 0 || concurrency_maximum <= limit,
+ "New concurrency limit should be larger than observed concurrency maximum. Maybe you want to call"
+ " concurrency_maximum_reset() to reset the maximum?");
+ concurrency_limit = limit;
+ }
+
+ /**
+ * @brief Gets the concurrency limit for this constraint
+ * @return The concurrency limit used by this constraint
+ */
+ int get_concurrency_limit() const { return concurrency_limit; }
+
+ /**
+ * @brief Reset the concurrency maximum for a given variable (we will update the maximum to reflect constraint
+ * evolution).
+ */
+ void reset_concurrency_maximum() { concurrency_maximum = 0; }
+
+ /**
+ * @brief Get the concurrency maximum for a given variable (which reflects constraint evolution).
+ * @return the maximum concurrency of the constraint
+ */
+ int get_concurrency_maximum() const
+ {
+ xbt_assert(concurrency_limit < 0 || concurrency_maximum <= concurrency_limit,
+ "Very bad: maximum observed concurrency is higher than limit. This is a bug of SURF, please report it.");
+ return concurrency_maximum;
+ }
+
+ int get_concurrency_slack() const
+ {
+ return concurrency_limit < 0 ? std::numeric_limits<int>::max() : concurrency_limit - concurrency_current;
+ }
+
+ /**
+ * @brief Get a var associated to a constraint
+ * @details Get the first variable of the next variable of elem if elem is not NULL
+ * @param elem A element of constraint of the constraint or NULL
+ * @return A variable associated to a constraint
+ */
+ lmm_variable_t get_variable(lmm_element_t* elem) const;
+
+ /**
+ * @brief Get a var associated to a constraint
+ * @details Get the first variable of the next variable of elem if elem is not NULL
+ * @param elem A element of constraint of the constraint or NULL
+ * @param nextelem A element of constraint of the constraint or NULL, the one after elem
+ * @param numelem parameter representing the number of elements to go
+ * @return A variable associated to a constraint
+ */
+ lmm_variable_t get_variable_safe(lmm_element_t* elem, lmm_element_t* nextelem, int* numelem) const;
+
+ /**
+ * @brief Get the data associated to a constraint
+ * @return The data associated to the constraint
+ */
+ void* get_id() const { return id; }
+
+ /* hookup to system */
+ s_xbt_swag_hookup_t constraint_set_hookup = {nullptr, nullptr};
+ s_xbt_swag_hookup_t active_constraint_set_hookup = {nullptr, nullptr};
+ s_xbt_swag_hookup_t modified_constraint_set_hookup = {nullptr, nullptr};
+ s_xbt_swag_hookup_t saturated_constraint_set_hookup = {nullptr, nullptr};
+ s_xbt_swag_t enabled_element_set; /* a list of lmm_element_t */
+ s_xbt_swag_t disabled_element_set; /* a list of lmm_element_t */
+ s_xbt_swag_t active_element_set; /* a list of lmm_element_t */
+ double remaining;
+ double usage;
+ double bound;
+ // TODO MARTIN Check maximum value across resources at the end of simulation and give a warning is more than e.g. 500
+ int concurrency_current; /* The current concurrency */
+ int concurrency_maximum; /* The maximum number of (enabled and disabled) variables associated to the constraint at any
+ * given time (essentially for tracing)*/
+
+ int sharing_policy; /* see @e_surf_link_sharing_policy_t (0: FATPIPE, 1: SHARED, 2: FULLDUPLEX) */
+ int id_int;
+ double lambda;
+ double new_lambda;
+ lmm_constraint_light_t cnst_light;
+
+private:
+ static int Global_debug_id;
+ int concurrency_limit; /* The maximum number of variables that may be enabled at any time (stage variables if
+ * necessary) */
+ void* id;
+};
+
+/**
+ * @brief LMM variable
+ *
+ * When something prevents us from enabling a variable, we "stage" the weight that we would have like to set, so that as
+ * soon as possible we enable the variable with desired weight
+ */
+XBT_PUBLIC_CLASS s_lmm_variable_t {
+public:
+ void initialize(simgrid::surf::Action* id_value, double sharing_weight_value, double bound_value,
+ int number_of_constraints, unsigned visited_value);
+
+ /**
+ * @brief Get the value of the variable after the last lmm solve
+ * @return The value of the variable
+ */
+ double get_value() const { return value; }
+
+ /**
+ * @brief Get the maximum value of the variable (-1.0 if no maximum value)
+ * @return The bound of the variable
+ */
+ double get_bound() const { return bound; }
+
+ /**
+ * @brief Set the concurrent share of the variable
+ * @param concurrency_share The new concurrency share
+ */
+ void set_concurrency_share(short int value) { concurrency_share = value; }
+
+ /**
+ * @brief Get the numth constraint associated to the variable
+ * @param num The rank of constraint we want to get
+ * @return The numth constraint
+ */
+ lmm_constraint_t get_constraint(unsigned num) const { return num < cnsts.size() ? cnsts[num].constraint : nullptr; }
+
+ /**
+ * @brief Get the weigth of the numth constraint associated to the variable
+ * @param num The rank of constraint we want to get
+ * @return The numth constraint
+ */
+ double get_constraint_weight(unsigned num) const { return num < cnsts.size() ? cnsts[num].consumption_weight : 0.0; }
+
+ /**
+ * @brief Get the number of constraint associated to a variable
+ * @return The number of constraint associated to the variable
+ */
+ int get_number_of_constraint() const { return cnsts.size(); }
+
+ /**
+ * @brief Get the data associated to a variable
+ * @return The data associated to the variable
+ */
+ simgrid::surf::Action* get_id() const { return id; }
+
+ /**
+ * @brief Get the weight of a variable
+ * @return The weight of the variable
+ */
+ double get_weight() const { return sharing_weight; }
+
+ /** @brief Measure the minimum concurrency slack across all constraints where the given var is involved */
+ int get_min_concurrency_slack() const;
+
+ /** @brief Check if a variable can be enabled
+ * Make sure to set staged_weight before, if your intent is only to check concurrency
+ */
+ int can_enable() const { return staged_weight > 0 && get_min_concurrency_slack() >= concurrency_share; }
+
+ /* hookup to system */
+ s_xbt_swag_hookup_t variable_set_hookup = {nullptr, nullptr};
+ s_xbt_swag_hookup_t saturated_variable_set_hookup = {nullptr, nullptr};
+
+ std::vector<s_lmm_element_t> cnsts;
+
+ // sharing_weight: variable's impact on the resource during the sharing
+ // if == 0, the variable is not considered by LMM
+ // on CPU, actions with N threads have a sharing of N
+ // on network, the actions with higher latency have a lesser sharing_weight
+ double sharing_weight;
+
+ double staged_weight; /* If non-zero, variable is staged for addition as soon as maxconcurrency constraints will be
+ * met */
+ double bound;
+ double value;
+ short int concurrency_share; /* The maximum number of elements that variable will add to a constraint */
+ simgrid::surf::Action* id;
+ int id_int;
+ unsigned visited; /* used by lmm_update_modified_set */
+ /* \begin{For Lagrange only} */
+ double mu;
+ double new_mu;
+ double (*func_f)(s_lmm_variable_t* var, double x); /* (f) */
+ double (*func_fp)(s_lmm_variable_t* var, double x); /* (f') */
+ double (*func_fpi)(s_lmm_variable_t* var, double x); /* (f')^{-1} */
+ /* \end{For Lagrange only} */
+
+private:
+ static int Global_debug_id;
+};
+
+inline void s_lmm_element_t::make_active()
+{
+ xbt_swag_insert_at_head(this, &constraint->active_element_set);
+}
+inline void s_lmm_element_t::make_inactive()
+{
+ xbt_swag_remove(this, &constraint->active_element_set);
+}
+
+/**
+ * @brief LMM system
+ */
+XBT_PUBLIC_CLASS s_lmm_system_t {
+public:
+ /**
+ * @brief Create a new Linear MaxMim system
+ * @param selective_update whether we should do lazy updates
+ */
+ explicit s_lmm_system_t(bool selective_update);
+ /** @brief Free an existing Linear MaxMin system */
+ ~s_lmm_system_t();
+
+ /**
+ * @brief Create a new Linear MaxMin constraint
+ * @param id Data associated to the constraint (e.g.: a network link)
+ * @param bound_value The bound value of the constraint
+ */
+ lmm_constraint_t constraint_new(void* id, double bound_value);
+
+ /**
+ * @brief Create a new Linear MaxMin variable
+ * @param id Data associated to the variable (e.g.: a network communication)
+ * @param weight_value The weight of the variable (0.0 if not used)
+ * @param bound The maximum value of the variable (-1.0 if no maximum value)
+ * @param number_of_constraints The maximum number of constraint to associate to the variable
+ */
+ lmm_variable_t variable_new(simgrid::surf::Action* id, double weight_value, double bound, int number_of_constraints);
+
+ /**
+ * @brief Free a variable
+ * @param var The variable to free
+ */
+ void variable_free(lmm_variable_t var);
+
+ /**
+ * @brief Associate a variable to a constraint with a coefficient
+ * @param cnst A constraint
+ * @param var A variable
+ * @param value The coefficient associated to the variable in the constraint
+ */
+ void expand(lmm_constraint_t cnst, lmm_variable_t var, double value);
+
+ /**
+ * @brief Add value to the coefficient between a constraint and a variable or create one
+ * @param cnst A constraint
+ * @param var A variable
+ * @param value The value to add to the coefficient associated to the variable in the constraint
+ */
+ void expand_add(lmm_constraint_t cnst, lmm_variable_t var, double value);
+
+ /**
+ * @brief Update the bound of a variable
+ * @param var A constraint
+ * @param bound The new bound
+ */
+ void update_variable_bound(lmm_variable_t var, double bound);
+
+ /**
+ * @brief Update the weight of a variable
+ * @param var A variable
+ * @param weight The new weight of the variable
+ */
+ void update_variable_weight(lmm_variable_t var, double weight);
+
+ /**
+ * @brief Update a constraint bound
+ * @param cnst A constraint
+ * @param bound The new bound of the consrtaint
+ */
+ void update_constraint_bound(lmm_constraint_t cnst, double bound);
+
+ /**
+ * @brief [brief description]
+ * @param cnst A constraint
+ * @return [description]
+ */
+ int constraint_used(lmm_constraint_t cnst) { return xbt_swag_belongs(cnst, &active_constraint_set); }
+
+ /** @brief Print the lmm system */
+ void print();
+
+ /** @brief Solve the lmm system */
+ void solve();
+
+private:
+ static void* variable_mallocator_new_f();
+ static void variable_mallocator_free_f(void* var);
+
+ void var_free(lmm_variable_t var);
+ void cnst_free(lmm_constraint_t cnst);
+ lmm_variable_t extract_variable() { return static_cast<lmm_variable_t>(xbt_swag_extract(&variable_set)); }
+ lmm_constraint_t extract_constraint() { return static_cast<lmm_constraint_t>(xbt_swag_extract(&constraint_set)); }
+ void insert_constraint(lmm_constraint_t cnst) { xbt_swag_insert(cnst, &constraint_set); }
+ void remove_variable(lmm_variable_t var)
+ {
+ xbt_swag_remove(var, &variable_set);
+ xbt_swag_remove(var, &saturated_variable_set);
+ }
+ void make_constraint_active(lmm_constraint_t cnst) { xbt_swag_insert(cnst, &active_constraint_set); }
+ void make_constraint_inactive(lmm_constraint_t cnst)
+ {
+ xbt_swag_remove(cnst, &active_constraint_set);
+ xbt_swag_remove(cnst, &modified_constraint_set);
+ }
+
+ void enable_var(lmm_variable_t var);
+ void disable_var(lmm_variable_t var);
+ void on_disabled_var(lmm_constraint_t cnstr);
+
+ /**
+ * @brief Update the value of element linking the constraint and the variable
+ * @param cnst A constraint
+ * @param var A variable
+ * @param value The new value
+ */
+ void update(lmm_constraint_t cnst, lmm_variable_t var, double value);
+
+ void update_modified_set(lmm_constraint_t cnst);
+ void update_modified_set_rec(lmm_constraint_t cnst);
+
+ /** @brief Remove all constraints of the modified_constraint_set. */
+ void remove_all_modified_set();
+ void check_concurrency();
+
+public:
+ bool modified;
+ s_xbt_swag_t variable_set; /* a list of lmm_variable_t */
+ s_xbt_swag_t active_constraint_set; /* a list of lmm_constraint_t */
+ s_xbt_swag_t saturated_variable_set; /* a list of lmm_variable_t */
+ s_xbt_swag_t saturated_constraint_set; /* a list of lmm_constraint_t */
+
+ simgrid::surf::ActionLmmListPtr keep_track;
+
+ void (*solve_fun)(lmm_system_t self);
+
+private:
+ bool selective_update_active; /* flag to update partially the system only selecting changed portions */
+ unsigned visited_counter; /* used by lmm_update_modified_set and lmm_remove_modified_set to cleverly (un-)flag the
+ * constraints (more details in these functions) */
+ s_xbt_swag_t constraint_set; /* a list of lmm_constraint_t */
+ s_xbt_swag_t modified_constraint_set; /* a list of modified lmm_constraint_t */
+ xbt_mallocator_t variable_mallocator;
+};
+
+extern XBT_PRIVATE double (*func_f_def)(lmm_variable_t, double);
+extern XBT_PRIVATE double (*func_fp_def)(lmm_variable_t, double);
+extern XBT_PRIVATE double (*func_fpi_def)(lmm_variable_t, double);
+
/** @} */
}
+}
#endif
#include "simgrid/datatypes.h"
#include "simgrid/forward.h"
#include "src/internal_config.h"
-#include "surf/datatypes.h"
+#include "surf/datatypes.hpp"
#include "xbt/config.h"
#include "xbt/dict.h"
#include "xbt/dynar.h"
#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:
std::vector<int>* recvcounts = nullptr;
std::string send_type = "";
std::string recv_type = "";
- ;
// NoOpTI: init, finalize, test, wait, barrier
explicit TIData(std::string name) : name_(name){};
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;
}
}
/* 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 "maxmin_private.hpp"
+#include "surf/maxmin.hpp"
#include "xbt/log.h"
#include "xbt/sysdep.h"
+#include <algorithm>
#include <cfloat>
#include <cmath>
#include <cstdlib>
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_maxmin);
-#define SHOW_EXPR_G(expr) XBT_DEBUG(#expr " = %g",expr);
-#define SHOW_EXPR_D(expr) XBT_DEBUG(#expr " = %d",expr);
-#define SHOW_EXPR_P(expr) XBT_DEBUG(#expr " = %p",expr);
+#define SHOW_EXPR_G(expr) XBT_DEBUG(#expr " = %g", expr);
+#define SHOW_EXPR_D(expr) XBT_DEBUG(#expr " = %d", expr);
+#define SHOW_EXPR_P(expr) XBT_DEBUG(#expr " = %p", expr);
-void bottleneck_solve(lmm_system_t sys)
+void simgrid::surf::bottleneck_solve(lmm_system_t sys)
{
- void *_var;
- void *_var_next;
- void *_cnst;
- void *_cnst_next;
- void *_elem;
- lmm_variable_t var = nullptr;
+ void* _var;
+ void* _var_next;
+ void* _cnst;
+ void* _cnst_next;
+ void* _elem;
+ lmm_variable_t var = nullptr;
lmm_constraint_t cnst = nullptr;
s_lmm_constraint_t s_cnst;
- lmm_element_t elem = nullptr;
+ lmm_element_t elem = nullptr;
xbt_swag_t cnst_list = nullptr;
- xbt_swag_t var_list = nullptr;
+ xbt_swag_t var_list = nullptr;
xbt_swag_t elem_list = nullptr;
static s_xbt_swag_t cnst_to_update;
var_list = &(sys->variable_set);
XBT_DEBUG("Variable set : %d", xbt_swag_size(var_list));
- xbt_swag_foreach(_var, var_list) {
- var = static_cast<lmm_variable_t>(_var);
- int nb = 0;
+ xbt_swag_foreach(_var, var_list)
+ {
+ var = static_cast<lmm_variable_t>(_var);
var->value = 0.0;
XBT_DEBUG("Handling variable %p", var);
xbt_swag_insert(var, &(sys->saturated_variable_set));
- for (int i = 0; i < var->cnsts_number; i++) {
- if (var->cnsts[i].consumption_weight == 0.0)
- nb++;
- }
- if ((nb == var->cnsts_number) && (var->sharing_weight > 0.0)) {
+ auto weighted = std::find_if(begin(var->cnsts), end(var->cnsts),
+ [](s_lmm_element_t const& x) { return x.consumption_weight != 0.0; });
+ if (weighted == end(var->cnsts) && var->sharing_weight > 0.0) {
XBT_DEBUG("Err, finally, there is no need to take care of variable %p", var);
xbt_swag_remove(var, &(sys->saturated_variable_set));
var->value = 1.0;
cnst_list = &(sys->active_constraint_set);
XBT_DEBUG("Active constraints : %d", xbt_swag_size(cnst_list));
- xbt_swag_foreach(_cnst, cnst_list) {
+ xbt_swag_foreach(_cnst, cnst_list)
+ {
cnst = static_cast<lmm_constraint_t>(_cnst);
xbt_swag_insert(cnst, &(sys->saturated_constraint_set));
}
cnst_list = &(sys->saturated_constraint_set);
- xbt_swag_foreach(_cnst, cnst_list) {
- cnst = static_cast<lmm_constraint_t>(_cnst);
+ xbt_swag_foreach(_cnst, cnst_list)
+ {
+ cnst = static_cast<lmm_constraint_t>(_cnst);
cnst->remaining = cnst->bound;
- cnst->usage = 0.0;
+ cnst->usage = 0.0;
}
XBT_DEBUG("Fair bottleneck Initialized");
do {
if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
XBT_DEBUG("Fair bottleneck done");
- lmm_print(sys);
+ sys->print();
}
XBT_DEBUG("******* Constraints to process: %d *******", xbt_swag_size(cnst_list));
- xbt_swag_foreach_safe(_cnst, _cnst_next, cnst_list) {
- cnst = static_cast<lmm_constraint_t>(_cnst);
+ xbt_swag_foreach_safe(_cnst, _cnst_next, cnst_list)
+ {
+ cnst = static_cast<lmm_constraint_t>(_cnst);
int nb = 0;
XBT_DEBUG("Processing cnst %p ", cnst);
- elem_list = &(cnst->enabled_element_set);
+ elem_list = &(cnst->enabled_element_set);
cnst->usage = 0.0;
- xbt_swag_foreach(_elem, elem_list) {
+ xbt_swag_foreach(_elem, elem_list)
+ {
elem = static_cast<lmm_element_t>(_elem);
xbt_assert(elem->variable->sharing_weight > 0);
if ((elem->consumption_weight > 0) && xbt_swag_belongs(elem->variable, var_list))
nb = 1;
if (not nb) {
cnst->remaining = 0.0;
- cnst->usage = cnst->remaining;
+ cnst->usage = cnst->remaining;
xbt_swag_remove(cnst, cnst_list);
continue;
}
XBT_DEBUG("\tConstraint Usage %p : %f with %d variables", cnst, cnst->usage, nb);
}
- xbt_swag_foreach_safe(_var, _var_next, var_list) {
- var = static_cast<lmm_variable_t>(_var);
+ xbt_swag_foreach_safe(_var, _var_next, var_list)
+ {
+ var = static_cast<lmm_variable_t>(_var);
double min_inc = DBL_MAX;
- for (int i = 0; i < var->cnsts_number; i++) {
- lmm_element_t elm = &var->cnsts[i];
- if (elm->consumption_weight > 0)
- min_inc = MIN(min_inc, elm->constraint->usage / elm->consumption_weight);
+ for (s_lmm_element_t const& elm : var->cnsts) {
+ if (elm.consumption_weight > 0)
+ min_inc = std::min(min_inc, elm.constraint->usage / elm.consumption_weight);
}
if (var->bound > 0)
- min_inc = MIN(min_inc, var->bound - var->value);
- var->mu = min_inc;
+ min_inc = std::min(min_inc, var->bound - var->value);
+ var->mu = min_inc;
XBT_DEBUG("Updating variable %p maximum increment: %g", var, var->mu);
var->value += var->mu;
if (var->value == var->bound) {
}
}
- xbt_swag_foreach_safe(_cnst, _cnst_next, cnst_list) {
+ xbt_swag_foreach_safe(_cnst, _cnst_next, cnst_list)
+ {
cnst = static_cast<lmm_constraint_t>(_cnst);
XBT_DEBUG("Updating cnst %p ", cnst);
elem_list = &(cnst->enabled_element_set);
- xbt_swag_foreach(_elem, elem_list) {
+ xbt_swag_foreach(_elem, elem_list)
+ {
elem = static_cast<lmm_element_t>(_elem);
xbt_assert(elem->variable->sharing_weight > 0);
if (cnst->sharing_policy) {
XBT_DEBUG("\tUpdate constraint %p (%g) with variable %p by %g", cnst, cnst->remaining, elem->variable,
- elem->variable->mu);
+ elem->variable->mu);
double_update(&(cnst->remaining), elem->consumption_weight * elem->variable->mu, sg_maxmin_precision);
} else {
- XBT_DEBUG("\tNon-Shared variable. Update constraint usage of %p (%g) with variable %p by %g",
- cnst, cnst->usage, elem->variable, elem->variable->mu);
- cnst->usage = MIN(cnst->usage, elem->consumption_weight * elem->variable->mu);
+ XBT_DEBUG("\tNon-Shared variable. Update constraint usage of %p (%g) with variable %p by %g", cnst,
+ cnst->usage, elem->variable, elem->variable->mu);
+ cnst->usage = std::min(cnst->usage, elem->consumption_weight * elem->variable->mu);
}
}
if (not cnst->sharing_policy) {
XBT_DEBUG("\tGet rid of constraint %p", cnst);
xbt_swag_remove(cnst, cnst_list);
- xbt_swag_foreach(_elem, elem_list) {
+ xbt_swag_foreach(_elem, elem_list)
+ {
elem = static_cast<lmm_element_t>(_elem);
if (elem->variable->sharing_weight <= 0)
break;
} while (xbt_swag_size(var_list));
xbt_swag_reset(cnst_list);
- sys->modified = 0;
+ sys->modified = true;
if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
XBT_DEBUG("Fair bottleneck done");
- lmm_print(sys);
+ sys->print();
}
}
* Modeling the proportional fairness using the Lagrangian Optimization Approach. For a detailed description see:
* "ssh://username@scm.gforge.inria.fr/svn/memo/people/pvelho/lagrange/ppf.ps".
*/
+#include "surf/maxmin.hpp"
#include "xbt/log.h"
#include "xbt/sysdep.h"
-#include "maxmin_private.hpp"
+#include <algorithm>
#include <cstdlib>
#ifndef MATH
#include <cmath>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_lagrange, surf, "Logging specific to SURF (lagrange)");
XBT_LOG_NEW_SUBCATEGORY(surf_lagrange_dichotomy, surf_lagrange, "Logging specific to SURF (lagrange dichotomy)");
-#define SHOW_EXPR(expr) XBT_CDEBUG(surf_lagrange,#expr " = %g",expr);
+#define SHOW_EXPR(expr) XBT_CDEBUG(surf_lagrange, #expr " = %g", expr);
+#define VEGAS_SCALING 1000.0
+#define RENO_SCALING 1.0
+#define RENO2_SCALING 1.0
+
+namespace simgrid {
+namespace surf {
-double (*func_f_def) (lmm_variable_t, double);
-double (*func_fp_def) (lmm_variable_t, double);
-double (*func_fpi_def) (lmm_variable_t, double);
+double (*func_f_def)(lmm_variable_t, double);
+double (*func_fp_def)(lmm_variable_t, double);
+double (*func_fpi_def)(lmm_variable_t, double);
/*
* Local prototypes to implement the Lagrangian optimization with optimal step, also called dichotomy.
*/
-//solves the proportional fairness using a Lagrangian optimization with dichotomy step
+// solves the proportional fairness using a Lagrangian optimization with dichotomy step
void lagrange_solve(lmm_system_t sys);
-//computes the value of the dichotomy using a initial values, init, with a specific variable or constraint
-static double dichotomy(double init, double diff(double, void *), void *var_cnst, double min_error);
-//computes the value of the differential of constraint param_cnst applied to lambda
-static double partial_diff_lambda(double lambda, void *param_cnst);
+// computes the value of the dichotomy using a initial values, init, with a specific variable or constraint
+static double dichotomy(double init, double diff(double, void*), void* var_cnst, double min_error);
+// computes the value of the differential of constraint param_cnst applied to lambda
+static double partial_diff_lambda(double lambda, void* param_cnst);
static int __check_feasible(xbt_swag_t cnst_list, xbt_swag_t var_list, int warn)
{
void* _cnst;
void* _elem;
void* _var;
- xbt_swag_t elem_list = nullptr;
- lmm_element_t elem = nullptr;
+ xbt_swag_t elem_list = nullptr;
+ lmm_element_t elem = nullptr;
lmm_constraint_t cnst = nullptr;
- lmm_variable_t var = nullptr;
+ lmm_variable_t var = nullptr;
- xbt_swag_foreach(_cnst, cnst_list) {
+ xbt_swag_foreach(_cnst, cnst_list)
+ {
cnst = static_cast<lmm_constraint_t>(_cnst);
double tmp = 0;
- elem_list = &(cnst->enabled_element_set);
- xbt_swag_foreach(_elem, elem_list) {
+ elem_list = &(cnst->enabled_element_set);
+ xbt_swag_foreach(_elem, elem_list)
+ {
elem = static_cast<lmm_element_t>(_elem);
- var = elem->variable;
+ var = elem->variable;
xbt_assert(var->sharing_weight > 0);
tmp += var->value;
}
if (double_positive(tmp - cnst->bound, sg_maxmin_precision)) {
if (warn)
- XBT_WARN ("The link (%p) is over-used. Expected less than %f and got %f", cnst, cnst->bound, tmp);
+ XBT_WARN("The link (%p) is over-used. Expected less than %f and got %f", cnst, cnst->bound, tmp);
return 0;
}
- XBT_DEBUG ("Checking feasability for constraint (%p): sat = %f, lambda = %f ", cnst, tmp - cnst->bound,
- cnst->lambda);
+ XBT_DEBUG("Checking feasability for constraint (%p): sat = %f, lambda = %f ", cnst, tmp - cnst->bound,
+ cnst->lambda);
}
- xbt_swag_foreach(_var, var_list) {
+ xbt_swag_foreach(_var, var_list)
+ {
var = static_cast<lmm_variable_t>(_var);
if (not var->sharing_weight)
break;
if (double_positive(var->value - var->bound, sg_maxmin_precision)) {
if (warn)
- XBT_WARN ("The variable (%p) is too large. Expected less than %f and got %f", var, var->bound, var->value);
+ XBT_WARN("The variable (%p) is too large. Expected less than %f and got %f", var, var->bound, var->value);
return 0;
}
}
{
double tmp = 0;
- for (int i = 0; i < var->cnsts_number; i++) {
- tmp += (var->cnsts[i].constraint)->lambda;
+ for (s_lmm_element_t const& elem : var->cnsts) {
+ tmp += elem.constraint->lambda;
}
if (var->bound > 0)
tmp += var->mu;
XBT_DEBUG("\t Working on var (%p). cost = %e; Weight = %e", var, tmp, var->sharing_weight);
- //uses the partial differential inverse function
+ // uses the partial differential inverse function
return var->func_fpi(var, tmp);
}
static double new_mu(lmm_variable_t var)
{
- double mu_i = 0.0;
+ double mu_i = 0.0;
double sigma_i = 0.0;
- for (int j = 0; j < var->cnsts_number; j++) {
- sigma_i += (var->cnsts[j].constraint)->lambda;
+ for (s_lmm_element_t const& elem : var->cnsts) {
+ sigma_i += elem.constraint->lambda;
}
mu_i = var->func_fp(var, var->bound) - sigma_i;
if (mu_i < 0.0)
static double dual_objective(xbt_swag_t var_list, xbt_swag_t cnst_list)
{
- void *_cnst;
- void *_var;
+ void* _cnst;
+ void* _var;
lmm_constraint_t cnst = nullptr;
- lmm_variable_t var = nullptr;
+ lmm_variable_t var = nullptr;
double obj = 0.0;
- xbt_swag_foreach(_var, var_list) {
- var = static_cast<lmm_variable_t>(_var);
+ xbt_swag_foreach(_var, var_list)
+ {
+ var = static_cast<lmm_variable_t>(_var);
double sigma_i = 0.0;
if (not var->sharing_weight)
break;
- for (int j = 0; j < var->cnsts_number; j++)
- sigma_i += (var->cnsts[j].constraint)->lambda;
+ for (s_lmm_element_t const& elem : var->cnsts)
+ sigma_i += elem.constraint->lambda;
if (var->bound > 0)
sigma_i += var->mu;
obj += var->mu * var->bound;
}
- xbt_swag_foreach(_cnst, cnst_list) {
+ xbt_swag_foreach(_cnst, cnst_list)
+ {
cnst = static_cast<lmm_constraint_t>(_cnst);
obj += cnst->lambda * cnst->bound;
}
void lagrange_solve(lmm_system_t sys)
{
/* Lagrange Variables. */
- int max_iterations = 100;
- double epsilon_min_error = 0.00001; /* this is the precision on the objective function so it's none of the configurable values and this value is the legacy one */
- double dichotomy_min_error = 1e-14;
+ int max_iterations = 100;
+ double epsilon_min_error = 0.00001; /* this is the precision on the objective function so it's none of the
+ configurable values and this value is the legacy one */
+ double dichotomy_min_error = 1e-14;
double overall_modification = 1;
- /* Variables to manipulate the data structure proposed to model the maxmin fairness. See documentation for details. */
- xbt_swag_t cnst_list = nullptr;
- void *_cnst;
- lmm_constraint_t cnst = nullptr;
-
- xbt_swag_t var_list = nullptr;
- void *_var;
- lmm_variable_t var = nullptr;
-
- /* Auxiliary variables. */
- int iteration = 0;
- double tmp = 0;
- int i;
- double obj;
- double new_obj;
-
XBT_DEBUG("Iterative method configuration snapshot =====>");
XBT_DEBUG("#### Maximum number of iterations : %d", max_iterations);
XBT_DEBUG("#### Minimum error tolerated : %e", epsilon_min_error);
XBT_DEBUG("#### Minimum error tolerated (dichotomy) : %e", dichotomy_min_error);
if (XBT_LOG_ISENABLED(surf_lagrange, xbt_log_priority_debug)) {
- lmm_print(sys);
+ sys->print();
}
if (not sys->modified)
return;
/* Initialize lambda. */
- cnst_list = &(sys->active_constraint_set);
- xbt_swag_foreach(_cnst, cnst_list) {
- cnst = (lmm_constraint_t)_cnst;
- cnst->lambda = 1.0;
- cnst->new_lambda = 2.0;
+ xbt_swag_t cnst_list = &(sys->active_constraint_set);
+ void* _cnst;
+ xbt_swag_foreach(_cnst, cnst_list)
+ {
+ lmm_constraint_t cnst = (lmm_constraint_t)_cnst;
+ cnst->lambda = 1.0;
+ cnst->new_lambda = 2.0;
XBT_DEBUG("#### cnst(%p)->lambda : %e", cnst, cnst->lambda);
}
* Initialize the var list variable with only the active variables.
* Associate an index in the swag variables. Initialize mu.
*/
- var_list = &(sys->variable_set);
- i = 0;
- xbt_swag_foreach(_var, var_list) {
- var = static_cast<lmm_variable_t>(_var);
- if (not var->sharing_weight)
- var->value = 0.0;
- else {
- int nb = 0;
- if (var->bound < 0.0) {
- XBT_DEBUG("#### NOTE var(%d) is a boundless variable", i);
- var->mu = -1.0;
+ xbt_swag_t var_list = &(sys->variable_set);
+ void* _var;
+ xbt_swag_foreach(_var, var_list)
+ {
+ lmm_variable_t var = static_cast<lmm_variable_t>(_var);
+ if (not var->sharing_weight)
+ var->value = 0.0;
+ else {
+ if (var->bound < 0.0) {
+ XBT_DEBUG("#### NOTE var(%p) is a boundless variable", var);
+ var->mu = -1.0;
+ } else {
+ var->mu = 1.0;
+ var->new_mu = 2.0;
+ }
var->value = new_value(var);
- } else {
- var->mu = 1.0;
- var->new_mu = 2.0;
- var->value = new_value(var);
- }
- XBT_DEBUG("#### var(%p) ->weight : %e", var, var->sharing_weight);
- XBT_DEBUG("#### var(%p) ->mu : %e", var, var->mu);
- XBT_DEBUG("#### var(%p) ->weight: %e", var, var->sharing_weight);
- XBT_DEBUG("#### var(%p) ->bound: %e", var, var->bound);
- for (i = 0; i < var->cnsts_number; i++) {
- if (var->cnsts[i].consumption_weight == 0.0)
- nb++;
- }
- if (nb == var->cnsts_number)
- var->value = 1.0;
+ XBT_DEBUG("#### var(%p) ->weight : %e", var, var->sharing_weight);
+ XBT_DEBUG("#### var(%p) ->mu : %e", var, var->mu);
+ XBT_DEBUG("#### var(%p) ->weight: %e", var, var->sharing_weight);
+ XBT_DEBUG("#### var(%p) ->bound: %e", var, var->bound);
+ auto weighted = std::find_if(begin(var->cnsts), end(var->cnsts),
+ [](s_lmm_element_t const& x) { return x.consumption_weight != 0.0; });
+ if (weighted == end(var->cnsts))
+ var->value = 1.0;
}
}
/* Compute dual objective. */
- obj = dual_objective(var_list, cnst_list);
+ double obj = dual_objective(var_list, cnst_list);
/* While doesn't reach a minimum error or a number maximum of iterations. */
+ int iteration = 0;
while (overall_modification > epsilon_min_error && iteration < max_iterations) {
iteration++;
XBT_DEBUG("************** ITERATION %d **************", iteration);
XBT_DEBUG("-------------- Gradient Descent ----------");
/* Improve the value of mu_i */
- xbt_swag_foreach(_var, var_list) {
- var = static_cast<lmm_variable_t>(_var);
- if (not var->sharing_weight)
- break;
- if (var->bound >= 0) {
+ xbt_swag_foreach(_var, var_list)
+ {
+ lmm_variable_t var = static_cast<lmm_variable_t>(_var);
+ if (var->sharing_weight && var->bound >= 0) {
XBT_DEBUG("Working on var (%p)", var);
var->new_mu = new_mu(var);
XBT_DEBUG("Updating mu : var->mu (%p) : %1.20f -> %1.20f", var, var->mu, var->new_mu);
var->mu = var->new_mu;
- new_obj = dual_objective(var_list, cnst_list);
+ double new_obj = dual_objective(var_list, cnst_list);
XBT_DEBUG("Improvement for Objective (%g -> %g) : %g", obj, new_obj, obj - new_obj);
xbt_assert(obj - new_obj >= -epsilon_min_error, "Our gradient sucks! (%1.20f)", obj - new_obj);
obj = new_obj;
}
/* Improve the value of lambda_i */
- xbt_swag_foreach(_cnst, cnst_list) {
- cnst = static_cast<lmm_constraint_t>(_cnst);
+ xbt_swag_foreach(_cnst, cnst_list)
+ {
+ lmm_constraint_t cnst = static_cast<lmm_constraint_t>(_cnst);
XBT_DEBUG("Working on cnst (%p)", cnst);
cnst->new_lambda = dichotomy(cnst->lambda, partial_diff_lambda, cnst, dichotomy_min_error);
XBT_DEBUG("Updating lambda : cnst->lambda (%p) : %1.20f -> %1.20f", cnst, cnst->lambda, cnst->new_lambda);
cnst->lambda = cnst->new_lambda;
- new_obj = dual_objective(var_list, cnst_list);
+ double new_obj = dual_objective(var_list, cnst_list);
XBT_DEBUG("Improvement for Objective (%g -> %g) : %g", obj, new_obj, obj - new_obj);
xbt_assert(obj - new_obj >= -epsilon_min_error, "Our gradient sucks! (%1.20f)", obj - new_obj);
obj = new_obj;
/* Now computes the values of each variable (\rho) based on the values of \lambda and \mu. */
XBT_DEBUG("-------------- Check convergence ----------");
overall_modification = 0;
- xbt_swag_foreach(_var, var_list) {
- var = static_cast<lmm_variable_t>(_var);
+ xbt_swag_foreach(_var, var_list)
+ {
+ lmm_variable_t var = static_cast<lmm_variable_t>(_var);
if (var->sharing_weight <= 0)
var->value = 0.0;
else {
- tmp = new_value(var);
+ double tmp = new_value(var);
- overall_modification = MAX(overall_modification, fabs(var->value - tmp));
+ overall_modification = std::max(overall_modification, fabs(var->value - tmp));
var->value = tmp;
XBT_DEBUG("New value of var (%p) = %e, overall_modification = %e", var, var->value, overall_modification);
XBT_DEBUG("The method converges in %d iterations.", iteration);
}
if (iteration >= max_iterations) {
- XBT_DEBUG ("Method reach %d iterations, which is the maximum number of iterations allowed.", iteration);
+ XBT_DEBUG("Method reach %d iterations, which is the maximum number of iterations allowed.", iteration);
}
if (XBT_LOG_ISENABLED(surf_lagrange, xbt_log_priority_debug)) {
- lmm_print(sys);
+ sys->print();
}
}
*
* @return a double corresponding to the result of the dichotomy process
*/
-static double dichotomy(double init, double diff(double, void *), void *var_cnst, double min_error)
+static double dichotomy(double init, double diff(double, void*), void* var_cnst, double min_error)
{
- double min =init;
- double max= init;
+ double min = init;
+ double max = init;
double overall_error;
double middle;
double middle_diff;
double max_diff = diff(max, var_cnst);
while (overall_error > min_error) {
- XBT_CDEBUG(surf_lagrange_dichotomy, "[min, max] = [%1.20f, %1.20f] || diffmin, diffmax = %1.20f, %1.20f",
- min, max, min_diff, max_diff);
+ XBT_CDEBUG(surf_lagrange_dichotomy, "[min, max] = [%1.20f, %1.20f] || diffmin, diffmax = %1.20f, %1.20f", min, max,
+ min_diff, max_diff);
if (min_diff > 0 && max_diff > 0) {
if (min == max) {
XBT_CDEBUG(surf_lagrange_dichotomy, "Decreasing min");
- min = min / 2.0;
+ min = min / 2.0;
min_diff = diff(min, var_cnst);
} else {
XBT_CDEBUG(surf_lagrange_dichotomy, "Decreasing max");
- max = min;
+ max = min;
max_diff = min_diff;
}
} else if (min_diff < 0 && max_diff < 0) {
if (min == max) {
XBT_CDEBUG(surf_lagrange_dichotomy, "Increasing max");
- max = max * 2.0;
+ max = max * 2.0;
max_diff = diff(max, var_cnst);
} else {
XBT_CDEBUG(surf_lagrange_dichotomy, "Increasing min");
- min = max;
+ min = max;
min_diff = max_diff;
}
} else if (min_diff < 0 && max_diff > 0) {
middle = (max + min) / 2.0;
XBT_CDEBUG(surf_lagrange_dichotomy, "Trying (max+min)/2 : %1.20f", middle);
- if ((fabs(min - middle) < 1e-20) || (fabs(max - middle) < 1e-20)){
- XBT_CWARN(surf_lagrange_dichotomy, "Cannot improve the convergence! min=max=middle=%1.20f, diff = %1.20f."
+ if ((fabs(min - middle) < 1e-20) || (fabs(max - middle) < 1e-20)) {
+ XBT_CWARN(surf_lagrange_dichotomy,
+ "Cannot improve the convergence! min=max=middle=%1.20f, diff = %1.20f."
" Reaching the 'double' limits. Maybe scaling your function would help ([%1.20f,%1.20f]).",
min, max - min, min_diff, max_diff);
break;
if (middle_diff < 0) {
XBT_CDEBUG(surf_lagrange_dichotomy, "Increasing min");
- min = middle;
+ min = middle;
overall_error = max_diff - middle_diff;
- min_diff = middle_diff;
+ min_diff = middle_diff;
} else if (middle_diff > 0) {
XBT_CDEBUG(surf_lagrange_dichotomy, "Decreasing max");
- max = middle;
+ max = middle;
overall_error = max_diff - middle_diff;
- max_diff = middle_diff;
+ max_diff = middle_diff;
} else {
overall_error = 0;
}
} else if (fabs(min_diff) < 1e-20) {
- max = min;
+ max = min;
overall_error = 0;
} else if (fabs(max_diff) < 1e-20) {
- min = max;
+ min = max;
overall_error = 0;
} else if (min_diff > 0 && max_diff < 0) {
XBT_CWARN(surf_lagrange_dichotomy, "The impossible happened, partial_diff(min) > 0 && partial_diff(max) < 0");
xbt_abort();
} else {
XBT_CWARN(surf_lagrange_dichotomy,
- "diffmin (%1.20f) or diffmax (%1.20f) are something I don't know, taking no action.",
- min_diff, max_diff);
+ "diffmin (%1.20f) or diffmax (%1.20f) are something I don't know, taking no action.", min_diff,
+ max_diff);
xbt_abort();
}
}
return ((min + max) / 2.0);
}
-static double partial_diff_lambda(double lambda, void *param_cnst)
+static double partial_diff_lambda(double lambda, void* param_cnst)
{
lmm_constraint_t cnst = static_cast<lmm_constraint_t>(param_cnst);
- double diff = 0.0;
+ double diff = 0.0;
XBT_IN();
xbt_swag_t elem_list = &(cnst->enabled_element_set);
void* _elem;
- xbt_swag_foreach(_elem, elem_list) {
+ xbt_swag_foreach(_elem, elem_list)
+ {
lmm_element_t elem = static_cast<lmm_element_t>(_elem);
lmm_variable_t var = elem->variable;
xbt_assert(var->sharing_weight > 0);
double sigma_i = 0.0;
// Compute sigma_i
- for (int j = 0; j < var->cnsts_number; j++) {
- sigma_i += (var->cnsts[j].constraint)->lambda;
+ for (s_lmm_element_t const& elem : var->cnsts) {
+ sigma_i += elem.constraint->lambda;
}
- //add mu_i if this flow has a RTT constraint associated
+ // add mu_i if this flow has a RTT constraint associated
if (var->bound > 0)
sigma_i += var->mu;
- //replace value of cnst->lambda by the value of parameter lambda
+ // replace value of cnst->lambda by the value of parameter lambda
sigma_i = (sigma_i - cnst->lambda) + lambda;
diff += -var->func_fpi(var, sigma_i);
* programming.
*
*/
-void lmm_set_default_protocol_function(double (*func_f) (lmm_variable_t var, double x),
- double (*func_fp) (lmm_variable_t var, double x),
- double (*func_fpi) (lmm_variable_t var, double x))
+void lmm_set_default_protocol_function(double (*func_f)(lmm_variable_t var, double x),
+ double (*func_fp)(lmm_variable_t var, double x),
+ double (*func_fpi)(lmm_variable_t var, double x))
{
- func_f_def = func_f;
- func_fp_def = func_fp;
+ func_f_def = func_f;
+ func_fp_def = func_fp;
func_fpi_def = func_fpi;
}
* Therefore: $fp(x) = \frac{\alpha D_f}{x}$
* Therefore: $fpi(x) = \frac{\alpha D_f}{x}$
*/
-#define VEGAS_SCALING 1000.0
-
double func_vegas_f(lmm_variable_t var, double x)
{
xbt_assert(x > 0.0, "Don't call me with stupid values! (%1.20f)", x);
* Therefore: $fp(x) = \frac{3}{3 D_f^2 x^2+2}$
* Therefore: $fpi(x) = \sqrt{\frac{1}{{D_f}^2 x} - \frac{2}{3{D_f}^2}}$
*/
-#define RENO_SCALING 1.0
double func_reno_f(lmm_variable_t var, double x)
{
xbt_assert(var->sharing_weight > 0.0, "Don't call me with stupid values!");
* Therefore: $fp(x) = 2/(Weight*x + 2)
* Therefore: $fpi(x) = (2*Weight)/x - 4
*/
-#define RENO2_SCALING 1.0
double func_reno2_f(lmm_variable_t var, double x)
{
xbt_assert(var->sharing_weight > 0.0, "Don't call me with stupid values!");
res_fpi = RENO2_SCALING * (-3.0 * tmp + sqrt(res_fpi)) / (4.0 * tmp);
return res_fpi;
}
+}
+}
--- /dev/null
+/* Copyright (c) 2004-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. */
+
+/* \file callbacks.h */
+
+#include "surf/maxmin.hpp"
+#include "xbt/backtrace.hpp"
+#include "xbt/log.h"
+#include "xbt/mallocator.h"
+#include "xbt/sysdep.h"
+#include <algorithm>
+#include <cmath>
+#include <cstdlib>
+#include <cxxabi.h>
+#include <limits>
+#include <vector>
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_maxmin, surf, "Logging specific to SURF (maxmin)");
+
+double sg_maxmin_precision = 0.00001; /* Change this with --cfg=maxmin/precision:VALUE */
+double sg_surf_precision = 0.00001; /* Change this with --cfg=surf/precision:VALUE */
+int sg_concurrency_limit = -1; /* Change this with --cfg=maxmin/concurrency-limit:VALUE */
+
+namespace simgrid {
+namespace surf {
+
+typedef std::vector<int> dyn_light_t;
+
+int s_lmm_variable_t::Global_debug_id = 1;
+int s_lmm_constraint_t::Global_debug_id = 1;
+
+int s_lmm_element_t::get_concurrency() const
+{
+ // Ignore element with weight less than one (e.g. cross-traffic)
+ return (consumption_weight >= 1) ? 1 : 0;
+ // There are other alternatives, but they will change the behaviour of the model..
+ // So do not use it unless you want to make a new model.
+ // If you do, remember to change the variables concurrency share to reflect it.
+ // Potential examples are:
+ // return (elem->weight>0)?1:0;//Include element as soon as weight is non-zero
+ // return (int)ceil(elem->weight);//Include element as the rounded-up integer value of the element weight
+}
+
+void s_lmm_element_t::decrease_concurrency()
+{
+ xbt_assert(constraint->concurrency_current >= get_concurrency());
+ constraint->concurrency_current -= get_concurrency();
+}
+
+void s_lmm_element_t::increase_concurrency()
+{
+ constraint->concurrency_current += get_concurrency();
+
+ if (constraint->concurrency_current > constraint->concurrency_maximum)
+ constraint->concurrency_maximum = constraint->concurrency_current;
+
+ xbt_assert(constraint->get_concurrency_limit() < 0 ||
+ constraint->concurrency_current <= constraint->get_concurrency_limit(),
+ "Concurrency limit overflow!");
+}
+
+void s_lmm_system_t::check_concurrency()
+{
+ // These checks are very expensive, so do them only if we want to debug SURF LMM
+ if (not XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug))
+ return;
+
+ void* cnstIt;
+ xbt_swag_foreach(cnstIt, &constraint_set)
+ {
+ lmm_constraint_t cnst = (lmm_constraint_t)cnstIt;
+ int concurrency = 0;
+ void* elemIt;
+ xbt_swag_foreach(elemIt, &(cnst->enabled_element_set))
+ {
+ lmm_element_t elem = (lmm_element_t)elemIt;
+ xbt_assert(elem->variable->sharing_weight > 0);
+ concurrency += elem->get_concurrency();
+ }
+
+ xbt_swag_foreach(elemIt, &(cnst->disabled_element_set))
+ {
+ lmm_element_t elem = (lmm_element_t)elemIt;
+ // We should have staged variables only if concurrency is reached in some constraint
+ xbt_assert(cnst->get_concurrency_limit() < 0 || elem->variable->staged_weight == 0 ||
+ elem->variable->get_min_concurrency_slack() < elem->variable->concurrency_share,
+ "should not have staged variable!");
+ }
+
+ xbt_assert(cnst->get_concurrency_limit() < 0 || cnst->get_concurrency_limit() >= concurrency,
+ "concurrency check failed!");
+ xbt_assert(cnst->concurrency_current == concurrency, "concurrency_current is out-of-date!");
+ }
+
+ // Check that for each variable, all corresponding elements are in the same state (i.e. same element sets)
+ void* varIt;
+ xbt_swag_foreach(varIt, &variable_set)
+ {
+ lmm_variable_t var = (lmm_variable_t)varIt;
+
+ if (var->cnsts.empty())
+ continue;
+
+ lmm_element_t elem = &var->cnsts[0];
+ int belong_to_enabled = xbt_swag_belongs(elem, &(elem->constraint->enabled_element_set));
+ int belong_to_disabled = xbt_swag_belongs(elem, &(elem->constraint->disabled_element_set));
+ int belong_to_active = xbt_swag_belongs(elem, &(elem->constraint->active_element_set));
+
+ for (s_lmm_element_t const& elem : var->cnsts) {
+ xbt_assert(belong_to_enabled == xbt_swag_belongs(&elem, &(elem.constraint->enabled_element_set)),
+ "Variable inconsistency (1): enabled_element_set");
+ xbt_assert(belong_to_disabled == xbt_swag_belongs(&elem, &(elem.constraint->disabled_element_set)),
+ "Variable inconsistency (2): disabled_element_set");
+ xbt_assert(belong_to_active == xbt_swag_belongs(&elem, &(elem.constraint->active_element_set)),
+ "Variable inconsistency (3): active_element_set");
+ }
+ }
+}
+
+void s_lmm_system_t::var_free(lmm_variable_t var)
+{
+ XBT_IN("(sys=%p, var=%p)", this, var);
+ modified = true;
+
+ // TODOLATER Can do better than that by leaving only the variable in only one enabled_element_set, call
+ // update_modified_set, and then remove it..
+ if (not var->cnsts.empty())
+ update_modified_set(var->cnsts[0].constraint);
+
+ for (s_lmm_element_t& elem : var->cnsts) {
+ if (var->sharing_weight > 0)
+ elem.decrease_concurrency();
+ xbt_swag_remove(&elem, &(elem.constraint->enabled_element_set));
+ xbt_swag_remove(&elem, &(elem.constraint->disabled_element_set));
+ xbt_swag_remove(&elem, &(elem.constraint->active_element_set));
+ int nelements = xbt_swag_size(&(elem.constraint->enabled_element_set)) +
+ xbt_swag_size(&(elem.constraint->disabled_element_set));
+ if (nelements == 0)
+ make_constraint_inactive(elem.constraint);
+ else
+ on_disabled_var(elem.constraint);
+ }
+
+ var->cnsts.clear();
+
+ check_concurrency();
+
+ xbt_mallocator_release(variable_mallocator, var);
+ XBT_OUT();
+}
+
+s_lmm_system_t::s_lmm_system_t(bool selective_update) : selective_update_active(selective_update)
+{
+ s_lmm_variable_t var;
+ s_lmm_constraint_t cnst;
+
+ modified = false;
+ visited_counter = 1;
+
+ XBT_DEBUG("Setting selective_update_active flag to %d", selective_update_active);
+
+ xbt_swag_init(&variable_set, xbt_swag_offset(var, variable_set_hookup));
+ xbt_swag_init(&constraint_set, xbt_swag_offset(cnst, constraint_set_hookup));
+
+ xbt_swag_init(&active_constraint_set, xbt_swag_offset(cnst, active_constraint_set_hookup));
+
+ xbt_swag_init(&modified_constraint_set, xbt_swag_offset(cnst, modified_constraint_set_hookup));
+ xbt_swag_init(&saturated_variable_set, xbt_swag_offset(var, saturated_variable_set_hookup));
+ xbt_swag_init(&saturated_constraint_set, xbt_swag_offset(cnst, saturated_constraint_set_hookup));
+
+ keep_track = nullptr;
+ variable_mallocator = xbt_mallocator_new(65536, s_lmm_system_t::variable_mallocator_new_f,
+ s_lmm_system_t::variable_mallocator_free_f, nullptr);
+ solve_fun = &lmm_solve;
+}
+
+s_lmm_system_t::~s_lmm_system_t()
+{
+ lmm_variable_t var;
+ lmm_constraint_t cnst;
+
+ while ((var = extract_variable())) {
+ auto demangled = simgrid::xbt::demangle(typeid(*var->id).name());
+ XBT_WARN("Probable bug: a %s variable (#%d) not removed before the LMM system destruction.", demangled.get(),
+ var->id_int);
+ var_free(var);
+ }
+ while ((cnst = extract_constraint()))
+ cnst_free(cnst);
+
+ xbt_mallocator_free(variable_mallocator);
+}
+
+void s_lmm_system_t::cnst_free(lmm_constraint_t cnst)
+{
+ make_constraint_inactive(cnst);
+ delete cnst;
+}
+
+s_lmm_constraint_t::s_lmm_constraint_t(void* id_value, double bound_value) : bound(bound_value), id(id_value)
+{
+ s_lmm_element_t elem;
+
+ id_int = Global_debug_id++;
+ xbt_swag_init(&enabled_element_set, xbt_swag_offset(elem, enabled_element_set_hookup));
+ xbt_swag_init(&disabled_element_set, xbt_swag_offset(elem, disabled_element_set_hookup));
+ xbt_swag_init(&active_element_set, xbt_swag_offset(elem, active_element_set_hookup));
+
+ remaining = 0.0;
+ usage = 0.0;
+ concurrency_limit = sg_concurrency_limit;
+ concurrency_current = 0;
+ concurrency_maximum = 0;
+ sharing_policy = 1; /* FIXME: don't hardcode the value */
+
+ lambda = 0.0;
+ new_lambda = 0.0;
+ cnst_light = nullptr;
+}
+
+lmm_constraint_t s_lmm_system_t::constraint_new(void* id, double bound_value)
+{
+ lmm_constraint_t cnst = new s_lmm_constraint_t(id, bound_value);
+ insert_constraint(cnst);
+ return cnst;
+}
+
+void* s_lmm_system_t::variable_mallocator_new_f()
+{
+ return new s_lmm_variable_t;
+}
+
+void s_lmm_system_t::variable_mallocator_free_f(void* var)
+{
+ delete static_cast<lmm_variable_t>(var);
+}
+
+lmm_variable_t s_lmm_system_t::variable_new(simgrid::surf::Action* id, double sharing_weight, double bound,
+ int number_of_constraints)
+{
+ XBT_IN("(sys=%p, id=%p, weight=%f, bound=%f, num_cons =%d)", this, id, sharing_weight, bound, number_of_constraints);
+
+ lmm_variable_t var = static_cast<lmm_variable_t>(xbt_mallocator_get(variable_mallocator));
+ var->initialize(id, sharing_weight, bound, number_of_constraints, visited_counter - 1);
+ if (sharing_weight)
+ xbt_swag_insert_at_head(var, &variable_set);
+ else
+ xbt_swag_insert_at_tail(var, &variable_set);
+
+ XBT_OUT(" returns %p", var);
+ return var;
+}
+
+void s_lmm_system_t::variable_free(lmm_variable_t var)
+{
+ remove_variable(var);
+ var_free(var);
+}
+
+void s_lmm_system_t::expand(lmm_constraint_t cnst, lmm_variable_t var, double consumption_weight)
+{
+ modified = true;
+
+ // Check if this variable already has an active element in this constraint
+ // If it does, substract it from the required slack
+ int current_share = 0;
+ if (var->concurrency_share > 1) {
+ for (s_lmm_element_t& elem : var->cnsts) {
+ if (elem.constraint == cnst && xbt_swag_belongs(&elem, &(elem.constraint->enabled_element_set)))
+ current_share += elem.get_concurrency();
+ }
+ }
+
+ // Check if we need to disable the variable
+ if (var->sharing_weight > 0 && var->concurrency_share - current_share > cnst->get_concurrency_slack()) {
+ double weight = var->sharing_weight;
+ disable_var(var);
+ for (s_lmm_element_t const& elem : var->cnsts)
+ on_disabled_var(elem.constraint);
+ consumption_weight = 0;
+ var->staged_weight = weight;
+ xbt_assert(not var->sharing_weight);
+ }
+
+ xbt_assert(var->cnsts.size() < var->cnsts.capacity(), "Too much constraints");
+
+ var->cnsts.resize(var->cnsts.size() + 1);
+ s_lmm_element_t& elem = var->cnsts.back();
+
+ elem.consumption_weight = consumption_weight;
+ elem.constraint = cnst;
+ elem.variable = var;
+
+ if (var->sharing_weight) {
+ xbt_swag_insert_at_head(&elem, &(elem.constraint->enabled_element_set));
+ elem.increase_concurrency();
+ } else
+ xbt_swag_insert_at_tail(&elem, &(elem.constraint->disabled_element_set));
+
+ if (not selective_update_active) {
+ make_constraint_active(cnst);
+ } else if (elem.consumption_weight > 0 || var->sharing_weight > 0) {
+ make_constraint_active(cnst);
+ update_modified_set(cnst);
+ // TODOLATER: Why do we need this second call?
+ if (var->cnsts.size() > 1)
+ update_modified_set(var->cnsts[0].constraint);
+ }
+
+ check_concurrency();
+}
+
+void s_lmm_system_t::expand_add(lmm_constraint_t cnst, lmm_variable_t var, double value)
+{
+ modified = true;
+
+ check_concurrency();
+
+ // BEWARE: In case you have multiple elements in one constraint, this will always add value to the first element.
+ auto elem_it = std::find_if(begin(var->cnsts), end(var->cnsts),
+ [&cnst](s_lmm_element_t const& x) { return x.constraint == cnst; });
+ if (elem_it != end(var->cnsts)) {
+ s_lmm_element_t& elem = *elem_it;
+ if (var->sharing_weight)
+ elem.decrease_concurrency();
+
+ if (cnst->sharing_policy)
+ elem.consumption_weight += value;
+ else
+ elem.consumption_weight = std::max(elem.consumption_weight, value);
+
+ // We need to check that increasing value of the element does not cross the concurrency limit
+ if (var->sharing_weight) {
+ if (cnst->get_concurrency_slack() < elem.get_concurrency()) {
+ double weight = var->sharing_weight;
+ disable_var(var);
+ for (s_lmm_element_t const& elem2 : var->cnsts)
+ on_disabled_var(elem2.constraint);
+ var->staged_weight = weight;
+ xbt_assert(not var->sharing_weight);
+ }
+ elem.increase_concurrency();
+ }
+ update_modified_set(cnst);
+ } else
+ expand(cnst, var, value);
+
+ check_concurrency();
+}
+
+lmm_variable_t s_lmm_constraint_t::get_variable(lmm_element_t* elem) const
+{
+ if (*elem == nullptr) {
+ // That is the first call, pick the first element among enabled_element_set (or disabled_element_set if
+ // enabled_element_set is empty)
+ *elem = (lmm_element_t)xbt_swag_getFirst(&enabled_element_set);
+ if (*elem == nullptr)
+ *elem = (lmm_element_t)xbt_swag_getFirst(&disabled_element_set);
+ } else {
+ // elem is not null, so we carry on
+ if (xbt_swag_belongs(*elem, &enabled_element_set)) {
+ // Look at enabled_element_set, and jump to disabled_element_set when finished
+ *elem = (lmm_element_t)xbt_swag_getNext(*elem, enabled_element_set.offset);
+ if (*elem == nullptr)
+ *elem = (lmm_element_t)xbt_swag_getFirst(&disabled_element_set);
+ } else {
+ *elem = (lmm_element_t)xbt_swag_getNext(*elem, disabled_element_set.offset);
+ }
+ }
+ if (*elem)
+ return (*elem)->variable;
+ else
+ return nullptr;
+}
+
+// if we modify the swag between calls, normal version may loop forever
+// this safe version ensures that we browse the swag elements only once
+lmm_variable_t s_lmm_constraint_t::get_variable_safe(lmm_element_t* elem, lmm_element_t* nextelem, int* numelem) const
+{
+ if (*elem == nullptr) {
+ *elem = (lmm_element_t)xbt_swag_getFirst(&enabled_element_set);
+ *numelem = xbt_swag_size(&enabled_element_set) + xbt_swag_size(&disabled_element_set) - 1;
+ if (*elem == nullptr)
+ *elem = (lmm_element_t)xbt_swag_getFirst(&disabled_element_set);
+ } else {
+ *elem = *nextelem;
+ if (*numelem > 0) {
+ (*numelem)--;
+ } else
+ return nullptr;
+ }
+ if (*elem) {
+ // elem is not null, so we carry on
+ if (xbt_swag_belongs(*elem, &enabled_element_set)) {
+ // Look at enabled_element_set, and jump to disabled_element_set when finished
+ *nextelem = (lmm_element_t)xbt_swag_getNext(*elem, enabled_element_set.offset);
+ if (*nextelem == nullptr)
+ *nextelem = (lmm_element_t)xbt_swag_getFirst(&disabled_element_set);
+ } else {
+ *nextelem = (lmm_element_t)xbt_swag_getNext(*elem, disabled_element_set.offset);
+ }
+ return (*elem)->variable;
+ } else
+ return nullptr;
+}
+
+static inline void saturated_constraints_update(double usage, int cnst_light_num, dyn_light_t& saturated_constraints,
+ double* min_usage)
+{
+ xbt_assert(usage > 0, "Impossible");
+
+ if (*min_usage < 0 || *min_usage > usage) {
+ *min_usage = usage;
+ XBT_HERE(" min_usage=%f (cnst->remaining / cnst->usage =%f)", *min_usage, usage);
+ saturated_constraints.assign(1, cnst_light_num);
+ } else if (*min_usage == usage) {
+ saturated_constraints.emplace_back(cnst_light_num);
+ }
+}
+
+static inline void saturated_variable_set_update(s_lmm_constraint_light_t* cnst_light_tab,
+ const dyn_light_t& saturated_constraints, lmm_system_t sys)
+{
+ /* Add active variables (i.e. variables that need to be set) from the set of constraints to saturate
+ * (cnst_light_tab)*/
+ for (int const& saturated_cnst : saturated_constraints) {
+ lmm_constraint_light_t cnst = &cnst_light_tab[saturated_cnst];
+ void* _elem;
+ xbt_swag_t elem_list = &(cnst->cnst->active_element_set);
+ xbt_swag_foreach(_elem, elem_list)
+ {
+ lmm_element_t elem = (lmm_element_t)_elem;
+ // Visiting active_element_set, so, by construction, should never get a zero weight, correct?
+ xbt_assert(elem->variable->sharing_weight > 0);
+ if (elem->consumption_weight > 0)
+ xbt_swag_insert(elem->variable, &(sys->saturated_variable_set));
+ }
+ }
+}
+
+void s_lmm_system_t::print()
+{
+ std::string buf = std::string("MAX-MIN ( ");
+ void* _var;
+
+ /* Printing Objective */
+ xbt_swag_t var_list = &variable_set;
+ xbt_swag_foreach(_var, var_list)
+ {
+ lmm_variable_t var = (lmm_variable_t)_var;
+ buf = buf + "'" + std::to_string(var->id_int) + "'(" + std::to_string(var->sharing_weight) + ") ";
+ }
+ buf += ")";
+ XBT_DEBUG("%20s", buf.c_str());
+ buf.clear();
+
+ XBT_DEBUG("Constraints");
+ /* Printing Constraints */
+ void* _cnst;
+ xbt_swag_t cnst_list = &active_constraint_set;
+ xbt_swag_foreach(_cnst, cnst_list)
+ {
+ lmm_constraint_t cnst = (lmm_constraint_t)_cnst;
+ double sum = 0.0;
+ // Show the enabled variables
+ void* _elem;
+ xbt_swag_t elem_list = &(cnst->enabled_element_set);
+ buf += "\t";
+ buf += ((cnst->sharing_policy) ? "(" : "max(");
+ xbt_swag_foreach(_elem, elem_list)
+ {
+ lmm_element_t elem = (lmm_element_t)_elem;
+ buf = buf + std::to_string(elem->consumption_weight) + ".'" + std::to_string(elem->variable->id_int) + "'(" +
+ std::to_string(elem->variable->value) + ")" + ((cnst->sharing_policy) ? " + " : " , ");
+ if (cnst->sharing_policy)
+ sum += elem->consumption_weight * elem->variable->value;
+ else
+ sum = std::max(sum, elem->consumption_weight * elem->variable->value);
+ }
+ // TODO: Adding disabled elements only for test compatibility, but do we really want them to be printed?
+ elem_list = &(cnst->disabled_element_set);
+ xbt_swag_foreach(_elem, elem_list)
+ {
+ lmm_element_t elem = (lmm_element_t)_elem;
+ buf = buf + std::to_string(elem->consumption_weight) + ".'" + std::to_string(elem->variable->id_int) + "'(" +
+ std::to_string(elem->variable->value) + ")" + ((cnst->sharing_policy) ? " + " : " , ");
+ if (cnst->sharing_policy)
+ sum += elem->consumption_weight * elem->variable->value;
+ else
+ sum = std::max(sum, elem->consumption_weight * elem->variable->value);
+ }
+
+ buf = buf + "0) <= " + std::to_string(cnst->bound) + " ('" + std::to_string(cnst->id_int) + "')";
+
+ if (not cnst->sharing_policy) {
+ buf += " [MAX-Constraint]";
+ }
+ XBT_DEBUG("%s", buf.c_str());
+ buf.clear();
+ xbt_assert(not double_positive(sum - cnst->bound, cnst->bound * sg_maxmin_precision),
+ "Incorrect value (%f is not smaller than %f): %g", sum, cnst->bound, sum - cnst->bound);
+ }
+
+ XBT_DEBUG("Variables");
+ /* Printing Result */
+ xbt_swag_foreach(_var, var_list)
+ {
+ lmm_variable_t var = (lmm_variable_t)_var;
+ if (var->bound > 0) {
+ XBT_DEBUG("'%d'(%f) : %f (<=%f)", var->id_int, var->sharing_weight, var->value, var->bound);
+ xbt_assert(not double_positive(var->value - var->bound, var->bound * sg_maxmin_precision),
+ "Incorrect value (%f is not smaller than %f", var->value, var->bound);
+ } else {
+ XBT_DEBUG("'%d'(%f) : %f", var->id_int, var->sharing_weight, var->value);
+ }
+ }
+}
+
+void s_lmm_system_t::solve()
+{
+ void* _cnst;
+ void* _cnst_next;
+ void* _elem;
+ double min_usage = -1;
+ double min_bound = -1;
+
+ if (not modified)
+ return;
+
+ XBT_IN("(sys=%p)", this);
+
+ /* Compute Usage and store the variables that reach the maximum. If selective_update_active is true, only constraints
+ * that changed are considered. Otherwise all constraints with active actions are considered.
+ */
+ xbt_swag_t cnst_list = selective_update_active ? &modified_constraint_set : &active_constraint_set;
+
+ XBT_DEBUG("Active constraints : %d", xbt_swag_size(cnst_list));
+ /* Init: Only modified code portions: reset the value of active variables */
+ xbt_swag_foreach(_cnst, cnst_list)
+ {
+ lmm_constraint_t cnst = (lmm_constraint_t)_cnst;
+ xbt_swag_t elem_list = &(cnst->enabled_element_set);
+ xbt_swag_foreach(_elem, elem_list)
+ {
+ lmm_variable_t var = ((lmm_element_t)_elem)->variable;
+ xbt_assert(var->sharing_weight > 0.0);
+ var->value = 0.0;
+ }
+ }
+
+ s_lmm_constraint_light_t* cnst_light_tab = new s_lmm_constraint_light_t[xbt_swag_size(cnst_list)]();
+ int cnst_light_num = 0;
+ dyn_light_t saturated_constraints;
+
+ xbt_swag_foreach_safe(_cnst, _cnst_next, cnst_list)
+ {
+ lmm_constraint_t cnst = (lmm_constraint_t)_cnst;
+ /* INIT: Collect constraints that actually need to be saturated (i.e remaining and usage are strictly positive)
+ * into cnst_light_tab. */
+ cnst->remaining = cnst->bound;
+ if (not double_positive(cnst->remaining, cnst->bound * sg_maxmin_precision))
+ continue;
+ cnst->usage = 0;
+ xbt_swag_t elem_list = &(cnst->enabled_element_set);
+ xbt_swag_foreach(_elem, elem_list)
+ {
+ lmm_element_t elem = (lmm_element_t)_elem;
+ xbt_assert(elem->variable->sharing_weight > 0);
+ if (elem->consumption_weight > 0) {
+ if (cnst->sharing_policy)
+ cnst->usage += elem->consumption_weight / elem->variable->sharing_weight;
+ else if (cnst->usage < elem->consumption_weight / elem->variable->sharing_weight)
+ cnst->usage = elem->consumption_weight / elem->variable->sharing_weight;
+
+ elem->make_active();
+ simgrid::surf::Action* action = static_cast<simgrid::surf::Action*>(elem->variable->id);
+ if (keep_track && not action->is_linked())
+ keep_track->push_back(*action);
+ }
+ }
+ XBT_DEBUG("Constraint '%d' usage: %f remaining: %f concurrency: %i<=%i<=%i", cnst->id_int, cnst->usage,
+ cnst->remaining, cnst->concurrency_current, cnst->concurrency_maximum, cnst->get_concurrency_limit());
+ /* Saturated constraints update */
+
+ if (cnst->usage > 0) {
+ cnst_light_tab[cnst_light_num].cnst = cnst;
+ cnst->cnst_light = &(cnst_light_tab[cnst_light_num]);
+ cnst_light_tab[cnst_light_num].remaining_over_usage = cnst->remaining / cnst->usage;
+ saturated_constraints_update(cnst_light_tab[cnst_light_num].remaining_over_usage, cnst_light_num,
+ saturated_constraints, &min_usage);
+ xbt_assert(cnst->active_element_set.count > 0,
+ "There is no sense adding a constraint that has no active element!");
+ cnst_light_num++;
+ }
+ }
+
+ saturated_variable_set_update(cnst_light_tab, saturated_constraints, this);
+
+ /* Saturated variables update */
+ do {
+ /* Fix the variables that have to be */
+ xbt_swag_t var_list = &saturated_variable_set;
+ void* _var;
+ lmm_variable_t var = nullptr;
+ xbt_swag_foreach(_var, var_list)
+ {
+ var = (lmm_variable_t)_var;
+ if (var->sharing_weight <= 0.0)
+ DIE_IMPOSSIBLE;
+ /* First check if some of these variables could reach their upper bound and update min_bound accordingly. */
+ XBT_DEBUG("var=%d, var->bound=%f, var->weight=%f, min_usage=%f, var->bound*var->weight=%f", var->id_int,
+ var->bound, var->sharing_weight, min_usage, var->bound * var->sharing_weight);
+ if ((var->bound > 0) && (var->bound * var->sharing_weight < min_usage)) {
+ if (min_bound < 0)
+ min_bound = var->bound * var->sharing_weight;
+ else
+ min_bound = std::min(min_bound, (var->bound * var->sharing_weight));
+ XBT_DEBUG("Updated min_bound=%f", min_bound);
+ }
+ }
+
+ while ((var = (lmm_variable_t)xbt_swag_getFirst(var_list))) {
+ if (min_bound < 0) {
+ // If no variable could reach its bound, deal iteratively the constraints usage ( at worst one constraint is
+ // saturated at each cycle)
+ var->value = min_usage / var->sharing_weight;
+ XBT_DEBUG("Setting var (%d) value to %f\n", var->id_int, var->value);
+ } else {
+ // If there exist a variable that can reach its bound, only update it (and other with the same bound) for now.
+ if (double_equals(min_bound, var->bound * var->sharing_weight, sg_maxmin_precision)) {
+ var->value = var->bound;
+ XBT_DEBUG("Setting %p (%d) value to %f\n", var, var->id_int, var->value);
+ } else {
+ // Variables which bound is different are not considered for this cycle, but they will be afterwards.
+ XBT_DEBUG("Do not consider %p (%d) \n", var, var->id_int);
+ xbt_swag_remove(var, var_list);
+ continue;
+ }
+ }
+ XBT_DEBUG("Min usage: %f, Var(%d)->weight: %f, Var(%d)->value: %f ", min_usage, var->id_int, var->sharing_weight,
+ var->id_int, var->value);
+
+ /* Update the usage of contraints where this variable is involved */
+ for (s_lmm_element_t& elem : var->cnsts) {
+ lmm_constraint_t cnst = elem.constraint;
+ if (cnst->sharing_policy) {
+ // Remember: shared constraints require that sum(elem.value * var->value) < cnst->bound
+ double_update(&(cnst->remaining), elem.consumption_weight * var->value, cnst->bound * sg_maxmin_precision);
+ double_update(&(cnst->usage), elem.consumption_weight / var->sharing_weight, sg_maxmin_precision);
+ // If the constraint is saturated, remove it from the set of active constraints (light_tab)
+ if (not double_positive(cnst->usage, sg_maxmin_precision) ||
+ not double_positive(cnst->remaining, cnst->bound * sg_maxmin_precision)) {
+ if (cnst->cnst_light) {
+ int index = (cnst->cnst_light - cnst_light_tab);
+ XBT_DEBUG("index: %d \t cnst_light_num: %d \t || usage: %f remaining: %f bound: %f ", index,
+ cnst_light_num, cnst->usage, cnst->remaining, cnst->bound);
+ cnst_light_tab[index] = cnst_light_tab[cnst_light_num - 1];
+ cnst_light_tab[index].cnst->cnst_light = &cnst_light_tab[index];
+ cnst_light_num--;
+ cnst->cnst_light = nullptr;
+ }
+ } else {
+ cnst->cnst_light->remaining_over_usage = cnst->remaining / cnst->usage;
+ }
+ elem.make_inactive();
+ } else {
+ // Remember: non-shared constraints only require that max(elem.value * var->value) < cnst->bound
+ cnst->usage = 0.0;
+ elem.make_inactive();
+ xbt_swag_t elem_list = &(cnst->enabled_element_set);
+ xbt_swag_foreach(_elem, elem_list)
+ {
+ lmm_element_t elem2 = static_cast<lmm_element_t>(_elem);
+ xbt_assert(elem2->variable->sharing_weight > 0);
+ if (elem2->variable->value > 0)
+ continue;
+ if (elem2->consumption_weight > 0)
+ cnst->usage = std::max(cnst->usage, elem2->consumption_weight / elem2->variable->sharing_weight);
+ }
+ // If the constraint is saturated, remove it from the set of active constraints (light_tab)
+ if (not double_positive(cnst->usage, sg_maxmin_precision) ||
+ not double_positive(cnst->remaining, cnst->bound * sg_maxmin_precision)) {
+ if (cnst->cnst_light) {
+ int index = (cnst->cnst_light - cnst_light_tab);
+ XBT_DEBUG("index: %d \t cnst_light_num: %d \t || \t cnst: %p \t cnst->cnst_light: %p "
+ "\t cnst_light_tab: %p usage: %f remaining: %f bound: %f ",
+ index, cnst_light_num, cnst, cnst->cnst_light, cnst_light_tab, cnst->usage, cnst->remaining,
+ cnst->bound);
+ cnst_light_tab[index] = cnst_light_tab[cnst_light_num - 1];
+ cnst_light_tab[index].cnst->cnst_light = &cnst_light_tab[index];
+ cnst_light_num--;
+ cnst->cnst_light = nullptr;
+ }
+ } else {
+ cnst->cnst_light->remaining_over_usage = cnst->remaining / cnst->usage;
+ xbt_assert(cnst->active_element_set.count > 0,
+ "Should not keep a maximum constraint that has no active"
+ " element! You want to check the maxmin precision and possible rounding effects.");
+ }
+ }
+ }
+ xbt_swag_remove(var, var_list);
+ }
+
+ /* Find out which variables reach the maximum */
+ min_usage = -1;
+ min_bound = -1;
+ saturated_constraints.clear();
+ int pos;
+ for (pos = 0; pos < cnst_light_num; pos++) {
+ xbt_assert(cnst_light_tab[pos].cnst->active_element_set.count > 0,
+ "Cannot saturate more a constraint that has"
+ " no active element! You may want to change the maxmin precision (--cfg=maxmin/precision:<new_value>)"
+ " because of possible rounding effects.\n\tFor the record, the usage of this constraint is %g while "
+ "the maxmin precision to which it is compared is %g.\n\tThe usage of the previous constraint is %g.",
+ cnst_light_tab[pos].cnst->usage, sg_maxmin_precision, cnst_light_tab[pos - 1].cnst->usage);
+ saturated_constraints_update(cnst_light_tab[pos].remaining_over_usage, pos, saturated_constraints, &min_usage);
+ }
+
+ saturated_variable_set_update(cnst_light_tab, saturated_constraints, this);
+
+ } while (cnst_light_num > 0);
+
+ modified = false;
+ if (selective_update_active)
+ remove_all_modified_set();
+
+ if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
+ print();
+ }
+
+ check_concurrency();
+
+ delete[] cnst_light_tab;
+ XBT_OUT();
+}
+
+void lmm_solve(lmm_system_t sys)
+{
+ sys->solve();
+}
+
+/** \brief Attribute the value bound to var->bound.
+ *
+ * \param sys the lmm_system_t
+ * \param var the lmm_variable_t
+ * \param bound the new bound to associate with var
+ *
+ * Makes var->bound equal to bound. Whenever this function is called a change is signed in the system. To
+ * avoid false system changing detection it is a good idea to test (bound != 0) before calling it.
+ */
+void s_lmm_system_t::update_variable_bound(lmm_variable_t var, double bound)
+{
+ modified = true;
+ var->bound = bound;
+
+ if (not var->cnsts.empty())
+ update_modified_set(var->cnsts[0].constraint);
+}
+
+void s_lmm_variable_t::initialize(simgrid::surf::Action* id_value, double sharing_weight_value, double bound_value,
+ int number_of_constraints, unsigned visited_value)
+{
+ id = id_value;
+ id_int = Global_debug_id++;
+ cnsts.reserve(number_of_constraints);
+ sharing_weight = sharing_weight_value;
+ staged_weight = 0.0;
+ bound = bound_value;
+ concurrency_share = 1;
+ value = 0.0;
+ visited = visited_value;
+ mu = 0.0;
+ new_mu = 0.0;
+ func_f = func_f_def;
+ func_fp = func_fp_def;
+ func_fpi = func_fpi_def;
+
+ variable_set_hookup.next = nullptr;
+ variable_set_hookup.prev = nullptr;
+ saturated_variable_set_hookup.next = nullptr;
+ saturated_variable_set_hookup.prev = nullptr;
+}
+
+int s_lmm_variable_t::get_min_concurrency_slack() const
+{
+ int minslack = std::numeric_limits<int>::max();
+ for (s_lmm_element_t const& elem : cnsts) {
+ int slack = elem.constraint->get_concurrency_slack();
+ if (slack < minslack) {
+ // This is only an optimization, to avoid looking at more constraints when slack is already zero
+ if (slack == 0)
+ return 0;
+ minslack = slack;
+ }
+ }
+ return minslack;
+}
+
+// Small remark: In this implementation of lmm_enable_var and lmm_disable_var, we will meet multiple times with var when
+// running sys->update_modified_set.
+// A priori not a big performance issue, but we might do better by calling sys->update_modified_set within the for loops
+// (after doing the first for enabling==1, and before doing the last for disabling==1)
+void s_lmm_system_t::enable_var(lmm_variable_t var)
+{
+ xbt_assert(not XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug) || var->can_enable());
+
+ var->sharing_weight = var->staged_weight;
+ var->staged_weight = 0;
+
+ // Enabling the variable, move to var to list head. Subtlety is: here, we need to call update_modified_set AFTER
+ // moving at least one element of var.
+
+ xbt_swag_remove(var, &variable_set);
+ xbt_swag_insert_at_head(var, &variable_set);
+ for (s_lmm_element_t& elem : var->cnsts) {
+ xbt_swag_remove(&elem, &(elem.constraint->disabled_element_set));
+ xbt_swag_insert_at_head(&elem, &(elem.constraint->enabled_element_set));
+ elem.increase_concurrency();
+ }
+ if (not var->cnsts.empty())
+ update_modified_set(var->cnsts[0].constraint);
+
+ // When used within on_disabled_var, we would get an assertion fail, because transiently there can be variables
+ // that are staged and could be activated.
+ // Anyway, caller functions all call check_concurrency() in the end.
+}
+
+void s_lmm_system_t::disable_var(lmm_variable_t var)
+{
+ xbt_assert(not var->staged_weight, "Staged weight should have been cleared");
+ // Disabling the variable, move to var to list tail. Subtlety is: here, we need to call update_modified_set
+ // BEFORE moving the last element of var.
+ xbt_swag_remove(var, &variable_set);
+ xbt_swag_insert_at_tail(var, &variable_set);
+ if (not var->cnsts.empty())
+ update_modified_set(var->cnsts[0].constraint);
+ for (s_lmm_element_t& elem : var->cnsts) {
+ xbt_swag_remove(&elem, &(elem.constraint->enabled_element_set));
+ xbt_swag_insert_at_tail(&elem, &(elem.constraint->disabled_element_set));
+
+ xbt_swag_remove(&elem, &(elem.constraint->active_element_set));
+
+ elem.decrease_concurrency();
+ }
+
+ var->sharing_weight = 0.0;
+ var->staged_weight = 0.0;
+ var->value = 0.0;
+ check_concurrency();
+}
+
+/* /brief Find variables that can be enabled and enable them.
+ *
+ * Assuming that the variable has already been removed from non-zero weights
+ * Can we find a staged variable to add?
+ * If yes, check that none of the constraints that this variable is involved in is at the limit of its concurrency
+ * And then add it to enabled variables
+ */
+void s_lmm_system_t::on_disabled_var(lmm_constraint_t cnstr)
+{
+ if (cnstr->get_concurrency_limit() < 0)
+ return;
+
+ int numelem = xbt_swag_size(&(cnstr->disabled_element_set));
+ if (not numelem)
+ return;
+
+ lmm_element_t elem = (lmm_element_t)xbt_swag_getFirst(&(cnstr->disabled_element_set));
+
+ // Cannot use xbt_swag_foreach, because lmm_enable_var will modify disabled_element_set.. within the loop
+ while (numelem-- && elem) {
+
+ lmm_element_t nextelem = (lmm_element_t)xbt_swag_getNext(elem, cnstr->disabled_element_set.offset);
+
+ if (elem->variable->staged_weight > 0 && elem->variable->can_enable()) {
+ // Found a staged variable
+ // TODOLATER: Add random timing function to model reservation protocol fuzziness? Then how to make sure that
+ // staged variables will eventually be called?
+ enable_var(elem->variable);
+ }
+
+ xbt_assert(cnstr->concurrency_current <= cnstr->get_concurrency_limit(), "Concurrency overflow!");
+ if (cnstr->concurrency_current == cnstr->get_concurrency_limit())
+ break;
+
+ elem = nextelem;
+ }
+
+ // We could get an assertion fail, because transiently there can be variables that are staged and could be activated.
+ // And we need to go through all constraints of the disabled var before getting back a coherent state.
+ // Anyway, caller functions all call check_concurrency() in the end.
+}
+
+/* \brief update the weight of a variable, and enable/disable it.
+ * @return Returns whether a change was made
+ */
+void s_lmm_system_t::update_variable_weight(lmm_variable_t var, double weight)
+{
+ xbt_assert(weight >= 0, "Variable weight should not be negative!");
+
+ if (weight == var->sharing_weight)
+ return;
+
+ int enabling_var = (weight > 0 && var->sharing_weight <= 0);
+ int disabling_var = (weight <= 0 && var->sharing_weight > 0);
+
+ XBT_IN("(sys=%p, var=%p, weight=%f)", this, var, weight);
+
+ modified = true;
+
+ // Are we enabling this variable?
+ if (enabling_var) {
+ var->staged_weight = weight;
+ int minslack = var->get_min_concurrency_slack();
+ if (minslack < var->concurrency_share) {
+ XBT_DEBUG("Staging var (instead of enabling) because min concurrency slack %i, with weight %f and concurrency"
+ " share %i",
+ minslack, weight, var->concurrency_share);
+ return;
+ }
+ XBT_DEBUG("Enabling var with min concurrency slack %i", minslack);
+ enable_var(var);
+ } else if (disabling_var) {
+ // Are we disabling this variable?
+ disable_var(var);
+ } else {
+ var->sharing_weight = weight;
+ }
+
+ check_concurrency();
+
+ XBT_OUT();
+}
+
+void s_lmm_system_t::update_constraint_bound(lmm_constraint_t cnst, double bound)
+{
+ modified = true;
+ update_modified_set(cnst);
+ cnst->bound = bound;
+}
+
+/** \brief Update the constraint set propagating recursively to other constraints so the system should not be entirely
+ * computed.
+ *
+ * \param sys the lmm_system_t
+ * \param cnst the lmm_constraint_t affected by the change
+ *
+ * A recursive algorithm to optimize the system recalculation selecting only constraints that have changed. Each
+ * constraint change is propagated to the list of constraints for each variable.
+ */
+void s_lmm_system_t::update_modified_set_rec(lmm_constraint_t cnst)
+{
+ void* _elem;
+
+ 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) {
+ if (var->visited == visited_counter)
+ break;
+ if (elem.constraint != cnst && not xbt_swag_belongs(elem.constraint, &modified_constraint_set)) {
+ xbt_swag_insert(elem.constraint, &modified_constraint_set);
+ update_modified_set_rec(elem.constraint);
+ }
+ }
+ // var will be ignored in later visits as long as sys->visited_counter does not move
+ var->visited = visited_counter;
+ }
+}
+
+void s_lmm_system_t::update_modified_set(lmm_constraint_t cnst)
+{
+ /* nothing to do if selective update isn't active */
+ if (selective_update_active && not xbt_swag_belongs(cnst, &modified_constraint_set)) {
+ xbt_swag_insert(cnst, &modified_constraint_set);
+ update_modified_set_rec(cnst);
+ }
+}
+
+void s_lmm_system_t::remove_all_modified_set()
+{
+ // We cleverly un-flag all variables just by incrementing visited_counter
+ // In effect, the var->visited value will no more be equal to visited counter
+ // To be clean, when visited counter has wrapped around, we force these var->visited values so that variables that
+ // were in the modified a long long time ago are not wrongly skipped here, which would lead to very nasty bugs
+ // (i.e. not readibily reproducible, and requiring a lot of run time before happening).
+ if (++visited_counter == 1) {
+ /* the counter wrapped around, reset each variable->visited */
+ void* _var;
+ xbt_swag_foreach(_var, &variable_set)((lmm_variable_t)_var)->visited = 0;
+ }
+ xbt_swag_reset(&modified_constraint_set);
+}
+
+/**
+ * Returns resource load (in flop per second, or byte per second, or similar)
+ *
+ * If the resource is shared (the default case), the load is sum of resource usage made by every variables located on
+ * this resource.
+ *
+ * If the resource is not shared (ie in FATPIPE mode), then the load is the max (not the sum) of all resource usages
+ * located on this resource.
+ *
+ * \param cnst the lmm_constraint_t associated to the resource
+ */
+double s_lmm_constraint_t::get_usage() const
+{
+ double result = 0.0;
+ const_xbt_swag_t elem_list = &enabled_element_set;
+ void* _elem;
+
+ xbt_swag_foreach(_elem, elem_list)
+ {
+ lmm_element_t elem = (lmm_element_t)_elem;
+ if (elem->consumption_weight > 0) {
+ if (sharing_policy)
+ result += elem->consumption_weight * elem->variable->value;
+ else if (result < elem->consumption_weight * elem->variable->value)
+ result = std::max(result, elem->consumption_weight * elem->variable->value);
+ }
+ }
+ return result;
+}
+
+int s_lmm_constraint_t::get_variable_amount() const
+{
+ int result = 0;
+ const_xbt_swag_t elem_list = &enabled_element_set;
+ void* _elem;
+
+ xbt_swag_foreach(_elem, elem_list)
+ {
+ lmm_element_t elem = (lmm_element_t)_elem;
+ if (elem->consumption_weight > 0)
+ result++;
+ }
+ return result;
+}
+}
+}
#include <vector>
#include "xbt/automaton.h"
+#include "xbt/backtrace.hpp"
#include "xbt/dynar.h"
#include "xbt/swag.h"
unw_word_t off;
do {
const char* name = not unw_get_proc_name(&cursor, buffer, 100, &off) ? buffer : "?";
-
- int status;
-
// Unmangle C++ names:
- char* realname = abi::__cxa_demangle(name, 0, 0, &status);
+ auto realname = simgrid::xbt::demangle(name);
#if defined(__x86_64__)
unw_word_t rip = 0;
unw_word_t rsp = 0;
unw_get_reg(&cursor, UNW_X86_64_RIP, &rip);
unw_get_reg(&cursor, UNW_X86_64_RSP, &rsp);
- fprintf(file, " %i: %s (RIP=0x%" PRIx64 " RSP=0x%" PRIx64 ")\n",
- nframe, realname ? realname : name, (std::uint64_t) rip, (std::uint64_t) rsp);
+ fprintf(file, " %i: %s (RIP=0x%" PRIx64 " RSP=0x%" PRIx64 ")\n", nframe, realname.get(), (std::uint64_t)rip,
+ (std::uint64_t)rsp);
#else
- fprintf(file, " %i: %s\n", nframe, realname ? realname : name);
+ fprintf(file, " %i: %s\n", nframe, realname.get());
#endif
- free(realname);
++nframe;
} while(unw_step(&cursor));
}
read_element(mc_model_checker->process(),
&remote_sync, remote(simcall_comm_waitany__get__comms(req)), value,
sizeof(remote_sync));
- char* p = pointer_to_string(&*remote_sync);
+ char* p = pointer_to_string(remote_sync.get());
args = bprintf("comm=%s (%d of %lu)",
p, value + 1, xbt_dynar_length(&comms));
xbt_free(p);
"\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.
*
#include "simgrid/host.h"
#include "simgrid/simix.hpp"
+#include "xbt/string.hpp"
extern "C" {
struct s_dirty_page {
- double prev_clock;
- double prev_remaining;
- msg_task_t task;
+ double prev_clock = 0.0;
+ double prev_remaining = 0.0;
+ msg_task_t task = nullptr;
};
typedef s_dirty_page* dirty_page_t;
/* The miration_rx process uses mbox_ctl to let the caller of do_migration()
* know the completion of the migration. */
- char *mbox_ctl;
+ std::string mbox_ctl;
/* The migration_rx and migration_tx processes use mbox to transfer migration data. */
- char *mbox;
+ std::string mbox;
};
static int migration_rx_fun(int argc, char *argv[])
std::string finalize_task_name = get_mig_task_name(ms->vm, ms->src_pm, ms->dst_pm, 3);
while (not received_finalize) {
msg_task_t task = nullptr;
- int ret = MSG_task_recv(&task, ms->mbox);
+ int ret = MSG_task_recv(&task, ms->mbox.c_str());
if (ret != MSG_OK) {
// An error occurred, clean the code and return
// Inform the SRC that the migration has been correctly performed
std::string task_name = get_mig_task_name(ms->vm, ms->src_pm, ms->dst_pm, 4);
msg_task_t task = MSG_task_create(task_name.c_str(), 0, 0, nullptr);
- msg_error_t ret = MSG_task_send(task, ms->mbox_ctl);
+ msg_error_t ret = MSG_task_send(task, ms->mbox_ctl.c_str());
if(ret == MSG_HOST_FAILURE){
// The DST has crashed, this is a problem has the VM since we are not sure whether SRC is considering that the VM
// has been correctly migrated on the DST node
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);
vm->pimpl_vm_->dp_enabled = 0;
}
-static double get_computed(const char* key, msg_vm_t vm, dirty_page_t dp, double remaining, double clock)
+static double get_computed(const std::string& key, msg_vm_t vm, dirty_page_t dp, double remaining, double clock)
{
double computed = dp->prev_remaining - remaining;
double duration = clock - dp->prev_clock;
- XBT_DEBUG("%s@%s: computed %f ops (remaining %f -> %f) in %f secs (%f -> %f)", key, vm->getCname(), computed,
+ XBT_DEBUG("%s@%s: computed %f ops (remaining %f -> %f) in %f secs (%f -> %f)", key.c_str(), vm->getCname(), computed,
dp->prev_remaining, remaining, duration, dp->prev_clock, clock);
return computed;
double total = 0;
for (auto const& elm : vm->pimpl_vm_->dp_objs) {
- const char* key = elm.first.c_str();
+ 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);
- char *key = bprintf("%s-%p", task->name, 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 = xbt_new0(s_dirty_page, 1);
+ dirty_page_t dp = new s_dirty_page;
dp->task = task;
if (vm->pimpl_vm_->dp_enabled) {
dp->prev_clock = MSG_get_clock();
dp->prev_remaining = remaining;
}
vm->pimpl_vm_->dp_objs.insert({key, dp});
- XBT_DEBUG("add %s on %s (remaining %f, dp_enabled %d)", key, host->getCname(), remaining, vm->pimpl_vm_->dp_enabled);
-
- xbt_free(key);
+ XBT_DEBUG("add %s on %s (remaining %f, dp_enabled %d)", key.c_str(), host->getCname(), remaining,
+ vm->pimpl_vm_->dp_enabled);
}
void MSG_host_del_task(msg_host_t host, msg_task_t task)
if (vm == nullptr)
return;
- char *key = bprintf("%s-%p", task->name, task);
+ std::string key = simgrid::xbt::string_printf("%s-%p", task->name, task);
dirty_page_t dp = nullptr;
- if (vm->pimpl_vm_->dp_objs.find(key) != vm->pimpl_vm_->dp_objs.end())
- dp = vm->pimpl_vm_->dp_objs.at(key);
+ auto dp_obj = vm->pimpl_vm_->dp_objs.find(key);
+ if (dp_obj != vm->pimpl_vm_->dp_objs.end())
+ dp = dp_obj->second;
xbt_assert(dp && dp->task == task);
/* 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
}
vm->pimpl_vm_->dp_objs.erase(key);
- xbt_free(dp);
+ delete dp;
- XBT_DEBUG("del %s on %s", key, host->getCname());
- xbt_free(key);
+ XBT_DEBUG("del %s on %s", key.c_str(), host->getCname());
}
-static sg_size_t send_migration_data(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm, sg_size_t size, char* mbox,
- int stage, int stage2_round, double mig_speed, double timeout)
+static sg_size_t send_migration_data(msg_vm_t vm, msg_host_t src_pm, msg_host_t dst_pm, sg_size_t size,
+ const std::string& mbox, int stage, int stage2_round, double mig_speed,
+ double timeout)
{
sg_size_t sent = 0;
std::string task_name = get_mig_task_name(vm, src_pm, dst_pm, stage);
msg_error_t ret;
if (mig_speed > 0)
- ret = MSG_task_send_with_timeout_bounded(task, mbox, timeout, mig_speed);
+ ret = MSG_task_send_with_timeout_bounded(task, mbox.c_str(), timeout, mig_speed);
else
- ret = MSG_task_send(task, mbox);
+ ret = MSG_task_send(task, mbox.c_str());
if (ret == MSG_OK) {
sent = size;
vm->pimpl_vm_->isMigrating = true;
- migration_session* ms = xbt_new(migration_session, 1);
- ms->vm = vm;
- ms->src_pm = src_pm;
- ms->dst_pm = dst_pm;
+ migration_session ms;
+ ms.vm = vm;
+ ms.src_pm = src_pm;
+ ms.dst_pm = dst_pm;
/* We have two mailboxes. mbox is used to transfer migration data between source and destination PMs. mbox_ctl is used
* to detect the completion of a migration. The names of these mailboxes must not conflict with others. */
- ms->mbox_ctl = bprintf("__mbox_mig_ctl:%s(%s-%s)", vm->getCname(), src_pm->getCname(), dst_pm->getCname());
- ms->mbox = bprintf("__mbox_mig_src_dst:%s(%s-%s)", vm->getCname(), src_pm->getCname(), dst_pm->getCname());
+ ms.mbox_ctl =
+ simgrid::xbt::string_printf("__mbox_mig_ctl:%s(%s-%s)", vm->getCname(), src_pm->getCname(), dst_pm->getCname());
+ ms.mbox = simgrid::xbt::string_printf("__mbox_mig_src_dst:%s(%s-%s)", vm->getCname(), src_pm->getCname(),
+ dst_pm->getCname());
std::string pr_rx_name = get_mig_process_rx_name(vm, src_pm, dst_pm);
std::string pr_tx_name = get_mig_process_tx_name(vm, src_pm, dst_pm);
- MSG_process_create(pr_rx_name.c_str(), migration_rx_fun, ms, dst_pm);
+ MSG_process_create(pr_rx_name.c_str(), migration_rx_fun, &ms, dst_pm);
- MSG_process_create(pr_tx_name.c_str(), migration_tx_fun, ms, src_pm);
+ MSG_process_create(pr_tx_name.c_str(), migration_tx_fun, &ms, src_pm);
/* wait until the migration have finished or on error has occurred */
XBT_DEBUG("wait for reception of the final ACK (i.e. migration has been correctly performed");
msg_task_t task = nullptr;
- msg_error_t ret = MSG_task_receive(&task, ms->mbox_ctl);
+ msg_error_t ret = MSG_task_receive(&task, ms.mbox_ctl.c_str());
vm->pimpl_vm_->isMigrating = false;
- xbt_free(ms->mbox_ctl);
- xbt_free(ms->mbox);
- xbt_free(ms);
-
if (ret == MSG_HOST_FAILURE) {
// Note that since the communication failed, the owner did not change and the task should be destroyed on the
// other side. Hence, just throw the execption
surf::Cpu* cpu = ws_vm->pimpl_cpu;
xbt_assert(cpu, "cpu-less host");
- double solved_value = ws_vm->pimpl_vm_->action_->getVariable()
- ->value; // this is X1 in comment above, what this VM got in the sharing on the PM
+ double solved_value = ws_vm->pimpl_vm_->action_->getVariable()->get_value(); // this is X1 in comment above, what
+ // this VM got in the sharing on the PM
XBT_DEBUG("assign %f to vm %s @ pm %s", solved_value, ws_vm->getCname(), ws_vm->pimpl_vm_->getPm()->getCname());
xbt_assert(cpu->model() == surf_cpu_model_vm);
- lmm_system_t vcpu_system = cpu->model()->getMaxminSystem();
- lmm_update_constraint_bound(vcpu_system, cpu->constraint(), virt_overhead * solved_value);
+ surf::lmm_system_t vcpu_system = cpu->model()->getMaxminSystem();
+ vcpu_system->update_constraint_bound(cpu->constraint(), virt_overhead * solved_value);
}
/* 2. Calculate resource share at the virtual machine layer. */
simcall_process_sleep(duration);
}
+void yield()
+{
+ simgrid::simix::kernelImmediate([] { /* do nothing*/ });
+}
+
XBT_PUBLIC(void) sleep_until(double timeout)
{
double now = SIMIX_get_clock();
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()
#include "simgrid/sg_config.h"
#include "simgrid/simix.hpp"
#include "src/surf/network_interface.hpp"
+#include "surf/maxmin.hpp"
#include "xbt/log.h"
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(s4u_link, s4u, "Logging specific to the S4U links");
return this->pimpl_->sharingPolicy();
}
+double Link::getUsage()
+{
+ return this->pimpl_->constraint()->get_usage();
+}
+
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);
}
/*************
XBT_VERB("(%d->%d): (%.2f, %.2f)-> (%.2f, %.2f)", i, j, src_start, src_end, dst_start, dst_end);
task->bytes_amount[i*(src_nb+dst_nb)+src_nb+j]=0.0;
if ((src_end > dst_start) && (dst_end > src_start)) { /* There is something to send */
- task->bytes_amount[i*(src_nb+dst_nb)+src_nb+j] = MIN(src_end, dst_end)- MAX(src_start, dst_start);
+ task->bytes_amount[i * (src_nb + dst_nb) + src_nb + j] =
+ std::min(src_end, dst_end) - std::max(src_start, dst_start);
XBT_VERB("==> %.2f", task->bytes_amount[i*(src_nb+dst_nb)+src_nb+j]);
}
}
* \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:
if (value.get() == nullptr) { // Sometimes we return nullptr in an intrusive_ptr...
simcall.dp = nullptr;
} else {
- intrusive_ptr_add_ref(&*value);
- simcall.dp = static_cast<void*>(&*value);
+ intrusive_ptr_add_ref(value.get());
+ simcall.dp = static_cast<void*>(value.get());
}
}
template <class T> inline boost::intrusive_ptr<T> unmarshal(type<boost::intrusive_ptr<T>>, u_smx_scalar const& simcall)
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);
/* 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 <boost/heap/fibonacci_heap.hpp>
#include <functional>
#include <memory>
-#include <queue>
#include "src/internal_config.h"
#include <csignal> /* Signal handling */
#include <xbt/algorithm.hpp>
#include <xbt/functional.hpp>
+#include <xbt/utility.hpp>
#include "simgrid/s4u/Engine.hpp"
#include "simgrid/s4u/Host.hpp"
std::unique_ptr<simgrid::simix::Global> simix_global;
+namespace {
+typedef std::pair<double, smx_timer_t> TimerQelt;
+boost::heap::fibonacci_heap<TimerQelt, boost::heap::compare<simgrid::xbt::HeapComparator<TimerQelt>>> simix_timers;
+}
+
/** @brief Timer datatype */
class s_smx_timer_t {
double date = 0.0;
public:
+ decltype(simix_timers)::handle_type handle_;
simgrid::xbt::Task<void()> callback;
- void disable() { date = -1.0; }
- bool isDisabled() { return date == -1.0; }
double getDate() { return date; }
s_smx_timer_t(double date, simgrid::xbt::Task<void()> callback) : date(date), callback(std::move(callback)) {}
};
-namespace {
-typedef std::pair<double, smx_timer_t> TimerQelt;
-std::priority_queue<TimerQelt, std::vector<TimerQelt>, std::greater<TimerQelt>> simix_timers;
-void SIMIX_timer_flush()
-{
- while (not simix_timers.empty() && simix_timers.top().second->isDisabled()) {
- delete simix_timers.top().second;
- simix_timers.pop();
- }
-}
-}
-
void (*SMPI_switch_data_segment)(int) = nullptr;
int _sg_do_verbose_exit = 1;
// (i.e. provide dispatchers that read and expand the args)
smx_timer_t timer = simix_timers.top().second;
simix_timers.pop();
- SIMIX_timer_flush();
try {
timer->callback();
} catch (...) {
smx_timer_t SIMIX_timer_set(double date, void (*callback)(void*), void *arg)
{
smx_timer_t timer = new s_smx_timer_t(date, [callback, arg]() { callback(arg); });
- simix_timers.emplace(date, timer);
+ timer->handle_ = simix_timers.emplace(std::make_pair(date, timer));
return timer;
}
smx_timer_t SIMIX_timer_set(double date, simgrid::xbt::Task<void()> callback)
{
smx_timer_t timer = new s_smx_timer_t(date, std::move(callback));
- simix_timers.emplace(date, timer);
+ timer->handle_ = simix_timers.emplace(std::make_pair(date, timer));
return timer;
}
/** @brief cancels a timer that was added earlier */
void SIMIX_timer_remove(smx_timer_t timer) {
- timer->disable();
- SIMIX_timer_flush();
+ simix_timers.erase(timer->handle_);
+ delete timer;
}
/** @brief Returns the date at which the timer will trigger (or 0 if nullptr timer) */
#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);
} else { /* we need a surf sleep action even when there is no timeout, otherwise surf won't tell us when the host
fails */
surf_action_t sleep = simcall->issuer->host->pimpl_cpu->sleep(timeout);
- sleep->setData(&*synchro);
+ sleep->setData(synchro.get());
simgrid::kernel::activity::CommImplPtr comm =
boost::static_pointer_cast<simgrid::kernel::activity::CommImpl>(synchro);
/* Copy at most dst_buff_size bytes of the message to receiver's buffer */
if (comm->dst_buff_size)
- buff_size = MIN(buff_size, *(comm->dst_buff_size));
+ buff_size = std::min(buff_size, *(comm->dst_buff_size));
/* Update the receiver's buffer size to the copied amount */
if (comm->dst_buff_size)
XBT_PUBLIC(void) SIMIX_clean();
/******************************** Exceptions *********************************/
-/** @brief Ask to the provided simix process to raise the provided exception */
+/** @brief Ask to the provided ActorImpl to raise the provided exception */
#define SMX_EXCEPTION(issuer, cat, val, msg) \
if (1) { \
- smx_actor_t _smx_throw_issuer = (issuer); /* evaluate only once */ \
+ simgrid::simix::ActorImpl* _smx_throw_issuer = (issuer); /* evaluate only once */ \
xbt_ex e(XBT_THROW_POINT, msg); \
e.category = cat; \
e.value = val; \
simgrid::kernel::activity::RawImplPtr sync =
simgrid::kernel::activity::RawImplPtr(new simgrid::kernel::activity::RawImpl());
sync->sleep = smx_host->pimpl_cpu->sleep(timeout);
- sync->sleep->setData(&*sync);
+ sync->sleep->setData(sync.get());
XBT_OUT();
return sync;
}
return MPI_SUCCESS;
}
-int PMPI_Init_thread(int *argc, char ***argv, int required, int *provided)
+int PMPI_Init_thread(int* argc, char*** argv, int /*required*/, int* provided)
{
if (provided != nullptr) {
*provided = MPI_THREAD_SINGLE;
}
}
-int PMPI_Abort(MPI_Comm comm, int errorcode)
+int PMPI_Abort(MPI_Comm /*comm*/, int /*errorcode*/)
{
smpi_bench_end();
// FIXME: should kill all processes in comm instead
return MPI_SUCCESS;
}
-int PMPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr){
+int PMPI_Alloc_mem(MPI_Aint size, MPI_Info /*info*/, void* baseptr)
+{
void *ptr = xbt_malloc(size);
if(ptr==nullptr)
return MPI_ERR_NO_MEM;
return MPI_ERR_TYPE;
if(comm==MPI_COMM_NULL)
return MPI_ERR_COMM;
- return type->pack(inbuf, incount, outbuf,outcount,position, comm);
+ return type->pack(inbuf == MPI_BOTTOM ? nullptr : inbuf, incount, outbuf, outcount, position, comm);
}
int PMPI_Pack_size(int incount, MPI_Datatype datatype, MPI_Comm comm, int* size) {
retval = MPI_ERR_WIN;
} else {
int rank = smpi_process()->index();
- TRACE_smpi_comm_in(rank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(rank, __FUNCTION__, new simgrid::instr::NoOpTIData("Win_fence"));
retval = win->fence(assert);
TRACE_smpi_comm_out(rank);
}
int rank = smpi_process()->index();
MPI_Group group;
win->get_group(&group);
- TRACE_smpi_comm_in(rank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(rank, __FUNCTION__, new simgrid::instr::Pt2PtTIData("Get", target_rank,
+ origin_datatype->is_basic() ? origin_count : origin_count * origin_datatype->size(),
+ encode_datatype(origin_datatype)));
retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
target_datatype);
int rank = smpi_process()->index();
MPI_Group group;
win->get_group(&group);
- TRACE_smpi_comm_in(rank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(rank, __FUNCTION__, new simgrid::instr::Pt2PtTIData("Rget", target_rank,
+ origin_datatype->is_basic() ? origin_count : origin_count * origin_datatype->size(),
+ encode_datatype(origin_datatype)));
retval = win->get( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
target_datatype, request);
MPI_Group group;
win->get_group(&group);
int dst_traced = group->index(target_rank);
- TRACE_smpi_comm_in(rank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(rank, __FUNCTION__, new simgrid::instr::Pt2PtTIData("Put", dst_traced,
+ origin_datatype->is_basic() ? origin_count : origin_count * origin_datatype->size(),
+ encode_datatype(origin_datatype)));
TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
MPI_Group group;
win->get_group(&group);
int dst_traced = group->index(target_rank);
- TRACE_smpi_comm_in(rank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(rank, __FUNCTION__, new simgrid::instr::Pt2PtTIData("Rput", dst_traced,
+ origin_datatype->is_basic() ? origin_count : origin_count * origin_datatype->size(),
+ encode_datatype(origin_datatype)));
TRACE_smpi_send(rank, rank, dst_traced, SMPI_RMA_TAG, origin_count*origin_datatype->size());
retval = win->put( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
int rank = smpi_process()->index();
MPI_Group group;
win->get_group(&group);
- TRACE_smpi_comm_in(rank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(rank, __FUNCTION__, new simgrid::instr::Pt2PtTIData("Accumulate", target_rank,
+ origin_datatype->is_basic() ? origin_count : origin_count * origin_datatype->size(),
+ encode_datatype(origin_datatype)));
retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
target_datatype, op);
int rank = smpi_process()->index();
MPI_Group group;
win->get_group(&group);
- TRACE_smpi_comm_in(rank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(rank, __FUNCTION__, new simgrid::instr::Pt2PtTIData("Raccumulate", target_rank,
+ origin_datatype->is_basic() ? origin_count : origin_count * origin_datatype->size(),
+ encode_datatype(origin_datatype)));
retval = win->accumulate( origin_addr, origin_count, origin_datatype, target_rank, target_disp, target_count,
target_datatype, op, request);
int rank = smpi_process()->index();
MPI_Group group;
win->get_group(&group);
- TRACE_smpi_comm_in(rank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(rank, __FUNCTION__, new simgrid::instr::Pt2PtTIData("Get_accumulate", target_rank,
+ target_datatype->is_basic() ? target_count : target_count * target_datatype->size(),
+ encode_datatype(target_datatype)));
retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
result_count, result_datatype, target_rank, target_disp,
int rank = smpi_process()->index();
MPI_Group group;
win->get_group(&group);
- TRACE_smpi_comm_in(rank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(rank, __FUNCTION__, new simgrid::instr::Pt2PtTIData("Rget_accumulate", target_rank,
+ target_datatype->is_basic() ? target_count : target_count * target_datatype->size(),
+ encode_datatype(target_datatype)));
retval = win->get_accumulate( origin_addr, origin_count, origin_datatype, result_addr,
result_count, result_datatype, target_rank, target_disp,
int rank = smpi_process()->index();
MPI_Group group;
win->get_group(&group);
- TRACE_smpi_comm_in(rank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(rank, __FUNCTION__, new simgrid::instr::Pt2PtTIData("Compare_and_swap", target_rank,
+ datatype->is_basic() ? 1 : datatype->size(),
+ encode_datatype(datatype)));
retval = win->compare_and_swap(origin_addr, compare_addr, result_addr, datatype, target_rank, target_disp);
retval = MPI_ERR_GROUP;
} else {
int rank = smpi_process()->index();
- TRACE_smpi_comm_in(rank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(rank, __FUNCTION__, new simgrid::instr::NoOpTIData("Win_post"));
retval = win->post(group,assert);
TRACE_smpi_comm_out(rank);
}
retval = MPI_ERR_GROUP;
} else {
int rank = smpi_process()->index();
- TRACE_smpi_comm_in(rank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(rank, __FUNCTION__, new simgrid::instr::NoOpTIData("Win_start"));
retval = win->start(group,assert);
TRACE_smpi_comm_out(rank);
}
retval = MPI_ERR_WIN;
} else {
int rank = smpi_process()->index();
- TRACE_smpi_comm_in(rank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(rank, __FUNCTION__, new simgrid::instr::NoOpTIData("Win_complete"));
retval = win->complete();
retval = MPI_ERR_WIN;
} else {
int rank = smpi_process()->index();
- TRACE_smpi_comm_in(rank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(rank, __FUNCTION__, new simgrid::instr::NoOpTIData("Win_wait"));
retval = win->wait();
retval = MPI_SUCCESS;
} else {
int myrank = smpi_process()->index();
- TRACE_smpi_comm_in(myrank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(myrank, __func__, new simgrid::instr::NoOpTIData("Win_lock"));
retval = win->lock(lock_type,rank,assert);
TRACE_smpi_comm_out(myrank);
}
retval = MPI_SUCCESS;
} else {
int myrank = smpi_process()->index();
- TRACE_smpi_comm_in(myrank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(myrank, __FUNCTION__, new simgrid::instr::NoOpTIData("Win_unlock"));
retval = win->unlock(rank);
TRACE_smpi_comm_out(myrank);
}
retval = MPI_ERR_WIN;
} else {
int myrank = smpi_process()->index();
- TRACE_smpi_comm_in(myrank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(myrank, __FUNCTION__, new simgrid::instr::NoOpTIData("Win_lock_all"));
retval = win->lock_all(assert);
TRACE_smpi_comm_out(myrank);
}
retval = MPI_ERR_WIN;
} else {
int myrank = smpi_process()->index();
- TRACE_smpi_comm_in(myrank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(myrank, __FUNCTION__, new simgrid::instr::NoOpTIData("Win_unlock_all"));
retval = win->unlock_all();
TRACE_smpi_comm_out(myrank);
}
retval = MPI_SUCCESS;
} else {
int myrank = smpi_process()->index();
- TRACE_smpi_comm_in(myrank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(myrank, __FUNCTION__, new simgrid::instr::NoOpTIData("Win_flush"));
retval = win->flush(rank);
TRACE_smpi_comm_out(myrank);
}
retval = MPI_SUCCESS;
} else {
int myrank = smpi_process()->index();
- TRACE_smpi_comm_in(myrank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(myrank, __FUNCTION__, new simgrid::instr::NoOpTIData("Win_flush_local"));
retval = win->flush_local(rank);
TRACE_smpi_comm_out(myrank);
}
retval = MPI_ERR_WIN;
} else {
int myrank = smpi_process()->index();
- TRACE_smpi_comm_in(myrank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(myrank, __FUNCTION__, new simgrid::instr::NoOpTIData("Win_flush_all"));
retval = win->flush_all();
TRACE_smpi_comm_out(myrank);
}
retval = MPI_ERR_WIN;
} else {
int myrank = smpi_process()->index();
- TRACE_smpi_comm_in(myrank, __FUNCTION__, nullptr);
+ TRACE_smpi_comm_in(myrank, __FUNCTION__, new simgrid::instr::NoOpTIData("Win_flush_local_all"));
retval = win->flush_local_all();
TRACE_smpi_comm_out(myrank);
}
#include "../colls_private.hpp"
#include "smpi_status.hpp"
+#include <algorithm>
namespace simgrid{
namespace smpi{
recvtype->extent(&recvtype_true_lb, &recvtype_true_extent);
- tmp_buf_rl= (void*)smpi_get_tmp_sendbuffer(total_count*(MAX(recvtype_true_extent,recvtype_extent)));
+ tmp_buf_rl = (void*)smpi_get_tmp_sendbuffer(total_count * std::max(recvtype_true_extent, recvtype_extent));
/* adjust for potential negative lower bound in datatype */
tmp_buf = (void *)((char*)tmp_buf_rl - recvtype_true_lb);
*/
#include "../colls_private.hpp"
+#include <algorithm>
+
namespace simgrid{
namespace smpi{
int Coll_allreduce_mvapich2_rs::allreduce(void *sendbuf,
datatype->extent(&true_lb, &true_extent);
extent = datatype->get_extent();
- tmp_buf_free= smpi_get_tmp_recvbuffer(count * (MAX(extent, true_extent)));
+ tmp_buf_free = smpi_get_tmp_recvbuffer(count * std::max(extent, true_extent));
/* adjust for potential negative lower bound in datatype */
tmp_buf = (void *) ((char *) tmp_buf_free - true_lb);
*/
#include "../colls_private.hpp"
+#include <algorithm>
#define MPIR_Gather_MV2_Direct Coll_gather_ompi_basic_linear::gather
#define MPIR_Gather_MV2_two_level_Direct Coll_gather_ompi_basic_linear::gather
if (local_rank == 0) {
/* Node leader, allocate tmp_buffer */
if (rank == root) {
- tmp_buf = smpi_get_tmp_recvbuffer(recvcnt * MAX(recvtype_extent,
- recvtype_true_extent) * local_size);
+ tmp_buf = smpi_get_tmp_recvbuffer(recvcnt * std::max(recvtype_extent, recvtype_true_extent) * local_size);
} else {
- tmp_buf = smpi_get_tmp_sendbuffer(sendcnt * MAX(sendtype_extent,
- sendtype_true_extent) *
- local_size);
+ tmp_buf = smpi_get_tmp_sendbuffer(sendcnt * std::max(sendtype_extent, sendtype_true_extent) * local_size);
}
if (tmp_buf == NULL) {
mpi_errno = MPI_ERR_OTHER;
* is the same as leader_root */
if (rank == root) {
leader_gather_buf =
- smpi_get_tmp_recvbuffer(recvcnt * MAX(recvtype_extent, recvtype_true_extent) * comm_size);
+ smpi_get_tmp_recvbuffer(recvcnt * std::max(recvtype_extent, recvtype_true_extent) * comm_size);
} else {
leader_gather_buf =
- smpi_get_tmp_sendbuffer(sendcnt * MAX(sendtype_extent, sendtype_true_extent) * comm_size);
+ smpi_get_tmp_sendbuffer(sendcnt * std::max(sendtype_extent, sendtype_true_extent) * comm_size);
}
if (leader_gather_buf == NULL) {
mpi_errno = MPI_ERR_OTHER;
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "../colls_private.hpp"
+#include <algorithm>
//#include <star-reduction.c>
namespace simgrid{
/* If I'm not the root, then my recvbuf may not be valid, therefore
I have to allocate a temporary one */
if (rank != root) {
- recvbuf = (void *) smpi_get_tmp_recvbuffer(count*(MAX(extent,true_extent)));
+ recvbuf = (void*)smpi_get_tmp_recvbuffer(count * std::max(extent, true_extent));
recvbuf = (void *)((char*)recvbuf - true_lb);
}
if ((rank != root) || (sendbuf != MPI_IN_PLACE)) {
*/
#include "../colls_private.hpp"
+#include <algorithm>
+
extern int mv2_reduce_intra_knomial_factor;
extern int mv2_reduce_inter_knomial_factor;
is_commutative = (op==MPI_OP_NULL || op->is_commutative());
if (rank != root) {
- recvbuf=(void *)smpi_get_tmp_recvbuffer(count*(MAX(extent,true_extent)));
+ recvbuf = (void*)smpi_get_tmp_recvbuffer(count * std::max(extent, true_extent));
recvbuf = (void *)((char*)recvbuf - true_lb);
}
tmp_buf = static_cast<void**>(xbt_malloc(sizeof(void *)*expected_recv_count));
requests = static_cast<MPI_Request*>(xbt_malloc(sizeof(MPI_Request)*expected_recv_count));
for(k=0; k < expected_recv_count; k++ ) {
- tmp_buf[k] = smpi_get_tmp_sendbuffer(count*(MAX(extent,true_extent)));
+ tmp_buf[k] = smpi_get_tmp_sendbuffer(count * std::max(extent, true_extent));
tmp_buf[k] = (void *)((char*)tmp_buf[k] - true_lb);
}
*/
#include "../colls_private.hpp"
+#include <algorithm>
+
#define MV2_INTRA_SHMEM_REDUCE_MSG 2048
#define mv2_g_shmem_coll_max_msg_size (1 << 17)
datatype->extent(&true_lb,
&true_extent);
extent =datatype->get_extent();
- stride = count * MAX(extent, true_extent);
+ stride = count * std::max(extent, true_extent);
if (local_size == total_size) {
/* First handle the case where there is only one node */
if (stride <= MV2_INTRA_SHMEM_REDUCE_MSG &&
is_commutative == 1) {
if (local_rank == 0 ) {
- tmp_buf=(void *)smpi_get_tmp_sendbuffer( count *
- (MAX(extent, true_extent)));
+ tmp_buf = (void*)smpi_get_tmp_sendbuffer(count * std::max(extent, true_extent));
tmp_buf = (void *) ((char *) tmp_buf - true_lb);
}
out_buf = NULL;
}
- if (count * (MAX(extent, true_extent)) < SHMEM_COLL_BLOCK_SIZE) {
+ if (count * (std::max(extent, true_extent)) < SHMEM_COLL_BLOCK_SIZE) {
mpi_errno = MPIR_Reduce_shmem_MV2(in_buf, out_buf, count, datatype, op, 0, shmem_comm);
} else {
mpi_errno = MPIR_Reduce_intra_knomial_wrapper_MV2(in_buf, out_buf, count, datatype, op, 0, shmem_comm);
}
leader_comm_size = leader_comm->size();
leader_comm_rank = leader_comm->rank();
- tmp_buf=(void *)smpi_get_tmp_sendbuffer(count *
- (MAX(extent, true_extent)));
+ tmp_buf = (void*)smpi_get_tmp_sendbuffer(count * std::max(extent, true_extent));
tmp_buf = (void *) ((char *) tmp_buf - true_lb);
}
if (sendbuf != MPI_IN_PLACE) {
*this step*/
if (MV2_Reduce_intra_function == & MPIR_Reduce_shmem_MV2)
{
- if (is_commutative == 1 && (count * (MAX(extent, true_extent)) < SHMEM_COLL_BLOCK_SIZE)) {
+ if (is_commutative == 1 && (count * (std::max(extent, true_extent)) < SHMEM_COLL_BLOCK_SIZE)) {
mpi_errno = MV2_Reduce_intra_function(in_buf, out_buf, count, datatype, op, intra_node_root, shmem_comm);
} else {
mpi_errno = MPIR_Reduce_intra_knomial_wrapper_MV2(in_buf, out_buf, count,
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "../colls_private.hpp"
+#include <algorithm>
static inline int MPIU_Mirror_permutation(unsigned int x, int bits)
{
}
/* allocate temporary buffer to store incoming data */
- tmp_recvbuf = (void*)smpi_get_tmp_recvbuffer(recvcounts[rank]*(MAX(true_extent,extent))+1);
+ tmp_recvbuf = (void*)smpi_get_tmp_recvbuffer(recvcounts[rank] * std::max(true_extent, extent) + 1);
/* adjust for potential negative lower bound in datatype */
tmp_recvbuf = (void *)((char*)tmp_recvbuf - true_lb);
/* noncommutative and (non-pof2 or block irregular), use recursive doubling. */
/* need to allocate temporary buffer to receive incoming data*/
- tmp_recvbuf= (void *) smpi_get_tmp_recvbuffer( total_count*(MAX(true_extent,extent)));
+ tmp_recvbuf= (void*)smpi_get_tmp_recvbuffer(total_count * std::max(true_extent, extent));
/* adjust for potential negative lower bound in datatype */
tmp_recvbuf = (void *)((char*)tmp_recvbuf - true_lb);
/* need to allocate another temporary buffer to accumulate
results */
- tmp_results = (void *)smpi_get_tmp_sendbuffer( total_count*(MAX(true_extent,extent)));
+ tmp_results = (void*)smpi_get_tmp_sendbuffer(total_count * std::max(true_extent, extent));
/* adjust for potential negative lower bound in datatype */
tmp_results = (void *)((char*)tmp_results - true_lb);
#ifndef SMPI_HOST_HPP_
#define SMPI_HOST_HPP_
-#include "src/include/smpi/smpi_utils.hpp"
+#include "smpi_utils.hpp"
#include "simgrid/s4u/Host.hpp"
#include <string>
void unserialize(void* contiguous_vector, void* noncontiguous_vector, int count, MPI_Op op);
};
-class Type_Vector: public Datatype{
- int block_count_;
- int block_length_;
- int block_stride_;
- MPI_Datatype old_type_;
-
-public:
- Type_Vector(int size, MPI_Aint lb, MPI_Aint ub, int flags, int count, int blocklen, int stride,
- MPI_Datatype old_type);
- ~Type_Vector();
- void serialize(void* noncontiguous, void* contiguous, int count);
- void unserialize(void* contiguous_vector, void* noncontiguous_vector, int count, MPI_Op op);
-};
-
class Type_Hvector: public Datatype{
int block_count_;
int block_length_;
void unserialize(void* contiguous_vector, void* noncontiguous_vector, int count, MPI_Op op);
};
-class Type_Indexed: public Datatype{
- int block_count_;
- int* block_lengths_;
- int* block_indices_;
- MPI_Datatype old_type_;
-
+class Type_Vector : public Type_Hvector {
public:
- Type_Indexed(int size, MPI_Aint lb, MPI_Aint ub, int flags, int block_count, int* block_lengths, int* block_indices,
- MPI_Datatype old_type);
- ~Type_Indexed();
- void serialize(void* noncontiguous, void* contiguous, int count);
- void unserialize(void* contiguous_vector, void* noncontiguous_vector, int count, MPI_Op op);
+ Type_Vector(int size, MPI_Aint lb, MPI_Aint ub, int flags, int count, int blocklen, int stride,
+ MPI_Datatype old_type);
};
class Type_Hindexed: public Datatype{
public:
Type_Hindexed(int size, MPI_Aint lb, MPI_Aint ub, int flags, int block_count, int* block_lengths,
MPI_Aint* block_indices, MPI_Datatype old_type);
+ Type_Hindexed(int size, MPI_Aint lb, MPI_Aint ub, int flags, int block_count, int* block_lengths, int* block_indices,
+ MPI_Datatype old_type, MPI_Aint factor);
~Type_Hindexed();
void serialize(void* noncontiguous, void* contiguous, int count);
void unserialize(void* contiguous_vector, void* noncontiguous_vector, int count, MPI_Op op);
};
+class Type_Indexed : public Type_Hindexed {
+public:
+ Type_Indexed(int size, MPI_Aint lb, MPI_Aint ub, int flags, int block_count, int* block_lengths, int* block_indices,
+ MPI_Datatype old_type);
+};
+
class Type_Struct: public Datatype{
int block_count_;
int* block_lengths_;
// Methods used to parse and store the values for timing injections in smpi
struct s_smpi_factor_t {
- size_t factor=0;
+ size_t factor = 0;
std::vector<double> values;
};
typedef s_smpi_factor_t* smpi_os_factor_t;
#include "SmpiHost.hpp"
#include "simgrid/s4u/VirtualMachine.hpp"
-#include "smpi/smpi_utils.hpp"
+#include "smpi_utils.hpp"
#include <string>
#include <vector>
"init", "0 1 0", "finalize", "0 1 0",
"put", "0.3 1 0", "get", "0 1 0.3", "accumulate", "1 0.3 0",
+ "rput", "0.3 1 0", "rget", "0 1 0.3", "raccumulate", "1 0.3 0",
+ "compare_and_swap", "0.3 1 0", "get_accumulate", "0 1 0.3", "rget_accumulate", "1 0.3 0",
"win_fence", "1 0 0.3", "win_post", "1 0 0.8", "win_wait", "1 0.8 0",
- "win_start", "0.8 0 1", "win_complete", "0.8 1 0", nullptr, nullptr,
+ "win_start", "0.8 0 1", "win_complete", "0.8 1 0", "win_lock", "1 0 0.3",
+ "win_unlock", "1 0 0.3", "win_lock_all", "1 0 0.8", "win_unlock_all", "1 0.8 0",
+ "win_flush", "1 0 0.3", "win_flush_local", "1 0 0.8", "win_flush_all", "1 0.8 0",
+ "win_flush_local_all", "1 0 0.3", "" , ""
};
static const char* instr_find_color(const char* state)
#include "private.hpp"
#include "simgrid/modelchecker.h"
#include "smpi_comm.hpp"
+#include "simgrid/host.h"
#include "smpi_process.hpp"
#include "src/internal_config.h"
#include "src/mc/mc_replay.hpp"
void smpi_execute_benched(double duration)
{
smpi_bench_end();
- smpi_execute(duration);
+ double speed = sg_host_speed(sg_host_self());
+ smpi_execute_flops(duration*speed);
smpi_bench_begin();
}
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 "
/* 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 "smpi/smpi_utils.hpp"
-#include "xbt/sysdep.h"
+#include "smpi_utils.hpp"
#include "xbt/log.h"
+#include "xbt/sysdep.h"
#include <boost/tokenizer.hpp>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_utils, smpi, "Logging specific to SMPI (utils)");
if (non_uniform_map_ != nullptr)
xbt_free(non_uniform_map_);
if (leaders_map_ != nullptr)
- xbt_free(leaders_map_);
+ delete[] leaders_map_;
}
void Comm::unref(Comm* comm){
MPI_Comm comm_intra = new Comm(group_intra, nullptr);
leader=min_index;
- int * leaders_map= static_cast<int*>(xbt_malloc0(sizeof(int)*comm_size));
- int * leader_list= static_cast<int*>(xbt_malloc0(sizeof(int)*comm_size));
- for(i=0; i<comm_size; i++){
- leader_list[i] = -1;
- }
+ int* leaders_map = new int[comm_size];
+ int* leader_list = new int[comm_size];
+ std::fill_n(leaders_map, comm_size, 0);
+ std::fill_n(leader_list, comm_size, -1);
Coll_allgather_mpich::allgather(&leader, 1, MPI_INT , leaders_map, 1, MPI_INT, this);
if(leaders_map_==nullptr){
leaders_map_= leaders_map;
}else{
- xbt_free(leaders_map);
+ delete[] leaders_map;
}
int j=0;
int leader_group_size = 0;
}else{
is_blocked_=global_blocked;
}
- xbt_free(leader_list);
+ delete[] leader_list;
if(replaying)
smpi_process()->set_replaying(true);
if (not smpi_process()->replaying())
memcpy(recvbuf, sendbuf, count);
} else if (not(sendtype->flags() & DT_FLAG_DERIVED)) {
- recvtype->unserialize( sendbuf, recvbuf, recvcount/recvtype->size(), MPI_REPLACE);
+ recvtype->unserialize(sendbuf, recvbuf, count / recvtype->size(), MPI_REPLACE);
} else if (not(recvtype->flags() & DT_FLAG_DERIVED)) {
- sendtype->serialize(sendbuf, recvbuf, sendcount/sendtype->size());
+ sendtype->serialize(sendbuf, recvbuf, count / sendtype->size());
}else{
void * buf_tmp = xbt_malloc(count);
op->apply( contiguous_buf_char, noncontiguous_buf_char, &n, old_type_);
}
-
-Type_Vector::Type_Vector(int size,MPI_Aint lb, MPI_Aint ub, int flags, int count, int block_length, int stride, MPI_Datatype old_type): Datatype(size, lb, ub, flags), block_count_(count), block_length_(block_length),block_stride_(stride), old_type_(old_type){
- old_type_->ref();
-}
-
-Type_Vector::~Type_Vector(){
- Datatype::unref(old_type_);
-}
-
-
-void Type_Vector::serialize( void* noncontiguous_buf, void *contiguous_buf,
- int count){
- char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
- char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf);
-
- for (int i = 0; i < block_count_ * count; i++) {
- if (not(old_type_->flags() & DT_FLAG_DERIVED))
- memcpy(contiguous_buf_char, noncontiguous_buf_char, block_length_ * old_type_->size());
- else
- old_type_->serialize(noncontiguous_buf_char, contiguous_buf_char, block_length_);
-
- contiguous_buf_char += block_length_*old_type_->size();
- if((i+1)%block_count_ ==0)
- noncontiguous_buf_char += block_length_*old_type_->get_extent();
- else
- noncontiguous_buf_char += block_stride_*old_type_->get_extent();
- }
-}
-
-void Type_Vector::unserialize( void* contiguous_buf, void *noncontiguous_buf,
- int count, MPI_Op op){
- char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
- char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf);
-
- for (int i = 0; i < block_count_ * count; i++) {
- if (not(old_type_->flags() & DT_FLAG_DERIVED)) {
- if(op != MPI_OP_NULL)
- op->apply(contiguous_buf_char, noncontiguous_buf_char, &block_length_,
- old_type_);
- }else
- old_type_->unserialize(contiguous_buf_char, noncontiguous_buf_char, block_length_, op);
-
- contiguous_buf_char += block_length_*old_type_->size();
- if((i+1)%block_count_ ==0)
- noncontiguous_buf_char += block_length_*old_type_->get_extent();
- else
- noncontiguous_buf_char += block_stride_*old_type_->get_extent();
- }
-}
-
Type_Hvector::Type_Hvector(int size,MPI_Aint lb, MPI_Aint ub, int flags, int count, int block_length, MPI_Aint stride, MPI_Datatype old_type): Datatype(size, lb, ub, flags), block_count_(count), block_length_(block_length), block_stride_(stride), old_type_(old_type){
old_type->ref();
}
}
}
-
void Type_Hvector::unserialize( void* contiguous_buf, void *noncontiguous_buf,
int count, MPI_Op op){
char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
}
}
-Type_Indexed::Type_Indexed(int size,MPI_Aint lb, MPI_Aint ub, int flags, int count, int* block_lengths, int* block_indices, MPI_Datatype old_type): Datatype(size, lb, ub, flags), block_count_(count), old_type_(old_type){
- old_type->ref();
- block_lengths_ = new int[count];
- block_indices_ = new int[count];
- for (int i = 0; i < count; i++) {
- block_lengths_[i]=block_lengths[i];
- block_indices_[i]=block_indices[i];
- }
-}
-
-Type_Indexed::~Type_Indexed(){
- Datatype::unref(old_type_);
- if(refcount()==0){
- delete[] block_lengths_;
- delete[] block_indices_;
- }
-}
-
-
-void Type_Indexed::serialize( void* noncontiguous_buf, void *contiguous_buf,
- int count){
- char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
- char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+block_indices_[0] * old_type_->size();
- for (int j = 0; j < count; j++) {
- for (int i = 0; i < block_count_; i++) {
- if (not(old_type_->flags() & DT_FLAG_DERIVED))
- memcpy(contiguous_buf_char, noncontiguous_buf_char, block_lengths_[i] * old_type_->size());
- else
- old_type_->serialize( noncontiguous_buf_char, contiguous_buf_char, block_lengths_[i]);
-
- contiguous_buf_char += block_lengths_[i]*old_type_->size();
- if (i<block_count_-1)
- noncontiguous_buf_char =
- static_cast<char*>(noncontiguous_buf) + block_indices_[i+1]*old_type_->get_extent();
- else
- noncontiguous_buf_char += block_lengths_[i]*old_type_->get_extent();
- }
- noncontiguous_buf=static_cast< void*>(noncontiguous_buf_char);
- }
+Type_Vector::Type_Vector(int size, MPI_Aint lb, MPI_Aint ub, int flags, int count, int block_length, int stride,
+ MPI_Datatype old_type)
+ : Type_Hvector(size, lb, ub, flags, count, block_length, stride * old_type->get_extent(), old_type)
+{
}
-
-void Type_Indexed::unserialize( void* contiguous_buf, void *noncontiguous_buf,
- int count, MPI_Op op){
- char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
- char* noncontiguous_buf_char =
- static_cast<char*>(noncontiguous_buf)+block_indices_[0]*old_type_->get_extent();
- for (int j = 0; j < count; j++) {
- for (int i = 0; i < block_count_; i++) {
- if (not(old_type_->flags() & DT_FLAG_DERIVED)) {
- if(op!=MPI_OP_NULL)
- op->apply( contiguous_buf_char, noncontiguous_buf_char, &block_lengths_[i],
- old_type_);
- }else
- old_type_->unserialize( contiguous_buf_char,noncontiguous_buf_char,block_lengths_[i], op);
-
- contiguous_buf_char += block_lengths_[i]*old_type_->size();
- if (i<block_count_-1)
- noncontiguous_buf_char =
- static_cast<char*>(noncontiguous_buf) + block_indices_[i+1]*old_type_->get_extent();
- else
- noncontiguous_buf_char += block_lengths_[i]*old_type_->get_extent();
- }
- noncontiguous_buf=static_cast<void*>(noncontiguous_buf_char);
+Type_Hindexed::Type_Hindexed(int size, MPI_Aint lb, MPI_Aint ub, int flags, int count, int* block_lengths,
+ MPI_Aint* block_indices, MPI_Datatype old_type)
+ : Datatype(size, lb, ub, flags), block_count_(count), old_type_(old_type)
+{
+ old_type_->ref();
+ block_lengths_ = new int[count];
+ block_indices_ = new MPI_Aint[count];
+ for (int i = 0; i < count; i++) {
+ block_lengths_[i] = block_lengths[i];
+ block_indices_[i] = block_indices[i];
}
}
-Type_Hindexed::Type_Hindexed(int size,MPI_Aint lb, MPI_Aint ub, int flags, int count, int* block_lengths, MPI_Aint* block_indices, MPI_Datatype old_type)
-: Datatype(size, lb, ub, flags), block_count_(count), old_type_(old_type)
+Type_Hindexed::Type_Hindexed(int size, MPI_Aint lb, MPI_Aint ub, int flags, int count, int* block_lengths,
+ int* block_indices, MPI_Datatype old_type, MPI_Aint factor)
+ : Datatype(size, lb, ub, flags), block_count_(count), old_type_(old_type)
{
old_type_->ref();
block_lengths_ = new int[count];
block_indices_ = new MPI_Aint[count];
for (int i = 0; i < count; i++) {
- block_lengths_[i]=block_lengths[i];
- block_indices_[i]=block_indices[i];
+ block_lengths_[i] = block_lengths[i];
+ block_indices_[i] = block_indices[i] * factor;
}
}
- Type_Hindexed::~Type_Hindexed(){
+Type_Hindexed::~Type_Hindexed()
+{
Datatype::unref(old_type_);
if(refcount()==0){
delete[] block_lengths_;
}
}
+Type_Indexed::Type_Indexed(int size, MPI_Aint lb, MPI_Aint ub, int flags, int count, int* block_lengths,
+ int* block_indices, MPI_Datatype old_type)
+ : Type_Hindexed(size, lb, ub, flags, count, block_lengths, block_indices, old_type, old_type->get_extent())
+{
+}
+
Type_Struct::Type_Struct(int size,MPI_Aint lb, MPI_Aint ub, int flags, int count, int* block_lengths, MPI_Aint* block_indices, MPI_Datatype* old_types): Datatype(size, lb, ub, flags), block_count_(count), block_lengths_(block_lengths), block_indices_(block_indices), old_types_(old_types){
block_lengths_= new int[count];
block_indices_= new MPI_Aint[count];
-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)
fi
shift 2
;;
- "-hostfile")
- HOSTFILE="$2"
- if [ ! -f "${HOSTFILE}" ]; then
- die "the file '${HOSTFILE}' does not exist"
- fi
- shift 2
- ;;
- "-machinefile")
+ "-hostfile" | "-machinefile")
HOSTFILE="$2"
if [ ! -f "${HOSTFILE}" ]; then
die "the file '${HOSTFILE}' does not exist"
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");
/* iterate for all virtual machines */
for (s4u::VirtualMachine* const& ws_vm : vm::VirtualMachineImpl::allVms_) {
Cpu* cpu = ws_vm->pimpl_cpu;
- int active_tasks = lmm_constraint_get_variable_amount(cpu->constraint());
+ int active_tasks = cpu->constraint()->get_variable_amount();
/* The impact of the VM over its PM is the min between its vCPU amount and the amount of tasks it contains */
int impact = std::min(active_tasks, ws_vm->pimpl_vm_->coreAmount());
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "StorageImpl.hpp"
-
+#include "surf/maxmin.hpp"
#include "surf_private.hpp"
-#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");
StorageModel::StorageModel() : Model()
{
- maxminSystem_ = lmm_system_new(true /* lazy update */);
+ maxminSystem_ = new s_lmm_system_t(true /* lazy update */);
}
StorageModel::~StorageModel()
{
- lmm_system_free(maxminSystem_);
+ delete maxminSystem_;
surf_storage_model = nullptr;
}
StorageImpl::StorageImpl(Model* model, std::string name, lmm_system_t maxminSystem, double bread, double bwrite,
std::string type_id, std::string content_name, sg_size_t size, std::string attach)
- : Resource(model, name.c_str(), lmm_constraint_new(maxminSystem, this, MAX(bread, bwrite)))
+ : Resource(model, name.c_str(), maxminSystem->constraint_new(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);
+ constraintRead_ = maxminSystem->constraint_new(this, bread);
+ constraintWrite_ = maxminSystem->constraint_new(this, bwrite);
storages->insert({name, this});
}
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 {
#include "cpu_cas01.hpp"
#include "cpu_ti.hpp"
-#include "maxmin_private.hpp"
#include "simgrid/sg_config.h"
+#include "surf/maxmin.hpp"
+#include <algorithm>
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_cpu_cas, surf_cpu, "Logging specific to the SURF CPU IMPROVED module");
}
p_cpuRunningActionSetThatDoesNotNeedBeingChecked = new ActionList();
- maxminSystem_ = lmm_system_new(selectiveUpdate_);
+ maxminSystem_ = new s_lmm_system_t(selectiveUpdate_);
if (getUpdateMechanism() == UM_LAZY) {
- actionHeap_ = xbt_heap_new(8, nullptr);
- xbt_heap_set_update_callback(actionHeap_, surf_action_lmm_update_index_heap);
modifiedSet_ = new ActionLmmList();
maxminSystem_->keep_track = modifiedSet_;
}
CpuCas01Model::~CpuCas01Model()
{
- lmm_system_free(maxminSystem_);
+ delete maxminSystem_;
maxminSystem_ = nullptr;
- xbt_heap_free(actionHeap_);
delete modifiedSet_;
surf_cpu_model_pm = nullptr;
/************
* Resource *
************/
-CpuCas01::CpuCas01(CpuCas01Model *model, simgrid::s4u::Host *host, std::vector<double> *speedPerPstate, int core)
-: Cpu(model, host, lmm_constraint_new(model->getMaxminSystem(), this, core * speedPerPstate->front()),
- speedPerPstate, core)
+CpuCas01::CpuCas01(CpuCas01Model* model, simgrid::s4u::Host* host, std::vector<double>* speedPerPstate, int core)
+ : Cpu(model, host, model->getMaxminSystem()->constraint_new(this, core * speedPerPstate->front()), speedPerPstate,
+ core)
{
}
bool CpuCas01::isUsed()
{
- return lmm_constraint_used(model()->getMaxminSystem(), constraint());
+ return model()->getMaxminSystem()->constraint_used(constraint());
}
/** @brief take into account changes of speed (either load or max) */
lmm_variable_t var = nullptr;
lmm_element_t elem = nullptr;
- lmm_update_constraint_bound(model()->getMaxminSystem(), constraint(), coresAmount_ * speed_.scale * speed_.peak);
- while ((var = lmm_get_var_from_cnst(model()->getMaxminSystem(), constraint(), &elem))) {
- CpuCas01Action* action = static_cast<CpuCas01Action*>(lmm_variable_id(var));
+ model()->getMaxminSystem()->update_constraint_bound(constraint(), coresAmount_ * speed_.scale * speed_.peak);
+ while ((var = constraint()->get_variable(&elem))) {
+ CpuCas01Action* action = static_cast<CpuCas01Action*>(var->get_id());
- lmm_update_variable_bound(model()->getMaxminSystem(), action->getVariable(),
- action->requestedCore() * speed_.scale * speed_.peak);
+ model()->getMaxminSystem()->update_variable_bound(action->getVariable(),
+ action->requestedCore() * speed_.scale * speed_.peak);
}
Cpu::onSpeedChange();
turnOff();
- while ((var = lmm_get_var_from_cnst(model()->getMaxminSystem(), cnst, &elem))) {
- Action *action = static_cast<Action*>(lmm_variable_id(var));
+ while ((var = cnst->get_variable(&elem))) {
+ Action* action = static_cast<Action*>(var->get_id());
if (action->getState() == Action::State::running ||
action->getState() == Action::State::ready ||
CpuAction *CpuCas01::sleep(double duration)
{
if (duration > 0)
- duration = MAX(duration, sg_surf_precision);
+ duration = std::max(duration, sg_surf_precision);
XBT_IN("(%s,%g)", getCname(), duration);
CpuCas01Action* action = new CpuCas01Action(model(), 1.0, isOff(), speed_.scale * speed_.peak, constraint());
action->getStateSet()->push_back(*action);
}
- lmm_update_variable_weight(model()->getMaxminSystem(), action->getVariable(), 0.0);
+ model()->getMaxminSystem()->update_variable_weight(action->getVariable(), 0.0);
if (model()->getUpdateMechanism() == UM_LAZY) { // remove action from the heap
action->heapRemove(model()->getActionHeap());
// this is necessary for a variable with weight 0 since such variables are ignored in lmm and we need to set its
CpuCas01Action::CpuCas01Action(Model* model, double cost, bool failed, double speed, lmm_constraint_t constraint,
int requestedCore)
: CpuAction(model, cost, failed,
- lmm_variable_new(model->getMaxminSystem(), this, 1.0 / requestedCore, requestedCore * speed, 1))
+ model->getMaxminSystem()->variable_new(this, 1.0 / requestedCore, requestedCore * speed, 1))
, requestedCore_(requestedCore)
{
if (model->getUpdateMechanism() == UM_LAZY) {
- updateIndexHeap(-1);
refreshLastUpdate();
setLastValue(0.0);
}
- lmm_expand(model->getMaxminSystem(), constraint, getVariable(), 1.0);
+ model->getMaxminSystem()->expand(constraint, getVariable(), 1.0);
}
CpuCas01Action::CpuCas01Action(Model* model, double cost, bool failed, double speed, lmm_constraint_t constraint)
void CpuModel::updateActionsStateLazy(double now, double /*delta*/)
{
- while ((xbt_heap_size(getActionHeap()) > 0)
- && (double_equals(xbt_heap_maxkey(getActionHeap()), now, sg_surf_precision))) {
+ while (not actionHeapIsEmpty() && double_equals(actionHeapTopDate(), now, sg_surf_precision)) {
- CpuAction *action = static_cast<CpuAction*>(xbt_heap_pop(getActionHeap()));
+ CpuAction* action = static_cast<CpuAction*>(actionHeapPop());
XBT_CDEBUG(surf_kernel, "Something happened to action %p", action);
if (TRACE_is_enabled()) {
- 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()), action->getLastUpdate(),
- now - action->getLastUpdate());
+ Cpu* cpu = static_cast<Cpu*>(action->getVariable()->get_constraint(0)->get_id());
+ TRACE_surf_host_set_utilization(cpu->getCname(), action->getCategory(), action->getVariable()->get_value(),
+ action->getLastUpdate(), now - action->getLastUpdate());
}
action->finish(Action::State::done);
//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)) );
-
- TRACE_surf_host_set_utilization(cpu->getCname(), action->getCategory(),
- lmm_variable_getvalue(action->getVariable()), now - delta, delta);
+ Cpu* cpu = static_cast<Cpu*>(action.getVariable()->get_constraint(0)->get_id());
+ TRACE_surf_host_set_utilization(cpu->getCname(), action.getCategory(), action.getVariable()->get_value(),
+ now - delta, delta);
TRACE_last_timestamp_to_dump = now - delta;
}
- action->updateRemains(lmm_variable_getvalue(action->getVariable()) * delta);
+ action.updateRemains(action.getVariable()->get_value() * 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) && (action.getVariable()->get_weight() > 0)) ||
+ ((action.getMaxDuration() != NO_MAX_DURATION) && (action.getMaxDuration() <= 0))) {
+ action.finish(Action::State::done);
}
}
}
updateRemains(getLastValue() * delta);
if (TRACE_is_enabled()) {
- Cpu *cpu = static_cast<Cpu*>(lmm_constraint_id(lmm_get_cnst_from_var(getModel()->getMaxminSystem(), getVariable(), 0)));
+ Cpu* cpu = static_cast<Cpu*>(getVariable()->get_constraint(0)->get_id());
TRACE_surf_host_set_utilization(cpu->getCname(), getCategory(), getLastValue(), getLastUpdate(),
now - getLastUpdate());
}
}
refreshLastUpdate();
- setLastValue(lmm_variable_getvalue(getVariable()));
+ setLastValue(getVariable()->get_value());
}
simgrid::xbt::signal<void(simgrid::surf::CpuAction*, Action::State)> CpuAction::onStateChange;
/** @brief returns a list of all CPUs that this action is using */
std::list<Cpu*> CpuAction::cpus() {
std::list<Cpu*> retlist;
- lmm_system_t sys = getModel()->getMaxminSystem();
- int llen = lmm_get_number_of_cnst_from_var(sys, getVariable());
+ int llen = getVariable()->get_number_of_constraint();
for (int i = 0; i < llen; i++) {
/* Beware of composite actions: ptasks put links and cpus together */
// extra pb: we cannot dynamic_cast from void*...
- Resource* resource = static_cast<Resource*>(lmm_constraint_id(lmm_get_cnst_from_var(sys, getVariable(), i)));
+ Resource* resource = static_cast<Resource*>(getVariable()->get_constraint(i)->get_id());
Cpu* cpu = dynamic_cast<Cpu*>(resource);
if (cpu != nullptr)
retlist.push_back(cpu);
#define SURF_CPU_INTERFACE_HPP_
#include "simgrid/s4u/Host.hpp"
-#include "src/surf/maxmin_private.hpp"
+#include "surf/maxmin.hpp"
#include <list>
* under the terms of the license (GNU LGPL) which comes with this package. */
#include "cpu_ti.hpp"
-#include "xbt/heap.h"
#include "src/surf/trace_mgr.hpp"
+#include <algorithm>
#ifndef SURF_MODEL_CPUTI_H_
#define SURF_MODEL_CPUTI_H_
namespace simgrid {
namespace surf {
-static inline
-void cpu_ti_action_update_index_heap(void *action, int i)
-{
- (static_cast<simgrid::surf::CpuTiAction*>(action))->updateIndexHeap(i);
-}
-
/*********
* Trace *
*********/
runningActionSetThatDoesNotNeedBeingChecked_ = new ActionList();
modifiedCpu_ = new CpuTiList();
-
- tiActionHeap_ = xbt_heap_new(8, nullptr);
- xbt_heap_set_update_callback(tiActionHeap_, cpu_ti_action_update_index_heap);
}
CpuTiModel::~CpuTiModel()
surf_cpu_model_pm = nullptr;
delete runningActionSetThatDoesNotNeedBeingChecked_;
delete modifiedCpu_;
- xbt_heap_free(tiActionHeap_);
}
Cpu *CpuTiModel::createCpu(simgrid::s4u::Host *host, std::vector<double>* speedPerPstate, int core)
{
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 */
- if (xbt_heap_size(tiActionHeap_) > 0)
- min_action_duration = xbt_heap_maxkey(tiActionHeap_) - now;
+ /* get the min next event if heap not empty */
+ if (not actionHeapIsEmpty())
+ min_action_duration = actionHeapTopDate() - now;
XBT_DEBUG("Share resources, min next event date: %f", min_action_duration);
void CpuTiModel::updateActionsState(double now, double /*delta*/)
{
- while ((xbt_heap_size(tiActionHeap_) > 0) && (xbt_heap_maxkey(tiActionHeap_) <= now)) {
- CpuTiAction *action = static_cast<CpuTiAction*>(xbt_heap_pop(tiActionHeap_));
+ while (not actionHeapIsEmpty() && actionHeapTopDate() <= now) {
+ CpuTiAction* action = static_cast<CpuTiAction*>(actionHeapPop());
XBT_DEBUG("Action %p: finish", action);
action->finish(Action::State::done);
/* set the remains to 0 due to precision problems when updating the remaining amount */
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);
- if (action->getIndexHeap() >= 0) {
- CpuTiAction* heap_act = static_cast<CpuTiAction*>(
- xbt_heap_remove(static_cast<CpuTiModel*>(model())->tiActionHeap_, action->getIndexHeap()));
- if (heap_act != action)
- DIE_IMPOSSIBLE;
- }
+ 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 */
- XBT_DEBUG("action(%p) index %d", action, action->getIndexHeap());
- if (action->getIndexHeap() >= 0) {
- CpuTiAction* heap_act = static_cast<CpuTiAction*>(
- xbt_heap_remove(static_cast<CpuTiModel*>(model())->tiActionHeap_, action->getIndexHeap()));
- if (heap_act != action)
- DIE_IMPOSSIBLE;
- }
if (min_finish > NO_MAX_DURATION)
- xbt_heap_push(static_cast<CpuTiModel*>(model())->tiActionHeap_, action, min_finish);
+ action.heapUpdate(model()->getActionHeap(), min_finish, NOTSET);
+ else
+ 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;
}
CpuAction *CpuTi::sleep(double duration)
{
if (duration > 0)
- duration = MAX(duration, sg_surf_precision);
+ duration = std::max(duration, sg_surf_precision);
XBT_IN("(%s,%g)", getCname(), duration);
CpuTiAction* action = new CpuTiAction(static_cast<CpuTiModel*>(model()), 1.0, isOff(), this);
: CpuAction(model_, cost, failed)
, cpu_(cpu)
{
- updateIndexHeap(-1);
cpu_->modified(true);
}
if (action_ti_hook.is_linked())
cpu_->actionSet_->erase(cpu_->actionSet_->iterator_to(*this));
/* remove from heap */
- xbt_heap_remove(static_cast<CpuTiModel*>(getModel())->tiActionHeap_, getIndexHeap());
+ heapRemove(getModel()->getActionHeap());
cpu_->modified(true);
delete this;
return 1;
void CpuTiAction::cancel()
{
this->setState(Action::State::failed);
- xbt_heap_remove(getModel()->getActionHeap(), getIndexHeap());
+ heapRemove(getModel()->getActionHeap());
cpu_->modified(true);
}
XBT_IN("(%p)", this);
if (suspended_ != 2) {
suspended_ = 1;
- xbt_heap_remove(getModel()->getActionHeap(), getIndexHeap());
+ heapRemove(getModel()->getActionHeap());
cpu_->modified(true);
}
XBT_OUT();
else
min_finish = getFinishTime();
-/* add in action heap */
- if (getIndexHeap() >= 0) {
- CpuTiAction* heap_act = static_cast<CpuTiAction*>(xbt_heap_remove(getModel()->getActionHeap(), getIndexHeap()));
- if (heap_act != this)
- DIE_IMPOSSIBLE;
- }
- xbt_heap_push(getModel()->getActionHeap(), this, min_finish);
+ /* add in action heap */
+ heapUpdate(getModel()->getActionHeap(), min_finish, NOTSET);
XBT_OUT();
}
-/* Copyright (c) 2013-2015. The SimGrid Team.
+/* Copyright (c) 2013-2017. The SimGrid Team.
* All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
ActionList *runningActionSetThatDoesNotNeedBeingChecked_;
CpuTiList *modifiedCpu_;
- xbt_heap_t tiActionHeap_;
};
}
+++ /dev/null
-/* Copyright (c) 2004-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. */
-
-/* \file callbacks.h */
-
-#include "maxmin_private.hpp"
-#include "xbt/log.h"
-#include "xbt/mallocator.h"
-#include "xbt/sysdep.h"
-#include <cmath>
-#include <cstdlib>
-#include <cxxabi.h>
-#include <limits>
-
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_maxmin, surf, "Logging specific to SURF (maxmin)");
-
-struct s_dyn_light_t {
- int *data;
- int pos;
- int size;
-};
-typedef s_dyn_light_t* dyn_light_t;
-
-double sg_maxmin_precision = 0.00001; /* Change this with --cfg=maxmin/precision:VALUE */
-double sg_surf_precision = 0.00001; /* Change this with --cfg=surf/precision:VALUE */
-int sg_concurrency_limit = -1; /* Change this with --cfg=maxmin/concurrency-limit:VALUE */
-
-static void *lmm_variable_mallocator_new_f();
-static void lmm_variable_mallocator_free_f(void *var);
-#define lmm_variable_mallocator_reset_f ((void_f_pvoid_t)nullptr)
-static void lmm_update_modified_set(lmm_system_t sys, lmm_constraint_t cnst);
-static void lmm_remove_all_modified_set(lmm_system_t sys);
-static int Global_debug_id = 1;
-static int Global_const_debug_id = 1;
-
-static inline void lmm_cnst_free(lmm_system_t sys, lmm_constraint_t cnst);
-
-static void lmm_on_disabled_var(lmm_system_t sys, lmm_constraint_t cnstr);
-static void lmm_enable_var(lmm_system_t sys, lmm_variable_t var);
-static int lmm_can_enable_var(lmm_variable_t var);
-static void lmm_disable_var(lmm_system_t sys, lmm_variable_t var);
-static int lmm_concurrency_slack(lmm_constraint_t cnstr);
-static int lmm_cnstrs_min_concurrency_slack(lmm_variable_t var);
-
-inline int lmm_element_concurrency(lmm_element_t elem) {
- //Ignore element with weight less than one (e.g. cross-traffic)
- return (elem->consumption_weight >= 1) ? 1 : 0;
- //There are other alternatives, but they will change the behaviour of the model..
- //So do not use it unless you want to make a new model.
- //If you do, remember to change the variables concurrency share to reflect it.
- //Potential examples are:
- //return (elem->weight>0)?1:0;//Include element as soon as weight is non-zero
- //return (int)ceil(elem->weight);//Include element as the rounded-up integer value of the element weight
-}
-
-inline void lmm_decrease_concurrency(lmm_element_t elem) {
- xbt_assert(elem->constraint->concurrency_current>=lmm_element_concurrency(elem));
- elem->constraint->concurrency_current-=lmm_element_concurrency(elem);
-}
-
-inline void lmm_increase_concurrency(lmm_element_t elem) {
- elem->constraint->concurrency_current+= lmm_element_concurrency(elem);
-
- lmm_constraint_t cnstr=elem->constraint;
-
- if(cnstr->concurrency_current > cnstr->concurrency_maximum)
- cnstr->concurrency_maximum= cnstr->concurrency_current;
-
- xbt_assert(cnstr->concurrency_limit<0 || cnstr->concurrency_current<=cnstr->concurrency_limit,
- "Concurrency limit overflow!");
-}
-
-static void lmm_check_concurrency(lmm_system_t sys)
-{
- // These checks are very expensive, so do them only if we want to debug SURF LMM
- if (not XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug))
- return;
-
- void* cnstIt;
- xbt_swag_foreach(cnstIt, &(sys->constraint_set))
- {
- lmm_constraint_t cnst = (lmm_constraint_t)cnstIt;
- int concurrency = 0;
- void* elemIt;
- xbt_swag_foreach(elemIt, &(cnst->enabled_element_set))
- {
- lmm_element_t elem = (lmm_element_t)elemIt;
- xbt_assert(elem->variable->sharing_weight > 0);
- concurrency += lmm_element_concurrency(elem);
- }
-
- xbt_swag_foreach(elemIt, &(cnst->disabled_element_set))
- {
- lmm_element_t elem = (lmm_element_t)elemIt;
- // We should have staged variables only if concurrency is reached in some constraint
- xbt_assert(cnst->concurrency_limit < 0 || elem->variable->staged_weight == 0 ||
- lmm_cnstrs_min_concurrency_slack(elem->variable) < elem->variable->concurrency_share,
- "should not have staged variable!");
- }
-
- xbt_assert(cnst->concurrency_limit < 0 || cnst->concurrency_limit >= concurrency, "concurrency check failed!");
- xbt_assert(cnst->concurrency_current == concurrency, "concurrency_current is out-of-date!");
- }
-
- // Check that for each variable, all corresponding elements are in the same state (i.e. same element sets)
- void* varIt;
- xbt_swag_foreach(varIt, &(sys->variable_set))
- {
- lmm_variable_t var = (lmm_variable_t)varIt;
-
- if (not var->cnsts_number)
- continue;
-
- lmm_element_t elem = &var->cnsts[0];
- int belong_to_enabled = xbt_swag_belongs(elem, &(elem->constraint->enabled_element_set));
- int belong_to_disabled = xbt_swag_belongs(elem, &(elem->constraint->disabled_element_set));
- int belong_to_active = xbt_swag_belongs(elem, &(elem->constraint->active_element_set));
-
- for (int i = 1; i < var->cnsts_number; i++) {
- elem = &var->cnsts[i];
- xbt_assert(belong_to_enabled == xbt_swag_belongs(elem, &(elem->constraint->enabled_element_set)),
- "Variable inconsistency (1): enabled_element_set");
- xbt_assert(belong_to_disabled == xbt_swag_belongs(elem, &(elem->constraint->disabled_element_set)),
- "Variable inconsistency (2): disabled_element_set");
- xbt_assert(belong_to_active == xbt_swag_belongs(elem, &(elem->constraint->active_element_set)),
- "Variable inconsistency (3): active_element_set");
- }
- }
-}
-
-static inline void lmm_variable_remove(lmm_system_t sys, lmm_variable_t var)
-{
- XBT_IN("(sys=%p, var=%p)", sys, var);
- sys->modified = 1;
-
- // TODOLATER Can do better than that by leaving only the variable in only one enabled_element_set, call
- // lmm_update_modified_set, and then remove it..
- if (var->cnsts_number)
- lmm_update_modified_set(sys, var->cnsts[0].constraint);
-
- for (int i = 0; i < var->cnsts_number; i++) {
- lmm_element_t elem = &var->cnsts[i];
- if (var->sharing_weight > 0)
- lmm_decrease_concurrency(elem);
- xbt_swag_remove(elem, &(elem->constraint->enabled_element_set));
- xbt_swag_remove(elem, &(elem->constraint->disabled_element_set));
- xbt_swag_remove(elem, &(elem->constraint->active_element_set));
- int nelements = xbt_swag_size(&(elem->constraint->enabled_element_set)) +
- xbt_swag_size(&(elem->constraint->disabled_element_set));
- if (nelements == 0)
- make_constraint_inactive(sys, elem->constraint);
- else
- 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 he first disabled variables get priority over those with smaller requirement
- for (int i = 0; i < var->cnsts_number; i++) {
- lmm_element_t elem = &var->cnsts[i];
- if (xbt_swag_size(&(elem->constraint->disabled_element_set)))
- lmm_on_disabled_var(sys, elem->constraint);
- }
-
- var->cnsts_number = 0;
-
- lmm_check_concurrency(sys);
-
- XBT_OUT();
-}
-
-static void lmm_var_free(lmm_system_t sys, lmm_variable_t var)
-{
- lmm_variable_remove(sys, var);
- xbt_mallocator_release(sys->variable_mallocator, var);
-}
-
-lmm_system_t lmm_system_new(bool selective_update)
-{
- s_lmm_variable_t var;
- s_lmm_constraint_t cnst;
-
- lmm_system_t l = xbt_new0(s_lmm_system_t, 1);
-
- l->modified = 0;
- l->selective_update_active = selective_update;
- l->visited_counter = 1;
-
- XBT_DEBUG("Setting selective_update_active flag to %d", l->selective_update_active);
-
- xbt_swag_init(&(l->variable_set), xbt_swag_offset(var, variable_set_hookup));
- xbt_swag_init(&(l->constraint_set), xbt_swag_offset(cnst, constraint_set_hookup));
-
- xbt_swag_init(&(l->active_constraint_set), xbt_swag_offset(cnst, active_constraint_set_hookup));
-
- xbt_swag_init(&(l->modified_constraint_set), xbt_swag_offset(cnst, modified_constraint_set_hookup));
- xbt_swag_init(&(l->saturated_variable_set), xbt_swag_offset(var, saturated_variable_set_hookup));
- xbt_swag_init(&(l->saturated_constraint_set), xbt_swag_offset(cnst, saturated_constraint_set_hookup));
-
- l->variable_mallocator = xbt_mallocator_new(65536,
- lmm_variable_mallocator_new_f,
- lmm_variable_mallocator_free_f,
- lmm_variable_mallocator_reset_f);
-
- l->solve_fun = &lmm_solve;
-
- return l;
-}
-
-void lmm_system_free(lmm_system_t sys)
-{
- lmm_variable_t var = nullptr;
- lmm_constraint_t cnst = nullptr;
-
- if (sys == nullptr)
- return;
-
- while ((var = (lmm_variable_t) extract_variable(sys))) {
- int status;
- char* demangled = abi::__cxa_demangle(typeid(*var->id).name(), 0, 0, &status);
-
- XBT_WARN("Probable bug: a %s variable (#%d) not removed before the LMM system destruction.", demangled,
- var->id_int);
- xbt_free(demangled);
- lmm_var_free(sys, var);
- }
- while ((cnst = (lmm_constraint_t) extract_constraint(sys)))
- lmm_cnst_free(sys, cnst);
-
- xbt_mallocator_free(sys->variable_mallocator);
- free(sys);
-}
-
-static inline void lmm_cnst_free(lmm_system_t sys, lmm_constraint_t cnst)
-{
- make_constraint_inactive(sys, cnst);
- free(cnst);
-}
-
-lmm_constraint_t lmm_constraint_new(lmm_system_t sys, void *id, double bound_value)
-{
- lmm_constraint_t cnst = nullptr;
- s_lmm_element_t elem;
-
- cnst = xbt_new0(s_lmm_constraint_t, 1);
- cnst->id = id;
- cnst->id_int = Global_const_debug_id++;
- xbt_swag_init(&(cnst->enabled_element_set), xbt_swag_offset(elem, enabled_element_set_hookup));
- xbt_swag_init(&(cnst->disabled_element_set), xbt_swag_offset(elem, disabled_element_set_hookup));
- xbt_swag_init(&(cnst->active_element_set), xbt_swag_offset(elem, active_element_set_hookup));
-
- cnst->bound = bound_value;
- cnst->concurrency_maximum=0;
- cnst->concurrency_current=0;
- cnst->concurrency_limit = sg_concurrency_limit;
- cnst->usage = 0;
- cnst->sharing_policy = 1; /* FIXME: don't hardcode the value */
- insert_constraint(sys, cnst);
-
- return cnst;
-}
-
-int lmm_constraint_concurrency_limit_get(lmm_constraint_t cnst)
-{
- return cnst->concurrency_limit;
-}
-
-void lmm_constraint_concurrency_limit_set(lmm_constraint_t cnst, int concurrency_limit)
-{
- xbt_assert(concurrency_limit<0 || cnst->concurrency_maximum<=concurrency_limit,
- "New concurrency limit should be larger than observed concurrency maximum. Maybe you want to call"
- " lmm_constraint_concurrency_maximum_reset() to reset the maximum?");
- cnst->concurrency_limit = concurrency_limit;
-}
-
-void lmm_constraint_concurrency_maximum_reset(lmm_constraint_t cnst)
-{
- cnst->concurrency_maximum = 0;
-}
-
-int lmm_constraint_concurrency_maximum_get(lmm_constraint_t cnst)
-{
- xbt_assert(cnst->concurrency_limit<0 || cnst->concurrency_maximum<=cnst->concurrency_limit,
- "Very bad: maximum observed concurrency is higher than limit. This is a bug of SURF, please report it.");
- return cnst->concurrency_maximum;
-}
-
-void lmm_constraint_shared(lmm_constraint_t cnst)
-{
- cnst->sharing_policy = 0;
-}
-
-/** Return true if the constraint is shared, and false if it's FATPIPE */
-int lmm_constraint_sharing_policy(lmm_constraint_t cnst)
-{
- return (cnst->sharing_policy);
-}
-
-/* @brief Remove a constraint
- * Currently this is dead code, but it is exposed in maxmin.hpp
- * Apparently, this call was designed assuming that constraint would no more have elements in it.
- * If not the case, assertion will fail, and you need to add calls e.g. to lmm_shrink before effectively removing it.
- */
-inline void lmm_constraint_free(lmm_system_t sys,lmm_constraint_t cnst)
-{
- xbt_assert(not xbt_swag_size(&(cnst->active_element_set)), "Removing constraint but it still has active elements");
- xbt_assert(not xbt_swag_size(&(cnst->enabled_element_set)), "Removing constraint but it still has enabled elements");
- xbt_assert(not xbt_swag_size(&(cnst->disabled_element_set)),
- "Removing constraint but it still has disabled elements");
- remove_constraint(sys, cnst);
- lmm_cnst_free(sys, cnst);
-}
-
-static void *lmm_variable_mallocator_new_f()
-{
- lmm_variable_t var = xbt_new(s_lmm_variable_t, 1);
- var->cnsts = nullptr; /* will be created by realloc */
- return var;
-}
-
-static void lmm_variable_mallocator_free_f(void *var)
-{
- xbt_free(((lmm_variable_t) var)->cnsts);
- xbt_free(var);
-}
-
-lmm_variable_t lmm_variable_new(lmm_system_t sys, simgrid::surf::Action* id, double sharing_weight, double bound,
- int number_of_constraints)
-{
- XBT_IN("(sys=%p, id=%p, weight=%f, bound=%f, num_cons =%d)", sys, id, sharing_weight, bound, number_of_constraints);
-
- lmm_variable_t var = (lmm_variable_t)xbt_mallocator_get(sys->variable_mallocator);
- var->id = id;
- var->id_int = Global_debug_id++;
- var->cnsts = static_cast<s_lmm_element_t*>(xbt_realloc(var->cnsts, number_of_constraints * sizeof(s_lmm_element_t)));
- for (int i = 0; i < number_of_constraints; i++) {
- var->cnsts[i].enabled_element_set_hookup.next = nullptr;
- var->cnsts[i].enabled_element_set_hookup.prev = nullptr;
- var->cnsts[i].disabled_element_set_hookup.next = nullptr;
- var->cnsts[i].disabled_element_set_hookup.prev = nullptr;
- var->cnsts[i].active_element_set_hookup.next = nullptr;
- var->cnsts[i].active_element_set_hookup.prev = nullptr;
- var->cnsts[i].constraint = nullptr;
- var->cnsts[i].variable = nullptr;
- var->cnsts[i].consumption_weight = 0.0;
- }
- var->cnsts_size = number_of_constraints;
- var->cnsts_number = 0;
- var->sharing_weight = sharing_weight;
- var->staged_weight = 0.0;
- var->bound = bound;
- var->concurrency_share = 1;
- var->value = 0.0;
- var->visited = sys->visited_counter - 1;
- var->mu = 0.0;
- var->new_mu = 0.0;
- var->func_f = func_f_def;
- var->func_fp = func_fp_def;
- var->func_fpi = func_fpi_def;
-
- var->variable_set_hookup.next = nullptr;
- var->variable_set_hookup.prev = nullptr;
- var->saturated_variable_set_hookup.next = nullptr;
- var->saturated_variable_set_hookup.prev = nullptr;
-
- if (sharing_weight)
- xbt_swag_insert_at_head(var, &(sys->variable_set));
- else
- xbt_swag_insert_at_tail(var, &(sys->variable_set));
-
- XBT_OUT(" returns %p", var);
- return var;
-}
-
-void lmm_variable_free(lmm_system_t sys, lmm_variable_t var)
-{
- remove_variable(sys, var);
- lmm_var_free(sys, var);
-}
-
-double lmm_variable_getvalue(lmm_variable_t var)
-{
- return (var->value);
-}
-
-void lmm_variable_concurrency_share_set(lmm_variable_t var, short int concurrency_share)
-{
- var->concurrency_share=concurrency_share;
-}
-
-double lmm_variable_getbound(lmm_variable_t var)
-{
- return (var->bound);
-}
-
-void lmm_shrink(lmm_system_t sys, lmm_constraint_t cnst, lmm_variable_t var)
-{
- lmm_element_t elem = nullptr;
- int found = 0;
-
- for (int i = 0; i < var->cnsts_number; i++) {
- elem = &(var->cnsts[i]);
- if (elem->constraint == cnst) {
- found = 1;
- break;
- }
- }
-
- if (not found) {
- XBT_DEBUG("cnst %p is not found in var %p", cnst, var);
- return;
- }
-
- sys->modified = 1;
-
- XBT_DEBUG("remove elem(value %f, cnst %p, var %p) in var %p", elem->consumption_weight, elem->constraint,
- elem->variable, var);
-
- /* We are going to change the constraint object and the variable object.
- * Propagate this change to other objects. Calling here before removing variable from not active elements
- * (inactive elements are not visited)
- */
- lmm_update_modified_set(sys, cnst);
- //Useful in case var was already removed from the constraint
- lmm_update_modified_set(sys, var->cnsts[0].constraint); // will look up enabled_element_set of this constraint, and
- //then each var in the enabled_element_set, and each var->cnsts[i].
-
- if(xbt_swag_remove(elem, &(elem->constraint->enabled_element_set)))
- lmm_decrease_concurrency(elem);
-
- xbt_swag_remove(elem, &(elem->constraint->active_element_set));
- elem->constraint = nullptr;
- elem->variable = nullptr;
- elem->consumption_weight = 0;
-
- var->cnsts_number -= 1;
-
- //No variable in this constraint -> make it inactive
- if (xbt_swag_size(&(cnst->enabled_element_set))+xbt_swag_size(&(cnst->disabled_element_set)) == 0)
- make_constraint_inactive(sys, cnst);
- else {
- //Check maxconcurrency to see if we can enable new variables
- lmm_on_disabled_var(sys,elem->constraint);
- }
-
- lmm_check_concurrency(sys);
-}
-
-void lmm_expand(lmm_system_t sys, lmm_constraint_t cnst, lmm_variable_t var, double consumption_weight)
-{
- sys->modified = 1;
-
- //Check if this variable already has an active element in this constraint
- //If it does, substract it from the required slack
- int current_share = 0;
- if(var->concurrency_share>1){
- for (int i = 0; i < var->cnsts_number; i++) {
- if(var->cnsts[i].constraint==cnst &&
- xbt_swag_belongs(&var->cnsts[i],&(var->cnsts[i].constraint->enabled_element_set)))
- current_share+=lmm_element_concurrency(&(var->cnsts[i]));
- }
- }
-
- //Check if we need to disable the variable
- if (var->sharing_weight > 0 && var->concurrency_share - current_share > lmm_concurrency_slack(cnst)) {
- double weight = var->sharing_weight;
- lmm_disable_var(sys,var);
- for (int i = 0; i < var->cnsts_number; i++)
- lmm_on_disabled_var(sys,var->cnsts[i].constraint);
- consumption_weight = 0;
- var->staged_weight=weight;
- xbt_assert(not var->sharing_weight);
- }
-
- xbt_assert(var->cnsts_number < var->cnsts_size, "Too much constraints");
-
- lmm_element_t elem = &(var->cnsts[var->cnsts_number++]);
-
- elem->consumption_weight = consumption_weight;
- elem->constraint = cnst;
- elem->variable = var;
-
- if (var->sharing_weight) {
- xbt_swag_insert_at_head(elem, &(elem->constraint->enabled_element_set));
- lmm_increase_concurrency(elem);
- } else
- xbt_swag_insert_at_tail(elem, &(elem->constraint->disabled_element_set));
-
- if (not sys->selective_update_active) {
- make_constraint_active(sys, cnst);
- } else if (elem->consumption_weight > 0 || var->sharing_weight > 0) {
- make_constraint_active(sys, cnst);
- lmm_update_modified_set(sys, cnst);
- //TODOLATER: Why do we need this second call?
- if (var->cnsts_number > 1)
- lmm_update_modified_set(sys, var->cnsts[0].constraint);
- }
-
- lmm_check_concurrency(sys);
-}
-
-void lmm_expand_add(lmm_system_t sys, lmm_constraint_t cnst, lmm_variable_t var, double value)
-{
- int i;
- sys->modified = 1;
-
- lmm_check_concurrency(sys);
-
- //BEWARE: In case you have multiple elements in one constraint, this will always add value to the first element.
- for (i = 0; i < var->cnsts_number; i++)
- if (var->cnsts[i].constraint == cnst)
- break;
-
- if (i < var->cnsts_number) {
- if (var->sharing_weight)
- lmm_decrease_concurrency(&var->cnsts[i]);
-
- if (cnst->sharing_policy)
- var->cnsts[i].consumption_weight += value;
- else
- var->cnsts[i].consumption_weight = MAX(var->cnsts[i].consumption_weight, value);
-
- //We need to check that increasing value of the element does not cross the concurrency limit
- if (var->sharing_weight) {
- if(lmm_concurrency_slack(cnst)<lmm_element_concurrency(&var->cnsts[i])){
- double weight = var->sharing_weight;
- lmm_disable_var(sys,var);
- for (int j = 0; j < var->cnsts_number; j++)
- lmm_on_disabled_var(sys,var->cnsts[j].constraint);
- var->staged_weight=weight;
- xbt_assert(not var->sharing_weight);
- }
- lmm_increase_concurrency(&var->cnsts[i]);
- }
- lmm_update_modified_set(sys, cnst);
- } else
- lmm_expand(sys, cnst, var, value);
-
- lmm_check_concurrency(sys);
-}
-
-lmm_constraint_t lmm_get_cnst_from_var(lmm_system_t /*sys*/, lmm_variable_t var, int num)
-{
- if (num < var->cnsts_number)
- return (var->cnsts[num].constraint);
- else
- return nullptr;
-}
-
-double lmm_get_cnst_weight_from_var(lmm_system_t /*sys*/, lmm_variable_t var, int num)
-{
- if (num < var->cnsts_number)
- return (var->cnsts[num].consumption_weight);
- else
- return 0.0;
-}
-
-int lmm_get_number_of_cnst_from_var(lmm_system_t /*sys*/, lmm_variable_t var)
-{
- return (var->cnsts_number);
-}
-
-lmm_variable_t lmm_get_var_from_cnst(lmm_system_t /*sys*/, lmm_constraint_t cnst, lmm_element_t * elem)
-{
- if (*elem == nullptr) {
- // That is the first call, pick the first element among enabled_element_set (or disabled_element_set if
- // enabled_element_set is empty)
- *elem = (lmm_element_t) xbt_swag_getFirst(&(cnst->enabled_element_set));
- if (*elem == nullptr)
- *elem = (lmm_element_t) xbt_swag_getFirst(&(cnst->disabled_element_set));
- } else {
- //elem is not null, so we carry on
- if(xbt_swag_belongs(*elem,&(cnst->enabled_element_set))){
- //Look at enabled_element_set, and jump to disabled_element_set when finished
- *elem = (lmm_element_t) xbt_swag_getNext(*elem, cnst->enabled_element_set.offset);
- if (*elem == nullptr)
- *elem = (lmm_element_t) xbt_swag_getFirst(&(cnst->disabled_element_set));
- } else {
- *elem = (lmm_element_t) xbt_swag_getNext(*elem, cnst->disabled_element_set.offset);
- }
- }
- if (*elem)
- return (*elem)->variable;
- else
- return nullptr;
-}
-
-//if we modify the swag between calls, normal version may loop forever
-//this safe version ensures that we browse the swag elements only once
-lmm_variable_t lmm_get_var_from_cnst_safe(lmm_system_t /*sys*/, lmm_constraint_t cnst, lmm_element_t * elem,
- lmm_element_t * nextelem, int * numelem)
-{
- if (*elem == nullptr) {
- *elem = (lmm_element_t) xbt_swag_getFirst(&(cnst->enabled_element_set));
- *numelem = xbt_swag_size(&(cnst->enabled_element_set))+xbt_swag_size(&(cnst->disabled_element_set))-1;
- if (*elem == nullptr)
- *elem = (lmm_element_t) xbt_swag_getFirst(&(cnst->disabled_element_set));
- }else{
- *elem = *nextelem;
- if(*numelem>0){
- (*numelem) --;
- }else
- return nullptr;
- }
- if (*elem){
- //elem is not null, so we carry on
- if(xbt_swag_belongs(*elem,&(cnst->enabled_element_set))){
- //Look at enabled_element_set, and jump to disabled_element_set when finished
- *nextelem = (lmm_element_t) xbt_swag_getNext(*elem, cnst->enabled_element_set.offset);
- if (*nextelem == nullptr)
- *nextelem = (lmm_element_t) xbt_swag_getFirst(&(cnst->disabled_element_set));
- } else {
- *nextelem = (lmm_element_t) xbt_swag_getNext(*elem, cnst->disabled_element_set.offset);
- }
- return (*elem)->variable;
- }else
- return nullptr;
-}
-
-void *lmm_constraint_id(lmm_constraint_t cnst)
-{
- return cnst->id;
-}
-
-void *lmm_variable_id(lmm_variable_t var)
-{
- return var->id;
-}
-
-static inline void saturated_constraint_set_update(double usage, int cnst_light_num,
- dyn_light_t saturated_constraint_set, double *min_usage)
-{
- xbt_assert(usage > 0,"Impossible");
-
- if (*min_usage < 0 || *min_usage > usage) {
- *min_usage = usage;
- XBT_HERE(" min_usage=%f (cnst->remaining / cnst->usage =%f)", *min_usage, usage);
- saturated_constraint_set->data[0] = cnst_light_num;
- saturated_constraint_set->pos = 1;
- } else if (*min_usage == usage) {
- if(saturated_constraint_set->pos == saturated_constraint_set->size) { // realloc the size
- saturated_constraint_set->size *= 2;
- saturated_constraint_set->data =
- (int*) xbt_realloc(saturated_constraint_set->data, (saturated_constraint_set->size) * sizeof(int));
- }
- saturated_constraint_set->data[saturated_constraint_set->pos] = cnst_light_num;
- saturated_constraint_set->pos++;
- }
-}
-
-static inline void saturated_variable_set_update(s_lmm_constraint_light_t *cnst_light_tab,
- dyn_light_t saturated_constraint_set, lmm_system_t sys)
-{
- /* Add active variables (i.e. variables that need to be set) from the set of constraints to saturate (cnst_light_tab)*/
- lmm_constraint_light_t cnst = nullptr;
- void *_elem;
- lmm_element_t elem = nullptr;
- xbt_swag_t elem_list = nullptr;
- int i;
- for(i = 0; i< saturated_constraint_set->pos; i++){
- cnst = &cnst_light_tab[saturated_constraint_set->data[i]];
- elem_list = &(cnst->cnst->active_element_set);
- xbt_swag_foreach(_elem, elem_list) {
- elem = (lmm_element_t)_elem;
- //Visiting active_element_set, so, by construction, should never get a zero weight, correct?
- xbt_assert(elem->variable->sharing_weight > 0);
- if (elem->consumption_weight > 0)
- xbt_swag_insert(elem->variable, &(sys->saturated_variable_set));
- }
- }
-}
-
-void lmm_print(lmm_system_t sys)
-{
- std::string buf = std::string("MAX-MIN ( ");
- void* _var;
-
- /* Printing Objective */
- xbt_swag_t var_list = &(sys->variable_set);
- xbt_swag_foreach(_var, var_list) {
- lmm_variable_t var = (lmm_variable_t)_var;
- buf = buf + "'" + std::to_string(var->id_int) + "'(" + std::to_string(var->sharing_weight) + ") ";
- }
- buf += ")";
- XBT_DEBUG("%20s", buf.c_str());
- buf.clear();
-
- XBT_DEBUG("Constraints");
- /* Printing Constraints */
- void* _cnst;
- xbt_swag_t cnst_list = &(sys->active_constraint_set);
- xbt_swag_foreach(_cnst, cnst_list) {
- lmm_constraint_t cnst = (lmm_constraint_t)_cnst;
- double sum = 0.0;
- //Show the enabled variables
- void* _elem;
- xbt_swag_t elem_list = &(cnst->enabled_element_set);
- buf += "\t";
- buf += ((cnst->sharing_policy) ? "(" : "max(");
- xbt_swag_foreach(_elem, elem_list) {
- lmm_element_t elem = (lmm_element_t)_elem;
- buf = buf + std::to_string(elem->consumption_weight) + ".'" + std::to_string(elem->variable->id_int) + "'(" +
- std::to_string(elem->variable->value) + ")" + ((cnst->sharing_policy) ? " + " : " , ");
- if(cnst->sharing_policy)
- sum += elem->consumption_weight * elem->variable->value;
- else
- sum = MAX(sum, elem->consumption_weight * elem->variable->value);
- }
- //TODO: Adding disabled elements only for test compatibility, but do we really want them to be printed?
- elem_list = &(cnst->disabled_element_set);
- xbt_swag_foreach(_elem, elem_list) {
- lmm_element_t elem = (lmm_element_t)_elem;
- buf = buf + std::to_string(elem->consumption_weight) + ".'" + std::to_string(elem->variable->id_int) + "'(" +
- std::to_string(elem->variable->value) + ")" + ((cnst->sharing_policy) ? " + " : " , ");
- if(cnst->sharing_policy)
- sum += elem->consumption_weight * elem->variable->value;
- else
- sum = MAX(sum, elem->consumption_weight * elem->variable->value);
- }
-
- buf = buf + "0) <= " + std::to_string(cnst->bound) + " ('" + std::to_string(cnst->id_int) + "')";
-
- if (not cnst->sharing_policy) {
- buf += " [MAX-Constraint]";
- }
- XBT_DEBUG("%s", buf.c_str());
- buf.clear();
- xbt_assert(not double_positive(sum - cnst->bound, cnst->bound * sg_maxmin_precision),
- "Incorrect value (%f is not smaller than %f): %g", sum, cnst->bound, sum - cnst->bound);
- }
-
- XBT_DEBUG("Variables");
- /* Printing Result */
- xbt_swag_foreach(_var, var_list) {
- lmm_variable_t var = (lmm_variable_t)_var;
- if (var->bound > 0) {
- XBT_DEBUG("'%d'(%f) : %f (<=%f)", var->id_int, var->sharing_weight, var->value, var->bound);
- xbt_assert(not double_positive(var->value - var->bound, var->bound * sg_maxmin_precision),
- "Incorrect value (%f is not smaller than %f", var->value, var->bound);
- } else {
- XBT_DEBUG("'%d'(%f) : %f", var->id_int, var->sharing_weight, var->value);
- }
- }
-}
-
-void lmm_solve(lmm_system_t sys)
-{
- void* _cnst;
- void* _cnst_next;
- void* _elem;
- double min_usage = -1;
- double min_bound = -1;
-
- if (not sys->modified)
- return;
-
- XBT_IN("(sys=%p)", sys);
-
- /* Compute Usage and store the variables that reach the maximum. If selective_update_active is true, only constraints
- * that changed are considered. Otherwise all constraints with active actions are considered.
- */
- xbt_swag_t cnst_list = sys->selective_update_active ? &(sys->modified_constraint_set) : &(sys->active_constraint_set);
-
- XBT_DEBUG("Active constraints : %d", xbt_swag_size(cnst_list));
- /* Init: Only modified code portions: reset the value of active variables */
- xbt_swag_foreach(_cnst, cnst_list) {
- lmm_constraint_t cnst = (lmm_constraint_t)_cnst;
- xbt_swag_t elem_list = &(cnst->enabled_element_set);
- xbt_swag_foreach(_elem, elem_list) {
- lmm_variable_t var = ((lmm_element_t)_elem)->variable;
- xbt_assert(var->sharing_weight > 0.0);
- var->value = 0.0;
- }
- }
-
- s_lmm_constraint_light_t* cnst_light_tab =
- static_cast<s_lmm_constraint_light_t*>(xbt_malloc0(xbt_swag_size(cnst_list) * sizeof(s_lmm_constraint_light_t)));
- int cnst_light_num = 0;
- dyn_light_t saturated_constraint_set = xbt_new0(s_dyn_light_t,1);
- saturated_constraint_set->size = 5;
- saturated_constraint_set->data = xbt_new0(int, saturated_constraint_set->size);
-
- xbt_swag_foreach_safe(_cnst, _cnst_next, cnst_list) {
- lmm_constraint_t cnst = (lmm_constraint_t)_cnst;
- /* INIT: Collect constraints that actually need to be saturated (i.e remaining and usage are strictly positive)
- * into cnst_light_tab. */
- cnst->remaining = cnst->bound;
- if (not double_positive(cnst->remaining, cnst->bound * sg_maxmin_precision))
- continue;
- cnst->usage = 0;
- xbt_swag_t elem_list = &(cnst->enabled_element_set);
- xbt_swag_foreach(_elem, elem_list) {
- lmm_element_t elem = (lmm_element_t)_elem;
- xbt_assert(elem->variable->sharing_weight > 0);
- if (elem->consumption_weight > 0) {
- if (cnst->sharing_policy)
- cnst->usage += elem->consumption_weight / elem->variable->sharing_weight;
- else if (cnst->usage < elem->consumption_weight / elem->variable->sharing_weight)
- cnst->usage = elem->consumption_weight / elem->variable->sharing_weight;
-
- make_elem_active(elem);
- simgrid::surf::Action *action = static_cast<simgrid::surf::Action*>(elem->variable->id);
- if (sys->keep_track && not action->is_linked())
- sys->keep_track->push_back(*action);
- }
- }
- XBT_DEBUG("Constraint '%d' usage: %f remaining: %f concurrency: %i<=%i<=%i", cnst->id_int, cnst->usage,
- cnst->remaining,cnst->concurrency_current,cnst->concurrency_maximum,cnst->concurrency_limit);
- /* Saturated constraints update */
-
- if(cnst->usage > 0) {
- cnst_light_tab[cnst_light_num].cnst = cnst;
- cnst->cnst_light = &(cnst_light_tab[cnst_light_num]);
- cnst_light_tab[cnst_light_num].remaining_over_usage = cnst->remaining / cnst->usage;
- saturated_constraint_set_update(cnst_light_tab[cnst_light_num].remaining_over_usage,
- cnst_light_num, saturated_constraint_set, &min_usage);
- xbt_assert(cnst->active_element_set.count>0, "There is no sense adding a constraint that has no active element!");
- cnst_light_num++;
- }
- }
-
- saturated_variable_set_update( cnst_light_tab, saturated_constraint_set, sys);
-
- /* Saturated variables update */
- do {
- /* Fix the variables that have to be */
- xbt_swag_t var_list = &(sys->saturated_variable_set);
- void* _var;
- lmm_variable_t var = nullptr;
- xbt_swag_foreach(_var, var_list) {
- var = (lmm_variable_t)_var;
- if (var->sharing_weight <= 0.0)
- DIE_IMPOSSIBLE;
- /* First check if some of these variables could reach their upper bound and update min_bound accordingly. */
- XBT_DEBUG("var=%d, var->bound=%f, var->weight=%f, min_usage=%f, var->bound*var->weight=%f", var->id_int,
- var->bound, var->sharing_weight, min_usage, var->bound * var->sharing_weight);
- if ((var->bound > 0) && (var->bound * var->sharing_weight < min_usage)) {
- if (min_bound < 0)
- min_bound = var->bound * var->sharing_weight;
- else
- min_bound = MIN(min_bound, (var->bound * var->sharing_weight));
- XBT_DEBUG("Updated min_bound=%f", min_bound);
- }
- }
-
- while ((var = (lmm_variable_t)xbt_swag_getFirst(var_list))) {
- int i;
-
- if (min_bound < 0) {
- //If no variable could reach its bound, deal iteratively the constraints usage ( at worst one constraint is
- // saturated at each cycle)
- var->value = min_usage / var->sharing_weight;
- XBT_DEBUG("Setting var (%d) value to %f\n", var->id_int, var->value);
- } else {
- //If there exist a variable that can reach its bound, only update it (and other with the same bound) for now.
- if (double_equals(min_bound, var->bound * var->sharing_weight, sg_maxmin_precision)) {
- var->value = var->bound;
- XBT_DEBUG("Setting %p (%d) value to %f\n", var, var->id_int, var->value);
- } else {
- // Variables which bound is different are not considered for this cycle, but they will be afterwards.
- XBT_DEBUG("Do not consider %p (%d) \n", var, var->id_int);
- xbt_swag_remove(var, var_list);
- continue;
- }
- }
- XBT_DEBUG("Min usage: %f, Var(%d)->weight: %f, Var(%d)->value: %f ", min_usage, var->id_int, var->sharing_weight,
- var->id_int, var->value);
-
- /* Update the usage of contraints where this variable is involved */
- for (i = 0; i < var->cnsts_number; i++) {
- lmm_element_t elem = &var->cnsts[i];
- lmm_constraint_t cnst = elem->constraint;
- if (cnst->sharing_policy) {
- //Remember: shared constraints require that sum(elem->value * var->value) < cnst->bound
- double_update(&(cnst->remaining), elem->consumption_weight * var->value, cnst->bound * sg_maxmin_precision);
- double_update(&(cnst->usage), elem->consumption_weight / var->sharing_weight, sg_maxmin_precision);
- //If the constraint is saturated, remove it from the set of active constraints (light_tab)
- if (not double_positive(cnst->usage, sg_maxmin_precision) ||
- not double_positive(cnst->remaining, cnst->bound * sg_maxmin_precision)) {
- if (cnst->cnst_light) {
- int index = (cnst->cnst_light-cnst_light_tab);
- XBT_DEBUG("index: %d \t cnst_light_num: %d \t || usage: %f remaining: %f bound: %f ",
- index,cnst_light_num, cnst->usage, cnst->remaining, cnst->bound);
- cnst_light_tab[index]=cnst_light_tab[cnst_light_num-1];
- cnst_light_tab[index].cnst->cnst_light = &cnst_light_tab[index];
- cnst_light_num--;
- cnst->cnst_light = nullptr;
- }
- } else {
- cnst->cnst_light->remaining_over_usage = cnst->remaining / cnst->usage;
- }
- make_elem_inactive(elem);
- } else {
- //Remember: non-shared constraints only require that max(elem->value * var->value) < cnst->bound
- cnst->usage = 0.0;
- make_elem_inactive(elem);
- xbt_swag_t elem_list = &(cnst->enabled_element_set);
- xbt_swag_foreach(_elem, elem_list) {
- elem = (lmm_element_t)_elem;
- xbt_assert(elem->variable->sharing_weight > 0);
- if (elem->variable->value > 0) continue;
- if (elem->consumption_weight > 0)
- cnst->usage = MAX(cnst->usage, elem->consumption_weight / elem->variable->sharing_weight);
- }
- //If the constraint is saturated, remove it from the set of active constraints (light_tab)
- if (not double_positive(cnst->usage, sg_maxmin_precision) ||
- not double_positive(cnst->remaining, cnst->bound * sg_maxmin_precision)) {
- if(cnst->cnst_light) {
- int index = (cnst->cnst_light-cnst_light_tab);
- XBT_DEBUG("index: %d \t cnst_light_num: %d \t || \t cnst: %p \t cnst->cnst_light: %p "
- "\t cnst_light_tab: %p usage: %f remaining: %f bound: %f ", index,cnst_light_num, cnst,
- cnst->cnst_light, cnst_light_tab, cnst->usage, cnst->remaining, cnst->bound);
- cnst_light_tab[index]=cnst_light_tab[cnst_light_num-1];
- cnst_light_tab[index].cnst->cnst_light = &cnst_light_tab[index];
- cnst_light_num--;
- cnst->cnst_light = nullptr;
- }
- } else {
- cnst->cnst_light->remaining_over_usage = cnst->remaining / cnst->usage;
- xbt_assert(cnst->active_element_set.count>0, "Should not keep a maximum constraint that has no active"
- " element! You want to check the maxmin precision and possible rounding effects." );
- }
- }
- }
- xbt_swag_remove(var, var_list);
- }
-
- /* Find out which variables reach the maximum */
- min_usage = -1;
- min_bound = -1;
- saturated_constraint_set->pos = 0;
- int pos;
- for(pos=0; pos<cnst_light_num; pos++){
- xbt_assert(cnst_light_tab[pos].cnst->active_element_set.count>0, "Cannot saturate more a constraint that has"
- " no active element! You may want to change the maxmin precision (--cfg=maxmin/precision:<new_value>)"
- " because of possible rounding effects.\n\tFor the record, the usage of this constraint is %g while "
- "the maxmin precision to which it is compared is %g.\n\tThe usage of the previous constraint is %g.",
- cnst_light_tab[pos].cnst->usage, sg_maxmin_precision, cnst_light_tab[pos-1].cnst->usage);
- saturated_constraint_set_update(cnst_light_tab[pos].remaining_over_usage, pos, saturated_constraint_set,
- &min_usage);
- }
-
- saturated_variable_set_update(cnst_light_tab, saturated_constraint_set, sys);
-
- } while (cnst_light_num > 0);
-
- sys->modified = 0;
- if (sys->selective_update_active)
- lmm_remove_all_modified_set(sys);
-
- if (XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug)) {
- lmm_print(sys);
- }
-
- lmm_check_concurrency(sys);
-
- xbt_free(saturated_constraint_set->data);
- xbt_free(saturated_constraint_set);
- xbt_free(cnst_light_tab);
- XBT_OUT();
-}
-
-/** \brief Attribute the value bound to var->bound.
- *
- * \param sys the lmm_system_t
- * \param var the lmm_variable_t
- * \param bound the new bound to associate with var
- *
- * Makes var->bound equal to bound. Whenever this function is called a change is signed in the system. To
- * avoid false system changing detection it is a good idea to test (bound != 0) before calling it.
- */
-void lmm_update_variable_bound(lmm_system_t sys, lmm_variable_t var, double bound)
-{
- sys->modified = 1;
- var->bound = bound;
-
- if (var->cnsts_number)
- lmm_update_modified_set(sys, var->cnsts[0].constraint);
-}
-
-int lmm_concurrency_slack(lmm_constraint_t cnstr){
- //FIXME MARTIN: Replace by infinite value std::numeric_limits<int>::(max)(), or something better within Simgrid?
- if(cnstr->concurrency_limit<0)
- return 666;
-
- return cnstr->concurrency_limit - cnstr->concurrency_current;
-}
-
-/** \brief Measure the minimum concurrency slack across all constraints where the given var is involved */
-int lmm_cnstrs_min_concurrency_slack(lmm_variable_t var){
- int minslack = std::numeric_limits<int>::max();
- for (int i = 0; i < var->cnsts_number; i++) {
- int slack = lmm_concurrency_slack(var->cnsts[i].constraint);
-
- //This is only an optimization, to avoid looking at more constraints when slack is already zero
- //Disable it when debugging to let lmm_concurrency_slack catch nasty things
- if (not slack && not XBT_LOG_ISENABLED(surf_maxmin, xbt_log_priority_debug))
- return 0;
-
- if(minslack>slack)
- minslack=slack;
- }
-
- return minslack;
-}
-
-/* /Check if a variable can be enabled
- *
- * Make sure to set staged_weight before, if your intent is only to check concurrency
- */
-int lmm_can_enable_var(lmm_variable_t var){
- return var->staged_weight>0 && lmm_cnstrs_min_concurrency_slack(var)>=var->concurrency_share;
-}
-
-//Small remark: In this implementation of lmm_enable_var and lmm_disable_var, we will meet multiple times with var when
-// running lmm_update_modified_set.
-//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));
-
- var->sharing_weight = var->staged_weight;
- var->staged_weight = 0;
-
- // Enabling the variable, move to var to list head. Subtlety is: here, we need to call lmm_update_modified_set AFTER
- // moving at least one element of var.
-
- xbt_swag_remove(var, &(sys->variable_set));
- xbt_swag_insert_at_head(var, &(sys->variable_set));
- for (int i = 0; i < var->cnsts_number; i++) {
- lmm_element_t elem = &var->cnsts[i];
- xbt_swag_remove(elem, &(elem->constraint->disabled_element_set));
- xbt_swag_insert_at_head(elem, &(elem->constraint->enabled_element_set));
- lmm_increase_concurrency(elem);
- }
- if (var->cnsts_number)
- lmm_update_modified_set(sys, var->cnsts[0].constraint);
-
- //When used within lmm_on_disabled_var, we would get an assertion fail, because transiently there can be variables
- // that are staged and could be activated.
- //Anyway, caller functions all call lmm_check_concurrency() in the end.
-}
-
-void lmm_disable_var(lmm_system_t sys, lmm_variable_t var){
- xbt_assert(not var->staged_weight, "Staged weight should have been cleared");
- // Disabling the variable, move to var to list tail. Subtlety is: here, we need to call lmm_update_modified_set BEFORE
- // moving the last element of var.
- xbt_swag_remove(var, &(sys->variable_set));
- xbt_swag_insert_at_tail(var, &(sys->variable_set));
- if (var->cnsts_number)
- lmm_update_modified_set(sys, var->cnsts[0].constraint);
- for (int i = 0; i < var->cnsts_number; i++) {
- lmm_element_t elem = &var->cnsts[i];
- xbt_swag_remove(elem, &(elem->constraint->enabled_element_set));
- xbt_swag_insert_at_tail(elem, &(elem->constraint->disabled_element_set));
-
- xbt_swag_remove(elem, &(elem->constraint->active_element_set));
-
- lmm_decrease_concurrency(elem);
- }
-
- var->sharing_weight = 0.0;
- var->staged_weight=0.0;
- var->value = 0.0;
- lmm_check_concurrency(sys);
-}
-
-/* /brief Find variables that can be enabled and enable them.
- *
- * Assuming that the variable has already been removed from non-zero weights
- * Can we find a staged variable to add?
- * If yes, check that none of the constraints that this variable is involved in is at the limit of its concurrency
- * And then add it to enabled variables
- */
-void lmm_on_disabled_var(lmm_system_t sys, lmm_constraint_t cnstr){
-
- if(cnstr->concurrency_limit<0)
- return;
-
- int numelem = xbt_swag_size(&(cnstr->disabled_element_set));
- if (not numelem)
- return;
-
- lmm_element_t elem = (lmm_element_t)xbt_swag_getFirst(&(cnstr->disabled_element_set));
-
- //Cannot use xbt_swag_foreach, because lmm_enable_var will modify disabled_element_set.. within the loop
- while (numelem-- && elem) {
-
- lmm_element_t nextelem = (lmm_element_t)xbt_swag_getNext(elem, cnstr->disabled_element_set.offset);
-
- if (elem->variable->staged_weight>0 ){
- //Found a staged variable
- //TODOLATER: Add random timing function to model reservation protocol fuzziness? Then how to make sure that
- //staged variables will eventually be called?
- if(lmm_can_enable_var(elem->variable)){
- lmm_enable_var(sys,elem->variable);
- }
- }
-
- xbt_assert(cnstr->concurrency_current<=cnstr->concurrency_limit,"Concurrency overflow!");
- if(cnstr->concurrency_current==cnstr->concurrency_limit)
- break;
-
- elem = nextelem;
- }
-
- //We could get an assertion fail, because transiently there can be variables that are staged and could be activated.
- //And we need to go through all constraints of the disabled var before getting back a coherent state.
- //Anyway, caller functions all call lmm_check_concurrency() in the end.
-}
-
-/* \brief update the weight of a variable, and enable/disable it.
- * @return Returns whether a change was made
- */
-void lmm_update_variable_weight(lmm_system_t sys, lmm_variable_t var, double weight)
-{
- xbt_assert(weight>=0,"Variable weight should not be negative!");
-
- if (weight == var->sharing_weight)
- return;
-
- int enabling_var = (weight > 0 && var->sharing_weight <= 0);
- int disabling_var = (weight <= 0 && var->sharing_weight > 0);
-
- XBT_IN("(sys=%p, var=%p, weight=%f)", sys, var, weight);
-
- sys->modified = 1;
-
- //Are we enabling this variable?
- if (enabling_var){
- var->staged_weight = weight;
- int minslack = lmm_cnstrs_min_concurrency_slack(var);
- if (minslack < var->concurrency_share) {
- XBT_DEBUG("Staging var (instead of enabling) because min concurrency slack %i, with weight %f and concurrency"
- " share %i", minslack, weight, var->concurrency_share);
- return;
- }
- XBT_DEBUG("Enabling var with min concurrency slack %i", minslack);
- lmm_enable_var(sys,var);
- } else if (disabling_var){
- //Are we disabling this variable?
- lmm_disable_var(sys,var);
- } else {
- var->sharing_weight = weight;
- }
-
- lmm_check_concurrency(sys);
-
- XBT_OUT();
-}
-
-double lmm_get_variable_weight(lmm_variable_t var)
-{
- return var->sharing_weight;
-}
-
-void lmm_update_constraint_bound(lmm_system_t sys, lmm_constraint_t cnst, double bound)
-{
- sys->modified = 1;
- lmm_update_modified_set(sys, cnst);
- cnst->bound = bound;
-}
-
-int lmm_constraint_used(lmm_system_t sys, lmm_constraint_t cnst)
-{
- 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.
- *
- * \param sys the lmm_system_t
- * \param cnst the lmm_constraint_t affected by the change
- *
- * A recursive algorithm to optimize the system recalculation selecting only constraints that have changed. Each
- * constraint change is propagated to the list of constraints for each variable.
- */
-static void lmm_update_modified_set_rec(lmm_system_t sys, lmm_constraint_t cnst)
-{
- 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;
- s_lmm_element_t *cnsts = var->cnsts;
- int i;
- for (i = 0; var->visited != sys->visited_counter && i < var->cnsts_number ; i++) {
- if (cnsts[i].constraint != cnst && not xbt_swag_belongs(cnsts[i].constraint, &sys->modified_constraint_set)) {
- xbt_swag_insert(cnsts[i].constraint, &sys->modified_constraint_set);
- lmm_update_modified_set_rec(sys, cnsts[i].constraint);
- }
- }
- //var will be ignored in later visits as long as sys->visited_counter does not move
- var->visited = sys->visited_counter;
- }
-}
-
-static void lmm_update_modified_set(lmm_system_t sys, lmm_constraint_t cnst)
-{
- /* nothing to do if selective update isn't active */
- if (sys->selective_update_active && not xbt_swag_belongs(cnst, &sys->modified_constraint_set)) {
- xbt_swag_insert(cnst, &sys->modified_constraint_set);
- lmm_update_modified_set_rec(sys, cnst);
- }
-}
-
-/** \brief Remove all constraints of the modified_constraint_set.
- *
- * \param sys the lmm_system_t
- */
-static void lmm_remove_all_modified_set(lmm_system_t sys)
-{
- // We cleverly un-flag all variables just by incrementing sys->visited_counter
- // In effect, the var->visited value will no more be equal to sys->visited counter
- // To be clean, when visited counter has wrapped around, we force these var->visited values so that variables that
- // were in the modified a long long time ago are not wrongly skipped here, which would lead to very nasty bugs
- // (i.e. not readibily reproducible, and requiring a lot of run time before happening).
- if (++sys->visited_counter == 1) {
- /* the counter wrapped around, reset each variable->visited */
- void *_var;
- xbt_swag_foreach(_var, &sys->variable_set)
- ((lmm_variable_t)_var)->visited = 0;
- }
- xbt_swag_reset(&sys->modified_constraint_set);
-}
-
-/**
- * Returns resource load (in flop per second, or byte per second, or similar)
- *
- * If the resource is shared (the default case), the load is sum of resource usage made by every variables located on
- * this resource.
- *
- * If the resource is not shared (ie in FATPIPE mode), then the load is the max (not the sum) of all resource usages
- * located on this resource.
- *
- * \param cnst the lmm_constraint_t associated to the resource
- */
-double lmm_constraint_get_usage(lmm_constraint_t cnst) {
- double usage = 0.0;
- xbt_swag_t elem_list = &(cnst->enabled_element_set);
- void* _elem;
-
- xbt_swag_foreach(_elem, elem_list)
- {
- lmm_element_t elem = (lmm_element_t)_elem;
- if (elem->consumption_weight > 0) {
- if (cnst->sharing_policy)
- usage += elem->consumption_weight * elem->variable->value;
- else if (usage < elem->consumption_weight * elem->variable->value)
- usage = std::max(usage, elem->consumption_weight * elem->variable->value);
- }
- }
- return usage;
-}
-
-int lmm_constraint_get_variable_amount(lmm_constraint_t cnst) {
- int usage = 0;
- xbt_swag_t elem_list = &(cnst->enabled_element_set);
- void *_elem;
-
- xbt_swag_foreach(_elem, elem_list) {
- lmm_element_t elem = (lmm_element_t)_elem;
- if (elem->consumption_weight > 0)
- usage++;
- }
- return usage;
-}
+++ /dev/null
-/* Copyright (c) 2004-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 SURF_MAXMIN_PRIVATE_H
-#define SURF_MAXMIN_PRIVATE_H
-
-#include "surf/maxmin.hpp"
-#include "surf_interface.hpp"
-#include "xbt/mallocator.h"
-#include "xbt/swag.h"
-
-/** @ingroup SURF_lmm
- * @brief LMM element
- * Elements can be seen as glue between constraint objects and variable objects.
- * Basically, each variable will have a set of elements, one for each constraint where it is involved.
- * Then, it is used to list all variables involved in constraint through constraint's xxx_element_set lists, or vice-versa list all constraints for a given variable.
- */
-struct s_lmm_element_t {
- /* hookup to constraint */
- s_xbt_swag_hookup_t enabled_element_set_hookup;
- s_xbt_swag_hookup_t disabled_element_set_hookup;
- s_xbt_swag_hookup_t active_element_set_hookup;
-
- lmm_constraint_t constraint;
- lmm_variable_t variable;
-
- // consumption_weight: impact of 1 byte or flop of your application onto the resource (in byte or flop)
- // - if CPU, then probably 1.
- // - If network, then 1 in forward direction and 0.05 backward for the ACKs
- double consumption_weight;
-};
-#define make_elem_active(elem) xbt_swag_insert_at_head(elem,&(elem->constraint->active_element_set))
-#define make_elem_inactive(elem) xbt_swag_remove(elem,&(elem->constraint->active_element_set))
-
-struct s_lmm_constraint_light_t {
- double remaining_over_usage;
- lmm_constraint_t cnst;
-};
-
-/** @ingroup SURF_lmm
- * @brief LMM constraint
- * Each constraint contains several partially overlapping logical sets of elements:
- * \li Disabled elements which variable's weight is zero. This variables are not at all processed by LMM, but eventually the corresponding action will enable it (at least this is the idea).
- * \li Enabled elements which variable's weight is non-zero. They are utilized in some LMM functions.
- * \li Active elements which variable's weight is non-zero (i.e. it is enabled) AND its element value is non-zero. LMM_solve iterates over active elements during resolution, dynamically making them active or unactive.
- *
- */
-struct s_lmm_constraint_t {
- /* hookup to system */
- s_xbt_swag_hookup_t constraint_set_hookup;
- s_xbt_swag_hookup_t active_constraint_set_hookup;
- s_xbt_swag_hookup_t modified_constraint_set_hookup;
- s_xbt_swag_hookup_t saturated_constraint_set_hookup;
-
- s_xbt_swag_t enabled_element_set; /* a list of lmm_element_t */
- s_xbt_swag_t disabled_element_set; /* a list of lmm_element_t */
- s_xbt_swag_t active_element_set; /* a list of lmm_element_t */
- double remaining;
- double usage;
- double bound;
- int concurrency_limit; /* The maximum number of variables that may be enabled at any time (stage variables if necessary) */
- //TODO MARTIN Check maximum value across resources at the end of simulation and give a warning is more than e.g. 500
- int concurrency_current; /* The current concurrency */
- int concurrency_maximum; /* The maximum number of (enabled and disabled) variables associated to the constraint at any given time (essentially for tracing)*/
-
- int sharing_policy; /* see @e_surf_link_sharing_policy_t (0: FATPIPE, 1: SHARED, 2: FULLDUPLEX) */
- void *id;
- int id_int;
- double lambda;
- double new_lambda;
- lmm_constraint_light_t cnst_light;
-};
-
-/** @ingroup SURF_lmm
- * @brief LMM variable
- *
- * When something prevents us from enabling a variable, we "stage" the weight that we would have like to set, so that as soon as possible we enable the variable with desired weight
- */
-struct s_lmm_variable_t {
- /* hookup to system */
- s_xbt_swag_hookup_t variable_set_hookup;
- s_xbt_swag_hookup_t saturated_variable_set_hookup;
-
- s_lmm_element_t *cnsts;
- int cnsts_size;
- int cnsts_number;
-
- // sharing_weight: variable's impact on the resource during the sharing
- // if == 0, the variable is not considered by LMM
- // on CPU, actions with N threads have a sharing of N
- // on network, the actions with higher latency have a lesser sharing_weight
- double sharing_weight;
-
- double staged_weight; /* If non-zero, variable is staged for addition as soon as maxconcurrency constraints will be met */
- double bound;
- double value;
- short int concurrency_share; /* The maximum number of elements that variable will add to a constraint */
- simgrid::surf::Action* id;
- int id_int;
- unsigned visited; /* used by lmm_update_modified_set */
- /* \begin{For Lagrange only} */
- double mu;
- double new_mu;
- double (*func_f)(s_lmm_variable_t* var, double x); /* (f) */
- double (*func_fp)(s_lmm_variable_t* var, double x); /* (f') */
- double (*func_fpi)(s_lmm_variable_t* var, double x); /* (f')^{-1} */
- /* \end{For Lagrange only} */
-};
-
-/** @ingroup SURF_lmm
- * @brief LMM system
- */
-struct s_lmm_system_t {
- int modified;
- bool selective_update_active; /* flag to update partially the system only selecting changed portions */
- unsigned visited_counter; /* used by lmm_update_modified_set and lmm_remove_modified_set to cleverly (un-)flag the constraints (more details in these functions)*/
- s_xbt_swag_t variable_set; /* a list of lmm_variable_t */
- s_xbt_swag_t constraint_set; /* a list of lmm_constraint_t */
-
- s_xbt_swag_t active_constraint_set; /* a list of lmm_constraint_t */
- s_xbt_swag_t modified_constraint_set; /* a list of modified lmm_constraint_t */
-
- s_xbt_swag_t saturated_variable_set; /* a list of lmm_variable_t */
- s_xbt_swag_t saturated_constraint_set; /* a list of lmm_constraint_t_t */
-
- simgrid::surf::ActionLmmListPtr keep_track;
-
- xbt_mallocator_t variable_mallocator;
-
- void (*solve_fun)(lmm_system_t self);
-};
-
-#define extract_variable(sys) xbt_swag_extract(&(sys->variable_set))
-#define extract_constraint(sys) xbt_swag_extract(&(sys->constraint_set))
-#define insert_constraint(sys,cnst) xbt_swag_insert(cnst,&(sys->constraint_set))
-#define remove_variable(sys,var) do {xbt_swag_remove(var,&(sys->variable_set));\
- xbt_swag_remove(var,&(sys->saturated_variable_set));} while(0)
-#define remove_constraint(sys,cnst) do {xbt_swag_remove(cnst,&(sys->constraint_set));\
- xbt_swag_remove(cnst,&(sys->saturated_constraint_set));} while(0)
-#define make_constraint_active(sys,cnst) xbt_swag_insert(cnst,&(sys->active_constraint_set))
-#define make_constraint_inactive(sys,cnst) \
- do { xbt_swag_remove(cnst, &sys->active_constraint_set); \
- xbt_swag_remove(cnst, &sys->modified_constraint_set); } while (0)
-
-/** @ingroup SURF_lmm
- * @brief Print information about a lmm system
- *
- * @param sys A lmm system
- */
-//XBT_PRIVATE void lmm_print(lmm_system_t sys);
-
-extern XBT_PRIVATE double (*func_f_def) (lmm_variable_t, double);
-extern XBT_PRIVATE double (*func_fp_def) (lmm_variable_t, double);
-extern XBT_PRIVATE double (*func_fpi_def) (lmm_variable_t, double);
-
-#endif /* SURF_MAXMIN_PRIVATE_H */
#include <algorithm>
-#include "maxmin_private.hpp"
#include "network_cm02.hpp"
#include "simgrid/s4u/Host.hpp"
#include "simgrid/sg_config.h"
#include "src/instr/instr_private.hpp" // TRACE_is_enabled(). FIXME: remove by subscribing tracing to the surf signals
+#include "surf/maxmin.hpp"
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network);
if (surf_network_model)
return;
- lmm_set_default_protocol_function(func_reno_f, func_reno_fp, func_reno_fpi);
+ lmm_set_default_protocol_function(simgrid::surf::func_reno_f, simgrid::surf::func_reno_fp,
+ simgrid::surf::func_reno_fpi);
xbt_cfg_setdefault_double("network/latency-factor", 13.01);
xbt_cfg_setdefault_double("network/bandwidth-factor", 0.97);
xbt_cfg_setdefault_double("network/weight-S", 20537);
- surf_network_model = new simgrid::surf::NetworkCm02Model(&lagrange_solve);
+ surf_network_model = new simgrid::surf::NetworkCm02Model(&simgrid::surf::lagrange_solve);
all_existing_models->push_back(surf_network_model);
}
if (surf_network_model)
return;
- lmm_set_default_protocol_function(func_reno2_f, func_reno2_fp, func_reno2_fpi);
+ lmm_set_default_protocol_function(simgrid::surf::func_reno2_f, simgrid::surf::func_reno2_fp,
+ simgrid::surf::func_reno2_fpi);
xbt_cfg_setdefault_double("network/latency-factor", 13.01);
xbt_cfg_setdefault_double("network/bandwidth-factor", 0.97);
xbt_cfg_setdefault_double("network/weight-S", 20537);
- surf_network_model = new simgrid::surf::NetworkCm02Model(&lagrange_solve);
+ surf_network_model = new simgrid::surf::NetworkCm02Model(&simgrid::surf::lagrange_solve);
all_existing_models->push_back(surf_network_model);
}
if (surf_network_model)
return;
- lmm_set_default_protocol_function(func_vegas_f, func_vegas_fp, func_vegas_fpi);
+ lmm_set_default_protocol_function(simgrid::surf::func_vegas_f, simgrid::surf::func_vegas_fp,
+ simgrid::surf::func_vegas_fpi);
xbt_cfg_setdefault_double("network/latency-factor", 13.01);
xbt_cfg_setdefault_double("network/bandwidth-factor", 0.97);
xbt_cfg_setdefault_double("network/weight-S", 20537);
- surf_network_model = new simgrid::surf::NetworkCm02Model(&lagrange_solve);
+ surf_network_model = new simgrid::surf::NetworkCm02Model(&simgrid::surf::lagrange_solve);
all_existing_models->push_back(surf_network_model);
}
xbt_die("Unsupported optimization (%s) for this model. Accepted: Full, Lazy.", optim.c_str());
}
- maxminSystem_ = lmm_system_new(selectiveUpdate_);
- loopback_ = createLink("__loopback__", 498000000, 0.000015, SURF_LINK_FATPIPE);
+ maxminSystem_ = new s_lmm_system_t(selectiveUpdate_);
+ loopback_ = NetworkCm02Model::createLink("__loopback__", 498000000, 0.000015, SURF_LINK_FATPIPE);
if (getUpdateMechanism() == UM_LAZY) {
- actionHeap_ = xbt_heap_new(8, nullptr);
- xbt_heap_set_update_callback(actionHeap_, surf_action_lmm_update_index_heap);
modifiedSet_ = new ActionLmmList();
maxminSystem_->keep_track = modifiedSet_;
}
void NetworkCm02Model::updateActionsStateLazy(double now, double /*delta*/)
{
- while ((xbt_heap_size(actionHeap_) > 0)
- && (double_equals(xbt_heap_maxkey(actionHeap_), now, sg_surf_precision))) {
+ while (not actionHeapIsEmpty() && double_equals(actionHeapTopDate(), now, sg_surf_precision)) {
- NetworkCm02Action *action = static_cast<NetworkCm02Action*> (xbt_heap_pop(actionHeap_));
+ NetworkCm02Action* action = static_cast<NetworkCm02Action*>(actionHeapPop());
XBT_DEBUG("Something happened to action %p", action);
if (TRACE_is_enabled()) {
- int n = lmm_get_number_of_cnst_from_var(maxminSystem_, action->getVariable());
+ int n = action->getVariable()->get_number_of_constraint();
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));
- double value = lmm_variable_getvalue(action->getVariable())*
- lmm_get_cnst_weight_from_var(maxminSystem_, action->getVariable(), i);
+ lmm_constraint_t constraint = action->getVariable()->get_constraint(i);
+ NetworkCm02Link* link = static_cast<NetworkCm02Link*>(constraint->get_id());
+ double value = action->getVariable()->get_value() * action->getVariable()->get_constraint_weight(i);
TRACE_surf_link_set_utilization(link->getCname(), action->getCategory(), value, action->getLastUpdate(),
now - action->getLastUpdate());
}
// if I am wearing a latency hat
if (action->getHat() == LATENCY) {
XBT_DEBUG("Latency paid for action %p. Activating", action);
- lmm_update_variable_weight(maxminSystem_, action->getVariable(), action->weight_);
- action->heapRemove(actionHeap_);
+ maxminSystem_->update_variable_weight(action->getVariable(), action->weight_);
+ action->heapRemove(getActionHeap());
action->refreshLastUpdate();
// if I am wearing a max_duration or normal hat
XBT_DEBUG("Action %p finished", action);
action->setRemains(0);
action->finish(Action::State::done);
- action->heapRemove(actionHeap_);
+ action->heapRemove(getActionHeap());
}
}
}
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())
+ maxminSystem_->update_variable_weight(action.getVariable(), action.weight_);
+ }
+ if (TRACE_is_enabled()) {
+ int n = action.getVariable()->get_number_of_constraint();
+ for (int i = 0; i < n; i++) {
+ lmm_constraint_t constraint = action.getVariable()->get_constraint(i);
+ NetworkCm02Link* link = static_cast<NetworkCm02Link*>(constraint->get_id());
+ TRACE_surf_link_set_utilization(
+ link->getCname(), action.getCategory(),
+ (action.getVariable()->get_value() * action.getVariable()->get_constraint_weight(i)),
+ action.getLastUpdate(), now - action.getLastUpdate());
}
- action->updateRemains(lmm_variable_getvalue(action->getVariable()) * delta);
+ }
+ if (not action.getVariable()->get_number_of_constraint()) {
+ /* 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(action.getVariable()->get_value() * 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) && (action.getVariable()->get_weight() > 0)) ||
+ ((action.getMaxDuration() > NO_MAX_DURATION) && (action.getMaxDuration() <= 0))) {
+ action.finish(Action::State::done);
}
}
}
action->latency_ = latency;
action->rate_ = rate;
if (getUpdateMechanism() == UM_LAZY) {
- action->updateIndexHeap(-1);
action->refreshLastUpdate();
}
constraints_per_variable += back_route.size();
if (action->latency_ > 0) {
- action->setVariable(lmm_variable_new(maxminSystem_, action, 0.0, -1.0, constraints_per_variable));
+ action->setVariable(maxminSystem_->variable_new(action, 0.0, -1.0, constraints_per_variable));
if (getUpdateMechanism() == UM_LAZY) {
// add to the heap the event when the latency is payed
XBT_DEBUG("Added action (%p) one latency event at date %f", action, action->latency_ + action->getLastUpdate());
- action->heapInsert(actionHeap_, action->latency_ + action->getLastUpdate(), route.empty() ? NORMAL : LATENCY);
+ action->heapInsert(getActionHeap(), action->latency_ + action->getLastUpdate(), route.empty() ? NORMAL : LATENCY);
}
} else
- action->setVariable(lmm_variable_new(maxminSystem_, action, 1.0, -1.0, constraints_per_variable));
+ action->setVariable(maxminSystem_->variable_new(action, 1.0, -1.0, constraints_per_variable));
if (action->rate_ < 0) {
- lmm_update_variable_bound(maxminSystem_, action->getVariable(), (action->latCurrent_ > 0) ? sg_tcp_gamma / (2.0 * action->latCurrent_) : -1.0);
+ maxminSystem_->update_variable_bound(action->getVariable(),
+ (action->latCurrent_ > 0) ? sg_tcp_gamma / (2.0 * action->latCurrent_) : -1.0);
} else {
- lmm_update_variable_bound(maxminSystem_, action->getVariable(), (action->latCurrent_ > 0) ? std::min(action->rate_, sg_tcp_gamma / (2.0 * action->latCurrent_)) : action->rate_);
+ maxminSystem_->update_variable_bound(action->getVariable(),
+ (action->latCurrent_ > 0)
+ ? std::min(action->rate_, sg_tcp_gamma / (2.0 * action->latCurrent_))
+ : action->rate_);
}
for (auto const& link : route)
- lmm_expand(maxminSystem_, link->constraint(), action->getVariable(), 1.0);
+ maxminSystem_->expand(link->constraint(), action->getVariable(), 1.0);
if (not back_route.empty()) { // sg_network_crosstraffic was activated
XBT_DEBUG("Fullduplex active adding backward flow using 5%%");
for (auto const& link : back_route)
- lmm_expand(maxminSystem_, link->constraint(), action->getVariable(), .05);
+ maxminSystem_->expand(link->constraint(), action->getVariable(), .05);
//Change concurrency_share here, if you want that cross-traffic is included in the SURF concurrency
//(You would also have to change lmm_element_concurrency())
************/
NetworkCm02Link::NetworkCm02Link(NetworkCm02Model* model, const std::string& name, double bandwidth, double latency,
e_surf_link_sharing_policy_t policy, lmm_system_t system)
- : LinkImpl(model, name, lmm_constraint_new(system, this, sg_bandwidth_factor * bandwidth))
+ : LinkImpl(model, name, system->constraint_new(this, sg_bandwidth_factor * bandwidth))
{
bandwidth_.scale = 1.0;
bandwidth_.peak = bandwidth;
latency_.peak = latency;
if (policy == SURF_LINK_FATPIPE)
- lmm_constraint_shared(constraint());
+ constraint()->unshare();
simgrid::s4u::Link::onCreation(this->piface_);
}
double now = surf_get_clock();
turnOff();
- while ((var = lmm_get_var_from_cnst(model()->getMaxminSystem(), constraint(), &elem))) {
- Action *action = static_cast<Action*>( lmm_variable_id(var) );
+ while ((var = constraint()->get_variable(&elem))) {
+ Action* action = static_cast<Action*>(var->get_id());
if (action->getState() == Action::State::running ||
action->getState() == Action::State::ready) {
void NetworkCm02Link::setBandwidth(double value)
{
-
bandwidth_.peak = value;
- lmm_update_constraint_bound(model()->getMaxminSystem(), constraint(),
- sg_bandwidth_factor * (bandwidth_.peak * bandwidth_.scale));
+ model()->getMaxminSystem()->update_constraint_bound(constraint(),
+ sg_bandwidth_factor * (bandwidth_.peak * bandwidth_.scale));
TRACE_surf_link_set_bandwidth(surf_get_clock(), getCname(), sg_bandwidth_factor * bandwidth_.peak * bandwidth_.scale);
if (sg_weight_S_parameter > 0) {
lmm_element_t elem = nullptr;
lmm_element_t nextelem = nullptr;
int numelem = 0;
- while ((var = lmm_get_var_from_cnst_safe(model()->getMaxminSystem(), constraint(), &elem, &nextelem, &numelem))) {
- NetworkCm02Action *action = static_cast<NetworkCm02Action*>(lmm_variable_id(var));
+ while ((var = constraint()->get_variable_safe(&elem, &nextelem, &numelem))) {
+ NetworkCm02Action* action = static_cast<NetworkCm02Action*>(var->get_id());
action->weight_ += delta;
if (not action->isSuspended())
- lmm_update_variable_weight(model()->getMaxminSystem(), action->getVariable(), action->weight_);
+ model()->getMaxminSystem()->update_variable_weight(action->getVariable(), action->weight_);
}
}
}
latency_.peak = value;
- while ((var = lmm_get_var_from_cnst_safe(model()->getMaxminSystem(), constraint(), &elem, &nextelem, &numelem))) {
- NetworkCm02Action *action = static_cast<NetworkCm02Action*>(lmm_variable_id(var));
+ while ((var = constraint()->get_variable_safe(&elem, &nextelem, &numelem))) {
+ NetworkCm02Action* action = static_cast<NetworkCm02Action*>(var->get_id());
action->latCurrent_ += delta;
action->weight_ += delta;
if (action->rate_ < 0)
- lmm_update_variable_bound(model()->getMaxminSystem(), action->getVariable(),
- sg_tcp_gamma / (2.0 * action->latCurrent_));
+ model()->getMaxminSystem()->update_variable_bound(action->getVariable(),
+ sg_tcp_gamma / (2.0 * action->latCurrent_));
else {
- lmm_update_variable_bound(model()->getMaxminSystem(), action->getVariable(),
- std::min(action->rate_, sg_tcp_gamma / (2.0 * action->latCurrent_)));
+ model()->getMaxminSystem()->update_variable_bound(
+ action->getVariable(), std::min(action->rate_, sg_tcp_gamma / (2.0 * action->latCurrent_)));
if (action->rate_ < sg_tcp_gamma / (2.0 * action->latCurrent_)) {
XBT_INFO("Flow is limited BYBANDWIDTH");
}
}
if (not action->isSuspended())
- lmm_update_variable_weight(model()->getMaxminSystem(), action->getVariable(), action->weight_);
+ model()->getMaxminSystem()->update_variable_weight(action->getVariable(), action->weight_);
}
}
setMaxDuration(max_duration);
}
- if ((getRemainsNoUpdate() <= 0 && (lmm_get_variable_weight(getVariable()) > 0)) ||
+ if ((getRemainsNoUpdate() <= 0 && (getVariable()->get_weight() > 0)) ||
((max_duration > NO_MAX_DURATION) && (max_duration <= 0))) {
finish(Action::State::done);
heapRemove(getModel()->getActionHeap());
}
refreshLastUpdate();
- setLastValue(lmm_variable_getvalue(getVariable()));
+ setLastValue(getVariable()->get_value());
}
}
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);
}
}
}
#include "simgrid/sg_config.h"
#include "src/surf/HostImpl.hpp"
-#include "src/surf/maxmin_private.hpp"
#include "src/surf/network_ib.hpp"
#include "src/surf/xml/platf.hpp"
+#include "surf/maxmin.hpp"
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>
if (not double_equals(penalized_bw, rate_before_update, sg_surf_precision)) {
XBT_DEBUG("%d->%d action %p penalty updated : bw now %f, before %f , initial rate %f", root->id,
(*it)->destination->id, (*it)->action, penalized_bw, (*it)->action->getBound(), (*it)->init_rate);
- lmm_update_variable_bound(maxminSystem_, (*it)->action->getVariable(), penalized_bw);
+ maxminSystem_->update_variable_bound((*it)->action->getVariable(), penalized_bw);
} else {
XBT_DEBUG("%d->%d action %p penalty not updated : bw %f, initial rate %f", root->id, (*it)->destination->id,
(*it)->action, penalized_bw, (*it)->init_rate);
XBT_DEBUG("Finished computing IB penalties");
}
-void NetworkIBModel::updateIBfactors_rec(IBNode* root, bool* updatedlist)
+void NetworkIBModel::updateIBfactors_rec(IBNode* root, std::vector<bool>& updatedlist)
{
- if (updatedlist[root->id] == 0) {
+ if (not updatedlist[root->id]) {
XBT_DEBUG("IB - Updating rec %d", root->id);
computeIBfactors(root);
- updatedlist[root->id] = 1;
+ updatedlist[root->id] = true;
for (std::vector<ActiveComm*>::iterator it = root->ActiveCommsUp.begin(); it != root->ActiveCommsUp.end(); ++it) {
- if (updatedlist[(*it)->destination->id] != 1)
+ if (not updatedlist[(*it)->destination->id])
updateIBfactors_rec((*it)->destination, updatedlist);
}
for (std::map<IBNode*, int>::iterator it = root->ActiveCommsDown.begin(); it != root->ActiveCommsDown.end(); ++it) {
- if (updatedlist[it->first->id] != 1)
+ if (not updatedlist[it->first->id])
updateIBfactors_rec(it->first, updatedlist);
}
}
if (from == to) // disregard local comms (should use loopback)
return;
- bool* updated = (bool*)xbt_malloc0(active_nodes.size() * sizeof(bool));
ActiveComm* comm = nullptr;
if (remove) {
if (to->ActiveCommsDown[from] == 1)
to->nbActiveCommsDown++;
}
XBT_DEBUG("IB - Updating %d", from->id);
+ std::vector<bool> updated(active_nodes.size(), false);
updateIBfactors_rec(from, updated);
XBT_DEBUG("IB - Finished updating %d", from->id);
- if (comm)
- delete comm;
- xbt_free(updated);
+ delete comm;
}
}
}
-/* Copyright (c) 2014-2015. The SimGrid Team.
+/* Copyright (c) 2014-2017. The SimGrid Team.
* All rights reserved. */
/* This program is free software; you can redistribute it and/or modify it
#include "xbt/base.h"
#include <unordered_map>
+#include <vector>
namespace simgrid {
namespace surf {
class XBT_PRIVATE NetworkIBModel : public NetworkSmpiModel {
private:
- void updateIBfactors_rec(IBNode *root, bool* updatedlist);
+ void updateIBfactors_rec(IBNode* root, std::vector<bool>& updatedlist);
void computeIBfactors(IBNode *root);
public:
NetworkIBModel();
{
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()
{
NetworkModel::~NetworkModel()
{
- lmm_system_free(maxminSystem_);
- xbt_heap_free(actionHeap_);
+ delete maxminSystem_;
delete modifiedSet_;
}
{
double minRes = Model::nextOccuringEventFull(now);
- for(auto it(getRunningActionSet()->begin()), itend(getRunningActionSet()->end()); it != itend ; 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);
bool LinkImpl::isUsed()
{
- return lmm_constraint_used(model()->getMaxminSystem(), constraint());
+ return model()->getMaxminSystem()->constraint_used(constraint());
}
double LinkImpl::latency()
int LinkImpl::sharingPolicy()
{
- return lmm_constraint_sharing_policy(constraint());
+ return constraint()->get_sharing_policy();
}
void LinkImpl::turnOn()
std::list<LinkImpl*> NetworkAction::links()
{
std::list<LinkImpl*> retlist;
- lmm_system_t sys = getModel()->getMaxminSystem();
- int llen = lmm_get_number_of_cnst_from_var(sys, getVariable());
+ int llen = getVariable()->get_number_of_constraint();
for (int i = 0; i < llen; i++) {
/* Beware of composite actions: ptasks put links and cpus together */
// extra pb: we cannot dynamic_cast from void*...
- Resource* resource = static_cast<Resource*>(lmm_constraint_id(lmm_get_cnst_from_var(sys, getVariable(), i)));
+ Resource* resource = static_cast<Resource*>(getVariable()->get_constraint(i)->get_id());
LinkImpl* link = dynamic_cast<LinkImpl*>(resource);
if (link != nullptr)
retlist.push_back(link);
#include "simgrid/s4u/Link.hpp"
#include "src/surf/PropertyHolder.hpp"
#include "src/surf/surf_interface.hpp"
+#include "surf/maxmin.hpp"
#include "xbt/base.h"
#include <list>
#include <unordered_map>
static LinkImpl* byName(std::string name);
static int linksCount();
static LinkImpl** linksList();
+ static void linksList(std::vector<s4u::Link*>* linkList);
static void linksExit();
};
#include "network_smpi.hpp"
#include "simgrid/sg_config.h"
-#include "smpi/smpi_utils.hpp"
+#include "smpi_utils.hpp"
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_network);
XBT_LOG_NEW_DEFAULT_SUBCATEGORY(surf_energy, surf, "Logging specific to the SURF energy plugin");
namespace simgrid {
-namespace energy {
+namespace plugin {
class PowerRange {
public:
// We consider that the machine is then fully loaded. That's arbitrary but it avoids a NaN
cpu_load = 1;
else
- cpu_load = lmm_constraint_get_usage(host->pimpl_cpu->constraint()) / current_speed;
+ cpu_load = host->pimpl_cpu->constraint()->get_usage() / current_speed;
/** Divide by the number of cores here **/
cpu_load /= host->pimpl_cpu->coreCount();
{
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)
if (dynamic_cast<simgrid::s4u::VirtualMachine*>(&host)) // Ignore virtual machines
return;
- HostEnergy* host_energy = host.extension<HostEnergy>();
- host_energy->update();
- XBT_INFO("Energy consumption of host %s: %f Joules", host.getCname(), host_energy->getConsumedEnergy());
+ XBT_INFO("Energy consumption of host %s: %f Joules", host.getCname(),
+ host.extension<HostEnergy>()->getConsumedEnergy());
}
static void onSimulationEnd()
{
xbt_assert(HostEnergy::EXTENSION_ID.valid(),
"The Energy plugin is not active. Please call sg_energy_plugin_init() during initialization.");
- double cpu_load = lmm_constraint_get_usage(host->pimpl_cpu->constraint()) / host->getSpeed();
+ double cpu_load = host->pimpl_cpu->constraint()->get_usage() / host->getSpeed();
return host->extension<HostEnergy>()->getCurrentWattsValue(cpu_load);
}
}
: host(ptr)
, last_updated(surf_get_clock())
, last_reset(surf_get_clock())
- , current_flops(lmm_constraint_get_usage(host->pimpl_cpu->constraint()))
+ , current_flops(host->pimpl_cpu->constraint()->get_usage())
{
}
if (last_updated < now) {
/* Current flop per second computed by the cpu; current_flops = k * pstate_speed_in_flops, k \in {0, 1, ..., cores}
* number of active cores */
- current_flops = lmm_constraint_get_usage(host->pimpl_cpu->constraint());
+ current_flops = host->pimpl_cpu->constraint()->get_usage();
/* flops == pstate_speed * cores_being_currently_used */
computed_flops += (now - last_updated) * current_flops;
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 link energy plugin, accounting 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="125Mbps" latency="5us" sharing_policy="SHARED" >
+ <prop id="watt_range" 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: sg_link_get_consumed_energy().
+ */
+
+XBT_LOG_NEW_DEFAULT_SUBCATEGORY(link_energy, surf, "Logging specific to the SURF LinkEnergy plugin");
+
+namespace simgrid {
+namespace plugin {
+
+class LinkEnergy {
+public:
+ static simgrid::xbt::Extension<simgrid::s4u::Link, LinkEnergy> EXTENSION_ID;
+
+ explicit LinkEnergy(simgrid::s4u::Link* ptr);
+ ~LinkEnergy();
+
+ void initWattsRangeList();
+ double getConsumedEnergy();
+ void update();
+
+private:
+ double getPower();
+
+ simgrid::s4u::Link* link_{};
+
+ bool inited_{false};
+ double idle_{0.0};
+ double busy_{0.0};
+
+ double totalEnergy_{0.0};
+ double lastUpdated_{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), lastUpdated_(surf_get_clock())
+{
+}
+
+LinkEnergy::~LinkEnergy() = default;
+
+void LinkEnergy::update()
+{
+ double power = getPower();
+ double now = surf_get_clock();
+ totalEnergy_ += power * (now - lastUpdated_);
+ lastUpdated_ = now;
+}
+
+void LinkEnergy::initWattsRangeList()
+{
+
+ if (inited_)
+ return;
+ inited_ = true;
+
+ 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* idleMsg = bprintf("Invalid idle power value for link%s", this->link_->getCname());
+ char* busyMsg = bprintf("Invalid busy power value for %s", this->link_->getCname());
+
+ idle_ = xbt_str_parse_double((current_power_values.at(0)).c_str(), idleMsg);
+ busy_ = xbt_str_parse_double((current_power_values.at(1)).c_str(), busyMsg);
+
+ xbt_free(idleMsg);
+ xbt_free(busyMsg);
+ update();
+ }
+}
+
+double LinkEnergy::getPower()
+{
+
+ if (!inited_)
+ return 0.0;
+
+ 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::getConsumedEnergy()
+{
+ if (lastUpdated_ < surf_get_clock()) // We need to simcall this as it modifies the environment
+ simgrid::simix::kernelImmediate(std::bind(&LinkEnergy::update, this));
+ return this->totalEnergy_;
+}
+}
+}
+
+using simgrid::plugin::LinkEnergy;
+
+/* **************************** events callback *************************** */
+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());
+ LinkEnergy* link_energy = link->piface_.extension<LinkEnergy>();
+ link_energy->initWattsRangeList();
+ link_energy->update();
+ }
+}
+
+static void onSimulationEnd()
+{
+ std::vector<simgrid::s4u::Link*> links;
+ simgrid::s4u::Engine::getInstance()->getLinkList(&links);
+
+ double total_energy = 0.0; // Total dissipated energy (whole platform)
+ for (const auto link : links) {
+ double link_energy = link->extension<LinkEnergy>()->getConsumedEnergy();
+ total_energy += link_energy;
+ }
+
+ XBT_INFO("Total energy over all links: %f", total_energy);
+}
+/* **************************** 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([](simgrid::s4u::Link& link) {
+ link.extension_set(new LinkEnergy(&link));
+ });
+
+ simgrid::s4u::Link::onStateChange.connect([](simgrid::s4u::Link& link) {
+ link.extension<LinkEnergy>()->update();
+ });
+
+ simgrid::s4u::Link::onDestruction.connect([](simgrid::s4u::Link& link) {
+ if (strcmp(link.getCname(), "__loopback__"))
+ XBT_INFO("Energy consumption of link '%s': %f Joules", link.getCname(),
+ link.extension<LinkEnergy>()->getConsumedEnergy());
+ });
+
+ simgrid::s4u::Link::onCommunicationStateChange.connect([](simgrid::surf::NetworkAction* action) {
+ for (simgrid::surf::LinkImpl* link : action->links()) {
+ if (link != nullptr)
+ link->piface_.extension<LinkEnergy>()->update();
+ }
+ });
+
+ simgrid::s4u::Link::onCommunicate.connect(&onCommunicate);
+ simgrid::s4u::onSimulationEnd.connect(&onSimulationEnd);
+}
+
+/** @ingroup plugin_energy
+ * @brief Returns the total energy consumed by the link so far (in Joules)
+ *
+ * Please note that since the consumption is lazily updated, it may require a simcall to update it.
+ * The result is that the actor requesting this value will be interrupted,
+ * the value will be updated in kernel mode before returning the control to the requesting actor.
+ */
+double sg_link_get_consumed_energy(sg_link_t link)
+{
+ return link->extension<LinkEnergy>()->getConsumedEnergy();
+}
+SG_END_DECL()
namespace surf {
HostL07Model::HostL07Model() : HostModel() {
- maxminSystem_ = lmm_system_new(true /* lazy */);
+ maxminSystem_ = new s_lmm_system_t(true /* lazy */);
maxminSystem_->solve_fun = &bottleneck_solve;
surf_network_model = new NetworkL07Model(this,maxminSystem_);
surf_cpu_model_pm = new CpuL07Model(this,maxminSystem_);
HostL07Model::~HostL07Model()
{
- lmm_system_free(maxminSystem_);
+ delete maxminSystem_;
maxminSystem_ = nullptr;
delete surf_network_model;
delete surf_cpu_model_pm;
, 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();
+ maxminSystem_->update_variable_weight(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(),
+ action.getVariable()->get_value() * delta);
+ action.updateRemains(action.getVariable()->get_value() * 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) && (action.getVariable()->get_weight() > 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 = action.getVariable()->get_constraint(i);
while (cnst != nullptr) {
i++;
- void *constraint_id = lmm_constraint_id(cnst);
+ void* constraint_id = cnst->get_id();
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 = action.getVariable()->get_constraint(i);
}
}
}
std::vector<LinkImpl*> route;
hostList_->at(i)->routeTo(hostList_->at(j), route, &lat);
- latency = MAX(latency, lat);
+ latency = std::max(latency, lat);
for (auto const& link : route)
affected_links.insert(link->getCname());
XBT_DEBUG("Creating a parallel task (%p) with %d hosts and %d unique links.", this, host_nb, nb_link);
latency_ = latency;
- setVariable(lmm_variable_new(model->getMaxminSystem(), this, 1.0, (rate > 0 ? rate : -1.0), host_nb + nb_link));
+ setVariable(model->getMaxminSystem()->variable_new(this, 1.0, (rate > 0 ? rate : -1.0), host_nb + nb_link));
if (latency_ > 0)
- lmm_update_variable_weight(model->getMaxminSystem(), getVariable(), 0.0);
+ model->getMaxminSystem()->update_variable_weight(getVariable(), 0.0);
for (int i = 0; i < host_nb; i++)
- lmm_expand(model->getMaxminSystem(), host_list[i]->pimpl_cpu->constraint(), getVariable(), flops_amount[i]);
+ model->getMaxminSystem()->expand(host_list[i]->pimpl_cpu->constraint(), getVariable(), flops_amount[i]);
if(bytes_amount != nullptr) {
for (int i = 0; i < host_nb; i++) {
hostList_->at(i)->routeTo(hostList_->at(j), route, nullptr);
for (auto const& link : route)
- lmm_expand_add(model->getMaxminSystem(), link->constraint(), this->getVariable(),
- bytes_amount[i * host_nb + j]);
+ model->getMaxminSystem()->expand_add(link->constraint(), this->getVariable(),
+ bytes_amount[i * host_nb + j]);
}
}
}
************/
CpuL07::CpuL07(CpuL07Model* model, simgrid::s4u::Host* host, std::vector<double>* speedPerPstate, int core)
- : Cpu(model, host, lmm_constraint_new(model->getMaxminSystem(), this, speedPerPstate->front()), speedPerPstate,
- core)
+ : Cpu(model, host, model->getMaxminSystem()->constraint_new(this, speedPerPstate->front()), speedPerPstate, core)
{
}
LinkL07::LinkL07(NetworkL07Model* model, const std::string& name, double bandwidth, double latency,
e_surf_link_sharing_policy_t policy)
- : LinkImpl(model, name, lmm_constraint_new(model->getMaxminSystem(), this, bandwidth))
+ : LinkImpl(model, name, model->getMaxminSystem()->constraint_new(this, bandwidth))
{
bandwidth_.peak = bandwidth;
latency_.peak = latency;
if (policy == SURF_LINK_FATPIPE)
- lmm_constraint_shared(constraint());
+ constraint()->unshare();
s4u::Link::onCreation(this->piface_);
}
L07Action *action = static_cast<L07Action*>(execution_start(1.0));
action->setMaxDuration(duration);
action->suspended_ = 2;
- lmm_update_variable_weight(model()->getMaxminSystem(), action->getVariable(), 0.0);
+ model()->getMaxminSystem()->update_variable_weight(action->getVariable(), 0.0);
return action;
}
bool CpuL07::isUsed(){
- return lmm_constraint_used(model()->getMaxminSystem(), constraint());
+ return model()->getMaxminSystem()->constraint_used(constraint());
}
/** @brief take into account changes of speed (either load or max) */
lmm_variable_t var = nullptr;
lmm_element_t elem = nullptr;
- lmm_update_constraint_bound(model()->getMaxminSystem(), constraint(), speed_.peak * speed_.scale);
- while ((var = lmm_get_var_from_cnst(model()->getMaxminSystem(), constraint(), &elem))) {
- Action* action = static_cast<Action*>(lmm_variable_id(var));
+ model()->getMaxminSystem()->update_constraint_bound(constraint(), speed_.peak * speed_.scale);
+ while ((var = constraint()->get_variable(&elem))) {
+ Action* action = static_cast<Action*>(var->get_id());
- lmm_update_variable_bound(model()->getMaxminSystem(), action->getVariable(), speed_.scale * speed_.peak);
+ model()->getMaxminSystem()->update_variable_bound(action->getVariable(), speed_.scale * speed_.peak);
}
Cpu::onSpeedChange();
bool LinkL07::isUsed(){
- return lmm_constraint_used(model()->getMaxminSystem(), constraint());
+ return model()->getMaxminSystem()->constraint_used(constraint());
}
void CpuL07::apply_event(tmgr_trace_event_t triggered, double value)
void LinkL07::setBandwidth(double value)
{
bandwidth_.peak = value;
- lmm_update_constraint_bound(model()->getMaxminSystem(), constraint(), bandwidth_.peak * bandwidth_.scale);
+ model()->getMaxminSystem()->update_constraint_bound(constraint(), bandwidth_.peak * bandwidth_.scale);
}
void LinkL07::setLatency(double value)
lmm_element_t elem = nullptr;
latency_.peak = value;
- while ((var = lmm_get_var_from_cnst(model()->getMaxminSystem(), constraint(), &elem))) {
- action = static_cast<L07Action*>(lmm_variable_id(var));
+ while ((var = constraint()->get_variable(&elem))) {
+ action = static_cast<L07Action*>(var->get_id());
action->updateBound();
}
}
std::vector<LinkImpl*> route;
hostList_->at(i)->routeTo(hostList_->at(j), route, &lat);
- lat_current = MAX(lat_current, lat * communicationAmount_[i * hostNb + j]);
+ lat_current = std::max(lat_current, lat * communicationAmount_[i * hostNb + j]);
}
}
}
XBT_DEBUG("action (%p) : lat_bound = %g", this, lat_bound);
if ((latency_ <= 0.0) && (suspended_ == 0)) {
if (rate_ < 0)
- lmm_update_variable_bound(getModel()->getMaxminSystem(), getVariable(), lat_bound);
+ getModel()->getMaxminSystem()->update_variable_bound(getVariable(), lat_bound);
else
- lmm_update_variable_bound(getModel()->getMaxminSystem(), getVariable(), std::min(rate_, lat_bound));
+ getModel()->getMaxminSystem()->update_variable_bound(getVariable(), std::min(rate_, lat_bound));
}
}
if (action_hook.is_linked())
stateSet_->erase(stateSet_->iterator_to(*this));
if (getVariable())
- lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
+ getModel()->getMaxminSystem()->variable_free(getVariable());
delete this;
return 1;
}
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;
#include "storage_n11.hpp"
#include "simgrid/s4u/Engine.hpp"
#include "src/kernel/routing/NetPoint.hpp"
+#include "surf/maxmin.hpp"
#include <cmath> /*ceil*/
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_storage);
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(action.getVariable()->get_value() * 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) && (action.getVariable()->get_weight() > 0)) ||
+ ((action.getMaxDuration() > NO_MAX_DURATION) && (action.getMaxDuration() <= 0))) {
+ action.finish(Action::State::done);
}
}
}
StorageN11Action::StorageN11Action(Model* model, double cost, bool failed, StorageImpl* storage,
e_surf_action_storage_type_t type)
- : StorageAction(model, cost, failed, lmm_variable_new(model->getMaxminSystem(), this, 1.0, -1.0, 3), storage, type)
+ : StorageAction(model, cost, failed, model->getMaxminSystem()->variable_new(this, 1.0, -1.0, 3), storage, type)
{
XBT_IN("(%s,%g", storage->getCname(), cost);
// Must be less than the max bandwidth for all actions
- lmm_expand(model->getMaxminSystem(), storage->constraint(), getVariable(), 1.0);
+ model->getMaxminSystem()->expand(storage->constraint(), getVariable(), 1.0);
switch(type) {
case READ:
- lmm_expand(model->getMaxminSystem(), storage->constraintRead_, getVariable(), 1.0);
+ model->getMaxminSystem()->expand(storage->constraintRead_, getVariable(), 1.0);
break;
case WRITE:
- lmm_expand(model->getMaxminSystem(), storage->constraintWrite_, getVariable(), 1.0);
+ model->getMaxminSystem()->expand(storage->constraintWrite_, getVariable(), 1.0);
break;
default:
THROW_UNIMPLEMENTED;
if (action_hook.is_linked())
stateSet_->erase(stateSet_->iterator_to(*this));
if (getVariable())
- lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
+ getModel()->getMaxminSystem()->variable_free(getVariable());
xbt_free(getCategory());
delete this;
return 1;
{
XBT_IN("(%p)", this);
if (suspended_ != 2) {
- lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
+ getModel()->getMaxminSystem()->update_variable_weight(getVariable(), 0.0);
suspended_ = 1;
}
XBT_OUT();
#include <xbt/base.h>
-#include "FileImpl.hpp"
#include "StorageImpl.hpp"
#ifndef STORAGE_N11_HPP_
#include "simgrid/s4u/Engine.hpp"
#include "src/instr/instr_private.hpp"
#include "src/plugins/vm/VirtualMachineImpl.hpp"
+#include <algorithm>
XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(surf_kernel);
XBT_DEBUG("Next TRACE event: %f", next_event_date);
if (not surf_network_model->nextOccuringEventIsIdempotent()) { // NS3, I see you
- if (next_event_date!=-1.0 && time_delta!=-1.0) {
- time_delta = MIN(next_event_date - NOW, time_delta);
+ if (next_event_date != -1.0) {
+ time_delta = std::min(next_event_date - NOW, time_delta);
} else {
- time_delta = MAX(next_event_date - NOW, time_delta); // Get the positive component
+ time_delta = std::max(next_event_date - NOW, time_delta); // Get the positive component
}
XBT_DEBUG("Run the NS3 network at most %fs", time_delta);
model_next_action_end = surf_network_model->nextOccuringEvent(time_delta);
XBT_DEBUG("Min for network : %f", model_next_action_end);
- if(model_next_action_end>=0.0)
+ if (model_next_action_end >= 0.0)
time_delta = model_next_action_end;
}
- if (next_event_date < 0.0) {
- XBT_DEBUG("no next TRACE event. Stop searching for it");
+ if (next_event_date < 0.0 || (next_event_date > NOW + time_delta)) {
+ // next event may have already occurred or will after the next resource change, then bail out
+ XBT_DEBUG("no next usable TRACE event. Stop searching for it");
break;
}
- if ((time_delta == -1.0) || (next_event_date > NOW + time_delta))
- break; // next event occurs after the next resource change, bail out
-
XBT_DEBUG("Updating models (min = %g, NOW = %g, next_event_date = %g)", time_delta, NOW, next_event_date);
while ((event = future_evt_set->pop_leq(next_event_date, &value, &resource))) {
NOW = NOW + time_delta;
// Inform the models of the date change
- for (auto const& model : *all_existing_models) {
+ for (auto const& model : *all_existing_models)
model->updateActionsState(NOW, time_delta);
- }
+
simgrid::s4u::onTimeAdvance(time_delta);
TRACE_paje_dump_buffer(false);
doneActionSet_ = new ActionList();
modifiedSet_ = nullptr;
- actionHeap_ = nullptr;
updateMechanism_ = UM_UNDEFINED;
selectiveUpdate_ = 0;
}
delete doneActionSet_;
}
+Action* Model::actionHeapPop()
+{
+ Action* action = actionHeap_.top().second;
+ actionHeap_.pop();
+ action->clearHeapHandle();
+ return action;
+}
+
double Model::nextOccuringEvent(double now)
{
//FIXME: set the good function once and for all
action->updateRemainingLazy(now);
double min = -1;
- double share = lmm_variable_getvalue(action->getVariable());
+ double share = action->getVariable()->get_value();
if (share > 0) {
double time_to_completion;
}
//hereafter must have already the min value for this resource model
- if (xbt_heap_size(actionHeap_) > 0) {
- double min = xbt_heap_maxkey(actionHeap_) - now;
+ if (not actionHeapIsEmpty()) {
+ double min = actionHeapTopDate() - now;
XBT_DEBUG("minimum with the HEAP %f", min);
return min;
} else {
maxminSystem_->solve_fun(maxminSystem_);
double min = -1;
- for (auto it(getRunningActionSet()->begin()), itend(getRunningActionSet()->end()); it != itend ; ++it) {
- Action *action = &*it;
- double value = lmm_variable_getvalue(action->getVariable());
+
+ for (Action& action : *getRunningActionSet()) {
+ double value = action.getVariable()->get_value();
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);
"SURF_ACTION_NOT_IN_THE_SYSTEM"
};
-/* added to manage the communication action's heap */
-void surf_action_lmm_update_index_heap(void *action, int i) {
- static_cast<simgrid::surf::Action*>(action)->updateIndexHeap(i);
-}
-
namespace simgrid {
namespace surf {
setState(state);
}
-Action::State Action::getState()
+Action::State Action::getState() const
{
if (stateSet_ == model_->getReadyActionSet())
return Action::State::ready;
stateSet_->push_back(*this);
}
-double Action::getBound()
+double Action::getBound() const
{
- return (variable_) ? lmm_variable_getbound(variable_) : 0;
+ return variable_ ? variable_->get_bound() : 0;
}
void Action::setBound(double bound)
{
XBT_IN("(%p,%g)", this, bound);
if (variable_)
- lmm_update_variable_bound(getModel()->getMaxminSystem(), variable_, bound);
+ getModel()->getMaxminSystem()->update_variable_bound(variable_, bound);
if (getModel()->getUpdateMechanism() == UM_LAZY && getLastUpdate() != surf_get_clock())
heapRemove(getModel()->getActionHeap());
XBT_OUT();
}
-double Action::getStartTime()
-{
- return start_;
-}
-
-double Action::getFinishTime()
-{
- return finishTime_;
-}
-
-void Action::setData(void* data)
-{
- data_ = data;
-}
-
void Action::setCategory(const char *category)
{
category_ = xbt_strdup(category);
{
XBT_IN("(%p,%g)", this, weight);
sharingWeight_ = weight;
- lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), weight);
+ getModel()->getMaxminSystem()->update_variable_weight(getVariable(), weight);
if (getModel()->getUpdateMechanism() == UM_LAZY)
heapRemove(getModel()->getActionHeap());
if (action_hook.is_linked())
stateSet_->erase(stateSet_->iterator_to(*this));
if (getVariable())
- lmm_variable_free(getModel()->getMaxminSystem(), getVariable());
+ getModel()->getMaxminSystem()->variable_free(getVariable());
if (getModel()->getUpdateMechanism() == UM_LAZY) {
/* remove from heap */
heapRemove(getModel()->getActionHeap());
{
XBT_IN("(%p)", this);
if (suspended_ != 2) {
- lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), 0.0);
+ getModel()->getMaxminSystem()->update_variable_weight(getVariable(), 0.0);
if (getModel()->getUpdateMechanism() == UM_LAZY){
heapRemove(getModel()->getActionHeap());
if (getModel()->getUpdateMechanism() == UM_LAZY && stateSet_ == getModel()->getRunningActionSet() &&
{
XBT_IN("(%p)", this);
if (suspended_ != 2) {
- lmm_update_variable_weight(getModel()->getMaxminSystem(), getVariable(), getPriority());
+ getModel()->getMaxminSystem()->update_variable_weight(getVariable(), getPriority());
suspended_ = 0;
if (getModel()->getUpdateMechanism() == UM_LAZY)
heapRemove(getModel()->getActionHeap());
* LATENCY = this is a heap entry to warn us when the latency is payed
* MAX_DURATION =this is a heap entry to warn us when the max_duration limit is reached
*/
-void Action::heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat)
+void Action::heapInsert(heap_type& heap, double key, enum heap_action_type hat)
{
hat_ = hat;
- xbt_heap_push(heap, this, key);
+ heapHandle_ = heap.emplace(std::make_pair(key, this));
}
-void Action::heapRemove(xbt_heap_t heap)
+void Action::heapRemove(heap_type& heap)
{
hat_ = NOTSET;
- if (indexHeap_ >= 0) {
- xbt_heap_remove(heap, indexHeap_);
+ if (heapHandle_) {
+ heap.erase(*heapHandle_);
+ clearHeapHandle();
}
}
-void Action::heapUpdate(xbt_heap_t heap, double key, enum heap_action_type hat)
+void Action::heapUpdate(heap_type& heap, double key, enum heap_action_type hat)
{
hat_ = hat;
- if (indexHeap_ >= 0) {
- xbt_heap_update(heap, indexHeap_, key);
- }else{
- xbt_heap_push(heap, this, key);
+ if (heapHandle_) {
+ heap.update(*heapHandle_, std::make_pair(key, this));
+ } else {
+ heapHandle_ = heap.emplace(std::make_pair(key, this));
}
}
-void Action::updateIndexHeap(int i) {
- indexHeap_ = i;
-}
-
double Action::getRemains()
{
XBT_IN("(%p)", this);
return remains_;
}
-double Action::getRemainsNoUpdate()
-{
- return remains_;
-}
-
}
}
#define SURF_MODEL_H_
#include "xbt/signal.hpp"
+#include "xbt/utility.hpp"
#include "src/surf/surf_private.hpp"
#include "surf/surf.hpp"
-#include "xbt/heap.h"
#include "xbt/str.h"
+#include <boost/heap/pairing_heap.hpp>
#include <boost/intrusive/list.hpp>
+#include <boost/optional.hpp>
+#include <cmath>
#include <set>
#include <string>
#include <unordered_map>
*********/
/* user-visible parameters */
+XBT_PUBLIC_DATA(double) sg_maxmin_precision;
+XBT_PUBLIC_DATA(double) sg_surf_precision;
+XBT_PUBLIC_DATA(int) sg_concurrency_limit;
+
extern XBT_PRIVATE double sg_tcp_gamma;
extern XBT_PRIVATE double sg_latency_factor;
extern XBT_PRIVATE double sg_bandwidth_factor;
extern XBT_PRIVATE std::unordered_map<std::string, tmgr_trace_t> traces_set_list;
extern XBT_PRIVATE std::set<std::string> watched_hosts;
+static inline void double_update(double* variable, double value, double precision)
+{
+ // printf("Updating %g -= %g +- %g\n",*variable,value,precision);
+ // xbt_assert(value==0 || value>precision);
+ // Check that precision is higher than the machine-dependent size of the mantissa. If not, brutal rounding may
+ // happen, and the precision mechanism is not active...
+ // xbt_assert(*variable< (2<<DBL_MANT_DIG)*precision && FLT_RADIX==2);
+ *variable -= value;
+ if (*variable < precision)
+ *variable = 0.0;
+}
+
+static inline int double_positive(double value, double precision)
+{
+ return (value > precision);
+}
+
+static inline int double_equals(double value1, double value2, double precision)
+{
+ return (fabs(value1 - value2) < precision);
+}
+
extern "C" {
XBT_PUBLIC(double) surf_get_clock();
}
* Action *
**********/
-XBT_PRIVATE void surf_action_lmm_update_index_heap(void *action, int i);
-
/** \ingroup SURF_models
* \brief List of initialized models
*/
namespace simgrid {
namespace surf {
+typedef std::pair<double, simgrid::surf::Action*> heap_element_type;
+typedef boost::heap::pairing_heap<heap_element_type, boost::heap::constant_time_size<false>, boost::heap::stable<true>,
+ boost::heap::compare<simgrid::xbt::HeapComparator<heap_element_type>>>
+ heap_type;
+
/** @ingroup SURF_interface
* @brief SURF action interface class
* @details An action is an event generated by a resource (e.g.: a communication for the network)
void finish(Action::State state);
/** @brief Get the [state](\ref simgrid::surf::Action::State) of the current Action */
- Action::State getState(); /**< get the state*/
+ Action::State getState() const; /**< get the state*/
/** @brief Set the [state](\ref simgrid::surf::Action::State) of the current Action */
virtual void setState(Action::State state);
/** @brief Get the bound of the current Action */
- double getBound();
+ double getBound() const;
/** @brief Set the bound of the current Action */
void setBound(double bound);
/** @brief Get the start time of the current action */
- double getStartTime();
+ double getStartTime() const { return start_; }
/** @brief Get the finish time of the current action */
- double getFinishTime();
+ double getFinishTime() const { return finishTime_; }
/** @brief Get the user data associated to the current action */
- void *getData() {return data_;}
+ void* getData() const { return data_; }
/** @brief Set the user data associated to the current action */
- void setData(void* data);
+ void setData(void* data) { data_ = data; }
/** @brief Get the cost of the current action */
- double getCost() {return cost_;}
+ double getCost() const { return cost_; }
/** @brief Set the cost of the current action */
void setCost(double cost) {cost_ = cost;}
/** @brief Get the remaining time of the current action after updating the resource */
virtual double getRemains();
/** @brief Get the remaining time of the current action without updating the resource */
- double getRemainsNoUpdate();
+ double getRemainsNoUpdate() const { return remains_; }
/** @brief Set the finish time of the current action */
void setFinishTime(double value) {finishTime_ = value;}
virtual bool isSuspended();
/** @brief Get the maximum duration of the current action */
- double getMaxDuration() {return maxDuration_;}
+ double getMaxDuration() const { return maxDuration_; }
/** @brief Set the maximum duration of the current Action */
virtual void setMaxDuration(double duration);
/** @brief Get the tracing category associated to the current action */
- char *getCategory() {return category_;}
+ char* getCategory() const { return category_; }
/** @brief Set the tracing category of the current Action */
void setCategory(const char *category);
/** @brief Get the priority of the current Action */
- double getPriority() { return sharingWeight_; };
+ double getPriority() const { return sharingWeight_; };
/** @brief Set the priority of the current Action */
virtual void setSharingWeight(double priority);
void setSharingWeightNoUpdate(double weight) { sharingWeight_ = weight; }
/** @brief Get the state set in which the action is */
- ActionList* getStateSet() {return stateSet_;};
+ ActionList* getStateSet() const { return stateSet_; };
s_xbt_swag_hookup_t stateHookup_ = {nullptr,nullptr};
- simgrid::surf::Model* getModel() { return model_; }
+ simgrid::surf::Model* getModel() const { return model_; }
protected:
ActionList* stateSet_;
double lastValue_ = 0;
lmm_variable_t variable_ = nullptr;
enum heap_action_type hat_ = NOTSET;
- int indexHeap_;
+ boost::optional<heap_type::handle_type> heapHandle_ = boost::none;
public:
virtual void updateRemainingLazy(double now) { THROW_IMPOSSIBLE; };
- void heapInsert(xbt_heap_t heap, double key, enum heap_action_type hat);
- void heapRemove(xbt_heap_t heap);
- void heapUpdate(xbt_heap_t heap, double key, enum heap_action_type hat);
- void updateIndexHeap(int i);
- lmm_variable_t getVariable() {return variable_;}
+ void heapInsert(heap_type& heap, double key, enum heap_action_type hat);
+ void heapRemove(heap_type& heap);
+ void heapUpdate(heap_type& heap, double key, enum heap_action_type hat);
+ void clearHeapHandle() { heapHandle_ = boost::none; }
+ lmm_variable_t getVariable() const { return variable_; }
void setVariable(lmm_variable_t var) { variable_ = var; }
- double getLastUpdate() {return lastUpdate_;}
+ double getLastUpdate() const { return lastUpdate_; }
void refreshLastUpdate() {lastUpdate_ = surf_get_clock();}
- double getLastValue() { return lastValue_; }
+ double getLastValue() const { return lastValue_; }
void setLastValue(double val) { lastValue_ = val; }
- enum heap_action_type getHat() { return hat_; }
- bool is_linked() {return action_lmm_hook.is_linked();}
- int getIndexHeap() { return indexHeap_; }
+ enum heap_action_type getHat() const { return hat_; }
+ bool is_linked() const { return action_lmm_hook.is_linked(); }
protected:
int suspended_ = 0;
};
virtual ~Model();
/** @brief Get the set of [actions](@ref Action) in *ready* state */
- virtual ActionList* getReadyActionSet() {return readyActionSet_;}
+ virtual ActionList* getReadyActionSet() const { return readyActionSet_; }
/** @brief Get the set of [actions](@ref Action) in *running* state */
- virtual ActionList* getRunningActionSet() {return runningActionSet_;}
+ virtual ActionList* getRunningActionSet() const { return runningActionSet_; }
/** @brief Get the set of [actions](@ref Action) in *failed* state */
- virtual ActionList* getFailedActionSet() {return failedActionSet_;}
+ virtual ActionList* getFailedActionSet() const { return failedActionSet_; }
/** @brief Get the set of [actions](@ref Action) in *done* state */
- virtual ActionList* getDoneActionSet() {return doneActionSet_;}
+ virtual ActionList* getDoneActionSet() const { return doneActionSet_; }
/** @brief Get the set of modified [actions](@ref Action) */
- virtual ActionLmmListPtr getModifiedSet() {return modifiedSet_;}
+ virtual ActionLmmListPtr getModifiedSet() const { return modifiedSet_; }
/** @brief Get the maxmin system of the current Model */
- lmm_system_t getMaxminSystem() {return maxminSystem_;}
+ lmm_system_t getMaxminSystem() const { return maxminSystem_; }
/**
* @brief Get the update mechanism of the current Model
* @see e_UM_t
*/
- e_UM_t getUpdateMechanism() {return updateMechanism_;}
+ e_UM_t getUpdateMechanism() const { return updateMechanism_; }
void setUpdateMechanism(e_UM_t mechanism) { updateMechanism_ = mechanism; }
/** @brief Get Action heap */
- xbt_heap_t getActionHeap() {return actionHeap_;}
+ heap_type& getActionHeap() { return actionHeap_; }
+
+ double actionHeapTopDate() const { return actionHeap_.top().first; }
+ Action* actionHeapPop();
+ bool actionHeapIsEmpty() const { return actionHeap_.empty(); }
/**
* @brief Share the resources between the actions
ActionLmmListPtr modifiedSet_;
lmm_system_t maxminSystem_ = nullptr;
bool selectiveUpdate_;
- xbt_heap_t actionHeap_;
private:
e_UM_t updateMechanism_ = UM_UNDEFINED;
ActionList* runningActionSet_; /**< Actions in state SURF_ACTION_RUNNING */
ActionList* failedActionSet_; /**< Actions in state SURF_ACTION_FAILED */
ActionList* doneActionSet_; /**< Actions in state SURF_ACTION_DONE */
+ heap_type actionHeap_;
};
}
#define SURF_SURF_PRIVATE_HPP
#include "src/surf/trace_mgr.hpp"
-#include "surf/maxmin.hpp"
#include "surf/surf.hpp"
#define NO_MAX_DURATION -1.0
};
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;
#include "xbt/graph.h"
#include "graph_private.h"
#include "xbt/dict.h"
-#include "xbt/heap.h"
#include <errno.h>
#include <stdio.h>
+++ /dev/null
-/* a generic and efficient heap */
-
-/* Copyright (c) 2004-2005, 2007-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/sysdep.h"
-#include "xbt/log.h"
-#include "heap_private.h"
-
-#include <stdio.h>
-XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_heap, xbt, "Heap");
-
-static void xbt_heap_max_heapify(xbt_heap_t H, int i);
-static void xbt_heap_increase_key(xbt_heap_t H, int i);
-
-/** @addtogroup XBT_heap
- * \brief This section describes the API to generic heap with O(log(n)) access.
- */
-
-/**
- * @brief Creates a new heap.
- * \param init_size initial size of the heap
- * \param free_func function to call on each element when you want to free the whole heap (or NULL if nothing to do).
- *
- * Creates a new heap.
- */
-inline xbt_heap_t xbt_heap_new(int init_size, void_f_pvoid_t const free_func)
-{
- xbt_heap_t H = xbt_new0(struct xbt_heap, 1);
- H->size = init_size;
- H->count = 0;
- H->items = (xbt_heap_item_t) xbt_new0(struct xbt_heap_item, init_size);
- H->free = free_func;
- return H;
-}
-
-/**
- * @brief Set the update callback function.
- * @param H the heap we're working on
- * \param update_callback function to call on each element to update its index when needed.
- */
-inline void xbt_heap_set_update_callback(xbt_heap_t H, void (*update_callback) (void*, int))
-{
- H->update_callback = update_callback;
-}
-
-/**
- * @brief kilkil a heap and its content
- * @param H poor victim
- */
-void xbt_heap_free(xbt_heap_t H)
-{
- if (!H)
- return;
-
- if (H->free)
- for (int i = 0; i < H->count; i++)
- H->free(H->items[i].content);
- free(H->items);
- free(H);
-}
-
-/**
- * @brief returns the number of elements in the heap
- * @param H the heap we're working on
- * @return the number of elements in the heap
- */
-inline int xbt_heap_size(xbt_heap_t H)
-{
- return (H->count);
-}
-
-/**
- * @brief Add an element into the heap.
- * \param H the heap we're working on
- * \param content the object you want to add to the heap
- * \param key the key associated to this object
- *
- * The element with the smallest key is automatically moved at the top of the heap.
- */
-void xbt_heap_push(xbt_heap_t H, void *content, double key)
-{
- H->count += 1;
- int count = H->count;
-
- int size = H->size;
- xbt_heap_item_t item;
-
- if (count > size) {
- H->size = (size << 1) + 1;
- H->items = (void *) xbt_realloc(H->items, (H->size) * sizeof(struct xbt_heap_item));
- xbt_assert(H->items != NULL);
- }
-
- item = &(H->items[count - 1]);
- item->key = key;
- item->content = content;
- xbt_heap_increase_key(H, count - 1);
- XBT_DEBUG("Heap has now %d elements and max elem is %g",xbt_heap_size(H),xbt_heap_maxkey(H));
-}
-
-/**
- * @brief Extracts from the heap and returns the element with the smallest key.
- * \param H the heap we're working on
- * \return the element with the smallest key
- *
- * Extracts from the heap and returns the element with the smallest key. The element with the next smallest key is
- * automatically moved at the top of the heap.
- */
-void *xbt_heap_pop(xbt_heap_t H)
-{
- xbt_heap_item_t items = H->items;
- int size = H->size;
- void *max;
-
- if (H->count == 0)
- return NULL;
-
- XBT_DEBUG("Heap has %d elements before extraction and max elem was %g",xbt_heap_size(H),xbt_heap_maxkey(H));
-
- max = CONTENT(H, 0);
-
- items[0] = items[(H->count) - 1];
- (H->count)--;
- xbt_heap_max_heapify(H,0);
- if (H->count < size >> 2 && size > 16) {
- size = (size >> 1) + 1;
- H->items = (void *) xbt_realloc(items, size * sizeof(struct xbt_heap_item));
- H->size = size;
- }
-
- if (H->update_callback)
- H->update_callback(max, -1);
- return max;
-}
-
-/**
- * @brief Extracts from the heap and returns the element at position i.
- * \param H the heap we're working on
- * \param i element position
- * \return the element at position i if ok, NULL otherwise
- *
- * Extracts from the heap and returns the element at position i. The heap is automatically reordered.
- */
-void *xbt_heap_remove(xbt_heap_t H, int i)
-{
- XBT_DEBUG("Heap has %d elements: extracting element %d",xbt_heap_size(H),i);
-
- if ((i < 0) || (i > H->count - 1))
- return NULL;
- /* put element i at head */
- if (i > 0) {
- KEY(H, i) = MIN_KEY_VALUE;
- xbt_heap_increase_key(H, i);
- }
-
- return xbt_heap_pop(H);
-}
-
-/** @brief Remove an arbitrary element from the heap
- * \param H the heap we're working on
- * \param content the object you want to remove from the heap
- * \param key the key associated to this object
- * \return the removed element if found, NULL otherwise
- */
-void *xbt_heap_rm_elm(xbt_heap_t H, void *content, double key)
-{
- int i=0;
- while (i < H->count && (KEY(H, i) != key || CONTENT(H, i) != content))
- i++;
- return xbt_heap_remove(H, i);
-}
-
-/**
- * @brief Updates an element of the heap with a new value.
- * \param H the heap we're working on
- * \param i element position
- * \param key new value for the element
- *
- * Updates an element of the heap with a new value.
- */
-void xbt_heap_update(xbt_heap_t H, int i, double key)
-{
- XBT_DEBUG("Heap has %d elements: updating element %d : was %1.12f to %1.12f ",xbt_heap_size(H),i,KEY(H, i), key);
-
- if ((i < 0) || (i > H->count - 1) || key == KEY(H, i))
- return ;
-
- if(key< KEY(H, i)){
- KEY(H, i)=key;
- xbt_heap_increase_key(H, i);
- }else{
- KEY(H, i)=key;
- xbt_heap_max_heapify(H,i);
- }
-}
-
-/**
- * @brief returns the smallest key in the heap (heap unchanged)
- * \param H the heap we're working on
- *
- * \return the smallest key in the heap without modifying the heap.
- */
-inline double xbt_heap_maxkey(xbt_heap_t H)
-{
- xbt_assert(H->count != 0, "Empty heap");
- return KEY(H, 0);
-}
-
-/**
- * @brief returns the value associated to the smallest key in the heap (heap unchanged)
- * \param H the heap we're working on
- *
- * \return the value associated to the smallest key in the heap
- * without modifying the heap.
- */
-void *xbt_heap_maxcontent(xbt_heap_t H)
-{
- xbt_assert(H->count != 0, "Empty heap");
- return CONTENT(H, 0);
-}
-
-/* <<<< private >>>>
- * \param H the heap we're working on
- *
- * Restores the heap property once an element has been deleted.
- */
-static void xbt_heap_max_heapify(xbt_heap_t H, int index)
-{
- int i = index;
- int count = H->count;
- xbt_heap_item_t items = H->items;
-
- while (1) {
- int greatest = i;
- int l = LEFT(i);
- int r = l + 1;
- if (l < count && items[l].key < items[i].key)
- greatest = l;
- if (r < count && items[r].key < items[greatest].key)
- greatest = r;
- if (greatest != i) {
- struct xbt_heap_item tmp = items[i];
- items[i] = items[greatest];
- items[greatest] = tmp;
- if (H->update_callback)
- H->update_callback(items[i].content, i);
- i = greatest;
- } else {
- if (H->update_callback)
- H->update_callback(items[i].content, i);
- return;
- }
- }
-}
-
-/* <<<< private >>>>
- * \param H the heap we're working on
- * \param i an item position in the heap
- *
- * Moves up an item at position i to its correct position. Works only when called from xbt_heap_push.
- * Do not use otherwise.
- */
-static void xbt_heap_increase_key(xbt_heap_t H, int i)
-{
- xbt_heap_item_t items = H->items;
- int p = PARENT(i);
- while (i > 0 && items[p].key > items[i].key) {
- struct xbt_heap_item tmp = items[i];
- items[i] = items[p];
- items[p] = tmp;
- if (H->update_callback)
- H->update_callback(items[i].content, i);
- i = p;
- p = PARENT(i);
- }
- if (H->update_callback)
- H->update_callback(items[i].content, i);
-}
+++ /dev/null
-/* Copyright (c) 2004-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 XBT_HEAP_PRIVATE_H
-#define XBT_HEAP_PRIVATE_H
-
-#include <float.h>
-#include <xbt/dynar.h>
-#include <xbt/heap.h>
-
-typedef struct xbt_heap_item {
- void *content;
- double key;
-} s_xbt_heap_item_t;
-typedef s_xbt_heap_item_t* xbt_heap_item_t;
-
-typedef struct xbt_heap {
- int size;
- int count;
- s_xbt_heap_item_t* items; /* array of structs */
- void_f_pvoid_t free;
- void (*update_callback) (void *, int);
-} s_xbt_heap_t;
-
-#define PARENT(i) (i >> 1)
-#define LEFT(i) (i << 1)
-#define RIGHT(i) ((i << 1) + 1)
-
-#define KEY(H,i) ((H->items)[i]).key
-#define CONTENT(H,i) ((H->items)[i]).content
-
-#define MIN_KEY_VALUE -DBL_MAX
-
-#endif
XBT_LOG_CONNECT(xbt_backtrace);
XBT_LOG_CONNECT(xbt_exception);
XBT_LOG_CONNECT(xbt_graph);
- XBT_LOG_CONNECT(xbt_heap);
XBT_LOG_CONNECT(xbt_mallocator);
XBT_LOG_CONNECT(xbt_memory_map);
XBT_LOG_CONNECT(xbt_parmap);
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 */
/* 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.h"
+#include "xbt/ex.hpp"
#include "xbt/synchro.h"
#include "simgrid/simix.h" /* used implementation */
simcall_cond_wait((smx_cond_t)cond, (smx_mutex_t)mutex);
}
-void xbt_cond_timedwait(xbt_cond_t cond, xbt_mutex_t mutex, double delay)
+int xbt_cond_timedwait(xbt_cond_t cond, xbt_mutex_t mutex, double delay)
{
- simcall_cond_wait_timeout((smx_cond_t)cond, (smx_mutex_t)mutex, delay);
+ try {
+ simcall_cond_wait_timeout((smx_cond_t)cond, (smx_mutex_t)mutex, delay);
+ } catch (xbt_ex& e) {
+ if (e.category == timeout_error) {
+ return 1;
+ } else {
+ throw; // rethrow the exceptions that I don't know
+ }
+ }
+ return 0;
}
void xbt_cond_signal(xbt_cond_t cond)
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;
int i;
};
-static void test_type_by_name(simgrid::mc::RemoteClient& process, s_foo my_foo)
+static void test_type_by_name(simgrid::mc::RemoteClient& process, s_foo /*my_foo*/)
{
assert(process.binary_info->full_types_by_name.find("struct s_foo") != process.binary_info->full_types_by_name.end());
}
# C examples
-foreach(x actions-comm actions-storage cloud-sharing get_sender host_on_off host_on_off_recv host_on_off_processes
+foreach(x actions-comm actions-storage cloud-sharing get_sender host_on_off host_on_off_recv host_on_off_processes
+ process-yield
trace_integration)
add_executable (${x} ${x}/${x}.c)
target_link_libraries(${x} simgrid)
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}/actions-comm/actions-comm_split_d.xml
${CMAKE_CURRENT_SOURCE_DIR}/actions-storage/actions-storage_d.xml
${CMAKE_CURRENT_SOURCE_DIR}/app-bittorrent/app-bittorrent_d.xml
- ${CMAKE_CURRENT_SOURCE_DIR}/trace_integration/test-hbp1.0-hbp1.0-hbp1.0.xml
+ ${CMAKE_CURRENT_SOURCE_DIR}/process-yield/process-yield_d.xml
+ ${CMAKE_CURRENT_SOURCE_DIR}/trace_integration/test-hbp1.0-hbp1.0-hbp1.0.xml
${CMAKE_CURRENT_SOURCE_DIR}/trace_integration/test-hbp1.0-hbp3.0-hbp4.0.xml
${CMAKE_CURRENT_SOURCE_DIR}/trace_integration/test-hbp1.5-hbp1.5.xml
${CMAKE_CURRENT_SOURCE_DIR}/trace_integration/test-hbp1-c0s0-c0s1.xml
${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
+ process-yield
+ 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();
> Passed: (Xx)2 with 1 load (100000000flops) took 0.1s as expected
> ### Test '( ooo )2'. 3 tasks on a bicore PM
> Passed: (xxX)2 with 0.6667 load (66666666flops) took 0.1s as expected
-> Passed: (Xxx)2 with 0.6667 load (66666666flops) took 0.1s as expected
> Passed: (xXx)2 with 0.6667 load (66666666flops) took 0.1s as expected
+> Passed: (Xxx)2 with 0.6667 load (66666666flops) took 0.1s as expected
> # TEST ON TWO-CORE PMs AND SINGLE-CORE VMs
> ## Check impact of a single VM (no degradation for the moment)
> ### Test '( [o]1 )2'. A task in a VM on a bicore PM
> Passed: ( [x]1 [X]1 [ ]1 )2 with 1 load (100000000flops) took 0.1s as expected
> ### Put three VMs on a PM, and put a task to each VM
> Passed: ( [X]1 [o]1 [o]1 )2 with 0.6667 load (66666666flops) took 0.1s as expected
-> Passed: ( [o]1 [o]1 [X]1 )2 with 0.6667 load (66666666flops) took 0.1s as expected
> Passed: ( [o]1 [X]1 [o]1 )2 with 0.6667 load (66666666flops) took 0.1s as expected
+> Passed: ( [o]1 [o]1 [X]1 )2 with 0.6667 load (66666666flops) took 0.1s as expected
> # TEST ON TWO-CORE PMs AND TWO-CORE VMs
> ## Check impact of a single VM (there is no degradation for the moment)
> ### Put a VM on a PM, and put a task to the VM
> Passed: ( [Xo]2 )2 with 1 load (100000000flops) took 0.1s as expected
> ### Put a VM on a PM, and put three tasks to the VM
> Passed: ( [ooX]2 )2 with 0.6667 load (66666666flops) took 0.1s as expected
-> Passed: ( [Xoo]2 )2 with 0.6667 load (66666666flops) took 0.1s as expected
> Passed: ( [oXo]2 )2 with 0.6667 load (66666666flops) took 0.1s as expected
+> Passed: ( [Xoo]2 )2 with 0.6667 load (66666666flops) took 0.1s as expected
> ## Check impact of a single VM collocated with a task (there is no degradation for the moment)
> ### Put a VM on a PM, and put a task to the PM
> Passed: ( [ ]2 X )2 with 1 load (100000000flops) took 0.1s as expected
> ### Put a VM on a PM, put one task to the PM and three tasks to the VM
> Passed: ( [ooo]2 X )2 with 0.6667 load (66666666flops) took 0.1s as expected
> Passed: ( [ooX]2 o )2 with 0.4444 load (44444444flops) took 0.1s as expected
-> Passed: ( [Xoo]2 o )2 with 0.4444 load (44444444flops) took 0.1s as expected
> Passed: ( [oXo]2 o )2 with 0.4444 load (44444444flops) took 0.1s as expected
+> Passed: ( [Xoo]2 o )2 with 0.4444 load (44444444flops) took 0.1s as expected
> ### Put a VM on a PM, and put two tasks to the PM
> Passed: ( [ ]2 oX )2 with 1 load (100000000flops) took 0.1s as expected
> Passed: ( [ ]2 Xo )2 with 1 load (100000000flops) took 0.1s as expected
> ### Put a VM on a PM, put one task to the PM and one task to the VM
-> Passed: ( [o]2 Xo )2 with 0.6667 load (66666666flops) took 0.1s as expected
> Passed: ( [o]2 oX )2 with 0.6667 load (66666666flops) took 0.1s as expected
+> Passed: ( [o]2 Xo )2 with 0.6667 load (66666666flops) took 0.1s as expected
> Passed: ( [X]2 oo )2 with 0.6667 load (66666666flops) took 0.1s as expected
> ### Put a VM on a PM, put one task to the PM and two tasks to the VM
-> Passed: ( [oo]2 Xo )2 with 0.5 load (50000000flops) took 0.1s as expected
> Passed: ( [oo]2 oX )2 with 0.5 load (50000000flops) took 0.1s as expected
+> Passed: ( [oo]2 Xo )2 with 0.5 load (50000000flops) took 0.1s as expected
> Passed: ( [oX]2 oo )2 with 0.5 load (50000000flops) took 0.1s as expected
> Passed: ( [Xo]2 oo )2 with 0.5 load (50000000flops) took 0.1s as expected
> ### Put a VM on a PM, put one task to the PM and three tasks to the VM
-> Passed: ( [ooo]2 Xo )2 with 0.5 load (50000000flops) took 0.1s as expected
> Passed: ( [ooo]2 oX )2 with 0.5 load (50000000flops) took 0.1s as expected
+> Passed: ( [ooo]2 Xo )2 with 0.5 load (50000000flops) took 0.1s as expected
> Passed: ( [ooX]2 oo )2 with 0.3333 load (33333333flops) took 0.1s as expected
-> Passed: ( [Xoo]2 oo )2 with 0.3333 load (33333333flops) took 0.1s as expected
> Passed: ( [oXo]2 oo )2 with 0.3333 load (33333333flops) took 0.1s as expected
+> Passed: ( [Xoo]2 oo )2 with 0.3333 load (33333333flops) took 0.1s as expected
> # TEST ON FOUR-CORE PMs AND TWO-CORE VMs
> ## Check impact of a single VM
> ### Put a VM on a PM, and put a task to the VM
> Passed: ( [Xo]2 )4 with 1 load (100000000flops) took 0.1s as expected
> ### ( [ooo]2 )4: Put a VM on a PM, and put three tasks to the VM
> Passed: ( [ooX]2 )4 with 0.6667 load (66666666flops) took 0.1s as expected
-> Passed: ( [Xoo]2 )4 with 0.6667 load (66666666flops) took 0.1s as expected
> Passed: ( [oXo]2 )4 with 0.6667 load (66666666flops) took 0.1s as expected
+> Passed: ( [Xoo]2 )4 with 0.6667 load (66666666flops) took 0.1s as expected
> ## Check impact of a single empty VM collocated with tasks
> ### Put a VM on a PM, and put a task to the PM
> Passed: ( [ ]2 X )4 with 1 load (100000000flops) took 0.1s as expected
> Passed: ( [ ]2 Xo )4 with 1 load (100000000flops) took 0.1s as expected
> ### Put a VM on a PM, and put three tasks to the PM
> Passed: ( [ ]2 ooX )4 with 1 load (100000000flops) took 0.1s as expected
-> Passed: ( [ ]2 Xoo )4 with 1 load (100000000flops) took 0.1s as expected
> Passed: ( [ ]2 oXo )4 with 1 load (100000000flops) took 0.1s as expected
+> Passed: ( [ ]2 Xoo )4 with 1 load (100000000flops) took 0.1s as expected
> ### Put a VM on a PM, and put four tasks to the PM
> Passed: ( [ ]2 oooX )4 with 1 load (100000000flops) took 0.1s as expected
> Passed: ( [ ]2 ooXo )4 with 1 load (100000000flops) took 0.1s as expected
> Passed: ( [o]2 X )4 with 1 load (100000000flops) took 0.1s as expected
> Passed: ( [X]2 o )4 with 1 load (100000000flops) took 0.1s as expected
> ### Put a VM on a PM, and put two tasks to the PM and one task to the VM
-> Passed: ( [o]2 Xo )4 with 1 load (100000000flops) took 0.1s as expected
> Passed: ( [o]2 oX )4 with 1 load (100000000flops) took 0.1s as expected
+> Passed: ( [o]2 Xo )4 with 1 load (100000000flops) took 0.1s as expected
> Passed: ( [X]2 oo )4 with 1 load (100000000flops) took 0.1s as expected
> ### Put a VM on a PM, and put two tasks to the PM and two tasks to the VM
-> Passed: ( [oo]2 Xo )4 with 1 load (100000000flops) took 0.1s as expected
> Passed: ( [oo]2 oX )4 with 1 load (100000000flops) took 0.1s as expected
+> Passed: ( [oo]2 Xo )4 with 1 load (100000000flops) took 0.1s as expected
> Passed: ( [oX]2 oo )4 with 1 load (100000000flops) took 0.1s as expected
> Passed: ( [Xo]2 oo )4 with 1 load (100000000flops) took 0.1s as expected
> ### Put a VM on a PM, and put three tasks to the PM and one tasks to the VM
> Passed: ( [o]2 ooX )4 with 1 load (100000000flops) took 0.1s as expected
-> Passed: ( [o]2 Xoo )4 with 1 load (100000000flops) took 0.1s as expected
> Passed: ( [o]2 oXo )4 with 1 load (100000000flops) took 0.1s as expected
+> Passed: ( [o]2 Xoo )4 with 1 load (100000000flops) took 0.1s as expected
> Passed: ( [X]2 ooo )4 with 1 load (100000000flops) took 0.1s as expected
> ### Put a VM on a PM, and put three tasks to the PM and two tasks to the VM
> Passed: ( [oo]2 ooX )4 with 0.8 load (80000000flops) took 0.1s as expected
-> Passed: ( [oo]2 Xoo )4 with 0.8 load (80000000flops) took 0.1s as expected
> Passed: ( [oo]2 oXo )4 with 0.8 load (80000000flops) took 0.1s as expected
+> Passed: ( [oo]2 Xoo )4 with 0.8 load (80000000flops) took 0.1s as expected
> Passed: ( [oX]2 ooo )4 with 0.8 load (80000000flops) took 0.1s as expected
> Passed: ( [Xo]2 ooo )4 with 0.8 load (80000000flops) took 0.1s as expected
> ### Put a VM on a PM, and put three tasks to the PM and three tasks to the VM
> Passed: ( [ooo]2 ooX )4 with 0.8 load (80000000flops) took 0.1s as expected
-> Passed: ( [ooo]2 Xoo )4 with 0.8 load (80000000flops) took 0.1s as expected
> Passed: ( [ooo]2 oXo )4 with 0.8 load (80000000flops) took 0.1s as expected
+> Passed: ( [ooo]2 Xoo )4 with 0.8 load (80000000flops) took 0.1s as expected
> Passed: ( [ooX]2 ooo )4 with 0.5333 load (53333333flops) took 0.1s as expected
-> Passed: ( [Xoo]2 ooo )4 with 0.5333 load (53333333flops) took 0.1s as expected
> Passed: ( [oXo]2 ooo )4 with 0.5333 load (53333333flops) took 0.1s as expected
+> Passed: ( [Xoo]2 ooo )4 with 0.5333 load (53333333flops) took 0.1s as expected
>
>
> ## 0 test failed
--- /dev/null
+#! ./tesh
+
+$ $SG_TEST_EXENV ${bindir:=.}/process-yield ${srcdir:=.}/../../../examples/platforms/small_platform_fatpipe.xml ${srcdir:=.}/process-yield_d.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n"
+> [ 0.000000] (1:yielder@Tremblay) I yielded 10 times. Goodbye now!
+> [ 0.000000] (2:yielder@Ruby) I yielded 15 times. Goodbye now!
--- /dev/null
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid/simgrid.dtd">
+<platform version="4.1">
+ <actor host="Tremblay" function="yielder">
+ <argument value="10"/> <!-- Number of yields to do -->
+ </actor>
+ <actor host="Ruby" function="yielder">
+ <argument value="15"/> <!-- Number of yields to do -->
+ </actor>
+</platform>
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)
> [ 4.600000] (host@bob) process 4 goes to sleep for 2 seconds
> [ 5.500000] (host@bob) process 5 is writing again!
> [ 5.600000] (host@bob) process 5 goes to sleep for 1 seconds
-> [ 6.600000] (host@bob) process 4 is reading!
-> [ 6.600000] (host@bob) process 5 is reading!
> [ 6.600000] (host@bob) process 1 is reading!
> [ 6.600000] (host@bob) process 2 is reading!
> [ 6.600000] (host@bob) process 3 is reading!
-> [ 6.750000] (host@bob) process 4 goes to sleep for 4 seconds
-> [ 6.750000] (host@bob) process 5 goes to sleep for 5 seconds
+> [ 6.600000] (host@bob) process 4 is reading!
+> [ 6.600000] (host@bob) process 5 is reading!
> [ 6.750000] (host@bob) process 1 goes to sleep for 1 seconds
> [ 6.750000] (host@bob) process 2 goes to sleep for 2 seconds
> [ 6.750000] (host@bob) process 3 goes to sleep for 3 seconds
+> [ 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
#include "simgrid/s4u.hpp"
#include <string>
+#include <xbt/string.hpp>
XBT_LOG_NEW_DEFAULT_CATEGORY(storage, "Messages specific for this simulation");
}
}
-static sg_size_t write_local_file(const char* dest, sg_size_t file_size)
+static sg_size_t write_local_file(const std::string& dest, sg_size_t file_size)
{
- simgrid::s4u::File* file = new simgrid::s4u::File(dest, nullptr);
- sg_size_t written = file->write(file_size);
+ simgrid::s4u::File file(dest, nullptr);
+ sg_size_t written = file.write(file_size);
XBT_INFO("%llu bytes on %llu bytes have been written by %s on /sd1", written, file_size,
simgrid::s4u::Actor::self()->getCname());
- delete file;
return written;
}
-static sg_size_t read_local_file(const char* src)
+static sg_size_t read_local_file(const std::string& src)
{
- simgrid::s4u::File* file = new simgrid::s4u::File(src, nullptr);
- sg_size_t file_size = file->size();
- sg_size_t read = file->read(file_size);
-
- XBT_INFO("%s has read %llu on %s", simgrid::s4u::Actor::self()->getCname(), read, src);
- delete file;
-
+ simgrid::s4u::File file(src, nullptr);
+ sg_size_t file_size = file.size();
+ sg_size_t read = file.read(file_size);
+ XBT_INFO("%s has read %llu on %s", simgrid::s4u::Actor::self()->getCname(), read, src.c_str());
return read;
}
// Read src file on local disk and send a put message to remote host (size of message = size of src file)
-static void hsm_put(const char* remote_host, const char* src, const char* dest)
+static void hsm_put(const std::string& remote_host, const std::string& src, const std::string& dest)
{
// Read local src file, and return the size that was actually read
sg_size_t read_size = read_local_file(src);
// Send file
- XBT_INFO("%s sends %llu to %s", simgrid::s4u::this_actor::getCname(), read_size, remote_host);
- char* payload = bprintf("%s %llu", dest, read_size);
+ XBT_INFO("%s sends %llu to %s", simgrid::s4u::this_actor::getCname(), read_size, remote_host.c_str());
+ std::string* payload = new std::string(simgrid::xbt::string_printf("%s %llu", dest.c_str(), read_size));
simgrid::s4u::MailboxPtr mailbox = simgrid::s4u::Mailbox::byName(remote_host);
mailbox->put(payload, static_cast<double>(read_size));
simgrid::s4u::this_actor::sleep_for(.4);
}
}
-static void dump_storage_by_name(const char* name)
+static void dump_storage_by_name(const std::string& name)
{
XBT_INFO("*** Dump a storage element ***");
simgrid::s4u::Storage* storage = simgrid::s4u::Storage::byName(name);
display_storage_content(storage);
}
-static void get_set_storage_data(const char* storage_name)
+static void get_set_storage_data(const std::string& storage_name)
{
- XBT_INFO("*** GET/SET DATA for storage element: %s ***", storage_name);
+ XBT_INFO("*** GET/SET DATA for storage element: %s ***", storage_name.c_str());
simgrid::s4u::Storage* storage = simgrid::s4u::Storage::byName(storage_name);
char* data = static_cast<char*>(storage->getUserdata());
XBT_INFO("*** Storage info on %s ***", host->getCname());
for (auto const& elm : host->getMountedStorages()) {
- const char* mount_name = elm.first.c_str();
+ const std::string& mount_name = elm.first;
simgrid::s4u::Storage* storage = elm.second;
- XBT_INFO("\tStorage name: %s, mount name: %s", storage->getCname(), mount_name);
+ XBT_INFO("\tStorage name: %s, mount name: %s", storage->getCname(), mount_name.c_str());
sg_size_t free_size = storage->getSizeFree();
sg_size_t used_size = storage->getSizeUsed();
hsm_put("alice", "/home/doc/simgrid/examples/msg/alias/masterslave_forwarder_with_alias.c", "c:\\Windows\\tata.c");
simgrid::s4u::MailboxPtr mailbox = simgrid::s4u::Mailbox::byName("alice");
- mailbox->put(xbt_strdup("finalize"), 0);
+ mailbox->put(new std::string("finalize"), 0);
get_set_storage_data("Disk1");
}
XBT_INFO("Server waiting for transfers ...");
while (1) {
- char* msg = static_cast<char*>(mailbox->get());
- if (not strcmp(msg, "finalize")) { // Shutdown ...
- xbt_free(msg);
+ std::string* msg = static_cast<std::string*>(mailbox->get());
+ if (*msg == "finalize") { // Shutdown ...
+ delete msg;
break;
} else { // Receive file to save
- char* saveptr;
- char* dest = strtok_r(msg, " ", &saveptr);
- sg_size_t size_to_write = std::stoull(strtok_r(nullptr, " ", &saveptr));
+ size_t pos = msg->find(' ');
+ std::string dest = msg->substr(0, pos);
+ sg_size_t size_to_write = std::stoull(msg->substr(pos + 1));
write_local_file(dest, size_to_write);
- xbt_free(dest);
+ delete msg;
}
}
int main(int argc, char* argv[])
{
- simgrid::s4u::Engine* e = new simgrid::s4u::Engine(&argc, 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]);
+ e.loadPlatform(argv[1]);
simgrid::s4u::Actor::createActor("server", simgrid::s4u::Host::by_name("alice"), server);
simgrid::s4u::Actor::createActor("client", simgrid::s4u::Host::by_name("bob"), client);
- e->run();
-
- XBT_INFO("Simulated time: %g", e->getClock());
+ e.run();
- delete e;
+ XBT_INFO("Simulated time: %g", e.getClock());
return 0;
}
> [ 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
endif()
if (enable_smpi_MPICH3_testsuite AND HAVE_RAW_CONTEXTS)
- ADD_TEST(test-smpi-mpich3-perf-raw ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/perf ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests ${TESH_OPTION} -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/perf -tests=testlist -execarg=--cfg=contexts/factory:raw -execarg=--cfg=smpi/host-speed:-1)
+ ADD_TEST(test-smpi-mpich3-perf-raw ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/perf ${PERL_EXECUTABLE} ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests ${TESH_OPTION} -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -tests=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/perf/testlist -execarg=-platform\ ${CMAKE_HOME_DIRECTORY}/examples/platforms/cluster.xml -execarg=--log=root.thr:critical -execarg=--cfg=smpi/async-small-thresh:65536 -execarg=--cfg=contexts/factory:raw -execarg=--cfg=smpi/host-speed:-1)
endif()
foreach(file allredtrace commcreatep non_zero_root sendrecvl timer transp-datatype twovec dtpack indexperf manyrma
print "TAP formatted results in $tapfullfile\n";
}
}
+exit ($err_count > 0);
#\f
# ---------------------------------------------------------------------------
# Routines
#include "xbt/log.h"
#include "xbt/module.h"
#include "xbt/sysdep.h"
+#include <algorithm>
#include <cmath>
XBT_LOG_NEW_DEFAULT_CATEGORY(surf_test, "Messages specific for surf example");
-#define PRINT_VAR(var) XBT_DEBUG(#var " = %g",lmm_variable_getvalue(var))
+using namespace simgrid::surf;
+
+#define PRINT_VAR(var) XBT_DEBUG(#var " = %g", (var)->get_value())
#define SHOW_EXPR(expr) XBT_DEBUG(#expr " = %g",expr)
/* ______ */
else if (method == LAGRANGE_RENO)
lmm_set_default_protocol_function(func_reno_f, func_reno_fpi, func_reno_fpi);
- lmm_system_t Sys = lmm_system_new(1);
- lmm_constraint_t L1 = lmm_constraint_new(Sys, nullptr, a);
- lmm_constraint_t L2 = lmm_constraint_new(Sys, nullptr, b);
- lmm_constraint_t L3 = lmm_constraint_new(Sys, nullptr, a);
+ lmm_system_t Sys = new s_lmm_system_t(true);
+ lmm_constraint_t L1 = Sys->constraint_new(nullptr, a);
+ lmm_constraint_t L2 = Sys->constraint_new(nullptr, b);
+ lmm_constraint_t L3 = Sys->constraint_new(nullptr, a);
- lmm_variable_t R_1_2_3 = lmm_variable_new(Sys, nullptr, 1.0, -1.0, 3);
- lmm_variable_t R_1 = lmm_variable_new(Sys, nullptr, 1.0, -1.0, 1);
- lmm_variable_t R_2 = lmm_variable_new(Sys, nullptr, 1.0, -1.0, 1);
- lmm_variable_t R_3 = lmm_variable_new(Sys, nullptr, 1.0, -1.0, 1);
+ lmm_variable_t R_1_2_3 = Sys->variable_new(nullptr, 1.0, -1.0, 3);
+ lmm_variable_t R_1 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
+ lmm_variable_t R_2 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
+ lmm_variable_t R_3 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
- lmm_update_variable_weight(Sys, R_1_2_3, 1.0);
- lmm_update_variable_weight(Sys, R_1, 1.0);
- lmm_update_variable_weight(Sys, R_2, 1.0);
- lmm_update_variable_weight(Sys, R_3, 1.0);
+ Sys->update_variable_weight(R_1_2_3, 1.0);
+ Sys->update_variable_weight(R_1, 1.0);
+ Sys->update_variable_weight(R_2, 1.0);
+ Sys->update_variable_weight(R_3, 1.0);
- lmm_expand(Sys, L1, R_1_2_3, 1.0);
- lmm_expand(Sys, L2, R_1_2_3, 1.0);
- lmm_expand(Sys, L3, R_1_2_3, 1.0);
+ Sys->expand(L1, R_1_2_3, 1.0);
+ Sys->expand(L2, R_1_2_3, 1.0);
+ Sys->expand(L3, R_1_2_3, 1.0);
- lmm_expand(Sys, L1, R_1, 1.0);
- lmm_expand(Sys, L2, R_2, 1.0);
- lmm_expand(Sys, L3, R_3, 1.0);
+ Sys->expand(L1, R_1, 1.0);
+ Sys->expand(L2, R_2, 1.0);
+ Sys->expand(L3, R_3, 1.0);
if (method == MAXMIN) {
lmm_solve(Sys);
lagrange_solve(Sys);
double max_deviation = 0.0;
- max_deviation = MAX(max_deviation, fabs(lmm_variable_getvalue(R_1) - x));
- max_deviation = MAX(max_deviation, fabs(lmm_variable_getvalue(R_3) - x));
- max_deviation = MAX(max_deviation, fabs(lmm_variable_getvalue(R_2) - (b - a + x)));
- max_deviation = MAX(max_deviation, fabs(lmm_variable_getvalue(R_1_2_3) - (a - x)));
+ max_deviation = std::max(max_deviation, fabs(R_1->get_value() - x));
+ max_deviation = std::max(max_deviation, fabs(R_3->get_value() - x));
+ max_deviation = std::max(max_deviation, fabs(R_2->get_value() - (b - a + x)));
+ max_deviation = std::max(max_deviation, fabs(R_1_2_3->get_value() - (a - x)));
if (max_deviation > 0.00001) { // Legacy value used in lagrange.c
XBT_WARN("Max Deviation from optimal solution : %g", max_deviation);
XBT_WARN("Found x = %1.20f", x);
- XBT_WARN("Deviation from optimal solution (R_1 = %g): %1.20f", x, lmm_variable_getvalue(R_1) - x);
- XBT_WARN("Deviation from optimal solution (R_2 = %g): %1.20f", b - a + x,
- lmm_variable_getvalue(R_2) - (b - a + x));
- XBT_WARN("Deviation from optimal solution (R_3 = %g): %1.20f", x, lmm_variable_getvalue(R_3) - x);
- XBT_WARN("Deviation from optimal solution (R_1_2_3 = %g): %1.20f", a - x,
- lmm_variable_getvalue(R_1_2_3) - (a - x));
+ XBT_WARN("Deviation from optimal solution (R_1 = %g): %1.20f", x, R_1->get_value() - x);
+ XBT_WARN("Deviation from optimal solution (R_2 = %g): %1.20f", b - a + x, R_2->get_value() - (b - a + x));
+ XBT_WARN("Deviation from optimal solution (R_3 = %g): %1.20f", x, R_3->get_value() - x);
+ XBT_WARN("Deviation from optimal solution (R_1_2_3 = %g): %1.20f", a - x, R_1_2_3->get_value() - (a - x));
}
}
PRINT_VAR(R_2);
PRINT_VAR(R_3);
- lmm_variable_free(Sys, R_1_2_3);
- lmm_variable_free(Sys, R_1);
- lmm_variable_free(Sys, R_2);
- lmm_variable_free(Sys, R_3);
- lmm_system_free(Sys);
+ Sys->variable_free(R_1_2_3);
+ Sys->variable_free(R_1);
+ Sys->variable_free(R_2);
+ Sys->variable_free(R_3);
+ delete Sys;
}
static void test2(method_t method)
if (method == LAGRANGE_RENO)
lmm_set_default_protocol_function(func_reno_f, func_reno_fp, func_reno_fpi);
- lmm_system_t Sys = lmm_system_new(1);
- lmm_constraint_t CPU1 = lmm_constraint_new(Sys, nullptr, 200.0);
- lmm_constraint_t CPU2 = lmm_constraint_new(Sys, nullptr, 100.0);
+ lmm_system_t Sys = new s_lmm_system_t(true);
+ lmm_constraint_t CPU1 = Sys->constraint_new(nullptr, 200.0);
+ lmm_constraint_t CPU2 = Sys->constraint_new(nullptr, 100.0);
- lmm_variable_t T1 = lmm_variable_new(Sys, nullptr, 1.0, -1.0, 1);
- lmm_variable_t T2 = lmm_variable_new(Sys, nullptr, 1.0, -1.0, 1);
+ lmm_variable_t T1 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
+ lmm_variable_t T2 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
- lmm_update_variable_weight(Sys, T1, 1.0);
- lmm_update_variable_weight(Sys, T2, 1.0);
+ Sys->update_variable_weight(T1, 1.0);
+ Sys->update_variable_weight(T2, 1.0);
- lmm_expand(Sys, CPU1, T1, 1.0);
- lmm_expand(Sys, CPU2, T2, 1.0);
+ Sys->expand(CPU1, T1, 1.0);
+ Sys->expand(CPU2, T2, 1.0);
if (method == MAXMIN) {
lmm_solve(Sys);
PRINT_VAR(T1);
PRINT_VAR(T2);
- lmm_variable_free(Sys, T1);
- lmm_variable_free(Sys, T2);
- lmm_system_free(Sys);
+ Sys->variable_free(T1);
+ Sys->variable_free(T2);
+ delete Sys;
}
static void test3(method_t method)
if (method == LAGRANGE_RENO)
lmm_set_default_protocol_function(func_reno_f, func_reno_fp, func_reno_fpi);
- lmm_system_t Sys = lmm_system_new(1);
+ lmm_system_t Sys = new s_lmm_system_t(true);
/* Creates the constraints */
lmm_constraint_t* tmp_cnst = new lmm_constraint_t[15];
for (int i = 0; i < 15; i++)
- tmp_cnst[i] = lmm_constraint_new(Sys, nullptr, B[i]);
+ tmp_cnst[i] = Sys->constraint_new(nullptr, B[i]);
/* Creates the variables */
lmm_variable_t* tmp_var = new lmm_variable_t[16];
for (int j = 0; j < 16; j++) {
- tmp_var[j] = lmm_variable_new(Sys, nullptr, 1.0, -1.0, 15);
- lmm_update_variable_weight(Sys, tmp_var[j], 1.0);
+ tmp_var[j] = Sys->variable_new(nullptr, 1.0, -1.0, 15);
+ Sys->update_variable_weight(tmp_var[j], 1.0);
}
/* Link constraints and variables */
for (int i = 0; i < 15; i++)
for (int j = 0; j < 16; j++)
if (A[i][j])
- lmm_expand(Sys, tmp_cnst[i], tmp_var[j], 1.0);
+ Sys->expand(tmp_cnst[i], tmp_var[j], 1.0);
if (method == MAXMIN) {
lmm_solve(Sys);
PRINT_VAR(tmp_var[j]);
for (int j = 0; j < 16; j++)
- lmm_variable_free(Sys, tmp_var[j]);
+ Sys->variable_free(tmp_var[j]);
delete[] tmp_var;
delete[] tmp_cnst;
- lmm_system_free(Sys);
+ delete Sys;
for (int i = 0; i < links + 5; i++)
delete[] A[i];
delete[] A;
#include <cstdio>
#include <cstdlib>
+using namespace simgrid::surf;
+
double date;
int64_t seedx = 0;
lmm_variable_t var[nb_var];
int used[nb_cnst];
- lmm_system_t Sys = lmm_system_new(1);
+ lmm_system_t Sys = new s_lmm_system_t(true);
for (int i = 0; i < nb_cnst; i++) {
- cnst[i] = lmm_constraint_new(Sys, NULL, float_random(10.0));
+ cnst[i] = Sys->constraint_new(NULL, float_random(10.0));
int l;
if(rate_no_limit>float_random(1.0))
//Look at what happens when there is no concurrency limit
//Badly logarithmically random concurrency limit in [2^pw_base_limit+1,2^pw_base_limit+2^pw_max_limit]
l=(1<<pw_base_limit)+(1<<int_random(pw_max_limit));
- lmm_constraint_concurrency_limit_set(cnst[i],l );
+ cnst[i]->set_concurrency_limit(l);
}
for (int i = 0; i < nb_var; i++) {
- var[i] = lmm_variable_new(Sys, NULL, 1.0, -1.0, nb_elem);
+ var[i] = Sys->variable_new(NULL, 1.0, -1.0, nb_elem);
//Have a few variables with a concurrency share of two (e.g. cross-traffic in some cases)
int concurrency_share = 1 + int_random(max_share);
- lmm_variable_concurrency_share_set(var[i],concurrency_share);
+ var[i]->set_concurrency_share(concurrency_share);
for (int j = 0; j < nb_cnst; j++)
used[j] = 0;
j--;
continue;
}
- lmm_expand(Sys, cnst[k], var[i], float_random(1.5));
- lmm_expand_add(Sys, cnst[k], var[i], float_random(1.5));
+ Sys->expand(cnst[k], var[i], float_random(1.5));
+ Sys->expand_add(cnst[k], var[i], float_random(1.5));
used[k]++;
}
}
fprintf(stderr,"Max concurrency:\n");
int l=0;
for (int i = 0; i < nb_cnst; i++) {
- int j=lmm_constraint_concurrency_maximum_get(cnst[i]);
- int k=lmm_constraint_concurrency_limit_get(cnst[i]);
+ int j = cnst[i]->get_concurrency_maximum();
+ int k = cnst[i]->get_concurrency_limit();
xbt_assert(k<0 || j<=k);
if(j>l)
l=j;
fprintf(stderr,"(%i):%i/%i ",i,j,k);
- lmm_constraint_concurrency_maximum_reset(cnst[i]);
- xbt_assert(not lmm_constraint_concurrency_maximum_get(cnst[i]));
+ cnst[i]->reset_concurrency_maximum();
+ xbt_assert(not cnst[i]->get_concurrency_maximum());
if(i%10==9)
fprintf(stderr,"\n");
}
fprintf(stderr,"\nTotal maximum concurrency is %i\n",l);
- lmm_print(Sys);
+ Sys->print();
}
for (int i = 0; i < nb_var; i++)
- lmm_variable_free(Sys, var[i]);
- lmm_system_free(Sys);
+ Sys->variable_free(var[i]);
+ delete Sys;
}
unsigned int TestClasses [][4]=
XBT_DEBUG("\t CPU actions");
simgrid::surf::ActionList* action_list = surf_cpu_model_pm->getFailedActionSet();
- for(simgrid::surf::ActionList::iterator it(action_list->begin()), itNext = it, itend(action_list->end()) ;
- it != itend ; it=itNext) {
- ++itNext;
- simgrid::surf::Action *action = static_cast<simgrid::surf::CpuAction*>(&*it);
- XBT_INFO(" CPU Failed action");
- XBT_DEBUG("\t * Failed : %p", action);
- action->unref();
+ while (not action_list->empty()) {
+ simgrid::surf::Action& action = action_list->front();
+ XBT_INFO(" CPU Failed action");
+ XBT_DEBUG("\t * Failed : %p", &action);
+ action.unref();
}
action_list = surf_cpu_model_pm->getDoneActionSet();
- for(simgrid::surf::ActionList::iterator it(action_list->begin()), itNext = it, itend(action_list->end()) ;
- it != itend ; it=itNext) {
- ++itNext;
- simgrid::surf::Action *action = static_cast<simgrid::surf::CpuAction*>(&*it);
+ while (not action_list->empty()) {
+ 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();
- for(simgrid::surf::ActionList::iterator it(action_list->begin()), itNext = it, itend(action_list->end()) ;
- it != itend ; it=itNext) {
- ++itNext;
- simgrid::surf::Action *action = static_cast<simgrid::surf::NetworkAction*>(&*it);
- XBT_INFO(" Network Failed action");
- XBT_DEBUG("\t * Failed : %p", action);
- action->unref();
+ while (not action_list->empty()) {
+ simgrid::surf::Action& action = action_list->front();
+ XBT_INFO(" Network Failed action");
+ XBT_DEBUG("\t * Failed : %p", &action);
+ action.unref();
}
action_list = surf_network_model->getDoneActionSet();
- for(simgrid::surf::ActionList::iterator it(action_list->begin()), itNext = it, itend(action_list->end()) ;
- it != itend ; it=itNext) {
- ++itNext;
- simgrid::surf::Action *action = static_cast<simgrid::surf::NetworkAction*>(&*it);
+ while (not action_list->empty()) {
+ 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() ||
-foreach(x heap_bench log_large log_usage mallocator parallel_log_crashtest)
+foreach(x log_large log_usage mallocator parallel_log_crashtest)
add_executable (${x} ${x}/${x}.c)
target_link_libraries(${x} simgrid)
set_target_properties(${x} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${x})
${CMAKE_CURRENT_SOURCE_DIR}/mmalloc/mmalloc_32.tesh PARENT_SCOPE)
set(teshsuite_src ${teshsuite_src} ${CMAKE_CURRENT_SOURCE_DIR}/mmalloc/mmalloc_test.cpp PARENT_SCOPE)
-foreach(x heap_bench log_large parallel_log_crashtest parmap_test) #mallocator parmap_bench
+foreach(x log_large parallel_log_crashtest parmap_test) #mallocator parmap_bench
ADD_TESH(tesh-xbt-${x} --setenv bindir=${CMAKE_BINARY_DIR}/teshsuite/xbt/${x} --cd ${CMAKE_HOME_DIRECTORY}/teshsuite/xbt/${x} ${x}.tesh)
endforeach()
+++ /dev/null
-/* A few tests for the xbt_heap module */
-
-/* Copyright (c) 2004-2010, 2012-2015. 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 <stdio.h>
-#include <math.h>
-#include <xbt/xbt_os_time.h>
-
-#include "simgrid/msg.h"
-#include "xbt/heap.h"
-#include "xbt/sysdep.h"
-
-#define MAX_TEST 1000000
-
-static int compare_double(const void *a, const void *b)
-{
- double pa = *((double *) a);
- double pb = *((double *) b);
-
- if (pa > pb)
- return 1;
- if (pa < pb)
- return -1;
- return 0;
-}
-
-static void test_reset_heap(xbt_heap_t * heap, int size)
-{
- xbt_heap_free(*heap);
- *heap = xbt_heap_new(size, NULL);
-
- for (int i = 0; i < size; i++) {
- xbt_heap_push(*heap, NULL, (10.0 * rand() / (RAND_MAX + 1.0)));
- }
-}
-
-static void test_heap_validity(int size)
-{
- xbt_heap_t heap = xbt_heap_new(size, NULL);
- double *tab = xbt_new0(double, size);
- int i;
-
- for (i = 0; i < size; i++) {
- tab[i] = (double) (10.0 * rand() / (RAND_MAX + 1.0));
- xbt_heap_push(heap, NULL, (double) tab[i]);
- }
-
- qsort(tab, size, sizeof(double), compare_double);
-
- for (i = 0; i < size; i++) {
- if (fabs(xbt_heap_maxkey(heap) - tab[i]) > 1e-9) {
- fprintf(stderr, "Problem !\n");
- exit(1);
- }
- xbt_heap_pop(heap);
- }
- xbt_heap_free(heap);
- free(tab);
- printf("Validity test complete!\n");
-}
-
-static void test_heap_mean_operation(int size)
-{
- xbt_heap_t heap = xbt_heap_new(size, NULL);
-
- double date = xbt_os_time() * 1000000;
- for (int i = 0; i < size; i++)
- xbt_heap_push(heap, NULL, (10.0 * rand() / (RAND_MAX + 1.0)));
-
- date = xbt_os_time() * 1000000 - date;
- printf("Creation time %d size heap : %g\n", size, date);
-
- date = xbt_os_time() * 1000000;
- for (int j = 0; j < MAX_TEST; j++) {
-
- if (!(j % size) && j)
- test_reset_heap(&heap, size);
-
- double val = xbt_heap_maxkey(heap);
- xbt_heap_pop(heap);
- xbt_heap_push(heap, NULL, 3.0 * val);
- }
- date = xbt_os_time() * 1000000 - date;
- printf("Mean access time for a %d size heap : %g\n", size, date * 1.0 / (MAX_TEST + 0.0));
-
- xbt_heap_free(heap);
-}
-
-int main(int argc, char** argv)
-{
- MSG_init(&argc, argv);
-
- for (int size = 100; size < 10000; size *= 10) {
- test_heap_validity(size);
- test_heap_mean_operation(size);
- }
- return 0;
-}
+++ /dev/null
-#! ./tesh
-
-! output display
-$ $SG_TEST_EXENV ${bindir:=.}/heap_bench
-> Validity test complete!
-> Creation time 100 size heap : 6
-> Mean access time for a 100 size heap : 0.14687
-> Validity test complete!
-> Creation time 1000 size heap : 38
-> Mean access time for a 1000 size heap : 0.179765
src/include/mc/datatypes.h
src/include/mc/mc.h
src/include/simgrid/sg_config.h
- src/include/smpi/smpi_utils.hpp
- src/include/surf/datatypes.h
+ src/include/surf/datatypes.hpp
src/include/surf/maxmin.hpp
src/include/surf/surf.hpp
src/include/xbt/parmap.hpp
src/smpi/colls/colls_private.hpp
src/smpi/colls/smpi_mvapich2_selector_stampede.hpp
src/smpi/include/private.hpp
+ src/smpi/include/smpi_utils.hpp
src/surf/cpu_cas01.hpp
src/surf/cpu_interface.hpp
src/surf/cpu_ti.hpp
- src/surf/maxmin_private.hpp
src/surf/network_cm02.hpp
src/surf/network_constant.hpp
src/surf/network_interface.hpp
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/xbt/backtrace_linux.cpp
src/xbt/dict_private.h
src/xbt/graph_private.h
- src/xbt/heap_private.h
src/xbt/log_private.h
src/xbt/mallocator_private.h
src/xbt/ex.cpp
src/xbt/exception.cpp
src/xbt/graph.c
- src/xbt/heap.c
src/xbt/log.c
src/xbt/mallocator.c
src/xbt/memory_map.cpp
src/surf/ns3/ns3_simulator.cpp )
set(SURF_SRC
+ src/kernel/lmm/fair_bottleneck.cpp
+ src/kernel/lmm/lagrange.cpp
+ src/kernel/lmm/maxmin.cpp
+
src/kernel/routing/ClusterZone.cpp
src/kernel/routing/ClusterZone.hpp
src/kernel/routing/DijkstraZone.cpp
src/surf/cpu_cas01.cpp
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/maxmin.cpp
src/surf/network_cm02.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
include/xbt/function_types.h
include/xbt/future.hpp
include/xbt/graph.h
- include/xbt/heap.h
include/xbt/log.h
include/xbt/log.hpp
include/xbt/mallocator.h
set(DOC_IMG
${CMAKE_HOME_DIRECTORY}/doc/sc3-description.png
${CMAKE_HOME_DIRECTORY}/doc/webcruft/AS_hierarchy.png
+ ${CMAKE_HOME_DIRECTORY}/doc/webcruft/eclipseScreenShot.png
${CMAKE_HOME_DIRECTORY}/doc/webcruft/Paje_MSG_screenshot.jpg
${CMAKE_HOME_DIRECTORY}/doc/webcruft/Paje_MSG_screenshot_thn.jpg
${CMAKE_HOME_DIRECTORY}/doc/webcruft/SGicon.gif
# the one specific to C but refused by C++
set(warnCFLAGS "${warnCFLAGS} -Wmissing-prototypes")
- if(CMAKE_Fotran_COMPILER_ID MATCHES "GCC|PGI")
+ if(CMAKE_Fortran_COMPILER_ID MATCHES "GCC|PGI")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -Wall")
endif()
- if(CMAKE_Fotran_COMPILER_ID MATCHES "Intel")
+ if(CMAKE_Fortran_COMPILER_ID MATCHES "Intel")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -warn all")
endif()
set(CMAKE_JAVA_COMPILE_FLAGS "-Xlint")
src/xbt/log.c src/xbt/xbt_log_appender_file.c
src/xbt/xbt_log_layout_format.c src/xbt/xbt_log_layout_simple.c
src/xbt/dict.cpp src/xbt/dict_elm.c src/xbt/dict_cursor.c
- src/xbt/dynar.cpp src/xbt/heap.c src/xbt/swag.c
- src/xbt/str.c src src/xbt/snprintf.c
- src/xbt/queue.c
+ src/xbt/dynar.cpp src/xbt/swag.c
+ src/xbt/xbt_str.cpp src/xbt/snprintf.c
src/xbt/xbt_os_time.c src/xbt/xbt_os_thread.c
- src/xbt/backtrace_linux.c
+ src/xbt/backtrace_linux.cpp
${MC_SRC_BASE} ${MC_SRC})
set (mcCFLAGS "-O3 -funroll-loops -fno-strict-aliasing")
if(CMAKE_COMPILER_IS_GNUCC)
export SONAR_SCANNER_OPTS="-server"
}
installBuildWrapper() {
- curl -LsS https://sonarqube.com/static/cpp/build-wrapper-linux-x86.zip > build-wrapper-linux-x86.zip
+ curl -LsS https://sonarcloud.io/static/cpp/build-wrapper-linux-x86.zip > build-wrapper-linux-x86.zip
unzip build-wrapper-linux-x86.zip
}
installSonarQubeScanner
# See https://docs.travis-ci.com/user/sonarqube/ for more info on tokens
# don't show the token in the logs
set +x
-sonar-scanner -Dsonar.host.url=https://sonarqube.com -Dsonar.login=$SONAR_TOKEN 2>&1 \
+sonar-scanner -Dsonar.host.url=https://sonarcloud.io -Dsonar.login=$SONAR_TOKEN 2>&1 \
| grep -v 'INFO: Parsing /home/travis/build/simgrid/simgrid/Testing/CoverageInfo' \
| grep -v 'WARN: File not analysed by Sonar, so ignoring coverage: /usr/include/'
re.compile("For details see http://code.google.com/p/address-sanitizer/issues/detail\\?id=189"),
re.compile("For details see https://github.com/google/sanitizers/issues/189"),
re.compile("Python runtime initialized with LC_CTYPE=C .*"),
- re.compile("^cmake: .*? no version information available (required by cmake)"), # Seen on CircleCI
+ re.compile("cmake: /usr/local/lib/libcurl.so.4: no version information available (required by cmake)"), # Seen on CircleCI
]
TeshState().jenkins = True # This is a Jenkins build