From a5779d88d1fbcae483e26849b3003e120a73b5d3 Mon Sep 17 00:00:00 2001 From: "Brendan K. Krueger" Date: Tue, 19 Nov 2024 10:35:32 -0700 Subject: [PATCH 1/8] Add [[maybe_unused]] for variables in the array test that are only used in compile-time expressions but are needed for the tests. --- test/test_array.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/test_array.cpp b/test/test_array.cpp index 06f112b6..b1da2bea 100644 --- a/test/test_array.cpp +++ b/test/test_array.cpp @@ -119,7 +119,7 @@ TEST_CASE("array begins and ends", "[array]") { using std::end; SECTION("with non-const array") { - array arr{{1, 2, 3}}; + [[maybe_unused]] array arr{{1, 2, 3}}; CHECK(std::is_same::value); CHECK(std::is_same::value); @@ -129,7 +129,7 @@ TEST_CASE("array begins and ends", "[array]") { } SECTION("with const array") { - array const arr{{1, 2, 3}}; + [[maybe_unused]] array const arr{{1, 2, 3}}; CHECK(std::is_same::value); CHECK(std::is_same::value); @@ -139,13 +139,13 @@ TEST_CASE("array begins and ends", "[array]") { } SECTION("with non-const zero-sized array") { - array arr; + [[maybe_unused]] array arr; CHECK(begin(arr) == end(arr)); } SECTION("with const zero-sized array") { - array const arr{}; + [[maybe_unused]] array const arr{}; CHECK(begin(arr) == end(arr)); } @@ -260,7 +260,7 @@ TEST_CASE("array swap", "[array]") { } TEST_CASE("array tuple_size", "[array]") { - array arr; + [[maybe_unused]] array arr; CHECK(std::tuple_size::value == 5); } @@ -268,13 +268,13 @@ TEST_CASE("array tuple_size", "[array]") { TEST_CASE("array tuple_element", "[array]") { struct Foo {}; - array foos; + [[maybe_unused]] array foos; CHECK(std::is_same::type>::value); } TEST_CASE("make_array function", "[array]") { - auto arr = make_array(1.0, 2.0, 3.0); + [[maybe_unused]] auto arr = make_array(1.0, 2.0, 3.0); CHECK(std::is_same>::value); } From 63802f88061eaeed83782193e6c9f59c90e83d17 Mon Sep 17 00:00:00 2001 From: "Brendan K. Krueger" Date: Tue, 19 Nov 2024 11:15:11 -0700 Subject: [PATCH 2/8] Create a dumb non-trivial type to use instead of std::vector to eliminate warnings about calling __host__ functions from __host__ __device__ warnings. --- test/test_static_vector.cpp | 72 ++++++++++++++++++++++++++----------- 1 file changed, 52 insertions(+), 20 deletions(-) diff --git a/test/test_static_vector.cpp b/test/test_static_vector.cpp index 88548b27..6e45413c 100644 --- a/test/test_static_vector.cpp +++ b/test/test_static_vector.cpp @@ -13,8 +13,41 @@ namespace static_vector_test { template constexpr static bool really_const = std::is_const>::value; + +// This doesn't do anything interesting. It just needs to be non-trivial to +// test that static_vector works for non-trivial types. +struct NonTrivialType { + int n; + int * p; + PORTABLE_FUNCTION NonTrivialType(int nn) + : n{nn} + , p{&n} + {} + PORTABLE_FUNCTION NonTrivialType(const NonTrivialType & other) + : n{other.n} + , p{&n} + {} + PORTABLE_FUNCTION NonTrivialType(NonTrivialType && other) + : n{other.n} + , p{&n} + {} + PORTABLE_FUNCTION NonTrivialType& operator=(const NonTrivialType & other) { + n = other.n; + p = &n; + return *this; + } + PORTABLE_FUNCTION NonTrivialType& operator=(NonTrivialType && other) { + n = other.n; + p = &n; + return *this; + } + PORTABLE_FUNCTION ~NonTrivialType() {} +}; + } +static_assert(!std::is_trivial::value); + TEST_CASE("static_vector", "[util][static_vector]") { using std::begin; using std::cbegin; @@ -22,6 +55,7 @@ TEST_CASE("static_vector", "[util][static_vector]") { using std::end; using static_vector_test::really_const; + using static_vector_test::NonTrivialType; SECTION("begin/end iteration") { SECTION("with non-zero size") { @@ -139,10 +173,9 @@ TEST_CASE("static_vector", "[util][static_vector]") { } SECTION("with non-trivial type") { - using test_t = PortsOfCall::static_vector, 5>; + using test_t = PortsOfCall::static_vector; - test_t data = {std::vector(2), std::vector(4), - std::vector(6)}; + test_t data = {NonTrivialType(2), NonTrivialType(4), NonTrivialType(6)}; CHECK(data.size() == 3); data.clear(); CHECK(data.size() == 0); @@ -150,35 +183,34 @@ TEST_CASE("static_vector", "[util][static_vector]") { } SECTION("push_back/emplace_back") { - using test_t = PortsOfCall::static_vector, 5>; + using test_t = PortsOfCall::static_vector; test_t data; - auto insert = std::vector(1); + auto insert = NonTrivialType(1); data.push_back(insert); // Note: Some compilers struggle to parse the Catch2 macros, and will generate errors // if you declare a lambda inside a CHECK macro. Therefore we move the line with the // lambda outside of the CHECK. - auto expected1 = {std::vector(1)}; + auto expected1 = {NonTrivialType(1)}; auto size_check1 = std::equal(begin(data), end(data), begin(expected1), end(expected1), - [](auto const &l, auto const &r) { return l.size() == r.size(); }); + [](auto const &l, auto const &r) { return l.n == r.n; }); CHECK(size_check1); - data.push_back(std::vector(2)); - auto expected2 = {std::vector(1), std::vector(2)}; + data.push_back(NonTrivialType(2)); + auto expected2 = {NonTrivialType(1), NonTrivialType(2)}; auto size_check2 = std::equal(begin(data), end(data), begin(expected2), end(expected2), - [](auto const &l, auto const &r) { return l.size() == r.size(); }); + [](auto const &l, auto const &r) { return l.n == r.n; }); CHECK(size_check2); data.emplace_back(3); - auto expected3 = {std::vector(1), std::vector(2), - std::vector(3)}; + auto expected3 = {NonTrivialType(1), NonTrivialType(2), NonTrivialType(3)}; auto size_check3 = std::equal(begin(data), end(data), begin(expected3), end(expected3), - [](auto const &l, auto const &r) { return l.size() == r.size(); }); + [](auto const &l, auto const &r) { return l.n == r.n; }); CHECK(size_check3); } @@ -193,18 +225,18 @@ TEST_CASE("static_vector", "[util][static_vector]") { } SECTION("with non-trivial type") { - using test_t = PortsOfCall::static_vector, 5>; - test_t data = {std::vector(1), std::vector(2), - std::vector(3), std::vector(4), - std::vector(5)}; + using test_t = PortsOfCall::static_vector; + test_t data = {NonTrivialType(1), NonTrivialType(2), + NonTrivialType(3), NonTrivialType(4), + NonTrivialType(5)}; data.pop_back(); - test_t const expected = {std::vector(1), std::vector(2), - std::vector(3), std::vector(4)}; + test_t const expected = {NonTrivialType(1), NonTrivialType(2), + NonTrivialType(3), NonTrivialType(4)}; auto size_check = std::equal(begin(data), end(data), begin(expected), end(expected), - [](auto const &l, auto const &r) { return l.size() == r.size(); }); + [](auto const &l, auto const &r) { return l.n == r.n; }); CHECK(size_check); } } From 4cf33933a721328a7053a3df3165fef1a3ef946d Mon Sep 17 00:00:00 2001 From: "Brendan K. Krueger" Date: Tue, 19 Nov 2024 11:47:37 -0700 Subject: [PATCH 3/8] Device-capable swap. --- ports-of-call/array.hpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/ports-of-call/array.hpp b/ports-of-call/array.hpp index 8eb90cc0..0d8f0fc3 100644 --- a/ports-of-call/array.hpp +++ b/ports-of-call/array.hpp @@ -194,9 +194,13 @@ struct array { //! swap the array contents with another PORTABLE_FUNCTION constexpr void swap(array &other) { - using std::swap; for (size_type i = 0; i < N; ++i) { - swap(arr[i], other.arr[i]); + // C++20 makes std::swap constexpr, so this should probably be replaced + // at that point. For now, this is required if a user wants to call swap + // on a GPU. + T t = arr[i]; + arr[i] = other.arr[i]; + other.arr[i] = t; } } }; From f639c92c22e7fd1a0e8cda64111eb2316fb1afe4 Mon Sep 17 00:00:00 2001 From: "Brendan K. Krueger" Date: Tue, 19 Nov 2024 12:46:03 -0700 Subject: [PATCH 4/8] Better handling of nonnegative checks in span. --- ports-of-call/span.hpp | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/ports-of-call/span.hpp b/ports-of-call/span.hpp index f8134f11..23b69141 100644 --- a/ports-of-call/span.hpp +++ b/ports-of-call/span.hpp @@ -55,6 +55,20 @@ namespace detail { using std::data; using std::size; +// type-safe check against 0 (prevents warnings about comparing an unsigned against 0) +template ::value, bool> = true> +PORTABLE_FUNCTION constexpr bool check_nonnegative(const T) +{ + return true; +} +template ::value, bool> = true> +PORTABLE_FUNCTION constexpr bool check_nonnegative(const T t) +{ + return t >= 0; +} + // object to handle storage of span template struct span_storage { @@ -195,7 +209,8 @@ class span { // explicit: extent != dynamic_extent // NB: iterator concepts to further restrict overload resolution constexpr span(pointer ptr, size_type count) : storage_(ptr, count) { - span_EXPECTS((ptr == nullptr && count == 0) || (ptr != nullptr && count >= 0)); + span_EXPECTS((ptr == nullptr && count == 0) || + (ptr != nullptr && detail::check_nonnegative(count))); } // constructs a span that is a view over the range [first, last) @@ -205,7 +220,7 @@ class span { // NB: iterator concepts to further restrict overload resolution constexpr span(pointer first_elem, pointer last_elem) : storage_(first_elem, last_elem - first_elem) { - span_EXPECTS(last_elem - first_elem >= 0); + span_EXPECTS(detail::check_nonnegative(last_elem - first_elem)); } // constructs a span that is a view over arr @@ -272,12 +287,12 @@ class span { // https://en.cppreference.com/w/cpp/container/span/first template constexpr span first() const { - span_EXPECTS(Count >= 0 && Count <= size()); + span_EXPECTS(detail::check_nonnegative(Count) && Count <= size()); return {data(), Count}; } constexpr span first(size_type count) const { - span_EXPECTS(count >= 0 && count <= size()); + span_EXPECTS(detail::check_nonnegative(count) && count <= size()); return {data(), count}; } @@ -285,12 +300,12 @@ class span { // https://en.cppreference.com/w/cpp/container/span/last template constexpr span last() const { - span_EXPECTS(Count >= 0 && Count <= size()); + span_EXPECTS(detail::check_nonnegative(Count) && Count <= size()); return {data() + (size() - Count), Count}; } constexpr span last(size_type count) const { - span_EXPECTS(count >= 0 && count <= size()); + span_EXPECTS(detail::check_nonnegative(count) && count <= size()); return {data() + (size() - count), count}; } @@ -305,16 +320,16 @@ class span { template constexpr subspan_return_t subspan() const { - span_EXPECTS((Offset >= 0 && Offset <= size()) && - (Count == dynamic_extent || (Count >= 0 && Count + Offset <= size()))); + span_EXPECTS((detail::check_nonnegative(Offset) && Offset <= size()) && + (Count == dynamic_extent || (detail::check_nonnegative(Count) && Count + Offset <= size()))); return {data() + Offset, Count != dynamic_extent ? Count : size() - Offset}; } constexpr span subspan(size_type offset, size_type count = dynamic_extent) const { - span_EXPECTS((offset >= 0 && offset <= size()) && + span_EXPECTS((detail::check_nonnegative(offset) && offset <= size()) && (count == static_cast(dynamic_extent) || - (count >= 0 && count + offset <= size()))); + (detail::check_nonnegative(count) && count + offset <= size()))); return {data() + offset, count == dynamic_extent ? size() - offset : count}; } @@ -337,7 +352,7 @@ class span { // [span.element_access]-- constexpr reference operator[](size_type idx) const { - span_EXPECTS(idx >= 0 && idx < size()); + span_EXPECTS(detail::check_nonnegative(idx) && idx < size()); return *(data() + idx); } From dfacbf28a15f133bea9aa313cb7d3ea6b3f004ca Mon Sep 17 00:00:00 2001 From: "Brendan K. Krueger" Date: Tue, 19 Nov 2024 15:46:42 -0700 Subject: [PATCH 5/8] Copying the warning flags from Nautilus. --- test/CMakeLists.txt | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 733458c5..b32b085c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -56,6 +56,41 @@ elseif (PORTS_OF_CALL_TEST_PORTABILITY_STRATEGY STREQUAL "Cuda") target_compile_definitions(portsofcall_iface INTERFACE PORTABILITY_STRATEGY_CUDA) endif() +if(NOT PORTS_OF_CALL_SILENCE_WARNINGS) + # turn on strict warnings and error + # NOTE: The ROCm 6.2.1 installation on some machines (RZAdams and RZVernal at least) will + # inject a `--gcc-toolchain` command-line argument into Clang, which is a deprecated + # option. Clang will warn about unused command-line arguments, so you get multiple + # instances of that warning. Then `-Werror` promotes those to errors. We can turn these + # back to non-fatal warnings with `-Wno-error=unused-command-line-argument` or we can + # turn off that particular warning with `-Wno-unused-command-line-argument`. + # TODO: find comiler flags for non-GNU compatible compilers + target_compile_options(portsofcall_iface INTERFACE + $<$:-Werror;-Wall;-pedantic-errors;-Wunused-parameter> + $<$:-Werror;-Wall;-Wunused-parameter> + $<$>:$<$:-Werror;-Wall;-Wno-unused-command-line-argument>> + $<$:$<$:-Wall;-Wno-c++98-compat;-Wno-c++98-compat-pedantic>> + $<$:-Werror;-w2;-Wunused-variable;-Wunused-parameter;-diag-disable=remark> + $<$:> + $<$:/permissive-> + $<$:> + ) +else() + # turn off warnings + # TODO: find comiler flags for non-GNU compatible compilers + target_compile_options(portsofcall_iface INTERFACE + $<$:-w> + $<$:> + $<$>:$<$:>> + $<$:$<$:>> + $<$:> + $<$:> + $<$:> + $<$:> + ) +endif() + + target_link_libraries(portsofcall_iface INTERFACE Catch2::Catch2) add_executable(test_portsofcall test_main.cpp) From 19fbfff3306addc33bf7c8adec8624a01fc278f0 Mon Sep 17 00:00:00 2001 From: "Brendan K. Krueger" Date: Tue, 19 Nov 2024 15:56:05 -0700 Subject: [PATCH 6/8] Changes to address warnings from the new warning flags. --- test/test_array.cpp | 2 +- test/test_portability.cpp | 4 ++-- test/test_span.cpp | 2 +- test/test_static_vector.cpp | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/test/test_array.cpp b/test/test_array.cpp index b1da2bea..4158ce5d 100644 --- a/test/test_array.cpp +++ b/test/test_array.cpp @@ -208,7 +208,7 @@ TEST_CASE("array sizes", "[array]") { TEST_CASE("array fill (GPU)", "[array][GPU]") { constexpr std::size_t N = 42; std::size_t count = 0; - auto func = PORTABLE_LAMBDA(const int i, std::size_t &count) { + auto func = PORTABLE_LAMBDA(const int /*i*/, std::size_t &count) { constexpr double value = 3.14; array arr; arr.fill(value); diff --git a/test/test_portability.cpp b/test/test_portability.cpp index ac7bd60d..8f81e624 100644 --- a/test/test_portability.cpp +++ b/test/test_portability.cpp @@ -102,7 +102,7 @@ TEST_CASE("portableCopy works with all portability strategies", "[portableCopy]" int sum{0}; portableReduce( "check portableCopy", 0, N, 0, 0, 0, 0, - PORTABLE_LAMBDA(const int &i, const int &j, const int &k, int &isum) { + PORTABLE_LAMBDA(const int &i, const int &/*j*/, const int &/*k*/, int &isum) { if (a[i] != index_func(i)) { isum += 1; } @@ -121,7 +121,7 @@ TEST_CASE("portableCopy works with all portability strategies", "[portableCopy]" // count elements that don't match reference sum = 0; - for (int i = 0; i < N; ++i) { + for (size_t i = 0; i < N; ++i) { if (b[i] != index_func(i)) { sum += 1; } diff --git a/test/test_span.cpp b/test/test_span.cpp index 799a0d44..20e4693f 100644 --- a/test/test_span.cpp +++ b/test/test_span.cpp @@ -569,7 +569,7 @@ TEST_CASE("span portability", "[PortsOfCall::span]") { constexpr Real d_gp = 2. * pi / static_cast(N); std::vector h_gp(N); - for (auto i = 0; i < N; ++i) { + for (std::size_t i = 0; i < N; ++i) { h_gp[i] = -pi + static_cast(i) * d_gp; } diff --git a/test/test_static_vector.cpp b/test/test_static_vector.cpp index 6e45413c..cadfb050 100644 --- a/test/test_static_vector.cpp +++ b/test/test_static_vector.cpp @@ -70,8 +70,8 @@ TEST_CASE("static_vector", "[util][static_vector]") { CHECK(not really_const); CHECK(not really_const); - auto cb = cbegin(data); - auto ce = cend(data); + [[maybe_unused]] auto cb = cbegin(data); + [[maybe_unused]] auto ce = cend(data); CHECK(really_const); CHECK(really_const); From f2a1d740eb2bce7bea725acca4a6ede2782b3571 Mon Sep 17 00:00:00 2001 From: "Brendan K. Krueger" Date: Wed, 20 Nov 2024 09:31:01 -0700 Subject: [PATCH 7/8] Missing maybe_unused (only shows up if you're not using Kokkos). --- ports-of-call/portability.hpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/ports-of-call/portability.hpp b/ports-of-call/portability.hpp index 5553d18d..8d57b7c0 100644 --- a/ports-of-call/portability.hpp +++ b/ports-of-call/portability.hpp @@ -153,7 +153,7 @@ void portableCopyToHost(T *const to, T const *const from, size_t const size_byte } template -void portableFor(const char *name, int start, int stop, Function function) { +void portableFor([[maybe_unused]] const char *name, int start, int stop, Function function) { #ifdef PORTABILITY_STRATEGY_KOKKOS using policy = Kokkos::RangePolicy<>; Kokkos::parallel_for(name, policy(start, stop), function); @@ -165,7 +165,7 @@ void portableFor(const char *name, int start, int stop, Function function) { } template -void portableFor(const char *name, int starty, int stopy, int startx, int stopx, +void portableFor([[maybe_unused]] const char *name, int starty, int stopy, int startx, int stopx, Function function) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy2D = Kokkos::MDRangePolicy>; @@ -180,7 +180,7 @@ void portableFor(const char *name, int starty, int stopy, int startx, int stopx, } template -void portableFor(const char *name, int startz, int stopz, int starty, int stopy, +void portableFor([[maybe_unused]] const char *name, int startz, int stopz, int starty, int stopy, int startx, int stopx, Function function) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy3D = Kokkos::MDRangePolicy>; @@ -198,7 +198,7 @@ void portableFor(const char *name, int startz, int stopz, int starty, int stopy, } template -void portableFor(const char *name, int starta, int stopa, int startz, int stopz, +void portableFor([[maybe_unused]] const char *name, int starta, int stopa, int startz, int stopz, int starty, int stopy, int startx, int stopx, Function function) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy4D = Kokkos::MDRangePolicy>; @@ -219,7 +219,7 @@ void portableFor(const char *name, int starta, int stopa, int startz, int stopz, } template -void portableFor(const char *name, int startb, int stopb, int starta, int stopa, +void portableFor([[maybe_unused]] const char *name, int startb, int stopb, int starta, int stopa, int startz, int stopz, int starty, int stopy, int startx, int stopx, Function function) { #ifdef PORTABILITY_STRATEGY_KOKKOS @@ -244,7 +244,7 @@ void portableFor(const char *name, int startb, int stopb, int starta, int stopa, } template -void portableReduce(const char *name, int start, int stop, Function function, +void portableReduce([[maybe_unused]] const char *name, int start, int stop, Function function, T &reduced) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy = Kokkos::RangePolicy<>; @@ -257,7 +257,7 @@ void portableReduce(const char *name, int start, int stop, Function function, } template -void portableReduce(const char *name, int starty, int stopy, int startx, int stopx, +void portableReduce([[maybe_unused]] const char *name, int starty, int stopy, int startx, int stopx, Function function, T &reduced) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy2D = Kokkos::MDRangePolicy>; @@ -273,7 +273,7 @@ void portableReduce(const char *name, int starty, int stopy, int startx, int sto } template -void portableReduce(const char *name, int startz, int stopz, int starty, int stopy, +void portableReduce([[maybe_unused]] const char *name, int startz, int stopz, int starty, int stopy, int startx, int stopx, Function function, T &reduced) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy3D = Kokkos::MDRangePolicy>; @@ -291,7 +291,7 @@ void portableReduce(const char *name, int startz, int stopz, int starty, int sto } template -void portableReduce(const char *name, int starta, int stopa, int startz, int stopz, +void portableReduce([[maybe_unused]] const char *name, int starta, int stopa, int startz, int stopz, int starty, int stopy, int startx, int stopx, Function function, T &reduced) { #ifdef PORTABILITY_STRATEGY_KOKKOS @@ -313,7 +313,7 @@ void portableReduce(const char *name, int starta, int stopa, int startz, int sto } template -void portableReduce(const char *name, int startb, int stopb, int starta, int stopa, +void portableReduce([[maybe_unused]] const char *name, int startb, int stopb, int starta, int stopa, int startz, int stopz, int starty, int stopy, int startx, int stopx, Function function, T &reduced) { #ifdef PORTABILITY_STRATEGY_KOKKOS From 5bf92e844b425ff42a216322da5e94e5ed4b4cef Mon Sep 17 00:00:00 2001 From: "Brendan K. Krueger" Date: Wed, 20 Nov 2024 09:43:49 -0700 Subject: [PATCH 8/8] format --- ports-of-call/portability.hpp | 46 +++++++++++++------------ ports-of-call/span.hpp | 21 +++++------- test/test_portability.cpp | 2 +- test/test_span.cpp | 3 +- test/test_static_vector.cpp | 54 ++++++++++++------------------ test/test_static_vector_kokkos.cpp | 2 +- 6 files changed, 58 insertions(+), 70 deletions(-) diff --git a/ports-of-call/portability.hpp b/ports-of-call/portability.hpp index 8d57b7c0..eb5f3540 100644 --- a/ports-of-call/portability.hpp +++ b/ports-of-call/portability.hpp @@ -153,7 +153,8 @@ void portableCopyToHost(T *const to, T const *const from, size_t const size_byte } template -void portableFor([[maybe_unused]] const char *name, int start, int stop, Function function) { +void portableFor([[maybe_unused]] const char *name, int start, int stop, + Function function) { #ifdef PORTABILITY_STRATEGY_KOKKOS using policy = Kokkos::RangePolicy<>; Kokkos::parallel_for(name, policy(start, stop), function); @@ -165,8 +166,8 @@ void portableFor([[maybe_unused]] const char *name, int start, int stop, Functio } template -void portableFor([[maybe_unused]] const char *name, int starty, int stopy, int startx, int stopx, - Function function) { +void portableFor([[maybe_unused]] const char *name, int starty, int stopy, int startx, + int stopx, Function function) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy2D = Kokkos::MDRangePolicy>; Kokkos::parallel_for(name, Policy2D({starty, startx}, {stopy, stopx}), function); @@ -180,8 +181,8 @@ void portableFor([[maybe_unused]] const char *name, int starty, int stopy, int s } template -void portableFor([[maybe_unused]] const char *name, int startz, int stopz, int starty, int stopy, - int startx, int stopx, Function function) { +void portableFor([[maybe_unused]] const char *name, int startz, int stopz, int starty, + int stopy, int startx, int stopx, Function function) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy3D = Kokkos::MDRangePolicy>; Kokkos::parallel_for(name, Policy3D({startz, starty, startx}, {stopz, stopy, stopx}), @@ -198,8 +199,9 @@ void portableFor([[maybe_unused]] const char *name, int startz, int stopz, int s } template -void portableFor([[maybe_unused]] const char *name, int starta, int stopa, int startz, int stopz, - int starty, int stopy, int startx, int stopx, Function function) { +void portableFor([[maybe_unused]] const char *name, int starta, int stopa, int startz, + int stopz, int starty, int stopy, int startx, int stopx, + Function function) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy4D = Kokkos::MDRangePolicy>; Kokkos::parallel_for( @@ -219,9 +221,9 @@ void portableFor([[maybe_unused]] const char *name, int starta, int stopa, int s } template -void portableFor([[maybe_unused]] const char *name, int startb, int stopb, int starta, int stopa, - int startz, int stopz, int starty, int stopy, int startx, int stopx, - Function function) { +void portableFor([[maybe_unused]] const char *name, int startb, int stopb, int starta, + int stopa, int startz, int stopz, int starty, int stopy, int startx, + int stopx, Function function) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy5D = Kokkos::MDRangePolicy>; Kokkos::parallel_for(name, @@ -244,8 +246,8 @@ void portableFor([[maybe_unused]] const char *name, int startb, int stopb, int s } template -void portableReduce([[maybe_unused]] const char *name, int start, int stop, Function function, - T &reduced) { +void portableReduce([[maybe_unused]] const char *name, int start, int stop, + Function function, T &reduced) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy = Kokkos::RangePolicy<>; Kokkos::parallel_reduce(name, Policy(start, stop), function, reduced); @@ -257,8 +259,8 @@ void portableReduce([[maybe_unused]] const char *name, int start, int stop, Func } template -void portableReduce([[maybe_unused]] const char *name, int starty, int stopy, int startx, int stopx, - Function function, T &reduced) { +void portableReduce([[maybe_unused]] const char *name, int starty, int stopy, int startx, + int stopx, Function function, T &reduced) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy2D = Kokkos::MDRangePolicy>; Kokkos::parallel_reduce(name, Policy2D({starty, startx}, {stopy, stopx}), function, @@ -273,8 +275,8 @@ void portableReduce([[maybe_unused]] const char *name, int starty, int stopy, in } template -void portableReduce([[maybe_unused]] const char *name, int startz, int stopz, int starty, int stopy, - int startx, int stopx, Function function, T &reduced) { +void portableReduce([[maybe_unused]] const char *name, int startz, int stopz, int starty, + int stopy, int startx, int stopx, Function function, T &reduced) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy3D = Kokkos::MDRangePolicy>; Kokkos::parallel_reduce(name, Policy3D({startz, starty, startx}, {stopz, stopy, stopx}), @@ -291,9 +293,9 @@ void portableReduce([[maybe_unused]] const char *name, int startz, int stopz, in } template -void portableReduce([[maybe_unused]] const char *name, int starta, int stopa, int startz, int stopz, - int starty, int stopy, int startx, int stopx, Function function, - T &reduced) { +void portableReduce([[maybe_unused]] const char *name, int starta, int stopa, int startz, + int stopz, int starty, int stopy, int startx, int stopx, + Function function, T &reduced) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy4D = Kokkos::MDRangePolicy>; Kokkos::parallel_reduce( @@ -313,9 +315,9 @@ void portableReduce([[maybe_unused]] const char *name, int starta, int stopa, in } template -void portableReduce([[maybe_unused]] const char *name, int startb, int stopb, int starta, int stopa, - int startz, int stopz, int starty, int stopy, int startx, int stopx, - Function function, T &reduced) { +void portableReduce([[maybe_unused]] const char *name, int startb, int stopb, int starta, + int stopa, int startz, int stopz, int starty, int stopy, int startx, + int stopx, Function function, T &reduced) { #ifdef PORTABILITY_STRATEGY_KOKKOS using Policy5D = Kokkos::MDRangePolicy>; Kokkos::parallel_reduce(name, diff --git a/ports-of-call/span.hpp b/ports-of-call/span.hpp index 23b69141..2739e1e1 100644 --- a/ports-of-call/span.hpp +++ b/ports-of-call/span.hpp @@ -56,17 +56,13 @@ using std::data; using std::size; // type-safe check against 0 (prevents warnings about comparing an unsigned against 0) -template ::value, bool> = true> -PORTABLE_FUNCTION constexpr bool check_nonnegative(const T) -{ +template ::value, bool> = true> +PORTABLE_FUNCTION constexpr bool check_nonnegative(const T) { return true; } -template ::value, bool> = true> -PORTABLE_FUNCTION constexpr bool check_nonnegative(const T t) -{ - return t >= 0; +template ::value, bool> = true> +PORTABLE_FUNCTION constexpr bool check_nonnegative(const T t) { + return t >= 0; } // object to handle storage of span @@ -210,7 +206,7 @@ class span { // NB: iterator concepts to further restrict overload resolution constexpr span(pointer ptr, size_type count) : storage_(ptr, count) { span_EXPECTS((ptr == nullptr && count == 0) || - (ptr != nullptr && detail::check_nonnegative(count))); + (ptr != nullptr && detail::check_nonnegative(count))); } // constructs a span that is a view over the range [first, last) @@ -321,7 +317,8 @@ class span { template constexpr subspan_return_t subspan() const { span_EXPECTS((detail::check_nonnegative(Offset) && Offset <= size()) && - (Count == dynamic_extent || (detail::check_nonnegative(Count) && Count + Offset <= size()))); + (Count == dynamic_extent || + (detail::check_nonnegative(Count) && Count + Offset <= size()))); return {data() + Offset, Count != dynamic_extent ? Count : size() - Offset}; } @@ -396,7 +393,7 @@ span(const std::array &) -> span; template span(Container &) -> span()))>::type>; + decltype(*detail::data(std::declval()))>::type>; template span(const Container &) -> span; diff --git a/test/test_portability.cpp b/test/test_portability.cpp index 8f81e624..04d4dad0 100644 --- a/test/test_portability.cpp +++ b/test/test_portability.cpp @@ -102,7 +102,7 @@ TEST_CASE("portableCopy works with all portability strategies", "[portableCopy]" int sum{0}; portableReduce( "check portableCopy", 0, N, 0, 0, 0, 0, - PORTABLE_LAMBDA(const int &i, const int &/*j*/, const int &/*k*/, int &isum) { + PORTABLE_LAMBDA(const int &i, const int & /*j*/, const int & /*k*/, int &isum) { if (a[i] != index_func(i)) { isum += 1; } diff --git a/test/test_span.cpp b/test/test_span.cpp index 20e4693f..090a730e 100644 --- a/test/test_span.cpp +++ b/test/test_span.cpp @@ -61,8 +61,7 @@ constexpr void generate(ForwardIt first, ForwardIt last, Generator g) { } template -[[nodiscard]] -constexpr auto slide(span s, std::size_t offset, std::size_t width) { +[[nodiscard]] constexpr auto slide(span s, std::size_t offset, std::size_t width) { return s.subspan(offset, offset + width <= s.size() ? width : 0U); } diff --git a/test/test_static_vector.cpp b/test/test_static_vector.cpp index cadfb050..815c3baa 100644 --- a/test/test_static_vector.cpp +++ b/test/test_static_vector.cpp @@ -17,34 +17,25 @@ constexpr static bool really_const = std::is_const>:: // This doesn't do anything interesting. It just needs to be non-trivial to // test that static_vector works for non-trivial types. struct NonTrivialType { - int n; - int * p; - PORTABLE_FUNCTION NonTrivialType(int nn) - : n{nn} - , p{&n} - {} - PORTABLE_FUNCTION NonTrivialType(const NonTrivialType & other) - : n{other.n} - , p{&n} - {} - PORTABLE_FUNCTION NonTrivialType(NonTrivialType && other) - : n{other.n} - , p{&n} - {} - PORTABLE_FUNCTION NonTrivialType& operator=(const NonTrivialType & other) { - n = other.n; - p = &n; - return *this; - } - PORTABLE_FUNCTION NonTrivialType& operator=(NonTrivialType && other) { - n = other.n; - p = &n; - return *this; - } - PORTABLE_FUNCTION ~NonTrivialType() {} + int n; + int *p; + PORTABLE_FUNCTION NonTrivialType(int nn) : n{nn}, p{&n} {} + PORTABLE_FUNCTION NonTrivialType(const NonTrivialType &other) : n{other.n}, p{&n} {} + PORTABLE_FUNCTION NonTrivialType(NonTrivialType &&other) : n{other.n}, p{&n} {} + PORTABLE_FUNCTION NonTrivialType &operator=(const NonTrivialType &other) { + n = other.n; + p = &n; + return *this; + } + PORTABLE_FUNCTION NonTrivialType &operator=(NonTrivialType &&other) { + n = other.n; + p = &n; + return *this; + } + PORTABLE_FUNCTION ~NonTrivialType() {} }; -} +} // namespace static_vector_test static_assert(!std::is_trivial::value); @@ -54,8 +45,8 @@ TEST_CASE("static_vector", "[util][static_vector]") { using std::cend; using std::end; - using static_vector_test::really_const; using static_vector_test::NonTrivialType; + using static_vector_test::really_const; SECTION("begin/end iteration") { SECTION("with non-zero size") { @@ -226,13 +217,12 @@ TEST_CASE("static_vector", "[util][static_vector]") { SECTION("with non-trivial type") { using test_t = PortsOfCall::static_vector; - test_t data = {NonTrivialType(1), NonTrivialType(2), - NonTrivialType(3), NonTrivialType(4), - NonTrivialType(5)}; + test_t data = {NonTrivialType(1), NonTrivialType(2), NonTrivialType(3), + NonTrivialType(4), NonTrivialType(5)}; data.pop_back(); - test_t const expected = {NonTrivialType(1), NonTrivialType(2), - NonTrivialType(3), NonTrivialType(4)}; + test_t const expected = {NonTrivialType(1), NonTrivialType(2), NonTrivialType(3), + NonTrivialType(4)}; auto size_check = std::equal(begin(data), end(data), begin(expected), end(expected), diff --git a/test/test_static_vector_kokkos.cpp b/test/test_static_vector_kokkos.cpp index 12097cdf..03389374 100644 --- a/test/test_static_vector_kokkos.cpp +++ b/test/test_static_vector_kokkos.cpp @@ -114,4 +114,4 @@ TEST_CASE("static vector GPU", "[reaction_network]") { // ================================================================================================ -#endif //PORTABILITY_STRATEGY_KOKKOS +#endif // PORTABILITY_STRATEGY_KOKKOS