Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into fixing_doc_index
- Loading branch information
Showing
24 changed files
with
680 additions
and
171 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
// Copyright (c) 2017 Antoine Tran Tan | ||
// | ||
// 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_LCOS_LOCAL_SPMD_BLOCK_HPP) | ||
#define HPX_LCOS_LOCAL_SPMD_BLOCK_HPP | ||
|
||
#include <hpx/lcos/future.hpp> | ||
#include <hpx/lcos/local/barrier.hpp> | ||
#include <hpx/parallel/execution_policy.hpp> | ||
#include <hpx/traits/is_execution_policy.hpp> | ||
#include <hpx/util/first_argument.hpp> | ||
|
||
#include <boost/range/irange.hpp> | ||
|
||
#include <cstddef> | ||
#include <functional> | ||
#include <memory> | ||
#include <type_traits> | ||
#include <utility> | ||
#include <vector> | ||
|
||
namespace hpx { namespace lcos { namespace local | ||
{ | ||
/// The class spmd_block defines an interface for launching | ||
/// multiple images while giving handles to each image to interact with | ||
/// the remaining images. The \a define_spmd_block function templates create | ||
/// multiple images of a user-defined function (or lambda) and launches them | ||
/// in a possibly separate thread. A temporary spmd block object is created | ||
/// and diffused to each image. The constraint for the function (or lambda) | ||
/// given to the define_spmd_block function is to accept a spmd_block as | ||
/// first parameter. | ||
struct spmd_block | ||
{ | ||
explicit spmd_block(std::size_t num_images, std::size_t image_id, | ||
hpx::lcos::local::barrier & barrier) | ||
: num_images_(num_images), image_id_(image_id), barrier_(barrier) | ||
{} | ||
|
||
// Note: spmd_block class is movable/move-assignable | ||
// but not copyable/copy-assignable | ||
|
||
spmd_block(spmd_block &&) = default; | ||
spmd_block(spmd_block const &) = delete; | ||
|
||
spmd_block & operator=(spmd_block &&) = default; | ||
spmd_block & operator=(spmd_block const &) = delete; | ||
|
||
std::size_t get_num_images() const | ||
{ | ||
return num_images_; | ||
} | ||
|
||
std::size_t this_image() const | ||
{ | ||
return image_id_; | ||
} | ||
|
||
void sync_all() const | ||
{ | ||
barrier_.get().wait(); | ||
} | ||
|
||
private: | ||
std::size_t num_images_; | ||
std::size_t image_id_; | ||
mutable std::reference_wrapper<hpx::lcos::local::barrier> barrier_; | ||
}; | ||
|
||
namespace detail | ||
{ | ||
template <typename F> | ||
struct spmd_block_helper | ||
{ | ||
mutable std::shared_ptr<hpx::lcos::local::barrier> barrier_; | ||
typename std::decay<F>::type f_; | ||
std::size_t num_images_; | ||
|
||
template <typename ... Ts> | ||
void operator()(std::size_t image_id, Ts && ... ts) const | ||
{ | ||
spmd_block block(num_images_, image_id, *barrier_); | ||
hpx::util::invoke( | ||
f_, std::move(block), std::forward<Ts>(ts)...); | ||
} | ||
}; | ||
} | ||
|
||
// Asynchronous version | ||
template <typename ExPolicy, typename F, typename ... Args, | ||
typename = typename std::enable_if< | ||
hpx::parallel::v1::is_async_execution_policy<ExPolicy>::value>::type | ||
> | ||
std::vector<hpx::future<void>> | ||
define_spmd_block(ExPolicy && policy, | ||
std::size_t num_images, F && f, Args && ... args) | ||
{ | ||
static_assert( | ||
parallel::execution::is_execution_policy<ExPolicy>::value, | ||
"parallel::execution::is_execution_policy<ExPolicy>::value"); | ||
|
||
using ftype = typename std::decay<F>::type; | ||
|
||
using first_type = | ||
typename hpx::util::first_argument<ftype>::type; | ||
|
||
using executor_type = | ||
typename hpx::util::decay<ExPolicy>::type::executor_type; | ||
|
||
static_assert(std::is_same<spmd_block, first_type>::value, | ||
"define_spmd_block() needs a function or lambda that " \ | ||
"has at least a local spmd_block as 1st argument"); | ||
|
||
std::shared_ptr<hpx::lcos::local::barrier> barrier | ||
= std::make_shared<hpx::lcos::local::barrier>(num_images); | ||
|
||
return | ||
hpx::parallel::executor_traits< | ||
typename std::decay<executor_type>::type | ||
>::bulk_async_execute( | ||
policy.executor(), | ||
detail::spmd_block_helper<F>{ | ||
barrier, std::forward<F>(f), num_images | ||
}, | ||
boost::irange(std::size_t(0), num_images), | ||
std::forward<Args>(args)...); | ||
} | ||
|
||
// Synchronous version | ||
template <typename ExPolicy, typename F, typename ... Args, | ||
typename = typename std::enable_if< | ||
!hpx::parallel::v1::is_async_execution_policy<ExPolicy>::value>::type | ||
> | ||
void | ||
define_spmd_block(ExPolicy && policy, | ||
std::size_t num_images, F && f, Args && ... args) | ||
{ | ||
static_assert( | ||
parallel::execution::is_execution_policy<ExPolicy>::value, | ||
"parallel::execution::is_execution_policy<ExPolicy>::value"); | ||
|
||
using ftype = typename std::decay<F>::type; | ||
|
||
using first_type = | ||
typename hpx::util::first_argument<ftype>::type; | ||
|
||
using executor_type = | ||
typename hpx::util::decay<ExPolicy>::type::executor_type; | ||
|
||
static_assert(std::is_same<spmd_block, first_type>::value, | ||
"define_spmd_block() needs a lambda that " \ | ||
"has at least a spmd_block as 1st argument"); | ||
|
||
std::shared_ptr<hpx::lcos::local::barrier> barrier | ||
= std::make_shared<hpx::lcos::local::barrier>(num_images); | ||
|
||
hpx::parallel::executor_traits< | ||
typename std::decay<executor_type>::type | ||
>::bulk_execute( | ||
policy.executor(), | ||
detail::spmd_block_helper<F>{ | ||
barrier, std::forward<F>(f), num_images | ||
}, | ||
boost::irange(std::size_t(0), num_images), | ||
std::forward<Args>(args)...); | ||
} | ||
|
||
template <typename F, typename ... Args> | ||
void define_spmd_block(std::size_t num_images, F && f, Args && ... args) | ||
{ | ||
define_spmd_block(parallel::execution::par, | ||
num_images, std::forward<F>(f), std::forward<Args>(args)...); | ||
} | ||
}}} | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.