Skip to content

Commit

Permalink
Merge pull request #5416 from Jedi18/adapt_uninit_value_construct
Browse files Browse the repository at this point in the history
Adapt uninitialized_value_construct and uninitialized_value_construct_n to C++ 20
  • Loading branch information
msimberg committed Jul 6, 2021
2 parents 99fb68a + 1854607 commit 38c970c
Show file tree
Hide file tree
Showing 11 changed files with 1,161 additions and 135 deletions.
6 changes: 4 additions & 2 deletions docs/sphinx/api/public_api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -573,13 +573,15 @@ Functions
- :cpp:func:`hpx::parallel::v1::uninitialized_fill_n`
- :cpp:func:`hpx::uninitialized_move`
- :cpp:func:`hpx::uninitialized_move_n`
- :cpp:func:`hpx::parallel::v1::uninitialized_value_construct`
- :cpp:func:`hpx::parallel::v1::uninitialized_value_construct_n`
- :cpp:func:`hpx::uninitialized_value_construct`
- :cpp:func:`hpx::uninitialized_value_construct_n`

- :cpp:func:`hpx::ranges::uninitialized_default_construct`
- :cpp:func:`hpx::ranges::uninitialized_default_construct_n`
- :cpp:func:`hpx::ranges::uninitialized_move`
- :cpp:func:`hpx::ranges::uninitialized_move_n`
- :cpp:func:`hpx::ranges::uninitialized_value_construct`
- :cpp:func:`hpx::ranges::uninitialized_value_construct_n`

