From d39692260a11fbbb9e88d2f8ef46891f872933e4 Mon Sep 17 00:00:00 2001 From: Francesco Biscani Date: Sat, 28 Jul 2018 18:28:10 +0200 Subject: [PATCH] Cleanups, compile fixes, more interface work, internal docs. --- benchmark/benchmark_00.cpp | 8 ++++---- include/rakau/tree.hpp | 42 +++++++++++++++++++++++++++----------- test/accuracy.cpp | 3 +-- test/update.cpp | 9 ++++---- 4 files changed, 39 insertions(+), 23 deletions(-) diff --git a/benchmark/benchmark_00.cpp b/benchmark/benchmark_00.cpp index aa945f3..761a0bd 100644 --- a/benchmark/benchmark_00.cpp +++ b/benchmark/benchmark_00.cpp @@ -7,6 +7,7 @@ // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #include +#include #include #include @@ -93,10 +94,9 @@ int main(int argc, char **argv) // auto parts = get_uniform_particles<3>(nparts, bsize); auto parts = get_plummer_sphere(nparts, bsize); - tree<3, float> t( - bsize, - std::array{parts.begin() + nparts, parts.begin() + 2 * nparts, parts.begin() + 3 * nparts, parts.begin()}, - nparts, max_leaf_n, ncrit); + tree<3, float> t(bsize, + {parts.begin() + nparts, parts.begin() + 2 * nparts, parts.begin() + 3 * nparts, parts.begin()}, + nparts, max_leaf_n, ncrit); std::cout << t << '\n'; std::array, 3> accs; t.accs_u(accs, 0.75f); diff --git a/include/rakau/tree.hpp b/include/rakau/tree.hpp index 986c510..4207615 100644 --- a/include/rakau/tree.hpp +++ b/include/rakau/tree.hpp @@ -1045,6 +1045,7 @@ class tree } public: + // NOTE: It needs to be a random access iterator, as we need to index into it for parallel iteration. template explicit tree(const F &box_size, std::array cm_it, const size_type &N, const size_type &max_leaf_n, const size_type &ncrit) @@ -1111,7 +1112,7 @@ class tree m_masses[i] = *(m_it + static_cast(i)); // Compute and store the code. m_codes[i] = me(disc_coords(tmp_coord.begin(), m_box_size).begin()); - // Store the index for indirect sorting. + // Store the index for indirect sorting (this is just a iota). m_isort[i] = i; } }); @@ -1148,6 +1149,32 @@ class tree + ") is too large, and it results in an overflow condition"); } } + +private: + template + static auto ilist_to_array(std::initializer_list ilist) + { + if (ilist.size() != NDim + 1u) { + throw std::invalid_argument("An initializer list containing " + std::to_string(ilist.size()) + + " iterators was used in the construction of a " + std::to_string(NDim) + + "-dimensional tree, but a list with " + std::to_string(NDim + 1u) + + " iterators is required instead (" + std::to_string(NDim) + + " iterators for the coordinates, 1 for the masses)"); + } + std::array retval; + std::copy(ilist.begin(), ilist.end(), retval.begin()); + return retval; + } + +public: + // NOTE: as in the other ctor, It must be a ra iterator. This ensures also we can def-construct it in the + // ilist_to_array() helper. + template + explicit tree(const F &box_size, std::initializer_list cm_it, const size_type &N, const size_type &max_leaf_n, + const size_type &ncrit) + : tree(box_size, ilist_to_array(cm_it), N, max_leaf_n, ncrit) + { + } tree(const tree &) = default; private: @@ -1356,8 +1383,8 @@ class tree size_type i = 0; if constexpr (simd_enabled && NDim == 3u) { // The SIMD-accelerated part. - const auto x_ptr = c_ptrs[0], y_ptr = c_ptrs[1], z_ptr = c_ptrs[2], tmp_x = tmp_ptrs[0], - tmp_y = tmp_ptrs[1], tmp_z = tmp_ptrs[2], tmp_dist3 = tmp_ptrs[3]; + const auto x_ptr = c_ptrs[0], y_ptr = c_ptrs[1], z_ptr = c_ptrs[2]; + const auto tmp_x = tmp_ptrs[0], tmp_y = tmp_ptrs[1], tmp_z = tmp_ptrs[2], tmp_dist3 = tmp_ptrs[3]; tuple_for_each(simd_sizes, [&](auto s) { constexpr auto batch_size = s.value; using batch_type = xsimd::batch; @@ -2022,15 +2049,6 @@ class tree { return ord_p_ranges_impl(*this); } - auto m_range_u() const - { - return std::make_pair(m_masses.data(), m_masses.data() + m_masses.size()); - } - auto m_range_o() const - { - return std::make_pair(boost::make_permutation_iterator(m_masses.begin(), m_ord_ind.begin()), - boost::make_permutation_iterator(m_masses.end(), m_ord_ind.end())); - } const auto &ord_ind() const { return m_ord_ind; diff --git a/test/accuracy.cpp b/test/accuracy.cpp index 2e64170..8a60575 100644 --- a/test/accuracy.cpp +++ b/test/accuracy.cpp @@ -60,8 +60,7 @@ TEST_CASE("accuracy") for (auto ncrit : ncrits) { std::vector x_diff, y_diff, z_diff; octree t( - bsize, - std::array{parts.begin() + s, parts.begin() + 2u * s, parts.begin() + 3u * s, parts.begin()}, s, + bsize, {parts.begin() + s, parts.begin() + 2u * s, parts.begin() + 3u * s, parts.begin()}, s, max_leaf_n, ncrit); t.accs_o(accs, theta); for (auto i = 0u; i < s; ++i) { diff --git a/test/update.cpp b/test/update.cpp index b3fe98b..9fdfe68 100644 --- a/test/update.cpp +++ b/test/update.cpp @@ -11,7 +11,7 @@ #define CATCH_CONFIG_MAIN #include "catch.hpp" -#include +#include #include #include #include @@ -33,9 +33,8 @@ TEST_CASE("update positions") constexpr auto bsize = static_cast(1); constexpr auto s = 10000u; auto parts = get_uniform_particles<3>(s, bsize, rng); - octree t(bsize, - std::array{parts.begin() + s, parts.begin() + 2u * s, parts.begin() + 3u * s, parts.begin()}, - s, 16, 256), + octree t(bsize, {parts.begin() + s, parts.begin() + 2u * s, parts.begin() + 3u * s, parts.begin()}, s, + 16, 256), t2(t); // Select randomly some particle indices to track. using size_type = typename decltype(t)::size_type; @@ -44,7 +43,7 @@ TEST_CASE("update positions") std::generate(track_idx.begin(), track_idx.end(), [&idist]() { return idist(rng); }); // First let's verify that the ordered ranges functions are working properly. auto pro = t.p_ranges_o(); - using oit_diff_t = typename std::iterator_traits::difference_type; + using oit_diff_t = typename std::iterator_traits::difference_type; for (auto idx : track_idx) { REQUIRE(pro[0].first[static_cast(idx)] == parts[s + idx]); REQUIRE(pro[1].first[static_cast(idx)] == parts[2 * s + idx]);