Skip to content

Commit

Permalink
Merge branch 'main' into feature/irecv
Browse files Browse the repository at this point in the history
  • Loading branch information
niklas-uhl committed Jan 31, 2024
2 parents 6d37148 + ba2e00f commit 26e2967
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 87 deletions.
10 changes: 7 additions & 3 deletions docs/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ PROJECT_NUMBER = 0.0.1
# for a project that appears at the top of each page and should give viewer a
# quick idea about the purpose of the project. Keep the description short.

PROJECT_BRIEF = "An MPI wrapper which makes using MPI feel like real C++"
PROJECT_BRIEF = "(Near) zero-overhead C++ MPI bindings."

# With the PROJECT_LOGO tag one can specify a logo or an icon that is included
# in the documentation. The maximum height of the logo should not exceed 55
Expand Down Expand Up @@ -1187,7 +1187,7 @@ HTML_HEADER = docs/custom_doxygen/header.html
# that doxygen normally uses.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_FOOTER = docs/custom_doxygen/footer.html
# HTML_FOOTER = docs/custom_doxygen/footer.html

# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
# sheet that is used by each HTML page. It can be used to fine-tune the look of
Expand Down Expand Up @@ -1225,7 +1225,9 @@ HTML_EXTRA_STYLESHEET = extern/doxygen-awesome-css/doxygen-awesome.css \
# files will be copied as-is; there are no commands or markers available.
# This tag requires that the tag GENERATE_HTML is set to YES.

HTML_EXTRA_FILES = extern/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js
HTML_EXTRA_FILES = extern/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js \
extern/doxygen-awesome-css/doxygen-awesome-fragment-copy-button.js \
extern/doxygen-awesome-css/doxygen-awesome-paragraph-link.js

# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
Expand All @@ -1238,6 +1240,8 @@ HTML_EXTRA_FILES = extern/doxygen-awesome-css/doxygen-awesome-darkmode-tog

HTML_COLORSTYLE_HUE = 220

HTML_COLORSTYLE = LIGHT

# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
# in the HTML output. For a value of 0 the output will use gray-scales only. A
# value of 255 will produce the most vivid colors.
Expand Down
30 changes: 0 additions & 30 deletions docs/custom_doxygen/footer.html

This file was deleted.

32 changes: 25 additions & 7 deletions docs/custom_doxygen/header.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
<!-- HTML header for doxygen 1.9.2-->
<!-- HTML header for doxygen 1.10.0-->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<html xmlns="http://www.w3.org/1999/xhtml" lang="$langISO">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=11"/>
<meta name="generator" content="Doxygen $doxygenversion"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->
<!--BEGIN PROJECT_ICON-->
<link rel="icon" href="$relpath^$projecticon" type="image/x-icon" />
<!--END PROJECT_ICON-->
<link href="$relpath^tabs.css" rel="stylesheet" type="text/css"/>
<!--BEGIN DISABLE_INDEX-->
<!--BEGIN FULL_SIDEBAR-->
Expand All @@ -16,12 +19,27 @@
<!--END DISABLE_INDEX-->
<script type="text/javascript" src="$relpath^jquery.js"></script>
<script type="text/javascript" src="$relpath^dynsections.js"></script>
<!--BEGIN COPY_CLIPBOARD-->
<script type="text/javascript" src="$relpath^clipboard.js"></script>
<!--END COPY_CLIPBOARD-->
$treeview
$search
$mathjax
$darkmode
<link href="$relpath^$stylesheet" rel="stylesheet" type="text/css" />
$extrastylesheet
<script type="text/javascript" src="$relpath^doxygen-awesome-darkmode-toggle.js"></script>
<script type="text/javascript" src="$relpath^doxygen-awesome-darkmode-toggle.js"></script>
<script type="text/javascript">
DoxygenAwesomeDarkModeToggle.init()
</script>
<script type="text/javascript" src="$relpath^doxygen-awesome-fragment-copy-button.js"></script>
<script type="text/javascript">
DoxygenAwesomeFragmentCopyButton.init()
</script>
<script type="text/javascript" src="$relpath^doxygen-awesome-paragraph-link.js"></script>
<script type="text/javascript">
DoxygenAwesomeParagraphLink.init()
</script>
</head>
<body>
<!--BEGIN DISABLE_INDEX-->
Expand All @@ -36,20 +54,20 @@
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<tr id="projectrow">
<!--BEGIN PROJECT_LOGO-->
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"/></td>
<td id="projectlogo"><img alt="Logo" src="$relpath^$projectlogo"$logosize/></td>
<!--END PROJECT_LOGO-->
<!--BEGIN PROJECT_NAME-->
<td id="projectalign" style="padding-left: 0.5em;">
<td id="projectalign">
<div id="projectname">$projectname<!--BEGIN PROJECT_NUMBER--><span id="projectnumber">&#160;$projectnumber</span><!--END PROJECT_NUMBER-->
</div>
<!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->
</td>
<!--END PROJECT_NAME-->
<!--BEGIN !PROJECT_NAME-->
<!--BEGIN PROJECT_BRIEF-->
<td style="padding-left: 0.5em;">
<td>
<div id="projectbrief">$projectbrief</div>
</td>
<!--END PROJECT_BRIEF-->
Expand Down
26 changes: 16 additions & 10 deletions include/kamping/result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -429,20 +429,24 @@ class NonBlockingResult {
auto extract() {
if constexpr (owns_request) {
auto result = extract_result(); // we try to extract the result first, so that we get a nice error message
// TODO: return a named struct
return std::pair(_request.extract(), std::move(result));
} else {
return extract_result();
}
}

/// @brief Waits for the underlying \ref Request to complete by calling \ref Request::wait() and upon completion
/// returns an \c std::pair containing an \ref MPIResult and the status if \ref kamping::status_out() is passend.
/// returns:
///
/// If the result is empty (see \ref MPIResult::is_empty), only the status is returned.
/// If \p status is an out-parameter:
/// - If the result is not empty (see \ref MPIResult::is_empty), an \c std::pair containing an \ref MPIResult and
/// the status.
/// - If the result is empty, only the status is returned.
///
/// If \c kamping::status(ignore<>) is passed as a parameter or the status
/// parameter is omited, only the result is returned (or nothing if the
/// result is empty).
/// If \p is \c kamping::status(ignore<>), or not an out-paramter:
/// - If the result is not empty (see \ref MPIResult::is_empty), only the result is returned.
/// - If the result is empty, nothing is returned.
///
/// This method is only available if this result owns the underlying request. If this is not the case, the user must
/// manually wait on the request that they own and manually obtain the result via \ref extract().
Expand Down Expand Up @@ -473,13 +477,15 @@ class NonBlockingResult {
}
}

