Same completion value can't be received multiple times

Issue #267 resolved
john bachan created an issue

For all comm operations which generate value-receiving completions, with the exception rpc, (this leaves rget<T> by value, reductions, broadcasts, etc), the value can't be received by multiple handlers reliably since the implementation moves-out of the same source value into each handler. Thus only the first handler called gets a reliable value. By luck, all comm ops except rpc demand trivial types, so the move-out problem doesn't surface since moving-out on trivials doesn't destroy the original, and rpc happens to use a different code path in completions (the to_lpc_dormant stuff) which handles this correctly. But, there are non spec'd ops which support non-trivial types (the nontrivial collections like reduce_all_nontrivial) and use the bad code path, so those do fall over dead.

#include <upcxx/upcxx.hpp>
#include "../util.hpp"

using namespace std;

int main() {
  upcxx::init();
  print_test_header();

  int countdown = 2;
  auto handler1 = [&](std::string xs) {
    UPCXX_ASSERT_ALWAYS(xs == std::string(10*upcxx::rank_n(),'x'));
    countdown -= 1;
  };

  #if 1 // avoid issue 266, when that is fixed this is irrelevant
  auto handler2 = [&](std::string xs) {
    UPCXX_ASSERT_ALWAYS(xs == std::string(10*upcxx::rank_n(),'x'));
    countdown -= 1;
  };
  #else
  auto handler2 = handler1;
  #endif

  upcxx::reduce_all_nontrivial(
    std::string(10,'x'),
    upcxx::op_add, // concatenate strings
    upcxx::world(),
    upcxx::operation_cx::as_lpc(upcxx::current_persona(), handler1) |
    upcxx::operation_cx::as_lpc(upcxx::current_persona(), handler2)
  );

  while(countdown != 0)
    upcxx::progress();

  print_test_success(true);
  upcxx::finalize();
}

Comments (3)

  1. john bachan reporter

    This fixes issue 266 and issue 267.

    266 required adding an integer "tag" to completions_state types which indexes their nesting depth in the class hierarchy to permit disambiguation of like-typed event handlers.

    267 required casting logic in completions_state to only give a && reference to the last handler in the chain.

    regression tests added:

    test/regression/issue266.cpp

    test/regression/issue267.cpp

    → <<cset dd132be1cb88>>

  2. Log in to comment