Skip to content

Commit

Permalink
Speeding up compile/link time for applications using partitioned_vector
Browse files Browse the repository at this point in the history
- by pre-compiling partitioned_vector<double>, partitioned_vector<std::string>,
  and partitioned_vector<int> into partitioned_vector component library
- fixing all tests to use the pre-compiled implementations
  • Loading branch information
hkaiser committed Aug 3, 2017
1 parent 73bcb71 commit 307c280
Show file tree
Hide file tree
Showing 44 changed files with 3,985 additions and 3,245 deletions.
188 changes: 86 additions & 102 deletions hpx/components/containers/coarray/coarray.hpp
Expand Up @@ -25,15 +25,19 @@
///////////////////////////////////////////////////////////////////////////////
/// \cond NOINTERNAL

#define HPX_REGISTER_COARRAY_DECLARATION(...) \
HPX_REGISTER_PARTITIONED_VECTOR_DECLARATION(__VA_ARGS__)
#define HPX_REGISTER_COARRAY(...) HPX_REGISTER_PARTITIONED_VECTOR(__VA_ARGS__)

namespace hpx
{
namespace detail{

namespace detail
{
struct auto_subscript
{
constexpr auto_subscript(){}
constexpr auto_subscript()
{
}

// Defined to pass the coarray_sizes constructor
operator std::size_t()
Expand All @@ -42,50 +46,48 @@ namespace hpx
}
};

template<typename C>
template <typename C>
struct cast_if_autosubscript
{
using type = C;
};

template<>
template <>
struct cast_if_autosubscript<detail::auto_subscript>
{
using type = int;
};

template<std::size_t N>
template <std::size_t N>
struct coarray_sizes
{
using iterator =
typename std::array<std::size_t,N>::iterator;
using iterator = typename std::array<std::size_t, N>::iterator;

using const_iterator =
typename std::array<std::size_t,N>::const_iterator;
typename std::array<std::size_t, N>::const_iterator;

template<typename ... I>
template <typename... I>
coarray_sizes(I... i)
: sizes_({{i...}})
: sizes_({{i...}})
{
using last_element =
typename util::detail::at_index<sizeof...(I)-1, I...>::type;
typename util::detail::at_index<sizeof...(I) - 1, I...>::type;
using condition =
typename std::is_same<last_element,detail::auto_subscript>;
typename std::is_same<last_element, detail::auto_subscript>;

static_assert(condition::value,
"hpx::coarray() needs the last size to be " \
"equal to hpx::_");
"hpx::coarray() needs the last size to be equal to hpx::_");

static_assert(N == sizeof...(I),
"hpx::coarray() needs the number of sizes to be " \
"hpx::coarray() needs the number of sizes to be "
"equal to its dimension");

static_assert( util::detail::all_of<
typename std::is_integral<
typename detail::cast_if_autosubscript<I>::type
>::type ... >::value,
"One or more elements in sizes given to hpx::coarray() "\
"is not integral");
static_assert(
util::detail::all_of<typename std::is_integral<
typename detail::cast_if_autosubscript<I>::type>::
type...>::value,
"One or more elements in sizes given to hpx::coarray() "
"is not integral");
}

iterator begin()
Expand All @@ -109,150 +111,132 @@ namespace hpx
}

private:
std::array<std::size_t,N> sizes_;
std::array<std::size_t, N> sizes_;
};

}