/// @brief Tests the underlying \ref Request for completion by calling \ref Request::test() and returns an \c
/// std::optional containing the underlying \ref MPIResult on success. If \ref kamping::status_out() is passed as a
/// parameter, also returns the status. If the associated operation has not completed yet, returns \c std::nullopt.
/// @brief Tests the underlying \ref Request for completion by calling \ref
/// Request::test() and returns a value convertible to \c bool indicating if the request is complete.
///
/// The return value depends on the encapsulated result and the status parameter: See \ref wait() for details.
/// The type of the return value depends on the encapsulated result and the \p status parameter and follows the same
/// semantics as \ref wait(), but its return value is wrapped in an \c std::optional.
/// The optional only contains a value if the request is complete, i.e. \c test() succeeded.
///
/// If both the result is empty and no status is requested, returns \c true if the underlying request is complete.
/// If both the result is empty and no status returned, returns a \c bool indicating completion instead of an \c
/// std::optional.
///
/// This method is only available if this result owns the underlying request. If this is not the case, the user must
/// manually test the request that they own and manually obtain the result via \ref extract().
Expand Down
94 changes: 58 additions & 36 deletions tests/nonblocking_result_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@

using namespace kamping;

static bool test_succeed = false;
static size_t num_wait_calls = 0;
int const TOUCHED_BY_MOCK_TAG = 42;
static bool let_mpi_test_succeed = false;
static size_t num_wait_calls = 0;
int const TOUCHED_BY_MOCK_TAG = 42;

KAMPING_MAKE_HAS_MEMBER(wait)
KAMPING_MAKE_HAS_MEMBER(test)
Expand All @@ -42,18 +42,18 @@ int MPI_Test(MPI_Request*, int* flag, MPI_Status* status) {
if (status != MPI_STATUS_IGNORE) {
status->MPI_TAG = TOUCHED_BY_MOCK_TAG;
}
*flag = test_succeed;
*flag = let_mpi_test_succeed;
return MPI_SUCCESS;
}

class NonBlockingResultTest : public ::testing::Test {
void SetUp() override {
test_succeed = false;
num_wait_calls = 0;
let_mpi_test_succeed = false;
num_wait_calls = 0;
}
void TearDown() override {
test_succeed = false;
num_wait_calls = 0;
let_mpi_test_succeed = false;
num_wait_calls = 0;
}
};

