From: Martin Quinson Date: Sun, 10 Sep 2017 15:34:48 +0000 (+0200) Subject: fix the s4u_async-waitany example X-Git-Tag: v3_17~150 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/966f7091ce13f6cc5f8dda3d9a8a84bc862fdc82 fix the s4u_async-waitany example --- diff --git a/examples/s4u/async-waitany/s4u_async-waitany.cpp b/examples/s4u/async-waitany/s4u_async-waitany.cpp index 26f711ec02..235269b912 100644 --- a/examples/s4u/async-waitany/s4u_async-waitany.cpp +++ b/examples/s4u/async-waitany/s4u_async-waitany.cpp @@ -1,118 +1,135 @@ -/* Copyright (c) 2010-2016. The SimGrid Team. All rights reserved. */ +/* 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. */ +/* This example shows how to use simgrid::s4u::this_actor::wait_any() to wait for the first occurring event. + * + * As for the other asynchronous examples, the sender initiate all the messages it wants to send and + * pack the resulting simgrid::s4u::CommPtr objects in a vector. All messages thus occurs concurrently. + * + * The sender then loops until there is no ongoing communication. Using wait_any() ensures that the sender + * will notice events as soon as they occur even if it does not follow the order of the container. + * + * Here, finalize messages will terminate earlier because their size is 0, so they travel faster than the + * other messages of this application. As expected, the trace shows that the finalize of worker 1 is + * processed before 'Message 5' that is sent to worker 0. + * + */ + #include "simgrid/s4u.hpp" -#include "xbt/str.h" +#include "xbt/str.h" #include #include -#include -XBT_LOG_NEW_DEFAULT_CATEGORY(msg_async_waitany, "Messages specific for this msg example"); +XBT_LOG_NEW_DEFAULT_CATEGORY(msg_async_waitall, "Messages specific for this msg example"); class sender { - long number_of_tasks = 0; /* - Number of tasks */ - long receivers_count = 0; /* - Number of workers */ - int diff_com = 0; + long messages_count; + long receivers_count; + double msg_size; /* in bytes */ public: explicit sender(std::vector args) { - xbt_assert(args.size()== 5, "This function expects 5 parameters from the XML deployment file"); - number_of_tasks = std::stol(args[0]); - double task_comp_size = std::stod(args[1]); - double task_comm_size = std::stod(args[2]); + xbt_assert(args.size() == 4, "This function expects 4 parameters from the XML deployment file but got %zu", + args.size()); + messages_count = std::stol(args[1]); + msg_size = std::stod(args[2]); receivers_count = std::stol(args[3]); - diff_com = std::stoi(args[4]); } void operator()() { - std::vector comms; - simgrid::s4u::CommPtr comm; - simgrid::s4u::MailboxPtr mbox = simgrid::s4u::Mailbox::byName("receiver_mailbox"); - /* First pack the communications in the dynar */ - for (int i = 0; i < number_of_tasks; i++) { - double coef = (diff_com == 0) ? 1 : (i + 1); - char mailbox[80]; - char taskname[80]; - snprintf(mailbox,79, "receiver-%ld", (i % receivers_count)); - snprintf(taskname,79, "Task_%d", i); - comm = mbox->put_async((void*)taskname, 42.0); - comms.push_back(comm); + std::vector* pending_comms = new std::vector(); + + /* Start dispatching all messages to receivers, in a round robin fashion */ + for (int i = 0; i < messages_count; i++) { + + std::string mboxName = std::string("receiver-") + std::to_string(i % receivers_count); + simgrid::s4u::MailboxPtr mbox = simgrid::s4u::Mailbox::byName(mboxName); + std::string msgName = std::string("Message ") + std::to_string(i); + char* payload = xbt_strdup(msgName.c_str()); // copy the data we send: 'msgName' is not a stable storage location + + XBT_INFO("Send '%s' to '%s'", msgName.c_str(), mboxName.c_str()); + /* Create a communication representing the ongoing communication */ + simgrid::s4u::CommPtr comm = mbox->put_async((void*)payload, msg_size); + /* Add this comm to the vector of all known comms */ + pending_comms->push_back(comm); } + /* Start sending messages to let the workers know that they should stop */ + for (int i = 0; i < receivers_count; i++) { + std::string mbox_name = std::string("receiver-") + std::to_string(i % receivers_count); + simgrid::s4u::MailboxPtr mbox = simgrid::s4u::Mailbox::byName(mbox_name); + char* payload = xbt_strdup("finalize"); // Make a copy of the data we will send - /* Here we are waiting for the completion of all communications */ - while (!comms.empty()) { - comm=comms.back(); - comms.pop_back(); - comm->wait(); + simgrid::s4u::CommPtr comm = mbox->put_async((void*)payload, 0); + pending_comms->push_back(comm); + XBT_INFO("Send 'finalize' to 'receiver-%ld'", i % receivers_count); } - comms.clear(); - comm = nullptr; + XBT_INFO("Done dispatching all messages"); - /* Here we are waiting for the completion of all tasks */ - for (int i = 0; i < receivers_count; i++) { - void* received = nullptr; - simgrid::s4u::CommPtr comm = mbox->get_async(&received); - comm->wait(); - comm = nullptr; + /* Now that all message exchanges were initiated, wait for their completion + * + * This loop waits for first terminating message with wait_any() and remove it with erase(), until all comms are + * terminated + * Even in this simple example, the pending comms do not terminate in the exact same order of creation. + * */ + for (int i = 0; i < messages_count + receivers_count; i++) { + int changed_pos = simgrid::s4u::Comm::wait_any(pending_comms); + pending_comms->erase(pending_comms->begin() + changed_pos); + if (changed_pos != 0) + XBT_INFO("Remove the %dth pending comm: it terminated earlier than another comm that was initiated first.", + changed_pos); } + XBT_INFO("Goodbye now!"); + delete pending_comms; } }; class receiver { - int id = 0; - int task_amount = 0; + simgrid::s4u::MailboxPtr mbox; + int message_count; + public: explicit receiver(std::vector args) { - xbt_assert(args.size() == 2, "This function expects 2 parameters from the XML deployment file"); - id = std::stoi(args[0]); - task_amount = std::stoi(args[1]); + xbt_assert(args.size() == 3, "This function expects 2 parameters from the XML deployment file but got %zu", + args.size()); + int id = xbt_str_parse_int(args[1].c_str(), "Any process of this example must have a numerical name, not %s"); + std::string mbox_name = std::string("receiver-") + std::to_string(id); + mbox = simgrid::s4u::Mailbox::byName(mbox_name); + message_count = xbt_str_parse_int(args[2].c_str(), "message_count parameter must be numerical but got '%s'"); } void operator()() { - void *received; - std::vector comms; - simgrid::s4u::CommPtr comm; - simgrid::s4u::MailboxPtr mbox; - - simgrid::s4u::this_actor::sleep_for(10.0); - for (int i = 0; i < task_amount; i++) { - XBT_INFO("Wait to receive task %d", i); - received = NULL; - comm = mbox->get_async(&received); - comms.push_back(comm); + XBT_INFO("Wait for my first message"); + while (1) { + char* received = static_cast(mbox->get()); + XBT_INFO("I got a '%s'.", received); + if (std::strcmp(received, "finalize") == 0) { /* If it's a finalize message, we're done */ + xbt_free(received); + break; + } + /* Otherwise receiving the message was all we were supposed to do */ + xbt_free(received); } - - /* Here we are waiting for the receiving of all communications */ - while (!comms.empty()) { - // returns the rank of the comm that just ended. Remove it. - comm=comms.back(); - comms.pop_back(); - comm->wait(); - } - comms.clear(); - comm = nullptr; - /* Here we tell to sender that all tasks are done */ - simgrid::s4u::Mailbox::byName("finalize")->put(nullptr, 1); - XBT_INFO("I'm done. See you!"); } }; int main(int argc, char *argv[]) { - simgrid::s4u::Engine *e = new simgrid::s4u::Engine(&argc,argv); + simgrid::s4u::Engine* e = new simgrid::s4u::Engine(&argc, argv); + + xbt_assert(argc > 2, "Usage: %s platform_file deployment_file\n", argv[0]); + + e->registerFunction("sender"); + e->registerFunction("receiver"); - e->registerFunction("sender"); - e->registerFunction("receiver"); - + e->loadPlatform(argv[1]); e->loadDeployment(argv[2]); e->run(); - delete e; return 0; } diff --git a/examples/s4u/async-waitany/s4u_async-waitany.tesh b/examples/s4u/async-waitany/s4u_async-waitany.tesh index 6637734a1a..cdf80383f4 100644 --- a/examples/s4u/async-waitany/s4u_async-waitany.tesh +++ b/examples/s4u/async-waitany/s4u_async-waitany.tesh @@ -1,34 +1,27 @@ #! ./tesh -p Testing the MSG_comm_waitany function +p Testing this_actor->wait_any() ! output sort 19 -$ $SG_TEST_EXENV ${bindir:=.}/async-waitany ${srcdir:=.}/small_platform.xml ${srcdir:=.}/../msg/async-waitany/async-waitany_d.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" -> [ 0.000000] (1:sender@Tremblay) Send to receiver-0 Task_0 comm_size 1000000.000000 -> [ 0.000000] (1:sender@Tremblay) Send to receiver-1 Task_1 comm_size 1000000.000000 -> [ 0.000000] (1:sender@Tremblay) Send to receiver-0 Task_2 comm_size 1000000.000000 -> [ 0.000000] (1:sender@Tremblay) Send to receiver-1 Task_3 comm_size 1000000.000000 -> [ 0.000000] (1:sender@Tremblay) Send to receiver-0 Task_4 comm_size 1000000.000000 -> [ 0.000000] (1:sender@Tremblay) Send to receiver-1 Task_5 comm_size 1000000.000000 -> [ 10.000000] (2:receiver@Fafard) Wait to receive task 0 -> [ 10.000000] (2:receiver@Fafard) Wait to receive task 1 -> [ 10.000000] (2:receiver@Fafard) Wait to receive task 2 -> [ 10.000000] (3:receiver@Jupiter) Wait to receive task 0 -> [ 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" -> [ 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) 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" -> [ 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.454477] (0:maestro@) Simulation time 12.4545 -> [ 12.454477] (1:sender@Tremblay) Goodbye now! -> [ 12.454477] (3:receiver@Jupiter) I'm done. See you! +$ $SG_TEST_EXENV ${bindir:=.}/s4u_async-waitany ${srcdir:=.}/small_platform.xml ${srcdir:=.}/../s4u/async-waitany/s4u_async-waitany_d.xml "--log=root.fmt:[%10.6r]%e(%i:%P@%h)%e%m%n" +> [ 0.000000] (1:sender@Tremblay) Send 'Message 0' to 'receiver-0' +> [ 0.000000] (2:receiver@Fafard) Wait for my first message +> [ 0.000000] (3:receiver@Jupiter) Wait for my first message +> [ 0.000000] (1:sender@Tremblay) Send 'Message 1' to 'receiver-1' +> [ 0.000000] (1:sender@Tremblay) Send 'Message 2' to 'receiver-0' +> [ 0.000000] (1:sender@Tremblay) Send 'Message 3' to 'receiver-1' +> [ 0.000000] (1:sender@Tremblay) Send 'Message 4' to 'receiver-0' +> [ 0.000000] (1:sender@Tremblay) Send 'Message 5' to 'receiver-1' +> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'receiver-0' +> [ 0.000000] (1:sender@Tremblay) Send 'finalize' to 'receiver-1' +> [ 0.000000] (1:sender@Tremblay) Done dispatching all messages +> [ 0.158397] (2:receiver@Fafard) I got a 'Message 0'. +> [ 0.169155] (3:receiver@Jupiter) I got a 'Message 1'. +> [ 0.316794] (2:receiver@Fafard) I got a 'Message 2'. +> [ 0.338309] (3:receiver@Jupiter) I got a 'Message 3'. +> [ 0.475190] (2:receiver@Fafard) I got a 'Message 4'. +> [ 0.500898] (2:receiver@Fafard) I got a 'finalize'. +> [ 0.500898] (1:sender@Tremblay) Remove the 1th pending comm: it terminated earlier than another comm that was initiated first. +> [ 0.507464] (3:receiver@Jupiter) I got a 'Message 5'. +> [ 0.526478] (3:receiver@Jupiter) I got a 'finalize'. +> [ 0.526478] (1:sender@Tremblay) Goodbye now! diff --git a/examples/s4u/async-waitany/s4u_async-waitany_d.xml b/examples/s4u/async-waitany/s4u_async-waitany_d.xml index 2e680c4c3f..8a3ff727e6 100644 --- a/examples/s4u/async-waitany/s4u_async-waitany_d.xml +++ b/examples/s4u/async-waitany/s4u_async-waitany_d.xml @@ -3,19 +3,17 @@ - - - + + - - + - +