// Used for "automatic" coarray subscript and "automatic" coarray size
namespace container{ namespace placeholders{
constexpr hpx::detail::auto_subscript _;
namespace container { namespace placeholders
{
constexpr hpx::detail::auto_subscript _;
}}

template<typename T, std::size_t N, typename Data = std::vector<T>>
struct coarray
: public partitioned_vector_view<T,N,Data>
template <typename T, std::size_t N, typename Data = std::vector<T>>
struct coarray : public partitioned_vector_view<T, N, Data>
{
private:
using base_type = partitioned_vector_view<T,N,Data>;
using indices =
typename hpx::util::detail::make_index_pack<N>::type;
using base_type = partitioned_vector_view<T, N, Data>;
using indices = typename hpx::util::detail::make_index_pack<N>::type;

std::vector<hpx::naming::id_type>
get_unrolled_localities(
std::vector< hpx::naming::id_type > const & in,
std::vector<hpx::naming::id_type> get_unrolled_localities(
std::vector<hpx::naming::id_type> const& in,
std::size_t num_segments,
std::size_t unroll)
{
using iterator = typename
std::vector<hpx::naming::id_type>::iterator;
using iterator = typename std::vector<hpx::naming::id_type>::iterator;

using const_iterator = typename
std::vector<hpx::naming::id_type>::const_iterator;
using const_iterator =
typename std::vector<hpx::naming::id_type>::const_iterator;

std::vector<hpx::naming::id_type> out(num_segments);

iterator o_end = out.end();
const_iterator i_begin = in.cbegin();
const_iterator i_end = in.cend();
const_iterator i_end = in.cend();
const_iterator i = i_begin;

for(iterator o = out.begin(); o<o_end; o+=unroll)
for (iterator o = out.begin(); o < o_end; o += unroll)
{
std::fill(o, (std::min)(o + unroll, o_end), *i);
i = (++i != i_end) ? i : i_begin;
}
std::fill(o, (std::min)(o + unroll, o_end), *i);
i = (++i != i_end) ? i : i_begin;
}

return out;
}
return out;
}

template<typename Iterator, std::size_t ... I>
base_type update_view(
hpx::detail::coarray_sizes<N> const & cosizes,
template <typename Iterator, std::size_t... I>
base_type update_view(hpx::detail::coarray_sizes<N> const& cosizes,
std::size_t num_images,
hpx::util::detail::pack_c<std::size_t, I...>,
hpx::lcos::spmd_block const & block,
Iterator && begin,
Iterator && last) const
hpx::lcos::spmd_block const& block,
Iterator&& begin,
Iterator&& last) const
{
return base_type(
block,
return base_type(block,
std::forward<Iterator>(begin),
std::forward<Iterator>(last),
{(cosizes.begin()[I]!= std::size_t(-1)
? cosizes.begin()[I] : num_images)...});
{(cosizes.begin()[I] != std::size_t(-1) ? cosizes.begin()[I] :
num_images)...});
}

public:
explicit coarray(
hpx::lcos::spmd_block const & block,
explicit coarray(hpx::lcos::spmd_block const& block,
std::string name,
hpx::detail::coarray_sizes<N> cosizes,
hpx::detail::coarray_sizes<N>
cosizes,
std::size_t segment_size)
: base_type(block), vector_(), this_image_(block.this_image())
: base_type(block)
, vector_()
, this_image_(block.this_image())
{
// Used to access base members
base_type & view (*this);
// Used to access base members
base_type& view(*this);

std::size_t num_images = block.get_num_images();

if (block.this_image() == 0)
{
std::size_t num_segments = N > 0 ? 1 : 0;

for(std::size_t const & i : cosizes)
for (std::size_t const& i : cosizes)
{
num_segments *= (i != std::size_t(-1) ? i : num_images);
}

std::vector< hpx::id_type > localities
= hpx::find_all_localities();
std::vector<hpx::id_type> localities = hpx::find_all_localities();

vector_ = hpx::partitioned_vector<T,Data>(
segment_size*num_segments, T(0),
hpx::container_layout(
num_segments,
get_unrolled_localities(
localities, num_segments,
num_segments/localities.size())
)
);
vector_ = hpx::partitioned_vector<T, Data>(
segment_size * num_segments, T(0),
hpx::container_layout(num_segments,
get_unrolled_localities(localities, num_segments,
num_segments / localities.size())));

vector_.register_as(hpx::launch::sync, name + "_hpx_coarray");
}
else
vector_.connect_to(hpx::launch::sync, name + "_hpx_coarray");

view = update_view(cosizes,
num_images, indices(), block, vector_.begin(), vector_.end());
view = update_view(cosizes, num_images, indices(), block,
vector_.begin(), vector_.end());
}

template<typename... I,
typename = std::enable_if_t<
! std::is_same<
typename util::detail::at_index<sizeof...(I)-1,I...>::type,
detail::auto_subscript>::value
>
>
hpx::detail::view_element<T,Data>
operator()(I... index) const
template <typename... I,
typename = std::enable_if_t<!std::is_same<
typename util::detail::at_index<sizeof...(I) - 1, I...>::type,
detail::auto_subscript>::value>>
hpx::detail::view_element<T, Data> operator()(I... index) const
{
return base_type::operator()(
(std::is_same<I,detail::auto_subscript>::value
? this_image_
: index)...);
(std::is_same<I, detail::auto_subscript>::value ? this_image_ :
index)...);
}

template<typename... I,
typename = std::enable_if_t<
std::is_same<
typename util::detail::at_index<sizeof...(I)-1,I...>::type,
detail::auto_subscript>::value
>
>
Data &
operator()(I... index)
template <typename... I,
typename = std::enable_if_t<std::is_same<
typename util::detail::at_index<sizeof...(I) - 1, I...>::type,
detail::auto_subscript>::value>>
Data& operator()(I... index)
{
return base_type::operator()(
(std::is_same<I,detail::auto_subscript>::value
? this_image_
: index)...).data();
(std::is_same<I, detail::auto_subscript>::value ? this_image_ :
index)...)
.data();
}

private:
hpx::partitioned_vector<T,Data> vector_;
hpx::partitioned_vector<T, Data> vector_;
std::size_t this_image_;
};
}

#endif // COARRAY_HPP
#endif // COARRAY_HPP
Expand Up @@ -8,7 +8,7 @@
#ifndef HPX_PARTITIONED_VECTOR_DETAIL_VIEW_ELEMENT_HPP
#define HPX_PARTITIONED_VECTOR_DETAIL_VIEW_ELEMENT_HPP

#include <hpx/components/containers/partitioned_vector/partitioned_vector_component.hpp>
#include <hpx/components/containers/partitioned_vector/partitioned_vector_component_decl.hpp>
#include <hpx/components/containers/partitioned_vector/partitioned_vector_segmented_iterator.hpp>
#include <hpx/lcos/spmd_block.hpp>
#include <hpx/runtime/get_locality_id.hpp>
Expand Down
@@ -0,0 +1,19 @@
// Copyright (c) 2017 Hartmut Kaiser
//
// 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)

#if !defined(HPX_PARTITIONED_VECTOR_EXPORT_DEFINITIONS_AUG_02_2017_0658PM)
#define HPX_PARTITIONED_VECTOR_EXPORT_DEFINITIONS_AUG_02_2017_0658PM

#include <hpx/config/export_definitions.hpp>

#if defined(HPX_PARTITIONED_VECTOR_MODULE_EXPORTS)
# define HPX_PARTITIONED_VECTOR_EXPORT HPX_SYMBOL_EXPORT
#else
# define HPX_PARTITIONED_VECTOR_EXPORT HPX_SYMBOL_IMPORT
#endif

#endif


0 comments on commit 307c280

Please sign in to comment.