Expand Down Expand Up @@ -176,12 +176,12 @@ TEST_F(NonBlockingResultTest, owning_request_and_result_test_works) {
recv_buf_obj.underlying().push_back(42);
recv_buf_obj.underlying().push_back(43);
recv_buf_obj.underlying().push_back(44);
auto request_obj = request();
auto result = kamping::make_nonblocking_result(std::move(recv_buf_obj), std::move(request_obj));
test_succeed = false;
auto request_obj = request();
auto result = kamping::make_nonblocking_result(std::move(recv_buf_obj), std::move(request_obj));
let_mpi_test_succeed = false;
EXPECT_FALSE(result.test().has_value());
test_succeed = true;
auto data = result.test();
let_mpi_test_succeed = true;
auto data = result.test();
EXPECT_TRUE(data.has_value());
auto expected_data = std::vector{42, 43, 44};
EXPECT_EQ(data.value().extract_recv_buffer(), expected_data);
Expand All @@ -192,12 +192,12 @@ TEST_F(NonBlockingResultTest, owning_request_and_result_test_works_status_out) {
recv_buf_obj.underlying().push_back(42);
recv_buf_obj.underlying().push_back(43);
recv_buf_obj.underlying().push_back(44);
auto request_obj = request();
auto result = kamping::make_nonblocking_result(std::move(recv_buf_obj), std::move(request_obj));
test_succeed = false;
auto request_obj = request();
auto result = kamping::make_nonblocking_result(std::move(recv_buf_obj), std::move(request_obj));
let_mpi_test_succeed = false;
EXPECT_FALSE(result.test(status_out()).has_value());
test_succeed = true;
auto data = result.test(status_out());
let_mpi_test_succeed = true;
auto data = result.test(status_out());
EXPECT_TRUE(data.has_value());
auto expected_data = std::vector{42, 43, 44};
EXPECT_EQ(data.value().first.extract_recv_buffer(), expected_data);
Expand All @@ -209,13 +209,13 @@ TEST_F(NonBlockingResultTest, owning_request_and_result_test_works_status_in) {
recv_buf_obj.underlying().push_back(42);
recv_buf_obj.underlying().push_back(43);
recv_buf_obj.underlying().push_back(44);
auto request_obj = request();
auto result = kamping::make_nonblocking_result(std::move(recv_buf_obj), std::move(request_obj));
test_succeed = false;
auto request_obj = request();
auto result = kamping::make_nonblocking_result(std::move(recv_buf_obj), std::move(request_obj));
let_mpi_test_succeed = false;
Status status;
EXPECT_FALSE(result.test(status_out(status)).has_value());
test_succeed = true;
auto data = result.test(status_out(status));
let_mpi_test_succeed = true;
auto data = result.test(status_out(status));
EXPECT_TRUE(data.has_value());
auto expected_data = std::vector{42, 43, 44};
EXPECT_EQ(data.value().extract_recv_buffer(), expected_data);
Expand Down Expand Up @@ -256,15 +256,6 @@ TEST_F(NonBlockingResultTest, owning_request_and_result_extract_works) {
TEST_F(NonBlockingResultTest, owning_request_and_empty_result_types_match) {
auto request_obj = request();
auto result = kamping::make_nonblocking_result(std::move(request_obj));
// EXPECT_TRUE(has_member_test_v<decltype(result)>);
// EXPECT_TRUE(has_member_test_v<decltype(result)>);
// {
// using test_return_type = decltype(result.test());
// EXPECT_TRUE((std::is_same_v<test_return_type, bool>));
// EXPECT_TRUE(has_member_wait_v<decltype(result)>);
// }
// using wait_return_type = decltype(result.wait());
// EXPECT_TRUE((std::is_same_v<wait_return_type, void>));

EXPECT_TRUE(has_member_test_v<decltype(result)>);
EXPECT_TRUE(has_member_wait_v<decltype(result)>);
Expand Down Expand Up @@ -304,14 +295,45 @@ TEST_F(NonBlockingResultTest, owning_request_and_empty_result_types_match) {
}

TEST_F(NonBlockingResultTest, owning_request_and_empty_result_test_works) {
auto request_obj = request();
auto result = kamping::make_nonblocking_result(std::move(request_obj));
test_succeed = false;
auto request_obj = request();
auto result = kamping::make_nonblocking_result(std::move(request_obj));
let_mpi_test_succeed = false;
EXPECT_FALSE(result.test());
test_succeed = true;
let_mpi_test_succeed = true;
EXPECT_TRUE(result.test());
}

TEST_F(NonBlockingResultTest, owning_request_and_empty_result_test_works_status_out) {
auto request_obj = request();
auto result = kamping::make_nonblocking_result(std::move(request_obj));
let_mpi_test_succeed = false;
EXPECT_FALSE(result.test(status_out()));
let_mpi_test_succeed = true;
std::optional<Status> status = result.test(status_out());
EXPECT_TRUE(status.has_value());
EXPECT_EQ(status.value().tag(), TOUCHED_BY_MOCK_TAG);
}

TEST_F(NonBlockingResultTest, owning_request_and_empty_result_test_works_status_in) {
auto request_obj = request();
auto result = kamping::make_nonblocking_result(std::move(request_obj));
let_mpi_test_succeed = false;
Status status;
EXPECT_FALSE(result.test(status_out(status)));
let_mpi_test_succeed = true;
EXPECT_TRUE(result.test(status_out(status)));
EXPECT_EQ(status.tag(), TOUCHED_BY_MOCK_TAG);
}

TEST_F(NonBlockingResultTest, owning_request_and_empty_result_wait_works) {
auto request_obj = request();
auto result = kamping::make_nonblocking_result(std::move(request_obj));
EXPECT_EQ(num_wait_calls, 0);
static_assert(std::is_same_v<decltype(result.wait()), void>);
result.wait();
EXPECT_EQ(num_wait_calls, 1);
}

TEST_F(NonBlockingResultTest, owning_request_and_empty_result_test_works_status_out) {
auto request_obj = request();
auto result = kamping::make_nonblocking_result(std::move(request_obj));
Expand Down

0 comments on commit 26e2967

Please sign in to comment.