From 09245f8fcd613312db68e558c3b04bb75a49477d Mon Sep 17 00:00:00 2001 From: Jacob Domagala Date: Mon, 26 Feb 2024 13:26:41 +0100 Subject: [PATCH] #2249: Add perf test for raw MPI Send/Recv and ObjGroup's Send --- tests/perf/send_cost.cc | 163 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 tests/perf/send_cost.cc diff --git a/tests/perf/send_cost.cc b/tests/perf/send_cost.cc new file mode 100644 index 0000000000..4da3570852 --- /dev/null +++ b/tests/perf/send_cost.cc @@ -0,0 +1,163 @@ +/* +//@HEADER +// ***************************************************************************** +// +// send_cost.cc +// DARMA/vt => Virtual Transport +// +// Copyright 2019-2021 National Technology & Engineering Solutions of Sandia, LLC +// (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S. +// Government retains certain rights in this software. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the name of the copyright holder nor the names of its +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Questions? Contact darma@sandia.gov +// +// ***************************************************************************** +//@HEADER +*/ +#include "common/test_harness.h" +#include "vt/configs/error/config_assert.h" +#include "vt/scheduler/scheduler.h" +#include +#include +#include + +#include + +#include + +using namespace vt; +using namespace vt::tests::perf::common; + +static constexpr std::array const payloadSizes = { + 1, 64, 128, 2048, 16384, 524288, 268435456}; + +vt::EpochType the_epoch = vt::no_epoch; + +struct SendTest : PerfTestHarness { }; + +struct NodeObj { + struct PingMsg : Message { + using MessageParentType = vt::Message; + vt_msg_serialize_required(); + std::vector vec_; + + PingMsg() : Message() { } + explicit PingMsg(size_t size) : Message() { + vec_.resize(size, vt::theContext()->getNode()); + } + + template + void serialize(SerializerT& s) { + MessageParentType::serialize(s); + s | vec_; + } + }; + + void sendHandler(NodeObj::PingMsg* msg) { handled_ = true; } + + explicit NodeObj(SendTest* test_obj) : test_obj_(test_obj) { } + + void initialize() { proxy_ = vt::theObjGroup()->getProxy(this); } + + bool handled_ = false; + SendTest* test_obj_ = nullptr; + vt::objgroup::proxy::Proxy proxy_ = {}; +}; + +VT_PERF_TEST(SendTest, test_send) { + auto const thisNode = vt::theContext()->getNode(); + + if (thisNode == 0) { + vt::theTerm()->disableTD(); + } + + auto const lastNode = theContext()->getNumNodes() - 1; + + auto const prevNode = (thisNode - 1 + num_nodes_) % num_nodes_; + auto const nextNode = (thisNode + 1) % num_nodes_; + int data = thisNode; + + for (auto size : payloadSizes) { + std::vector dataVec(size, data); + std::vector recvData(size, data); + + StartTimer(fmt::format("Payload size {}", size)); + + MPI_Request request; + MPI_Irecv( + &recvData[0], size, MPI_INT, prevNode, 0, MPI_COMM_WORLD, &request); + MPI_Send(&dataVec[0], size, MPI_INT, nextNode, 0, MPI_COMM_WORLD); + + MPI_Wait(&request, MPI_STATUS_IGNORE); + + StopTimer(fmt::format("Payload size {}", size)); + } + + if (vt::theContext()->getNode() == 0) { + vt::theTerm()->enableTD(); + } +} + +VT_PERF_TEST(SendTest, test_objgroup_send) { + auto grp_proxy = + vt::theObjGroup()->makeCollective("test_objgroup_send", this); + grp_proxy[my_node_].invoke<&NodeObj::initialize>(); + + if (theContext()->getNode() == 0) { + theTerm()->disableTD(); + } + + auto const thisNode = vt::theContext()->getNode(); + auto const lastNode = theContext()->getNumNodes() - 1; + + auto const prevNode = (thisNode - 1 + num_nodes_) % num_nodes_; + auto const nextNode = (thisNode + 1) % num_nodes_; + int data = thisNode; + { + for (auto size : payloadSizes) { + NodeObj::PingMsg msg(size); + StartTimer(fmt::format("ObjGroup Payload size {}", size)); + + vt::runInEpochCollective([grp_proxy, nextNode, tmpMsg = std::move(msg)] { + grp_proxy[nextNode].send<&NodeObj::sendHandler>(std::move(tmpMsg)); + }); + + StopTimer(fmt::format("ObjGroup Payload size {}", size)); + + assert(grp_proxy[thisNode].get()->handled_); + grp_proxy[thisNode].get()->handled_ = false; + } + } + + if (vt::theContext()->getNode() == 0) { + vt::theTerm()->enableTD(); + } +} + +VT_PERF_TEST_MAIN()