Skip to content

Commit

Permalink
Merge pull request ct-clmsn#46 from STEllAR-GROUP/array_tests
Browse files Browse the repository at this point in the history
Adding tests for array iteration
  • Loading branch information
hkaiser authored Apr 28, 2023
2 parents 02c87eb + fcce3e1 commit e710c44
Show file tree
Hide file tree
Showing 9 changed files with 691 additions and 6 deletions.
2 changes: 1 addition & 1 deletion library/include/chplx/adapt_array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace chplx {
//-----------------------------------------------------------------------------
// 1D iteration support
template <typename T, typename Domain>
hpx::generator<T> iterate(
hpx::generator<T&, T> iterate(
detail::IteratorGenerator<Array<T, Domain>> a) noexcept {

auto size = a.size;
Expand Down
22 changes: 19 additions & 3 deletions library/include/chplx/array.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ template <typename T, typename Domain> class Array {
public:
static constexpr int rank = Domain::rank();
static constexpr bool Stridable = Domain::stridable();

using idxType = typename Domain::idxType;
using indexType = typename Domain::indexType;
using indicesType = typename Domain::indicesType;

private:
using arrayHandle =
domains::BaseRectangularArray<T, rank, idxType, Stridable>;

using indexType = typename Domain::indexType;
using indicesType = typename Domain::indicesType;

public:
Array() = default;

Expand Down Expand Up @@ -156,6 +156,22 @@ template <typename T, typename Domain> class Array {
return array->dsiGetBaseDomain()->dsiDim(i);
}

// Returns an integer representing the zero-based ordinal value of ind within
// the domain's sequence of values if it is a member of the sequence.
// Otherwise, returns -1. The indexOrder procedure is the reverse of
// orderToIndex.
[[nodiscard]] constexpr std::int64_t
indexOrder(indexType idx) const noexcept {
return array->dsiGetBaseDomain()->dsiIndexOrder(idx);
}

// Returns the zero-based ord-th element of this domain's represented
// sequence. The orderToIndex procedure is the reverse of indexOrder.
[[nodiscard]] constexpr indexType
orderToIndex(std::int64_t order) const noexcept {
return array->dsiGetBaseDomain()->dsiOrderToIndex(order);
}

// return the location of this array instance
chplx::locale locale = chplx::here;

Expand Down
4 changes: 2 additions & 2 deletions library/include/chplx/coforall_loop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ void coforall(detail::ZipRange<Rs...> const &zr, F &&f, Args &&...args) {
}

//-----------------------------------------------------------------------------
// forall loop for aray iteration
// forall loop for array iteration
template <typename T, typename Domain, typename F, typename... Args>
void coforall(Array<T, Domain> const &a, F &&f, Args &&...args) {

Expand All @@ -170,7 +170,7 @@ void coforall(Array<T, Domain> const &a, F &&f, Args &&...args) {
hpx::wait_all(hpx::parallel::execution::bulk_async_execute(
policy.executor(),
[&](std::size_t idx, auto &&...fargs) {
return f(a.orderToIndex(idx), std::forward<decltype(args)>(fargs)...);
return f(a(idx), std::forward<decltype(args)>(fargs)...);
},
a.size(),
detail::task_intent<std::decay_t<Args>>::call(
Expand Down
8 changes: 8 additions & 0 deletions library/include/chplx/for_loop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,12 @@ void forLoop(Array<T, Domain> const &a, F &&f) {
}
}

template <typename T, typename Domain, typename F>
void forLoop(Array<T, Domain> &a, F &&f) {

for (auto &e : a.these()) {
f(e);
}
}

} // namespace chplx
6 changes: 6 additions & 0 deletions library/include/chplx/write.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace chplx {

//-----------------------------------------------------------------------------
template <typename T> void write_one(std::ostream &os, T &&t) { os << t; }

template <typename... Ts> void write(std::ostream &os, Ts &&...ts) {
Expand All @@ -22,6 +23,9 @@ template <typename... Ts> void writeln(std::ostream &os, Ts &&...ts) {
os << "\n";
}

inline void writeln(std::ostream &os) { os << "\n"; }

//-----------------------------------------------------------------------------
template <typename T, typename... Ts>
requires(!std::is_convertible_v<std::decay_t<T> &, std::ostream &>)
void write(T &&t, Ts &&...ts) {
Expand All @@ -34,4 +38,6 @@ void writeln(T &&t, Ts &&...ts) {
writeln(std::cout, std::forward<T>(t), std::forward<Ts>(ts)...);
}

inline void writeln() { writeln(std::cout); }

} // namespace chplx
3 changes: 3 additions & 0 deletions library/test/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,20 @@ set(tests
atomic
begin
cobegin
coforall_loop_array
coforall_loop_assoc_domain
coforall_loop_domain
coforall_loop_range
coforall_loop_tuple
coforall_loop_zip
domain
forall_loop_array
forall_loop_assoc_domain
forall_loop_domain
forall_loop_range
forall_loop_tuple
forall_loop_zip
for_loop_array
for_loop_assoc_domain
for_loop_domain
for_loop_range
Expand Down
222 changes: 222 additions & 0 deletions library/test/unit/coforall_loop_array.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
// Copyright (c) 2023 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 <chplx.hpp>

#include <hpx/hpx_main.hpp>
#include <hpx/modules/testing.hpp>
#include <hpx/thread.hpp>

#include <cstddef>
#include <mutex>
#include <set>

template <typename T, typename Domain>
void testCoforallLoopArray(chplx::Array<T, Domain> d) {

std::set<T> values;
hpx::mutex mtx;

std::size_t count = 0;

chplx::coforall(
d,
[&](auto &value, int fortytwo) {
HPX_TEST_EQ(fortytwo, 42);
std::lock_guard l(mtx);
++count;
auto p = values.insert(value);
HPX_TEST(p.second);
},
42);

HPX_TEST_EQ(count, static_cast<std::size_t>(d.size()));
count = 0;

for (auto val : d.these()) {
++count;
HPX_TEST(values.contains(val));
}

HPX_TEST_EQ(count, values.size());
}

namespace detail {

//-----------------------------------------------------------------------------
template <typename T, typename R> auto initArray1D(R &&r) {

auto array = chplx::Array(chplx::Domain(r), T());
T value = T();
chplx::forLoop(array, [&](auto &v) { v = ++value; });
return array;
}

template <typename T, typename... Rs, std::size_t... Is>
void testCoforallLoopArrays1D(chplx::Tuple<Rs...> const &r,
std::index_sequence<Is...> s) {

(testCoforallLoopArray(initArray1D<T>(std::get<Is>(r))), ...);
}

//-----------------------------------------------------------------------------
template <typename T, typename R1, typename R2>
auto initArray2D(R1 &&r1, R2 &&r2) {

auto array = chplx::Array(chplx::Domain(r1, r2), T());
T value = T();
chplx::forLoop(array, [&](auto &v) { v = ++value; });
return array;
}

template <typename T, std::size_t N, typename... Rs, std::size_t... Js>
void testCoforallLoopArrays2D(chplx::Tuple<Rs...> const &r,
std::index_sequence<Js...>) {

(testCoforallLoopArray(initArray2D<T>(std::get<Js>(r), std::get<N>(r))), ...);
}

template <typename T, typename... Rs, std::size_t... Is>
void testCoforallLoopArrays2D(chplx::Tuple<Rs...> const &r,
std::index_sequence<Is...> s) {

(testCoforallLoopArrays2D<T, Is>(r, s), ...);
}

//-----------------------------------------------------------------------------
template <typename T, typename R1, typename R2, typename R3>
auto initArray3D(R1 &&r1, R2 &&r2, R3 &&r3) {

auto array = chplx::Array(chplx::Domain(r1, r2, r3), T());
T value = T();
chplx::forLoop(array, [&](auto &v) { v = ++value; });
return array;
}

template <typename T, std::size_t N, std::size_t M, typename... Rs,
std::size_t... Js>
void testCoforallLoopArrays3D_2(chplx::Tuple<Rs...> const &r,
std::index_sequence<Js...>) {

(testCoforallLoopArray(
initArray3D<T>(std::get<Js>(r), std::get<N>(r), std::get<M>(r))),
...);
}

template <typename T, std::size_t N, typename... Rs, std::size_t... Is>
void testCoforallLoopArrays3D_1(chplx::Tuple<Rs...> const &r,
std::index_sequence<Is...> s) {

(testCoforallLoopArrays3D_2<T, N, Is>(r, s), ...);
}

template <typename T, typename... Rs, std::size_t... Is>
void testCoforallLoopArrays3D(chplx::Tuple<Rs...> const &r,
std::index_sequence<Is...> s) {

(testCoforallLoopArrays3D_1<T, Is>(r, s), ...);
}

//-----------------------------------------------------------------------------
template <typename T, typename R1, typename R2, typename R3, typename R4>
auto initArray4D(R1 &&r1, R2 &&r2, R3 &&r3, R4 &&r4) {

auto array = chplx::Array(chplx::Domain(r1, r2, r3, r4), T());
T value = T();
chplx::forLoop(array, [&](auto &v) { v = ++value; });
return array;
}

template <typename T, std::size_t N, std::size_t M, std::size_t O,
typename... Rs, std::size_t... Js>
void testCoforallLoopArrays4D_3(chplx::Tuple<Rs...> const &r,
std::index_sequence<Js...>) {

(testCoforallLoopArray(initArray4D<T>(std::get<Js>(r), std::get<N>(r),
std::get<M>(r), std::get<O>(r))),
...);
}

template <typename T, std::size_t N, std::size_t M, typename... Rs,
std::size_t... Is>
void testCoforallLoopArrays4D_2(chplx::Tuple<Rs...> const &r,
std::index_sequence<Is...> s) {

(testCoforallLoopArrays4D_3<T, N, M, Is>(r, s), ...);
}

template <typename T, std::size_t N, typename... Rs, std::size_t... Is>
void testCoforallLoopArrays4D_1(chplx::Tuple<Rs...> const &r,
std::index_sequence<Is...> s) {

(testCoforallLoopArrays4D_2<T, N, Is>(r, s), ...);
}

template <typename T, typename... Rs, std::size_t... Is>
void testCoforallLoopArrays4D(chplx::Tuple<Rs...> const &r,
std::index_sequence<Is...> s) {

(testCoforallLoopArrays4D_1<T, Is>(r, s), ...);
}

} // namespace detail

template <typename T, typename... Rs>
void testCoforallLoopArrays1D(chplx::Tuple<Rs...> r) {

detail::testCoforallLoopArrays1D<T>(
r, std::make_index_sequence<sizeof...(Rs)>());
}

template <typename T, typename... Rs>
void testCoforallLoopArrays2D(chplx::Tuple<Rs...> r) {

detail::testCoforallLoopArrays2D<T>(
r, std::make_index_sequence<sizeof...(Rs)>());
}

template <typename T, typename... Rs>
void testCoforallLoopArrays3D(chplx::Tuple<Rs...> r) {

detail::testCoforallLoopArrays3D<T>(
r, std::make_index_sequence<sizeof...(Rs)>());
}

template <typename T, typename... Rs>
void testCoforallLoopArrays4D(chplx::Tuple<Rs...> r) {

detail::testCoforallLoopArrays4D<T>(
r, std::make_index_sequence<sizeof...(Rs)>());
}

int main() {

{
auto constexpr r1 = chplx::Range(0, 10);
auto constexpr r2 = chplx::BoundedRange<int, true>(0, 10, -1);
auto constexpr r3 = chplx::BoundedRange<int, true>(0, 10, 2);
auto constexpr r4 = chplx::BoundedRange<int, true>(0, 10, -2);

testCoforallLoopArrays1D<double>(chplx::Tuple(r1, r2, r3, r4));
testCoforallLoopArrays2D<double>(chplx::Tuple(r1, r2, r3, r4));
testCoforallLoopArrays3D<double>(chplx::Tuple(r1, r2, r3, r4));
testCoforallLoopArrays4D<double>(chplx::Tuple(r1, r2, r3, r4));
}

{
auto constexpr r1 = chplx::Range(1, 9);
auto constexpr r2 = chplx::BoundedRange<int, true>(1, 9, -1);
auto constexpr r3 = chplx::BoundedRange<int, true>(1, 9, 2);
auto constexpr r4 = chplx::BoundedRange<int, true>(1, 9, -2);

testCoforallLoopArrays1D<int>(chplx::Tuple(r1, r2, r3, r4));
testCoforallLoopArrays2D<int>(chplx::Tuple(r1, r2, r3, r4));
testCoforallLoopArrays3D<int>(chplx::Tuple(r1, r2, r3, r4));
testCoforallLoopArrays4D<int>(chplx::Tuple(r1, r2, r3, r4));
}

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

0 comments on commit e710c44

Please sign in to comment.