Header ``hpx/numeric.hpp``
==========================
Expand Down
4 changes: 2 additions & 2 deletions docs/sphinx/manual/writing_single_node_hpx_applications.rst
Original file line number Diff line number Diff line change
Expand Up @@ -748,11 +748,11 @@ Parallel algorithms
* Moves a number of objects to an uninitialized area of memory.
* ``<hpx/memory.hpp>``
* :cppreference-memory:`uninitialized_move_n`
* * :cpp:func:`hpx::parallel::v1::uninitialized_value_construct`
* * :cpp:func:`hpx::uninitialized_value_construct`
* Constructs objects in an uninitialized area of memory.
* ``<hpx/memory.hpp>``
* :cppreference-memory:`uninitialized_value_construct`
* * :cpp:func:`hpx::parallel::v1::uninitialized_value_construct_n`
* * :cpp:func:`hpx::uninitialized_value_construct_n`
* Constructs objects in an uninitialized area of memory.
* ``<hpx/memory.hpp>``
* :cppreference-memory:`uninitialized_value_construct_n`
Expand Down
2 changes: 0 additions & 2 deletions libs/full/include_local/include/hpx/local/memory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,4 @@ namespace hpx {
using hpx::parallel::uninitialized_copy_n;
using hpx::parallel::uninitialized_fill;
using hpx::parallel::uninitialized_fill_n;
using hpx::parallel::uninitialized_value_construct;
using hpx::parallel::uninitialized_value_construct_n;
} // namespace hpx
1 change: 1 addition & 0 deletions libs/parallelism/algorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ set(algorithms_headers
hpx/parallel/container_algorithms/transform_reduce.hpp
hpx/parallel/container_algorithms/uninitialized_default_construct.hpp
hpx/parallel/container_algorithms/uninitialized_move.hpp
hpx/parallel/container_algorithms/uninitialized_value_construct.hpp
hpx/parallel/container_algorithms/unique.hpp
hpx/parallel/container_memory.hpp
hpx/parallel/container_numeric.hpp
Expand Down

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void test_uninitialized_value_construct(ExPolicy&& policy, IteratorTag)
std::memset(
static_cast<void*>(p), 0xcd, data_size * sizeof(value_constructable));

hpx::parallel::uninitialized_value_construct(
hpx::uninitialized_value_construct(
std::forward<ExPolicy>(policy), iterator(p), iterator(p + data_size));

std::size_t count = 0;
Expand All @@ -66,7 +66,7 @@ void test_uninitialized_value_construct_async(ExPolicy&& policy, IteratorTag)
std::memset(
static_cast<void*>(p), 0xcd, data_size * sizeof(value_constructable));

auto f = hpx::parallel::uninitialized_value_construct(
auto f = hpx::uninitialized_value_construct(
std::forward<ExPolicy>(policy), iterator(p), iterator(p + data_size));
f.wait();

Expand Down Expand Up @@ -104,7 +104,7 @@ void test_uninitialized_value_construct_exception(ExPolicy policy, IteratorTag)
bool caught_exception = false;
try
{
hpx::parallel::uninitialized_value_construct(policy,
hpx::uninitialized_value_construct(policy,
decorated_iterator(p,
[&throw_after]() {
if (throw_after-- == 0)
Expand Down Expand Up @@ -152,7 +152,7 @@ void test_uninitialized_value_construct_exception_async(
bool returned_from_algorithm = false;
try
{
auto f = hpx::parallel::uninitialized_value_construct(policy,
auto f = hpx::uninitialized_value_construct(policy,
decorated_iterator(p,
[&throw_after]() {
if (throw_after-- == 0)
Expand Down Expand Up @@ -207,7 +207,7 @@ void test_uninitialized_value_construct_bad_alloc(ExPolicy policy, IteratorTag)
bool caught_bad_alloc = false;
try
{
hpx::parallel::uninitialized_value_construct(policy,
hpx::uninitialized_value_construct(policy,
decorated_iterator(p,
[&throw_after]() {
if (throw_after-- == 0)
Expand Down Expand Up @@ -255,7 +255,7 @@ void test_uninitialized_value_construct_bad_alloc_async(
bool returned_from_algorithm = false;
try
{
auto f = hpx::parallel::uninitialized_value_construct(policy,
auto f = hpx::uninitialized_value_construct(policy,
decorated_iterator(p,
[&throw_after]() {
if (throw_after-- == 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ void test_uninitialized_value_construct_n(ExPolicy policy, IteratorTag)
std::memset(
static_cast<void*>(p), 0xcd, data_size * sizeof(value_constructable));

hpx::parallel::uninitialized_value_construct_n(
policy, iterator(p), data_size);
hpx::uninitialized_value_construct_n(policy, iterator(p), data_size);

std::size_t count = 0;
std::for_each(p, p + data_size, [&count](value_constructable v1) {
Expand All @@ -64,8 +63,8 @@ void test_uninitialized_value_construct_n_async(ExPolicy policy, IteratorTag)
std::memset(
static_cast<void*>(p), 0xcd, data_size * sizeof(value_constructable));

auto f = hpx::parallel::uninitialized_value_construct_n(
policy, iterator(p), data_size);
auto f =
hpx::uninitialized_value_construct_n(policy, iterator(p), data_size);
f.wait();

std::size_t count = 0;
Expand Down Expand Up @@ -122,7 +121,7 @@ void test_uninitialized_value_construct_n_exception(
bool caught_exception = false;
try
{
hpx::parallel::uninitialized_value_construct_n(policy,
hpx::uninitialized_value_construct_n(policy,
decorated_iterator(p,
[&throw_after]() {
if (throw_after-- == 0)
Expand Down Expand Up @@ -170,7 +169,7 @@ void test_uninitialized_value_construct_n_exception_async(
bool returned_from_algorithm = false;
try
{
auto f = hpx::parallel::uninitialized_value_construct_n(policy,
auto f = hpx::uninitialized_value_construct_n(policy,
decorated_iterator(p,
[&throw_after]() {
if (throw_after-- == 0)
Expand Down Expand Up @@ -250,7 +249,7 @@ void test_uninitialized_value_construct_n_bad_alloc(
bool caught_bad_alloc = false;
try
{
hpx::parallel::uninitialized_value_construct_n(policy,
hpx::uninitialized_value_construct_n(policy,
decorated_iterator(p,
[&throw_after]() {
if (throw_after-- == 0)
Expand Down Expand Up @@ -298,7 +297,7 @@ void test_uninitialized_value_construct_n_bad_alloc_async(
bool returned_from_algorithm = false;
try
{
auto f = hpx::parallel::uninitialized_value_construct_n(policy,
auto f = hpx::uninitialized_value_construct_n(policy,
decorated_iterator(p,
[&throw_after]() {
if (throw_after-- == 0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ set(tests
uninitialized_default_constructn_range
uninitialized_move_range
uninitialized_move_n_range
uninitialized_value_construct_range
uninitialized_value_constructn_range
unique_range
unique_copy_range
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
// Copyright (c) 2018 Christopher Ogle
// Copyright (c) 2020 Hartmut Kaiser
//
// SPDX-License-Identifier: BSL-1.0
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <hpx/iterator_support/tests/iter_sent.hpp>
#include <hpx/local/init.hpp>
#include <hpx/modules/testing.hpp>
#include <hpx/parallel/container_algorithms/uninitialized_value_construct.hpp>

#include <cstddef>
#include <cstdint>
#include <iostream>
#include <iterator>
#include <numeric>
#include <string>
#include <utility>
#include <vector>

#include "test_utils.hpp"

////////////////////////////////////////////////////////////////////////////
struct value_constructable
{
bool operator!=(std::int32_t lhs) const
{
return lhs != value_;
}

std::int32_t value_;
};

std::size_t const data_size = 10007;

////////////////////////////////////////////////////////////////////////////
template <typename IteratorTag>
void test_uninitialized_value_construct_range_sent(IteratorTag)
{
typedef std::vector<value_constructable> base_iterator;

base_iterator c(data_size, {10});
auto end_size = rand() % data_size;
c[end_size] = {20};

hpx::ranges::uninitialized_value_construct(
std::begin(c), sentinel<std::int32_t>{20});

std::size_t count42 = 0;
std::size_t count10 = 0;
std::for_each(std::begin(c), std::begin(c) + data_size,
[&count42, &count10](value_constructable v1) {
if (v1.value_ == 0)
{
count42++;
}
else if (v1.value_ == 10)
{
count10++;
}
});

HPX_TEST_EQ(count42, end_size);
HPX_TEST_EQ(count10, data_size - end_size - 1);
}

template <typename ExPolicy, typename IteratorTag>
void test_uninitialized_value_construct_range_sent(
ExPolicy&& policy, IteratorTag)
{
typedef std::vector<value_constructable> base_iterator;

base_iterator c(data_size, {10});
auto end_size = rand() % data_size;
c[end_size] = {20};

hpx::ranges::uninitialized_value_construct(
policy, std::begin(c), sentinel<std::int32_t>{20});

std::size_t count42 = 0;
std::size_t count10 = 0;
std::for_each(std::begin(c), std::begin(c) + data_size,
[&count42, &count10](value_constructable v1) {
if (v1.value_ == 0)
{
count42++;
}
else if (v1.value_ == 10)
{
count10++;
}
});

HPX_TEST_EQ(count42, end_size);
HPX_TEST_EQ(count10, data_size - end_size - 1);
}

template <typename IteratorTag>
void test_uninitialized_value_construct_range(IteratorTag)
{
typedef std::vector<value_constructable> base_iterator;

base_iterator c(data_size, {10});
hpx::ranges::uninitialized_value_construct(c);

std::size_t count = 0;
std::for_each(std::begin(c), std::begin(c) + data_size,
[&count](value_constructable v1) {
HPX_TEST_EQ(v1.value_, 0);
++count;
});
HPX_TEST_EQ(count, data_size);
}

template <typename ExPolicy, typename IteratorTag>
void test_uninitialized_value_construct_range(ExPolicy&& policy, IteratorTag)
{
static_assert(hpx::is_execution_policy<ExPolicy>::value,
"hpx::is_execution_policy<ExPolicy>::value");

typedef std::vector<value_constructable> base_iterator;

base_iterator c(data_size, {10});
hpx::ranges::uninitialized_value_construct(
std::forward<ExPolicy>(policy), c);

std::size_t count = 0;
std::for_each(std::begin(c), std::begin(c) + data_size,
[&count](value_constructable v1) {
HPX_TEST_EQ(v1.value_, 0);
++count;
});
HPX_TEST_EQ(count, data_size);
}

template <typename ExPolicy, typename IteratorTag>
void test_uninitialized_value_construct_range_async(
ExPolicy&& policy, IteratorTag)
{
static_assert(hpx::is_execution_policy<ExPolicy>::value,
"hpx::is_execution_policy<ExPolicy>::value");

typedef std::vector<value_constructable> base_iterator;

base_iterator c(data_size, {10});
auto f = hpx::ranges::uninitialized_value_construct(
std::forward<ExPolicy>(policy), c);
f.wait();

std::size_t count = 0;
std::for_each(std::begin(c), std::begin(c) + data_size,
[&count](value_constructable v1) {
HPX_TEST_EQ(v1.value_, 0);
++count;
});
HPX_TEST_EQ(count, data_size);
}

template <typename IteratorTag>
void test_uninitialized_value_construct_range()
{
using namespace hpx::execution;

test_uninitialized_value_construct_range(IteratorTag());
test_uninitialized_value_construct_range(seq, IteratorTag());
test_uninitialized_value_construct_range(par, IteratorTag());
test_uninitialized_value_construct_range(par_unseq, IteratorTag());

test_uninitialized_value_construct_range_async(seq(task), IteratorTag());
test_uninitialized_value_construct_range_async(par(task), IteratorTag());

test_uninitialized_value_construct_range_sent(IteratorTag());
test_uninitialized_value_construct_range_sent(seq, IteratorTag());
test_uninitialized_value_construct_range_sent(par, IteratorTag());
test_uninitialized_value_construct_range_sent(par_unseq, IteratorTag());
}

void uninitialized_value_construct_range_test()
{
test_uninitialized_value_construct_range<std::random_access_iterator_tag>();
test_uninitialized_value_construct_range<std::forward_iterator_tag>();
}

////////////////////////////////////////////////////////////////////////////
int hpx_main(hpx::program_options::variables_map& vm)
{
unsigned int seed = (unsigned int) std::time(nullptr);
if (vm.count("seed"))
seed = vm["seed"].as<unsigned int>();

std::cout << "using seed: " << seed << std::endl;
std::srand(seed);

uninitialized_value_construct_range_test();
return hpx::local::finalize();
}

int main(int argc, char* argv[])
{
// add command line option which controls the random number generator seed
using namespace hpx::program_options;
options_description desc_commandline(
"Usage: " HPX_APPLICATION_STRING " [options]");

desc_commandline.add_options()("seed,s", value<unsigned int>(),
"the random number generator seed to use for this run");

// By value this test should run on all available cores
std::vector<std::string> const cfg = {"hpx.os_threads=all"};

// Initialize and run HPX
hpx::local::init_params init_args;
init_args.desc_cmdline = desc_commandline;
init_args.cfg = cfg;

HPX_TEST_EQ_MSG(hpx::local::init(hpx_main, argc, argv, init_args), 0,
"HPX main exited with non-zero status");

return hpx::util::report_errors();
}
Loading

0 comments on commit 38c970c

Please sign in to comment.