Henri Casanova <henric@hawaii.edu> <casanova@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Henri Casanova <henric@hawaii.edu> <casanova@fac-dhcp04.ics.hawaii.edu>
Henri Casanova <henric@hawaii.edu> <casanova@fac-dhcp06.ics.hawaii.edu>
+Henri Casanova <henric@hawaii.edu> <henricasanova@gmail.com>
Stéphane Castelli <stephane.castelli@loria.fr> <scastelli@ipb.fr>
Stéphane Castelli <stephane.castelli@loria.fr> <stephane.castelli@inria.fr>
Fabien Chaix <chaix@ics.forth.gr>
Bruno Donassolo <donassbr@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Yann Duplouy <yann.duplouy@inria.fr> <duplouy@crans.org>
Pierre-François Dutot <dutot@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
-Julien Emmanuel <julien.emmanuel@atos.net>
+Julien Emmanuel <julien.emmanuel@inria.fr>
+Julien Emmanuel <julien.emmanuel@inria.fr> <julien.emmanuel@atos.net>
Lionel Eyraud-Dubois <lionel.eyraud-dubois@inria.fr>
Lionel Eyraud-Dubois <lionel.eyraud-dubois@inria.fr> <eyraud@etincel.(none)>
Lionel Eyraud-Dubois <lionel.eyraud-dubois@inria.fr> <eyraudl@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
- Many MSG tests were converted to the new S4U's interface in C, that
was extended for that.
+Simix:
+ - Remove obsolete option --cfg=contexts/parallel-threshold.
+
Fixed bugs (FG#.. -> FramaGit bugs; FG!.. -> FG merge requests)
(FG: issues on Framagit; GF: issues on GForge; GH: issues on GitHub)
- FG#41: Add sg_actor_create C interface
- FG#43: xbt::random needs some care
- FG#48: The Impossible Did Happen (yet again)
- FG!24: Documentation and fix for xbt/random
+ - FG!35: Add a modeling hint for parallel links in doc
- GF#18137: Allow different stack sizes?
- GH#128: Parallelization of simulation with --cfg=contexts/nthreads
- GH#139: Allow pthread creation in SMPI
- GH#336: Packet-level simulation using SMPI?
- GH!337: Fix link_energy plugin for wifi platforms
+ - GH!339: Add Mailbox set_receiver method to python binding
----------------------------------------------------------------------------
- Rename Energy plugin into host_energy
- Rename Load plugin into host_load
-simix:
+Simix:
- Add parameter --cfg=simix/breakpoint to raise a SIGTRAP at given time.
- kill simix::onDeadlock() that was somewhat dupplicating s4u::on_deadlock()
- Improve performance when handling timeouts of simix synchros.
- **contexts/factory:** :ref:`cfg=contexts/factory`
- **contexts/guard-size:** :ref:`cfg=contexts/guard-size`
- **contexts/nthreads:** :ref:`cfg=contexts/nthreads`
-- **contexts/parallel-threshold:** :ref:`cfg=contexts/parallel-threshold`
- **contexts/stack-size:** :ref:`cfg=contexts/stack-size`
- **contexts/synchro:** :ref:`cfg=contexts/synchro`
application.
.. _cfg=contexts/nthreads:
-.. _cfg=contexts/parallel-threshold:
.. _cfg=contexts/synchro:
Running User Code in Parallel
of cores that you have in your computer (or lower than 1 to have the
amount of cores auto-detected).
-Even if you asked several worker threads using the previous option,
-you can request to start the parallel execution (and pay the
-associated synchronization costs) only if the potential parallelism is
-large enough. For that, set the ``contexts/parallel-threshold``
-item to the minimal amount of user contexts needed to start the
-parallel execution. In any given simulation round, if that amount is
-not reached, the contexts will be run sequentially directly by the
-main thread (thus saving the synchronization costs). Note that this
-option is mainly useful when the grain of the user code is very fine,
-because our synchronization is now very efficient.
-
When parallel execution is activated, you can choose the
synchronization schema used with the ``contexts/synchro`` item,
which value is either:
Of course, this is only one possible way to model these things. YMMV ;)
+.. _howto_parallel_links:
+
+Modeling parallel links
+***********************
+
+Most HPC topologies, such as fat-trees, allow parallel links (a
+router A and a router B can be connected by more than one link).
+You might be tempted to model this configuration as follows :
+
+.. code-block:: xml
+
+ <router id="routerA"/>
+ <router id="routerB"/>
+
+ <link id="link1" bandwidth="10GBps" latency="2us"/>
+ <link id="link2" bandwidth="10GBps" latency="2us"/>
+
+ <route src="routerA" dst="routerB">
+ <link_ctn id="link1"/>
+ </route>
+ <route src="routerA" dst="routerB">
+ <link_ctn id="link2"/>
+ </route>
+
+But that will not work, since SimGrid doesn't allow several routes for
+a single `{src ; dst}` pair. Instead, what you should do is :
+
+ - Use a single route with both links (so both will be traversed
+ each time a message is exchanged between router A and B)
+
+ - Double the bandwidth of one link, to model the total bandwidth of
+ both links used in parallel. This will make sure no combined
+ communications between router A and B use more than the bandwidth
+ of two links
+
+ - Assign the other link a `FATPIPE` sharing policy, which will allow
+ several communications to use the full bandwidth of this link without
+ having to share it. This will model the fact that individual
+ communications can use at most this link's bandwidth
+
+ - Set the latency of one of the links to 0, so that latency is only
+ accounted for once (since both link are traversed by each message)
+
+So the final platform for our example becomes :
+
+.. code-block:: xml
+
+ <router id="routerA"/>
+ <router id="routerB"/>
+
+ <!-- This link limits the total bandwidth of all parallel communications -->
+ <link id="link1" bandwidth="20GBps" latency="2us"/>
+
+ <!-- This link only limits the bandwidth of individual communications -->
+ <link id="link2" bandwidth="10GBps" latency="0us" sharing_policy="FATPIPE"/>
+
+ <!-- Each message traverses both links -->
+ <route src="routerA" dst="routerB">
+ <link_ctn id="link1"/>
+ <link_ctn id="link2"/>
+ </route>
+
.. _understanding_lv08
Understanding the default TCP model
> 5 11 7 send "0 0 1"
> 5 12 7 execute "0 1 1"
> 4 13 0 6 6 ACTOR_LINK
-> 4 14 0 6 6 ACTOR_TASK_LINK
> 6 0.000000 33 6 1 "policeman-2"
> 12 0.000000 7 32 9
-> 15 0.000000 14 0 SR 33 p0
+> 15 0.000000 13 0 SR 33 p0
> 12 0.000000 7 33 11
> 13 2.000000 7 32
> 12 2.000000 7 32 10
> 13 2.025708 7 33
-> 15 2.025708 14 0 SR 33 p1
+> 15 2.025708 13 0 SR 33 p1
> 12 2.025708 7 33 11
-> 16 2.025708 14 0 SR 32 p0
+> 16 2.025708 13 0 SR 32 p0
> 15 2.025708 13 0 M 32 0
> 7 2.025708 6 32
> 6 2.025708 34 6 1 "emigrant-1"
> 13 4.025708 7 34
> 12 4.025708 7 34 10
> 13 4.025903 7 33
-> 15 4.025903 14 0 SR 33 p2
+> 15 4.025903 13 0 SR 33 p2
> 12 4.025903 7 33 11
-> 16 4.025903 14 0 SR 34 p1
+> 16 4.025903 13 0 SR 34 p1
> 15 4.025903 13 0 M 34 1
> 7 4.025903 6 34
> 6 4.025903 35 6 2 "emigrant-1"
> 13 6.025903 7 35
> 12 6.025903 7 35 10
> 13 6.044918 7 33
-> 15 6.044918 14 0 SR 33 p3
+> 15 6.044918 13 0 SR 33 p3
> 12 6.044918 7 33 11
-> 16 6.044918 14 0 SR 35 p2
+> 16 6.044918 13 0 SR 35 p2
> 15 6.044918 13 0 M 35 2
> 7 6.044918 6 35
> 6 6.044918 36 6 3 "emigrant-1"
> 13 8.044918 7 36
> 12 8.044918 7 36 10
> 13 8.070626 7 33
-> 15 8.070626 14 0 SR 33 p4
+> 15 8.070626 13 0 SR 33 p4
> 12 8.070626 7 33 11
-> 16 8.070626 14 0 SR 36 p3
+> 16 8.070626 13 0 SR 36 p3
> 15 8.070626 13 0 M 36 3
> 7 8.070626 6 36
> 6 8.070626 37 6 4 "emigrant-1"
> 13 10.070626 7 37
> 12 10.070626 7 37 10
> 13 10.087178 7 33
-> 15 10.087178 14 0 SR 33 p5
+> 15 10.087178 13 0 SR 33 p5
> 12 10.087178 7 33 11
-> 16 10.087178 14 0 SR 37 p4
+> 16 10.087178 13 0 SR 37 p4
> 15 10.087178 13 0 M 37 4
> 7 10.087178 6 37
> 6 10.087178 38 6 5 "emigrant-1"
> 13 12.087178 7 38
> 12 12.087178 7 38 10
> 13 12.112617 7 33
-> 15 12.112617 14 0 SR 33 p6
+> 15 12.112617 13 0 SR 33 p6
> 12 12.112617 7 33 11
-> 16 12.112617 14 0 SR 38 p5
+> 16 12.112617 13 0 SR 38 p5
> 15 12.112617 13 0 M 38 5
> 7 12.112617 6 38
> 6 12.112617 39 6 3 "emigrant-1"
> 13 14.112617 7 39
> 12 14.112617 7 39 10
> 13 14.138325 7 33
-> 15 14.138325 14 0 SR 33 p7
+> 15 14.138325 13 0 SR 33 p7
> 12 14.138325 7 33 11
-> 16 14.138325 14 0 SR 39 p6
+> 16 14.138325 13 0 SR 39 p6
> 15 14.138325 13 0 M 39 6
> 7 14.138325 6 39
> 6 14.138325 40 6 1 "emigrant-1"
> 13 16.138325 7 40
> 12 16.138325 7 40 10
> 13 16.138521 7 33
-> 15 16.138521 14 0 SR 33 p8
+> 15 16.138521 13 0 SR 33 p8
> 12 16.138521 7 33 11
-> 16 16.138521 14 0 SR 40 p7
+> 16 16.138521 13 0 SR 40 p7
> 15 16.138521 13 0 M 40 7
> 7 16.138521 6 40
> 6 16.138521 41 6 4 "emigrant-1"
> 13 18.138521 7 41
> 12 18.138521 7 41 10
> 13 18.155073 7 33
-> 16 18.155073 14 0 SR 41 p8
+> 16 18.155073 13 0 SR 41 p8
> 7 18.155073 6 33
> 7 18.155073 6 41
> 7 18.155073 2 16
{
xbt_assert((bucket != nullptr), "Provided a NULL bucket");
- for (auto const& id : bucket->nodes) {
+ for (auto const& id : bucket->nodes_) {
unsigned int distance = id ^ destination_id_;
nodes_.push_back(std::pair<unsigned int, unsigned int>(id, distance));
}
}
-}
+} // namespace kademlia
bool destinationFound() const;
void addBucket(const kademlia::Bucket* bucket);
};
-}
+} // namespace kademlia
#endif
Message(const Message&) = delete;
Message& operator=(const Message&) = delete;
};
-}
+} // namespace kademlia
#endif
Bucket* bucket = table.findBucket(id);
// check if the id is already in the bucket.
- auto id_pos = std::find(bucket->nodes.begin(), bucket->nodes.end(), id);
+ auto id_pos = std::find(bucket->nodes_.begin(), bucket->nodes_.end(), id);
- if (id_pos == bucket->nodes.end()) {
+ if (id_pos == bucket->nodes_.end()) {
/* We check if the bucket is full or not. If it is, we evict an old element */
- if (bucket->nodes.size() >= BUCKET_SIZE) {
- bucket->nodes.pop_back();
+ if (bucket->nodes_.size() >= BUCKET_SIZE) {
+ bucket->nodes_.pop_back();
}
- bucket->nodes.push_front(id);
+ bucket->nodes_.push_front(id);
XBT_VERB("I'm adding to my routing table %08x", id);
} else {
// We push the element to the front
- bucket->nodes.erase(id_pos);
- bucket->nodes.push_front(id);
+ bucket->nodes_.erase(id_pos);
+ bucket->nodes_.push_front(id);
XBT_VERB("I'm updating %08x", id);
}
}
for (int i = 1; answer->getSize() < BUCKET_SIZE && ((bucket_id - i > 0) || (bucket_id + i < IDENTIFIER_SIZE)); i++) {
/* We check the previous buckets */
if (bucket_id - i >= 0) {
- const Bucket* bucket_p = &table.buckets[bucket_id - i];
+ const Bucket* bucket_p = &table.getBucketAt(bucket_id - i);
answer->addBucket(bucket_p);
}
/* We check the next buckets */
if (bucket_id + i <= IDENTIFIER_SIZE) {
- const Bucket* bucket_n = &table.buckets[bucket_id + i];
+ const Bucket* bucket_n = &table.getBucketAt(bucket_id + i);
answer->addBucket(bucket_n);
}
}
// Sending the answer
msg->answer_to_->put_init(answer, 1)->detach(kademlia::destroy);
}
+
+void Node::displaySuccessRate()
+{
+ XBT_INFO("%u/%u FIND_NODE have succeeded", find_node_success, find_node_success + find_node_failed);
}
+} // namespace kademlia
/**@brief Returns an identifier which is in a specific bucket of a routing table
* @param id id of the routing table owner
* @param prefix id of the bucket where we want that identifier to be
class Node {
unsigned int id_; // node id - 160 bits
RoutingTable table; // node routing table
+ unsigned int find_node_success = 0; // Number of find_node which have succeeded.
+ unsigned int find_node_failed = 0; // Number of find_node which have failed.
public:
simgrid::s4u::CommPtr receive_comm = nullptr;
void* received_msg = nullptr;
- unsigned int find_node_success = 0; // Number of find_node which have succeeded.
- unsigned int find_node_failed = 0; // Number of find_node which have failed.
explicit Node(unsigned int node_id) : id_(node_id), table(node_id) {}
Node(const Node&) = delete;
Node& operator=(const Node&) = delete;
bool findNode(unsigned int id_to_find, bool count_in_stats);
void randomLookup();
void handleFindNode(const Message* msg);
+ void displaySuccessRate();
};
-}
+} // namespace kademlia
// identifier functions
unsigned int get_id_in_prefix(unsigned int id, unsigned int prefix);
unsigned int get_node_prefix(unsigned int id, unsigned int nb_bits);
/** @brief Initialization of a node routing table. */
RoutingTable::RoutingTable(unsigned int node_id) : id_(node_id)
{
- buckets.reserve(IDENTIFIER_SIZE + 1);
+ buckets_.reserve(IDENTIFIER_SIZE + 1);
for (unsigned int i = 0; i < IDENTIFIER_SIZE + 1; i++)
- buckets.emplace_back(i);
+ buckets_.emplace_back(i);
}
void RoutingTable::print() const
XBT_INFO("Routing table of %08x:", id_);
for (unsigned int i = 0; i <= IDENTIFIER_SIZE; i++) {
- if (not buckets[i].nodes.empty()) {
+ if (not buckets_[i].nodes_.empty()) {
XBT_INFO("Bucket number %u: ", i);
int j = 0;
- for (auto value : buckets[i].nodes) {
+ for (auto value : buckets_[i].nodes_) {
XBT_INFO("Element %d: %08x", j, value);
j++;
}
unsigned int xor_number = id_ ^ id;
unsigned int prefix = get_node_prefix(xor_number, IDENTIFIER_SIZE);
xbt_assert(prefix <= IDENTIFIER_SIZE, "Tried to return a bucket that doesn't exist.");
- return &buckets[prefix];
+ return &buckets_[prefix];
}
/** Returns if the routing table contains the id. */
bool RoutingTable::contains(unsigned int node_id)
{
const Bucket* bucket = findBucket(node_id);
- return std::find(bucket->nodes.begin(), bucket->nodes.end(), node_id) != bucket->nodes.end();
-}
+ return std::find(bucket->nodes_.begin(), bucket->nodes_.end(), node_id) != bucket->nodes_.end();
}
+} // namespace kademlia
class Bucket {
unsigned int id_; // bucket id
public:
- std::deque<unsigned int> nodes; // Nodes in the bucket.
+ std::deque<unsigned int> nodes_; // Nodes in the bucket.
unsigned int getId() const { return id_; }
explicit Bucket(unsigned int id) noexcept : id_(id) {}
};
/* Node routing table */
class RoutingTable {
unsigned int id_; // node id of the client's routing table
+ std::vector<Bucket> buckets_; // Node bucket list
public:
- std::vector<Bucket> buckets; // Node bucket list - 160 sized.
explicit RoutingTable(unsigned int node_id);
RoutingTable(const RoutingTable&) = delete;
RoutingTable& operator=(const RoutingTable&) = delete;
void print() const;
Bucket* findBucket(unsigned int id);
+ const Bucket& getBucketAt(unsigned int pos) const { return buckets_[pos]; }
bool contains(unsigned int node_id);
};
-}
+} // namespace kademlia
#endif
XBT_INFO("I couldn't join the network :(");
}
XBT_DEBUG("I'm leaving the network");
- XBT_INFO("%u/%u FIND_NODE have succeeded", node.find_node_success, node.find_node_success + node.find_node_failed);
+ node.displaySuccessRate();
}
/** @brief Main function */
namespace kademlia {
class Answer;
class Message;
-}
+} // namespace kademlia
constexpr double FIND_NODE_TIMEOUT = 10.0;
constexpr double FIND_NODE_GLOBAL_TIMEOUT = 50.0;
> 6 0.000000 1 1 0 "rank-0"
> 6 0.000000 2 1 0 "rank-1"
> 6 0.000000 3 1 0 "rank-2"
-> 5 6 2 computing "0 1 1"
-> 5 7 2 smpi_replay_run_init "0 1 0"
+> 5 6 2 smpi_replay_run_init "0 1 0"
+> 5 7 2 computing "0 1 1"
> 5 8 2 action_bcast "0 0.78 0.39"
-> 12 0.000000 2 1 7
+> 12 0.000000 2 1 6
> 13 0.000000 2 1
-> 12 0.000000 2 2 7
+> 12 0.000000 2 2 6
> 13 0.000000 2 2
-> 12 0.000000 2 3 7
+> 12 0.000000 2 3 6
> 13 0.000000 2 3
> 12 0.000000 2 1 8
> 12 0.000000 2 2 8
> 12 0.000000 2 3 8
> 13 0.000000 2 1
-> 12 0.000000 2 1 6
+> 12 0.000000 2 1 7
> 5 9 2 action_reduce "0 1 0"
> 5 10 2 smpi_replay_run_finalize "0 1 0"
> 13 0.015036 2 2
-> 12 0.015036 2 2 6
+> 12 0.015036 2 2 7
> 13 0.015676 2 3
-> 12 0.015676 2 3 6
+> 12 0.015676 2 3 7
> 13 2.636405 2 2
> 12 2.636405 2 2 8
> 13 5.097100 2 1
> 12 5.097100 2 1 8
> 13 5.097100 2 1
-> 12 5.097100 2 1 6
+> 12 5.097100 2 1 7
> 13 5.112136 2 2
-> 12 5.112136 2 2 6
+> 12 5.112136 2 2 7
> 13 6.569099 2 3
> 12 6.569099 2 3 8
> 13 6.584775 2 3
-> 12 6.584775 2 3 6
+> 12 6.584775 2 3 7
> 13 7.733505 2 2
> 12 7.733505 2 2 9
+> 12 7.733505 2 2 7
> 13 10.194200 2 1
> 12 10.194200 2 1 9
> 13 13.138198 2 3
> 12 13.138198 2 3 9
+> 12 13.138198 2 3 7
+> 12 13.153874 2 1 7
+> 13 14.286929 2 2
> 13 14.286929 2 2
> 12 14.286929 2 2 10
> 13 14.286929 2 2
> 7 14.286929 1 2
> 13 18.250974 2 1
+> 13 18.250974 2 1
> 12 18.250974 2 1 10
> 13 18.250974 2 1
> 7 18.250974 1 1
> 13 19.691622 2 3
+> 13 19.691622 2 3
> 12 19.691622 2 3 10
> 13 19.691622 2 3
> 7 19.691622 1 3
> 6 0.000000 1 1 0 "rank-0"
> 6 0.000000 2 1 0 "rank-1"
> 6 0.000000 3 1 0 "rank-2"
-> 5 6 2 computing "0 1 1"
-> 5 7 2 smpi_replay_run_init "0 1 0"
+> 5 6 2 smpi_replay_run_init "0 1 0"
+> 5 7 2 computing "0 1 1"
> 5 8 2 action_bcast "0 0.78 0.39"
-> 12 0.000000 2 1 7
+> 12 0.000000 2 1 6
> 13 0.000000 2 1
-> 12 0.000000 2 2 7
+> 12 0.000000 2 2 6
> 13 0.000000 2 2
-> 12 0.000000 2 3 7
+> 12 0.000000 2 3 6
> 13 0.000000 2 3
> 12 0.000000 2 1 8
> 12 0.000000 2 2 8
> 12 0.000000 2 3 8
> 13 0.000000 2 1
-> 12 0.000000 2 1 6
+> 12 0.000000 2 1 7
> 5 9 2 action_reduce "0 1 0"
> 5 10 2 smpi_replay_run_finalize "0 1 0"
> 13 0.015036 2 2
-> 12 0.015036 2 2 6
+> 12 0.015036 2 2 7
> 13 0.015676 2 3
-> 12 0.015676 2 3 6
+> 12 0.015676 2 3 7
> 13 2.636405 2 2
> 12 2.636405 2 2 8
> 13 5.097100 2 1
> 12 5.097100 2 1 8
> 13 5.097100 2 1
-> 12 5.097100 2 1 6
+> 12 5.097100 2 1 7
> 13 5.112136 2 2
-> 12 5.112136 2 2 6
+> 12 5.112136 2 2 7
> 13 6.569099 2 3
> 12 6.569099 2 3 8
> 13 6.584775 2 3
-> 12 6.584775 2 3 6
+> 12 6.584775 2 3 7
> 13 7.733505 2 2
> 12 7.733505 2 2 9
+> 12 7.733505 2 2 7
> 13 10.194200 2 1
> 12 10.194200 2 1 9
> 13 13.138198 2 3
> 12 13.138198 2 3 9
+> 12 13.138198 2 3 7
+> 12 13.153874 2 1 7
+> 13 14.286929 2 2
> 13 14.286929 2 2
> 12 14.286929 2 2 10
> 13 14.286929 2 2
> 7 14.286929 1 2
> 13 18.250974 2 1
+> 13 18.250974 2 1
> 12 18.250974 2 1 10
> 13 18.250974 2 1
> 7 18.250974 1 1
> 13 19.691622 2 3
+> 13 19.691622 2 3
> 12 19.691622 2 3 10
> 13 19.691622 2 3
> 7 19.691622 1 3
*
* @details This represents a position in the network. One can send information between two netpoints
*/
-class NetPoint : public simgrid::xbt::Extendable<NetPoint> {
+class NetPoint : public xbt::Extendable<NetPoint> {
public:
enum class Type { Host, Router, NetZone };
bool is_host() const { return component_type_ == Type::Host; }
bool is_router() const { return component_type_ == Type::Router; }
- static simgrid::xbt::signal<void(NetPoint&)> on_creation;
+ static xbt::signal<void(NetPoint&)> on_creation;
bool operator<(const NetPoint& rhs) const { return name_ < rhs.name_; }
XBT_PUBLIC sg_link_t sg_link_by_name(const char* name);
XBT_PUBLIC int sg_link_is_shared(const_sg_link_t link);
XBT_PUBLIC double sg_link_bandwidth(const_sg_link_t link);
+XBT_PUBLIC void sg_link_bandwidth_set(sg_link_t link, double value);
XBT_PUBLIC double sg_link_latency(const_sg_link_t link);
+XBT_PUBLIC void sg_link_latency_set(sg_link_t link, double value);
XBT_PUBLIC void* sg_link_data(const_sg_link_t link);
XBT_PUBLIC void sg_link_data_set(sg_link_t link, void* data);
XBT_PUBLIC int sg_link_count();
/** @brief Get the bandwidth in bytes per second of current Link */
double get_bandwidth() const;
+ void set_bandwidth(double value);
/** @brief Get the latency in seconds of current Link */
double get_latency() const;
+ void set_latency(double value);
/** @brief Describes how the link is shared between flows */
SharingPolicy get_sharing_policy() const;
XBT_PUBLIC int SIMIX_context_is_parallel();
XBT_PUBLIC int SIMIX_context_get_nthreads();
XBT_PUBLIC void SIMIX_context_set_nthreads(int nb_threads);
-XBT_PUBLIC int SIMIX_context_get_parallel_threshold();
-XBT_PUBLIC void SIMIX_context_set_parallel_threshold(int threshold);
XBT_PUBLIC e_xbt_parmap_mode_t SIMIX_context_get_parallel_mode();
XBT_PUBLIC void SIMIX_context_set_parallel_mode(e_xbt_parmap_mode_t mode);
XBT_PUBLIC int SIMIX_is_maestro();
// data.dec_ref(); // FIXME: why does it break python-actor-create?
return data;
},
- py::call_guard<GilScopedRelease>(), "Blocking data reception");
+ py::call_guard<GilScopedRelease>(), "Blocking data reception")
+ .def("set_receiver",
+ [](Mailbox* self, ActorPtr actor) {
+ self->set_receiver(actor);
+ },
+ py::call_guard<GilScopedRelease>(),
+ "Sets the actor as permanent receiver");
/* Class Comm */
py::class_<simgrid::s4u::Comm, simgrid::s4u::CommPtr>(m, "Comm", "Communication")
void StateType::set_event(const std::string& value_name)
{
- events_.push_back(new StateEvent(issuer_, this, PAJE_SetState, get_entity_value(value_name), nullptr));
+ events_.push_back(new StateEvent(get_issuer(), this, PAJE_SetState, get_entity_value(value_name), nullptr));
}
void StateType::push_event(const std::string& value_name, TIData* extra)
{
- events_.push_back(new StateEvent(issuer_, this, PAJE_PushState, get_entity_value(value_name), extra));
+ events_.push_back(new StateEvent(get_issuer(), this, PAJE_PushState, get_entity_value(value_name), extra));
}
void StateType::push_event(const std::string& value_name)
{
- events_.push_back(new StateEvent(issuer_, this, PAJE_PushState, get_entity_value(value_name), nullptr));
+ events_.push_back(new StateEvent(get_issuer(), this, PAJE_PushState, get_entity_value(value_name), nullptr));
}
void StateType::pop_event()
void StateType::pop_event(TIData* extra)
{
- events_.push_back(new StateEvent(issuer_, this, PAJE_PopState, nullptr, extra));
+ events_.push_back(new StateEvent(get_issuer(), this, PAJE_PopState, nullptr, extra));
}
void VariableType::instr_event(double now, double delta, const char* resource, double value)
void VariableType::set_event(double timestamp, double value)
{
- events_.push_back(new VariableEvent(timestamp, issuer_, this, PAJE_SetVariable, value));
+ events_.push_back(new VariableEvent(timestamp, get_issuer(), this, PAJE_SetVariable, value));
}
void VariableType::add_event(double timestamp, double value)
{
- events_.push_back(new VariableEvent(timestamp, issuer_, this, PAJE_AddVariable, value));
+ events_.push_back(new VariableEvent(timestamp, get_issuer(), this, PAJE_AddVariable, value));
}
void VariableType::sub_event(double timestamp, double value)
{
- events_.push_back(new VariableEvent(timestamp, issuer_, this, PAJE_SubVariable, value));
+ events_.push_back(new VariableEvent(timestamp, get_issuer(), this, PAJE_SubVariable, value));
}
void LinkType::start_event(Container* startContainer, const std::string& value, const std::string& key)
void LinkType::start_event(Container* startContainer, const std::string& value, const std::string& key, int size)
{
- new LinkEvent(issuer_, this, PAJE_StartLink, startContainer, value, key, size);
+ new LinkEvent(get_issuer(), this, PAJE_StartLink, startContainer, value, key, size);
}
void LinkType::end_event(Container* endContainer, const std::string& value, const std::string& key)
{
- new LinkEvent(issuer_, this, PAJE_EndLink, endContainer, value, key, -1);
+ new LinkEvent(get_issuer(), this, PAJE_EndLink, endContainer, value, key, -1);
}
Type* Type::by_name(const std::string& name)
std::string name_;
std::string color_;
Type* father_;
+ std::map<std::string, std::unique_ptr<Type>> children_;
+ Container* issuer_ = nullptr;
+
+protected:
+ Container* get_issuer() const { return issuer_; }
public:
static xbt::signal<void(Type&, e_event_type event_type)> on_creation;
- std::map<std::string, std::unique_ptr<Type>> children_;
- Container* issuer_ = nullptr;
Type(e_event_type event_type, const std::string& name, const std::string& alias, const std::string& color,
Type* father);
const char* get_cname() { return name_.c_str(); }
const std::string& get_color() const { return color_; }
Type* get_father() const { return father_; }
+ const std::map<std::string, std::unique_ptr<Type>>& get_children() { return children_; }
bool is_colored() { return not color_.empty(); }
Type* by_name(const std::string& name);
if (root->get_name() == "LINK")
root->by_name_or_create(std::string("b") + new_typename, color);
- for (auto const& elm : root->children_) {
+ for (auto const& elm : root->get_children()) {
recursiveNewVariableType(new_typename, color, elm.second.get());
}
}
if (root->get_name() == father_type) {
root->by_name_or_create(new_typename, color);
}
- for (auto const& elm : root->children_)
+ for (auto const& elm : root->get_children())
recursiveNewUserVariableType(father_type, new_typename, color, elm.second.get());
}
if (root->get_name() == father_type)
root->by_name_or_create<simgrid::instr::StateType>(new_typename);
- for (auto const& elm : root->children_)
+ for (auto const& elm : root->get_children())
recursiveNewUserStateType(father_type, new_typename, elm.second.get());
}
if (root->get_name() == type_name)
static_cast<simgrid::instr::StateType*>(root)->add_entity_value(val, color);
- for (auto const& elm : root->children_)
+ for (auto const& elm : root->get_children())
recursiveNewValueForUserStateType(type_name, val, color, elm.second.get());
}
}
}
-static void on_host_speed_change(s4u::Host const& host)
-{
- Container::by_name(host.get_name())
- ->get_variable("speed")
- ->set_event(surf_get_clock(), host.get_core_count() * host.get_available_speed());
-}
-
static void on_action_state_change(kernel::resource::Action const& action,
kernel::resource::Action::State /* previous */)
{
}
}
-static void on_link_bandwidth_change(s4u::Link const& link)
-{
- Container::by_name(link.get_name())
- ->get_variable("bandwidth")
- ->set_event(surf_get_clock(), sg_bandwidth_factor * link.get_bandwidth());
-}
-
-static void on_netpoint_creation(kernel::routing::NetPoint const& netpoint)
-{
- if (netpoint.is_router())
- new RouterContainer(netpoint.get_name(), currentContainer.back());
-}
-
static void on_platform_created()
{
currentContainer.clear();
static void on_actor_creation(s4u::Actor const& actor)
{
- const Container* root = Container::get_root();
- Container* container = Container::by_name(actor.get_host()->get_name());
+ const Container* root = Container::get_root();
+ Container* container = Container::by_name(actor.get_host()->get_name());
+ std::string container_name = instr_pid(actor);
- container->create_child(instr_pid(actor), "ACTOR");
+ container->create_child(container_name, "ACTOR");
ContainerType* actor_type = container->type_->by_name_or_create<ContainerType>("ACTOR");
StateType* state = actor_type->by_name_or_create<StateType>("ACTOR_STATE");
state->add_entity_value("suspend", "1 0 1");
state->add_entity_value("send", "0 0 1");
state->add_entity_value("execute", "0 1 1");
root->type_->by_name_or_create("ACTOR_LINK", actor_type, actor_type);
- root->type_->by_name_or_create("ACTOR_TASK_LINK", actor_type, actor_type);
- std::string container_name = instr_pid(actor);
actor.on_exit([container_name](bool failed) {
if (failed)
// kill means that this actor no longer exists, let's destroy it
if (TRACE_needs_platform()) {
s4u::Engine::on_platform_created.connect(on_platform_created);
s4u::Host::on_creation.connect(on_host_creation);
- s4u::Host::on_speed_change.connect(on_host_speed_change);
+ s4u::Host::on_speed_change.connect([](s4u::Host const& host) {
+ Container::by_name(host.get_name())
+ ->get_variable("speed")
+ ->set_event(surf_get_clock(), host.get_core_count() * host.get_available_speed());
+ });
s4u::Link::on_creation.connect(on_link_creation);
- s4u::Link::on_bandwidth_change.connect(on_link_bandwidth_change);
+ s4u::Link::on_bandwidth_change.connect([](s4u::Link const& link) {
+ Container::by_name(link.get_name())
+ ->get_variable("bandwidth")
+ ->set_event(surf_get_clock(), sg_bandwidth_factor * link.get_bandwidth());
+ });
s4u::NetZone::on_seal.connect([](s4u::NetZone const& /*netzone*/) { currentContainer.pop_back(); });
- kernel::routing::NetPoint::on_creation.connect(on_netpoint_creation);
+ kernel::routing::NetPoint::on_creation.connect([](kernel::routing::NetPoint const& netpoint) {
+ if (netpoint.is_router())
+ new RouterContainer(netpoint.get_name(), currentContainer.back());
+ });
}
+
s4u::NetZone::on_creation.connect(on_netzone_creation);
kernel::resource::CpuAction::on_state_change.connect(on_action_state_change);
s4u::Actor::on_host_change.connect(on_actor_host_change);
}
+ if (TRACE_smpi_is_enabled() && TRACE_smpi_is_computing()) {
+ s4u::Exec::on_start.connect([](simgrid::s4u::Actor const& actor, s4u::Exec const& exec) {
+ Container::by_name(std::string("rank-") + std::to_string(actor.get_pid()))
+ ->get_state("MPI_STATE")
+ ->push_event("computing", new CpuTIData("compute", exec.get_cost()));
+ });
+ s4u::Exec::on_completion.connect([](s4u::Actor const& actor, s4u::Exec const&) {
+ Container::by_name(std::string("rank-") + std::to_string(actor.get_pid()))->get_state("MPI_STATE")->pop_event();
+ });
+ }
+
if (TRACE_vm_is_enabled()) {
s4u::Host::on_creation.connect(on_vm_creation);
s4u::VirtualMachine::on_start.connect([](s4u::VirtualMachine const& vm) {
XBT_PRIVATE container_t smpi_container(int rank);
XBT_PRIVATE void TRACE_smpi_setup_container(int rank, const_sg_host_t host);
-XBT_PRIVATE void TRACE_smpi_computing_init(int rank);
-XBT_PRIVATE void TRACE_smpi_computing_out(int rank);
-XBT_PRIVATE void TRACE_smpi_computing_in(int rank, double amount);
-XBT_PRIVATE void TRACE_smpi_sleeping_init(int rank);
XBT_PRIVATE void TRACE_smpi_sleeping_out(int rank);
XBT_PRIVATE void TRACE_smpi_sleeping_in(int rank, double duration);
XBT_PRIVATE void TRACE_smpi_comm_in(int rank, const char* operation, simgrid::instr::TIData* extra);
XBT_PRIVATE void TRACE_smpi_comm_out(int rank);
XBT_PRIVATE void TRACE_smpi_send(int rank, int src, int dst, int tag, int size);
XBT_PRIVATE void TRACE_smpi_recv(int src, int dst, int tag);
-XBT_PRIVATE void TRACE_smpi_init(int rank);
+XBT_PRIVATE void TRACE_smpi_init(int rank, std::string calling_func);
+
/* SMPI + LB (load balancer) */
XBT_PRIVATE void TRACE_smpi_process_change_host(int rank, const_sg_host_t new_host);
s4u::Disk piface_;
double read_bw_;
double write_bw_;
+ lmm::Constraint* constraint_write_; /* Constraint for maximum write bandwidth*/
+ lmm::Constraint* constraint_read_; /* Constraint for maximum write bandwidth*/
public:
DiskImpl(Model* model, const std::string& name, kernel::lmm::System* maxmin_system, double read_bw, double bwrite_bw);
/** @brief Public interface */
s4u::Disk* get_iface() { return &piface_; }
+ s4u::Host* get_host() const { return host_; }
+ void set_host(s4u::Host* host) { host_ = host; }
+
double get_read_bandwidth() { return read_bw_; }
double get_write_bandwidth() { return write_bw_; }
+ lmm::Constraint* get_read_constraint() const { return constraint_read_; }
+ lmm::Constraint* get_write_constraint() const { return constraint_write_; }
/** @brief Check if the Storage is used (if an action currently uses its resources) */
bool is_used() override;
-
void apply_event(profile::Event* event, double value) override;
-
void turn_on() override;
void turn_off() override;
- s4u::Host* get_host() const { return host_; }
- void set_host(s4u::Host* host) { host_ = host; }
-
void destroy(); // Must be called instead of the destructor
virtual DiskAction* io_start(sg_size_t size, s4u::Io::OpType type) = 0;
virtual DiskAction* read(sg_size_t size) = 0;
virtual DiskAction* write(sg_size_t size) = 0;
-
- lmm::Constraint* constraint_write_; /* Constraint for maximum write bandwidth*/
- lmm::Constraint* constraint_read_; /* Constraint for maximum write bandwidth*/
};
/**********
XBT_PUBLIC Checker* createLivenessChecker(Session& session);
XBT_PUBLIC Checker* createSafetyChecker(Session& session);
XBT_PUBLIC Checker* createCommunicationDeterminismChecker(Session& session);
-}
-}
+
+} // namespace mc
+} // namespace simgrid
#endif
void prepare();
void real_run();
void log_state() override;
- void deterministic_comm_pattern(int process, const simgrid::mc::PatternCommunication* comm, int backtracking);
+ void deterministic_comm_pattern(int process, const PatternCommunication* comm, int backtracking);
void restoreState();
public:
// These are used by functions which should be moved in CommunicationDeterminismChecker:
void get_comm_pattern(smx_simcall_t request, e_mc_call_type_t call_type, int backtracking);
- void complete_comm_pattern(simgrid::mc::RemotePtr<simgrid::kernel::activity::CommImpl> comm_addr, unsigned int issuer,
- int backtracking);
+ void complete_comm_pattern(RemotePtr<kernel::activity::CommImpl> comm_addr, unsigned int issuer, int backtracking);
private:
/** Stack representing the position in the exploration graph */
- std::list<std::unique_ptr<simgrid::mc::State>> stack_;
- simgrid::mc::VisitedStates visited_states_;
+ std::list<std::unique_ptr<State>> stack_;
+ VisitedStates visited_states_;
unsigned long expanded_states_count_ = 0;
bool initial_communications_pattern_done = false;
char *send_diff = nullptr;
char *recv_diff = nullptr;
};
+} // namespace mc
+} // namespace simgrid
#endif
-}
-}
public:
int num = 0;
bool search_cycle = false;
- std::shared_ptr<simgrid::mc::State> graph_state = nullptr; /* System state included */
+ std::shared_ptr<State> graph_state = nullptr; /* System state included */
xbt_automaton_state_t automaton_state = nullptr;
std::shared_ptr<const std::vector<int>> atomic_propositions;
int requests = 0;
public:
int num;
int other_num = 0; /* Dot output for */
- std::shared_ptr<simgrid::mc::State> graph_state = nullptr; /* System state included */
+ std::shared_ptr<State> graph_state = nullptr; /* System state included */
xbt_automaton_state_t automaton_state;
std::shared_ptr<const std::vector<int>> atomic_propositions;
std::size_t heap_bytes_used = 0;
int actors_count = 0;
- VisitedPair(
- int pair_num, xbt_automaton_state_t automaton_state,
- std::shared_ptr<const std::vector<int>> atomic_propositions,
- std::shared_ptr<simgrid::mc::State> graph_state);
+ VisitedPair(int pair_num, xbt_automaton_state_t automaton_state,
+ std::shared_ptr<const std::vector<int>> atomic_propositions, std::shared_ptr<State> graph_state);
~VisitedPair() = default;
};
private:
std::shared_ptr<const std::vector<int>> get_proposition_values();
- std::shared_ptr<VisitedPair> insert_acceptance_pair(simgrid::mc::Pair* pair);
- int insert_visited_pair(std::shared_ptr<VisitedPair> visited_pair, simgrid::mc::Pair* pair);
+ std::shared_ptr<VisitedPair> insert_acceptance_pair(Pair* pair);
+ int insert_visited_pair(std::shared_ptr<VisitedPair> visited_pair, Pair* pair);
void show_acceptance_cycle(std::size_t depth);
void replay();
void remove_acceptance_pair(int pair_num);
std::string previous_request_;
};
-}
-}
+} // namespace mc
+} // namespace simgrid
#endif
namespace mc {
class XBT_PRIVATE SafetyChecker : public Checker {
- simgrid::mc::ReductionMode reductionMode_ = simgrid::mc::ReductionMode::unset;
+ ReductionMode reductionMode_ = ReductionMode::unset;
+
public:
explicit SafetyChecker(Session& session);
~SafetyChecker() = default;
void restore_state();
/** Stack representing the position in the exploration graph */
- std::list<std::unique_ptr<simgrid::mc::State>> stack_;
- simgrid::mc::VisitedStates visited_states_;
- std::unique_ptr<simgrid::mc::VisitedState> visited_state_;
+ std::list<std::unique_ptr<State>> stack_;
+ VisitedStates visited_states_;
+ std::unique_ptr<VisitedState> visited_state_;
unsigned long expanded_states_count_ = 0;
};
-}
-}
+} // namespace mc
+} // namespace simgrid
#endif
*/
struct ExpressionContext {
/** CPU state (registers) */
- unw_cursor_t* cursor = nullptr;
- void* frame_base = nullptr;
- const simgrid::mc::AddressSpace* address_space = nullptr; /** Address space used to read memory */
- simgrid::mc::ObjectInformation* object_info = nullptr;
+ unw_cursor_t* cursor = nullptr;
+ void* frame_base = nullptr;
+ const mc::AddressSpace* address_space = nullptr; /** Address space used to read memory */
+ mc::ObjectInformation* object_info = nullptr;
};
/** When an error happens in the execution of a DWARF expression */
int get_socket() const { return socket_; }
};
-}
-}
+} // namespace mc
+} // namespace simgrid
#endif
static Client* initialize();
static Client* get() { return instance_.get(); }
};
-}
-}
+} // namespace mc
+} // namespace simgrid
#endif
class ActorInformation {
public:
/** MCed address of the process */
- RemotePtr<simgrid::kernel::actor::ActorImpl> address{nullptr};
- Remote<simgrid::kernel::actor::ActorImpl> copy;
+ RemotePtr<kernel::actor::ActorImpl> address{nullptr};
+ Remote<kernel::actor::ActorImpl> copy;
/** Hostname (owned by `mc_modelchecker->hostnames`) */
const char* hostname = nullptr;
void clear_bytes(RemotePtr<void> address, size_t len);
// Debug information:
- std::shared_ptr<simgrid::mc::ObjectInformation> find_object_info(RemotePtr<void> addr) const;
- std::shared_ptr<simgrid::mc::ObjectInformation> find_object_info_exec(RemotePtr<void> addr) const;
- std::shared_ptr<simgrid::mc::ObjectInformation> find_object_info_rw(RemotePtr<void> addr) const;
- simgrid::mc::Frame* find_function(RemotePtr<void> ip) const;
- const simgrid::mc::Variable* find_variable(const char* name) const;
+ std::shared_ptr<ObjectInformation> find_object_info(RemotePtr<void> addr) const;
+ std::shared_ptr<ObjectInformation> find_object_info_exec(RemotePtr<void> addr) const;
+ std::shared_ptr<ObjectInformation> find_object_info_rw(RemotePtr<void> addr) const;
+ Frame* find_function(RemotePtr<void> ip) const;
+ const Variable* find_variable(const char* name) const;
// Heap access:
xbt_mheap_t get_heap()
void ignore_global_variable(const char* name)
{
- for (std::shared_ptr<simgrid::mc::ObjectInformation> const& info : this->object_infos)
+ for (std::shared_ptr<ObjectInformation> const& info : this->object_infos)
info->remove_global_variable(name);
}
void unignore_heap(void* address, size_t size);
void ignore_local_variable(const char* var_name, const char* frame_name);
- std::vector<simgrid::mc::ActorInformation>& actors();
- std::vector<simgrid::mc::ActorInformation>& dead_actors();
+ std::vector<ActorInformation>& actors();
+ std::vector<ActorInformation>& dead_actors();
/** Get a local description of a remote SIMIX actor */
- simgrid::mc::ActorInformation* resolve_actor_info(simgrid::mc::RemotePtr<simgrid::kernel::actor::ActorImpl> actor)
+ ActorInformation* resolve_actor_info(RemotePtr<kernel::actor::ActorImpl> actor)
{
xbt_assert(mc_model_checker != nullptr);
if (not actor)
}
/** Get a local copy of the SIMIX actor structure */
- simgrid::kernel::actor::ActorImpl* resolve_actor(simgrid::mc::RemotePtr<simgrid::kernel::actor::ActorImpl> process)
+ kernel::actor::ActorImpl* resolve_actor(RemotePtr<kernel::actor::ActorImpl> process)
{
- simgrid::mc::ActorInformation* actor_info = this->resolve_actor_info(process);
+ ActorInformation* actor_info = this->resolve_actor_info(process);
if (actor_info)
return actor_info->copy.get_buffer();
else
pid_t pid_ = -1;
Channel channel_;
bool running_ = false;
- std::vector<simgrid::xbt::VmMap> memory_map_;
+ std::vector<xbt::VmMap> memory_map_;
RemotePtr<void> maestro_stack_start_;
RemotePtr<void> maestro_stack_end_;
int memory_file = -1;
public:
// object info
// TODO, make private (first, objectify simgrid::mc::ObjectInformation*)
- std::vector<std::shared_ptr<simgrid::mc::ObjectInformation>> object_infos;
- std::shared_ptr<simgrid::mc::ObjectInformation> libsimgrid_info;
- std::shared_ptr<simgrid::mc::ObjectInformation> binary_info;
+ std::vector<std::shared_ptr<ObjectInformation>> object_infos;
+ std::shared_ptr<ObjectInformation> libsimgrid_info;
+ std::shared_ptr<ObjectInformation> binary_info;
// Copies of MCed SMX data structures
/** Copy of `simix_global->process_list`
/** Open a FD to a remote process memory (`/dev/$pid/mem`)
*/
XBT_PRIVATE int open_vm(pid_t pid, int flags);
-}
-}
+} // namespace mc
+} // namespace simgrid
#endif
{
return RemotePtr<T>(p);
}
-}
-}
+} // namespace mc
+} // namespace simgrid
#endif
private:
void add_region(RegionType type, ObjectInformation* object_info, void* start_addr, std::size_t size);
- void snapshot_regions(simgrid::mc::RemoteClient* process);
- void snapshot_stacks(simgrid::mc::RemoteClient* process);
+ void snapshot_regions(RemoteClient* process);
+ void snapshot_stacks(RemoteClient* process);
};
} // namespace mc
} // namespace simgrid
if (TRACE_actor_is_enabled()) {
container_t process_container = instr::Container::by_name(instr_pid(*MSG_process_self()));
std::string key = std::string("p") + std::to_string(get_id());
- instr::Container::get_root()->get_link("ACTOR_TASK_LINK")->start_event(process_container, "SR", key);
+ instr::Container::get_root()->get_link("ACTOR_LINK")->start_event(process_container, "SR", key);
}
/* Prepare the task to send */
container_t process_container = simgrid::instr::Container::by_name(instr_pid(*MSG_process_self()));
std::string key = std::string("p") + std::to_string((*task)->get_id());
- simgrid::instr::Container::get_root()->get_link("ACTOR_TASK_LINK")->end_event(process_container, "SR", key);
+ simgrid::instr::Container::get_root()->get_link("ACTOR_LINK")->end_event(process_container, "SR", key);
}
return ret;
}
return this->pimpl_->get_latency();
}
+void Link::set_latency(double value)
+{
+ kernel::actor::simcall([this, value] { pimpl_->set_latency(value); });
+}
+
double Link::get_bandwidth() const
{
return this->pimpl_->get_bandwidth();
}
+void Link::set_bandwidth(double value)
+{
+ kernel::actor::simcall([this, value] { pimpl_->set_bandwidth(value); });
+}
+
Link::SharingPolicy Link::get_sharing_policy() const
{
return this->pimpl_->get_sharing_policy();
{
return link->get_bandwidth();
}
+
+void sg_link_bandwidth_set(sg_link_t link, double value)
+{
+ return link->set_bandwidth(value);
+}
+
double sg_link_latency(const_sg_link_t link)
{
return link->get_latency();
}
+void sg_link_latency_set(sg_link_t link, double value)
+{
+ return link->set_latency(value);
+}
void* sg_link_data(const_sg_link_t link)
{
return link->get_data();
simgrid::config::declare_flag<int>("contexts/nthreads", "Number of parallel threads used to execute user contexts", 1,
&SIMIX_context_set_nthreads);
- simgrid::config::declare_flag<int>("contexts/parallel-threshold",
- "Minimal number of user contexts to be run in parallel (raw contexts only)", 2,
- &SIMIX_context_set_parallel_threshold);
- simgrid::config::alias("contexts/parallel-threshold", {"contexts/parallel_threshold"});
-
/* synchronization mode for parallel user contexts */
#if HAVE_FUTEX_H
std::string default_synchro_mode = "futex";
unsigned smx_context_stack_size;
unsigned smx_context_guard_size;
static int smx_parallel_contexts = 1;
-static int smx_parallel_threshold = 2;
static e_xbt_parmap_mode_t smx_parallel_synchronization_mode = XBT_PARMAP_DEFAULT;
/**
smx_parallel_contexts = nb_threads;
}
-/**
- * @brief Returns the threshold above which user processes are run in parallel.
- *
- * If the number of threads is set to 1, there is no parallelism and this
- * threshold has no effect.
- *
- * @return when the number of user processes ready to run is above
- * this threshold, they are run in parallel
- */
-int SIMIX_context_get_parallel_threshold() {
- return smx_parallel_threshold;
-}
-
-/**
- * @brief Sets the threshold above which user processes are run in parallel.
- *
- * If the number of threads is set to 1, there is no parallelism and this
- * threshold has no effect.
- *
- * @param threshold when the number of user processes ready to run is above
- * this threshold, they are run in parallel
- */
-void SIMIX_context_set_parallel_threshold(int threshold) {
- smx_parallel_threshold = threshold;
-}
-
/**
* @brief Returns the synchronization mode used when processes are run in
* parallel.
simgrid::smpi::ActorExt::init();
int rank_traced = simgrid::s4u::this_actor::get_pid();
- TRACE_smpi_init(rank_traced);
- TRACE_smpi_comm_in(rank_traced, __func__, new simgrid::instr::NoOpTIData("init"));
- TRACE_smpi_comm_out(rank_traced);
- TRACE_smpi_computing_init(rank_traced);
- TRACE_smpi_sleeping_init(rank_traced);
+ TRACE_smpi_init(rank_traced, __func__);
smpi_bench_begin();
smpi_process()->mark_as_initialized();
father->create_child(std::string("rank-") + std::to_string(rank), "MPI"); // This container is of type MPI
}
-void TRACE_smpi_init(int rank)
+void TRACE_smpi_init(int rank, std::string calling_func)
{
if (not TRACE_smpi_is_enabled())
return;
TRACE_smpi_setup_container(rank, sg_host_self());
simgrid::s4u::this_actor::on_exit([self](bool) { smpi_container(self->get_pid())->remove_from_parent(); });
+
+ simgrid::instr::StateType* state = smpi_container(rank)->get_state("MPI_STATE");
+
+ state->add_entity_value(calling_func, instr_find_color(calling_func.c_str()));
+ state->push_event(calling_func, new simgrid::instr::NoOpTIData("init"));
+ state->pop_event();
+ if (TRACE_smpi_is_computing())
+ state->add_entity_value("computing", instr_find_color("computing"));
+ if (TRACE_smpi_is_sleeping())
+ state->add_entity_value("sleeping", instr_find_color("sleeping"));
+
#if HAVE_PAPI
const simgrid::instr::Container* container = smpi_container(rank);
papi_counter_t counters = smpi_process()->papi_counters();
#endif
}
-void TRACE_smpi_computing_init(int rank)
-{
- //first use, initialize the color in the trace
- if (TRACE_smpi_is_enabled() && TRACE_smpi_is_computing())
- smpi_container(rank)->get_state("MPI_STATE")->add_entity_value("computing", instr_find_color("computing"));
-}
-
-void TRACE_smpi_sleeping_init(int rank)
-{
- //first use, initialize the color in the trace
- if (TRACE_smpi_is_enabled() && TRACE_smpi_is_sleeping())
- smpi_container(rank)->get_state("MPI_STATE")->add_entity_value("sleeping", instr_find_color("sleeping"));
-}
-
-void TRACE_smpi_computing_in(int rank, double amount)
-{
- if (TRACE_smpi_is_enabled() && TRACE_smpi_is_computing())
- smpi_container(rank)
- ->get_state("MPI_STATE")
- ->push_event("computing", new simgrid::instr::CpuTIData("compute", amount));
-}
-
-void TRACE_smpi_computing_out(int rank)
-{
- if (TRACE_smpi_is_enabled() && TRACE_smpi_is_computing())
- smpi_container(rank)->get_state("MPI_STATE")->pop_event();
-}
-
void TRACE_smpi_sleeping_in(int rank, double duration)
{
if (TRACE_smpi_is_enabled() && TRACE_smpi_is_sleeping())
smpi_switch_data_segment(simgrid::s4u::Actor::self());
}
-void smpi_execute_flops(double flops) {
- int rank = simgrid::s4u::this_actor::get_pid();
- TRACE_smpi_computing_in(rank, flops);
-
+void smpi_execute_flops(double flops)
+{
private_execute_flops(flops);
-
- TRACE_smpi_computing_out(rank);
}
void smpi_execute(double duration)
{
if (duration >= smpi_cfg_cpu_thresh()) {
XBT_DEBUG("Sleep for %g to handle real computation time", duration);
- double flops = duration * smpi_cfg_host_speed();
- int rank = simgrid::s4u::this_actor::get_pid();
- TRACE_smpi_computing_in(rank, flops);
-
- private_execute_flops(flops);
-
- TRACE_smpi_computing_out(rank);
-
+ private_execute_flops(duration * smpi_cfg_host_speed());
} else {
XBT_DEBUG("Real computation took %g while option smpi/cpu-threshold is set to %g => ignore it", duration,
smpi_cfg_cpu_thresh());
}
void SMPI_thread_create() {
- TRACE_smpi_init(simgrid::s4u::this_actor::get_pid());
+ TRACE_smpi_init(simgrid::s4u::this_actor::get_pid(), __func__);
}
int my_proc_id = simgrid::s4u::this_actor::get_pid();
- TRACE_smpi_init(my_proc_id);
- TRACE_smpi_computing_init(my_proc_id);
- TRACE_smpi_comm_in(my_proc_id, "smpi_replay_run_init", new simgrid::instr::NoOpTIData("init"));
- TRACE_smpi_comm_out(my_proc_id);
+ TRACE_smpi_init(my_proc_id, "smpi_replay_run_init");
xbt_replay_action_register("init", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::InitAction().execute(action); });
xbt_replay_action_register("finalize", [](simgrid::xbt::ReplayAction const&) { /* nothing to do */ });
xbt_replay_action_register("comm_size", [](simgrid::xbt::ReplayAction& action) { simgrid::smpi::replay::CommunicatorAction().execute(action); });
model->get_maxmin_system()->expand(disk->get_constraint(), get_variable(), 1.0);
switch (type) {
case s4u::Io::OpType::READ:
- model->get_maxmin_system()->expand(disk->constraint_read_, get_variable(), 1.0);
+ model->get_maxmin_system()->expand(disk->get_read_constraint(), get_variable(), 1.0);
break;
case s4u::Io::OpType::WRITE:
- model->get_maxmin_system()->expand(disk->constraint_write_, get_variable(), 1.0);
+ model->get_maxmin_system()->expand(disk->get_write_constraint(), get_variable(), 1.0);
break;
default:
THROW_UNIMPLEMENTED;
surf_file_to_parse = surf_fopen(file, "r");
if (surf_file_to_parse == nullptr)
- throw std::invalid_argument(std::string("Unable to open ')") + file + "' from '" + simgrid::xbt::Path().get_name() +
+ throw std::invalid_argument(std::string("Unable to open '") + file + "' from '" + simgrid::xbt::Path().get_name() +
"'. Does this file exist?");
surf_input_buffer = surf_parse__create_buffer(surf_file_to_parse, YY_BUF_SIZE);
surf_parse__switch_to_buffer(surf_input_buffer);