1 #ifndef COARRAY_H_INCLUDED 2 #define COARRAY_H_INCLUDED 6 #include <dash/Types.h> 7 #include <dash/GlobRef.h> 8 #include <dash/iterator/GlobIter.h> 10 #include <dash/pattern/BlockPattern.h> 11 #include <dash/Dimensional.h> 12 #include <dash/TeamSpec.h> 13 #include <dash/util/ArrayExpr.h> 15 #include <dash/Array.h> 16 #include <dash/Matrix.h> 18 #include <dash/Dimensional.h> 20 #include <dash/atomic/Type_traits.h> 49 template<
typename Container>
50 inline void sync_images(
const Container & image_ids);
59 constexpr std::array<ValueT, Rank>
60 type_extents_as_array_impl(
62 return { (
static_cast<ValueT
>(std::extent<ArrayT,Is>::value) )... };
69 constexpr std::array<ValueT, Rank>
70 type_extents_as_array() {
71 return type_extents_as_array_impl<ArrayT,ValueT,Rank>(
77 constexpr
bool type_is_complete() {
78 return (std::get<0>(coarray::detail::type_extents_as_array<T,
79 int, std::rank<T>::value>()) > 0);
83 typename element_type,
84 typename pattern_type,
86 typename LocalMemSpaceT>
87 struct local_ref_type {
88 using type = LocalMatrixRef<element_type,
91 pattern_type, LocalMemSpaceT>;
95 typename element_type,
96 typename pattern_type,
97 typename LocalMemSpaceT>
98 struct local_ref_type<
dash::Atomic<element_type>, pattern_type, 1, LocalMemSpaceT> {
99 using type = GlobRef<element_type>;
103 typename element_type,
104 typename pattern_type,
105 typename LocalMemSpaceT>
106 struct local_ref_type<element_type, pattern_type, 1, LocalMemSpaceT> {
107 using type = element_type &;
110 template<
typename element_type>
114 using type = GlobRef<element_type>;
120 template<
typename element_type>
121 struct ref_type<
dash::Atomic<element_type>> {
122 using type = GlobRef<dash::Atomic<element_type>>;
125 template<
typename element_type>
126 struct const_ref_type {
127 using type = GlobAsyncRef<const element_type>;
133 template<
typename element_type>
134 struct const_ref_type<
dash::Atomic<element_type>> {
135 using type = GlobRef<dash::Atomic<const element_type>>;
147 MemArrange Arrangement = ROW_MAJOR>
151 typename dash::remove_atomic<T>::type>::value+1,
182 MemArrange Arrangement = ROW_MAJOR,
193 using _element_type =
typename std::remove_all_extents<T>::type;
194 using _base_type =
typename dash::remove_atomic<_element_type>::type;
196 using _valuetype_rank = std::integral_constant<int,
197 std::rank<T>::value>;
198 using _rank = std::integral_constant<int,
199 _valuetype_rank::value+1>;
201 using _size_type =
typename std::make_unsigned<IndexType>::type;
207 template<
int _subrank = _valuetype_rank::value>
208 using _view_type =
typename _storage_type::template view_type<_subrank>;
209 using _local_ref_type =
typename coarray::detail::local_ref_type<
212 _valuetype_rank::value, LocalMemSpaceT>::type;
214 using _offset_type = std::array<IndexType, _rank::value>;
218 using value_type = _element_type;
221 using difference_type = IndexType;
222 using index_type = IndexType;
223 using size_type = _size_type;
226 using reverse_iterator =
typename _storage_type::reverse_iterator;
227 using const_reverse_iterator =
typename _storage_type::const_reverse_iterator;
230 using local_pointer = _element_type *;
231 using const_local_pointer =
const _element_type *;
232 template<
int subrank>
233 using view_type = _view_type<subrank>;
234 using local_type = _local_ref_type;
235 using pattern_type = _pattern_type;
238 constexpr
_sspec_type _make_size_spec() const noexcept {
240 std::array<size_type, 1> {
static_cast<size_type
>(
dash::size())},
241 coarray::detail::type_extents_as_array<T,
242 size_type, _valuetype_rank::value>()));
245 constexpr
_sspec_type _make_size_spec(
const size_type & first_dim)
const noexcept {
247 !coarray::detail::type_is_complete<T>(),
248 "Array type may not be fully specified");
251 std::array<size_type, 1> {
static_cast<size_type
>(
dash::size())},
252 dash::ce::replace_nth<0>(
254 coarray::detail::type_extents_as_array<T,
255 size_type, _valuetype_rank::value>())));
258 constexpr _offset_type _offsets_unit(
const team_unit_t & unit)
const noexcept {
259 return _storage.pattern().global(unit, std::array<index_type, _rank::value> {});
262 constexpr _offset_type _extents_unit(
const team_unit_t & unit)
const noexcept {
263 return _storage.pattern().local_extents(unit);
266 inline index_type _myid()
const {
267 return static_cast<index_type
>(_storage.team().myid());
273 return static_cast<dim_t>(_rank::value);
285 (std::is_array<_base_type>::value ==
false 286 || std::extent<_base_type, 0>::value != 0))
299 int __valuetype_rank = _valuetype_rank::value,
300 typename =
typename std::enable_if<(__valuetype_rank != 0)>::type>
303 allocate(first_dim, team);
320 explicit Coarray(std::vector<size_type> extents,
323 extents.insert(extents.begin(),
static_cast<size_type
>(
dash::size()));
325 const _pattern_type a_pattern(extents,
329 _storage.allocate(a_pattern);
335 int __valuetype_rank = _valuetype_rank::value,
336 typename =
typename std::enable_if<(__valuetype_rank == 0)>::type>
340 *(_storage.lbegin()) = value;
348 constexpr
const pattern_type & pattern()
const noexcept {
349 return _storage.pattern();
352 iterator
begin() noexcept {
353 return _storage.begin();
356 constexpr const_iterator
begin()
const noexcept {
357 return _storage.begin();
360 constexpr const_iterator cbegin()
const noexcept {
361 return _storage.begin();
364 iterator
end() noexcept {
365 return _storage.end();
368 constexpr const_iterator
end()
const noexcept {
369 return _storage.end();
372 constexpr const_iterator cend()
const noexcept {
373 return _storage.cend();
376 local_pointer lbegin() noexcept {
377 return _storage.lbegin();
380 constexpr const_local_pointer lbegin()
const noexcept {
381 return _storage.lbegin();
384 local_pointer lend() noexcept {
385 return _storage.lend();
388 constexpr const_local_pointer lend()
const noexcept {
389 return _storage.lend();
392 constexpr size_type
size()
const noexcept {
393 return _storage.size();
396 constexpr
bool empty()
const noexcept {
397 return _storage.size() == 0;
401 std::swap(this->_storage, other._storage);
405 constexpr size_type local_size()
const noexcept {
406 return _storage.local_size();
409 constexpr
bool is_local(index_type gi)
const noexcept {
410 return _storage.is_local(gi);
417 if(_storage.size() == 0){
418 _storage.allocate(_pattern_type(_make_size_spec(),
433 if((_storage.size() == 0) && (n > 0)){
434 _storage.allocate(_pattern_type(_make_size_spec(n),
447 _storage.deallocate();
450 inline Team & team() {
451 return _storage.team();
470 template<
typename Container>
480 inline void flush_local(){
481 _storage.flush_local();
490 template<
int __valuetype_rank = _valuetype_rank::value>
492 return this->operator ()(static_cast<index_type>(unit));
497 template<
int __valuetype_rank = _valuetype_rank::value>
498 typename std::enable_if<(__valuetype_rank != 0), view_type<__valuetype_rank>>::type
500 return _storage[unit];
506 template<
int __valuetype_rank = _valuetype_rank::value>
507 typename std::enable_if<(__valuetype_rank == 0), reference>::type
509 return _storage.at(unit);
516 template<
int __valuetype_rank = _valuetype_rank::value>
517 typename std::enable_if<(
518 __valuetype_rank == 1 &&
520 const local_type>::type
521 inline operator[](
const index_type & idx)
const 523 return const_cast<const local_type
>(
524 *(_storage.lbegin()+idx));
531 template<
int __valuetype_rank = _valuetype_rank::value>
532 typename std::enable_if<(
533 __valuetype_rank == 1 &&
535 inline operator[](
const index_type & idx) {
536 return *(_storage.lbegin()+idx);
546 template<
int __valuetype_rank = _valuetype_rank::value>
547 typename std::enable_if<(
548 __valuetype_rank > 1 &&
550 inline operator[](
const index_type & idx) {
565 return _storage.local[0][idx];
571 template<
int __valuetype_rank = _valuetype_rank::value>
572 typename std::enable_if<(
573 __valuetype_rank > 0 &&
575 inline operator[](
const index_type & idx) {
577 return operator()(_myid())[idx];
587 template<
int __valuetype_rank = _valuetype_rank::value>
588 typename std::enable_if<(
589 __valuetype_rank == 0 &&
591 inline operator=(
const value_type & value){
592 return *(_storage.lbegin()) = value;
599 template<
int __valuetype_rank = _valuetype_rank::value>
600 typename std::enable_if<(
601 __valuetype_rank == 0 &&
603 inline operator=(
const value_type & value){
604 return operator()(_myid()) = value;
617 int __valuetype_rank = _valuetype_rank::value,
618 typename =
typename std::enable_if<(
619 __valuetype_rank == 0 &&
621 inline operator value_type()
const {
622 return *(_storage.lbegin());
630 int __valuetype_rank = _valuetype_rank::value,
631 typename =
typename std::enable_if<(
632 __valuetype_rank == 0 &&
635 return _storage[_myid()];
642 int __valuetype_rank = _valuetype_rank::value,
643 typename =
typename std::enable_if<(__valuetype_rank == 0)>::type>
644 explicit inline operator reference() {
645 return _storage[
myid()];
654 int __valuetype_rank = _valuetype_rank::value,
655 typename =
typename std::enable_if<(__valuetype_rank == 0)>::type>
657 auto *s_begin =
reinterpret_cast<char *
>(_storage.lbegin());
659 return *(
reinterpret_cast<MEMTYPE*
>(s_begin));
673 int __valuetype_rank = _valuetype_rank::value,
674 typename =
typename std::enable_if<(__valuetype_rank == 0)>::type>
675 inline MEMTYPE &
member(
const MEMTYPE P::*mem) {
676 auto offs = (size_t) & (reinterpret_cast<P *>(0)->*mem);
677 return member<MEMTYPE>(offs);
689 int __valuetype_rank = _valuetype_rank::value,
690 typename =
typename std::enable_if<(
691 __valuetype_rank == 0 &&
693 inline value_type &
operator +=(
const value_type & value) {
694 return *(_storage.lbegin()) += value;
698 int __valuetype_rank = _valuetype_rank::value,
699 typename =
typename std::enable_if<(
700 __valuetype_rank == 0 &&
703 return operator()(_myid()) += value;
711 int __valuetype_rank = _valuetype_rank::value,
712 typename =
typename std::enable_if<(
713 __valuetype_rank == 0 &&
715 inline value_type &
operator -=(
const value_type & value) {
716 return *(_storage.lbegin()) -= value;
720 int __valuetype_rank = _valuetype_rank::value,
721 typename =
typename std::enable_if<(
722 __valuetype_rank == 0 &&
725 return operator()(_myid()) -= value;
733 int __valuetype_rank = _valuetype_rank::value,
734 typename =
typename std::enable_if<(
735 __valuetype_rank == 0 &&
737 inline value_type &
operator *=(
const value_type & value) {
738 return *(_storage.lbegin()) *= value;
742 int __valuetype_rank = _valuetype_rank::value,
743 typename =
typename std::enable_if<(
744 __valuetype_rank == 0 &&
746 inline reference
operator *=(
const value_type & value) {
747 return operator()(_myid()) *= value;
754 int __valuetype_rank = _valuetype_rank::value,
755 typename =
typename std::enable_if<(
756 __valuetype_rank == 0 &&
758 inline value_type &
operator /=(
const value_type & value) {
759 return *(_storage.lbegin()) /= value;
763 int __valuetype_rank = _valuetype_rank::value,
764 typename =
typename std::enable_if<(
765 __valuetype_rank == 0 &&
767 inline reference
operator /=(
const value_type & value) {
768 return operator()(_myid()) /= value;
781 int __valuetype_rank = _valuetype_rank::value,
782 typename =
typename std::enable_if<(
783 __valuetype_rank == 0 &&
785 inline value_type
operator +(
const value_type & value)
const {
786 return *(_storage.lbegin()) + value;
793 int __valuetype_rank = _valuetype_rank::value,
794 typename =
typename std::enable_if<(
795 __valuetype_rank == 0 &&
797 inline value_type
operator -(
const value_type & value)
const {
798 return *(_storage.lbegin()) - value;
805 int __valuetype_rank = _valuetype_rank::value,
806 typename =
typename std::enable_if<(
807 __valuetype_rank == 0 &&
809 inline value_type
operator *(
const value_type & value)
const {
810 return *(_storage.lbegin()) * value;
817 int __valuetype_rank = _valuetype_rank::value,
818 typename =
typename std::enable_if<(
819 __valuetype_rank == 0 &&
821 inline value_type
operator /(
const value_type & value)
const {
822 return *(_storage.lbegin()) / value;
829 int __valuetype_rank = _valuetype_rank::value,
830 typename =
typename std::enable_if<(
831 __valuetype_rank == 0 &&
833 inline value_type &
operator ++() {
834 return ++(*(_storage.lbegin()));
838 int __valuetype_rank = _valuetype_rank::value,
839 typename =
typename std::enable_if<(
840 __valuetype_rank == 0 &&
843 return ++(operator()(_myid()));
850 int __valuetype_rank = _valuetype_rank::value,
851 typename =
typename std::enable_if<(
852 __valuetype_rank == 0 &&
854 inline value_type
operator ++(
int) {
855 return (*(_storage.lbegin()))++;
862 int __valuetype_rank = _valuetype_rank::value,
863 typename =
typename std::enable_if<(
864 __valuetype_rank == 0 &&
866 inline value_type &
operator --() {
867 return --(*(_storage.lbegin()));
871 int __valuetype_rank = _valuetype_rank::value,
872 typename =
typename std::enable_if<(
873 __valuetype_rank == 0 &&
876 return --(operator()(_myid()));
883 int __valuetype_rank = _valuetype_rank::value,
884 typename =
typename std::enable_if<(
885 __valuetype_rank == 0 &&
887 inline value_type
operator --(
int) {
888 return (*(_storage.lbegin()))--;
905 return lhs +
static_cast<Lhs
>(rhs);
912 return lhs -
static_cast<Lhs
>(rhs);
919 return lhs *
static_cast<Lhs
>(rhs);
926 return lhs /
static_cast<Lhs
>(rhs);
929 #include <dash/coarray/Utils.h> 930 #include <dash/Coevent.h> constexpr dim_t rank(const DimensionalType &d)
void sync_images(const Container &image_ids)
Blocks until all selected units reach this statement.
global_unit_t myid()
Shortcut to query the global unit ID of the calling unit.
type traits for dash::Atomic
Defines how a list of global indices is mapped to single units within a Team.
size_t size()
Return the number of units in the global team.
constexpr auto end(RangeType &&range) -> decltype(std::forward< RangeType >(range).end())
Coarray(const size_type &first_dim, Team &team=Team::All())
Constructor for array types with one unspecified dimension:
This class is a simple memory pool which holds allocates elements of size ValueType.
MEMTYPE & member(const MEMTYPE P::*mem)
Get the member via pointer to member.
Specifies cartesian extents in a specific number of dimensions.
Generates a compile-sequence integer (size_t) sequence in ascending order.
constexpr auto begin(RangeType &&range) -> decltype(std::forward< RangeType >(range).begin())
int dim_t
Scalar type for a dimension value, with 0 indicating the first dimension.
view_type< __valuetype_rank > operator()(const team_unit_t &unit)
Operator to select remote unit.
MEMTYPE & member(size_t offs)
Get a reference to a member of a certain type at the specified offset.
DASH_CONSTEXPR auto operator-(const GlobIter< ElementType, Pattern, GlobMemType, Pointer, Reference > &lhs, const GlobIter< ElementType, Pattern, GlobMemType, Pointer, Reference > &rhs) DASH_NOEXCEPT
bool is_initialized()
Check whether DASH has been initialized already.
void allocate(const size_type &n, Team &team=dash::Team::All())
allocate an array which was initialized before dash has been initialized
std::enable_if<(__valuetype_rank !=0), view_type< __valuetype_rank > >::type operator()(const index_type &unit)
Operator to select remote unit for array types.
helper to create a coarray pattern for coarrays where the local size of each unit is equal (symmetric...
internal::default_signed_index default_index_t
Signed integer type used as default for index values.
A Team instance specifies a subset of all available units.
void allocate(Team &team=dash::Team::All())
allocate an array which was initialized before dash has been initialized
void deallocate()
free the memory allocated by this coarray.
constexpr dim_t ndim(const DimensionalType &d)
Specifies the arrangement of team units in a specified number of dimensions.
std::enable_if<(__valuetype_rank==0), reference >::type operator()(const index_type &unit)
Operator to select remote unit for scalar types.
struct dash::unit_id< dash::local_unit, dart_team_unit_t > team_unit_t
Unit ID to use for team-local IDs.
Coarray(Team &team=Team::All())
Constructor for scalar types and fully specified array types:
void sync_all()
Blocks until all team members of this container have reached the statement and flushes the memory...
void sync_images(const Container &image_ids)
Blocks until all selected team members of this container have reached the statement and flushes the m...
_base_type value_base_type
Same as value_type but without atomic wrapper.
void barrier()
A global barrier involving all units.
Global value reference for asynchronous / non-blocking operations.
static Team & All()
The invariant Team instance containing all available units.
void swap(dash::GlobRef< T > &&a, dash::GlobRef< T > &&b)
specialization for unqualified calls to swap
DistributionSpec describes distribution patterns of all dimensions,.