diff --git a/CMakeExt/CompilerFlags.cmake b/CMakeExt/CompilerFlags.cmake index 325a4ed11..bdd310c7c 100644 --- a/CMakeExt/CompilerFlags.cmake +++ b/CMakeExt/CompilerFlags.cmake @@ -234,18 +234,18 @@ set(CMAKE_CXX_FLAGS_DEBUG set(CMAKE_C_FLAGS_RELEASE - "${CMAKE_C_FLAGS_RELEASE} ${CC_STD_FLAG} ${CC_OMP_FLAG}") + "${CMAKE_C_FLAGS_RELEASE} ${CC_STD_FLAG} ${CC_OMP_FLAG}") set(CMAKE_C_FLAGS_RELEASE - "${CMAKE_C_FLAGS_RELEASE} ${CXX_LTO_FLAG} ${CC_REPORT_FLAG}") + "${CMAKE_C_FLAGS_RELEASE} ${CXX_LTO_FLAG} ${CC_REPORT_FLAG}") set(CMAKE_C_FLAGS_RELEASE - "${CMAKE_C_FLAGS_RELEASE} ${CC_WARN_FLAG} -Ofast -DDASH_RELEASE") + "${CMAKE_C_FLAGS_RELEASE} ${CC_WARN_FLAG} -Ofast -DDASH_RELEASE") set(CMAKE_CXX_FLAGS_RELEASE - "${CMAKE_CXX_FLAGS_RELEASE} ${CXX_STD_FLAG} ${CXX_OMP_FLAG}") + "${CMAKE_CXX_FLAGS_RELEASE} ${CXX_STD_FLAG} ${CXX_OMP_FLAG}") set(CMAKE_CXX_FLAGS_RELEASE - "${CMAKE_CXX_FLAGS_RELEASE} ${CXX_LTO_FLAG} ${CC_REPORT_FLAG}") + "${CMAKE_CXX_FLAGS_RELEASE} ${CXX_LTO_FLAG} ${CC_REPORT_FLAG}") set(CMAKE_CXX_FLAGS_RELEASE - "${CMAKE_CXX_FLAGS_RELEASE} ${CXX_WARN_FLAG} -Ofast -DDASH_RELEASE") + "${CMAKE_CXX_FLAGS_RELEASE} ${CXX_WARN_FLAG} -Ofast -DDASH_RELEASE") if (BUILD_COVERAGE_TESTS) # Profiling is only supported for Debug builds: diff --git a/dash/CMakeLists.txt b/dash/CMakeLists.txt index 05b9b669f..01539446f 100644 --- a/dash/CMakeLists.txt +++ b/dash/CMakeLists.txt @@ -305,13 +305,13 @@ foreach (dart_variant ${DART_IMPLEMENTATIONS_LIST}) DeployLibrary(${DASH_LIBRARY}) # cmake packaging -if(${CMAKE_VERSION} VERSION_GREATER 3.0.0 ) + if(${CMAKE_VERSION} VERSION_GREATER 3.0.0 ) include(CMakePackageConfigHelpers) target_include_directories("${DASH_LIBRARY}" PUBLIC $ PUBLIC ${ADDITIONAL_INCLUDES}) -endif() + endif() string(TOUPPER ${dart_variant} DART_VARIANT) diff --git a/dash/examples/bench.05.pattern/MockPattern.h b/dash/examples/bench.05.pattern/MockPattern.h deleted file mode 100644 index a4904b1f9..000000000 --- a/dash/examples/bench.05.pattern/MockPattern.h +++ /dev/null @@ -1,1171 +0,0 @@ -#ifndef DASH__MOCK_PATTERN_H_ -#define DASH__MOCK_PATTERN_H_ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -namespace dash { - -/** - * Irregular Pattern for Compressed Sparse Row Storage. - * - * \concept{DashPatternConcept} - */ -template< - dim_t NumDimensions, - MemArrange Arrangement = dash::ROW_MAJOR, - typename IndexType = dash::default_index_t -> -class MockPattern; - -/** - * Irregular Pattern for Compressed Sparse Row Storage. - * Specialization for 1-dimensional data. - * - * \concept{DashPatternConcept} - */ -template< - MemArrange Arrangement, - typename IndexType -> -class MockPattern<1, Arrangement, IndexType> -{ -private: - static const dim_t NumDimensions = 1; - -public: - static constexpr char const * PatternName = "MockPattern<1>"; - -public: - /// Satisfiable properties in pattern property category Partitioning: - typedef pattern_partitioning_properties< - // Minimal number of blocks in every dimension, i.e. one block - // per unit. - pattern_partitioning_tag::minimal, - // Block extents are constant for every dimension. - pattern_partitioning_tag::rectangular, - // Varying block sizes. - pattern_partitioning_tag::unbalanced - > partitioning_properties; - /// Satisfiable properties in pattern property category Mapping: - typedef pattern_mapping_properties< - // Number of blocks assigned to a unit may differ. - pattern_mapping_tag::balanced - > mapping_properties; - /// Satisfiable properties in pattern property category Layout: - typedef pattern_layout_properties< - // Elements are contiguous in local memory within single block. - pattern_layout_tag::blocked, - // Local element order corresponds to a logical linearization - // within single blocks. - pattern_layout_tag::linear - > layout_properties; - -private: - /// Derive size type from given signed index / ptrdiff type - typedef typename std::make_unsigned::type - SizeType; - /// Fully specified type definition of self - typedef MockPattern - self_t; - typedef CartesianIndexSpace - MemoryLayout_t; - typedef CartesianIndexSpace - LocalMemoryLayout_t; - typedef DistributionSpec - DistributionSpec_t; - typedef TeamSpec - TeamSpec_t; - typedef SizeSpec - SizeSpec_t; - typedef ViewSpec - ViewSpec_t; - typedef internal::PatternArguments - PatternArguments_t; - -public: - typedef IndexType index_type; - typedef SizeType size_type; - typedef ViewSpec_t viewspec_type; - typedef struct { - dash::team_unit_t unit; - IndexType index; - } local_index_t; - typedef struct { - dash::team_unit_t unit; - std::array coords; - } local_coords_t; - -private: - PatternArguments_t _arguments; - /// Extent of the linear pattern. - SizeType _size; - /// Number of local elements for every unit in the active team. - std::vector _local_sizes; - /// Block offsets for every unit. Prefix sum of local sizes. - std::vector _block_offsets; - /// Global memory layout of the pattern. - MemoryLayout_t _memory_layout; - /// Distribution type (BLOCKED, CYCLIC, BLOCKCYCLIC or NONE) of - /// all dimensions. Defaults to BLOCKED. - DistributionSpec_t _distspec; - /// Team containing the units to which the patterns element are mapped - dash::Team * _team = nullptr; - /// Cartesian arrangement of units within the team - TeamSpec_t _teamspec; - /// Total amount of units to which this pattern's elements are mapped - SizeType _nunits = 0; - /// Maximum extents of a block in this pattern - SizeType _blocksize = 0; - /// Number of blocks in all dimensions - SizeType _nblocks = 0; - /// Actual number of local elements of the active unit. - SizeType _local_size; - /// Local memory layout of the pattern. - LocalMemoryLayout_t _local_memory_layout; - /// Maximum number of elements assigned to a single unit - SizeType _local_capacity; - /// Corresponding global index to first local index of the active unit - IndexType _lbegin; - /// Corresponding global index past last local index of the active unit - IndexType _lend; - - /// Mock position, incremented in every call of local() - mutable IndexType _mock_idx = 0; - -public: - /** - * Constructor, initializes a pattern from an argument list consisting - * of the pattern size (extent, number of elements) followed by an optional - * distribution type. - * - */ - template - MockPattern( - /// Number of local elements for every unit in the active team. - const std::vector & local_sizes, - /// Argument list consisting of the pattern size (extent, number of - /// elements) in every dimension followed by optional distribution - /// types. - SizeType arg, - /// Argument list consisting of the pattern size (extent, number of - /// elements) in every dimension followed by optional distribution - /// types. - Args && ... args) - : _arguments(arg, args...), - _size(_arguments.sizespec().size()), - _local_sizes(local_sizes), - _block_offsets(initialize_block_offsets( - _local_sizes)), - _memory_layout(std::array {{ _size }}), - _distspec(_arguments.distspec()), - _team(&_arguments.team()), - _teamspec(_arguments.teamspec()), - _nunits(_team->size()), - _blocksize(initialize_blocksize( - _size, - _distspec, - _nunits)), - _nblocks(_nunits), - _local_size( - initialize_local_extent(_team->myid())), - _local_memory_layout(std::array {{ _local_size }}), - _local_capacity(initialize_local_capacity()) - { - DASH_LOG_TRACE("MockPattern()", "Constructor with argument list"); - DASH_ASSERT_EQ( - _local_sizes.size(), _nunits, - "Number of given local sizes " << _local_sizes.size() << " " << - "does not match number of units" << _nunits); - initialize_local_range(); - DASH_LOG_TRACE("MockPattern()", "MockPattern initialized"); - } - - /** - * Constructor, initializes a pattern from explicit instances of - * \c SizeSpec, \c DistributionSpec, \c TeamSpec and a \c Team. - * - */ - MockPattern( - /// Number of local elements for every unit in the active team. - const std::vector & local_sizes, - /// Cartesian arrangement of units within the team - const TeamSpec_t & teamspec, - /// Team containing units to which this pattern maps its elements - dash::Team & team = dash::Team::All()) - : _size(initialize_size( - local_sizes)), - _local_sizes(local_sizes), - _block_offsets(initialize_block_offsets( - _local_sizes)), - _memory_layout(std::array {{ _size }}), - _distspec(DistributionSpec_t()), - _team(&team), - _teamspec( - teamspec, - _distspec, - *_team), - _nunits(_team->size()), - _blocksize(initialize_blocksize( - _size, - _distspec, - _nunits)), - _nblocks(_nunits), - _local_size( - initialize_local_extent(_team->myid())), - _local_memory_layout(std::array {{ _local_size }}), - _local_capacity(initialize_local_capacity()) - { - DASH_LOG_TRACE("MockPattern()", "(sizespec, dist, teamspec, team)"); - DASH_ASSERT_EQ( - _local_sizes.size(), _nunits, - "Number of given local sizes " << _local_sizes.size() << " " << - "does not match number of units" << _nunits); - initialize_local_range(); - DASH_LOG_TRACE("MockPattern()", "MockPattern initialized"); - } - - /** - * Constructor, initializes a pattern from explicit instances of - * \c SizeSpec, \c DistributionSpec, \c TeamSpec and a \c Team. - * - */ - MockPattern( - /// Number of local elements for every unit in the active team. - const std::vector & local_sizes, - /// Team containing units to which this pattern maps its elements - Team & team = dash::Team::All()) - : _size(initialize_size( - local_sizes)), - _local_sizes(local_sizes), - _block_offsets(initialize_block_offsets( - _local_sizes)), - _memory_layout(std::array {{ _size }}), - _distspec(DistributionSpec_t()), - _team(&team), - _teamspec(_distspec, *_team), - _nunits(_team->size()), - _blocksize(initialize_blocksize( - _size, - _distspec, - _nunits)), - _nblocks(_nunits), - _local_size( - initialize_local_extent(_team->myid())), - _local_memory_layout(std::array {{ _local_size }}), - _local_capacity(initialize_local_capacity()) - { - DASH_LOG_TRACE("MockPattern()", "(sizespec, dist, team)"); - DASH_ASSERT_EQ( - _local_sizes.size(), _nunits, - "Number of given local sizes " << _local_sizes.size() << " " << - "does not match number of units" << _nunits); - initialize_local_range(); - DASH_LOG_TRACE("MockPattern()", "MockPattern initialized"); - } - - /** - * Copy constructor. - */ - MockPattern(const self_t & other) - : _size(other._size), - _local_sizes(other._local_sizes), - _block_offsets(other._block_offsets), - _memory_layout(other._memory_layout), - _distspec(other._distspec), - _team(other._team), - _teamspec(other._teamspec), - _nunits(other._nunits), - _blocksize(other._blocksize), - _nblocks(other._nblocks), - _local_size(other._local_size), - _local_memory_layout(other._local_memory_layout), - _local_capacity(other._local_capacity), - _lbegin(other._lbegin), - _lend(other._lend) { - // No need to copy _arguments as it is just used to - // initialize other members. - DASH_LOG_TRACE("MockPattern(other)", "MockPattern copied"); - } - - /** - * Copy constructor using non-const lvalue reference parameter. - * - * Introduced so variadic constructor is not a better match for - * copy-construction. - */ - MockPattern(self_t & other) - : MockPattern(static_cast(other)) { - } - - /** - * Equality comparison operator. - */ - bool operator==( - /// Pattern instance to compare for equality - const self_t & other - ) const { - if (this == &other) { - return true; - } - // no need to compare all members as most are derived from - // constructor arguments. - return( - _size == other._size && - _local_sizes == other._local_sizes && - _distspec == other._distspec && - _teamspec == other._teamspec && - _nblocks == other._nblocks && - _blocksize == other._blocksize && - _nunits == other._nunits - ); - } - - /** - * Inquality comparison operator. - */ - bool operator!=( - /// Pattern instance to compare for inequality - const self_t & other - ) const { - return !(*this == other); - } - - /** - * Assignment operator. - */ - self_t & operator=(const self_t & other) { - DASH_LOG_TRACE("MockPattern.=(other)"); - if (this != &other) { - _size = other._size; - _local_sizes = other._local_sizes; - _block_offsets = other._block_offsets; - _memory_layout = other._memory_layout; - _distspec = other._distspec; - _team = other._team; - _teamspec = other._teamspec; - _local_size = other._local_size; - _local_memory_layout = other._local_memory_layout; - _blocksize = other._blocksize; - _nblocks = other._nblocks; - _local_capacity = other._local_capacity; - _nunits = other._nunits; - _lbegin = other._lbegin; - _lend = other._lend; - DASH_LOG_TRACE("MockPattern.=(other)", "MockPattern assigned"); - } - return *this; - } - - /** - * Resolves the global index of the first local element in the pattern. - * - * \see DashPatternConcept - */ - IndexType lbegin() const { - return _lbegin; - } - - /** - * Resolves the global index past the last local element in the pattern. - * - * \see DashPatternConcept - */ - IndexType lend() const { - return _lend; - } - - //////////////////////////////////////////////////////////////////////////// - /// unit_at - //////////////////////////////////////////////////////////////////////////// - - /** - * Convert given point in pattern to its assigned unit id. - * - * \see DashPatternConcept - */ - dash::team_unit_t unit_at( - /// Absolute coordinates of the point - const std::array & coords, - /// View specification (offsets) to apply on \c coords - const ViewSpec_t & viewspec) const { - DASH_LOG_TRACE_VAR("MockPattern.unit_at()", coords); - // Apply viewspec offsets to coordinates: - dash::team_unit_t unit_id{((coords[0] + viewspec[0].offset) / _blocksize) - % _nunits}; - DASH_LOG_TRACE_VAR("MockPattern.unit_at >", unit_id); - return unit_id; - } - - /** - * Convert given coordinate in pattern to its assigned unit id. - * - * \see DashPatternConcept - */ - dash::team_unit_t unit_at( - const std::array & g_coords) const { - DASH_LOG_TRACE_VAR("MockPattern.unit_at()", g_coords); - dash::team_unit_t unit_idx{0}; - auto g_coord = g_coords[0]; - for (; unit_idx < _nunits - 1; ++unit_idx) { - if (_block_offsets[unit_idx+1] >= g_coord) { - DASH_LOG_TRACE_VAR("MockPattern.unit_at >", unit_idx); - return unit_idx; - } - } - DASH_LOG_TRACE_VAR("MockPattern.unit_at >", _nunits-1); - return dash::team_unit_t(_nunits-1); - } - - /** - * Convert given global linear index to its assigned unit id. - * - * \see DashPatternConcept - */ - dash::team_unit_t unit_at( - /// Global linear element offset - IndexType global_pos, - /// View to apply global position - const ViewSpec_t & viewspec) const { - DASH_LOG_TRACE_VAR("MockPattern.unit_at()", global_pos); - DASH_LOG_TRACE_VAR("MockPattern.unit_at()", viewspec); - dash::team_unit_t unit_idx{0}; - // Apply viewspec offsets to coordinates: - auto g_coord = global_pos + viewspec[0].offset; - for (; unit_idx < _nunits - 1; ++unit_idx) { - if (_block_offsets[unit_idx+1] >= g_coord) { - DASH_LOG_TRACE_VAR("MockPattern.unit_at >", unit_idx); - return unit_idx; - } - } - DASH_LOG_TRACE_VAR("MockPattern.unit_at >", _nunits-1); - return dash::team_unit_t(_nunits-1); - } - - /** - * Convert given global linear index to its assigned unit id. - * - * \see DashPatternConcept - */ - dash::team_unit_t unit_at( - /// Global linear element offset - IndexType g_index) const { - DASH_LOG_TRACE_VAR("MockPattern.unit_at()", g_index); - dash::team_unit_t unit_idx{0}; - for (; unit_idx < _nunits - 1; ++unit_idx) { - if (_block_offsets[unit_idx+1] >= g_index) { - DASH_LOG_TRACE_VAR("MockPattern.unit_at >", unit_idx); - return unit_idx; - } - } - DASH_LOG_TRACE_VAR("MockPattern.unit_at >", _nunits-1); - return dash::team_unit_t(_nunits-1); - } - - //////////////////////////////////////////////////////////////////////////// - /// extent - //////////////////////////////////////////////////////////////////////////// - - /** - * The number of elements in this pattern in the given dimension. - * - * \see blocksize() - * \see local_size() - * \see local_extent() - * - * \see DashPatternConcept - */ - IndexType extent(dim_t dim) const { - DASH_ASSERT_EQ( - 0, dim, - "Wrong dimension for Pattern::local_extent. " << - "Expected dimension = 0, got " << dim); - return _size; - } - - /** - * The actual number of elements in this pattern that are local to the - * calling unit in the given dimension. - * - * \see local_extents() - * \see blocksize() - * \see local_size() - * \see extent() - * - * \see DashPatternConcept - */ - IndexType local_extent(dim_t dim) const { - DASH_ASSERT_EQ( - 0, dim, - "Wrong dimension for Pattern::local_extent. " << - "Expected dimension = 0, got " << dim); - return _local_size; - } - - /** - * The actual number of elements in this pattern that are local to the - * given unit, by dimension. - * - * \see local_extent() - * \see blocksize() - * \see local_size() - * \see extent() - * - * \see DashPatternConcept - */ - std::array local_extents( - dash::team_unit_t unit) const { - DASH_LOG_DEBUG_VAR("MockPattern.local_extents()", unit); - DASH_LOG_DEBUG_VAR("MockPattern.local_extents >", _local_size); - return std::array {{ _local_size }}; - } - - //////////////////////////////////////////////////////////////////////////// - /// local - //////////////////////////////////////////////////////////////////////////// - - /** - * Convert given local coordinates and viewspec to linear local offset - * (index). - * - * \see DashPatternConcept - */ - IndexType local_at( - /// Point in local memory - const std::array & local_coords, - /// View specification (offsets) to apply on \c coords - const ViewSpec_t & viewspec) const { - return local_coords[0] + viewspec[0].offset; - } - - /** - * Convert given local coordinates to linear local offset (index). - * - * \see DashPatternConcept - */ - IndexType local_at( - /// Point in local memory - const std::array & local_coords) const { - return local_coords[0]; - } - - /** - * Converts global coordinates to their associated unit and its respective - * local coordinates. - * - * NOTE: Same as \c local_index. - * - * \see DashPatternConcept - */ - inline local_coords_t local( - const std::array & g_coords) const noexcept { - DASH_LOG_TRACE_VAR("MockPattern.local()", g_coords); - IndexType g_index = g_coords[0]; - local_index_t l_index; - l_index.unit = g_index / _nunits; - if (_mock_idx == _local_size) { _mock_idx = 0; } - l_index.index = _mock_idx; - ++_mock_idx; - return l_index; - } - - /** - * Converts global index to its associated unit and respective local index. - * - * NOTE: Same as \c local_index. - * - * \see DashPatternConcept - */ - inline local_index_t local( - IndexType g_index) const noexcept { - DASH_LOG_TRACE_VAR("MockPattern.local()", g_index); - local_index_t l_index; - l_index.unit = g_index / _nunits; - if (_mock_idx == _local_size) { _mock_idx = 0; } - l_index.index = _mock_idx; - ++_mock_idx; - return l_index; - } - - /** - * Converts global coordinates to their associated unit's respective - * local coordinates. - * - * \see DashPatternConcept - */ - std::array local_coords( - const std::array & g_coords) const { - DASH_LOG_TRACE_VAR("MockPattern.local_coords()", g_coords); - IndexType g_index = g_coords[0]; - for (auto unit_idx = _nunits-1; unit_idx >= 0; --unit_idx) { - index_type block_offset = _block_offsets[unit_idx]; - if (block_offset <= g_index) { - auto l_coord = g_index - block_offset; - DASH_LOG_TRACE_VAR("MockPattern.local_coords >", l_coord); - return std::array {{ l_coord }}; - } - } - DASH_THROW( - dash::exception::InvalidArgument, - "MockPattern.local_coords: global index " << g_index << - " is out of bounds"); - } - - /** - * Converts global coordinates to their associated unit and their respective - * local index. - * - * \see DashPatternConcept - */ - local_index_t local_index( - const std::array & g_coords) const { - IndexType g_index = g_coords[0]; - DASH_LOG_TRACE_VAR("MockPattern.local_index()", g_coords); - local_index_t l_index; - for (auto unit_idx = _nunits-1; unit_idx >= 0; --unit_idx) { - index_type block_offset = _block_offsets[unit_idx]; - if (block_offset <= g_index) { - l_index.unit = unit_idx; - l_index.index = g_index - block_offset; - DASH_LOG_TRACE_VAR("MockPattern.local >", l_index.unit); - DASH_LOG_TRACE_VAR("MockPattern.local >", l_index.index); - return l_index; - } - } - DASH_THROW( - dash::exception::InvalidArgument, - "MockPattern.local: global index " << g_index < " is out of bounds"); - } - - //////////////////////////////////////////////////////////////////////////// - /// global - //////////////////////////////////////////////////////////////////////////// - - /** - * Converts local coordinates of a given unit to global coordinates. - * - * \see DashPatternConcept - */ - inline std::array global( - dash::team_unit_t unit, - const std::array & l_coords) const noexcept { - DASH_LOG_DEBUG_VAR("MockPattern.global()", unit); - DASH_LOG_DEBUG_VAR("MockPattern.global()", l_coords); - DASH_LOG_TRACE_VAR("MockPattern.global", _nunits); - if (_nunits < 2) { - return l_coords; - } - // Initialize global index with element phase (= l coords): - index_type glob_index = _block_offsets[unit] + l_coords[0]; - DASH_LOG_TRACE_VAR("MockPattern.global >", glob_index); - return std::array {{ glob_index }}; - } - - /** - * Converts local coordinates of active unit to global coordinates. - * - * \see DashPatternConcept - */ - inline std::array global( - const std::array & l_coords) const noexcept { - return global(_team->myid(), l_coords); - } - - /** - * Resolve an element's linear global index from the given unit's local - * index of that element. - * - * \see at Inverse of local() - * - * \see DashPatternConcept - */ - inline IndexType global( - dash::team_unit_t unit, - IndexType l_index) const noexcept { - return global(unit, std::array {{ l_index }})[0]; - } - - /** - * Resolve an element's linear global index from the calling unit's local - * index of that element. - * - * \see at Inverse of local() - * - * \see DashPatternConcept - */ - inline IndexType global( - IndexType l_index) const noexcept { - return global(_team->myid(), std::array {{ l_index }})[0]; - } - - /** - * Resolve an element's linear global index from a given unit's local - * coordinates of that element. - * - * \see at - * - * \see DashPatternConcept - */ - IndexType global_index( - dash::team_unit_t unit, - const std::array & l_coords) const { - auto g_index = global(unit, l_coords[0]); - return g_index; - } - - //////////////////////////////////////////////////////////////////////////// - /// at - //////////////////////////////////////////////////////////////////////////// - - /** - * Global coordinates to local index. - * - * Convert given global coordinates in pattern to their respective - * linear local index. - * - * \see DashPatternConcept - */ - inline IndexType at( - const std::array & g_coords) const { - return local_coords(g_coords)[0]; - } - - /** - * Global coordinates and viewspec to local index. - * - * Convert given global coordinate in pattern to its linear local index. - * - * \see DashPatternConcept - */ - inline IndexType at( - const std::array & g_coords, - const ViewSpec_t & viewspec) const { - auto vs_coords = g_coords; - vs_coords[0] += viewspec[0].offset; - return local_coords(vs_coords)[0]; - } - - /** - * Global coordinates to local index. - * - * Convert given coordinate in pattern to its linear local index. - * - * \see DashPatternConcept - */ - template - inline IndexType at(IndexType value, Values ... values) const noexcept { - static_assert( - sizeof...(values) == NumDimensions-1, - "Wrong parameter number"); - std::array inputindex = { - value, (IndexType)values... - }; - return at(inputindex); - } - - /** - * Whether there are local elements in a dimension at a given offset, - * e.g. in a specific row or column. - * - * \see DashPatternConcept - */ - bool has_local_elements( - /// Dimension to check - dim_t dim, - /// Offset in dimension - IndexType dim_offset, - /// DART id of the unit - dash::team_unit_t unit, - /// Viewspec to apply - const ViewSpec_t & viewspec) const { - DASH_ASSERT_EQ( - 0, dim, - "Wrong dimension for Pattern::has_local_elements. " << - "Expected dimension = 0, got " << dim); - DASH_LOG_TRACE_VAR("MockPattern.has_local_elements()", dim_offset); - DASH_LOG_TRACE_VAR("MockPattern.has_local_elements()", unit); - DASH_LOG_TRACE_VAR("MockPattern.has_local_elements()", viewspec); - DASH_THROW( - dash::exception::NotImplemented, - "MockPattern.has_local_elements is not implemented"); - } - - /** - * Whether the given global index is local to the specified unit. - * - * \see DashPatternConcept - */ - inline bool is_local( - IndexType index, - dash::team_unit_t unit) const noexcept { - DASH_LOG_TRACE_VAR("MockPattern.is_local()", index); - DASH_LOG_TRACE_VAR("MockPattern.is_local()", unit); - bool is_loc = index >= _block_offsets[unit] && - (unit == _nunits-1 || - index < _block_offsets[unit+1]); - DASH_LOG_TRACE_VAR("MockPattern.is_local >", is_loc); - return is_loc; - } - - /** - * Whether the given global index is local to the unit that created - * this pattern instance. - * - * \see DashPatternConcept - */ - inline bool is_local( - IndexType index) const noexcept { - auto unit = team().myid(); - DASH_LOG_TRACE_VAR("MockPattern.is_local()", index); - DASH_LOG_TRACE_VAR("MockPattern.is_local", unit); - bool is_loc = index >= _block_offsets[unit] && - (unit == _nunits-1 || - index < _block_offsets[unit+1]); - DASH_LOG_TRACE_VAR("MockPattern.is_local >", is_loc); - return is_loc; - } - - /** - * Maximum number of elements in a single block in the given dimension. - * - * \return The blocksize in the given dimension - * - * \see DashPatternConcept - */ - SizeType blocksize( - /// The dimension in the pattern - dim_t dimension) const noexcept { - return _blocksize; - } - - /** - * Maximum number of elements in a single block in all dimensions. - * - * \return The maximum number of elements in a single block assigned to - * a unit. - * - * \see DashPatternConcept - */ - SizeType max_blocksize() const noexcept { - return _blocksize; - } - - /** - * Maximum number of elements assigned to a single unit in total, - * equivalent to the local capacity of every unit in this pattern. - * - * \see DashPatternConcept - */ - constexpr SizeType local_capacity() const noexcept { - return _local_capacity; - } - - /** - * The actual number of elements in this pattern that are local to the - * calling unit in total. - * - * \see blocksize() - * \see local_extent() - * \see local_capacity() - * - * \see DashPatternConcept - */ - constexpr SizeType local_size() const noexcept { - return _local_size; - } - - /** - * The number of units to which this pattern's elements are mapped. - * - * \see DashPatternConcept - */ - constexpr IndexType num_units() const noexcept { - return _nunits; - } - - /** - * The maximum number of elements arranged in this pattern. - * - * \see DashPatternConcept - */ - constexpr IndexType capacity() const noexcept { - return _size; - } - - /** - * The number of elements arranged in this pattern. - * - * \see DashPatternConcept - */ - constexpr IndexType size() const noexcept { - return _size; - } - - /** - * The Team containing the units to which this pattern's elements are - * mapped. - */ - constexpr dash::Team & team() const noexcept { - return *_team; - } - - /** - * Distribution specification of this pattern. - */ - const DistributionSpec_t & distspec() const noexcept { - return _distspec; - } - - /** - * Size specification of the index space mapped by this pattern. - * - * \see DashPatternConcept - */ - SizeSpec_t sizespec() const noexcept { - return SizeSpec_t(std::array {{ _size }}); - } - - /** - * Size specification of the index space mapped by this pattern. - * - * \see DashPatternConcept - */ - const std::array & extents() const noexcept { - return std::array {{ _size }}; - } - - /** - * Cartesian index space representing the underlying memory model of the - * pattern. - * - * \see DashPatternConcept - */ - const MemoryLayout_t & memory_layout() const noexcept { - return _memory_layout; - } - - /** - * Cartesian index space representing the underlying local memory model - * of this pattern for the calling unit. - * Not part of DASH Pattern concept. - */ - const LocalMemoryLayout_t & local_memory_layout() const noexcept { - return _local_memory_layout; - } - - /** - * Cartesian arrangement of the Team containing the units to which this - * pattern's elements are mapped. - * - * \see DashPatternConcept - */ - const TeamSpec_t & teamspec() const noexcept { - return _teamspec; - } - - /** - * Convert given global linear offset (index) to global cartesian - * coordinates. - * - * \see DashPatternConcept - */ - std::array coords( - IndexType index) const noexcept { - return std::array {{ index }}; - } - - /** - * View spec (offset and extents) of block at global linear block index in - * cartesian element space. - */ - ViewSpec_t block( - index_type g_block_index) const noexcept { - index_type offset = _block_offsets[g_block_index]; - auto blocksize = _local_sizes[g_block_index]; - return ViewSpec_t(offset, blocksize); - } - - /** - * View spec (offset and extents) of block at local linear block index in - * global cartesian element space. - */ - ViewSpec_t local_block( - index_type l_block_index) const noexcept { - DASH_LOG_DEBUG_VAR("MockPattern.local_block()", l_block_index); - DASH_ASSERT_EQ( - 0, l_block_index, - "MockPattern always assigns exactly 1 block to a single unit"); - index_type block_offset = _block_offsets[_team->myid()]; - size_type block_size = _local_sizes[_team->myid()]; - ViewSpec_t block_vs({ block_offset }, { block_size }); - DASH_LOG_DEBUG_VAR("MockPattern.local_block >", block_vs); - return block_vs; - } - - /** - * View spec (offset and extents) of block at local linear block index in - * local cartesian element space. - */ - ViewSpec_t local_block_local( - index_type local_block_index) const noexcept { - size_type block_size = _local_sizes[_team->myid()]; - return ViewSpec_t({ 0 }, { block_size }); - } - - /** - * Memory order followed by the pattern. - */ - constexpr static MemArrange memory_order() noexcept { - return Arrangement; - } - - /** - * Number of dimensions of the cartesian space partitioned by the pattern. - */ - constexpr static dim_t ndim() noexcept { - return 1; - } - - /** - * Initialize the size (number of mapped elements) of the Pattern. - */ - SizeType initialize_size( - const std::vector & local_sizes) const noexcept { - DASH_LOG_TRACE_VAR("MockPattern.init_size()", local_sizes); - size_type size = 0; - for (size_type unit_idx = 0; unit_idx < local_sizes.size(); ++unit_idx) { - size += local_sizes[unit_idx]; - } - DASH_LOG_TRACE_VAR("MockPattern.init_size >", size); - return size; - } - - /** - * Initialize block size specs from memory layout, team spec and - * distribution spec. - */ - std::vector initialize_block_offsets( - const std::vector & local_sizes) const noexcept { - DASH_LOG_TRACE_VAR("MockPattern.init_block_offsets", local_sizes); - std::vector block_offsets; - // NOTE: Assuming 1 block for every unit. - block_offsets.push_back(0); - for (auto unit_idx = 0; unit_idx < local_sizes.size() - 1; ++unit_idx) { - auto block_offset = block_offsets[unit_idx] + - local_sizes[unit_idx]; - block_offsets.push_back(block_offset); - } - return block_offsets; - } - - /** - * Initialize block size specs from memory layout, team spec and - * distribution spec. - */ - SizeType initialize_blocksize( - SizeType size, - const DistributionSpec_t & distspec, - SizeType nunits) const noexcept { - DASH_LOG_TRACE_VAR("MockPattern.init_blocksize", nunits); - if (nunits == 0) { - return 0; - } - // NOTE: Assuming 1 block for every unit. - return 1; - } - - /** - * Initialize local block spec from global block spec. - */ - SizeType initialize_num_local_blocks( - SizeType num_blocks, - SizeType blocksize, - const DistributionSpec_t & distspec, - SizeType nunits, - SizeType local_size) const { - auto num_l_blocks = local_size; - if (blocksize > 0) { - num_l_blocks = dash::math::div_ceil( - num_l_blocks, - blocksize); - } else { - num_l_blocks = 0; - } - DASH_LOG_TRACE_VAR("MockPattern.init_num_local_blocks", num_l_blocks); - return num_l_blocks; - } - - /** - * Max. elements per unit (local capacity) - */ - SizeType initialize_local_capacity() const { - SizeType l_capacity = 0; - if (_nunits == 0) { - return 0; - } - DASH_LOG_TRACE_VAR("MockPattern.init_lcapacity", _nunits); - // Local capacity is maximum number of elements assigned to a single unit, - // i.e. the maximum local size: - l_capacity = *(std::max_element(_local_sizes.begin(), _local_sizes.end())); - DASH_LOG_DEBUG_VAR("MockPattern.init_lcapacity >", l_capacity); - return l_capacity; - } - - /** - * Initialize block- and block size specs from memory layout, team spec - * and distribution spec. - */ - void initialize_local_range() { - auto l_size = _local_size; - DASH_LOG_DEBUG_VAR("MockPattern.init_local_range()", l_size); - if (l_size == 0) { - _lbegin = 0; - _lend = 0; - } else { - // First local index transformed to global index - _lbegin = global(0); - // Index past last local index transformed to global index. - // global(l_size) would be out of range, so we use the global index - // to the last element and increment by 1: - _lend = global(l_size - 1) + 1; - } - DASH_LOG_DEBUG_VAR("MockPattern.init_local_range >", _lbegin); - DASH_LOG_DEBUG_VAR("MockPattern.init_local_range >", _lend); - } - - /** - * Resolve extents of local memory layout for a specified unit. - */ - SizeType initialize_local_extent( - dash::team_unit_t unit) const { - DASH_LOG_DEBUG_VAR("MockPattern.init_local_extent()", unit); - DASH_LOG_DEBUG_VAR("MockPattern.init_local_extent()", _nunits); - if (_nunits == 0) { - return 0; - } - // Local size of given unit: - SizeType l_extent = _local_sizes[unit]; - DASH_LOG_DEBUG_VAR("MockPattern.init_local_extent >", l_extent); - return l_extent; - } - -}; - -} // namespace dash - -#endif // DASH__MOCK_PATTERN_H_ diff --git a/dash/examples/bench.05.pattern/main.cpp b/dash/examples/bench.05.pattern/main.cpp index 675ecf607..97a954ae9 100644 --- a/dash/examples/bench.05.pattern/main.cpp +++ b/dash/examples/bench.05.pattern/main.cpp @@ -1,7 +1,6 @@ #include #include "../bench.h" -#include "MockPattern.h" #include #include @@ -21,11 +20,11 @@ typedef dash::util::Timer< #define TYPE int #endif -typedef dash::MockPattern< +typedef dash::BlockPattern< 1, dash::ROW_MAJOR, int -> MockPattern_t; +> BlockPattern_t; typedef dash::CSRPattern< 1, dash::ROW_MAJOR, @@ -40,8 +39,8 @@ typedef dash::TilePattern< typedef dash::Array< TYPE, int, - MockPattern_t -> ArrayMockDist_t; + BlockPattern_t +> ArrayBlockDist_t; typedef dash::Array< TYPE, int, @@ -123,7 +122,7 @@ void perform_test( << "iterations" << ", " << std::setw(11) - << "mock" + << "block" << ", " << std::setw(11) << "irreg" @@ -143,12 +142,11 @@ void perform_test( local_sizes.push_back(ELEM_PER_UNIT); } - MockPattern_t mock_pat( - // Local sizes - local_sizes + BlockPattern_t block_pat( + ELEM_PER_UNIT * num_units ); - ArrayMockDist_t arr_mock_dist( - mock_pat + ArrayBlockDist_t arr_block_dist( + block_pat ); IrregPattern_t irreg_pat( // Local sizes @@ -165,7 +163,7 @@ void perform_test( dash::TILE(ELEM_PER_UNIT)) ); - double t_mock = test_pattern_gups(arr_mock_dist, ELEM_PER_UNIT, REPEAT); + double t_block = test_pattern_gups(arr_block_dist, ELEM_PER_UNIT, REPEAT); double t_irreg = test_pattern_gups(arr_irreg_dist, ELEM_PER_UNIT, REPEAT); double t_tiled = test_pattern_gups(arr_tiled_dist, ELEM_PER_UNIT, REPEAT); double t_raw = test_raw_gups( arr_tiled_dist, ELEM_PER_UNIT, REPEAT); @@ -173,7 +171,7 @@ void perform_test( dash::barrier(); if (dash::myid() == 0) { - double gups_mock = gups(num_units, t_mock, ELEM_PER_UNIT, REPEAT); + double gups_block = gups(num_units, t_block, ELEM_PER_UNIT, REPEAT); double gups_irreg = gups(num_units, t_irreg, ELEM_PER_UNIT, REPEAT); double gups_tiled = gups(num_units, t_tiled, ELEM_PER_UNIT, REPEAT); double gups_raw = gups(num_units, t_raw, ELEM_PER_UNIT, REPEAT); @@ -188,7 +186,7 @@ void perform_test( << REPEAT << ", " << std::setw(11) << std::fixed << std::setprecision(4) - << gups_mock + << gups_block << ", " << std::setw(11) << std::fixed << std::setprecision(4) << gups_irreg diff --git a/dash/examples/bench.10.summa/main.cpp b/dash/examples/bench.10.summa/main.cpp index bb186da1f..53cc8cabb 100644 --- a/dash/examples/bench.10.summa/main.cpp +++ b/dash/examples/bench.10.summa/main.cpp @@ -299,7 +299,7 @@ void perform_test( std::array team_extents {{ params.units_y, params.units_x }}; team_spec.resize(team_extents); } -#if 1 +#if 0 auto pattern = dash::make_pattern< dash::summa_pattern_partitioning_constraints, dash::summa_pattern_mapping_constraints, @@ -335,7 +335,7 @@ void perform_test( if (myid == 0) { if (iteration == 0) { - cout << "-- Pattern: " << pattern << endl + cout << "-- Pattern: " << dash::typestr(pattern) << endl << "--" << endl; // Print data set column headers: cout << std::right diff --git a/dash/examples/ex.08.io-hdf5/main.cpp b/dash/examples/ex.08.io-hdf5/main.cpp index b038b7f47..f2902d05e 100644 --- a/dash/examples/ex.08.io-hdf5/main.cpp +++ b/dash/examples/ex.08.io-hdf5/main.cpp @@ -51,8 +51,8 @@ int main(int argc, char * argv[]) if(myid == 0){ - cout << "DASH HDF5 API example. After each change in the hdf5 file" - << " the contents are printed using h5dump" << endl; + cout << "DASH HDF5 API example. After each change in the hdf5 file " + << "the contents are printed using h5dump" << endl; } // Write Array to HDF5 file using defaults { @@ -69,8 +69,8 @@ int main(int argc, char * argv[]) { if(myid == 0){ print_separator(); - cout << "Read " << FILENAME << " / group/data into Array C," - << " reconstruct pattern" << endl; + cout << "Read " << FILENAME << " / group/data into Array C, " + << "reconstruct pattern" << endl; } // Use delayed allocation array_t array_c; @@ -83,14 +83,17 @@ int main(int argc, char * argv[]) { if(myid == 0){ print_separator(); - cout << "Read " << FILENAME << " / group/data into already allocated Array C" << endl; + cout << "Read " << FILENAME + << " / group/data into already allocated Array C" << endl; } // pass allocated array to define custom pattern array_t array_c(pattern_b); // tilesize=7 StoreHDF::read(array_c, FILENAME, "group/data"); if(myid == 0){ - cout << "Array A Pattern: Tilesize: " << array_a.pattern().blocksize(0) << endl; - cout << "Array C Pattern: Tilesize: " << array_c.pattern().blocksize(0) << endl; + cout << "Array A Pattern: Tilesize: " + << array_a.pattern().blocksize(0) << endl; + cout << "Array C Pattern: Tilesize: " + << array_c.pattern().blocksize(0) << endl; } } diff --git a/dash/include/dash/Array.h b/dash/include/dash/Array.h index 618199843..cae28e488 100644 --- a/dash/include/dash/Array.h +++ b/dash/include/dash/Array.h @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -635,16 +636,9 @@ template< > class Array { - /** - * The Cray compiler (as of CCE8.5.6) does not support - * std::is_trivially_copyable. - * - * TODO: Remove the guard once this has been fixed by Cray. - */ -#ifndef __CRAYC - static_assert(std::is_trivially_copyable::value, - "Element type must be trivially copyable"); -#endif + static_assert( + dash::is_container_compatible::value, + "Type not supported for DASH containers"); private: typedef Array self_t; diff --git a/dash/include/dash/Atomic.h b/dash/include/dash/Atomic.h index 3397a1147..3b8e0e38e 100644 --- a/dash/include/dash/Atomic.h +++ b/dash/include/dash/Atomic.h @@ -1,9 +1,9 @@ #ifndef DASH__ATOMIC_H__INCLUDED #define DASH__ATOMIC_H__INCLUDED -#include +#include -#include +#include namespace dash { @@ -67,9 +67,10 @@ class Atomic { /** * Disabled assignment as this violates the atomic semantics * - * TODO: Assignment semantics are not well-defined: - * - Constructor Atomic(T) is default-defined - * - Assignment Atomic=(T) is deleted + * \todo + * Assignment semantics are not well-defined: + * - Constructor Atomic(T) is default-defined + * - Assignment Atomic=(T) is deleted */ T operator=(T value) = delete; @@ -115,7 +116,7 @@ std::ostream & operator<<( const Atomic & at) { std::ostringstream ss; - ss << dash::internal::typestr(at) << ""; + ss << dash::typestr(at) << ""; return operator<<(os, ss.str()); } diff --git a/dash/include/dash/Cartesian.h b/dash/include/dash/Cartesian.h index d04fa61ce..0d2564f33 100644 --- a/dash/include/dash/Cartesian.h +++ b/dash/include/dash/Cartesian.h @@ -44,20 +44,25 @@ class CartesianSpace protected: /// Number of elements in the cartesian space spanned by this instance. - SizeType _size; + SizeType _size = 0; /// Number of dimensions of the cartesian space, initialized with 0's. - SizeType _ndim; + SizeType _rank = NumDimensions; /// Extents of the cartesian space by dimension. extents_type _extents = {{ }}; public: + /** + * The number of dimension in the cartesian space. + */ + typedef std::integral_constant ndim; + /** * Default constructor, creates a cartesian space of extent 0 in all * dimensions. */ constexpr CartesianSpace() : _size(0), - _ndim(NumDimensions) + _rank(NumDimensions) { } /** @@ -67,7 +72,7 @@ class CartesianSpace template CartesianSpace(SizeType arg, Args... args) : _size(0), - _ndim(NumDimensions) { + _rank(NumDimensions) { resize(arg, args...); } @@ -77,17 +82,10 @@ class CartesianSpace CartesianSpace( const extents_type & extents) : _size(0), - _ndim(NumDimensions) { + _rank(NumDimensions) { resize(extents); } - /** - * Number of dimensions of the cartesian space. - */ - constexpr static dim_t ndim() { - return NumDimensions; - } - /** * Equality comparison operator. */ @@ -149,23 +147,12 @@ class CartesianSpace * The number of dimension in the cartesian space with extent greater * than 1. * - * \see num_dimensions() + * \see ndim * * \return The number of dimensions in the coordinate */ - constexpr SizeType rank() const { - return NumDimensions; - } - - /** - * The number of dimension in the cartesian space. - * - * \see rank() - * - * \return The number of dimensions in the coordinate - */ - constexpr SizeType num_dimensions() const noexcept { - return NumDimensions; + constexpr dim_t rank() const noexcept { + return _rank; } /** @@ -241,6 +228,9 @@ class SizeSpec : public CartesianSpace /** * Defines a cartesian, totally-ordered index space by mapping linear * indices to cartesian coordinates depending on memory order. + * + * \note Not derived from CartesianSpace to provide resizing in O(d) + * instead of O(2d). */ template< dim_t NumDimensions, @@ -261,17 +251,13 @@ class CartesianIndexSpace typedef SizeType size_type; typedef std::array extents_type; -/* - * Note: Not derived from CartesianSpace to provide resizing in O(d) - * instead of O(2d). - */ protected: /// Number of elements in the cartesian space spanned by this instance. - SizeType _size = 0; - /// Number of dimensions of the cartesian space, initialized with 0's. - SizeType _ndim = NumDimensions; + SizeType _size = 0; + /// Number of dimensions in the cartesian space. + SizeType _rank = NumDimensions; /// Extents of the cartesian space by dimension. - extents_type _extents = { }; + extents_type _extents = { }; /// Cumulative index offsets of the index space by dimension respective /// to row order. Avoids recalculation of \c NumDimensions-1 offsets /// in every call of \at(). @@ -282,6 +268,11 @@ class CartesianIndexSpace extents_type _offset_col_major = { }; public: + /** + * The number of dimension in the cartesian space. + */ + typedef std::integral_constant ndim; + /** * Default constructor, creates a cartesian index space of extent 0 * in all dimensions. @@ -293,9 +284,7 @@ class CartesianIndexSpace */ CartesianIndexSpace( const extents_type & extents) - : _size(0), - _ndim(NumDimensions), - _extents(extents) + : _extents(extents) { resize(extents); } @@ -305,13 +294,23 @@ class CartesianIndexSpace */ template CartesianIndexSpace(SizeType arg, Args... args) - : _size(0), - _ndim(NumDimensions), - _extents({{ }}) + : _extents({{ }}) { resize(arg, args...); } + /** + * The number of dimension in the cartesian space with extent greater + * than 1. + * + * \see num_dimensions() + * + * \return The number of dimensions in the coordinate + */ + constexpr dim_t rank() const noexcept { + return _rank; + } + /** * Equality comparison operator. */ @@ -382,29 +381,6 @@ class CartesianIndexSpace resize(_extents); } - /** - * The number of dimension in the cartesian space with extent greater - * than 1. - * - * \see num_dimensions() - * - * \return The number of dimensions in the coordinate - */ - constexpr SizeType rank() const noexcept { - return NumDimensions; - } - - /** - * The number of dimension in the cartesian space. - * - * \see rank() - * - * \return The number of dimensions in the coordinate - */ - constexpr SizeType num_dimensions() const noexcept { - return NumDimensions; - } - /** * The number of discrete elements within the space spanned by the * coordinate. @@ -585,7 +561,7 @@ class CartesianIndexSpace IndexType index, dim_t dimension, IndexType dim_offset) const { - if (_ndim == 1) { + if (_rank == 1) { // Shortcut for trivial case return (index >= 0 && index < size()); } diff --git a/dash/include/dash/Dimensional.h b/dash/include/dash/Dimensional.h index 1ebd23de9..0da2c298b 100644 --- a/dash/include/dash/Dimensional.h +++ b/dash/include/dash/Dimensional.h @@ -370,6 +370,25 @@ struct ViewRegion { std::array end; }; +template< + typename IndexType = dash::default_index_t> +struct ViewRange { + // Range begin offset. + IndexType begin; + // Range end offset. + IndexType end; +}; + +template +std::ostream & operator<<( + std::ostream & os, + const ViewRange & viewrange) { + os << "dash::ViewRange<" << typeid(IndexType).name() << ">(" + << "begin:" << viewrange.begin << " " + << "end:" << viewrange.end << ")"; + return os; +} + /** * Equality comparison operator for ViewPair. */ @@ -399,9 +418,9 @@ template std::ostream & operator<<( std::ostream & os, const ViewPair & viewpair) { - os << "dash::ViewPair<" << typeid(IndexType).name() << ">(offset:" - << viewpair.offset << " extent:" - << viewpair.extent << ")"; + os << "dash::ViewPair<" << typeid(IndexType).name() << ">(" + << "offset:" << viewpair.offset << " " + << "extent:" << viewpair.extent << ")"; return os; } @@ -425,6 +444,7 @@ class ViewSpec public: typedef ViewRegion region_type; + typedef ViewRange range_type; public: template @@ -635,7 +655,7 @@ class ViewSpec return _extents[dimension]; } - constexpr std::array extents() const + constexpr const std::array & extents() const { return _extents; } @@ -644,11 +664,18 @@ class ViewSpec return _extents[dim]; } - constexpr std::array offsets() const + constexpr const std::array & offsets() const { return _offsets; } + constexpr range_type range(dim_t dim) const + { + return range_type { + static_cast(_offsets[dim]), + static_cast(_offsets[dim] + _extents[dim]) }; + } + constexpr IndexType offset(dim_t dim) const { return _offsets[dim]; diff --git a/dash/include/dash/GlobPtr.h b/dash/include/dash/GlobPtr.h index f778be1a6..25d3c4dbc 100644 --- a/dash/include/dash/GlobPtr.h +++ b/dash/include/dash/GlobPtr.h @@ -99,7 +99,7 @@ class GlobPtr /** * Constructor for conversion of std::nullptr_t. */ - constexpr GlobPtr(std::nullptr_t p) : _dart_gptr(DART_GPTR_NULL) + constexpr explicit GlobPtr(std::nullptr_t p) : _dart_gptr(DART_GPTR_NULL) { } /** diff --git a/dash/include/dash/GlobRef.h b/dash/include/dash/GlobRef.h index dad642bfd..a7a65bd15 100644 --- a/dash/include/dash/GlobRef.h +++ b/dash/include/dash/GlobRef.h @@ -61,19 +61,16 @@ class GlobRef public: /** - * Default constructor, creates an GlobRef object referencing an element in - * global memory. + * Reference semantics forbid declaration without definition. */ - GlobRef() - : _gptr(DART_GPTR_NULL) { - } + GlobRef() = delete; /** * Constructor, creates an GlobRef object referencing an element in global * memory. */ template - explicit GlobRef( + explicit constexpr GlobRef( /// Pointer to referenced object in global memory GlobPtr & gptr) : GlobRef(gptr.dart_gptr()) @@ -84,7 +81,7 @@ class GlobRef * memory. */ template - explicit GlobRef( + explicit constexpr GlobRef( /// Pointer to referenced object in global memory const GlobPtr & gptr) : GlobRef(gptr.dart_gptr()) @@ -94,34 +91,26 @@ class GlobRef * Constructor, creates an GlobRef object referencing an element in global * memory. */ - explicit GlobRef(dart_gptr_t dart_gptr) + explicit constexpr GlobRef(dart_gptr_t dart_gptr) : _gptr(dart_gptr) - { - DASH_LOG_TRACE_VAR("GlobRef(dart_gptr_t)", dart_gptr); - } + { } /** - * TODO: Try deleting copy constructors to preserve unified copy semantics - * ref_a = ref_b. + * Like native references, global reference types cannot be copied. * - * Copy constructor. + * Default definition of copy constructor would conflict with semantics + * of \c operator=(const self_t &). */ - GlobRef(const self_t & other) = default; + GlobRef(const self_t & other) = delete; - GlobRef(self_t && other) = default; - /** - * TODO: Try deleting copy constructors to preserve unified copy semantics - * ref_a = ref_b. - * - * Copy constructor. + * Unlike native reference types, global reference types are moveable. */ - template - GlobRef( - const GlobRef & other) - : _gptr(other._gptr) - { } + GlobRef(self_t && other) = default; + /** + * Value-assignment operator. + */ GlobRef & operator=(const T val) { set(val); return *this; @@ -132,14 +121,6 @@ class GlobRef */ GlobRef & operator=(const self_t & other) { - // This results in a dart_put, required for STL algorithms like - // std::copy to work on global ranges. - // TODO: Not well-defined: - // This violates copy semantics, as - // GlobRef(const GlobRef & other) - // copies the GlobRef instance while - // GlobRef=(const GlobRef & other) - // puts the value. set(static_cast(other)); return *this; } @@ -150,14 +131,6 @@ class GlobRef template GlobRef & operator=(GlobRefOrElementT && other) { - // This results in a dart_put, required for STL algorithms like - // std::copy to work on global ranges. - // TODO: Not well-defined: - // This violates copy semantics, as - // GlobRef(const GlobRef & other) - // copies the GlobRef instance while - // GlobRef=(const GlobRef & other) - // puts the value. set(std::forward(other)); return *this; } @@ -332,7 +305,7 @@ class GlobRef return GlobPtr(_gptr); } - dart_gptr_t dart_gptr() const { + constexpr dart_gptr_t dart_gptr() const noexcept { return _gptr; } diff --git a/dash/include/dash/Iterator.h b/dash/include/dash/Iterator.h index ecdb466d0..226ea6196 100644 --- a/dash/include/dash/Iterator.h +++ b/dash/include/dash/Iterator.h @@ -48,6 +48,16 @@ namespace dash { +namespace detail { + DASH__META__DEFINE_TRAIT__HAS_TYPE(value_type); + DASH__META__DEFINE_TRAIT__HAS_TYPE(iterator); + DASH__META__DEFINE_TRAIT__HAS_TYPE(const_iterator); + DASH__META__DEFINE_TRAIT__HAS_TYPE(reference); + DASH__META__DEFINE_TRAIT__HAS_TYPE(const_reference); + DASH__META__DEFINE_TRAIT__HAS_TYPE(pointer); + DASH__META__DEFINE_TRAIT__HAS_TYPE(const_pointer); +} + /** * * \concept{DashIteratorConcept} @@ -59,13 +69,37 @@ index(IndexType idx) { return idx; } +/** + * + * \concept{DashIteratorConcept} + */ +// template +// constexpr auto index(Iterator it) -> decltype((++it).pos()) { +// return it.pos(); +// } + /** * * \concept{DashIteratorConcept} */ template -constexpr auto index(Iterator it) -> decltype((++it).pos()) { - return it.pos(); +constexpr auto index(Iterator it) -> decltype((++it).gpos()) { + return it.gpos(); +} + + +/** + * Resolve the number of elements between two iterators. + * + * \concept{DashIteratorConcept} + */ +template +typename RandomAccessIt::difference_type +distance( + const RandomAccessIt & first, + const RandomAccessIt & last) +{ + return last - first; } /** diff --git a/dash/include/dash/List.h b/dash/include/dash/List.h index d9d88dfbe..3e9d9b96a 100644 --- a/dash/include/dash/List.h +++ b/dash/include/dash/List.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -168,16 +169,9 @@ template< class AllocatorType = dash::allocator::DynamicAllocator > class List { - /** - * The Cray compiler (as of CCE8.5.6) does not support - * std::is_trivially_copyable. - * - * TODO: Remove the guard once this has been fixed by Cray. - */ - #ifndef __CRAYC - static_assert(std::is_trivially_copyable::value, - "Element type must be trivially copyable"); - #endif + static_assert( + dash::is_container_compatible::value, + "Type not supported for DASH containers"); template friend class LocalListRef; diff --git a/dash/include/dash/Matrix.h b/dash/include/dash/Matrix.h index 52472d9b5..b22da371c 100644 --- a/dash/include/dash/Matrix.h +++ b/dash/include/dash/Matrix.h @@ -9,6 +9,7 @@ #include #include #include +#include #include @@ -134,16 +135,10 @@ template< class PatternT = TilePattern > class Matrix { - /** - * The Cray compiler (as of CCE8.5.6) does not support - * std::is_trivially_copyable. - * - * TODO: Remove the guard once this has been fixed by Cray. - */ -#ifndef __CRAYC - static_assert(std::is_trivially_copyable::value, - "Element type must be trivially copyable"); -#endif + static_assert( + dash::is_container_compatible::value, + "Type not supported for DASH containers"); + static_assert(std::is_same::value, "Index type IndexT must be the same for Matrix and specified pattern"); @@ -650,3 +645,4 @@ using NArray = dash::Matrix; #include #endif // DASH__MATRIX_H_INCLUDED + diff --git a/dash/include/dash/Meta.h b/dash/include/dash/Meta.h new file mode 100644 index 000000000..a7f52096e --- /dev/null +++ b/dash/include/dash/Meta.h @@ -0,0 +1,144 @@ +#ifndef DASH__META_H__INCLUDED +#define DASH__META_H__INCLUDED + +#include + +#include + + +#ifndef DOXYGEN + +#define DASH__META__DEFINE_TRAIT__HAS_TYPE(DepType) \ + template \ + struct has_type_##DepType { \ + private: \ + typedef char yes; \ + typedef struct { char array[2]; } no; \ + template static yes test(typename C:: DepType *); \ + template static no test(...); \ + public: \ + static constexpr bool value = sizeof(test(0)) == sizeof(yes); \ + }; + +#endif // DOXYGEN + +namespace dash { + + +template struct conjunction : std::true_type { }; + +template struct conjunction : Cond0 { }; + +template +struct conjunction +: std::conditional< + bool(Cond0::value), + conjunction, + Cond0 > +{ }; + + + +/** + * Definition of type trait \c dash::has_type_iterator + * with static member \c value indicating whether type \c T provides + * dependent type \c iterator. + */ +DASH__META__DEFINE_TRAIT__HAS_TYPE(iterator); +/** + * Definition of type trait \c dash::has_type_const_iterator + * with static member \c value indicating whether type \c T provides + * dependent type \c const_iterator. + */ +DASH__META__DEFINE_TRAIT__HAS_TYPE(const_iterator); +/** + * Definition of type trait \c dash::has_type_reference + * with static member \c value indicating whether type \c T provides + * dependent type \c reference. + */ +DASH__META__DEFINE_TRAIT__HAS_TYPE(reference); +/** + * Definition of type trait \c dash::has_type_const_reference + * with static member \c value indicating whether type \c T provides + * dependent type \c const_reference. + */ +DASH__META__DEFINE_TRAIT__HAS_TYPE(const_reference); +/** + * Definition of type trait \c dash::has_type_value_type + * with static member \c value indicating whether type \c T provides + * dependent type \c value_type. + */ +DASH__META__DEFINE_TRAIT__HAS_TYPE(value_type); + + +/** + * Type trait indicating whether the specified type is eligible for + * elements of DASH containers. + */ +template +struct is_container_compatible : + public std::integral_constant::value +#if !defined(__CRAYC) && false + // The Cray compiler (as of CCE8.5.6) does not support + // std::is_trivially_copyable. + && std::is_trivially_copyable::value +#endif + > +{ }; + +} // namespace dash + +#include +#include + +#ifndef DOXYGEN + +namespace dash { + +/* + * For reference, see + * + * "Working Draft, C++ Extension for Ranges" + * http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/n4569.pdf + * + */ + +template +using reference_t = typename std::add_lvalue_reference::type; + +template +using rvalue_reference_t = + decltype(std::move(std::declval>())); + +// void f(ValueType && val) { +// std::string i(move(val)); +// // ... +// } +// +// ValueType val; +// std::bind(f, dash::make_adv(std::move(val)))(); + +template struct adv { + T _value; + explicit adv(T && value) : _value(std::forward(value)) {} + template T && operator()(U &&...) { + return std::forward(_value); + } +}; + +template adv make_adv(T && value) { + return adv { std::forward(value) }; +} + +} // namespace dash + +namespace std { + // Must be defined in global std namespace. + template + struct is_bind_expression< dash::adv > : std::true_type {}; +} + +#endif // DOXYGEN + +#endif // DASH__META_H__INCLUDED diff --git a/dash/include/dash/Pair.h b/dash/include/dash/Pair.h index 922e3539d..2b024843d 100644 --- a/dash/include/dash/Pair.h +++ b/dash/include/dash/Pair.h @@ -1,7 +1,7 @@ #ifndef DASH_DASH_INCLUDE_DASH_PAIR_H_ #define DASH_DASH_INCLUDE_DASH_PAIR_H_ -#include +#include #include #include @@ -215,7 +215,7 @@ namespace dash { const Pair & pair) { std::ostringstream ss; - ss << dash::internal::typestr(pair) + ss << dash::typestr(pair) << " { " << pair.first << " , " << pair.second << " } "; diff --git a/dash/include/dash/Pattern.h b/dash/include/dash/Pattern.h index a081745b6..79dce5cf7 100644 --- a/dash/include/dash/Pattern.h +++ b/dash/include/dash/Pattern.h @@ -1,5 +1,5 @@ -#ifndef DASH__PATTERN_H_ -#define DASH__PATTERN_H_ +#ifndef DASH__PATTERN_H__INCLUDED +#define DASH__PATTERN_H__INCLUDED #ifdef DOXYGEN @@ -654,4 +654,4 @@ using Pattern = dash::BlockPattern; #include #include -#endif // DASH__PATTERN_H_ +#endif // DASH__PATTERN_H__INCLUDED diff --git a/dash/include/dash/Range.h b/dash/include/dash/Range.h index ceb5fa24a..490f9f4ca 100644 --- a/dash/include/dash/Range.h +++ b/dash/include/dash/Range.h @@ -47,6 +47,7 @@ #include +#include #include @@ -85,18 +86,18 @@ class IteratorRange; * \concept{DashRangeConcept} */ template -constexpr auto begin(const RangeType & range) - -> decltype(range.begin()) { - return range.begin(); +constexpr auto begin(RangeType && range) + -> decltype(std::forward(range).begin()) { + return std::forward(range).begin(); } /** * \concept{DashRangeConcept} */ template -constexpr auto end(const RangeType & range) - -> decltype(range.end()) { - return range.end(); +constexpr auto end(RangeType && range) + -> decltype(std::forward(range).end()) { + return std::forward(range).end(); } /** @@ -104,9 +105,9 @@ constexpr auto end(const RangeType & range) */ template constexpr auto -size(const RangeType & r) - -> decltype(r.size()) { - return r.size(); +size(RangeType && r) + -> decltype(std::forward(r).size()) { + return std::forward(r).size(); } @@ -159,32 +160,46 @@ struct _is_range_type #endif // Test if x.begin() is valid expression and type x::iterator is // defined: - template - static yes has_begin(C *); template static yes has_begin(C *); static no has_begin(...); + template + static yes has_const_begin(C *); + static no has_const_begin(...); + // Test if x.end() is valid expression and type x::iterator is // defined: - template - static yes has_end(C *); template static yes has_end(C *); static no has_end(...); + template + static yes has_const_end(C *); + static no has_const_end(...); + public: enum { value = ( - sizeof(has_begin(static_cast(nullptr))) == sizeof(yes) - && sizeof(has_end(static_cast(nullptr))) == sizeof(yes) + ( sizeof(has_begin(static_cast(nullptr))) + == sizeof(yes) + || sizeof(has_const_begin(static_cast(nullptr))) + == sizeof(yes) ) + && + ( sizeof(has_end(static_cast(nullptr))) + == sizeof(yes) + || sizeof(has_const_end(static_cast(nullptr))) + == sizeof(yes) ) ) }; }; } // namespace detail /** - * Type trait for testing if `dash::begin` and `dash::end` - * are defined. + * Definition of type trait \c dash::is_range + * with static member \c value indicating whether type \c T is a model + * of the Range concept. + * + * Implemented as test if `dash::begin` and `dash::end` are defined. * * In the current implementation, range types must specify the * return type of `dash::begin` and `dash::end` as type @@ -340,8 +355,6 @@ class IteratorRange constexpr const local_type local() const { return local_type( - // dash::local(_begin), - // dash::local(_end) _begin.local(), _end.local() ); @@ -358,8 +371,8 @@ class IteratorRange /** - * Adapter template for range concept, wraps `begin` and `end` iterators - * in range type. + * Specialization of adapter template for range concept, wraps `begin` + * and `end` pointers in range type. */ template < typename LocalIterator, @@ -413,7 +426,7 @@ class IteratorRange /** * Adapter utility function. - * Wraps `begin` and `end` iterators in range type. + * Wraps `begin` and `end` const iterators in range type. */ template constexpr dash::IteratorRange @@ -425,6 +438,10 @@ make_range( end); } +/** + * Adapter utility function. + * Wraps `begin` and `end` pointers in range type. + */ template constexpr dash::IteratorRange make_range( @@ -435,6 +452,10 @@ make_range( end); } +/** + * Adapter utility function. + * Wraps `begin` and `end` iterators in range type. + */ template dash::IteratorRange make_range( diff --git a/dash/include/dash/Shared.h b/dash/include/dash/Shared.h index 6c930a9d2..8547e9690 100644 --- a/dash/include/dash/Shared.h +++ b/dash/include/dash/Shared.h @@ -139,9 +139,7 @@ class Shared { DASH_LOG_DEBUG_VAR("Shared.cget", _owner); DASH_LOG_DEBUG_VAR("Shared.cget", _ptr); DASH_ASSERT(!DART_GPTR_ISNULL(_ptr.dart_gptr())); - const_reference ref = *_ptr; - DASH_LOG_DEBUG_VAR("Shared.cget >", static_cast(ref)); - return ref; + return *_ptr; } /** @@ -153,9 +151,7 @@ class Shared { DASH_LOG_DEBUG_VAR("Shared.get", _owner); DASH_LOG_DEBUG_VAR("Shared.get", _ptr); DASH_ASSERT(!DART_GPTR_ISNULL(_ptr.dart_gptr())); - reference ref = *_ptr; - DASH_LOG_DEBUG_VAR("Shared.get >", static_cast(ref)); - return ref; + return *_ptr; } /** diff --git a/dash/include/dash/TeamSpec.h b/dash/include/dash/TeamSpec.h index a1f150060..be8d1f720 100644 --- a/dash/include/dash/TeamSpec.h +++ b/dash/include/dash/TeamSpec.h @@ -252,8 +252,11 @@ class TeamSpec : // Find best surface-to-volume: auto teamsize_prime_factors = dash::math::factorize(num_units); // Equally distribute factors to extents. - // Start with the largest factors and multiply them onto the lowest value - for (auto it = teamsize_prime_factors.rbegin(); it != teamsize_prime_factors.rend(); ++it) { + // Start with the largest factors and multiply them onto the lowest + // value. + for (auto it = teamsize_prime_factors.rbegin(); + it != teamsize_prime_factors.rend(); + ++it) { DASH_LOG_TRACE("TeamSpec.balance_extents()", "factor:", it->first, "x", it->second); for (auto i = 1; i < it->second + 1; ++i) { @@ -263,7 +266,9 @@ class TeamSpec : } int d = 0; - for (auto it = new_extents.rbegin(); it != new_extents.rend(); ++it, ++d) { + for (auto it = new_extents.rbegin(); + it != new_extents.rend(); + ++it, ++d) { this->_extents[d] = *it; } diff --git a/dash/include/dash/View.h b/dash/include/dash/View.h index 5d322d239..e7b0a845c 100644 --- a/dash/include/dash/View.h +++ b/dash/include/dash/View.h @@ -107,10 +107,6 @@ template < class Sentinel > class IteratorViewOrigin; -// Currently only supporting -// - global iterators -// - 1-dimensional IteratorViewOrigin types. - template < class Iterator, class Sentinel > @@ -120,7 +116,7 @@ struct view_traits > { typedef IteratorViewOrigin image_type; // Uses container::local_type directly, e.g. dash::LocalArrayRef: -//typedef typename dash::view_traits::local_type local_type; + // typedef typename dash::view_traits::local_type local_type; // Uses ViewLocalMod wrapper on domain, e.g. ViewLocalMod: typedef ViewLocalMod local_type; typedef ViewGlobalMod global_type; @@ -138,7 +134,6 @@ struct view_traits > { template < class Iterator, class Sentinel -//class DomainType = dash::IteratorViewOriginOrigin<1> > class IteratorViewOrigin : public dash::IteratorRange diff --git a/dash/include/dash/algorithm/Copy.h b/dash/include/dash/algorithm/Copy.h index 77e85ae9d..368d58ed9 100644 --- a/dash/include/dash/algorithm/Copy.h +++ b/dash/include/dash/algorithm/Copy.h @@ -632,7 +632,7 @@ dash::Future copy_async( GlobInputIt in_last, ValueType * out_first) { - auto & team = in_first.team(); + const auto & team = in_first.team(); dash::util::UnitLocality uloc(team, team.myid()); // Size of L2 data cache line: int l2_line_size = uloc.hwinfo().cache_line_sizes[1]; @@ -843,7 +843,7 @@ ValueType * copy( GlobInputIt in_last, ValueType * out_first) { - auto & team = in_first.team(); + const auto & team = in_first.team(); dash::util::UnitLocality uloc(team, team.myid()); // Size of L2 data cache line: int l2_line_size = uloc.hwinfo().cache_line_sizes[1]; @@ -853,8 +853,8 @@ ValueType * copy( DASH_LOG_TRACE("dash::copy()", "blocking, global to local"); ValueType * dest_first = out_first; - // Return value, initialize with begin of output range, indicating no values - // have been copied: + // Return value, initialize with begin of output range, indicating no + // values have been copied: ValueType * out_last = out_first; // Check if part of the input range is local: DASH_LOG_TRACE_VAR("dash::copy", in_first.dart_gptr()); @@ -866,9 +866,9 @@ ValueType * copy( // Total number of elements to be copied: auto total_copy_elem = in_last - in_first; - // Instead of testing in_first.local() and in_last.local(), this test for a - // local-only range only requires one call to in_first.local() which increases - // throughput by ~10% for local ranges. + // Instead of testing in_first.local() and in_last.local(), this test for + // a local-only range only requires one call to in_first.local() which + // increases throughput by ~10% for local ranges. if (num_local_elem == total_copy_elem) { // Entire input range is local: DASH_LOG_TRACE("dash::copy", "entire input range is local"); diff --git a/dash/include/dash/internal/Macro.h b/dash/include/dash/internal/Macro.h index 8ff011bce..66f43367a 100644 --- a/dash/include/dash/internal/Macro.h +++ b/dash/include/dash/internal/Macro.h @@ -26,4 +26,20 @@ #endif // __ICC #endif // NOINLINE_ATTRIBUTE +#define DASH__DECLTYPE_AUTO_RETURN(...) \ + -> decltype(__VA_ARGS__) \ + { return (__VA_ARGS__); } \ + /**/ + +#define DASH__DECLTYPE_AUTO_RETURN_NOEXCEPT(...) \ + noexcept(noexcept(decltype(__VA_ARGS__)(__VA_ARGS__))) \ + -> decltype(__VA_ARGS__) \ + { return (__VA_ARGS__); } \ + /**/ + +#define DASH__DECLTYPE_NOEXCEPT(...) \ + noexcept(noexcept(decltype(__VA_ARGS__)(__VA_ARGS__))) \ + -> decltype(__VA_ARGS__) \ + /**/ + #endif // DASH__INTERNAL__MACRO_H_ diff --git a/dash/include/dash/internal/StreamConversion.h b/dash/include/dash/internal/StreamConversion.h index 0aafb3988..e65bcd621 100644 --- a/dash/include/dash/internal/StreamConversion.h +++ b/dash/include/dash/internal/StreamConversion.h @@ -2,7 +2,8 @@ #define DASH__INTERNAL__STREAM_CONVERSION_H_ #include -#include + +#include #include @@ -16,6 +17,7 @@ #include #include #include +#include namespace dash { @@ -87,34 +89,43 @@ std::ostream & operator<<( /** * Write range of random access iterators to output stream. */ -template +template < + class Range, + class RangeDType = typename std::decay::type +> auto operator<<( - std::ostream & o, - const Range & range) + std::ostream & o, + Range && range) -> typename std::enable_if< ( // type is range: - dash::is_range::value && + dash::is_range::value && // type is not std::string or derivative: - !std::is_same::value && - !std::is_base_of::value && + !std::is_same::value && + !std::is_base_of::value && // range iterator type is random access: std::is_same< std::random_access_iterator_tag, typename std::iterator_traits< - decltype(dash::begin(range))>::iterator_category + typename std::decay< + decltype(dash::begin(std::forward(range))) + >::type + >::iterator_category >::value ), std::ostream & >::type { - typedef typename Range::value_type value_t; + typedef typename std::iterator_traits::value_type + value_t; + + auto && rng = std::forward(range); std::ostringstream ss; int pos = 0; - ss << dash::internal::typestr(*dash::begin(range)) + ss << dash::typestr(*dash::begin(rng)) << " { "; - for (auto it = dash::begin(range); it != dash::end(range); ++it, ++pos) { + for (auto it = dash::begin(rng); it != dash::end(rng); ++it, ++pos) { ss << static_cast(*it) << " "; } ss << "}"; @@ -124,33 +135,42 @@ auto operator<<( /** * Write range of non-random access iterators to output stream. */ -template +template < + class Range, + class RangeDType = typename std::decay::type +> auto operator<<( - std::ostream & o, - const Range & range) + std::ostream & o, + Range && range) -> typename std::enable_if< ( // type is range: - dash::is_range::value && + dash::is_range::value && // type is not std::string or derivative: - !std::is_same::value && - !std::is_base_of::value && + !std::is_same::value && + !std::is_base_of::value && // range iterator type is not random access: !std::is_same< std::random_access_iterator_tag, typename std::iterator_traits< - decltype(dash::begin(range))>::iterator_category + typename std::decay< + decltype(dash::begin(std::forward(range))) + >::type + >::iterator_category >::value ), std::ostream & >::type { - typedef typename Range::value_type value_t; + typedef typename std::iterator_traits::value_type + value_t; + + auto && rng = std::forward(range); std::ostringstream ss; - ss << dash::internal::typestr(*dash::begin(range)) + ss << dash::typestr(*dash::begin(rng)) << " { "; - for (auto it = dash::begin(range); it != dash::end(range); ++it) { + for (auto it = dash::begin(rng); it != dash::end(rng); ++it) { ss << static_cast(*it) << " "; } ss << "}"; diff --git a/dash/include/dash/internal/TypeInfo.h b/dash/include/dash/internal/TypeInfo.h deleted file mode 100644 index 459fcc1e3..000000000 --- a/dash/include/dash/internal/TypeInfo.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef DASH__INTERNAL__TYPE_INFO_H__INCLUDED -#define DASH__INTERNAL__TYPE_INFO_H__INCLUDED - -#include -#include - -namespace dash { -namespace internal { - -std::string demangle(const char * typeid_name); - -template -std::string typestr(const T & obj) { - return dash::internal::demangle( - typeid(obj).name() - ); -} - -} // namespace internal -} // namespace dash - -#endif // DASH__INTERNAL__TYPE_INFO_H__INCLUDED diff --git a/dash/include/dash/io/hdf5/StorageDriver.h b/dash/include/dash/io/hdf5/StorageDriver.h index 3ad4ae6fc..f8fb859aa 100644 --- a/dash/include/dash/io/hdf5/StorageDriver.h +++ b/dash/include/dash/io/hdf5/StorageDriver.h @@ -470,10 +470,10 @@ class StoreHDF { using index_t = typename pattern_t::index_type; constexpr auto ndim = pattern_t::ndim(); hdf5_hyperslab_spec hs; - auto& ms = hs.memory; - auto& ts = hs.dataset; + auto & ms = hs.memory; + auto & ts = hs.dataset; - auto& lblockspec = pattern.local_blockspec(); + const auto & lblockspec = pattern.local_blockspec(); // get the index of the start block of the current slab // if local space is not empty diff --git a/dash/include/dash/iterator/GlobIter.h b/dash/include/dash/iterator/GlobIter.h index 97f616d0f..3b9768123 100644 --- a/dash/include/dash/iterator/GlobIter.h +++ b/dash/include/dash/iterator/GlobIter.h @@ -195,9 +195,31 @@ class GlobIter /** * Copy constructor. */ - template + template < + class P_, + class GM_, + class Ptr_, + class Ref_ > + constexpr GlobIter( + const GlobIter & other) + : _globmem(other._globmem) + , _pattern(other._pattern) + , _idx (other._idx) + , _max_idx(other._max_idx) + , _myid (other._myid) + , _lbegin (other._lbegin) + { } + + /** + * Move constructor. + */ + template < + class P_, + class GM_, + class Ptr_, + class Ref_ > constexpr GlobIter( - const GlobIterT & other) + GlobIter && other) : _globmem(other._globmem) , _pattern(other._pattern) , _idx (other._idx) @@ -224,6 +246,29 @@ class GlobIter _max_idx = other._max_idx; _myid = other._myid; _lbegin = other._lbegin; + return *this; + } + + /** + * Move-assignment operator. + */ + template < + typename T_, + class P_, + class GM_, + class Ptr_, + class Ref_ > + self_t & operator=( + GlobIter && other) + { + _globmem = other._globmem; + _pattern = other._pattern; + _idx = other._idx; + _max_idx = other._max_idx; + _myid = other._myid; + _lbegin = other._lbegin; + // no ownership to transfer + return *this; } /** @@ -235,6 +280,8 @@ class GlobIter } /** + * TODO: Conversion from iterator to pointer looks dubios + * * Type conversion operator to \c GlobPtr. * * \return A global reference to the element at the iterator's position @@ -264,6 +311,8 @@ class GlobIter } /** + * TODO: Conversion from iterator to pointer looks dubios + * * Type conversion operator to \c GlobPtr. * * \return A global reference to the element at the iterator's position @@ -335,20 +384,9 @@ class GlobIter * * \return A global reference to the element at the iterator's position. */ - reference operator*() + inline reference operator*() { - DASH_LOG_TRACE("GlobIter.*()", _idx); - typedef typename pattern_type::local_index_t - local_pos_t; - index_type idx = _idx; - // Global index to local index and unit: - local_pos_t local_pos = _pattern->local(idx); - DASH_LOG_TRACE("GlobIter.* >", - "unit:", local_pos.unit, "index:", local_pos.index); - // Global reference to element at given position: - return reference( - _globmem->at(local_pos.unit, - local_pos.index)); + return this->operator[](_idx); } /** @@ -356,20 +394,9 @@ class GlobIter * * \return A global reference to the element at the iterator's position. */ - const_reference operator*() const + inline const_reference operator*() const { - DASH_LOG_TRACE("GlobIter.*", _idx); - typedef typename pattern_type::local_index_t - local_pos_t; - index_type idx = _idx; - // Global index to local index and unit: - local_pos_t local_pos = _pattern->local(idx); - DASH_LOG_TRACE_VAR("GlobIter.*", local_pos.unit); - DASH_LOG_TRACE_VAR("GlobIter.*", local_pos.index); - // Global reference to element at given position: - return const_reference( - _globmem->at(local_pos.unit, - local_pos.index)); + return this->operator[](_idx); } /** @@ -380,15 +407,14 @@ class GlobIter /// The global position of the element index_type g_index) { - DASH_LOG_TRACE("GlobIter.[]", g_index); - index_type idx = g_index; typedef typename pattern_type::local_index_t local_pos_t; // Global index to local index and unit: - local_pos_t local_pos = _pattern->local(idx); - DASH_LOG_TRACE_VAR("GlobIter.[]", local_pos.unit); - DASH_LOG_TRACE_VAR("GlobIter.[]", local_pos.index); + local_pos_t local_pos = _pattern->local(g_index); // Global reference to element at given position: + DASH_LOG_TRACE("GlobIter.[]", + "(index:", g_index, ") ->", + "(unit:", local_pos.unit, " index:", local_pos.index, ")"); return reference( _globmem->at(local_pos.unit, local_pos.index)); @@ -402,15 +428,14 @@ class GlobIter /// The global position of the element index_type g_index) const { - DASH_LOG_TRACE("GlobIter.[]", g_index); - index_type idx = g_index; typedef typename pattern_type::local_index_t local_pos_t; // Global index to local index and unit: - local_pos_t local_pos = _pattern->local(idx); - DASH_LOG_TRACE_VAR("GlobIter.[]", local_pos.unit); - DASH_LOG_TRACE_VAR("GlobIter.[]", local_pos.index); + local_pos_t local_pos = _pattern->local(g_index); // Global reference to element at given position: + DASH_LOG_TRACE("GlobIter.[]", + "(index:", g_index, ") ->", + "(unit:", local_pos.unit, " index:", local_pos.index, ")"); return const_reference( _globmem->at(local_pos.unit, local_pos.index)); @@ -427,16 +452,18 @@ class GlobIter /** * Convert global iterator to native pointer. - * - * TODO: Evaluate alternative: - * auto l_idx_this = _container.pattern().local(this->pos()); - * return (l_idx_this.unit == _myid - * ? _lbegin + l_idx_this - * : nullptr - * ); */ local_pointer local() const { + /* + * + * TODO: Evaluate alternative: + * auto l_idx_this = _container.pattern().local(this->pos()); + * return (l_idx_this.unit == _myid + * ? _lbegin + l_idx_this + * : nullptr + * ); + */ DASH_LOG_TRACE_VAR("GlobIter.local=()", _idx); typedef typename pattern_type::local_index_t local_pos_t; diff --git a/dash/include/dash/iterator/GlobViewIter.h b/dash/include/dash/iterator/GlobViewIter.h index 2b1b34db4..2b8c3d714 100644 --- a/dash/include/dash/iterator/GlobViewIter.h +++ b/dash/include/dash/iterator/GlobViewIter.h @@ -18,6 +18,14 @@ namespace dash { #ifndef DOXYGEN // Forward-declaration +template< + typename ElementType, + class PatternType, + class GlobMemType, + class PointerType, + class ReferenceType > +class GlobIter; +// Forward-declaration template< typename ElementType, class PatternType, @@ -35,7 +43,8 @@ class GlobStencilIter; template< typename ElementType, class PatternType, - class GlobMemType = GlobMem, + class GlobMemType + = GlobMem< typename std::remove_const::type >, class PointerType = GlobPtr, class ReferenceType = GlobRef > class GlobViewIter @@ -54,22 +63,44 @@ class GlobViewIter ReferenceType> self_t; + typedef GlobIter< + ElementType, + PatternType, + GlobMemType, + PointerType, + ReferenceType> + global_type; + + typedef GlobIter< + const ElementType, + PatternType, + GlobMemType, + PointerType, + ReferenceType> + const_global_type; + + typedef typename std::remove_const::type + nonconst_value_type; + typedef typename PatternType::viewspec_type ViewSpecType; typedef typename PatternType::index_type IndexType; public: - typedef ElementType value_type; + typedef ElementType value_type; - typedef ReferenceType reference; - typedef typename reference::const_type const_reference; + typedef ReferenceType reference; + typedef typename ReferenceType::const_type const_reference; - typedef PointerType pointer; - typedef typename pointer::const_type const_pointer; + typedef PointerType pointer; + typedef typename PointerType::const_type const_pointer; - typedef PatternType pattern_type; - typedef IndexType index_type; + typedef typename GlobMemType::local_pointer local_pointer; + typedef typename GlobMemType::local_pointer local_type; + + typedef PatternType pattern_type; + typedef typename PatternType::index_type index_type; private: typedef GlobViewIter< @@ -141,105 +172,120 @@ class GlobViewIter /// Unit id of the active unit team_unit_t _myid; /// Pointer to first element in local memory - ElementType * _lbegin = nullptr; + local_pointer _lbegin = nullptr; public: /** * Default constructor. */ - GlobViewIter() - : _globmem(nullptr), - _pattern(nullptr), - _viewspec(nullptr), - _idx(0), - _view_idx_offset(0), - _max_idx(0), - _myid(dash::Team::GlobalUnitID()), - _lbegin(nullptr) - { - DASH_LOG_TRACE_VAR("GlobViewIter()", _idx); - DASH_LOG_TRACE_VAR("GlobViewIter()", _max_idx); - } + constexpr GlobViewIter() + : _globmem(nullptr) + , _pattern(nullptr) + , _viewspec(nullptr) + , _idx(0) + , _view_idx_offset(0) + , _max_idx(0) + , _myid(dash::Team::All().myid()) + , _lbegin(nullptr) + { } /** * Constructor, creates a global iterator on global memory following * the element order specified by the given pattern and view spec. */ - template - GlobViewIter( - GlobMemType_ * gmem, + template + constexpr GlobViewIter( + GlobMemT_ * gmem, const PatternType & pat, const ViewSpecType & viewspec, IndexType position = 0, IndexType view_index_offset = 0) - : _globmem(reinterpret_cast(gmem)), - _pattern(&pat), - _viewspec(&viewspec), - _idx(position), - _view_idx_offset(view_index_offset), - _max_idx(viewspec.size() - 1), - _myid(dash::Team::GlobalUnitID()), - _lbegin(_globmem->lbegin()) - { - DASH_LOG_TRACE_VAR("GlobViewIter(gmem,pat,vs,idx,abs)", _idx); - DASH_LOG_TRACE_VAR("GlobViewIter(gmem,pat,vs,idx,abs)", _max_idx); - DASH_LOG_TRACE_VAR("GlobViewIter(gmem,pat,vs,idx,abs)", *_viewspec); - DASH_LOG_TRACE_VAR("GlobViewIter(gmem,pat,vs,idx,abs)", _view_idx_offset); - } + : _globmem(reinterpret_cast(gmem)) + , _pattern(&pat) + , _viewspec(&viewspec) + , _idx(position) + , _view_idx_offset(view_index_offset) + , _max_idx(viewspec.size() - 1) + , _myid(pat.team().myid()) + , _lbegin(_globmem->lbegin()) + { } /** * Constructor, creates a global iterator on global memory following * the element order specified by the given pattern and view spec. */ - template - GlobViewIter( - GlobMemType_ * gmem, + template + constexpr GlobViewIter( + GlobMemT_ * gmem, const PatternType & pat, IndexType position = 0, IndexType view_index_offset = 0) - : _globmem(reinterpret_cast(gmem)), - _pattern(&pat), - _viewspec(nullptr), - _idx(position), - _view_idx_offset(view_index_offset), - _max_idx(pat.size() - 1), - _myid(dash::Team::GlobalUnitID()), - _lbegin(_globmem->lbegin()) - { - DASH_LOG_TRACE_VAR("GlobViewIter(gmem,pat,idx,abs)", _idx); - DASH_LOG_TRACE_VAR("GlobViewIter(gmem,pat,idx,abs)", _max_idx); - DASH_LOG_TRACE_VAR("GlobViewIter(gmem,pat,idx,abs)", _view_idx_offset); - } + : _globmem(reinterpret_cast(gmem)) + , _pattern(&pat) + , _viewspec(nullptr) + , _idx(position) + , _view_idx_offset(view_index_offset) + , _max_idx(pat.size() - 1) + , _myid(dash::Team::GlobalUnitID()) + , _lbegin(_globmem->lbegin()) + { } /** * Constructor, creates a global view iterator from a global iterator. */ - template - GlobViewIter( - const GlobIter & other, - const ViewSpecType & viewspec, - IndexType view_idx_offset = 0) - : _globmem(other._globmem), - _pattern(other._pattern), - _viewspec(&viewspec), - _idx(other._idx), - _view_idx_offset(view_idx_offset), - _max_idx(other._max_idx), - _myid(other._myid), - _lbegin(other._lbegin) - { - DASH_LOG_TRACE_VAR("GlobViewIter(GlobIter)", _idx); - DASH_LOG_TRACE_VAR("GlobViewIter(GlobIter)", _max_idx); - DASH_LOG_TRACE_VAR("GlobViewIter(GlobIter)", *_viewspec); - DASH_LOG_TRACE_VAR("GlobViewIter(GlobIter)", _view_idx_offset); - } + template < + class P_, + class GM_, + class Ptr_, + class Ref_ > + constexpr GlobViewIter( + const GlobIter & other, + const ViewSpecType & viewspec, + IndexType view_offs = 0) + : _globmem(other._globmem) + , _pattern(other._pattern) + , _viewspec(&viewspec) + , _idx(other._idx) + , _view_idx_offset(view_offs) + , _max_idx(other._max_idx) + , _myid(other._myid) + , _lbegin(other._lbegin) + { } /** * Copy constructor. */ - template - GlobViewIter( - const GlobViewIterT & other) + template < + typename T_, + class P_, + class GM_, + class Ptr_, + class Ref_ > + constexpr GlobViewIter( +// const GlobViewIter & other) + const GlobViewIter & other) + : _globmem (other._globmem) + , _pattern (other._pattern) + , _viewspec (other._viewspec) + , _idx (other._idx) + , _view_idx_offset(other._view_idx_offset) + , _max_idx (other._max_idx) + , _myid (other._myid) + , _lbegin (other._lbegin) + { } + + /** + * Move constructor. + */ + template < + typename T_, + class P_, + class GM_, + class Ptr_, + class Ref_ > + constexpr GlobViewIter( +// GlobViewIter && other) + GlobViewIter && other) : _globmem (other._globmem) , _pattern (other._pattern) , _viewspec (other._viewspec) @@ -272,6 +318,30 @@ class GlobViewIter _lbegin = other._lbegin; } + /** + * Move-assignment operator. + */ + template < + typename T_, + class P_, + class GM_, + class Ptr_, + class Ref_ > + self_t & operator=( + GlobViewIter && other) + { + _globmem = other._globmem; + _pattern = other._pattern; + _viewspec = other._viewspec; + _idx = other._idx; + _view_idx_offset = other._view_idx_offset; + _max_idx = other._max_idx; + _myid = other._myid; + _lbegin = other._lbegin; + // no ownership to transfer + return *this; + } + /** * The number of dimensions of the iterator's underlying pattern. */ @@ -285,7 +355,49 @@ class GlobViewIter * * \return A global reference to the element at the iterator's position */ - operator pointer() const + explicit operator const_pointer() const + { + DASH_LOG_TRACE_VAR("GlobViewIter.GlobPtr()", _idx); + typedef typename pattern_type::local_index_t + local_pos_t; + IndexType idx = _idx; + IndexType offset = 0; + DASH_LOG_TRACE_VAR("GlobViewIter.GlobPtr", _max_idx); + // Convert iterator position (_idx) to local index and unit. + if (_idx > _max_idx) { + // Global iterator pointing past the range indexed by the pattern + // which is the case for .end() iterators. + idx = _max_idx; + offset += _idx - _max_idx; + } + DASH_LOG_TRACE_VAR("GlobViewIter.GlobPtr", idx); + DASH_LOG_TRACE_VAR("GlobViewIter.GlobPtr", offset); + // Global index to local index and unit: + local_pos_t local_pos; + if (_viewspec == nullptr) { + // No viewspec mapping required: + local_pos = _pattern->local(idx); + } else { + // Viewspec projection required: + auto glob_coords = coords(idx); + local_pos = _pattern->local_index(glob_coords); + } + DASH_LOG_TRACE_VAR("GlobViewIter.GlobPtr >", local_pos.unit); + DASH_LOG_TRACE_VAR("GlobViewIter.GlobPtr >", local_pos.index + offset); + // Create global pointer from unit and local offset: + const_pointer gptr( + _globmem->at(local_pos.unit, local_pos.index) + ); + gptr += offset; + return gptr; + } + + /** + * Type conversion operator to \c GlobPtr. + * + * \return A global reference to the element at the iterator's position + */ + explicit operator pointer() { DASH_LOG_TRACE_VAR("GlobViewIter.GlobPtr()", _idx); typedef typename pattern_type::local_index_t @@ -315,7 +427,7 @@ class GlobViewIter DASH_LOG_TRACE_VAR("GlobViewIter.GlobPtr >", local_pos.unit); DASH_LOG_TRACE_VAR("GlobViewIter.GlobPtr >", local_pos.index + offset); // Create global pointer from unit and local offset: - PointerType gptr( + pointer gptr( _globmem->at(local_pos.unit, local_pos.index) ); gptr += offset; @@ -360,7 +472,7 @@ class GlobViewIter "unit:", local_pos.unit, "local index:", local_pos.index); // Global pointer to element at given position: - dash::GlobPtr gptr( + const_pointer gptr( _globmem->at( local_pos.unit, local_pos.index) @@ -374,26 +486,46 @@ class GlobViewIter * * \return A global reference to the element at the iterator's position. */ - reference operator*() const + inline reference operator*() + { + return this->operator[](_idx); + } + + /** + * Dereference operator. + * + * \return A global reference to the element at the iterator's position. + */ + inline const_reference operator*() const + { + return this->operator[](_idx); + } + + /** + * Subscript operator, returns global reference to element at given + * global index. + */ + reference operator[]( + /// The global position of the element + index_type g_index) { - DASH_LOG_TRACE("GlobViewIter.*", _idx, _view_idx_offset); typedef typename pattern_type::local_index_t local_pos_t; - IndexType idx = _idx; // Global index to local index and unit: local_pos_t local_pos; if (_viewspec == nullptr) { // No viewspec mapping required: - local_pos = _pattern->local(idx); + local_pos = _pattern->local(g_index); } else { // Viewspec projection required: - auto glob_coords = coords(idx); + auto glob_coords = coords(g_index); local_pos = _pattern->local_index(glob_coords); } - DASH_LOG_TRACE_VAR("GlobViewIter.*", local_pos.unit); - DASH_LOG_TRACE_VAR("GlobViewIter.*", local_pos.index); + DASH_LOG_TRACE("GlobViewIter.[]", + "(index:", g_index, " voffset:", _view_idx_offset, ") ->", + "(unit:", local_pos.unit, " index:", local_pos.index, ")"); // Global reference to element at given position: - return ReferenceType( + return reference( _globmem->at(local_pos.unit, local_pos.index)); } @@ -402,28 +534,27 @@ class GlobViewIter * Subscript operator, returns global reference to element at given * global index. */ - reference operator[]( + const_reference operator[]( /// The global position of the element index_type g_index) const { - DASH_LOG_TRACE("GlobViewIter.[]", g_index, _view_idx_offset); - IndexType idx = g_index; typedef typename pattern_type::local_index_t local_pos_t; // Global index to local index and unit: local_pos_t local_pos; if (_viewspec == nullptr) { // No viewspec mapping required: - local_pos = _pattern->local(idx); + local_pos = _pattern->local(g_index); } else { // Viewspec projection required: - auto glob_coords = coords(idx); + auto glob_coords = coords(g_index); local_pos = _pattern->local_index(glob_coords); } - DASH_LOG_TRACE_VAR("GlobViewIter.[]", local_pos.unit); - DASH_LOG_TRACE_VAR("GlobViewIter.[]", local_pos.index); + DASH_LOG_TRACE("GlobViewIter.[]", + "(index:", g_index, " voffset:", _view_idx_offset, ") ->", + "(unit:", local_pos.unit, " index:", local_pos.index, ")"); // Global reference to element at given position: - return ReferenceType( + return const_reference( _globmem->at(local_pos.unit, local_pos.index)); } @@ -440,7 +571,7 @@ class GlobViewIter /** * Convert global iterator to native pointer. */ - ElementType * local() const + local_pointer local() const { DASH_LOG_TRACE_VAR("GlobViewIter.local=()", _idx); typedef typename pattern_type::local_index_t @@ -481,24 +612,34 @@ class GlobViewIter /** * Map iterator to global index domain by projecting the iterator's view. */ - inline GlobIter global() const + inline const_global_type global() const { auto g_idx = gpos(); - return dash::GlobIter( + return const_global_type( _globmem, *_pattern, g_idx ); } + /** + * Map iterator to global index domain by projecting the iterator's view. + */ + inline global_type global() + { + return global_type( + _globmem, + *_pattern, + gpos() + ); + } + /** * Position of the iterator in its view's iteration space and the view's * offset in global index space. */ - inline index_type pos() const + constexpr index_type pos() const noexcept { - DASH_LOG_TRACE("GlobViewIter.pos()", - "idx:", _idx, "vs_offset:", _view_idx_offset); return _idx + _view_idx_offset; } @@ -506,7 +647,7 @@ class GlobViewIter * Position of the iterator in its view's iteration space, disregarding * the view's offset in global index space. */ - inline index_type rpos() const + inline index_type rpos() const noexcept { return _idx; } @@ -608,7 +749,7 @@ class GlobViewIter * The instance of \c GlobMem used by this iterator to resolve addresses * in global memory. */ - constexpr const GlobMemType & globmem() const + constexpr const GlobMemType & globmem() const noexcept { return *_globmem; } @@ -617,7 +758,7 @@ class GlobViewIter * The instance of \c GlobMem used by this iterator to resolve addresses * in global memory. */ - inline GlobMemType & globmem() + inline GlobMemType & globmem() noexcept { return *_globmem; } @@ -625,7 +766,7 @@ class GlobViewIter /** * Prefix increment operator. */ - self_t & operator++() + self_t & operator++() noexcept { ++_idx; return *this; @@ -634,7 +775,7 @@ class GlobViewIter /** * Postfix increment operator. */ - self_t operator++(int) + self_t operator++(int) noexcept { self_t result = *this; ++_idx; @@ -644,7 +785,7 @@ class GlobViewIter /** * Prefix decrement operator. */ - self_t & operator--() + self_t & operator--() noexcept { --_idx; return *this; @@ -653,26 +794,26 @@ class GlobViewIter /** * Postfix decrement operator. */ - self_t operator--(int) + self_t operator--(int) noexcept { self_t result = *this; --_idx; return result; } - self_t & operator+=(index_type n) + self_t & operator+=(index_type n) noexcept { _idx += n; return *this; } - self_t & operator-=(index_type n) + self_t & operator-=(index_type n) noexcept { _idx -= n; return *this; } - self_t operator+(index_type n) const + self_t operator+(index_type n) const noexcept { if (_viewspec == nullptr) { self_t res( @@ -691,7 +832,7 @@ class GlobViewIter return res; } - self_t operator-(index_type n) const + self_t operator-(index_type n) const noexcept { if (_viewspec == nullptr) { self_t res( @@ -711,7 +852,7 @@ class GlobViewIter } index_type operator+( - const self_t & other) const + const self_t & other) const noexcept { return _idx + other._idx; } @@ -722,7 +863,7 @@ class GlobViewIter return _idx - other._idx; } - inline bool operator<(const self_t & other) const + inline bool operator<(const self_t & other) const noexcept { // NOTE: // This function call is significantly slower than the explicit @@ -732,7 +873,7 @@ class GlobViewIter std::less()); } - inline bool operator<=(const self_t & other) const + inline bool operator<=(const self_t & other) const noexcept { // NOTE: // This function call is significantly slower than the explicit @@ -742,7 +883,7 @@ class GlobViewIter std::less_equal()); } - inline bool operator>(const self_t & other) const + inline bool operator>(const self_t & other) const noexcept { // NOTE: // This function call is significantly slower than the explicit @@ -752,7 +893,7 @@ class GlobViewIter std::greater()); } - inline bool operator>=(const self_t & other) const + inline bool operator>=(const self_t & other) const noexcept { // NOTE: // This function call is significantly slower than the explicit @@ -762,7 +903,7 @@ class GlobViewIter std::greater_equal()); } - inline bool operator==(const self_t & other) const + inline bool operator==(const self_t & other) const noexcept { // NOTE: See comments in method compare(). if (_viewspec == other._viewspec) { @@ -780,7 +921,7 @@ class GlobViewIter lhs_local.index == rhs_local.index); } - inline bool operator!=(const self_t & other) const + inline bool operator!=(const self_t & other) const noexcept { // NOTE: See comments in method compare(). if (_viewspec == other._viewspec) { @@ -798,12 +939,12 @@ class GlobViewIter lhs_local.index != rhs_local.index); } - inline const PatternType & pattern() const + constexpr const PatternType & pattern() const noexcept { return *_pattern; } - inline dash::Team & team() const + constexpr dash::Team & team() const noexcept { return _pattern->team(); } @@ -819,7 +960,7 @@ class GlobViewIter bool compare( const self_t & other, const GlobIndexCmpFun & gidx_cmp, - const GlobPtrCmpFun & gptr_cmp) const + const GlobPtrCmpFun & gptr_cmp) const noexcept { #if __REMARK__ // Usually this is a best practice check, but it's an infrequent case @@ -860,7 +1001,9 @@ class GlobViewIter * Convert a global offset within the global iterator's range to * corresponding global coordinates with respect to viewspec projection. * - * NOTE: + * This method is bounds-checked and might throw. + * + * \note * This method could be specialized for NumDimensions = 1 for performance * tuning. */ diff --git a/dash/include/dash/util/internal/IteratorBase.h b/dash/include/dash/iterator/internal/IteratorBase.h similarity index 85% rename from dash/include/dash/util/internal/IteratorBase.h rename to dash/include/dash/iterator/internal/IteratorBase.h index 6cbd227d7..1abe61b36 100644 --- a/dash/include/dash/util/internal/IteratorBase.h +++ b/dash/include/dash/iterator/internal/IteratorBase.h @@ -1,5 +1,5 @@ -#ifndef DASH__UTIL__INTERNAL__ITERATOR_BASE_H__INCLUDED -#define DASH__UTIL__INTERNAL__ITERATOR_BASE_H__INCLUDED +#ifndef DASH__ITERATOR__INTERNAL__ITERATOR_BASE_H__INCLUDED +#define DASH__ITERATOR__INTERNAL__ITERATOR_BASE_H__INCLUDED #include @@ -15,7 +15,14 @@ template < class IndexType = dash::default_index_t, class Pointer = ValueType *, class Reference = ValueType & > -class IndexIteratorBase { +class IndexIteratorBase +: public std::iterator< + std::random_access_iterator_tag, + ValueType, + IndexType, + Pointer, + Reference > +{ typedef IndexIteratorBase< IteratorType, ValueType, @@ -61,6 +68,10 @@ class IndexIteratorBase { return _pos; } + constexpr index_type gpos() const { + return _pos; + } + constexpr reference operator*() const { return derived().dereference(_pos); } @@ -69,6 +80,10 @@ class IndexIteratorBase { return derived().dereference(_pos); } + constexpr reference operator[](int pos) const { + return derived().dereference(pos); + } + derived_t & operator++() { _pos++; return derived(); @@ -132,7 +147,6 @@ class IndexIteratorBase { } // namespace detail - } // namespace dash -#endif // DASH__UTIL__INTERNAL__ITERATOR_BASE_H__INCLUDED +#endif // DASH__ITERATOR__INTERNAL__ITERATOR_BASE_H__INCLUDED diff --git a/dash/include/dash/map/UnorderedMap.h b/dash/include/dash/map/UnorderedMap.h index c58fbd73c..4b4dae851 100644 --- a/dash/include/dash/map/UnorderedMap.h +++ b/dash/include/dash/map/UnorderedMap.h @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -78,18 +79,10 @@ template< std::pair > > class UnorderedMap { - /** - * The Cray compiler (as of CCE8.5.6) does not support - * std::is_trivially_copyable. - * - * TODO: Remove the guard once this has been fixed by Cray. - */ -#ifndef __CRAYC - static_assert(std::is_trivially_copyable::value, - "Element type must be trivially copyable"); - static_assert(std::is_trivially_copyable::value, - "Element type must be trivially copyable"); -#endif + static_assert( + dash::is_container_compatible::value && + dash::is_container_compatible::value, + "Type not supported for DASH containers"); template friend class UnorderedMapLocalRef; diff --git a/dash/include/dash/matrix/LocalMatrixRef.h b/dash/include/dash/matrix/LocalMatrixRef.h index caa121dca..d82fe9e86 100644 --- a/dash/include/dash/matrix/LocalMatrixRef.h +++ b/dash/include/dash/matrix/LocalMatrixRef.h @@ -47,10 +47,10 @@ class LocalMatrixRef; */ template < typename T, - dim_t NumDimensions, - dim_t CUR = NumDimensions, - class PatternT = - TilePattern > + dim_t NumDimensions, + dim_t CUR = NumDimensions, + class PatternT = + TilePattern > class LocalMatrixRef { private: @@ -71,15 +71,15 @@ class LocalMatrixRef public: template< typename T_, - dim_t NumDimensions_, + dim_t NumDimensions_, typename IndexT_, - class PatternT_ > + class PatternT_ > friend class Matrix; template< typename T_, - dim_t NumDimensions1, - dim_t NumDimensions2, - class PatternT_ > + dim_t NumDimensions1, + dim_t NumDimensions2, + class PatternT_ > friend class LocalMatrixRef; public: @@ -108,7 +108,7 @@ class LocalMatrixRef typedef self_t local_type; template - using view_type = + using ViewT = LocalMatrixRef; public: @@ -351,8 +351,19 @@ class LocalMatrixRef friend class LocalMatrixRef; public: - typedef typename PatternT::index_type index_type; - typedef typename PatternT::size_type size_type; + typedef self_t local_type; + typedef PatternT pattern_type; + + typedef typename PatternT::index_type index_type; + typedef typename PatternT::size_type size_type; + + public: + typedef std::integral_constant + rank; + + static constexpr dim_t ndim() { + return 1; + } public: /** diff --git a/dash/include/dash/matrix/internal/LocalMatrixRef-inl.h b/dash/include/dash/matrix/internal/LocalMatrixRef-inl.h index ba0146dbd..ff5310ca3 100644 --- a/dash/include/dash/matrix/internal/LocalMatrixRef-inl.h +++ b/dash/include/dash/matrix/internal/LocalMatrixRef-inl.h @@ -1,4 +1,4 @@ -#ifndef DASH__MATRIX__INTERNAL__LOCAL_MATRIX_REF_INL_H_INCLUDED + #ifndef DASH__MATRIX__INTERNAL__LOCAL_MATRIX_REF_INL_H_INCLUDED #define DASH__MATRIX__INTERNAL__LOCAL_MATRIX_REF_INL_H_INCLUDED #include @@ -83,7 +83,7 @@ ::block( // Local view of local block: auto l_block_l_view = pattern.local_block_local(block_lindex); // Return a view specified by the block's viewspec: - view_type view; + ViewT view; view._refview = MatrixRefView_t(_refview._mat); view._refview._viewspec = l_block_g_view; view._refview._l_viewspec = l_block_l_view; @@ -115,7 +115,7 @@ ::block( // Local view of local block: auto l_block_l_view = pattern.local_block_local(block_lindex); // Return a view specified by the block's viewspec: - view_type view; + ViewT view; view._refview = MatrixRefView_t(_refview._mat); view._refview._viewspec = l_block_g_view; view._refview._l_viewspec = l_block_l_view; diff --git a/dash/include/dash/meta/TypeInfo.h b/dash/include/dash/meta/TypeInfo.h new file mode 100644 index 000000000..b0e2bb5e8 --- /dev/null +++ b/dash/include/dash/meta/TypeInfo.h @@ -0,0 +1,41 @@ +#ifndef DASH__META__TYPE_INFO_H__INCLUDED +#define DASH__META__TYPE_INFO_H__INCLUDED + +#include +#include + +namespace dash { + +namespace internal { + std::string demangle(const char * typeid_name); +} + +/** + * Returns string containing the type name of the given object. + * + * Similar to the `typeid` operator but ensures human-readable, demangled + * format. + */ +template +std::string typestr(const T & obj) { + return dash::internal::demangle( + typeid(obj).name() + ); +} + +/** + * Returns string containing the name of the specified type. + * + * Similar to the `typeid` operator but ensures human-readable, demangled + * format. + */ +template +std::string typestr() { + return dash::internal::demangle( + typeid(T).name() + ); +} + +} // namespace dash + +#endif // DASH__META__TYPE_INFO_H__INCLUDED diff --git a/dash/include/dash/pattern/BlockPattern.h b/dash/include/dash/pattern/BlockPattern.h index 20f8a83b2..fda2620fe 100644 --- a/dash/include/dash/pattern/BlockPattern.h +++ b/dash/include/dash/pattern/BlockPattern.h @@ -1017,6 +1017,36 @@ class BlockPattern return block_idx; } + /** + * Unit and local block index at given global coordinates. + * + * \see DashPatternConcept + */ + local_index_t local_block_at( + /// Global coordinates of element + const std::array & g_coords) const + { + local_index_t l_pos; + + std::array l_block_coords; + std::array unit_ts_coords; + for (dim_t d = 0; d < NumDimensions; ++d) { + auto nunits_d = _teamspec.extent(d); + auto blocksize_d = _blocksize_spec.extent(d); + auto block_coord_d = g_coords[d] / blocksize_d; + l_block_coords[d] = block_coord_d / nunits_d; + unit_ts_coords[d] = block_coord_d % nunits_d; + } + l_pos.unit = _teamspec.at(unit_ts_coords); + l_pos.index = _local_blockspec.at(l_block_coords); + + DASH_LOG_TRACE("BlockPattern.local_block_at >", + "coords", g_coords, + "unit:", l_pos.unit, + "local block index:", l_pos.index); + return l_pos; + } + /** * View spec (offset and extents) of block at global linear block index in * cartesian element space. diff --git a/dash/include/dash/pattern/BlockPattern1D.h b/dash/include/dash/pattern/BlockPattern1D.h index 4e2755fec..83116acb6 100644 --- a/dash/include/dash/pattern/BlockPattern1D.h +++ b/dash/include/dash/pattern/BlockPattern1D.h @@ -572,7 +572,8 @@ class BlockPattern<1, Arrangement, IndexType> * \see DashPatternConcept */ constexpr std::array local_coords( - const std::array & global_coords) const { + const std::array & global_coords + ) const noexcept { return std::array {{ static_cast( (((global_coords[0] / _blocksize) / _nunits) * _blocksize) @@ -775,13 +776,13 @@ class BlockPattern<1, Arrangement, IndexType> /** * Cartesian arrangement of local pattern blocks. */ - const BlockSpec_t local_blockspec() const + constexpr BlockSpec_t local_blockspec() const { return BlockSpec_t({ _nlblocks }); } /** - * Index of block at given global coordinates. + * Gobal index of block at given global coordinates. * * \see DashPatternConcept */ @@ -790,6 +791,24 @@ class BlockPattern<1, Arrangement, IndexType> const std::array & g_coords) const { return g_coords[0] / _blocksize; } + + /** + * Local index of block at given global coordinates. + * + * \see DashPatternConcept + */ + constexpr local_index_t local_block_at( + /// Global coordinates of element + const std::array & g_coords) const { + return local_index_t { + // unit id: + static_cast( + (g_coords[0] / _blocksize) % _teamspec.size()), + // local block index: + static_cast( + (g_coords[0] / _blocksize) / _teamspec.size()) + }; + } /** * View spec (offset and extents) of block at global linear block index in @@ -799,7 +818,6 @@ class BlockPattern<1, Arrangement, IndexType> /// Global block index index_type g_block_index) const { -#if 1 return ViewSpec_t( {{ static_cast(g_block_index * _blocksize) }}, {{ static_cast( @@ -808,16 +826,6 @@ class BlockPattern<1, Arrangement, IndexType> : underfilled_blocksize(0) ) ) }} ); -#else - index_type offset = g_block_index * _size; - std::array offsets = {{ offset }}; - std::array extents = {{ _blocksize }}; - if(g_block_index == (_nblocks - 1)){ - extents[0] -= underfilled_blocksize(0); - } - ViewSpec_t block_vs(offsets, extents); - return block_vs; -#endif } /** @@ -828,7 +836,6 @@ class BlockPattern<1, Arrangement, IndexType> /// Local block index index_type l_block_index) const { -#if 1 // Local block index to local block coords: return ViewSpec_t( {{ static_cast( global(l_block_index * _blocksize) ) }}, @@ -840,18 +847,6 @@ class BlockPattern<1, Arrangement, IndexType> : _blocksize ) ) }} ); -#else - auto l_elem_index = l_block_index * _blocksize; - auto g_elem_index = global(l_elem_index); - std::array offsets = {{ g_elem_index }}; - std::array extents = {{ _blocksize }}; - if(l_block_index == (_nlblocks - 1)) { - size_type remaining = _local_size % extents[0]; - extents[0] = (remaining == 0) ? extents[0] : remaining; - } - ViewSpec_t block_vs(offsets, extents); - return block_vs; -#endif } /** @@ -939,7 +934,7 @@ class BlockPattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - constexpr SizeType local_size() const + constexpr SizeType local_size() const noexcept { return _local_size; } @@ -949,7 +944,7 @@ class BlockPattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - constexpr IndexType num_units() const { + constexpr IndexType num_units() const noexcept { return _nunits; } @@ -958,7 +953,7 @@ class BlockPattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - constexpr IndexType capacity() const { + constexpr IndexType capacity() const noexcept { return _size; } @@ -967,7 +962,7 @@ class BlockPattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - constexpr IndexType size() const { + constexpr IndexType size() const noexcept { return _size; } @@ -975,14 +970,14 @@ class BlockPattern<1, Arrangement, IndexType> * The Team containing the units to which this pattern's elements are * mapped. */ - constexpr dash::Team & team() const { + constexpr dash::Team & team() const noexcept { return *_team; } /** * Distribution specification of this pattern. */ - constexpr const DistributionSpec_t & distspec() const { + constexpr const DistributionSpec_t & distspec() const noexcept { return _distspec; } @@ -1070,16 +1065,6 @@ class BlockPattern<1, Arrangement, IndexType> ? 0 : _blocksize - (_size % _blocksize) ); -#if 0 - auto ovf_blocksize = (_blocksize == 0) - ? 0 - : _size % _blocksize; - if (ovf_blocksize == 0) { - return 0; - } else { - return _blocksize - ovf_blocksize; - } -#endif } private: @@ -1209,41 +1194,6 @@ class BlockPattern<1, Arrangement, IndexType> ) ); -#if 0 - if (_nunits == 0) { - return 0; - } - // Coordinates of local unit id in team spec: - SizeType l_extent = 0; - // Minimum number of blocks local to every unit in dimension: - auto min_local_blocks = _nblocks / _nunits; - // Possibly there are more blocks than units in dimension and no - // block left for this unit. Local extent in d then becomes 0. - l_extent = min_local_blocks * _blocksize; - if (_nblocks == 1 && _nunits == 1) { - // One block assigned to one unit, use full extent in dimension: - l_extent = _size; - } else { - // Number of additional blocks for this unit, if any: - IndexType num_add_blocks = static_cast( - _nblocks % _nunits); - // Unit id assigned to the last block in dimension: - team_unit_t last_block_unit(((_nblocks % _nunits == 0) - ? _nunits - 1 - : (_nblocks % _nunits) - 1)); - if (unit < num_add_blocks) { - // Unit is assigned to an additional block: - l_extent += _blocksize; - } - if (unit == last_block_unit) { - // If the last block in the dimension is underfilled and - // assigned to the local unit, subtract the missing extent: - SizeType undfill_blocksize = underfilled_blocksize(0); - l_extent -= undfill_blocksize; - } - } - return l_extent; -#endif } }; diff --git a/dash/include/dash/pattern/MakePattern.h b/dash/include/dash/pattern/MakePattern.h index 845fee560..34eeb1c26 100644 --- a/dash/include/dash/pattern/MakePattern.h +++ b/dash/include/dash/pattern/MakePattern.h @@ -27,7 +27,7 @@ template< typename LayoutTags, class SizeSpecType > -TeamSpec +TeamSpec make_team_spec( /// Size spec of cartesian space to be distributed by the pattern. const SizeSpecType & sizespec, @@ -40,7 +40,7 @@ make_team_spec( typedef typename SizeSpecType::index_type index_t; // Deduce number of dimensions from size spec: - const dim_t ndim = SizeSpecType::ndim(); + const dim_t ndim = SizeSpecType::ndim::value; // Default team spec: std::array team_extents; @@ -181,7 +181,7 @@ template< typename LayoutTags, class SizeSpecType > -TeamSpec +TeamSpec make_team_spec( /// Size spec of cartesian space to be distributed by the pattern. const SizeSpecType & sizespec, @@ -242,7 +242,7 @@ template< class SizeSpecType, class TeamSpecType > -DistributionSpec +DistributionSpec make_distribution_spec( /// Size spec of cartesian space to be distributed by the pattern. const SizeSpecType & sizespec, @@ -253,7 +253,7 @@ make_distribution_spec( DASH_LOG_TRACE("dash::make_distribution_spec()"); // Deduce number of dimensions from size spec: - const dim_t ndim = SizeSpecType::ndim(); + const dim_t ndim = SizeSpecType::ndim::value; // Array of distribution specifiers in all dimensions, // e.g. { TILE(10), TILE(120) }: std::array distributions = {{ }}; @@ -261,7 +261,7 @@ make_distribution_spec( if (PartitioningTags::minimal) { // Find minimal block size in minimal partitioning, initialize with // pattern size (maximum): - for (auto d = 0; d < SizeSpecType::ndim(); ++d) { + for (auto d = 0; d < SizeSpecType::ndim::value; ++d) { auto extent_d = sizespec.extent(d); auto nunits_d = teamspec.extent(d); auto blocksize_d = extent_d / nunits_d; @@ -274,7 +274,7 @@ make_distribution_spec( min_block_extent); } // Resolve balanced tile extents from size spec and team spec: - for (auto d = 0; d < SizeSpecType::ndim(); ++d) { + for (auto d = 0; d < SizeSpecType::ndim::value; ++d) { auto extent_d = sizespec.extent(d); auto nunits_d = teamspec.extent(d); DASH_LOG_TRACE("dash::make_distribution_spec", @@ -366,7 +366,7 @@ typename std::enable_if< PartitioningTags::balanced && !PartitioningTags::unbalanced && LayoutTags::blocked, - TilePattern >::type @@ -377,7 +377,7 @@ make_pattern( const TeamSpecType & teamspec) { // Deduce number of dimensions from size spec: - const dim_t ndim = SizeSpecType::ndim(); + const dim_t ndim = SizeSpecType::ndim::value; // Deduce index type from size spec: typedef typename SizeSpecType::index_type index_t; typedef dash::TilePattern pattern_t; @@ -431,8 +431,8 @@ typename std::enable_if< MappingTags::diagonal && (LayoutTags::blocked || (PartitioningTags::balanced && - SizeSpecType::ndim() == 1)), - ShiftTilePattern >::type @@ -443,7 +443,7 @@ make_pattern( const TeamSpecType & teamspec) { // Deduce number of dimensions from size spec: - const dim_t ndim = SizeSpecType::ndim(); + const dim_t ndim = SizeSpecType::ndim::value; // Deduce index type from size spec: typedef typename SizeSpecType::index_type index_t; typedef dash::ShiftTilePattern pattern_t; @@ -490,7 +490,7 @@ template< > typename std::enable_if< LayoutTags::canonical, - BlockPattern >::type @@ -501,7 +501,7 @@ make_pattern( const TeamSpecType & teamspec) { // Deduce number of dimensions from size spec: - const dim_t ndim = SizeSpecType::ndim(); + const dim_t ndim = SizeSpecType::ndim::value; // Deduce index type from size spec: typedef typename SizeSpecType::index_type index_t; typedef dash::BlockPattern pattern_t; diff --git a/dash/include/dash/pattern/PatternProperties.h b/dash/include/dash/pattern/PatternProperties.h index 2564385d5..44e704e42 100644 --- a/dash/include/dash/pattern/PatternProperties.h +++ b/dash/include/dash/pattern/PatternProperties.h @@ -780,12 +780,22 @@ struct pattern_traits index_type; typedef typename PatternType::size_type size_type; + typedef typename dash::pattern_partitioning_traits::type partitioning; typedef typename dash::pattern_mapping_traits::type mapping; typedef typename dash::pattern_layout_traits::type layout; + + typedef typename std::decay< + decltype(std::declval().blockspec()) + >::type + blockspec_type; + typedef typename std::decay< + decltype(std::declval().local_blockspec()) + >::type + local_blockspec_type; }; ////////////////////////////////////////////////////////////////////////////// diff --git a/dash/include/dash/pattern/PatternTraits.h b/dash/include/dash/pattern/PatternTraits.h index 0bbd19427..628340ff2 100644 --- a/dash/include/dash/pattern/PatternTraits.h +++ b/dash/include/dash/pattern/PatternTraits.h @@ -162,7 +162,7 @@ struct pattern_partitioning_spec template struct pattern_partitioning_spec { - typedef + typedef ... }; #endif diff --git a/dash/include/dash/pattern/ShiftTilePattern.h b/dash/include/dash/pattern/ShiftTilePattern.h index 9cb1b6fdf..534a2ec26 100644 --- a/dash/include/dash/pattern/ShiftTilePattern.h +++ b/dash/include/dash/pattern/ShiftTilePattern.h @@ -1175,6 +1175,20 @@ class ShiftTilePattern return block_idx; } + /** + * Unit and local block index at given global coordinates. + * + * \see DashPatternConcept + */ + local_index_t local_block_at( + /// Global coordinates of element + const std::array & g_coords) const + { + DASH_THROW( + dash::exception::NotImplemented, + "ShiftTilePattern.local_block_at is not implemented"); + } + /** * View spec (offset and extents) of block at global linear block index in * global cartesian element space. diff --git a/dash/include/dash/pattern/TilePattern.h b/dash/include/dash/pattern/TilePattern.h index 962261e5c..78282c1c8 100644 --- a/dash/include/dash/pattern/TilePattern.h +++ b/dash/include/dash/pattern/TilePattern.h @@ -122,7 +122,7 @@ class TilePattern /// Team containing the units to which the patterns element are mapped dash::Team * _team = nullptr; /// The active unit's id. - team_unit_t _myid; + team_unit_t _myid; /// Cartesian arrangement of units within the team TeamSpec_t _teamspec; /// The global layout of the pattern's elements in memory respective to @@ -381,12 +381,15 @@ class TilePattern : TilePattern(static_cast(other)) { } + /** + * Assignment operator. + */ + TilePattern & operator=(const self_t & other) = default; + /** * Equality comparison operator. */ - bool operator==( - /// TilePattern instance to compare for equality - const self_t & other) const + bool operator==(const self_t & other) const { if (this == &other) { return true; @@ -406,42 +409,19 @@ class TilePattern /** * Inquality comparison operator. */ - bool operator!=( + constexpr bool operator!=( /// TilePattern instance to compare for inequality const self_t & other) const { return !(*this == other); } - /** - * Assignment operator. - */ - TilePattern & operator=(const TilePattern & other) - { - if (this != &other) { - _distspec = other._distspec; - _team = other._team; - _myid = other._myid; - _teamspec = other._teamspec; - _memory_layout = other._memory_layout; - _nunits = other._nunits; - _blocksize_spec = other._blocksize_spec; - _blockspec = other._blockspec; - _local_blockspec = other._local_blockspec; - _local_memory_layout = other._local_memory_layout; - _local_capacity = other._local_capacity; - _lbegin = other._lbegin; - _lend = other._lend; - } - return *this; - } - /** * Resolves the global index of the first local element in the pattern. * * \see DashPatternConcept */ - IndexType lbegin() const { + constexpr IndexType lbegin() const { return _lbegin; } @@ -450,7 +430,7 @@ class TilePattern * * \see DashPatternConcept */ - IndexType lend() const { + constexpr IndexType lend() const { return _lend; } @@ -601,16 +581,13 @@ class TilePattern * * \see DashPatternConcept */ - std::array local_extents( + constexpr std::array local_extents( team_unit_t unit = UNDEFINED_TEAM_UNIT_ID) const { - if (unit == UNDEFINED_TEAM_UNIT_ID) { - unit = _myid; - } - if (unit == _myid) { - return _local_memory_layout.extents(); - } - return initialize_local_extents(unit); + return ( ( unit == UNDEFINED_TEAM_UNIT_ID || + unit == _myid ) + ? _local_memory_layout.extents() + : initialize_local_extents(unit) ); } //////////////////////////////////////////////////////////////////////// @@ -645,13 +622,19 @@ class TilePattern block_coords_l[d] = vs_coord_d / block_size_d; } DASH_LOG_TRACE("TilePattern.local_at", - "local_coords:", local_coords, - "view:", viewspec, - "local blocks:", _local_blockspec.extents(), - "local block coords:", block_coords_l, + "local_coords:", local_coords); + DASH_LOG_TRACE("TilePattern.local_at", + "view:", viewspec); + DASH_LOG_TRACE("TilePattern.local_at", + "local blocks:", _local_blockspec.extents()); + DASH_LOG_TRACE("TilePattern.local_at", + "local block coords:", block_coords_l); + DASH_LOG_TRACE("TilePattern.local_at", "phase coords:", phase_coords); // Number of blocks preceeding the coordinates' block: auto block_offset_l = _local_blockspec.at(block_coords_l); + DASH_LOG_TRACE("TilePattern.local_at", + "local block offset:", block_offset_l); auto local_index = block_offset_l * _blocksize_spec.size() + // preceeding blocks _blocksize_spec.at(phase_coords); // element phase @@ -730,10 +713,9 @@ class TilePattern * * \see DashPatternConcept */ - local_index_t local( + constexpr local_index_t local( IndexType g_index) const { - DASH_LOG_TRACE_VAR("TilePattern.local()", g_index); // TODO: Implement dedicated method for this, conversion to/from // global coordinates is expensive. return local_index(coords(g_index)); @@ -851,7 +833,7 @@ class TilePattern * * \see DashPatternConcept */ - std::array global( + constexpr std::array global( const std::array & local_coords) const { return global(_myid, local_coords); } @@ -1161,7 +1143,7 @@ class TilePattern * * \see DashPatternConcept */ - bool is_local( + constexpr bool is_local( IndexType index) const { return is_local(index, _myid); @@ -1285,7 +1267,7 @@ class TilePattern * * \see DashPatternConcept */ - ViewSpec_t local_block( + constexpr ViewSpec_t local_block( index_type local_block_index) const { return local_block(_myid, local_block_index); @@ -1354,7 +1336,7 @@ class TilePattern /** * Cartesian arrangement of pattern blocks. */ - const BlockSpec_t & blockspec() const + constexpr const BlockSpec_t & blockspec() const { return _blockspec; } @@ -1362,7 +1344,7 @@ class TilePattern /** * Cartesian arrangement of pattern blocks. */ - const BlockSpec_t & local_blockspec() const + constexpr const BlockSpec_t & local_blockspec() const { return _local_blockspec; } @@ -1374,7 +1356,7 @@ class TilePattern * * \see DashPatternConcept */ - SizeType blocksize( + constexpr SizeType blocksize( /// The dimension in the pattern dim_t dimension) const { @@ -1389,7 +1371,7 @@ class TilePattern * * \see DashPatternConcept */ - SizeType max_blocksize() const { + constexpr SizeType max_blocksize() const { return _blocksize_spec.size(); } @@ -1399,7 +1381,8 @@ class TilePattern * * \see DashPatternConcept */ - SizeType local_capacity(team_unit_t unit = UNDEFINED_TEAM_UNIT_ID) const { + constexpr SizeType local_capacity( + team_unit_t unit = UNDEFINED_TEAM_UNIT_ID) const { return local_size(); } @@ -1427,7 +1410,7 @@ class TilePattern * * \see DashPatternConcept */ - IndexType num_units() const { + constexpr IndexType num_units() const { return _teamspec.size(); } @@ -1436,7 +1419,7 @@ class TilePattern * * \see DashPatternConcept */ - IndexType capacity() const { + constexpr IndexType capacity() const { return _memory_layout.size(); } @@ -1445,7 +1428,7 @@ class TilePattern * * \see DashPatternConcept */ - IndexType size() const { + constexpr IndexType size() const { return _memory_layout.size(); } @@ -1453,14 +1436,14 @@ class TilePattern * The Team containing the units to which this pattern's elements are * mapped. */ - dash::Team & team() const { + constexpr dash::Team & team() const { return *_team; } /** * Distribution specification of this pattern. */ - const DistributionSpec_t & distspec() const { + constexpr const DistributionSpec_t & distspec() const { return _distspec; } @@ -1469,16 +1452,16 @@ class TilePattern * * \see DashPatternConcept */ - SizeSpec_t sizespec() const { + constexpr SizeSpec_t sizespec() const { return SizeSpec_t(_memory_layout.extents()); } /** - * Size specification of the index space mapped by this pattern. + * Size specification (shape) of the index space mapped by this pattern. * * \see DashPatternConcept */ - const std::array & extents() const { + constexpr const std::array & extents() const { return _memory_layout.extents(); } @@ -1488,7 +1471,7 @@ class TilePattern * * \see DashPatternConcept */ - const MemoryLayout_t & memory_layout() const { + constexpr const MemoryLayout_t & memory_layout() const { return _memory_layout; } @@ -1497,7 +1480,7 @@ class TilePattern * of this pattern for the calling unit. * Not part of DASH Pattern concept. */ - const LocalMemoryLayout_t & local_memory_layout() const { + constexpr const LocalMemoryLayout_t & local_memory_layout() const { return _local_memory_layout; } @@ -1507,7 +1490,7 @@ class TilePattern * * \see DashPatternConcept */ - const TeamSpec_t & teamspec() const { + constexpr const TeamSpec_t & teamspec() const { return _teamspec; } @@ -1517,7 +1500,7 @@ class TilePattern * * \see DashPatternConcept */ - std::array coords( + constexpr std::array coords( IndexType index) const { return _memory_layout.coords(index); } @@ -1546,7 +1529,10 @@ class TilePattern const SizeSpec_t & sizespec, const DistributionSpec_t & distspec, const TeamSpec_t & teamspec) const { - DASH_LOG_TRACE("TilePattern.init_blocksizespec()"); + DASH_LOG_TRACE("TilePattern.init_blocksizespec()", + "sizespec:", sizespec.extents(), + "distspec:", distspec.values(), + "teamspec:", teamspec.extents()); // Extents of a single block: std::array s_blocks; if (sizespec.size() == 0 || teamspec.size() == 0) { diff --git a/dash/include/dash/pattern/TilePattern1D.h b/dash/include/dash/pattern/TilePattern1D.h index c82fdd437..79ee429ff 100644 --- a/dash/include/dash/pattern/TilePattern1D.h +++ b/dash/include/dash/pattern/TilePattern1D.h @@ -95,11 +95,11 @@ class TilePattern<1, Arrangement, IndexType> typedef SizeType size_type; typedef ViewSpec_t viewspec_type; typedef struct { - team_unit_t unit; - IndexType index; + team_unit_t unit; + IndexType index; } local_index_t; typedef struct { - team_unit_t unit; + team_unit_t unit; std::array coords; } local_coords_t; @@ -328,25 +328,7 @@ class TilePattern<1, Arrangement, IndexType> /** * Copy constructor. */ - TilePattern(const self_t & other) - : _size(other._size), - _memory_layout(other._memory_layout), - _distspec(other._distspec), - _team(other._team), - _teamspec(other._teamspec), - _nunits(other._nunits), - _blocksize(other._blocksize), - _nblocks(other._nblocks), - _local_size(other._local_size), - _local_memory_layout(other._local_memory_layout), - _nlblocks(other._nlblocks), - _local_capacity(other._local_capacity), - _lbegin(other._lbegin), - _lend(other._lend) { - // No need to copy _arguments as it is just used to - // initialize other members. - DASH_LOG_TRACE("TilePattern<1>(other)", "TilePattern copied"); - } + constexpr TilePattern(const self_t & other) = default; /** * Copy constructor using non-const lvalue reference parameter. @@ -354,7 +336,7 @@ class TilePattern<1, Arrangement, IndexType> * Introduced so variadic constructor is not a better match for * copy-construction. */ - TilePattern(self_t & other) + constexpr TilePattern(self_t & other) : TilePattern(static_cast(other)) { } @@ -393,34 +375,14 @@ class TilePattern<1, Arrangement, IndexType> /** * Assignment operator. */ - self_t & operator=(const self_t & other) { - DASH_LOG_TRACE("TilePattern<1>.=(other)"); - if (this != &other) { - _size = other._size; - _memory_layout = other._memory_layout; - _distspec = other._distspec; - _team = other._team; - _teamspec = other._teamspec; - _local_size = other._local_size; - _local_memory_layout = other._local_memory_layout; - _blocksize = other._blocksize; - _nblocks = other._nblocks; - _nlblocks = other._nlblocks; - _local_capacity = other._local_capacity; - _nunits = other._nunits; - _lbegin = other._lbegin; - _lend = other._lend; - DASH_LOG_TRACE("TilePattern<1>.=(other)", "TilePattern assigned"); - } - return *this; - } + self_t & operator=(const self_t & other) = default; /** * Resolves the global index of the first local element in the pattern. * * \see DashPatternConcept */ - IndexType lbegin() const { + constexpr IndexType lbegin() const { return _lbegin; } @@ -429,7 +391,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - IndexType lend() const { + constexpr IndexType lend() const { return _lend; } @@ -492,14 +454,11 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - team_unit_t unit_at( + constexpr team_unit_t unit_at( /// Global linear element offset IndexType global_pos ) const { - DASH_LOG_TRACE_VAR("TilePattern<1>.unit_at()", global_pos); - team_unit_t unit_id((global_pos / _blocksize) % _nunits); - DASH_LOG_TRACE_VAR("TilePattern<1>.unit_at >", unit_id); - return unit_id; + return team_unit_t((global_pos / _blocksize) % _nunits); } //////////////////////////////////////////////////////////////////////////// @@ -515,11 +474,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - IndexType extent(dim_t dim) const { - DASH_ASSERT_EQ( - 0, dim, - "Wrong dimension for TilePattern<1>::local_extent. " << - "Expected dimension = 0, got " << dim); + constexpr IndexType extent(dim_t dim) const { return _size; } @@ -534,11 +489,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - IndexType local_extent(dim_t dim) const { - DASH_ASSERT_EQ( - 0, dim, - "Wrong dimension for TilePattern<1>::local_extent. " << - "Expected dimension = 0, got " << dim); + constexpr IndexType local_extent(dim_t dim) const { return _local_size; } @@ -553,10 +504,8 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - std::array local_extents( + constexpr std::array local_extents( team_unit_t unit = UNDEFINED_TEAM_UNIT_ID) const { - DASH_LOG_DEBUG_VAR("TilePattern<1>.local_extents()", unit); - DASH_LOG_DEBUG_VAR("TilePattern<1>.local_extents >", _local_size); return std::array {{ _local_size }}; } @@ -570,7 +519,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - IndexType local_at( + constexpr IndexType local_at( /// Point in local memory const std::array & local_coords, /// View specification (offsets) to apply on \c coords @@ -583,7 +532,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - IndexType local_at( + constexpr IndexType local_at( /// Point in local memory const std::array & local_coords) const { return local_coords[0]; @@ -593,22 +542,22 @@ class TilePattern<1, Arrangement, IndexType> * Converts global coordinates to their associated unit and its respective * local coordinates. * - * TODO: Unoptimized + * \todo Unoptimized * * \see DashPatternConcept */ - local_coords_t local( + constexpr local_coords_t local( const std::array & global_coords) const { - local_coords_t l_coords; - l_coords.coords = local_coords(global_coords); - l_coords.unit = unit_at(global_coords); - return l_coords; + return local_coords_t {{ + unit_at(global_coords), + local_coords(global_coords) + }}; } /** * Converts global index to its associated unit and respective local index. * - * TODO: Unoptimized + * \todo Unoptimized * * \see DashPatternConcept */ @@ -705,7 +654,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - std::array global( + constexpr std::array global( const std::array & l_coords) const { return global(_team->myid(), l_coords); } @@ -718,7 +667,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - IndexType global( + constexpr IndexType global( team_unit_t unit, IndexType l_index) const { return global(unit, std::array {{ l_index }})[0]; @@ -732,7 +681,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - IndexType global( + constexpr IndexType global( IndexType l_index) const { return global(_team->myid(), std::array {{ l_index }})[0]; } @@ -745,11 +694,10 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - IndexType global_index( + constexpr IndexType global_index( team_unit_t unit, const std::array & l_coords) const { - auto g_index = global(unit, l_coords[0]); - return g_index; + return global(unit, l_coords[0]); } //////////////////////////////////////////////////////////////////////////// @@ -764,7 +712,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - IndexType at( + constexpr IndexType at( const std::array & g_coords) const { return local_coords(g_coords)[0]; } @@ -792,14 +740,13 @@ class TilePattern<1, Arrangement, IndexType> * \see DashPatternConcept */ template - IndexType at(IndexType value, Values ... values) const { + constexpr IndexType at(IndexType value, Values ... values) const { static_assert( sizeof...(values) == NumDimensions-1, "Wrong parameter number"); - std::array inputindex = { - value, (IndexType)values... - }; - return at(inputindex); + return at(std::array {{ + value, (IndexType)values... + }} ); } //////////////////////////////////////////////////////////////////////////// @@ -840,12 +787,10 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - bool is_local( + constexpr bool is_local( IndexType index, team_unit_t unit) const { - auto coords_unit = unit_at(index); - DASH_LOG_TRACE_VAR("TilePattern<1>.is_local >", (coords_unit == unit)); - return coords_unit == unit; + return unit_at(index) == unit; } /** @@ -854,7 +799,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - bool is_local( + constexpr bool is_local( IndexType index) const { return is_local(index, team().myid()); } @@ -866,9 +811,8 @@ class TilePattern<1, Arrangement, IndexType> /** * Cartesian arrangement of pattern blocks. */ - BlockSpec_t blockspec() const { - BlockSpec_t bspec({ dash::math::div_ceil(_size, _blocksize) }); - return bspec; + constexpr BlockSpec_t blockspec() const { + return BlockSpec_t({ dash::math::div_ceil(_size, _blocksize) }); } /** @@ -876,15 +820,29 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - index_type block_at( + constexpr index_type block_at( /// Global coordinates of element const std::array & g_coords) const { - index_type block_idx = g_coords[0] / _blocksize; - DASH_LOG_TRACE("TilePattern<1>.block_at", - "coords", g_coords, - "> block index", block_idx); - return block_idx; + return g_coords[0] / _blocksize; + } + + /** + * Local index of block at given global coordinates. + * + * \see DashPatternConcept + */ + constexpr local_index_t local_block_at( + /// Global coordinates of element + const std::array & g_coords) const { + return local_index_t { + // unit id: + static_cast( + (g_coords[0] / _blocksize) % _teamspec.size()), + // local block index: + static_cast( + (g_coords[0] / _blocksize) / _teamspec.size()) + }; } /** @@ -941,7 +899,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - SizeType blocksize( + constexpr SizeType blocksize( /// The dimension in the pattern dim_t dimension) const { return _blocksize; @@ -955,7 +913,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - SizeType max_blocksize() const { + constexpr SizeType max_blocksize() const { return _blocksize; } @@ -1021,7 +979,7 @@ class TilePattern<1, Arrangement, IndexType> /** * Distribution specification of this pattern. */ - const DistributionSpec_t & distspec() const { + constexpr const DistributionSpec_t & distspec() const { return _distspec; } @@ -1030,7 +988,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - SizeSpec_t sizespec() const { + constexpr SizeSpec_t sizespec() const { return SizeSpec_t(std::array {{ _size }}); } @@ -1039,7 +997,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - const std::array extents() const { + constexpr const std::array extents() const { return std::array {{ _size }}; } @@ -1049,7 +1007,7 @@ class TilePattern<1, Arrangement, IndexType> * * \see DashPatternConcept */ - const MemoryLayout_t & memory_layout() const { + constexpr const MemoryLayout_t & memory_layout() const { return _memory_layout; } @@ -1058,7 +1016,7 @@ class TilePattern<1, Arrangement, IndexType> * of this pattern for the calling unit. * Not part of DASH Pattern concept. */ - const LocalMemoryLayout_t & local_memory_layout() const { + constexpr const LocalMemoryLayout_t & local_memory_layout() const { return _local_memory_layout; } diff --git a/dash/include/dash/util/FunctionalExpr.h b/dash/include/dash/util/FunctionalExpr.h index b14aa1f6a..f32dd7b37 100644 --- a/dash/include/dash/util/FunctionalExpr.h +++ b/dash/include/dash/util/FunctionalExpr.h @@ -63,17 +63,18 @@ template ///< binary reduce operation constexpr T accumulate( const std::array &arr, ///< array to accumulate - const size_t first, ///< start index for accumulation - const size_t length, ///< number of values to accumulate + const size_t first_idx, ///< start index for accumulation + const size_t final_idx, ///< index past last element to accumulate const T initialValue, ///< initial accumulation value const ReduceOp & op ///< binary operation ) { - return (first < (first + length)) - ? op(arr[first], + return (first_idx < final_idx) + ? op(arr[first_idx], dash::ce::accumulate( arr, - first + 1, length - 1, - initialValue, op)) + first_idx + 1, final_idx, + initialValue, + op)) : initialValue; } diff --git a/dash/include/dash/util/LocalityDomain.h b/dash/include/dash/util/LocalityDomain.h index 9708c9cef..5c7d58be5 100644 --- a/dash/include/dash/util/LocalityDomain.h +++ b/dash/include/dash/util/LocalityDomain.h @@ -157,21 +157,44 @@ class LocalityDomain typedef LocalityDomain self_t; typedef dash::util::Locality::Scope Scope_t; -private: - public: - typedef internal::LocalityDomainIterator iterator; typedef internal::LocalityDomainIterator const_iterator; private: - LocalityDomain( const self_t & parent, dart_domain_locality_t * domain); -public: +private: + /// Underlying \c dart_domain_locality_t object. + dart_domain_locality_t * _domain = nullptr; + /// Copy of _domain->domain_tag to avoid string copying. + std::string _domain_tag = "."; + /// Cache of lazy-loaded subdomains, mapped by subdomain relative index. + /// Must be heap-allocated as type is incomplete due to type definition + /// cycle. + mutable std::unordered_map * _subdomains = nullptr; + /// Units in the domain. + std::vector _unit_ids; +#if 0 + /// Locality descriptors of units in the domain. Only specified in root + /// locality domain and resolved from parent in upward recursion otherwise. + std::unordered_map _unit_localities; +#endif + /// Iterator to the first subdomain. + iterator _begin; + /// Iterator past the last subdomain. + iterator _end; + /// Whether this instance is owner of _domain. + bool _is_owner = false; + /// Domain tags of groups in the locality domain. + std::vector _groups; + std::vector _group_domain_tags; + /// Split domains in the team locality, one domain for every split group. + std::vector _parts; +public: LocalityDomain() = default; explicit LocalityDomain( @@ -195,8 +218,7 @@ class LocalityDomain self_t && other); inline bool operator==( - const self_t & rhs) const - { + const self_t & rhs) const { return ( (_domain == rhs._domain) || ( (_domain != nullptr && @@ -209,8 +231,7 @@ class LocalityDomain } inline bool operator!=( - const self_t & rhs) const - { + const self_t & rhs) const { return !(*this == rhs); } @@ -477,34 +498,6 @@ class LocalityDomain } } -private: - /// Underlying \c dart_domain_locality_t object. - dart_domain_locality_t * _domain = nullptr; - /// Copy of _domain->domain_tag to avoid string copying. - std::string _domain_tag; - /// Cache of lazy-loaded subdomains, mapped by subdomain relative index. - /// Must be heap-allocated as type is incomplete due to type definition - /// cycle. - mutable std::unordered_map * _subdomains = nullptr; - /// Units in the domain. - std::vector _unit_ids; -#if 0 - /// Locality descriptors of units in the domain. Only specified in root - /// locality domain and resolved from parent in upward recursion otherwise. - std::unordered_map _unit_localities; -#endif - /// Iterator to the first subdomain. - iterator _begin; - /// Iterator past the last subdomain. - iterator _end; - /// Whether this instance is owner of _domain. - bool _is_owner = false; - /// Domain tags of groups in the locality domain. - std::vector _groups; - std::vector _group_domain_tags; - /// Split domains in the team locality, one domain for every split group. - std::vector _parts; - }; // class LocalityDomain std::ostream & operator<<( diff --git a/dash/include/dash/util/UnitLocality.h b/dash/include/dash/util/UnitLocality.h index c8f6fda60..54c9cd4d8 100644 --- a/dash/include/dash/util/UnitLocality.h +++ b/dash/include/dash/util/UnitLocality.h @@ -35,8 +35,8 @@ class UnitLocality public: UnitLocality( - dash::Team & team, - team_unit_t unit) + const dash::Team & team, + team_unit_t unit) : _team(&team) { DASH_ASSERT_RETURNS( @@ -98,7 +98,7 @@ class UnitLocality return *_unit_domain; } - inline dash::Team & team() + inline const dash::Team & team() { if (nullptr == _team) { return dash::Team::Null(); @@ -326,7 +326,7 @@ class UnitLocality private: - dash::Team * _team = nullptr; + const dash::Team * _team = nullptr; dart_unit_locality_t * _unit_locality = nullptr; dart_domain_locality_t * _unit_domain = nullptr; dash::util::LocalityDomain _node_domain; diff --git a/dash/include/dash/util/UniversalMember.h b/dash/include/dash/util/UniversalMember.h index 3679e90c5..fcf3e9970 100644 --- a/dash/include/dash/util/UniversalMember.h +++ b/dash/include/dash/util/UniversalMember.h @@ -50,15 +50,26 @@ template class UniversalMember { typedef UniversalMember self_t; + // References related to reference / temporary binding: + // + // - `shared_view` in range-v3, seems similar top the `std::shared_ptr` + // variant: + // https://github.com/ericniebler/range-v3/pull/557/files + // + // - `common_reference` proposal: + // http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0022r2.html + // + // - ref-qualified member functions: + // http://kukuruku.co/hub/cpp/ref-qualified-member-functions std::shared_ptr _value; public: - UniversalMember() = delete; + UniversalMember() = default; - constexpr UniversalMember(self_t && other) = default; - constexpr UniversalMember(const self_t & other) = default; - - self_t & operator=(const self_t & other) = default; - self_t & operator=(self_t && other) = default; +// constexpr UniversalMember(self_t && other) = default; +// constexpr UniversalMember(const self_t & other) = delete; +// +// self_t & operator=(const self_t & other) = delete; +// self_t & operator=(self_t && other) = default; constexpr explicit UniversalMember(ValueType && value) : _value(std::make_shared(std::move(value))) @@ -75,6 +86,10 @@ class UniversalMember { *(_value.get()) = std::forward(value); return *this; } + + constexpr const std::shared_ptr & shared() const { + return _value; + } }; } // namespace dash diff --git a/dash/include/dash/view/Domain.h b/dash/include/dash/view/Domain.h index 3ae3435d0..cb790a8c3 100644 --- a/dash/include/dash/view/Domain.h +++ b/dash/include/dash/view/Domain.h @@ -18,17 +18,26 @@ namespace dash { */ template < class ViewT, - typename ViewValueT = - typename std::remove_const< - typename std::remove_reference::type - >::type -> + typename ViewValueT = typename std::decay::type > constexpr auto domain(ViewT && view) -> typename std::enable_if< - dash::view_traits::is_view::value, - // const typename dash::view_traits::domain_type & + // dash::view_traits::is_view::value, + dash::detail::has_type_domain_type::value, + decltype(std::forward(view).domain()) + >::type { + return std::forward(view).domain(); +} + +template +constexpr auto +domain(const ViewT & view) + -> typename std::enable_if< + dash::detail::has_type_domain_type::value, + // dash::view_traits::is_view::value, decltype(view.domain()) + // const typename dash::view_traits::domain_type & + // const typename ViewT::domain_type & >::type { return view.domain(); } @@ -40,9 +49,28 @@ domain(ViewT && view) * * \concept{DashViewConcept} */ -template +template < + class ContainerT, + typename ContainerValueT = typename std::decay::type > +constexpr typename std::enable_if< +//!dash::view_traits::is_view::value, + !dash::detail::has_type_domain_type::value, + ContainerT & +>::type +domain(ContainerT & container) { + return container; +} + +/** + * + * \concept{DashViewConcept} + */ +template < + class ContainerT, + typename ContainerValueT = typename std::decay::type > constexpr typename std::enable_if< - !dash::view_traits::is_view::value, +//!dash::view_traits::is_view::value, + !dash::detail::has_type_domain_type::value, const ContainerT & >::type domain(const ContainerT & container) { diff --git a/dash/include/dash/view/IndexSet.h b/dash/include/dash/view/IndexSet.h index f933133fd..1911e0770 100644 --- a/dash/include/dash/view/IndexSet.h +++ b/dash/include/dash/view/IndexSet.h @@ -13,7 +13,11 @@ #include -#include +#include +#include +#include + +#include #include @@ -50,42 +54,49 @@ using global_index_t // Forward-declarations -template +template class IndexSetBase; -template +template class IndexSetIdentity; -template +template class IndexSetLocal; -template +template class IndexSetGlobal; -template +template class IndexSetSub; -template +// ----------------------------------------------------------------------- +// dash::index +// ----------------------------------------------------------------------- + +template < + class DomainType, + class DomainDecayType = typename std::decay::type > constexpr auto -index(const ViewType & v) --> typename std::enable_if< - dash::view_traits::is_view::value, -// decltype(v.index_set()) - const typename ViewType::index_set_type - >::type { - return v.index_set(); +index(DomainType && v) + -> typename std::enable_if< + dash::view_traits::is_view::value, + decltype(std::forward(v).index_set()) + >::type { + return std::forward(v).index_set(); } -template +template < + class DomainType, + class DomainDecayType = typename std::decay::type > constexpr auto -index(const ContainerType & c) --> typename std::enable_if < - dash::view_traits::is_origin::value, - IndexSetIdentity - >::type { - return IndexSetIdentity(c); +index(const DomainType & v) + -> typename std::enable_if< + dash::view_traits::is_view::value, + decltype(v.index_set()) + >::type { + return v.index_set(); } @@ -140,19 +151,31 @@ class IndexSetIterator constexpr index_type dereference(index_type idx) const { return (idx * _stride) < dash::size(*_index_set) ? (*_index_set)[idx * _stride] - : ((*_index_set)[dash::size(*_index_set)-1] - + ((idx * _stride) - (dash::size(*_index_set) - 1)) + : ((*_index_set)[_index_set->size() - 1] + + ((idx * _stride) - (_index_set->size() - 1)) ); } }; } // namespace detail + +template < + class ContainerType, + class ContainerDecayType = typename std::decay::type > +constexpr auto +index(const ContainerType & c) +-> typename std::enable_if < + !dash::view_traits::is_view::value, + const IndexSetIdentity + >::type { + return IndexSetIdentity(c); +} + // ----------------------------------------------------------------------- // IndexSetBase // ----------------------------------------------------------------------- - /* NOTE: Local and global mappings of index sets should be implemented * without IndexSet member functions like this: * @@ -165,58 +188,72 @@ class IndexSetIterator * */ - template < - class IndexSetType, - class ViewType, + class IndexSetType, + class DomainType, std::size_t NDim > constexpr auto local( - const IndexSetBase & index_set) + const IndexSetBase & index_set) // -> decltype(index_set.local()) { -// -> typename view_traits>::global_type & { - -> const IndexSetLocal & { +// -> typename view_traits>::global_type & { + -> const IndexSetLocal & { return index_set.local(); } template < - class IndexSetType, - class ViewType, + class IndexSetType, + class DomainType, std::size_t NDim > constexpr auto global( - const IndexSetBase & index_set) + const IndexSetBase & index_set) // -> decltype(index_set.global()) { -// -> typename view_traits>::global_type & { - -> const IndexSetGlobal & { +// -> typename view_traits>::global_type & { + -> const IndexSetGlobal & { return index_set.global(); } + +namespace detail { + +template +struct index_set_domain_bind_t { + typedef typename + std::conditional< dash::is_view::value, + DomainT, + const DomainT & >::type + type; +}; + +} // namespace detail + /** * \concept{DashRangeConcept} */ template < - class IndexSetType, - class ViewType, - std::size_t NDim = ViewType::rank::value > + class IndexSetType, + class DomainType, + std::size_t NDim = DomainType::rank::value > class IndexSetBase { - typedef IndexSetBase self_t; + typedef IndexSetBase self_t; + + typedef typename std::decay::type DomainValueT; + public: - typedef typename ViewType::index_type - index_type; - typedef typename dash::view_traits::origin_type - origin_type; - typedef typename dash::view_traits::domain_type + typedef typename dash::view_traits::origin_type + view_origin_type; + typedef DomainValueT view_domain_type; - typedef typename ViewType::local_type + typedef typename DomainValueT::local_type view_local_type; - typedef typename dash::view_traits::global_type + typedef typename dash::view_traits::global_type view_global_type; - typedef typename dash::view_traits::index_set_type - index_set_domain_type; - typedef typename origin_type::pattern_type + typedef typename view_traits::index_set_type + domain_type; + typedef typename view_traits::pattern_type pattern_type; typedef typename dash::view_traits::index_set_type local_type; @@ -225,27 +262,78 @@ class IndexSetBase typedef detail::IndexSetIterator iterator; + typedef detail::IndexSetIterator + const_iterator; + typedef typename DomainType::size_type + size_type; + typedef typename DomainType::index_type + index_type; typedef index_type value_type; + typedef typename detail::index_set_domain_bind_t::type + domain_member_type; + typedef std::integral_constant rank; + static constexpr std::size_t ndim() { return NDim; } + protected: - const ViewType & _view; - const pattern_type & _pattern; + domain_member_type _domain; + const pattern_type * _pattern; - IndexSetType & derived() { - return static_cast(*this); - } constexpr const IndexSetType & derived() const { return static_cast(*this); } - constexpr explicit IndexSetBase(const ViewType & view) - : _view(view) - , _pattern(dash::origin(view).pattern()) + constexpr explicit IndexSetBase(const DomainType & domain) + : _domain(domain) + , _pattern(&dash::origin(domain).pattern()) + { } + + constexpr explicit IndexSetBase(DomainType && domain) + : _domain(std::forward(domain)) + , _pattern(&dash::origin(view_domain()).pattern()) { } + + typedef struct { + index_type begin; + index_type end; + } index_range_t; + + static constexpr index_range_t index_range_intersect( + const index_range_t & a, + const index_range_t & b) noexcept { + return index_range_t { + std::max(a.begin, b.begin), + std::min(a.end, b.end) + }; + } + static constexpr index_type index_range_size( + const index_range_t & irng) noexcept { + return irng.end - irng.begin; + } + + template + static constexpr index_range_t index_range_g2l( + const PatternT_ & pat, + const index_range_t & grng) noexcept { + return index_range_t { + pat.local_coords({{ grng.begin }})[0], + pat.local_coords({{ grng.end }})[0] + }; + } + + template + static constexpr index_range_t index_range_l2g( + const PatternT_ & pat, + const index_range_t & lrng) noexcept { + return index_range_t { + pat.global(lrng.begin), + pat.global(lrng.end) + }; + } ~IndexSetBase() = default; public: @@ -255,57 +343,122 @@ class IndexSetBase self_t & operator=(self_t &&) = default; self_t & operator=(const self_t &) = default; - const ViewType & view() { - return _view; // *(_view.get()); + constexpr const DomainType & view_domain() const & { + return _domain; } - constexpr const ViewType & view() const { - return _view; // *(_view.get()); + + constexpr DomainType view_domain() const && { + return _domain; } - constexpr iterator begin() const { - return iterator(derived(), 0); + constexpr auto domain() const +// -> decltype(dash::index( +// std::declval() +// )) { + -> typename view_traits::index_set_type { + return dash::index(this->view_domain()); } - constexpr iterator end() const { - return iterator(derived(), derived().size()); + constexpr const pattern_type & pattern() const { + return *_pattern; } - constexpr index_type first() const { - return *(derived().begin()); + constexpr const local_type local() const { + return dash::index(dash::local(_domain)); + } + + constexpr const global_type global() const { + return dash::index(dash::global(_domain)); } - constexpr index_type last() const { - return *(derived().begin() + (derived().size() - 1)); + constexpr bool is_local() const noexcept { + return dash::view_traits::is_local::value; } - constexpr const local_type & local() const { -// -> decltype(dash::index(dash::local( -// std::declval< ViewType & >() ))) { - return dash::index(dash::local(_view)); + constexpr bool is_strided() const noexcept { + return ( + this->pattern().blockspec().size() > this->pattern().team().size() + || ( this->pattern().ndim() > 1 && + this->domain().extent(1) < + ( this->domain().is_local() + ? this->pattern().local_extents()[1] + : this->pattern().extents()[1] )) + ); } - constexpr const global_type & global() const { -// -> decltype(dash::index(dash::global( -// std::declval< ViewType & >() ))) { - return dash::index(dash::global(_view)); + // ---- extents --------------------------------------------------------- + + constexpr std::array + extents() const { + return pattern().extents(); } - constexpr const index_set_domain_type domain() const { - // To allow subclasses to overwrite method view(): -// return dash::index(dash::domain(derived().view())); - return dash::index(dash::domain(_view)); + template + constexpr size_type extent() const { + return derived().extents()[ShapeDim]; } - constexpr const pattern_type & pattern() const { - return _pattern; // *(_pattern.get()); -// return (dash::origin(*_view).pattern()); + constexpr size_type extent(std::size_t shape_dim) const { + return derived().extents()[shape_dim]; + } + + // ---- offsets --------------------------------------------------------- + + constexpr std::array + offsets() const { + return std::array { }; + } + + template + constexpr index_type offset() const { + return derived().offsets()[ShapeDim]; + } + + constexpr index_type offset(std::size_t shape_dim) const { + return derived().offsets()[shape_dim]; + } + + // ---- access ---------------------------------------------------------- + + constexpr index_type rel(index_type image_index) const { + return image_index; + } + + constexpr index_type rel( + const std::array & coords) const { + return -1; + } + + constexpr index_type operator[](index_type image_index) const { + return domain()[derived().rel(image_index)]; + } + + constexpr index_type operator[]( + const std::array & coords) const { + return domain()[derived().rel(coords)]; + } + + constexpr const_iterator begin() const { + return iterator(derived(), 0); + } + + constexpr const_iterator end() const { + return iterator(derived(), derived().size()); + } + + constexpr index_type first() const { + return derived()[0]; + } + + constexpr index_type last() const { + return derived()[ derived().size() - 1 ]; } /* * dash::index(r(10..100)).step(2)[8] -> 26 * dash::index(r(10..100)).step(-5)[4] -> 80 */ - constexpr iterator step(index_type stride) const { + constexpr const_iterator step(index_type stride) const { return ( stride > 0 ? iterator(derived(), 0, stride) @@ -318,23 +471,65 @@ class IndexSetBase // IndexSetIdentity // ----------------------------------------------------------------------- -template -constexpr const IndexSetIdentity & -local(const IndexSetIdentity & index_set) { +template +constexpr auto +local(const IndexSetIdentity & index_set) + -> typename std::enable_if< + !view_traits::is_local::value, + decltype(dash::local(dash::domain(index_set))) + >::type { + return dash::local(dash::domain(index_set)); +} +template +constexpr auto +local(const IndexSetIdentity & index_set) + -> typename std::enable_if< + view_traits::is_local::value, + const IndexSetIdentity & + >::type { + return index_set; +} + +template +constexpr auto +global(const IndexSetIdentity & index_set) + -> typename std::enable_if< + view_traits::is_local::value && + !std::is_same< + typename std::decay::type, + IndexSetIdentity + >::value, + decltype(dash::global(dash::domain(index_set))) + >::type { + return dash::global(dash::domain(index_set)); +} +template +constexpr auto +global(const IndexSetIdentity & index_set) + -> typename std::enable_if< + !view_traits::is_local::value || + std::is_same< + typename std::decay::type, + IndexSetIdentity + >::value, + const IndexSetIdentity & + >::type { return index_set; } /** * \concept{DashRangeConcept} */ -template +template class IndexSetIdentity : public IndexSetBase< - IndexSetIdentity, - ViewType > + IndexSetIdentity, + DomainType > { - typedef IndexSetIdentity self_t; - typedef IndexSetBase base_t; + typedef IndexSetIdentity self_t; + typedef IndexSetBase base_t; + public: + typedef typename base_t::iterator iterator; public: constexpr IndexSetIdentity() = delete; constexpr IndexSetIdentity(self_t &&) = default; @@ -343,162 +538,22 @@ class IndexSetIdentity self_t & operator=(self_t &&) = default; self_t & operator=(const self_t &) = default; public: - typedef typename ViewType::index_type index_type; + typedef typename DomainType::index_type index_type; public: - constexpr explicit IndexSetIdentity(const ViewType & view) + constexpr explicit IndexSetIdentity(const DomainType & view) : base_t(view) { } - - constexpr index_type operator[](index_type image_index) const { - return image_index; - } - - constexpr index_type size() const { - return this->view().size(); - } - - constexpr const self_t & pre() const { - return *this; - } -}; - -// ----------------------------------------------------------------------- -// IndexSetBlocks -// ----------------------------------------------------------------------- - -/* - * TODO: - * Assuming 1-dimensional views for blocks, some patterns provide - * n-dimensional arrangement of blocks, however. - */ - -template -class IndexSetBlocks -: public IndexSetBase< - IndexSetBlocks, - ViewType, - 1 > -{ - typedef IndexSetBlocks self_t; - typedef IndexSetBase base_t; - public: - typedef typename ViewType::index_type index_type; - - typedef self_t local_type; - typedef IndexSetGlobal global_type; - typedef global_type preimage_type; - - typedef typename base_t::iterator iterator; - typedef typename base_t::pattern_type pattern_type; - - typedef dash::local_index_t local_index_type; - typedef dash::global_index_t global_index_type; - - private: - index_type _size; - - constexpr static dim_t NDim = 1; - public: - constexpr IndexSetBlocks() = delete; - constexpr IndexSetBlocks(self_t &&) = default; - constexpr IndexSetBlocks(const self_t &) = default; - ~IndexSetBlocks() = default; - self_t & operator=(self_t &&) = default; - self_t & operator=(const self_t &) = default; - - public: - constexpr explicit IndexSetBlocks(const ViewType & view) - : base_t(view) - , _size(calc_size()) + constexpr explicit IndexSetIdentity(DomainType && view) + : base_t(std::forward(view)) { } - constexpr iterator begin() const { - return iterator(*this, 0); - } - - constexpr iterator end() const { - return iterator(*this, size()); - } - - constexpr index_type - operator[](index_type block_index) const { - return block_index + - // index of block at first index in domain - this->pattern().block_at( - std::array ({ - // this->domain()[0] - *(this->domain().begin()) - }) - ); + constexpr index_type rel(index_type image_index) const { + return image_index; } constexpr index_type size() const { - // return _size; - return calc_size(); - } - - private: - constexpr index_type calc_size() const { - return ( - // index of block at last index in domain - this->pattern().block_at( - {{ this->domain().last() }} - ) - - // index of block at first index in domain - this->pattern().block_at( - {{ this->domain().first() }} - ) + 1 - ); + return this->view_domain().size(); } -}; - -// ----------------------------------------------------------------------- -// IndexSetBlock -// ----------------------------------------------------------------------- - -template -class IndexSetBlock -: public IndexSetBase< - IndexSetBlock, - ViewType, - 1 > -{ - typedef IndexSetBlock self_t; - typedef IndexSetBase base_t; - public: - typedef typename ViewType::index_type index_type; - - typedef self_t local_type; - typedef IndexSetGlobal global_type; - typedef global_type preimage_type; - - typedef typename base_t::iterator iterator; - typedef typename base_t::pattern_type pattern_type; - - typedef dash::local_index_t local_index_type; - typedef dash::global_index_t global_index_type; - - private: - index_type _block_idx; -//index_type _size; - - constexpr static dim_t NDim = 1; - public: - constexpr IndexSetBlock() = delete; - constexpr IndexSetBlock(self_t &&) = default; - constexpr IndexSetBlock(const self_t &) = default; - ~IndexSetBlock() = default; - self_t & operator=(self_t &&) = default; - self_t & operator=(const self_t &) = default; - - public: - constexpr explicit IndexSetBlock( - const ViewType & view, - index_type block_idx) - : base_t(view) - , _block_idx(block_idx) -//, _size(calc_size()) - { } constexpr iterator begin() const { return iterator(*this, 0); @@ -508,32 +563,18 @@ class IndexSetBlock return iterator(*this, size()); } - constexpr index_type - operator[](index_type image_index) const { - return image_index + - // index of block at first index in domain - this->pattern().block_at( - {{ *(this->domain().begin()) }} - ); + constexpr index_type operator[](index_type image_index) const { + return image_index; } - constexpr index_type size() const { - // return _size; - return calc_size(); + template + constexpr index_type operator[]( + const std::array & coords) const { + return -1; } - private: - constexpr index_type calc_size() const { - return ( - // index of block at last index in domain - this->pattern().block_at( - {{ *(this->domain().begin() + (this->domain().size() - 1)) }} - ) - - // index of block at first index in domain - this->pattern().block_at( - {{ *(this->domain().begin()) }} - ) + 1 - ); + constexpr const self_t & pre() const { + return *this; } }; @@ -541,54 +582,68 @@ class IndexSetBlock // IndexSetSub // ----------------------------------------------------------------------- -template +template < + class DomainType, + std::size_t SubDim > constexpr auto -local(const IndexSetSub & index_set) -> -// decltype(index_set.local()) { - typename view_traits>::local_type & { +local(const IndexSetSub & index_set) + -> decltype(index_set.local()) { +//-> typename view_traits>::local_type & { return index_set.local(); } -template +template < + class DomainType, + std::size_t SubDim > constexpr auto -global(const IndexSetSub & index_set) -> -// decltype(index_set.global()) { - typename view_traits>::global_type & { +global(const IndexSetSub & index_set) + -> decltype(index_set.global()) { +//-> typename view_traits>::global_type & { return index_set.global(); } /** * \concept{DashRangeConcept} */ -template +template < + class DomainType, + std::size_t SubDim = 0 > class IndexSetSub : public IndexSetBase< - IndexSetSub, - ViewType > + IndexSetSub, + DomainType > { - typedef IndexSetSub self_t; - typedef IndexSetBase base_t; + typedef IndexSetSub self_t; + typedef IndexSetBase base_t; public: - typedef typename ViewType::index_type index_type; + typedef typename base_t::index_type index_type; + typedef typename base_t::size_type size_type; + typedef typename base_t::view_origin_type view_origin_type; typedef typename base_t::view_domain_type view_domain_type; + typedef typename base_t::pattern_type pattern_type; typedef typename base_t::local_type local_type; typedef typename base_t::global_type global_type; typedef typename base_t::iterator iterator; - typedef IndexSetSub preimage_type; + typedef IndexSetSub preimage_type; public: constexpr IndexSetSub() = delete; constexpr IndexSetSub(self_t &&) = default; constexpr IndexSetSub(const self_t &) = default; ~IndexSetSub() = default; - self_t & operator=(self_t &&) = delete; - self_t & operator=(const self_t &) = delete; + self_t & operator=(self_t &&) = default; + self_t & operator=(const self_t &) = default; private: index_type _domain_begin_idx; index_type _domain_end_idx; + + static constexpr std::size_t NDim = base_t::ndim(); public: + /** + * Constructor, creates index set for given view. + */ constexpr IndexSetSub( - const ViewType & view, + const DomainType & view, index_type begin_idx, index_type end_idx) : base_t(view) @@ -596,10 +651,105 @@ class IndexSetSub , _domain_end_idx(end_idx) { } - constexpr index_type operator[](index_type image_index) const { -// TODO: -// return this->domain()[_domain_begin_idx + image_index]; - return (_domain_begin_idx + image_index); + /** + * Constructor, creates index set for given view. + */ + constexpr IndexSetSub( + DomainType && view, + index_type begin_idx, + index_type end_idx) + : base_t(std::forward(view)) + , _domain_begin_idx(begin_idx) + , _domain_end_idx(end_idx) + { } + + // ---- extents --------------------------------------------------------- + + template + constexpr size_type extent() const { + return ( ExtDim == SubDim + ? _domain_end_idx - _domain_begin_idx + : this->domain().template extent() + ); + } + + constexpr size_type extent(std::size_t shape_dim) const { + return ( shape_dim == SubDim + ? _domain_end_idx - _domain_begin_idx + : this->domain().extent(shape_dim) + ); + } + + constexpr std::array extents() const { + return dash::ce::replace_nth( + extent(), + this->domain().extents()); + } + + // ---- offsets --------------------------------------------------------- + + template + constexpr index_type offset() const { + return ( ExtDim == SubDim + ? _domain_begin_idx + : this->domain().template offset() + ); + } + + constexpr index_type offset(std::size_t shape_dim) const { + return ( shape_dim == SubDim + ? _domain_begin_idx + : this->domain().offset(shape_dim) + ); + } + + constexpr std::array offsets() const { + return dash::ce::replace_nth( + offset(), + this->domain().offsets()); + } + + // ---- size ------------------------------------------------------------ + + constexpr size_type size(std::size_t sub_dim = 0) const { + return extent(sub_dim) * + (sub_dim + 1 < NDim && NDim > 0 + ? size(sub_dim + 1) + : 1); + } + + // ---- access ---------------------------------------------------------- + + /** + * Domain index at specified linear offset. + */ + constexpr index_type rel(index_type image_index) const { + return ( + ( NDim == 1 + ? _domain_begin_idx + image_index + : ( SubDim == 0 + // Rows sub section: + ? ( // full rows in domain: + (offset(0) * this->domain().extent(1)) + + image_index ) + // Columns sub section: + : ( // first index: + offset(1) + // row in view region: + + ( (image_index / extent(1)) + * this->domain().extent(1)) + + image_index % extent(1) ) + ) + ) + ); + } + + /** + * Domain index at specified Cartesian coordinates. + */ + constexpr index_type rel( + const std::array & coords) const { + return -1; } constexpr iterator begin() const { @@ -610,58 +760,66 @@ class IndexSetSub return iterator(*this, size()); } - constexpr index_type size() const { - return std::min( - (_domain_end_idx - _domain_begin_idx), - // TODO: - // this->domain().size() - (_domain_end_idx - _domain_begin_idx) - ); - } - constexpr preimage_type pre() const { return preimage_type( - this->view(), - -_domain_begin_idx, - -_domain_begin_idx + this->view().size() + dash::origin(this->view_domain()), + -(this->operator[](0)), + -(this->operator[](0)) + + dash::origin(this->view_domain()).size() ); } -}; +}; // class IndexSetSub // ----------------------------------------------------------------------- // IndexSetLocal // ----------------------------------------------------------------------- -template -constexpr const IndexSetLocal & -local(const IndexSetLocal & index_set) { +template +constexpr const IndexSetLocal & +local(const IndexSetLocal & index_set) { return index_set; } -template +template constexpr auto -global(const IndexSetLocal & index_set) -> -// decltype(index_set.global()) { - typename view_traits>::global_type & { +global(const IndexSetLocal & index_set) -> + decltype(index_set.global()) { return index_set.global(); } +template +constexpr auto +global(IndexSetLocal && index_set) -> + decltype(std::move(index_set).global()) { + // Note: Not a universal reference, index_set has partially defined type + return std::move(index_set).global(); +} + /** * \concept{DashRangeConcept} */ -template +template class IndexSetLocal : public IndexSetBase< - IndexSetLocal, - ViewType > + IndexSetLocal, + DomainType > { - typedef IndexSetLocal self_t; - typedef IndexSetBase base_t; + typedef IndexSetLocal self_t; + typedef IndexSetBase base_t; + + constexpr static bool view_domain_is_local + = dash::view_traits::is_local::value; public: - typedef typename ViewType::index_type index_type; + typedef typename DomainType::index_type index_type; + typedef typename DomainType::size_type size_type; typedef self_t local_type; - typedef IndexSetGlobal global_type; + typedef IndexSetGlobal global_type; +//typedef decltype( +// dash::global( +// dash::index( +// std::declval()) +// )) global_type; typedef global_type preimage_type; typedef typename base_t::iterator iterator; @@ -681,41 +839,75 @@ class IndexSetLocal self_t & operator=(const self_t &) = default; public: - constexpr explicit IndexSetLocal(const ViewType & view) + /** + * Constructor, creates index set for given view. + */ + constexpr explicit IndexSetLocal(const DomainType & view) : base_t(view) , _size(calc_size()) { } - constexpr iterator begin() const { - return iterator(*this, 0); + /** + * Constructor, creates index set for given view. + */ + constexpr explicit IndexSetLocal(DomainType && view) + : base_t(std::forward(view)) + , _size(calc_size()) + { } + + constexpr const local_type & local() const noexcept { + return *this; } - constexpr iterator end() const { - return iterator(*this, size()); + constexpr auto global() const noexcept + -> decltype(dash::index(dash::global( + std::declval() + ))) { + return dash::index(dash::global(this->view_domain())); } - constexpr index_type - operator[](index_type local_index) const { - // NOTE: - // Random access operator must allow access at [end] because - // end iterator of an index range may be dereferenced. - return local_index + - // only required if local of sub - ( this->domain()[0] == 0 - ? 0 - : this->pattern().at( - std::max( - this->pattern().global(0), - this->domain()[0] - )) - ); + constexpr preimage_type pre() const noexcept { + return preimage_type(this->view_domain()); } - constexpr index_type size() const { + // ---- extents --------------------------------------------------------- + + // TODO: + // Index set types should specify extent and apply mapping of domain + // (as in calc_size) with extents() implemented in IndexSetBase as + // sequence { extent... }. + // + constexpr auto extents() const noexcept + -> decltype( + std::declval< + typename std::add_lvalue_reference::type + >().local_extents()) { + return this->pattern().local_extents(); + } + + template + constexpr index_type extent() const noexcept { + return this->pattern().local_extents()[ShapeDim]; + } + + constexpr index_type extent(std::size_t shape_dim) const noexcept { + return this->pattern().local_extents()[shape_dim]; + } + + // ---- size ------------------------------------------------------------ + + constexpr size_type size(std::size_t sub_dim) const noexcept { return _size; } - constexpr index_type calc_size() const { + constexpr size_type size() const noexcept { + return size(0); + } + + // TODO: + // Should be accumulate of extents(). + // + constexpr index_type calc_size() const noexcept { typedef typename dash::pattern_partitioning_traits::type pat_partitioning_traits; @@ -723,71 +915,193 @@ class IndexSetLocal pat_partitioning_traits::rectangular, "index sets for non-rectangular patterns are not supported yet"); + /* + dash::ce::index_sequence + return dash::ce::accumulate( + {{ (extent())... }}, // values + 0, NDim, // index range + 0, // accumulate init + std::multiplies() // reduce op + ); + */ return ( - //pat_partitioning_traits::minimal || - this->pattern().blockspec().size() - <= this->pattern().team().size() - // blocked (not blockcyclic) distribution: single local - // element space with contiguous global index range - ? std::min( - this->pattern().local_size(), - this->domain().size() - ) - // blockcyclic distribution: local element space chunked - // in global index range - : this->pattern().local_size() + // <-- TODO: intersection of local - this->domain().pre()[0] // blocks and domain + !this->is_strided() + // blocked (not blockcyclic) distribution: single local + // element space with contiguous global index range + ? this->index_range_size( + this->index_range_intersect( + // local range in global index space: + { this->pattern().lbegin(), + this->pattern().lend() - 1 }, + // domain range in global index space; + { this->domain().first(), + this->domain().last() } + )) + 1 + // blockcyclic distribution: local element space chunked + // in global index range + : this->index_range_size( + this->index_range_g2l( + this->pattern(), + // intersection of local range and domain range: + this->index_range_intersect( + // local range in global index space: + { + this->pattern().lbegin(), + ( this->pattern().lend() < this->domain().last() + // domain range contains end of local range: + ? this->pattern().lend() - 1 + // domain range ends in local range, determine last + // local index contained in domain from last local + // block contained in domain range: + // + // gbi: 0 1 2 3 4 5 + // lbi: 0 0 1 1 2 2 + // : : + // [ | |xxxx| |xxxx| | |xxxx] + // '---------------------' + // + // --> domain.end.gbi = 4 ------------. + // domain.end.lbi = 2 -. | + // | | + // v | + // local.lblock(lbi = 2).gbi = 5 | + // | | + // ! 5 > domain.end.gbi = 4 <-----'-' + // --> local.lblock(lbi = 1) + // + // Resolve global index past the last element: + // + : ( domain_block_gidx_last() >= local_block_gidx_last() + // Last local block is included in domain: + ? this->pattern().block( + local_block_gidx_last() + ).range(0).end - 1 + // Domain ends before last local block: + : local_block_gidx_at_block_lidx( + domain_block_lidx_last()) + > domain_block_gidx_last() + ? this->pattern().local_block( + domain_block_lidx_last() - 1 + ).range(0).end - 1 + : this->pattern().local_block( + domain_block_lidx_last() + ).range(0).end - 1 ) + ) + }, + // domain range in global index space; + { this->domain().first(), + this->domain().last() + }) + )) + 1 ); } - constexpr const local_type & local() const { - return *this; + constexpr index_type domain_block_gidx_last() const { + return this->pattern().block_at( + this->pattern().coords( + this->domain().last())); + } + constexpr index_type domain_block_lidx_last() const { + return this->pattern().local_block_at( + this->pattern().coords( + this->domain().last())).index; + } + constexpr index_type local_block_gidx_last() const { + return this->pattern().block_at( + this->pattern().coords( + this->pattern().lend() - 1)); + } + constexpr index_type local_block_gidx_at_block_lidx(index_type lbi) const { + return this->pattern().block_at( + this->pattern().coords( + this->pattern().local_block(lbi).offset(0))); } - constexpr global_type global() const { - return global_type(this->view()); + // ---- access ---------------------------------------------------------- + + constexpr iterator begin() const noexcept { + return iterator(*this, 0); } - constexpr preimage_type pre() const { - return preimage_type(this->view()); + constexpr iterator end() const noexcept { + return iterator(*this, size()); + } + + constexpr index_type rel(index_type local_index) const noexcept { + // NOTE: + // Random access operator must allow access at [end] because + // end iterator of an index range may be dereferenced. + return local_index + + // only required if local of sub + ( this->domain()[0] == 0 + ? 0 + : this->pattern().local( + std::max( + this->pattern().global(0), + this->domain()[0] + )).index + ); + } + + constexpr index_type operator[](index_type local_index) const noexcept { + return rel(local_index); } -}; + + template + constexpr index_type operator[]( + const std::array & local_coords) const noexcept { + return -1; + } +}; // class IndexSetLocal // ----------------------------------------------------------------------- // IndexSetGlobal // ----------------------------------------------------------------------- -template +template constexpr auto -local(const IndexSetGlobal & index_set) - -> decltype(index_set.local()) -{ -// -> typename view_traits>::local_type & { +local(const IndexSetGlobal & index_set) + -> decltype(index_set.local()) { return index_set.local(); } -template -constexpr const IndexSetGlobal & -global(const IndexSetGlobal & index_set) -{ +template +constexpr auto +local(IndexSetGlobal && index_set) + -> decltype(index_set.local()) { + // Note: Not a universal reference, index_set has partially defined type + return index_set.local(); +} + +template +constexpr const IndexSetGlobal & +global(const IndexSetGlobal & index_set) { return index_set; } /** * \concept{DashRangeConcept} */ -template +template class IndexSetGlobal : public IndexSetBase< - IndexSetGlobal, - ViewType > + IndexSetGlobal, + DomainType > { - typedef IndexSetGlobal self_t; - typedef IndexSetBase base_t; - public: - typedef typename ViewType::index_type index_type; + typedef IndexSetGlobal self_t; + typedef IndexSetBase base_t; - typedef IndexSetLocal local_type; + constexpr static bool view_domain_is_local + = dash::view_traits::is_local::value; + public: + typedef typename DomainType::index_type index_type; + +//typedef IndexSetLocal local_type; + typedef decltype( + dash::local( + dash::index( + std::declval()) + )) local_type; typedef self_t global_type; typedef local_type preimage_type; @@ -796,6 +1110,8 @@ class IndexSetGlobal typedef dash::local_index_t local_index_type; typedef dash::global_index_t global_index_type; + private: +//index_type _size; public: constexpr IndexSetGlobal() = delete; constexpr IndexSetGlobal(self_t &&) = default; @@ -803,47 +1119,336 @@ class IndexSetGlobal ~IndexSetGlobal() = default; self_t & operator=(self_t &&) = default; self_t & operator=(const self_t &) = default; + + public: + /** + * Constructor, creates index set for given view. + */ + constexpr explicit IndexSetGlobal(const DomainType & view) + : base_t(view) +//, _size(calc_size()) + { } + + /** + * Constructor, creates index set for given view. + */ + constexpr explicit IndexSetGlobal(DomainType && view) + : base_t(std::forward(view)) +//, _size(calc_size()) + { } + +//constexpr local_type local() const { + constexpr auto local() const noexcept +// -> decltype(dash::index(dash::local(this->view_domain()))) { + -> decltype(dash::index(dash::local( + std::declval() + ))) { + return dash::index(dash::local(this->view_domain())); +// return local_type(this->view_domain()); + } + + constexpr const global_type & global() const noexcept { + return *this; + } + + constexpr const preimage_type & pre() const noexcept { + return dash::index(dash::local(this->domain())); + } + + // ---- access ---------------------------------------------------------- + + constexpr index_type rel(index_type global_index) const noexcept { + return ( view_domain_is_local + ? this->pattern().local( + global_index + ).index + : global_index ); + } + + constexpr index_type operator[](index_type global_index) const noexcept { + return this->domain()[this->rel(global_index)]; + } + + template + constexpr index_type operator[]( + const std::array & local_coords) const noexcept { + return -1; + } + + constexpr index_type size() const noexcept { + return this->domain().size(); + } +}; // class IndexSetGlobal + +// ----------------------------------------------------------------------- +// IndexSetBlocks +// ----------------------------------------------------------------------- + +template +class IndexSetBlocks +: public IndexSetBase< + IndexSetBlocks, + DomainType, + // Number of dimensions in the domain pattern's block spec: + dash::pattern_traits< + typename dash::view_traits< + typename std::decay::type + >::pattern_type + >::blockspec_type::ndim::value + > +{ + typedef IndexSetBlocks self_t; + typedef IndexSetBase base_t; + public: + typedef typename DomainType::index_type index_type; + + typedef self_t local_type; + typedef IndexSetGlobal global_type; + typedef global_type preimage_type; + + typedef typename base_t::iterator iterator; + typedef typename base_t::pattern_type pattern_type; + + typedef dash::local_index_t local_index_type; + typedef dash::global_index_t global_index_type; + private: index_type _size; + + // Rank of blocks index set should depend on blockspec dimensions of + // the domain's pattern type. + static constexpr std::size_t NBlocksDim = base_t::rank::value; + + constexpr static bool view_domain_is_local + = dash::view_traits::is_local::value; + public: + constexpr IndexSetBlocks() = delete; + constexpr IndexSetBlocks(self_t &&) = default; + constexpr IndexSetBlocks(const self_t &) = default; + ~IndexSetBlocks() = default; + self_t & operator=(self_t &&) = default; + self_t & operator=(const self_t &) = default; + public: - constexpr explicit IndexSetGlobal(const ViewType & view) + /** + * Constructor, creates index set for given view. + */ + constexpr explicit IndexSetBlocks(const DomainType & view) : base_t(view) , _size(calc_size()) { } - constexpr index_type - operator[](index_type global_index) const { - // NOTE: - // Random access operator must allow access at [end] because - // end iterator of an index range may be dereferenced. - return this->pattern().at( - global_index + /** + * Constructor, creates index set for given view. + */ + constexpr explicit IndexSetBlocks(DomainType && view) + : base_t(std::forward(view)) + , _size(calc_size()) + { } + + constexpr iterator begin() const { + return iterator(*this, 0); + } + + constexpr iterator end() const { + return iterator(*this, size()); + } + + template + constexpr index_type rel( + index_type block_coord, Args... block_coords) const { + return rel(std::array {{ + block_coord, (index_type)(block_coords)... + }}); + } + + constexpr index_type rel(index_type block_index) const { + return block_index + + // index of block at first index in domain + ( view_domain_is_local + // global coords to local block index: + ? this->pattern().local_block_at( + // global offset to global coords: + this->pattern().coords( + // local offset to global offset: + this->pattern().global( + this->domain()[0] + ) + ) + ).index + // global coords to global block index: + : this->pattern().block_at( + // global offset to global coords: + this->pattern().coords(this->domain()[0] )) ); } + constexpr index_type operator[](index_type block_index) const noexcept { + return rel(block_index); + } + + template + constexpr index_type operator[]( + const std::array & block_coords) const noexcept { + return -1; + } + + constexpr index_type size() const { + return _size; // calc_size(); + } + + private: constexpr index_type calc_size() const { - return std::max( - this->pattern().size(), - this->domain().size() + return ( + view_domain_is_local + ? ( // index of block at last index in domain + this->pattern().local_block_at( + this->pattern().coords( + // local offset to global offset: + this->pattern().global( + this->domain().last() + ) + ) + ).index - + // index of block at first index in domain + this->pattern().local_block_at( + this->pattern().coords( + // local offset to global offset: + this->pattern().global( + this->domain().first() + ) + ) + ).index + 1 ) + : ( // index of block at last index in domain + this->pattern().block_at( + this->pattern().coords(this->domain().last()) + ) - + // index of block at first index in domain + this->pattern().block_at( + this->pattern().coords(this->domain().first()) + ) + 1 ) + ); + } +}; // class IndexSetBlocks + +// ----------------------------------------------------------------------- +// IndexSetBlock +// ----------------------------------------------------------------------- +#if 0 +// Currently using IndexSetSub instead +// +template +class IndexSetBlock +: public IndexSetBase< + IndexSetBlock, + DomainType, + 1 > +{ + typedef IndexSetBlock self_t; + typedef IndexSetBase base_t; + public: + typedef typename DomainType::index_type index_type; + + typedef self_t local_type; + typedef IndexSetGlobal global_type; + typedef global_type preimage_type; + + typedef typename base_t::iterator iterator; + typedef typename base_t::pattern_type pattern_type; + + typedef dash::local_index_t local_index_type; + typedef dash::global_index_t global_index_type; + + private: + index_type _block_idx; + index_type _size; + + constexpr static dim_t NDim = 1; + constexpr static bool view_domain_is_local + = dash::view_traits::is_local::value; + public: + constexpr IndexSetBlock() = delete; + constexpr IndexSetBlock(self_t &&) = default; + constexpr IndexSetBlock(const self_t &) = default; + ~IndexSetBlock() = default; + self_t & operator=(self_t &&) = default; + self_t & operator=(const self_t &) = default; + + public: + constexpr explicit IndexSetBlock( + const DomainType & view, + index_type block_idx) + : base_t(view) + , _block_idx(block_idx) + , _size(calc_size()) + { } + + constexpr iterator begin() const { + return iterator(*this, 0); + } + + constexpr iterator end() const { + return iterator(*this, size()); + } + + constexpr index_type rel(index_type block_phase) const { + return block_phase + + ( view_domain_is_local + ? ( // index of block at last index in domain + this->pattern().local_block_at( + this->pattern().coords( + // local offset to global offset: + this->pattern().global( + *(this->domain().begin()) + ) + ) + ).index ) + : ( // index of block at first index in domain + this->pattern().block_at( + {{ *(this->domain().begin()) }} + ) ) ); } - constexpr index_type size() const { - return _size; + constexpr index_type operator[](index_type block_phase) const noexcept { + return rel(block_phase); } - constexpr const local_type & local() const { - return dash::index(dash::local(this->view())); + template + constexpr index_type operator[]( + const std::array & block_phase_coords) const noexcept { + return -1; } - constexpr const global_type & global() const { - return *this; + constexpr index_type size() const { + return _size; // calc_size(); } - constexpr const preimage_type & pre() const { - return dash::index(dash::local(this->view())); + private: + constexpr index_type calc_size() const { + return ( view_domain_is_local + ? ( // index of block at last index in domain + this->pattern().local_block_at( + {{ *( this->domain().begin() + + (this->domain().size() - 1) ) }} + ).index - + // index of block at first index in domain + this->pattern().local_block_at( + {{ *( this->domain().begin() ) }} + ).index + 1 ) + : ( // index of block at last index in domain + this->pattern().block_at( + {{ *( this->domain().begin() + + (this->domain().size() - 1) ) }} + ) - + // index of block at first index in domain + this->pattern().block_at( + {{ *(this->domain().begin()) }} + ) + 1 ) + ); } -}; +}; // class IndexSetBlock +#endif } // namespace dash #endif // DOXYGEN diff --git a/dash/include/dash/view/Local.h b/dash/include/dash/view/Local.h index 3b75a9467..c58aeb0a6 100644 --- a/dash/include/dash/view/Local.h +++ b/dash/include/dash/view/Local.h @@ -9,19 +9,64 @@ namespace dash { +namespace detail { + /** + * Definition of type trait \c dash::detail::has_type_local_type + * with static member \c value indicating whether type \c T provides + * dependent type \c local_type. + */ + DASH__META__DEFINE_TRAIT__HAS_TYPE(local_type); +} + /** * \concept{DashViewConcept} */ -template +template < + class ViewType, + typename ViewValueT = typename std::decay::type > constexpr auto local(ViewType & v) -> typename std::enable_if< - std::is_pointer< typename ViewType::iterator >::value, + ( std::is_pointer< typename ViewType::iterator >::value || + ( // dash::view_traits::is_origin::value && + dash::view_traits::is_local::value ) ), ViewType & >::type { return v; } +#if 0 +template < + class ContainerLocalType, + typename ContainerLocalDecayType + = typename std::decay::type > +constexpr +typename std::enable_if< + ( dash::view_traits::is_origin::value && + dash::view_traits::is_local::value ), + ContainerLocalType & +>::type +local(ContainerLocalType & cl) { + return cl; +} +#endif + +template < + class ContainerType, + typename ContainerDecayType + = typename std::decay::type > +constexpr +typename std::enable_if< + ( !dash::view_traits::is_view::value && + !dash::view_traits::is_local::value && + dash::view_traits::is_origin::value ), + const typename ContainerType::local_type & +>::type +local(const ContainerType & c) { + return c.local; +} + +#if 0 /** * \concept{DashViewConcept} */ @@ -29,25 +74,64 @@ template constexpr auto local(const ViewType & v) -> typename std::enable_if< - dash::view_traits::is_view::value, - decltype(v.local()) + !dash::view_traits::is_view::value && + !dash::view_traits::is_local::value && + dash::detail::has_type_local_type::value, + dash::IndexSetIdentity >::type { - return v.local(); + return IndexSetIdentity( + v.local()); } +#endif /** * \concept{DashViewConcept} */ +template +constexpr auto +local(const ViewType & v) +-> typename std::enable_if< + dash::view_traits::is_view::value, + decltype(v.local()) + >::type { + return v.local(); +} + +template < + class ViewType, + typename ViewValueT = typename std::decay::type > +constexpr auto +local(ViewType && v) +-> typename std::enable_if< + ( dash::view_traits::is_view::value && + !dash::view_traits::is_local::value ), + decltype(std::forward(v).local()) + >::type { + return std::forward(v).local(); +} + +#if 0 template -constexpr -typename std::enable_if< - !dash::view_traits::is_view::value, - const typename ContainerType::local_type & ->::type -local(const ContainerType & c) { - return c.local; +constexpr auto local(const ContainerType & c) + -> typename std::enable_if< + !dash::view_traits< ContainerType >::is_view::value + && dash::view_traits< ContainerType >::rank::value == 1, + dash::ViewSubMod + >::type { + return dash::ViewSubMod(0, c.size(), c); } +template +constexpr auto local(const ContainerType & c) + -> typename std::enable_if< + !dash::view_traits< ContainerType >::is_view::value + && (dash::view_traits< ContainerType >::rank::value > 1), + dash::NViewSubMod + >::type { + return dash::NViewSubMod(0, c.extents()[0], c); +} +#endif + /** * Convert global iterator referencing an element the active unit's * memory to a corresponding native pointer referencing the element. @@ -63,6 +147,10 @@ constexpr auto local( return g_it.local(); } +// ========================================================================= +// Multidimensional Views +// ========================================================================= + } // namespace dash #endif // DASH__VIEW__LOCAL_H__INCLUDED diff --git a/dash/include/dash/view/NViewMod.h b/dash/include/dash/view/NViewMod.h deleted file mode 100644 index 5e103be65..000000000 --- a/dash/include/dash/view/NViewMod.h +++ /dev/null @@ -1,637 +0,0 @@ -#ifndef DASH__VIEW__NVIEW_MOD_H__INCLUDED -#define DASH__VIEW__NVIEW_MOD_H__INCLUDED - -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include - - -namespace dash { - - -#ifndef DOXYGEN - -// Related: boost::multi_array -// -// http://www.boost.org/doc/libs/1_63_0/libs/multi_array/doc/user.html -// - -// ------------------------------------------------------------------------ -// Forward-declarations -// ------------------------------------------------------------------------ - -template -class NViewOrigin; - -template < - class ViewModType, - class DomainType, - std::size_t NDim > -class NViewModBase; - -template < - class DomainType = NViewOrigin<1>, - std::size_t NDim = dash::view_traits::rank::value > -class NViewLocalMod; - -template < - class DomainType = NViewOrigin<1>, - std::size_t NDim = dash::view_traits::rank::value > -class NViewGlobalMod; - -template < - class DomainType = NViewOrigin<1>, - std::size_t SubDim = 0, - std::size_t NDim = dash::view_traits::rank::value > -class NViewSubMod; - -// -------------------------------------------------------------------- -// ViewOrigin -// -------------------------------------------------------------------- - -/** - * Monotype for the logical symbol that represents a view origin. - */ -template -class NViewOrigin -{ - typedef NViewOrigin self_t; - -public: - typedef dash::default_index_t index_type; - typedef self_t domain_type; - typedef IndexSetIdentity index_set_type; - -public: - typedef std::integral_constant is_local; - typedef std::integral_constant rank; - -private: - std::array _extents = { }; - std::array _offsets = { }; - index_set_type _index_set; -public: - constexpr NViewOrigin() = delete; - constexpr NViewOrigin(self_t &&) = default; - constexpr NViewOrigin(const self_t &) = default; - ~NViewOrigin() = default; - self_t & operator=(self_t &&) = default; - self_t & operator=(const self_t &) = default; - - constexpr explicit NViewOrigin( - std::initializer_list extents) - : _extents(extents) - , _index_set(*this) - { } - - constexpr const domain_type & domain() const { - return *this; - } - - inline domain_type & domain() { - return *this; - } - - constexpr const index_set_type & index_set() const { - return _index_set; - } - - constexpr bool operator==(const self_t & rhs) const { - return (this == &rhs); - } - - constexpr bool operator!=(const self_t & rhs) const { - return !(*this == rhs); - } - - // ---- extents --------------------------------------------------------- - - constexpr const std::array & extents() const { - return _extents; - } - - template - constexpr index_type extent() const { - return _extents[ExtentDim]; - } - - constexpr index_type extent(dim_t extent_dim) const { - return _extents[extent_dim]; - } - - // ---- offsets --------------------------------------------------------- - - constexpr const std::array & offsets() const { - return _offsets; - } - - template - constexpr index_type offset() const { - return _offsets[OffsetDim]; - } - - constexpr index_type offset(dim_t offset_dim) const { - return _offsets[offset_dim]; - } - - // ---- size ------------------------------------------------------------ - - template - constexpr index_type size() const { - return extent() * - (SizeDim < NDim - ? size() - : 1); - } -}; - -template -struct view_traits> { - typedef NViewOrigin origin_type; - typedef NViewOrigin domain_type; - typedef NViewOrigin image_type; - typedef typename NViewOrigin::index_type index_type; - typedef typename NViewOrigin::index_set_type index_set_type; - - typedef std::integral_constant is_projection; - typedef std::integral_constant is_view; - typedef std::integral_constant is_origin; - typedef std::integral_constant is_local; - - typedef std::integral_constant rank; -}; - - -// ------------------------------------------------------------------------ -// NViewModBase -// ------------------------------------------------------------------------ - -template < - class NViewModType, - class DomainType, - std::size_t NDim > -class NViewModBase -{ - typedef NViewModBase self_t; -public: - typedef DomainType domain_type; - typedef typename view_traits::origin_type origin_type; - typedef typename view_traits::index_type index_type; - typedef typename origin_type::value_type value_type; - - typedef std::integral_constant rank; - -protected: - const DomainType * _domain; - - NViewModType & derived() { - return static_cast(*this); - } - const NViewModType & derived() const { - return static_cast(*this); - } - - constexpr explicit NViewModBase(const domain_type & domain) - : _domain(&domain) - { } - - constexpr NViewModBase() = delete; - constexpr NViewModBase(self_t &&) = default; - constexpr NViewModBase(const self_t &) = default; - ~NViewModBase() = default; - -public: - self_t & operator=(self_t &&) = default; - self_t & operator=(const self_t &) = default; - - constexpr const domain_type & domain() const { - return *_domain; - } - - constexpr bool operator==(const NViewModType & rhs) const { - return &derived() == &rhs; - } - - constexpr bool operator!=(const NViewModType & rhs) const { - return !(derived() == rhs); - } - - constexpr bool is_local() const { - return view_traits::is_local::value; - } - - // ---- extents --------------------------------------------------------- - - constexpr auto extents() const - -> decltype( - std::declval< - typename std::add_lvalue_reference::type - >().extents()) { - return _domain->extents(); - } - - template - constexpr index_type extent() const { - return (*_domain).template extent(); - } - - constexpr index_type extent(std::size_t shape_dim) const { - return _domain->extent(shape_dim); - } - - // ---- offsets --------------------------------------------------------- - - constexpr auto offsets() const - -> decltype( - std::declval< - typename std::add_lvalue_reference::type - >().offsets()) { - return _domain->offsets(); - } - - template - constexpr index_type offset() const { - return (*_domain).template offset(); - } - - constexpr index_type offset(std::size_t shape_dim) const { - return _domain->offset(shape_dim); - } - - // ---- size ------------------------------------------------------------ - - template - constexpr index_type size() const { - return extent() * - (SizeDim < NDim - ? size() - : 1); - } -}; - - -// ------------------------------------------------------------------------ -// NViewLocalMod -// ------------------------------------------------------------------------ - -template < - class DomainType, - std::size_t NDim > -struct view_traits > { - typedef DomainType domain_type; - typedef typename view_traits::origin_type origin_type; - typedef typename domain_type::local_type image_type; - typedef NViewLocalMod local_type; - typedef domain_type global_type; - - typedef typename DomainType::index_type index_type; - typedef dash::IndexSetLocal< NViewLocalMod > - index_set_type; - - typedef std::integral_constant is_projection; - typedef std::integral_constant is_view; - typedef std::integral_constant is_origin; - typedef std::integral_constant is_local; - - typedef std::integral_constant rank; -}; - -template < - class DomainType, - std::size_t NDim > -class NViewLocalMod -: public NViewModBase< - NViewLocalMod, - DomainType, - NDim > -{ -public: - typedef DomainType domain_type; - typedef typename view_traits::origin_type origin_type; - typedef typename domain_type::local_type image_type; - typedef typename DomainType::index_type index_type; -private: - typedef NViewLocalMod self_t; - typedef NViewModBase< - NViewLocalMod, DomainType, NDim > base_t; -public: - typedef dash::IndexSetLocal< - NViewLocalMod > index_set_type; - typedef self_t local_type; - typedef typename domain_type::global_type global_type; - - typedef std::integral_constant is_local; - -private: - index_set_type _index_set; -public: - constexpr NViewLocalMod() = delete; - constexpr NViewLocalMod(self_t &&) = default; - constexpr NViewLocalMod(const self_t &) = default; - ~NViewLocalMod() = default; - self_t & operator=(self_t &&) = default; - self_t & operator=(const self_t &) = default; - - constexpr explicit NViewLocalMod( - const DomainType & domain) - : base_t(domain) - , _index_set(*this) - { } - - constexpr bool operator==(const self_t & rhs) const { - return (this == &rhs || - ( base_t::operator==(rhs) && - _index_set == rhs._index_set ) ); - } - - constexpr bool operator!=(const self_t & rhs) const { - return not (*this == rhs); - } - - constexpr auto begin() const - -> decltype(dash::begin(dash::local( - std::declval< - typename std::add_lvalue_reference::type >() - ))) { - return dash::begin( - dash::local( - dash::origin( - *this - ) - ) - ) - + dash::index(dash::local(dash::domain(*this))).pre()[ - dash::index(dash::local(dash::domain(*this)))[0] - ]; - } - - constexpr auto end() const - -> decltype(dash::end(dash::local( - std::declval< - typename std::add_lvalue_reference::type >() - ))) { - return dash::begin( - dash::local( - dash::origin( - *this - ) - ) - ) - + dash::index(dash::local(dash::domain(*this))).pre()[ - (*dash::end(dash::index(dash::local(dash::domain(*this)))))-1 - ] + 1; - } - - constexpr auto operator[](int offset) const - -> decltype(*(dash::begin( - dash::local(dash::origin( - std::declval< - typename std::add_lvalue_reference::type >() - ))))) { - return *(this->begin() + offset); - } - - constexpr index_type size() const { - return index_set().size(); - } - - constexpr const local_type & local() const { - return *this; - } - - inline local_type & local() { - return *this; - } - - constexpr const global_type & global() const { - return dash::global(dash::domain(*this)); - } - - inline global_type & global() { - return dash::global(dash::domain(*this)); - } - - constexpr const index_set_type & index_set() const { - return _index_set; - } - - template - constexpr index_type size() const { - return extent() * - (SizeDim < NDim - ? size() - : 1); - } -}; - - -// ------------------------------------------------------------------------ -// NViewSubMod -// ------------------------------------------------------------------------ - -template < - class DomainType, - std::size_t SubDim, - std::size_t NDim > -struct view_traits > { - typedef DomainType domain_type; - typedef typename dash::view_traits::origin_type origin_type; - typedef NViewSubMod image_type; - typedef NViewSubMod local_type; - typedef NViewSubMod global_type; - - typedef typename DomainType::index_type index_type; - typedef dash::IndexSetSub< - NViewSubMod > index_set_type; - - typedef std::integral_constant is_projection; - typedef std::integral_constant is_view; - typedef std::integral_constant is_origin; - typedef std::integral_constant::is_local::value > is_local; - - typedef std::integral_constant rank; -}; - - -template < - class DomainType, - std::size_t SubDim, - std::size_t NDim > -class NViewSubMod -: public NViewModBase< - NViewSubMod, - DomainType, - NDim > -{ -public: - typedef DomainType domain_type; - typedef typename view_traits::index_type index_type; -private: - typedef NViewSubMod self_t; - typedef NViewModBase< - NViewSubMod, DomainType, NDim - > base_t; -public: - typedef dash::IndexSetSub< - NViewSubMod > index_set_type; - typedef NViewLocalMod local_type; - typedef self_t global_type; - - typedef std::integral_constant is_local; - -private: - index_type _begin_idx; - index_type _end_idx; - index_set_type _index_set; - -public: - constexpr NViewSubMod() = delete; - constexpr NViewSubMod(self_t &&) = default; - constexpr NViewSubMod(const self_t &) = default; - ~NViewSubMod() = default; - self_t & operator=(self_t &&) = default; - self_t & operator=(const self_t &) = default; - - constexpr NViewSubMod( - const DomainType & domain, - index_type begin, - index_type end) - : base_t(domain) - , _begin_idx(begin) - , _end_idx(end) - , _index_set(*this, begin, end) - { } - - // ---- extents --------------------------------------------------------- - - template - constexpr index_type extent() const { - return ( ExtDim == SubDim - ? _end_idx - _begin_idx - // : base_t::template extent() - : base_t::extent(ExtDim) - ); - } - - constexpr auto extents() const - -> decltype( - std::declval< - typename std::add_lvalue_reference::type - >().extents()) { - return dash::ce::replace_nth( - static_cast< - typename std::remove_reference< - decltype( std::get<0>(dash::domain(*this).extents()) ) - >::type - >(_end_idx - _begin_idx), - dash::domain(*this).extents()); - } - - constexpr index_type extent(std::size_t shape_dim) const { - return ( shape_dim == SubDim - ? _end_idx - _begin_idx - : base_t::extent(shape_dim) - ); - } - - // ---- offsets --------------------------------------------------------- - - template - constexpr index_type offset() const { - return ( ExtDim == SubDim - ? _begin_idx - // : base_t::template offset() - : base_t::offset(ExtDim) - ); - } - - constexpr auto offsets() const - -> decltype( - std::declval< - typename std::add_lvalue_reference::type - >().offsets()) { - return dash::ce::replace_nth( - static_cast< - typename std::remove_reference< - decltype( std::get<0>(dash::domain(*this).offsets()) ) - >::type - >(_begin_idx), - dash::domain(*this).offsets()); - } - - constexpr index_type offset(std::size_t shape_dim) const { - return ( shape_dim == SubDim - ? _begin_idx - : base_t::offset(shape_dim) - ); - } - - // ---- size ------------------------------------------------------------ - - template - constexpr index_type size() const { - return extent() * - (SizeDim < NDim - ? size() - : 1); - } - - constexpr index_type size() const { - return _index_set.size(); - } - - // ---- access ---------------------------------------------------------- - - constexpr auto begin() const - -> decltype(dash::begin( - std::declval< - typename std::add_lvalue_reference::type - >() )) { - return dash::begin(dash::domain(*this)) + - *dash::begin(dash::index(*this)); - } - - constexpr auto end() const - -> decltype(dash::begin( - std::declval< - typename std::add_lvalue_reference::type - >() )) { - return dash::begin(dash::domain(*this)) + - *dash::end(dash::index(*this)); - } - - constexpr auto operator[](int offset) const - -> decltype(*(dash::begin( - std::declval< - typename std::add_lvalue_reference::type - >() ))) { - return *(this->begin() + offset); - } - - constexpr const index_set_type & index_set() const { - return _index_set; - } - - constexpr local_type local() const { - return local_type(*this); - } -}; - - -#endif // DOXYGEN - -} // namespace dash - -#endif // DASH__NVIEW__VIEW_MOD_H__INCLUDED diff --git a/dash/include/dash/view/Origin.h b/dash/include/dash/view/Origin.h index 2a8d6f9b9..9b69a2835 100644 --- a/dash/include/dash/view/Origin.h +++ b/dash/include/dash/view/Origin.h @@ -7,6 +7,7 @@ #include #include +#include namespace dash { @@ -17,31 +18,81 @@ namespace dash { * * \concept{DashViewConcept} */ -template -typename dash::view_traits::origin_type -origin(const ContainerT & container); +template +typename dash::view_traits::origin_type +origin(ViewT & view); #else template -constexpr typename std::enable_if< - !dash::view_traits::is_view::value, - const typename dash::view_traits::origin_type & +typename std::enable_if< + dash::view_traits::is_origin::value, + ContainerT & +>::type +origin(ContainerT & container) { + return container; +} + +template +constexpr auto +origin(const ViewT & view) + -> typename std::enable_if< + ( dash::view_traits::is_view::value && + !dash::view_traits::is_local::value ), + const typename dash::view_traits::origin_type & + >::type { + // Recurse to origin of global view: + return dash::origin(view.domain()); +} + + +template +typename std::enable_if< + dash::view_traits::is_origin::value, + ContainerT & >::type -origin(const ContainerT & container) { +global_origin(ContainerT & container) { return container; } +template +constexpr auto +global_origin(const ViewT & view) + -> typename std::enable_if< + !dash::view_traits::is_origin::value, + const typename dash::view_traits::origin_type & + >::type { + // Recurse to origin of local view: + return dash::global_origin(view.domain()); +} + +template +constexpr auto +origin(const ViewT & view) + -> typename std::enable_if< + ( dash::view_traits::is_view::value && + dash::view_traits< + typename dash::view_traits::domain_type + >::is_local::value ), + const typename dash::view_traits::origin_type::local_type & + >::type { + // Recurse to origin of local view: + return dash::local(dash::global_origin(view.domain())); +} + template constexpr auto origin(const ViewT & view) -> typename std::enable_if< - dash::view_traits::is_view::value, + ( dash::view_traits::is_view::value && + dash::view_traits::is_local::value && + !dash::view_traits< + typename dash::view_traits::domain_type + >::is_local::value ), const typename dash::view_traits::origin_type & - // decltype(dash::origin(dash::domain(view))) >::type { - // recurse upwards: - return dash::origin(dash::domain(view)); + // Recurse to global origin of local view: + return dash::global_origin(view.domain()); } #endif // DOXYGEN diff --git a/dash/include/dash/view/Sub.h b/dash/include/dash/view/Sub.h index 22294e8c8..8c9960f80 100644 --- a/dash/include/dash/view/Sub.h +++ b/dash/include/dash/view/Sub.h @@ -5,7 +5,6 @@ #include #include -#include namespace dash { @@ -14,9 +13,9 @@ namespace dash { // View Modifiers (not coupled with origin memory / index space): // ------------------------------------------------------------------------- -// Sub-space slice, view dimensions maintain domain dimensions - /** + * Sub-section, view dimensions maintain domain dimensions. + * * \concept{DashViewConcept} */ template < @@ -31,6 +30,8 @@ sub(OffsetFirstT begin, } /** + * Sub-section, view dimensions maintain domain dimensions. + * * \concept{DashViewConcept} */ template < @@ -43,10 +44,10 @@ sub(const IndexRangeT & range) { dash::end(range)); } -// Sub-space projection, view reduces domain by one dimension - #if 0 /** + * Sub-space projection, view reduces domain by one dimension. + * * \concept{DashViewConcept} */ template < @@ -63,92 +64,50 @@ sub( // View Proxies (coupled with origin memory / index space): // ------------------------------------------------------------------------- -// Sub-space slice, view dimensions maintain domain dimensions - -#if 0 -/** - * \concept{DashViewConcept} - */ template < dim_t SubDim = 0, class DomainT, class OffsetFirstT, class OffsetFinalT, - typename DomainValueT = - typename std::remove_const< - typename std::remove_reference::type - >::type -> -constexpr auto -sub( - OffsetFirstT begin, - OffsetFinalT end, - DomainT & domain) - -> typename std::enable_if< - dash::view_traits< - DomainValueT - >::rank::value == 1, - ViewSubMod - >::type { - return ViewSubMod( - domain, - begin, - end); -} -#endif - -#if 1 -template < - dim_t SubDim = 0, - class DomainT, - class OffsetFirstT, - class OffsetFinalT, - typename DomainValueT = - // typename std::remove_const< - typename std::remove_reference::type - // >::type -> -constexpr auto + typename DomainValueT = typename std::decay::type > +constexpr +ViewSubMod< + DomainValueT, + SubDim, + dash::view_traits::rank::value > sub( OffsetFirstT begin, OffsetFinalT end, - DomainT && domain) - -> typename std::enable_if< - dash::view_traits< - DomainValueT - >::rank::value == 1, - ViewSubMod - >::type { - return ViewSubMod( - std::forward(domain), + const DomainT & domain) { + return ViewSubMod< + DomainValueT, + SubDim, + dash::view_traits::rank::value + >(domain, begin, end); } -#endif - -// ========================================================================= -// Multidimensional Views -// ========================================================================= template < - dim_t SubDim = 0, - class DomainT, - class OffsetFirstT, - class OffsetFinalT > -constexpr auto + dim_t SubDim = 0, + class DomainT, + class OffsetFirstT, + class OffsetFinalT, + typename DomainValueT = typename std::decay::type > +constexpr +ViewSubMod< + DomainValueT, + SubDim, + dash::view_traits::rank::value > sub( OffsetFirstT begin, OffsetFinalT end, - const DomainT & domain) - -> typename std::enable_if< - (dash::view_traits::rank::value > 1), - NViewSubMod::rank::value> - >::type { - return NViewSubMod< - DomainT, + DomainT && domain) { + return ViewSubMod< + DomainValueT, SubDim, - dash::view_traits::rank::value - >(domain, + dash::view_traits::rank::value + >(std::forward(domain), begin, end); } diff --git a/dash/include/dash/view/ViewBlocksMod.h b/dash/include/dash/view/ViewBlocksMod.h index 029df140b..433b90f99 100644 --- a/dash/include/dash/view/ViewBlocksMod.h +++ b/dash/include/dash/view/ViewBlocksMod.h @@ -5,6 +5,8 @@ #include #include +#include + #include #include #include @@ -27,7 +29,9 @@ namespace dash { // ------------------------------------------------------------------------ // template < - class DomainType = ViewOrigin<1> > + class DomainType, + dim_t NDim = dash::view_traits< + typename std::decay::type>::rank::value > class ViewBlocksMod; // ------------------------------------------------------------------------ @@ -45,7 +49,8 @@ struct view_traits > { typedef ViewBlockMod global_type; typedef typename DomainType::index_type index_type; - typedef dash::IndexSetSub> index_set_type; + // TODO: Defaulting to SubDim = 0 here, clarify + typedef dash::IndexSetSub index_set_type; typedef std::integral_constant is_projection; typedef std::integral_constant is_view; @@ -69,26 +74,54 @@ class ViewBlockMod ViewBlockMod, DomainType > { + private: + typedef ViewBlockMod self_t; + typedef ViewModBase< ViewBlockMod, DomainType > base_t; public: typedef DomainType domain_type; typedef typename view_traits::index_type index_type; - private: - typedef ViewBlockMod self_t; - typedef ViewModBase< ViewBlockMod, DomainType > - base_t; +//typedef typename view_traits::origin_type origin_type; + typedef typename base_t::origin_type origin_type; public: -//typedef dash::IndexSetSub< ViewBlockMod > index_set_type; - typedef dash::IndexSetSub< DomainType > index_set_type; + // TODO: Defaulting to SubDim = 0 here, clarify + typedef dash::IndexSetSub< DomainType, 0 > index_set_type; typedef ViewLocalMod local_type; typedef self_t global_type; typedef std::integral_constant is_local; - typedef decltype(dash::begin( - std::declval< - typename std::add_lvalue_reference::type - >() )) + typedef decltype( + dash::begin( + std::declval< + typename std::add_lvalue_reference::type + >() )) + origin_iterator; + + typedef decltype( + dash::begin( + std::declval< + typename std::add_lvalue_reference::type + >() )) + const_origin_iterator; + + typedef ViewIterator iterator; + typedef ViewIterator + const_iterator; + + typedef + decltype(*dash::begin( + std::declval< + typename std::add_lvalue_reference::type + >() )) + reference; + + typedef + decltype(*dash::begin( + std::declval< + typename std::add_lvalue_reference::type + >() )) + const_reference; private: index_set_type _index_set; @@ -96,14 +129,14 @@ class ViewBlockMod public: constexpr ViewBlockMod() = delete; constexpr ViewBlockMod(self_t &&) = default; - constexpr ViewBlockMod(const self_t &) = delete; + constexpr ViewBlockMod(const self_t &) = default; ~ViewBlockMod() = default; self_t & operator=(self_t &&) = default; - self_t & operator=(const self_t &) = delete; + self_t & operator=(const self_t &) = default; constexpr ViewBlockMod( const domain_type & domain, - index_type block_idx) + index_type block_idx) : base_t(domain) , _index_set(domain, block_first_gidx(domain, block_idx), @@ -117,35 +150,38 @@ class ViewBlockMod domain_type && domain, index_type block_idx) : base_t(std::forward(domain)) - , _index_set(domain, - block_first_gidx(domain, block_idx), - block_final_gidx(domain, block_idx)) + , _index_set(this->domain(), + block_first_gidx(this->domain(), block_idx), + block_final_gidx(this->domain(), block_idx)) { } - constexpr auto begin() const - -> decltype(dash::begin( - std::declval< - typename std::add_lvalue_reference::type - >() )) { - return this->domain().begin() + - _index_set[0]; + constexpr const_iterator begin() const { + return const_iterator(dash::origin(*this).begin(), + _index_set, 0); } - constexpr auto end() const - -> decltype(dash::begin( - std::declval< - typename std::add_lvalue_reference::type - >() )) { - return this->domain().begin() + - _index_set.last() + 1; + iterator begin() { + return iterator(const_cast( + dash::origin(*this) + ).begin(), + _index_set, 0); } - constexpr auto operator[](int offset) const - -> decltype(*(dash::begin( - std::declval< - typename std::add_lvalue_reference::type - >() ))) { - return begin()[offset]; + constexpr const_iterator end() const { + return const_iterator(dash::origin(*this).begin(), + _index_set, _index_set.size()); + } + + iterator end() { + return iterator(const_cast( + dash::origin(*this) + ).begin(), + _index_set, _index_set.size()); + } + + constexpr const_reference operator[](int offset) const { + return *(const_iterator(dash::origin(*this).begin(), + _index_set, offset)); } constexpr const index_set_type & index_set() const { @@ -157,39 +193,58 @@ class ViewBlockMod } private: - /// Block index of first element in view + /// Index of first element in block view /// constexpr index_type block_first_gidx( const DomainType & vdomain, index_type block_idx) const { + // If domain is local, block_idx refers to local block range + // so use pattern().local_block(block_idx) // - // TODO: If domain is local, use pattern().local_block(block_idx) - // + // TODO: Currently values passed as `block_idx` are global block indices + // even if domain is local return std::max( ( // block viewspec (extents, offsets) - dash::index(vdomain) - .pattern().block(block_idx).offsets()[0] + ( false && + dash::view_traits::is_local::value + ? dash::index(vdomain) + .pattern().local_block(block_idx).offsets()[0] + : dash::index(vdomain) + .pattern().block(block_idx).offsets()[0] + ) ), dash::index(vdomain).first() ) - dash::index(vdomain).first(); } - /// Index past block index of last element in view: + /// Index past last element in block view: /// constexpr index_type block_final_gidx( const DomainType & vdomain, index_type block_idx) const { + // If domain is local, block_idx refers to local block range + // so use pattern().local_block(block_idx) // - // TODO: If domain is local, use pattern().local_block(block_idx) - // + // TODO: Currently values passed as `block_idx` are global block indices + // even if domain is local return std::min( dash::index(vdomain).last() + 1, ( // block viewspec (extents, offsets) - dash::index(vdomain) - .pattern().block(block_idx).offsets()[0] - + dash::index(vdomain) - .pattern().block(block_idx).extents()[0] + ( false && + dash::view_traits::is_local::value + ? dash::index(vdomain) + .pattern().local_block(block_idx).offsets()[0] + : dash::index(vdomain) + .pattern().block(block_idx).offsets()[0] + ) + + ( false && + dash::view_traits::is_local::value + ? dash::index(vdomain) + .pattern().local_block(block_idx).extents()[0] + : dash::index(vdomain) + .pattern().block(block_idx).extents()[0] + ) ) ) - dash::index(vdomain).first(); @@ -207,52 +262,60 @@ blocks(const ViewType & domain) { } template < - class ViewType, - typename ViewValueT = - typename std::remove_const< - typename std::remove_reference::type - >::type -> + class ViewType, + class ViewValueT + = typename std::decay::type > constexpr ViewBlocksMod blocks(ViewType && domain) { return ViewBlocksMod(std::forward(domain)); } template < - class DomainType > -struct view_traits > { + class DomainType, + dim_t NDim > +struct view_traits > { typedef DomainType domain_type; typedef typename view_traits::origin_type origin_type; typedef typename view_traits::pattern_type pattern_type; - typedef ViewBlocksMod image_type; + typedef ViewBlocksMod image_type; typedef typename domain_type::local_type local_type; - typedef ViewBlocksMod global_type; + typedef ViewBlocksMod global_type; typedef typename DomainType::index_type index_type; - typedef dash::IndexSetBlocks> index_set_type; + typedef dash::IndexSetBlocks> + index_set_type; typedef std::integral_constant is_projection; typedef std::integral_constant is_view; typedef std::integral_constant is_origin; - typedef std::integral_constant is_local; + typedef std::integral_constant::is_local::value > is_local; + + typedef std::integral_constant rank; }; template < - class DomainType > + class DomainType, + dim_t NDim > class ViewBlocksMod -: public ViewModBase< ViewBlocksMod, DomainType > { +: public ViewModBase< ViewBlocksMod, DomainType, NDim > { + private: + typedef ViewBlocksMod self_t; + typedef ViewModBase, DomainType, NDim> + base_t; + typedef ViewBlocksMod const_self_t; public: typedef DomainType domain_type; - typedef typename view_traits::origin_type origin_type; + typedef typename base_t::origin_type origin_type; typedef typename view_traits::index_type index_type; + typedef typename view_traits::size_type size_type; private: - typedef ViewBlocksMod self_t; - typedef ViewModBase, DomainType> base_t; typedef ViewBlockMod block_type; + typedef typename domain_type::local_type domain_local_type; public: - typedef dash::IndexSetBlocks> index_set_type; + typedef dash::IndexSetBlocks index_set_type; typedef self_t global_type; - typedef typename domain_type::local_type local_type; + typedef ViewBlocksMod local_type; typedef std::integral_constant is_local; @@ -267,7 +330,8 @@ class ViewBlocksMod block_type, index_type, std::nullptr_t, - block_type > { + block_type > + { private: typedef internal::IndexIteratorBase< block_iterator, @@ -276,13 +340,14 @@ class ViewBlocksMod std::nullptr_t, // pointer type block_type > // reference type iterator_base_t; + typedef typename view_traits::domain_type + blocks_view_domain_type; private: -// ViewBlocksModType & _blocks_view; - const self_t & _blocks_view; + const blocks_view_domain_type & _blocks_view_domain; public: constexpr block_iterator() = delete; constexpr block_iterator(block_iterator &&) = default; - constexpr block_iterator(const block_iterator &) = delete; + constexpr block_iterator(const block_iterator &) = default; ~block_iterator() = default; block_iterator & operator=(block_iterator &&) = default; block_iterator & operator=(const block_iterator &) = default; @@ -291,14 +356,21 @@ class ViewBlocksMod const block_iterator & other, index_type position) : iterator_base_t(position) - , _blocks_view(other._blocks_view) + , _blocks_view_domain(other._blocks_view_domain) { } constexpr block_iterator( const ViewBlocksModType & blocks_view, - index_type position) + index_type position) + : iterator_base_t(position) + , _blocks_view_domain(dash::domain(blocks_view)) + { } + + constexpr block_iterator( + ViewBlocksModType && blocks_view, + index_type position) : iterator_base_t(position) - , _blocks_view(blocks_view) + , _blocks_view_domain(std::forward(blocks_view)) { } constexpr block_type dereference(index_type idx) const { @@ -307,13 +379,14 @@ class ViewBlocksMod // Note that block index is relative to the domain and is // translated to global block index in IndexSetBlocks. return ViewBlockMod( - dash::domain(_blocks_view), idx); + _blocks_view_domain, + idx); } }; public: typedef block_iterator iterator; - typedef block_iterator const_iterator; + typedef block_iterator const_iterator; public: constexpr ViewBlocksMod() = delete; @@ -329,7 +402,7 @@ class ViewBlocksMod constexpr explicit ViewBlocksMod( const domain_type & domain) : base_t(domain) - , _index_set(*this) + , _index_set(domain) { } /** @@ -338,53 +411,51 @@ class ViewBlocksMod constexpr explicit ViewBlocksMod( domain_type && domain) : base_t(std::forward(domain)) - , _index_set(*this) + , _index_set(this->domain()) { } - constexpr iterator begin() const { - return const_iterator(*this, _index_set.first()); + // ---- offsets --------------------------------------------------------- + + // ---- size ------------------------------------------------------------ + + constexpr size_type size() const { + return index_set().size(); } - inline iterator begin() { + + // ---- access ---------------------------------------------------------- + + constexpr const_iterator begin() const { + return const_iterator(*const_cast(this), + _index_set.first()); + } + iterator begin() { return iterator(*this, _index_set.first()); } - constexpr iterator end() const { - return const_iterator(*this, _index_set.last() + 1); + constexpr const_iterator end() const { + return const_iterator(*const_cast(this), + _index_set.last() + 1); } - inline iterator end() { + iterator end() { return iterator(*this, _index_set.last() + 1); } constexpr block_type operator[](int offset) const { return *iterator(*this, _index_set[offset]); } - inline block_type operator[](int offset) { + block_type operator[](int offset) { return *iterator(*this, _index_set[offset]); } - constexpr auto local() const -//constexpr const local_type local() const { - -> decltype(dash::local( - std::declval< - typename std::add_lvalue_reference::type - >() )) { - return dash::local(this->domain()); - } - - inline auto local() -//inline local_type local() { - -> decltype(dash::local( - std::declval< - typename std::add_lvalue_reference::type - >() )) { - return dash::local(this->domain()); + constexpr local_type local() const { + return local_type(dash::local(this->domain())); } constexpr const global_type global() const { return dash::global(dash::domain(*this)); } - inline global_type global() { + global_type global() { return dash::global(dash::domain(*this)); } diff --git a/dash/include/dash/view/ViewIterator.h b/dash/include/dash/view/ViewIterator.h new file mode 100644 index 000000000..1ddd66542 --- /dev/null +++ b/dash/include/dash/view/ViewIterator.h @@ -0,0 +1,193 @@ +#ifndef DASH__VIEW__VIEW_ITERATOR_H__INCLUDED +#define DASH__VIEW__VIEW_ITERATOR_H__INCLUDED + +#include +#include +#include + +#include +#include + + +namespace dash { + +// -------------------------------------------------------------------- +// ViewIterator +// -------------------------------------------------------------------- + +template < + class DomainIterator, + class IndexSetType > +class ViewIterator + : public dash::internal::IndexIteratorBase< + ViewIterator, + typename DomainIterator::value_type, // value type + typename DomainIterator::difference_type, // difference type + typename DomainIterator::pointer, // pointer + typename DomainIterator::reference // reference +> { + typedef ViewIterator self_t; + typedef dash::internal::IndexIteratorBase< + ViewIterator, + typename DomainIterator::value_type, + typename DomainIterator::difference_type, + typename DomainIterator::pointer, + typename DomainIterator::reference > base_t; + + template + friend std::ostream & operator<<( + std::ostream & os, + const ViewIterator & view_it); +public: + typedef typename base_t::reference reference; + typedef typename base_t::value_type value_type; + typedef typename IndexSetType::index_type index_type; +private: + DomainIterator _domain_it; + IndexSetType _index_set; +public: + constexpr ViewIterator() = delete; + + template + ViewIterator( + const DomainItType & domain_it, + const IndexSetType & index_set, + index_type position) + : base_t(position) + , _domain_it(domain_it) + , _index_set(index_set) + { } + + template + ViewIterator( + DomainItType && domain_it, + const IndexSetType & index_set, + index_type position) + : base_t(position) + , _domain_it(std::forward(domain_it)) + , _index_set(index_set) + { } + + ViewIterator( + const self_t & other, + index_type position) + : base_t(position) + , _domain_it(other._domain_it) + , _index_set(other._index_set) + { } + + constexpr reference dereference(index_type idx) const { + return *(_domain_it + (_index_set[idx])); + } + + constexpr index_type gpos() const { + return (_index_set)[this->pos()]; + } + + constexpr const value_type * local() const { + return (_domain_it + (_index_set[this->pos()])).local(); + } + + inline value_type * local() { + return (_domain_it + (_index_set[this->pos()])).local(); + } + + constexpr dart_gptr_t dart_gptr() const { + return (_domain_it + _index_set[this->pos()]).dart_gptr(); + } + + constexpr explicit operator dart_gptr_t() const { + return dart_gptr(); + } + + constexpr explicit operator DomainIterator() const { + return (_domain_it + _index_set[this->pos()]); + } +}; + +template < + class DomainIterator, + class IndexSetType > +class ViewIterator + : public dash::internal::IndexIteratorBase< + ViewIterator, + DomainIterator, + std::ptrdiff_t, + DomainIterator *, + DomainIterator & > +{ + typedef ViewIterator self_t; + typedef dash::internal::IndexIteratorBase< + ViewIterator, + DomainIterator, + std::ptrdiff_t, + DomainIterator *, + DomainIterator & > base_t; + + template + friend std::ostream & operator<<( + std::ostream & os, + const ViewIterator & view_it); +public: + typedef DomainIterator & reference; + typedef DomainIterator value_type; + typedef std::ptrdiff_t index_type; +private: + DomainIterator * _domain_it; + IndexSetType _index_set; +public: + constexpr ViewIterator() = delete; + + template + ViewIterator( + DomainItType * domain_it, + const IndexSetType & index_set, + index_type position) + : base_t(position) + , _domain_it(domain_it) + , _index_set(index_set) + { } + + ViewIterator( + const self_t & other, + index_type position) + : base_t(position) + , _domain_it(other._domain_it) + , _index_set(other._index_set) + { } + + constexpr reference dereference(index_type idx) const { + return (_domain_it)[ (_index_set)[idx] ]; + } + + constexpr index_type gpos() const { + return (_index_set)[this->pos()]; + } + + constexpr const value_type * local() const { + return (_domain_it + (_index_set[this->pos()])).local(); + } + + inline value_type * local() { + return (_domain_it + (_index_set[this->pos()])).local(); + } +}; + +template +std::ostream & operator<<( + std::ostream & os, + const ViewIterator & view_it) +{ + std::ostringstream ss; + ss << dash::typestr(view_it) << " " + << "{ " + << "domain_it: " << view_it._domain_it << ", " + << "rpos: " << view_it.pos() << ", " + << "gpos: " << view_it.gpos() + << " }"; + return operator<<(os, ss.str()); +} + +} // namespace dash + +#endif // DASH__VIEW__VIEW_ITERATOR_H__INCLUDED diff --git a/dash/include/dash/view/ViewMod.h b/dash/include/dash/view/ViewMod.h index f037a989f..bd660ee93 100644 --- a/dash/include/dash/view/ViewMod.h +++ b/dash/include/dash/view/ViewMod.h @@ -6,9 +6,12 @@ #include #include +#include #include #include +#include +#include #include #include @@ -115,121 +118,34 @@ namespace dash { // Forward-declarations // ------------------------------------------------------------------------ -template < - dim_t NDim = 1> -class ViewOrigin; - template < class ViewModType, - class DomainType > + class DomainType, + dim_t NDim = dash::view_traits< + typename std::decay::type>::rank::value > class ViewModBase; template < - class DomainType = ViewOrigin<1> > + class DomainType, + dim_t NDim = dash::view_traits< + typename std::decay::type>::rank::value > class ViewLocalMod; template < - class DomainType = ViewOrigin<1>, - dim_t SubDim = 0 > + class DomainType, + dim_t SubDim = 0, + dim_t NDim = dash::view_traits< + typename std::decay::type>::rank::value > class ViewSubMod; template < - class DomainType = ViewOrigin<1> > + class DomainType, + dim_t NDim = dash::view_traits< + typename std::decay::type>::rank::value > class ViewGlobalMod; +#endif // DOXYGEN -// -------------------------------------------------------------------- -// ViewOrigin -// -------------------------------------------------------------------- - -/** - * Monotype for the logical symbol that represents a view origin. - */ -template -class ViewOrigin -{ - typedef ViewOrigin self_t; - - public: - typedef dash::default_index_t index_type; - typedef self_t domain_type; - typedef IndexSetIdentity index_set_type; - - public: - typedef std::integral_constant is_local; - typedef std::integral_constant rank; - - private: - std::array _extents = { }; - index_set_type _index_set; - public: - constexpr ViewOrigin() = delete; - constexpr ViewOrigin(self_t &&) = default; - constexpr ViewOrigin(const self_t &) = default; - ~ViewOrigin() = default; - self_t & operator=(self_t &&) = default; - self_t & operator=(const self_t &) = default; - - constexpr explicit ViewOrigin( - std::initializer_list extents) - : _extents(extents) - , _index_set(*this) - { } - - constexpr const domain_type & domain() const { - return *this; - } - - inline domain_type & domain() { - return *this; - } - - constexpr const index_set_type & index_set() const { - return _index_set; - } - - constexpr bool operator==(const self_t & rhs) const { - return (this == &rhs); - } - - constexpr bool operator!=(const self_t & rhs) const { - return !(*this == rhs); - } - - template - constexpr index_type extent() const { - return _extents[ExtentDim]; - } - - constexpr index_type size() const { - return _size<0>(); - } - - private: - template - constexpr index_type _size() const { - return extent() + - (SizeDim < NDim - ? _size() - : 0); - } -}; - -template -struct view_traits> { - typedef ViewOrigin origin_type; - typedef ViewOrigin domain_type; - typedef ViewOrigin image_type; - typedef typename ViewOrigin::index_type index_type; - typedef typename ViewOrigin::index_set_type index_set_type; - - typedef std::integral_constant is_projection; - typedef std::integral_constant is_view; - typedef std::integral_constant is_origin; - typedef std::integral_constant is_local; - - typedef std::integral_constant rank; -}; // ------------------------------------------------------------------------ @@ -238,25 +154,84 @@ struct view_traits> { template < class ViewModType, - class DomainType > -class ViewModBase { - typedef ViewModBase self_t; -//typedef typename std::remove_reference::type domain_value_type; - public: - typedef DomainType domain_type; - typedef typename view_traits::origin_type origin_type; - typedef typename view_traits::index_type index_type; - typedef typename origin_type::value_type value_type; - - typedef std::integral_constant rank; + class DomainType, + dim_t NDim > +class ViewModBase +{ + typedef ViewModBase self_t; +public: + typedef DomainType domain_type; - protected: - dash::UniversalMember _domain; + typedef typename std::conditional< + view_traits::is_origin::value, + const domain_type &, + domain_type + >::type + domain_member_type; + + // TODO: BUG! + // For example, assume + // domain = sub(local(array)) + // then view_traits::is_local resolves to `true` + // and domain_type is defined as ViewSub> + // instead of ViewLocal or Array::local_type. + // + // Note that the origin of ViewLocalMod is the global origin + // while the origin of and view on ViewLocalMod is the local + // origin. + typedef typename std::conditional< + view_traits::is_local::value, + // domain_type, + typename view_traits< + typename view_traits::origin_type + >::local_type, + typename view_traits::origin_type + >::type + origin_type; + + typedef decltype( + dash::begin( + std::declval< + typename std::add_lvalue_reference::type + >() )) + origin_iterator; + + typedef decltype( + dash::begin( + std::declval< + typename std::add_lvalue_reference::type + >() )) + const_origin_iterator; + + typedef + decltype(*dash::begin( + std::declval< + typename std::add_lvalue_reference::type + >() )) + reference; + + typedef + decltype(*dash::begin( + std::declval< + typename std::add_lvalue_reference::type + >() )) + const_reference; + + typedef typename view_traits::index_type index_type; + typedef typename view_traits::size_type size_type; + typedef typename origin_type::value_type value_type; + + typedef std::integral_constant rank; + + static constexpr dim_t ndim() { return NDim; } + +protected: + domain_member_type _domain; ViewModType & derived() { return static_cast(*this); } - const ViewModType & derived() const { + constexpr const ViewModType & derived() const { return static_cast(*this); } @@ -275,14 +250,19 @@ class ViewModBase { { } constexpr ViewModBase() = delete; - constexpr ViewModBase(const self_t &) = delete; - self_t & operator=(const self_t &) = delete; + ~ViewModBase() = default; - public: +public: + constexpr ViewModBase(const self_t &) = default; constexpr ViewModBase(self_t &&) = default; + self_t & operator=(const self_t &) = default; self_t & operator=(self_t &&) = default; - constexpr const domain_type & domain() const { + constexpr const domain_type & domain() const & { + return _domain; + } + + constexpr domain_type domain() const && { return _domain; } @@ -298,6 +278,38 @@ class ViewModBase { return view_traits::is_local::value; } + // ---- extents --------------------------------------------------------- + + constexpr const std::array extents() const { + return domain().extents(); + } + + template + constexpr size_type extent() const { + return domain().template extent(); + } + + constexpr size_type extent(dim_t shape_dim) const { + return domain().extent(shape_dim); + } + + // ---- offsets --------------------------------------------------------- + + constexpr const std::array offsets() const { + return domain().offsets(); + } + + template + constexpr index_type offset() const { + return domain().template offset(); + } + + constexpr index_type offset(dim_t shape_dim) const { + return domain().offset(shape_dim); + } + + // ---- size ------------------------------------------------------------ + constexpr index_type size() const { return dash::index(derived()).size(); } @@ -309,17 +321,19 @@ class ViewModBase { // ------------------------------------------------------------------------ template < - class DomainType > -struct view_traits > { + class DomainType, + dim_t NDim > +struct view_traits > { typedef DomainType domain_type; typedef typename view_traits::origin_type origin_type; typedef typename view_traits::pattern_type pattern_type; typedef typename domain_type::local_type image_type; - typedef ViewLocalMod local_type; + typedef ViewLocalMod local_type; typedef domain_type global_type; - typedef typename DomainType::index_type index_type; - typedef dash::IndexSetLocal< ViewLocalMod > index_set_type; + typedef typename view_traits::index_type index_type; + typedef typename view_traits::size_type size_type; + typedef dash::IndexSetLocal index_set_type; typedef std::integral_constant is_projection; typedef std::integral_constant is_view; @@ -330,39 +344,75 @@ struct view_traits > { }; template < - class DomainType > + class DomainType, + dim_t NDim > class ViewLocalMod -: public ViewModBase< ViewLocalMod, DomainType > { - public: +: public ViewModBase< + ViewLocalMod, + DomainType, + NDim > { +public: typedef DomainType domain_type; typedef typename view_traits::origin_type origin_type; typedef typename domain_type::local_type image_type; - typedef typename DomainType::index_type index_type; - private: - typedef ViewLocalMod self_t; - typedef ViewModBase< ViewLocalMod, DomainType > base_t; - public: - typedef dash::IndexSetLocal< ViewLocalMod > index_set_type; + typedef typename view_traits::index_type index_type; + typedef typename view_traits::size_type size_type; +private: + typedef ViewLocalMod self_t; + typedef ViewModBase< + ViewLocalMod, DomainType, NDim > base_t; +public: + typedef dash::IndexSetLocal index_set_type; typedef self_t local_type; typedef typename domain_type::global_type global_type; typedef std::integral_constant is_local; - typedef decltype(dash::begin(dash::local( - std::declval< - typename std::add_lvalue_reference::type >() - ))) + typedef + decltype( + dash::begin( + dash::local(dash::origin( + std::declval< + typename std::add_lvalue_reference::type >() + )))) iterator; - private: + typedef + decltype( + dash::begin( + dash::local(dash::origin( + std::declval< + typename std::add_lvalue_reference::type >() + )))) + const_iterator; + + typedef + decltype( + *(dash::begin( + dash::local(dash::origin( + std::declval< + typename std::add_lvalue_reference::type >() + ))))) + reference; + + typedef + decltype( + *(dash::begin( + dash::local(dash::origin( + std::declval< + typename std::add_lvalue_reference::type >() + ))))) + const_reference; + +private: index_set_type _index_set; - public: +public: constexpr ViewLocalMod() = delete; constexpr ViewLocalMod(self_t &&) = default; - constexpr ViewLocalMod(const self_t &) = delete; + constexpr ViewLocalMod(const self_t &) = default; ~ViewLocalMod() = default; self_t & operator=(self_t &&) = default; - self_t & operator=(const self_t &) = delete; + self_t & operator=(const self_t &) = default; /** * Constructor, creates a view on a given domain. @@ -370,7 +420,7 @@ class ViewLocalMod constexpr explicit ViewLocalMod( domain_type && domain) : base_t(std::forward(domain)) - , _index_set(*this) + , _index_set(this->domain()) { } /** @@ -379,7 +429,7 @@ class ViewLocalMod constexpr explicit ViewLocalMod( const DomainType & domain) : base_t(domain) - , _index_set(*this) + , _index_set(domain) { } constexpr bool operator==(const self_t & rhs) const { @@ -392,60 +442,85 @@ class ViewLocalMod return not (*this == rhs); } - constexpr iterator begin() const { + // ---- extents --------------------------------------------------------- + + constexpr const std::array extents() const { + return _index_set.extents(); + } + + template + constexpr size_type extent() const { + return _index_set.template extent(); + } + + constexpr size_type extent(dim_t shape_dim) const { + return _index_set.extent(shape_dim); + } + + // ---- offsets --------------------------------------------------------- + + constexpr const std::array offsets() const { + return _index_set.offsets(); + } + + // ---- size ------------------------------------------------------------ + + constexpr size_type size(dim_t sub_dim = 0) const { + return index_set().size(sub_dim); + } + + // ---- access ---------------------------------------------------------- + + constexpr const_iterator begin() const { + return dash::begin( + dash::local( + dash::origin(*this) )) + + _index_set[0]; + } + + iterator begin() { + return dash::begin( + dash::local( + const_cast(dash::origin(*this)) + )) + + _index_set[0]; + } + + constexpr const_iterator end() const { return dash::begin( dash::local( - dash::origin( - *this - ) - ) - ) -#if 1 - + _index_set.pre()[ - _index_set.first() - ]; -#else - + dash::index(dash::local(dash::domain(*this))).pre()[ - *dash::begin(dash::index(dash::local(dash::domain(*this)))) - ]; -#endif - } - - constexpr iterator end() const { + dash::origin(*this) )) + + _index_set[_index_set.size() - 1] + 1; + } + + iterator end() { return dash::begin( dash::local( - dash::origin( - *this - ) - ) - ) -#if 1 - + _index_set.pre()[ - _index_set.last() - ] + 1; -#else - + dash::index(dash::local(dash::domain(*this))).pre()[ - *(dash::begin(dash::index(dash::local(dash::domain(*this)))) - + dash::index(dash::local(dash::domain(*this))).size() - - 1 ) - ] + 1; -#endif - } - - constexpr auto operator[](int offset) const - -> decltype(*(dash::begin( - dash::local(dash::origin( - std::declval< - typename std::add_lvalue_reference::type >() - ))))) { - return *(this->begin() + offset); + const_cast(dash::origin(*this)) + )) + + _index_set[_index_set.size() - 1] + 1; + } + + constexpr const_reference operator[](int offset) const { + return *(dash::begin( + dash::local( + dash::origin(*this) )) + + _index_set[offset]); + } + + reference operator[](int offset) { + return *(dash::begin( + dash::local( + const_cast(dash::origin(*this)) + )) + + _index_set[offset]); } constexpr const local_type & local() const { return *this; } - inline local_type & local() { + local_type & local() { return *this; } @@ -453,10 +528,6 @@ class ViewLocalMod return dash::global(dash::domain(*this)); } - inline global_type & global() { - return dash::global(dash::domain(*this)); - } - constexpr const index_set_type & index_set() const { return _index_set; } @@ -469,17 +540,21 @@ class ViewLocalMod template < class DomainType, - dim_t SubDim > -struct view_traits > { + dim_t SubDim, + dim_t NDim > +struct view_traits > { typedef DomainType domain_type; typedef typename view_traits::origin_type origin_type; typedef typename view_traits::pattern_type pattern_type; - typedef ViewSubMod image_type; - typedef ViewSubMod local_type; - typedef ViewSubMod global_type; + typedef ViewSubMod image_type; +//typedef ViewSubMod local_type; + typedef ViewLocalMod< + ViewSubMod, NDim> local_type; + typedef ViewSubMod global_type; typedef typename DomainType::index_type index_type; - typedef dash::IndexSetSub> index_set_type; + typedef typename DomainType::size_type size_type; + typedef dash::IndexSetSub index_set_type; typedef std::integral_constant is_projection; typedef std::integral_constant is_view; @@ -493,213 +568,161 @@ struct view_traits > { template < class DomainType, - dim_t SubDim > + dim_t SubDim, + dim_t NDim > class ViewSubMod : public ViewModBase< - ViewSubMod, - DomainType > + ViewSubMod, + DomainType, + NDim > { public: - typedef DomainType domain_type; - typedef typename view_traits::index_type index_type; + typedef DomainType domain_type; private: - typedef ViewSubMod self_t; - typedef ViewModBase< ViewSubMod, DomainType > base_t; + typedef ViewSubMod self_t; + typedef ViewModBase< + ViewSubMod, + domain_type, NDim > base_t; + public: + typedef typename base_t::origin_type origin_type; + + typedef typename view_traits::index_type index_type; + typedef typename view_traits::size_type size_type; public: - typedef dash::IndexSetSub< ViewSubMod > index_set_type; - typedef ViewLocalMod local_type; - typedef self_t global_type; + typedef ViewLocalMod local_type; + typedef self_t global_type; + + typedef std::integral_constant is_local; - typedef std::integral_constant is_local; + typedef dash::IndexSetSub index_set_type; - typedef decltype(dash::begin( - std::declval< - typename std::add_lvalue_reference::type - >() )) + typedef ViewIterator< + typename base_t::origin_iterator, index_set_type > iterator; + typedef ViewIterator< + typename base_t::const_origin_iterator, index_set_type > + const_iterator; + + using reference = typename base_t::reference; + using const_reference = typename base_t::const_reference; private: - index_type _begin_idx; - index_type _end_idx; index_set_type _index_set; public: constexpr ViewSubMod() = delete; constexpr ViewSubMod(self_t &&) = default; - constexpr ViewSubMod(const self_t &) = delete; + constexpr ViewSubMod(const self_t &) = default; ~ViewSubMod() = default; self_t & operator=(self_t &&) = default; - self_t & operator=(const self_t &) = delete; + self_t & operator=(const self_t &) = default; constexpr ViewSubMod( domain_type && domain, index_type begin, index_type end) : base_t(std::forward(domain)) - , _begin_idx(begin) - , _end_idx(end) - , _index_set(*this, begin, end) + , _index_set(this->domain(), begin, end) { } constexpr ViewSubMod( - domain_type & domain, - index_type begin, - index_type end) + const domain_type & domain, + index_type begin, + index_type end) : base_t(domain) - , _begin_idx(begin) - , _end_idx(end) - , _index_set(*this, begin, end) + , _index_set(domain, begin, end) { } - constexpr iterator begin() const { - return dash::begin(dash::domain(*this)) + - *dash::begin(dash::index(*this)); - } - - constexpr iterator end() const { - return dash::begin(dash::domain(*this)) + - *dash::end(dash::index(*this)); - } + // ---- extents --------------------------------------------------------- - constexpr auto operator[](int offset) const - -> decltype(*(dash::begin( - std::declval< - typename std::add_lvalue_reference::type - >() ))) { - return *(this->begin() + offset); + constexpr std::array extents() const { + return _index_set.extents(); } - constexpr const index_set_type & index_set() const { - return _index_set; + template + constexpr size_type extent() const { + return _index_set.template extent(); } - constexpr local_type local() const { - return local_type(*this); + constexpr size_type extent(dim_t shape_dim) const { + return _index_set.extent(shape_dim); } -}; - - -// ------------------------------------------------------------------------ -// ViewGlobalMod -// ------------------------------------------------------------------------ -template < - class DomainType > -struct view_traits > { - typedef DomainType domain_type; - typedef typename view_traits::origin_type origin_type; - typedef typename view_traits::pattern_type pattern_type; - typedef typename domain_type::global_type image_type; - typedef typename domain_type::local_type local_type; - typedef ViewGlobalMod global_type; + // ---- offsets --------------------------------------------------------- - typedef typename DomainType::index_type index_type; - typedef dash::IndexSetLocal< ViewLocalMod > index_set_type; - - typedef std::integral_constant is_projection; - typedef std::integral_constant is_view; - typedef std::integral_constant is_origin; - typedef std::integral_constant is_local; -}; - -template < - class DomainType > -class ViewGlobalMod -: public ViewModBase< ViewGlobalMod, DomainType > -{ - public: - typedef DomainType domain_type; - typedef typename view_traits::origin_type origin_type; - typedef typename domain_type::global_type image_type; - typedef typename DomainType::index_type index_type; - private: - typedef ViewGlobalMod self_t; - typedef ViewModBase< ViewLocalMod, DomainType > base_t; - public: - typedef dash::IndexSetGlobal< ViewGlobalMod > index_set_type; - typedef self_t global_type; - typedef typename domain_type::local_type local_type; - - typedef std::integral_constant is_local; + template + constexpr index_type offset() const { + return _index_set.template offset(); + } - private: - index_set_type _index_set; - public: - constexpr ViewGlobalMod() = delete; - constexpr ViewGlobalMod(self_t &&) = default; - constexpr ViewGlobalMod(const self_t &) = default; - ~ViewGlobalMod() = default; - self_t & operator=(self_t &&) = default; - self_t & operator=(const self_t &) = default; + constexpr std::array offsets() const { + return _index_set.offsets(); + } - /** - * Constructor, creates a view on a given domain. - */ - constexpr explicit ViewGlobalMod( - const domain_type & domain) - : base_t(domain) - , _index_set(*this) - { } + constexpr index_type offset(dim_t shape_dim) const { + return _index_set.offset(shape_dim); + } - /** - * Constructor, creates a view on a given domain. - */ - constexpr explicit ViewGlobalMod( - domain_type && domain) - : base_t(std::forward(domain)) - , _index_set(*this) - { } + // ---- size ------------------------------------------------------------ - constexpr auto begin() const - -> decltype(dash::begin(dash::global(dash::domain(*this)))) { - return dash::begin( - dash::global( - dash::domain( - *this))); + constexpr size_type size(dim_t sub_dim = 0) const { + return _index_set.size(sub_dim); } - constexpr auto end() const - -> decltype(dash::end(dash::global(dash::domain(*this)))) { - return dash::begin( - dash::global( - dash::domain( - *this))) - + *dash::end(dash::index(dash::domain(*this))); + // ---- access ---------------------------------------------------------- + + constexpr const_iterator begin() const { + return const_iterator( + dash::origin(*this).begin(), + _index_set, 0); } - constexpr auto operator[](int offset) const - -> decltype(*(dash::begin( - dash::global(dash::domain(*this))))) { - return *(this->begin() + offset); + iterator begin() { + return iterator( + const_cast( + dash::origin(*this) + ).begin(), + _index_set, 0); } - constexpr const local_type & local() const { - // if any parent domain is local, it will return *this - // and in effect eliminate dash::global( ... dash::local( ... )) - return dash::local(dash::domain(*this)); + constexpr const_iterator end() const { + return const_iterator( + dash::origin(*this).begin(), + _index_set, _index_set.size()); } - inline local_type & local() { - // if any parent domain is local, it will return *this - // and in effect eliminate dash::global( ... dash::local( ... )) - return dash::local(dash::domain(*this)); + iterator end() { + return iterator( + const_cast( + dash::origin(*this) + ).begin(), + _index_set, _index_set.size()); } - constexpr const global_type & global() const { - return *this; + constexpr const_reference operator[](int offset) const { + return *(const_iterator(dash::origin(*this).begin(), + _index_set, offset)); } - inline global_type & global() { - return *this; + reference operator[](int offset) { + return *(iterator(const_cast( + dash::origin(*this) + ).begin(), + _index_set, offset)); } constexpr const index_set_type & index_set() const { return _index_set; } + + constexpr local_type local() const { + return local_type(*this); + } }; -#endif // DOXYGEN } // namespace dash +#include + #endif // DASH__VIEW__VIEW_MOD_H__INCLUDED diff --git a/dash/include/dash/view/ViewMod1D.h b/dash/include/dash/view/ViewMod1D.h new file mode 100644 index 000000000..dc4859fa2 --- /dev/null +++ b/dash/include/dash/view/ViewMod1D.h @@ -0,0 +1,475 @@ +#ifndef DASH__VIEW__VIEW_MOD_1D_H__INCLUDED +#define DASH__VIEW__VIEW_MOD_1D_H__INCLUDED + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + + +namespace dash { + +#ifndef DOXYGEN + +// ------------------------------------------------------------------------ +// ViewSubMod +// ------------------------------------------------------------------------ + +template < + class DomainType, + dim_t SubDim > +struct view_traits > { + typedef DomainType domain_type; + typedef typename view_traits::origin_type origin_type; + typedef typename view_traits::pattern_type pattern_type; + typedef ViewSubMod image_type; +//typedef ViewSubMod local_type; + typedef ViewLocalMod< + ViewSubMod, 1> local_type; + typedef ViewSubMod global_type; + + typedef typename DomainType::index_type index_type; + typedef typename DomainType::size_type size_type; + typedef dash::IndexSetSub index_set_type; + + typedef std::integral_constant is_projection; + typedef std::integral_constant is_view; + typedef std::integral_constant is_origin; + + typedef std::integral_constant::is_local::value > is_local; + + typedef std::integral_constant rank; +}; + + +template < + class DomainType, + dim_t SubDim > +class ViewSubMod +: public ViewModBase< + ViewSubMod, + DomainType > +{ + public: + typedef DomainType domain_type; + private: + typedef ViewSubMod self_t; + typedef ViewModBase< ViewSubMod, domain_type > base_t; + public: + typedef typename base_t::origin_type origin_type; + + typedef typename view_traits::index_type index_type; + typedef typename view_traits::size_type size_type; + public: + typedef dash::IndexSetSub index_set_type; + typedef ViewLocalMod local_type; + typedef self_t global_type; + + typedef std::integral_constant is_local; + + typedef ViewIterator< + typename base_t::origin_iterator, index_set_type > + iterator; + typedef ViewIterator< + typename base_t::const_origin_iterator, index_set_type > + const_iterator; + + using reference = typename base_t::reference; + using const_reference = typename base_t::const_reference; + + private: + index_set_type _index_set; + + public: + constexpr ViewSubMod() = delete; + constexpr ViewSubMod(self_t &&) = default; + constexpr ViewSubMod(const self_t &) = default; + ~ViewSubMod() = default; + self_t & operator=(self_t &&) = default; + self_t & operator=(const self_t &) = default; + + constexpr ViewSubMod( + domain_type && domain, + index_type begin, + index_type end) + : base_t(std::forward(domain)) + , _index_set(this->domain(), begin, end) + { } + + constexpr ViewSubMod( + const domain_type & domain, + index_type begin, + index_type end) + : base_t(domain) + , _index_set(domain, begin, end) + { } + + constexpr const_iterator begin() const { + return const_iterator(dash::origin(*this).begin(), + _index_set, 0); + } + + iterator begin() { + return iterator(const_cast( + dash::origin(*this) + ).begin(), + _index_set, 0); + } + + constexpr const_iterator end() const { + return const_iterator(dash::origin(*this).begin(), + _index_set, _index_set.size()); + } + + iterator end() { + return iterator(const_cast( + dash::origin(*this) + ).begin(), + _index_set, _index_set.size()); + } + + constexpr const_reference operator[](int offset) const { + return *(const_iterator(dash::origin(*this).begin(), + _index_set, offset)); + } + + reference operator[](int offset) { + return *(iterator(const_cast( + dash::origin(*this) + ).begin(), + _index_set, offset)); + } + + constexpr const index_set_type & index_set() const { + return _index_set; + } + + constexpr local_type local() const { + return local_type(*this); + } +}; // class ViewSubMod + + +// ------------------------------------------------------------------------ +// ViewLocalMod +// ------------------------------------------------------------------------ + +template < + class DomainType > +struct view_traits > { + typedef DomainType domain_type; + typedef typename view_traits::origin_type origin_type; + typedef typename view_traits::pattern_type pattern_type; + typedef typename domain_type::local_type image_type; + typedef ViewLocalMod local_type; + typedef domain_type global_type; + + typedef typename view_traits::index_type index_type; + typedef typename view_traits::size_type size_type; + typedef dash::IndexSetLocal index_set_type; + + typedef std::integral_constant is_projection; + typedef std::integral_constant is_view; + typedef std::integral_constant is_origin; + typedef std::integral_constant is_local; + + typedef std::integral_constant rank; +}; + +template < + class DomainType > +class ViewLocalMod +: public ViewModBase< + ViewLocalMod, + DomainType > { + public: + typedef DomainType domain_type; + typedef typename view_traits::origin_type origin_type; + typedef typename domain_type::local_type image_type; + typedef typename domain_type::index_type index_type; + typedef typename domain_type::size_type size_type; + private: + typedef ViewLocalMod self_t; + typedef ViewModBase< + ViewLocalMod, DomainType, 1 > base_t; + public: + typedef dash::IndexSetLocal index_set_type; + typedef self_t local_type; + typedef typename domain_type::global_type global_type; + + typedef std::integral_constant is_local; + + typedef + decltype( + dash::begin( + dash::local(dash::origin( + std::declval< + typename std::add_lvalue_reference::type >() + )))) + iterator; + + typedef + decltype( + dash::begin( + dash::local(dash::origin( + std::declval< + typename std::add_lvalue_reference::type >() + )))) + const_iterator; + + typedef + decltype( + *(dash::begin( + dash::local(dash::origin( + std::declval< + typename std::add_lvalue_reference::type >() + ))))) + reference; + + typedef + decltype( + *(dash::begin( + dash::local(dash::origin( + std::declval< + typename std::add_lvalue_reference::type >() + ))))) + const_reference; + + private: + index_set_type _index_set; + public: + constexpr ViewLocalMod() = delete; + constexpr ViewLocalMod(self_t &&) = default; + constexpr ViewLocalMod(const self_t &) = default; + ~ViewLocalMod() = default; + self_t & operator=(self_t &&) = default; + self_t & operator=(const self_t &) = default; + + /** + * Constructor, creates a view on a given domain. + */ + constexpr explicit ViewLocalMod( + domain_type && domain) + : base_t(std::forward(domain)) + , _index_set(this->domain()) + { } + + /** + * Constructor, creates a view on a given domain. + */ + constexpr explicit ViewLocalMod( + const DomainType & domain) + : base_t(domain) + , _index_set(domain) + { } + + constexpr bool operator==(const self_t & rhs) const { + return (this == &rhs || + ( base_t::operator==(rhs) && + _index_set == rhs._index_set ) ); + } + + constexpr bool operator!=(const self_t & rhs) const { + return !(*this == rhs); + } + + constexpr const_iterator begin() const { + return dash::begin( + dash::local( + dash::origin(*this) )) + + _index_set[0]; + } + + iterator begin() { + return dash::begin( + dash::local( + const_cast(dash::origin(*this)) + )) + + _index_set[0]; + } + + constexpr const_iterator end() const { + return dash::begin( + dash::local( + dash::origin(*this) )) + + _index_set[_index_set.size() - 1] + 1; + } + + iterator end() { + return dash::begin( + dash::local( + const_cast(dash::origin(*this)) + )) + + _index_set[_index_set.size() - 1] + 1; + } + + constexpr const_reference operator[](int offset) const { + return *(dash::begin( + dash::local( + dash::origin(*this) )) + + _index_set[offset]); + } + + reference operator[](int offset) { + return *(dash::begin( + dash::local( + const_cast(dash::origin(*this)) + )) + + _index_set[offset]); + } + + constexpr const local_type & local() const { + return *this; + } + + constexpr const global_type & global() const { + return dash::global(dash::domain(*this)); + } + + constexpr const index_set_type & index_set() const { + return _index_set; + } +}; // class ViewLocalMod + + +// ------------------------------------------------------------------------ +// ViewGlobalMod +// ------------------------------------------------------------------------ + +template < + class DomainType > +struct view_traits > { + typedef DomainType domain_type; + typedef typename view_traits::origin_type origin_type; + typedef typename view_traits::pattern_type pattern_type; + typedef typename domain_type::global_type image_type; + typedef typename domain_type::local_type local_type; + typedef ViewGlobalMod global_type; + + typedef typename DomainType::index_type index_type; + typedef typename DomainType::size_type size_type; + typedef dash::IndexSetLocal< DomainType > index_set_type; + + typedef std::integral_constant is_projection; + typedef std::integral_constant is_view; + typedef std::integral_constant is_origin; + typedef std::integral_constant is_local; + + typedef std::integral_constant rank; +}; + +template < + class DomainType > +class ViewGlobalMod +: public ViewModBase< ViewGlobalMod, DomainType > { + public: + typedef DomainType domain_type; + private: + typedef ViewGlobalMod self_t; + typedef ViewModBase< ViewLocalMod, DomainType > base_t; + public: + typedef typename base_t::origin_type origin_type; + typedef typename domain_type::global_type image_type; + typedef typename view_traits::index_type index_type; + typedef typename view_traits::size_type size_type; + public: + typedef dash::IndexSetGlobal< DomainType > index_set_type; + typedef self_t global_type; + typedef typename domain_type::local_type local_type; + + typedef std::integral_constant is_local; + + private: + index_set_type _index_set; + public: + constexpr ViewGlobalMod() = delete; + constexpr ViewGlobalMod(self_t &&) = default; + constexpr ViewGlobalMod(const self_t &) = default; + ~ViewGlobalMod() = default; + self_t & operator=(self_t &&) = default; + self_t & operator=(const self_t &) = default; + + /** + * Constructor, creates a view on a given domain. + */ + constexpr explicit ViewGlobalMod( + domain_type && domain) + : base_t(std::forward(domain)) + , _index_set(this->domain()) + { } + + /** + * Constructor, creates a view on a given domain. + */ + constexpr explicit ViewGlobalMod( + const domain_type & domain) + : base_t(domain) + , _index_set(domain) + { } + + constexpr auto begin() const + -> decltype(dash::begin(dash::global(dash::domain(*this)))) { + return dash::begin( + dash::global( + dash::domain( + *this))); + } + + constexpr auto end() const + -> decltype(dash::end(dash::global(dash::domain(*this)))) { + return dash::begin( + dash::global( + dash::domain( + *this))) + + *dash::end(dash::index(dash::domain(*this))); + } + + constexpr auto operator[](int offset) const + -> decltype(*(dash::begin( + dash::global(dash::domain(*this))))) { + return *(this->begin() + offset); + } + + constexpr const local_type & local() const { + // if any parent domain is local, it will return *this + // and in effect eliminate dash::global( ... dash::local( ... )) + return dash::local(dash::domain(*this)); + } + + inline local_type & local() { + // if any parent domain is local, it will return *this + // and in effect eliminate dash::global( ... dash::local( ... )) + return dash::local(dash::domain(*this)); + } + + constexpr const global_type & global() const { + return *this; + } + + inline global_type & global() { + return *this; + } + + constexpr const index_set_type & index_set() const { + return _index_set; + } +}; // class ViewGlobalMod + +#endif // DOXYGEN + +} // namespace dash + +#endif // DASH__VIEW__VIEW_MOD_1D_H__INCLUDED diff --git a/dash/include/dash/view/ViewOrigin.h b/dash/include/dash/view/ViewOrigin.h new file mode 100644 index 000000000..a20a452c0 --- /dev/null +++ b/dash/include/dash/view/ViewOrigin.h @@ -0,0 +1,134 @@ +#ifndef DASH__VIEW__VIEW_ORIGIN_H__INCLUDED +#define DASH__VIEW__VIEW_ORIGIN_H__INCLUDED + +#include +#include +#include + +#include +#include +#include + + +namespace dash { + +// ------------------------------------------------------------------------ +// ViewOrigin +// ------------------------------------------------------------------------ + +/** + * Monotype for the logical symbol that represents a view origin. + */ +template +class ViewOrigin +{ + typedef ViewOrigin self_t; + +public: + typedef dash::default_index_t index_type; + typedef dash::default_extent_t size_type; + typedef self_t domain_type; + typedef self_t local_type; + typedef self_t global_type; + typedef IndexSetIdentity index_set_type; + +public: + typedef std::integral_constant is_local; + typedef std::integral_constant rank; + +private: + std::array _extents = { }; + std::array _offsets = { }; + index_set_type _index_set; +public: + constexpr ViewOrigin() = delete; + constexpr ViewOrigin(self_t &&) = default; + constexpr ViewOrigin(const self_t &) = default; + ~ViewOrigin() = default; + self_t & operator=(self_t &&) = default; + self_t & operator=(const self_t &) = default; + + constexpr explicit ViewOrigin( + std::initializer_list extents) + : _extents(extents) + , _index_set(*this) + { } + + constexpr const domain_type & domain() const { + return *this; + } + + constexpr const index_set_type & index_set() const { + return _index_set; + } + + constexpr bool operator==(const self_t & rhs) const { + return (this == &rhs); + } + + constexpr bool operator!=(const self_t & rhs) const { + return !(*this == rhs); + } + + // ---- extents --------------------------------------------------------- + + constexpr const std::array extents() const { + return _extents; + } + + template + constexpr index_type extent() const { + return _extents[ExtentDim]; + } + + constexpr index_type extent(dim_t extent_dim) const { + return _extents[extent_dim]; + } + + // ---- offsets --------------------------------------------------------- + + constexpr const std::array & offsets() const { + return _offsets; + } + + template + constexpr index_type offset() const { + return _offsets[OffsetDim]; + } + + constexpr index_type offset(dim_t offset_dim) const { + return _offsets[offset_dim]; + } + + // ---- size ------------------------------------------------------------ + + template + constexpr index_type size() const { + return extent() * + (SizeDim + 1 < NDim + ? size() + : 1); + } +}; + +template +struct view_traits> { + typedef ViewOrigin origin_type; + typedef ViewOrigin domain_type; + typedef ViewOrigin image_type; + + typedef typename ViewOrigin::index_type index_type; + typedef typename ViewOrigin::size_type size_type; + typedef typename ViewOrigin::index_set_type index_set_type; + + typedef std::integral_constant is_projection; + typedef std::integral_constant is_view; + typedef std::integral_constant is_origin; + typedef std::integral_constant is_local; + + typedef std::integral_constant rank; +}; + +} // namespace dash + +#endif // DASH__VIEW__VIEW_ORIGIN_H__INCLUDED diff --git a/dash/include/dash/view/ViewTraits.h b/dash/include/dash/view/ViewTraits.h index 653775bc6..fc0555981 100644 --- a/dash/include/dash/view/ViewTraits.h +++ b/dash/include/dash/view/ViewTraits.h @@ -3,6 +3,7 @@ #include +#include #include @@ -52,24 +53,23 @@ template class IndexSetIdentity; namespace detail { + /** + * Definition of type trait \c dash::detail::has_type_domain_type + * with static member \c value indicating whether type \c T provides + * dependent type \c domain_type. + */ + DASH__META__DEFINE_TRAIT__HAS_TYPE(domain_type); + DASH__META__DEFINE_TRAIT__HAS_TYPE(index_set_type); +} - template - struct _has_domain_type - { - private: - typedef char yes; - typedef struct { char array[2]; } no; - - template static yes test(typename C::domain_type*); - template static no test(...); - public: - static constexpr bool value = sizeof(test(0)) == sizeof(yes); - }; - -} // namespace detail - +/** + * Definition of type trait \c dash::is_view + * with static member \c value indicating whether type \c T is a model + * of the View concept. + */ template -struct is_view : dash::detail::_has_domain_type { }; +// struct is_view : dash::detail::has_type_domain_type { }; +struct is_view : dash::detail::has_type_index_set_type { }; @@ -87,14 +87,19 @@ namespace detail { * Specialization of \c dash::view_traits for view types. */ template - struct _view_traits + struct _view_traits< + ViewT, + true, // is view + true // is range + > { typedef std::integral_constant is_projection; typedef std::integral_constant is_view; /// Whether the view is the origin domain. - typedef std::integral_constant is_origin; + typedef std::integral_constant is_origin; typedef typename ViewT::index_type index_type; + typedef typename ViewT::size_type size_type; typedef typename ViewT::index_set_type index_set_type; typedef typename ViewT::domain_type domain_type; typedef std::integral_constant - struct _view_traits { + struct _view_traits< + ContainerT, + false, // is view + true // is range + > + { typedef ContainerT origin_type; typedef ContainerT domain_type; typedef ContainerT image_type; typedef ContainerT global_type; typedef typename ContainerT::local_type local_type; typedef typename ContainerT::index_type index_type; + typedef typename ContainerT::size_type size_type; typedef typename dash::IndexSetIdentity index_set_type; typedef typename ContainerT::pattern_type pattern_type; diff --git a/dash/include/libdash.h b/dash/include/libdash.h index a8af19ddf..f0fe6993b 100644 --- a/dash/include/libdash.h +++ b/dash/include/libdash.h @@ -17,6 +17,7 @@ namespace dash { #include #include +#include #include #include #include diff --git a/dash/scripts/bench/benchmark_runs.yml b/dash/scripts/bench/benchmark_runs.yml new file mode 100644 index 000000000..5d74d925a --- /dev/null +++ b/dash/scripts/bench/benchmark_runs.yml @@ -0,0 +1,11 @@ +config: + - mpicmd: mpirun -map-by core -n ${NUNITS} + +benchmarks: + bench.10.summa: + runs: + - -sb $((100 * NUNITS)) -nt 2 + bench.05.pattern: + runs: + - -params none + diff --git a/dash/scripts/circleci/run-docker.sh b/dash/scripts/circleci/run-docker.sh index c339fb43e..9c450cf5c 100644 --- a/dash/scripts/circleci/run-docker.sh +++ b/dash/scripts/circleci/run-docker.sh @@ -3,18 +3,20 @@ MPIENVS=(mpich openmpi) BUILD_CONFIG=$1 COMPILER=$2 - -DASH_ENV_EXPORTS="export DASH_MAKE_PROCS='4'; export DASH_MAX_UNITS='3'; export DASH_BUILDEX='OFF';" +MAKE_PROCS=4 if [[ "$COMPILER" == "clang" ]]; then C_COMPILER="clang-3.8" CXX_COMPILER="clang++-3.8" + MAKE_PROCS=2 else COMPILER="gnu" C_COMPILER="gcc" CXX_COMPILER="g++" fi +DASH_ENV_EXPORTS="export DASH_MAKE_PROCS='${MAKE_PROCS}'; export DASH_MAX_UNITS='3'; export DASH_BUILDEX='OFF';" + DASH_ENV_EXPORTS="${DASH_ENV_EXPORTS} export CC='${C_COMPILER}'; export CXX='${CXX_COMPILER}';" # run tests diff --git a/dash/scripts/dash-test-all-single.sh b/dash/scripts/dash-test-all-single.sh index 81462a0ea..717a279c3 100755 --- a/dash/scripts/dash-test-all-single.sh +++ b/dash/scripts/dash-test-all-single.sh @@ -40,13 +40,15 @@ echo "[[ LOG ]] Writing output to $LOGFILE" if [ $DART_IMPL = "shmem" ]; then RUN_CMD="$BIN_PATH/dartrun-shmem" - TEST_BINARY="${EXEC_WRAP} $BIN_PATH/dash/test/shmem/dash-test-shmem" + TEST_BINARY="${EXEC_WRAP} $BIN_PATH/dash-test-mpi" +# TEST_BINARY="${EXEC_WRAP} $BIN_PATH/dash/test/shmem/dash-test-shmem" elif [ $DART_IMPL = "mpi" ]; then # if (mpirun --help | grep -ic "open\(.\)\?mpi" >/dev/null 2>&1) ; then # fi MPI_EXEC_FLAGS="-map-by core ${MPI_EXEC_FLAGS}" RUN_CMD="${EXEC_PREFIX} mpirun ${MPI_EXEC_FLAGS}" - TEST_BINARY="${EXEC_WRAP} $BIN_PATH/dash/test/mpi/dash-test-mpi" + TEST_BINARY="${EXEC_WRAP} $BIN_PATH/dash-test-mpi" +# TEST_BINARY="${EXEC_WRAP} $BIN_PATH/dash/test/mpi/dash-test-mpi" else usage exit -1 diff --git a/dash/src/TypeInfo.cc b/dash/src/TypeInfo.cc index 2ac361a83..038521a44 100644 --- a/dash/src/TypeInfo.cc +++ b/dash/src/TypeInfo.cc @@ -1,5 +1,5 @@ -#include +#include #include #include diff --git a/dash/test/DARTLocalityTest.h b/dash/test/DARTLocalityTest.h deleted file mode 100644 index 22e7564db..000000000 --- a/dash/test/DARTLocalityTest.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef DASH__TEST__DART_LOCALITY_TEST_H_ -#define DASH__TEST__DART_LOCALITY_TEST_H_ - -#include "TestBase.h" - - -/** - * Test fixture for onesided operations provided by DART. - */ -class DARTLocalityTest : public dash::test::TestBase { -protected: - size_t _dash_id; - size_t _dash_size; - - DARTLocalityTest() - : _dash_id(0), - _dash_size(0) { - LOG_MESSAGE(">>> Test suite: DARTLocalityTest"); - } - - virtual ~DARTLocalityTest() { - LOG_MESSAGE("<<< Closing test suite: DARTLocalityTest"); - } - - virtual void SetUp() { - dash::test::TestBase::SetUp(); - _dash_id = dash::myid(); - _dash_size = dash::size(); - } -}; - -#endif // DASH__TEST__DART_LOCALITY_TEST_H_ diff --git a/dash/test/DARTMemAllocTest.h b/dash/test/DARTMemAllocTest.h deleted file mode 100644 index cad752146..000000000 --- a/dash/test/DARTMemAllocTest.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef DASH__TEST__DART_ONESIDED_TEST_H_ -#define DASH__TEST__DART_ONESIDED_TEST_H_ - -#include "TestBase.h" - - -/** - * Test fixture for onesided operations provided by DART. - */ -class DARTMemAllocTest : public dash::test::TestBase { -protected: - size_t _dash_id; - size_t _dash_size; - - DARTMemAllocTest() - : _dash_id(0), - _dash_size(0) { - LOG_MESSAGE(">>> Test suite: DARTOnesidedTest"); - } - - virtual ~DARTMemAllocTest() { - LOG_MESSAGE("<<< Closing test suite: DARTOnesidedTest"); - } - - virtual void SetUp() { - dash::test::TestBase::SetUp(); - _dash_id = dash::myid(); - _dash_size = dash::size(); - } -}; - -#endif // DASH__TEST__DART_ONESIDED_TEST_H_ diff --git a/dash/test/DARTOnesidedTest.h b/dash/test/DARTOnesidedTest.h deleted file mode 100644 index f3efe5c50..000000000 --- a/dash/test/DARTOnesidedTest.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef DASH__TEST__DART_ONESIDED_TEST_H_ -#define DASH__TEST__DART_ONESIDED_TEST_H_ - -#include "TestBase.h" - - -/** - * Test fixture for onesided operations provided by DART. - */ -class DARTOnesidedTest : public dash::test::TestBase { -protected: - size_t _dash_id; - size_t _dash_size; - - DARTOnesidedTest() - : _dash_id(0), - _dash_size(0) { - LOG_MESSAGE(">>> Test suite: DARTOnesidedTest"); - } - - virtual ~DARTOnesidedTest() { - LOG_MESSAGE("<<< Closing test suite: DARTOnesidedTest"); - } - - virtual void SetUp() { - dash::test::TestBase::SetUp(); - _dash_id = dash::myid(); - _dash_size = dash::size(); - } -}; - -#endif // DASH__TEST__DART_ONESIDED_TEST_H_ diff --git a/dash/test/DomainTest.h b/dash/test/DomainTest.h deleted file mode 100644 index 95225593c..000000000 --- a/dash/test/DomainTest.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef DASH__TEST__DOMAIN_TEST_H_ -#define DASH__TEST__DOMAIN_TEST_H_ - -#include "TestBase.h" - -/** - * Test fixture for class dash::Domain - */ -class DomainTest : public dash::test::TestBase { -protected: - size_t _dash_id; - size_t _dash_size; - - DomainTest() - : _dash_id(0), - _dash_size(0) { - LOG_MESSAGE(">>> Test suite: DomainTest"); - } - - virtual ~DomainTest() { - LOG_MESSAGE("<<< Closing test suite: DomainTest"); - } - - virtual void SetUp() { - dash::test::TestBase::SetUp(); - _dash_id = dash::myid(); - _dash_size = dash::size(); - } -}; - -#endif // DASH__TEST__DOMAIN_TEST_H_ diff --git a/dash/test/NViewTest.cc b/dash/test/NViewTest.cc deleted file mode 100644 index 01fd0898e..000000000 --- a/dash/test/NViewTest.cc +++ /dev/null @@ -1,199 +0,0 @@ - -#include "NViewTest.h" - -#include - -#include -#include -#include - -#include - - -namespace dash { -namespace test { - - template - void initialize_matrix(MatrixT & matrix) { -#if 0 - for (auto li = 0; li != matrix.local.size(); ++li) { - matrix.local.begin()[li] = // unit - (1.0000 * dash::myid()) + - // local offset - (0.0001 * (li+1)); - } -#else - if (dash::myid() == 0) { - for(size_t i = 0; i < matrix.extent(0); ++i) { - for(size_t k = 0; k < matrix.extent(1); ++k) { - matrix[i][k] = (i + 1) * 1.000 + (k + 1) * 0.001; - } - } - } -#endif - matrix.barrier(); - } - - template - std::string range_str( - const ValueRange & vrange) { - typedef typename ValueRange::value_type value_t; - std::ostringstream ss; - auto idx = dash::index(vrange); - int i = 0; - for (const auto & v : vrange) { - ss << "[" << *(dash::begin(idx) + i) << "] " - << static_cast(v) << " "; - ++i; - } - return ss.str(); - } - -} -} - -using dash::test::range_str; - - -TEST_F(NViewTest, MatrixBlocked1DimLocalView) -{ - auto nunits = dash::size(); - - int block_rows = 5; - int block_cols = 3; - - int nrows = nunits * block_rows; - int ncols = nunits * block_cols; - - // columns distributed in blocks of same size: - // - // 0 0 0 | 1 1 1 | 2 2 2 | ... - // 0 0 0 | 1 1 1 | 2 2 2 | ... - // 0 0 0 | 1 1 1 | 2 2 2 | ... - // - dash::Matrix mat( - nrows, ncols, - dash::NONE, dash::BLOCKED); - - mat.barrier(); - - DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimLocalView", - "Matrix initialized"); - - // select first 2 matrix rows: - auto nview_rows_g = dash::sub<0>(1, 3, mat); - auto nview_cols_g = dash::sub<1>(2, 7, mat); - auto nview_cr_s_g = dash::sub<1>(2, 7, nview_rows_g); - auto nview_rc_s_g = dash::sub<0>(1, 3, nview_cols_g); - - DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimLocalView", - "mat ->", - "offsets:", mat.offsets(), - "extents:", mat.extents(), - "size:", mat.size()); - - DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimLocalView", - "sub<0>(1,3, mat) ->", - "offsets:", nview_rows_g.offsets(), - "extents:", nview_rows_g.extents(), - "size:", nview_rows_g.size()); - - DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimLocalView", - "sub<1>(2,7, mat) ->", - "offsets:", nview_cols_g.offsets(), - "extents:", nview_cols_g.extents(), - "size:", nview_cols_g.size()); - - DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimLocalView", - "sub<1>(2,7, sub<0>(1,3, mat) ->", - "offsets:", nview_cr_s_g.offsets(), - "extents:", nview_cr_s_g.extents(), - "size:", nview_cr_s_g.size()); - - DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimLocalView", - "sub<0>(1,3, sub<0>(2,7, mat) ->", - "offsets:", nview_rc_s_g.offsets(), - "extents:", nview_rc_s_g.extents(), - "size:", nview_rc_s_g.size()); - - EXPECT_EQ_U(2, nview_rows_g.extent<0>()); - EXPECT_EQ_U(mat.extent(1), nview_rows_g.extent<1>()); - - EXPECT_EQ_U(nview_rc_s_g.extents(), nview_cr_s_g.extents()); - EXPECT_EQ_U(nview_rc_s_g.offsets(), nview_cr_s_g.offsets()); - -#if __TODO__ - auto nview_rows_l = dash::local(nview_rows_g); - - DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimLocalView", - nview_rows_l.extents()); - - EXPECT_EQ_U(2, nview_rows_l.extent<0>()); - EXPECT_EQ_U(block_cols, nview_rows_l.extent<1>()); -#endif -} - -TEST_F(NViewTest, MatrixBlocked1DimSub) -{ - auto nunits = dash::size(); - - int block_rows = 4; - int block_cols = 3; - - int nrows = nunits * block_rows; - int ncols = nunits * block_cols; - - // columns distributed in blocks of same size: - // - // 0 0 0 | 1 1 1 | 2 2 2 | ... - // 0 0 0 | 1 1 1 | 2 2 2 | ... - // 0 0 0 | 1 1 1 | 2 2 2 | ... - // - dash::Matrix mat( - nrows, ncols, - dash::NONE, dash::BLOCKED); - dash::test::initialize_matrix(mat); - - if (dash::myid() == 0) { - for (int r = 0; r < nrows; ++r) { - std::vector row_values; - for (int c = 0; c < ncols; ++c) { - row_values.push_back( - static_cast(mat[r][c])); - } - DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSub", - "row[", r, "]", row_values); - } - } - auto nview_sub_cols = dash::sub<1>( - 1, ncols - 1, - mat - ); - auto nview_sub = dash::sub<0>( - 1, nrows - 1, - nview_sub_cols - ); - auto nview_rows = nview_sub.extent<0>(); - auto nview_cols = nview_sub.extent<1>(); - - DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", nview_rows); - DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", nview_cols); - - if (dash::myid() == 0) { - for (int r = 0; r < nview_rows; ++r) { - std::vector row_values; - for (int c = 0; c < nview_cols; ++c) { - row_values.push_back(nview_sub[r * nview_cols + c]); - } - DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSub", - "row[", r, "]", row_values); - } - for (int r = 0; r < nview_rows; ++r) { - auto row_view = dash::sub<0>(r, r+1, nview_sub); - DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSub", - "row[", r, "]", - range_str(row_view)); - } - } -} - diff --git a/dash/test/RangeTest.cc b/dash/test/RangeTest.cc deleted file mode 100644 index 21ae93ba7..000000000 --- a/dash/test/RangeTest.cc +++ /dev/null @@ -1,56 +0,0 @@ - -#include "RangeTest.h" - -#include - -#include -#include -#include - -#include - - -TEST_F(RangeTest, RangeTraits) -{ - dash::Array array(dash::size() * 10); - auto v_sub = dash::sub(0, 10, array); - auto i_sub = dash::index(v_sub); - auto v_ssub = dash::sub(0, 5, (dash::sub(0, 10, array))); - auto v_loc = dash::local(array); - - static_assert(dash::is_range< - dash::Array - >::value == true, - "dash::is_range::value not matched"); - - static_assert(dash::is_range< - typename dash::Array::local_type - >::value == true, - "dash::is_range::value not matched"); - - static_assert(dash::is_range< - typename dash::Array::iterator - >::value == false, - "dash::is_range>::value not matched"); - static_assert(dash::is_range::value == true, - "range type traits for dash::Array not matched"); - static_assert(dash::is_range::value == true, - "range type traits for local(dash::Array) not matched"); - static_assert(dash::is_range::value == true, - "range type traits for sub(dash::Array) not matched"); - static_assert(dash::is_range::value == true, - "range type traits for sub(sub(dash::Array)) not matched"); - static_assert(dash::is_range::value == true, - "range type traits for index(sub(dash::Array)) not matched"); - - static_assert( - dash::is_range::value == true, - "dash::is_range>::value not matched"); - - auto l_range = dash::make_range(array.local.begin(), - array.local.end()); - static_assert( - dash::is_range::value == true, - "dash::is_range::value not matched"); -} - diff --git a/dash/test/TestBase.h b/dash/test/TestBase.h index 53e68c7a2..9b16daa09 100644 --- a/dash/test/TestBase.h +++ b/dash/test/TestBase.h @@ -6,9 +6,13 @@ #include #include +#include +#include + +#include #include +#include #include -#include #include "TestGlobals.h" #include "TestPrinter.h" @@ -50,7 +54,10 @@ namespace internal { #pragma GCC diagnostic ignored "-Wconversion-null" #endif // defined(__GNUC__) template -typename std::enable_if::value, ::testing::AssertionResult>::type +typename std::enable_if< + !std::is_floating_point::value, + ::testing::AssertionResult + >::type assert_float_eq( const char *exp_e, const char *exp_a, @@ -90,30 +97,43 @@ struct float_type_helper { using type = double; }; +template +struct float_type_helper { + using type = float; +}; + template struct float_type_helper { using type = double; }; +template +struct float_type_helper { + using type = float; +}; template<> struct float_type_helper { using type = double; }; +template<> +struct float_type_helper { + using type = float; +}; -#define ASSERT_EQ_U(e,a) \ - do { \ - if (std::is_floating_point::value \ - || std::is_floating_point::value) { \ - using value_type = \ - typename ::testing::internal::float_type_helper< \ - decltype(e), decltype(a)>::type; \ - EXPECT_PRED_FORMAT2( \ - ::testing::internal::assert_float_eq, e, a) \ - << "Unit " << dash::myid().id; \ - } \ - else { \ - EXPECT_EQ(e,a) << "Unit " << dash::myid().id; \ - } \ +#define ASSERT_EQ_U(_e,_a) \ + do { \ + if (std::is_floating_point::value \ + || std::is_floating_point::value) { \ + using value_type = \ + typename ::testing::internal::float_type_helper< \ + decltype(_e), decltype(_a)>::type; \ + EXPECT_PRED_FORMAT2( \ + ::testing::internal::assert_float_eq,(_e),(_a)) \ + << "Unit " << dash::myid().id; \ + } \ + else { \ + EXPECT_EQ(_e,_a) << "Unit " << dash::myid().id; \ + } \ } while(0) #define EXPECT_EQ_U(e,a) ASSERT_EQ_U(e,a) @@ -183,6 +203,43 @@ extern void ColoredPrintf( namespace dash { namespace test { +template +static std::string range_str( + const ValueRange & vrange) { + typedef typename ValueRange::value_type value_t; + std::ostringstream ss; + auto idx = dash::index(vrange); + int i = 0; + + // ss << "<" << dash::internal::typestr(*vrange.begin()) << "> "; + for (const auto & v : vrange) { + ss << std::setw(2) << *(dash::begin(idx) + i) << "|" + << std::fixed << std::setprecision(4) + << static_cast(v) << " "; + ++i; + } + return ss.str(); +} + +template +static bool expect_range_values_equal( + const RangeA & rng_a, + const RangeB & rng_b) { + DASH_LOG_TRACE_VAR("TestBase.expect_range_values_equal", rng_a); + DASH_LOG_TRACE_VAR("TestBase.expect_range_values_equal", rng_b); + auto it_a = dash::begin(rng_a); + auto it_b = dash::begin(rng_b); + const auto end_a = dash::end(rng_a); + const auto end_b = dash::end(rng_b); + for (; it_a != end_a && it_b != end_b; ++it_a, ++it_b) { + if (static_cast(*it_a) != + static_cast(*it_b)) { + return false; + } + } + return (end_a == it_a) && (end_b == it_b); +} + class TestBase : public ::testing::Test { protected: @@ -193,6 +250,7 @@ class TestBase : public ::testing::Test { LOG_MESSAGE("===> Running test case %s.%s ...", test_info->test_case_name(), test_info->name()); dash::init(&TESTENV.argc, &TESTENV.argv); + LOG_MESSAGE("-==- DASH initialized with %lu units", dash::size()); dash::barrier(); } diff --git a/dash/test/ViewTest.cc b/dash/test/ViewTest.cc deleted file mode 100644 index abfca9e6f..000000000 --- a/dash/test/ViewTest.cc +++ /dev/null @@ -1,1072 +0,0 @@ - -#include "ViewTest.h" - -#include -#include - -#include -#include -#include - - -namespace dash { -namespace test { - - template - void initialize_array(ArrayT & array) { - auto block_size = array.pattern().blocksize(0); - for (auto li = 0; li != array.local.size(); ++li) { - auto block_lidx = li / block_size; - auto block_gidx = (block_lidx * dash::size()) + dash::myid(); - auto gi = (block_gidx * block_size) + (li % block_size); - array.local[li] = // unit - (1.0000 * dash::myid()) + - // local offset - (0.0001 * (li+1)) + - // global offset - (0.0100 * gi); - } - array.barrier(); - } - - template - std::string range_str( - const ValueRange & vrange) { - typedef typename ValueRange::value_type value_t; - std::ostringstream ss; - auto idx = dash::index(vrange); - int i = 0; - for (const auto & v : vrange) { - ss << "[" << *(dash::begin(idx) + i) << "] " - << static_cast(v) << " "; - ++i; - } - return ss.str(); - } - -} -} - -using dash::test::range_str; - - -TEST_F(ViewTest, ViewTraits) -{ - dash::Array array(dash::size() * 10); - auto v_sub = dash::sub(0, 10, array); - auto i_sub = dash::index(v_sub); - auto v_ssub = dash::sub(0, 5, (dash::sub(0, 10, array))); - auto v_loc = dash::local(array); - - static_assert( - dash::view_traits::is_local::value == false, - "view traits is_local for dash::Array not matched"); - static_assert( - dash::view_traits::is_view::value == false, - "view traits is_view for dash::Array not matched"); - static_assert( - dash::view_traits::is_view::value == true, - "view traits is_view for sub(dash::Array) not matched"); - - // TODO: Clarify if local container types should be considered views. - // - // static_assert( - // dash::view_traits::is_view::value == true, - // "view traits is_view for local(dash::Array) not matched"); - static_assert( - dash::view_traits::is_view::value == false, - "view traits is_origin for local(dash::Array) not matched"); - - static_assert( - dash::view_traits::is_origin::value == true, - "view traits is_origin for dash::Array not matched"); - static_assert( - dash::view_traits::is_origin::value == false, - "view traits is_origin for sub(dash::Array) not matched"); - static_assert( - dash::view_traits::is_origin::value == false, - "view traits is_origin for sub(sub(dash::Array)) not matched"); - static_assert( - dash::view_traits::is_origin::value == true, - "view traits is_origin for local(dash::Array) not matched"); - static_assert( - dash::view_traits::is_local::value == true, - "view traits is_local for local(dash::Array) not matched"); - - static_assert( - dash::view_traits::rank::value == 1, - "rank of array different from 1"); - static_assert( - dash::view_traits::rank::value == 1, - "rank of sub(array) different from 1"); - static_assert( - dash::view_traits::rank::value == 1, - "rank of sub(sub(array)) different from 1"); - static_assert( - dash::view_traits::rank::value == 1, - "rank of local(array) different from 1"); -} - -TEST_F(ViewTest, ArrayBlockedPatternGlobalView) -{ - int block_size = 3; - int array_size = dash::size() * block_size; - int block_begin_gidx = block_size * dash::myid(); - int block_end_gidx = block_size * (dash::myid() + 1); - - dash::Array a(array_size); - dash::test::initialize_array(a); - - // View to global index range of local block: - auto block_gview = dash::sub(block_begin_gidx, - block_end_gidx, - a); - EXPECT_EQ(block_size, block_gview.size()); - - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternGlobalView", - range_str(block_gview)); - - EXPECT_TRUE_U(std::equal(a.begin() + block_begin_gidx, - a.begin() + block_end_gidx, - block_gview.begin())); - - // Origin of block view is array: - auto & block_domain = dash::domain(block_gview); - - EXPECT_EQ(array_size, block_domain.size()); - EXPECT_EQ(a.begin(), dash::begin(block_domain)); - EXPECT_EQ(a.end(), dash::end(block_domain)); - - auto view_begin_gidx = dash::index(dash::begin(block_gview)); - auto view_end_gidx = dash::index(dash::end(block_gview)); - - EXPECT_EQ(block_begin_gidx, view_begin_gidx); - EXPECT_EQ(block_end_gidx, view_end_gidx); -} - -TEST_F(ViewTest, ArrayBlockedPatternChainedGlobalView) -{ - int block_size = 7; - int array_size = dash::size() * block_size; - int block_begin_gidx = block_size * dash::myid(); - int block_end_gidx = block_size * (dash::myid() + 1); - - dash::Array a(array_size); - dash::test::initialize_array(a); - - // View to global index range of local block: - auto block_gview_outer = dash::sub(block_begin_gidx, - block_end_gidx, - a); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternGlobalView", - block_gview_outer); - - // Sub-range in block from block index 10 to -10: - auto block_gview_inner = dash::sub(2, - block_size - 2, - block_gview_outer); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternGlobalView", - block_gview_inner); - - EXPECT_EQ(block_size - 4, block_gview_inner.size()); - EXPECT_EQ(block_begin_gidx + 2, - dash::index(dash::begin(block_gview_inner))); - EXPECT_EQ(block_begin_gidx + block_size - 2, - dash::index(dash::end(block_gview_inner))); - - // Origin of inner view is outer view: - auto & block_gview_inner_domain = dash::domain(block_gview_inner); - EXPECT_EQ(block_gview_outer, block_gview_inner_domain); - - // Origin of outer view is array: - auto & block_gview_outer_domain = dash::domain(block_gview_outer); - EXPECT_EQ(a.begin(), dash::begin(block_gview_outer_domain)); - EXPECT_EQ(a.end(), dash::end(block_gview_outer_domain)); -} - -TEST_F(ViewTest, ArrayBlockCyclicPatternGlobalView) -{ - int block_size = 5; - int blocks_per_unit = 3; - int array_size = dash::size() * block_size * blocks_per_unit - + (block_size * 2) - - 2; - int block_begin_gidx = block_size * dash::myid(); - int block_end_gidx = block_size * (dash::myid() + 1); - - dash::Array a(array_size, dash::BLOCKCYCLIC(block_size)); - dash::test::initialize_array(a); - - // View to global index range of local block: - auto block_gview = dash::sub(block_begin_gidx, - block_end_gidx, - a); - - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternGlobalView", - block_gview); - - EXPECT_EQ(block_size, block_gview.size()); - - // Origin of block view is array: - auto & block_domain = dash::domain(block_gview); - EXPECT_EQ(a.begin(), dash::begin(block_domain)); - EXPECT_EQ(a.end(), dash::end(block_domain)); - - if (dash::myid() == 0) { - auto blocks_view = dash::blocks( - dash::sub( - block_size / 2, - a.size() - (block_size / 2), - a)); - int b_idx = 0; - for (auto block : blocks_view) { - DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternGlobalView", - "block[", b_idx, "]:", range_str(block)); - // TODO: Assert - ++b_idx; - } - } -} - -TEST_F(ViewTest, Intersect1DimSingle) -{ - int block_size = 13; - int array_size = dash::size() * block_size - // unbalanced size: - + 2; - - int sub_left_begin_gidx = 0; - int sub_left_end_gidx = (array_size * 2) / 3; - int sub_right_begin_gidx = (array_size * 1) / 3; - int sub_right_end_gidx = array_size; - - dash::Array array(array_size); - - for (auto li = 0; li != array.local.size(); ++li) { - array.local[li] = (1000 * (dash::myid() + 1)) + - (100 * li) + - (dash::myid() * block_size) + li; - } - array.barrier(); - - // View to first two thirds of global array: - auto gview_left = dash::sub(sub_left_begin_gidx, - sub_left_end_gidx, - array); - // View to last two thirds of global array: - auto gview_right = dash::sub(sub_right_begin_gidx, - sub_right_end_gidx, - array); - - auto gview_isect = dash::intersect(gview_left, gview_right); - - auto gindex_isect = dash::index(gview_isect); - - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", array.size()); - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", gview_left.size()); - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", gview_right.size()); - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", gview_isect.size()); - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", *gindex_isect.begin()); - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", *gindex_isect.end()); - - EXPECT_EQ_U(sub_left_end_gidx - sub_left_begin_gidx, - gview_left.size()); - EXPECT_EQ_U(sub_right_end_gidx - sub_right_begin_gidx, - gview_right.size()); - EXPECT_EQ_U(sub_left_end_gidx - sub_right_begin_gidx, - gview_isect.size()); - - for (int isect_idx = 0; isect_idx < gview_isect.size(); isect_idx++) { - EXPECT_EQ_U(static_cast(array[sub_right_begin_gidx + isect_idx]), - static_cast(gview_isect[isect_idx])); - } - - auto lview_isect = dash::local(gview_isect); - auto lindex_isect = dash::index(lview_isect); - - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", *lindex_isect.begin()); - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", *lindex_isect.end()); -} - -TEST_F(ViewTest, IndexSet) -{ - typedef float value_t; - typedef dash::default_index_t index_t; - - int block_size = 4; - int blocks_per_unit = 2; - int array_size = dash::size() - * (blocks_per_unit * block_size); - - dash::Array> - array(array_size, dash::TILE(block_size)); - dash::test::initialize_array(array); - - if (dash::myid() == 0) { - std::vector values(array.begin(), array.end()); - DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", values); - - auto sub_gview = dash::sub( - block_size / 2, - array_size - (block_size / 2), - array); - - auto sub_index = dash::index(sub_gview); - - DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", sub_index); - - std::vector sub_values(sub_gview.begin(), - sub_gview.end()); - DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", sub_values); - - EXPECT_EQ_U(array_size - block_size, sub_gview.size()); - EXPECT_EQ_U(array_size - block_size, sub_index.size()); - - EXPECT_TRUE_U(std::equal(array.begin() + (block_size / 2), - array.begin() + array_size - (block_size / 2), - sub_gview.begin())); - } - array.barrier(); - - auto sub_gview = dash::sub( - block_size / 2, - array_size - (block_size / 2), - array); - auto locsub_gview = dash::local(sub_gview); - - auto locsub_index = dash::index(locsub_gview); - - DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", locsub_index); - DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", locsub_gview); - - array.barrier(); - - if (dash::myid() == 0) { - auto sub_gview = dash::sub( - block_size / 2, - array_size - (block_size / 2), - array); - EXPECT_EQ_U( - dash::distance( - array.begin() + (block_size / 2), - array.begin() + (array_size - (block_size / 2))), - dash::distance( - sub_gview.begin(), - sub_gview.end()) ); - EXPECT_TRUE_U( - std::equal( - array.begin() + (block_size / 2), - array.begin() + (array_size - (block_size / 2)), - sub_gview.begin()) ); - - auto subsub_gview = dash::sub(3, 6, sub_gview); - auto subsub_index = dash::index(subsub_gview); - - DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", subsub_index); - std::vector subsub_values(subsub_gview.begin(), - subsub_gview.end()); - DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", subsub_values); - - EXPECT_EQ_U( - dash::distance( - array.begin() + (block_size / 2) + 3, - array.begin() + (block_size / 2) + 6), - dash::distance( - subsub_gview.begin(), - subsub_gview.end()) ); - EXPECT_TRUE_U( - std::equal( - array.begin() + (block_size / 2) + 3, - array.begin() + (block_size / 2) + 6, - subsub_gview.begin()) ); - } -} - -TEST_F(ViewTest, LocalBlocksView1Dim) -{ - typedef float value_t; - typedef dash::default_index_t index_t; - - int block_size = 4; - int blocks_per_unit = 2; - int array_size = dash::size() - * (blocks_per_unit * block_size) - + (block_size * 3 / 2); - - dash::Array array(array_size, dash::BLOCKCYCLIC(block_size)); - dash::test::initialize_array(array); - - if (dash::myid() == 0) { - std::vector values(array.begin(), array.end()); - DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", values); - } - array.barrier(); - - auto lblocks_view = dash::local( - dash::blocks( - array)); - - auto lblocks_index = dash::index(lblocks_view); - - std::vector lblocks_indices(lblocks_index.begin(), - lblocks_index.end()); - DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", lblocks_indices); - - std::vector lblocks_values(lblocks_view.begin(), - lblocks_view.end()); - DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", lblocks_values); - - auto blocksl_view = dash::blocks( - dash::local( - array)); - - auto blocksl_index = dash::index(blocksl_view); - - auto lsize = array.pattern().local_extent(0); - auto l_beg = array.pattern().global_index(array.team().myid(), - {{ 0 }} ); - auto l_end = array.pattern().global_index(array.team().myid(), - {{ lsize }} ); - auto n_lblocks = dash::math::div_ceil(array.lsize(), block_size); - - DASH_LOG_DEBUG("ViewTest.LocalBlocksView1Dim", - "n_lblocks:", n_lblocks, "l_beg:", l_beg, "l_end:", l_end); - - EXPECT_EQ_U(n_lblocks, blocksl_view.size()); - EXPECT_EQ_U(n_lblocks, blocksl_index.size()); - - int b_idx = 0; - for (auto block : blocksl_view) { - auto block_index = dash::index(block); - - DASH_LOG_DEBUG("ViewTest.LocalBlocksView1Dim", - "---- local block", b_idx); - - std::vector block_indices(block_index.begin(), - block_index.end()); - DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", block_indices); - - std::vector block_values(block.begin(), block.end()); - DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", block_values); - - auto lblock_size = array.pattern().local_block(b_idx).extents()[0]; - auto lblock_gbegin = array.pattern().local_block(b_idx).offsets()[0]; - - EXPECT_EQ_U(lblock_size, block.size()); - for (auto bi = 0; bi < lblock_size; ++bi) { - EXPECT_EQ_U(static_cast(array[bi + lblock_gbegin]), - static_cast(block[bi])); - } - b_idx++; - } - - dash::Array array_bal( - dash::size() * block_size, - dash::BLOCKCYCLIC(block_size)); - dash::test::initialize_array(array_bal); - - auto sub_view = dash::sub( - block_size / 2, - array.size() - (block_size / 2), - array_bal); - auto blockssub_view = dash::blocks(sub_view); - auto lblockssub_view = dash::local(blockssub_view); - - auto lblockssub_index = dash::index(lblockssub_view); - - DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", lblockssub_index); - DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", lblockssub_view); -} - -TEST_F(ViewTest, BlocksView1Dim) -{ - typedef float value_t; - typedef dash::default_index_t index_t; - - int block_size = 3; - int blocks_per_unit = 3; - int array_size = dash::size() - * (blocks_per_unit * block_size) - // unbalanced size, last block underfilled: - - (block_size / 2); - - int sub_left_begin_gidx = 0; - int sub_left_end_gidx = array_size - (block_size / 2) - 1; - int sub_right_begin_gidx = (block_size * 3) / 2; - int sub_right_end_gidx = array_size; - - dash::Array array(array_size, dash::BLOCKCYCLIC(block_size)); - dash::test::initialize_array(array); - - if (dash::myid() == 0) { - std::vector values(array.begin(), array.end()); - DASH_LOG_DEBUG_VAR("ViewTest.BlocksView1Dim", values); - } - array.barrier(); - - auto array_blocks = dash::blocks( - dash::sub<0>(0, array.size(), - array)); - - DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", - "array.blocks.size:", array_blocks.size(), - "=", array_blocks.end() - array_blocks.begin(), - "=", dash::index(array_blocks).size()); - - EXPECT_EQ_U(array_blocks.size(), - array_blocks.end() - array_blocks.begin()); - - array.barrier(); - - if (dash::myid() == 0) { - DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "blocks(array):", - "index(blocks).begin, index(blocks).end:", - "(", *(dash::index(array_blocks).begin()), - ",", *(dash::index(array_blocks).end()), - ")", "size:", array_blocks.size(), - "=", array_blocks.end() - array_blocks.begin(), - "=", "indices:", dash::index(array_blocks).size()); - - int b_idx = 0; - for (auto b_it = array_blocks.begin(); - b_it != array_blocks.end(); ++b_it, ++b_idx) { - auto && block = *b_it; - EXPECT_EQ_U(b_idx, b_it.pos()); - - DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "--", - "block[", b_idx, "]:", - dash::internal::typestr(block)); - DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "----", - "p.offsets:", array.pattern().block(b_idx).offsets()[0], - "p.extents:", array.pattern().block(b_idx).extents()[0], - "->", dash::index(array_blocks)[b_idx], - "index(block).begin, index(block).end:", - "(", *(dash::begin(dash::index(block))), - ",", *(dash::end(dash::index(block))), - ")", "size:", block.size(), - "=", "indices:", dash::index(block).size()); - - DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "----", - range_str(block)); - - EXPECT_EQ_U(( b_idx < array_blocks.size() - 1 - ? block_size - : block_size - (block_size / 2) ), - block.size()); - EXPECT_TRUE_U( - std::equal(array.begin() + (b_idx * block_size), - array.begin() + (b_idx * block_size) + block.size(), - block.begin())); - } - } - array.barrier(); - - // View to first two thirds of global array: - auto gview_left = dash::sub(sub_left_begin_gidx, - sub_left_end_gidx, - array); - // View to last two thirds of global array: - auto gview_right = dash::sub(sub_right_begin_gidx, - sub_right_end_gidx, - array); - - auto gview_isect = dash::intersect(gview_left, gview_right); - - EXPECT_EQ_U(sub_left_end_gidx - sub_right_begin_gidx, - gview_isect.size()); - - if (dash::myid() == 0) { - DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "index(gview_isect(array)):", - "(begin, first, last, end):", - "(", *(dash::index(gview_isect).begin()), - ",", dash::index(gview_isect).first(), - ",", dash::index(gview_isect).last(), - ",", *(dash::index(gview_isect).end()), - ")", "size:", dash::index(gview_isect).size()); - - DASH_LOG_DEBUG_VAR("ViewTest.BlocksView1Dim", range_str(gview_isect)); - } - array.barrier(); - - EXPECT_TRUE_U( - std::equal(array.begin() + sub_right_begin_gidx, - array.begin() + sub_left_end_gidx, - gview_isect.begin())); - - auto gview_blocks = dash::blocks(gview_isect); - - static_assert( - dash::view_traits< - std::remove_reference< decltype(gview_blocks) >::type - >::is_view::value == true, - "view traits is_view for blocks(dash::Array) not matched"); - - array.barrier(); - - if (dash::myid() == 0) { - DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", - "index(blocks(gview_isect(array))):", - "(begin, first, last, end):", - "(", *(dash::index(gview_blocks).begin()), - ",", dash::index(gview_blocks).first(), - ",", dash::index(gview_blocks).last(), - ",", *(dash::index(gview_blocks).end()), - ")", "size:", dash::index(gview_blocks).size()); - - int b_idx = 0; - for (auto block : gview_blocks) { - DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "--", - "block[", b_idx, "]:", - dash::internal::typestr(block)); - DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "----", - "p.offsets:", array.pattern().block(b_idx).offsets()[0], - "p.extents:", array.pattern().block(b_idx).extents()[0], - "->", (dash::index(gview_blocks)[b_idx]), - "index(block.begin, block.end):", - "(", *(dash::index(block).begin()), - ",", *(dash::index(block).end()), ")", - "size:", dash::index(block).size()); - - DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "----", - range_str(block)); - // TODO: Assert - b_idx++; - } - } -} - -TEST_F(ViewTest, Intersect1DimMultiple) -{ - int block_size = 4; - int blocks_per_unit = 3; - int array_size = dash::size() - * (blocks_per_unit * block_size) - // unbalanced size, last block underfilled: - - (block_size / 2); - - int sub_left_begin_gidx = 0; - int sub_left_end_gidx = array_size - (block_size / 2); - int sub_right_begin_gidx = (block_size / 2); - int sub_right_end_gidx = array_size; - - dash::Array array(array_size, dash::BLOCKCYCLIC(block_size)); - - for (auto li = 0; li != array.local.size(); ++li) { - array.local[li] = (1000 * (dash::myid() + 1)) + - (100 * li) + - (dash::myid() * block_size) + li; - } - - array.barrier(); - - DASH_LOG_DEBUG("ViewTest.Intersect1DimMultiple", - "array initialized"); - - // View to first two thirds of global array: - auto gview_left = dash::sub(sub_left_begin_gidx, - sub_left_end_gidx, - array); - // View to last two thirds of global array: - auto gview_right = dash::sub(sub_right_begin_gidx, - sub_right_end_gidx, - array); - - auto gview_isect = dash::intersect(gview_left, gview_right); - - auto gindex_isect = dash::index(gview_isect); - - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimMultiple", array.size()); - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimMultiple", gview_left.size()); - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimMultiple", gview_right.size()); - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimMultiple", gview_isect.size()); - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimMultiple", *gindex_isect.begin()); - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimMultiple", *gindex_isect.end()); - - // TODO: Assert - - auto lview_isect = dash::local(gview_isect); - auto lindex_isect = dash::index(lview_isect); - - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimMultiple", - *dash::begin(lindex_isect)); - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimMultiple", - *dash::end(lindex_isect)); - - if (dash::myid() == 0) { - std::vector values(array.begin(), array.end()); - DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimMultiple", values); - // TODO: Assert - } -} - -TEST_F(ViewTest, ArrayBlockedPatternLocalView) -{ - int block_size = 7; - int array_size = dash::size() * block_size; - int lblock_begin_gidx = block_size * dash::myid(); - int lblock_end_gidx = lblock_begin_gidx + block_size; - - dash::Array array(array_size); - - for (auto li = 0; li != array.local.size(); ++li) { - array.local[li] = (1000000 * (dash::myid() + 1)) + - (1000 * li) + - (dash::myid() * block_size) + li; - } - - array.barrier(); - DASH_LOG_DEBUG("ViewTest.ArrayBlockedPatternLocalView", - "array initialized"); - - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - array.pattern().size()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - array.pattern().blockspec().size()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - array.pattern().local_size()); - - // View index sets: - auto l_begin_gidx = array.pattern().global(0); - - DASH_LOG_DEBUG("ViewTest.ArrayBlockedPatternLocalView", - "index(sub(", - l_begin_gidx, ",", l_begin_gidx + block_size, ", a ))"); - - auto g_idx_set = dash::index( - dash::sub( - l_begin_gidx, - l_begin_gidx + block_size, - array) ); - - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *g_idx_set.begin()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *g_idx_set.end()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - g_idx_set.end() - g_idx_set.begin()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - g_idx_set.size()); - - EXPECT_EQ_U(block_size, g_idx_set.size()); - EXPECT_EQ_U(block_size, g_idx_set.end() - g_idx_set.begin()); - EXPECT_EQ_U(l_begin_gidx, *g_idx_set.begin()); - EXPECT_EQ_U(l_begin_gidx + block_size, *g_idx_set.end()); - - DASH_LOG_DEBUG("ViewTest.ArrayBlockedPatternLocalView", - "index(local(sub(", - l_begin_gidx, ",", l_begin_gidx + block_size, ", a )))"); - - auto l_idx_set = dash::index( - dash::local( - dash::sub( - l_begin_gidx, - l_begin_gidx + block_size, - array) ) ); - - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *l_idx_set.begin()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - l_idx_set.end() - l_idx_set.begin()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - l_idx_set.size()); - // TODO: Assert - - auto l_idx_set_begin = *dash::begin(l_idx_set); - auto l_idx_set_end = *dash::end(l_idx_set); - - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - l_idx_set_begin); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - l_idx_set_end); - EXPECT_EQ(0, l_idx_set_begin); - EXPECT_EQ(0 + block_size, l_idx_set_end); - - // Use case: - // - // array [ ... | 0 1 2 3 4 5 6 7 8 9 | ... ] - // : | | : - // sub : '---------' : - // | : : | - // local '---------------------' - // | | - // '----.----' - // | - // local(sub(array)) - // - { - DASH_LOG_DEBUG("ViewTest.ArrayBlockedPatternLocalView", - "--------- inner ---------"); - int sub_begin_gidx = lblock_begin_gidx + 2; - int sub_end_gidx = lblock_end_gidx - 2; - - // View to global index range of local block: - auto sub_lblock = dash::sub(sub_begin_gidx, - sub_end_gidx, - array); - - static_assert( - !dash::view_traits::is_local::value, - "sub(range) expected have type trait local = false"); - - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *dash::begin(dash::index(sub_lblock))); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *dash::end(dash::index(sub_lblock))); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - sub_lblock.size()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - dash::end(sub_lblock) - dash::begin(sub_lblock)); - - EXPECT_EQ(block_size - 4, sub_lblock.size()); - EXPECT_EQ(sub_lblock.size(), - dash::end(sub_lblock) - dash::begin(sub_lblock)); - - auto l_sub_lblock = dash::local(sub_lblock); - - static_assert( - dash::view_traits::is_local::value, - "local(sub(range)) expected have type trait local = true"); - - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *dash::begin(dash::index(l_sub_lblock))); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *dash::end(dash::index(l_sub_lblock))); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - l_sub_lblock.size()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - dash::end(l_sub_lblock) - dash::begin(l_sub_lblock)); - - EXPECT_EQ(sub_lblock.size(), l_sub_lblock.size()); - EXPECT_EQ(l_sub_lblock.size(), - dash::end(l_sub_lblock) - dash::begin(l_sub_lblock)); - - EXPECT_EQ(array.pattern().at( - dash::index(sub_lblock)[0]), - dash::index(l_sub_lblock)[0]); - EXPECT_EQ(dash::index(sub_lblock).size(), - dash::index(l_sub_lblock).size()); - - for (int lsi = 0; lsi != sub_lblock.size(); lsi++) { - int sub_elem = sub_lblock[lsi]; - int l_sub_elem = l_sub_lblock[lsi]; - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", sub_elem); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", l_sub_elem); - EXPECT_EQ(sub_elem, l_sub_elem); - } - - auto sub_l_sub_lblock = dash::sub(1,4, dash::local(l_sub_lblock)); - - static_assert( - dash::view_traits::is_local::value, - "sub(local(sub(range))) expected have type trait local = true"); - - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *dash::begin(dash::index(sub_l_sub_lblock))); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *dash::end(dash::index(sub_l_sub_lblock))); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - sub_l_sub_lblock.size()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - dash::end(sub_l_sub_lblock) - - dash::begin(sub_l_sub_lblock)); - // TODO: Assert - - for (int slsi = 0; slsi != sub_l_sub_lblock.size(); slsi++) { - int sub_l_sub_elem = sub_l_sub_lblock[slsi]; - int l_sub_elem = l_sub_lblock[slsi+1]; - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - l_sub_elem); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - sub_l_sub_elem); - EXPECT_EQ(l_sub_elem, sub_l_sub_elem); - } - } - // Use case: - // - // array [ .. | 0 1 2 3 4 5 6 7 8 9 | ... ] - // | : : | - // sub '---------------------' - // : : - // local '---------' - // | | - // '----.----' - // | - // local(sub(array)) - // - { - DASH_LOG_DEBUG("ViewTest.ArrayBlockedPatternLocalView", - "--------- outer ---------"); - int sub_begin_gidx = lblock_begin_gidx; - int sub_end_gidx = lblock_end_gidx; - - if (dash::myid() > 0) { - sub_begin_gidx -= 3; - } - if (dash::myid() < dash::size() - 1) { - sub_end_gidx += 3; - } - - // View to global index range of local block: - auto sub_lblock = dash::sub(sub_begin_gidx, - sub_end_gidx, - array); - static_assert( - !dash::view_traits::is_local::value, - "sub(range) expected have type trait local = false"); - - EXPECT_EQ(sub_end_gidx - sub_begin_gidx, sub_lblock.size()); - EXPECT_EQ(sub_lblock.size(), - dash::end(sub_lblock) - dash::begin(sub_lblock)); - - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *dash::begin(dash::index(sub_lblock))); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *dash::end(dash::index(sub_lblock))); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - sub_lblock.size()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - dash::end(sub_lblock) - dash::begin(sub_lblock)); - - auto l_sub_lblock = dash::local(sub_lblock); - - static_assert( - dash::view_traits::is_local::value, - "local(sub(range)) expected have type trait local = true"); - - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *dash::begin(dash::index(l_sub_lblock))); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *dash::end(dash::index(l_sub_lblock))); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - l_sub_lblock.size()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - dash::end(l_sub_lblock) - dash::begin(l_sub_lblock)); - - EXPECT_EQ(block_size, l_sub_lblock.size()); - EXPECT_EQ(l_sub_lblock.size(), - dash::end(l_sub_lblock) - dash::begin(l_sub_lblock)); - - for (int lsi = 0; lsi != sub_lblock.size(); lsi++) { - int sub_elem = sub_lblock[lsi]; - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", sub_elem); - } - for (int lsi = 0; lsi != l_sub_lblock.size(); lsi++) { - int l_sub_elem = l_sub_lblock[lsi]; - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", l_sub_elem); - // TODO: Assert - } - - auto sub_l_sub_lblock = dash::sub(1,4, dash::local(l_sub_lblock)); - - static_assert( - dash::view_traits::is_local::value, - "sub(local(sub(range))) expected have type trait local = true"); - - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *dash::begin(dash::index(sub_l_sub_lblock))); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - *dash::end(dash::index(sub_l_sub_lblock))); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - sub_l_sub_lblock.size()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - dash::end(sub_l_sub_lblock) - - dash::begin(sub_l_sub_lblock)); - // TODO: Assert - - for (int slsi = 0; slsi != sub_l_sub_lblock.size(); slsi++) { - int sub_l_sub_elem = sub_l_sub_lblock[slsi]; - int l_sub_elem = l_sub_lblock[slsi+1]; - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - l_sub_elem); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", - sub_l_sub_elem); - EXPECT_EQ(l_sub_elem, sub_l_sub_elem); - } - } -} - -TEST_F(ViewTest, ArrayBlockCyclicPatternLocalView) -{ - int block_size = 3; - int nblocks_per_unit = 2; - int array_size = dash::size() * block_size * nblocks_per_unit; - - dash::Array array(array_size, dash::BLOCKCYCLIC(block_size)); - - for (auto li = 0; li != array.local.size(); ++li) { - array.local[li] = (100 * (dash::myid() + 1)) + - (li) + - ((dash::myid() * nblocks_per_unit * block_size) - + li) * - 0.01; - } - - array.barrier(); - - int sub_begin_gidx = 2; - int sub_end_gidx = array.size() - 2; - - auto sub_range = dash::sub(sub_begin_gidx, - sub_end_gidx, - array); - - if (dash::myid() == 0) { - for (int si = 0; si != sub_range.size(); si++) { - double sub_elem = sub_range[si]; - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalView", - sub_elem); - // TODO: Assert - } - } - array.barrier(); - - for (int si = 0; si != sub_range.size(); si++) { - double sub_elem = sub_range[si]; - double arr_elem = array[si + sub_begin_gidx]; - EXPECT_EQ(arr_elem, sub_elem); - } - - auto lsub_range = dash::local(sub_range); - - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalView", - lsub_range.size()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalView", - dash::index(lsub_range).size()); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalView", - *dash::begin(dash::index(lsub_range))); - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalView", - *dash::end(dash::index(lsub_range))); - - for (int lsi = 0; lsi != lsub_range.size(); lsi++) { - double lsub_elem = lsub_range[lsi]; - DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalView", - lsub_elem); - // TODO: Assert - } -} - -/* -TEST_F(ViewTest, ArrayBlockedPatternViewUnion) -{ - int block_size = 37; - int array_size = dash::size() * block_size; - - int block_a_begin_gidx = (block_size / 2) * (dash::myid() + 0); - int block_a_end_gidx = (block_size / 2) * (dash::myid() + 1); - int block_b_begin_gidx = (block_size / 2) * (dash::myid() + 1); - int block_b_end_gidx = (block_size / 2) * (dash::myid() + 2); - - dash::Array a(array_size); - - auto block_a_gview = dash::sub(block_a_begin_gidx, - block_a_end_gidx, - a); - auto block_b_gview = dash::sub(block_b_begin_gidx, - block_b_end_gidx, - a); - auto block_views_union = dash::set_union({ - block_a_gview, - block_b_gview - }); -} -*/ diff --git a/dash/test/AccumulateTest.cc b/dash/test/algorithm/AccumulateTest.cc similarity index 98% rename from dash/test/AccumulateTest.cc rename to dash/test/algorithm/AccumulateTest.cc index 947e8c00b..1f28e3c60 100644 --- a/dash/test/AccumulateTest.cc +++ b/dash/test/algorithm/AccumulateTest.cc @@ -2,7 +2,7 @@ #include #include "AccumulateTest.h" -#include "TestBase.h" +#include "../TestBase.h" #include #include diff --git a/dash/test/AccumulateTest.h b/dash/test/algorithm/AccumulateTest.h similarity index 69% rename from dash/test/AccumulateTest.h rename to dash/test/algorithm/AccumulateTest.h index d6beba5ea..c7d430ee2 100644 --- a/dash/test/AccumulateTest.h +++ b/dash/test/algorithm/AccumulateTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__ACCUMULATE_TEST_H_ #define DASH__TEST__ACCUMULATE_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::accumulate @@ -13,13 +13,8 @@ class AccumulateTest : public dash::test::TestBase { AccumulateTest() : _dash_id(0), - _dash_size(0) { - LOG_MESSAGE(">>> Test suite: AccumulateTest"); - } - - virtual ~AccumulateTest() { - LOG_MESSAGE("<<< Closing test suite: AccumulateTest"); - } + _dash_size(0) + { } virtual void SetUp() { dash::test::TestBase::SetUp(); diff --git a/dash/test/CopyTest.cc b/dash/test/algorithm/CopyTest.cc similarity index 99% rename from dash/test/CopyTest.cc rename to dash/test/algorithm/CopyTest.cc index 416291aca..267782af7 100644 --- a/dash/test/CopyTest.cc +++ b/dash/test/algorithm/CopyTest.cc @@ -9,8 +9,8 @@ #include #include -#include "TestBase.h" -#include "TestLogHelpers.h" +#include "../TestBase.h" +#include "../TestLogHelpers.h" #include "CopyTest.h" #include diff --git a/dash/test/CopyTest.h b/dash/test/algorithm/CopyTest.h similarity index 59% rename from dash/test/CopyTest.h rename to dash/test/algorithm/CopyTest.h index 1ed9882a2..e70d27f9e 100644 --- a/dash/test/CopyTest.h +++ b/dash/test/algorithm/CopyTest.h @@ -3,7 +3,7 @@ #include -#include "TestBase.h" +#include "../TestBase.h" /** @@ -11,18 +11,8 @@ */ class CopyTest : public dash::test::TestBase { protected: - size_t _dash_id; - size_t _dash_size; - - CopyTest() - : _dash_id(0), - _dash_size(0) { - LOG_MESSAGE(">>> Test suite: CopyTest"); - } - - virtual ~CopyTest() { - LOG_MESSAGE("<<< Closing test suite: CopyTest"); - } + size_t _dash_id = 0; + size_t _dash_size = 0; virtual void SetUp() { dash::test::TestBase::SetUp(); diff --git a/dash/test/FillTest.cc b/dash/test/algorithm/FillTest.cc similarity index 100% rename from dash/test/FillTest.cc rename to dash/test/algorithm/FillTest.cc diff --git a/dash/test/FillTest.h b/dash/test/algorithm/FillTest.h similarity index 91% rename from dash/test/FillTest.h rename to dash/test/algorithm/FillTest.h index 512431ea4..1ae625484 100644 --- a/dash/test/FillTest.h +++ b/dash/test/algorithm/FillTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__FILL_TEST_H_ #define DASH__TEST__FILL_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::transform diff --git a/dash/test/FindTest.cc b/dash/test/algorithm/FindTest.cc similarity index 100% rename from dash/test/FindTest.cc rename to dash/test/algorithm/FindTest.cc diff --git a/dash/test/FindTest.h b/dash/test/algorithm/FindTest.h similarity index 95% rename from dash/test/FindTest.h rename to dash/test/algorithm/FindTest.h index c82e50925..040134ade 100644 --- a/dash/test/FindTest.h +++ b/dash/test/algorithm/FindTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__FIND_TEST_H_ #define DASH__TEST__FIND_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" #include diff --git a/dash/test/ForEachTest.cc b/dash/test/algorithm/ForEachTest.cc similarity index 100% rename from dash/test/ForEachTest.cc rename to dash/test/algorithm/ForEachTest.cc diff --git a/dash/test/ForEachTest.h b/dash/test/algorithm/ForEachTest.h similarity index 96% rename from dash/test/ForEachTest.h rename to dash/test/algorithm/ForEachTest.h index 7fa02ae00..624c1a0b2 100644 --- a/dash/test/ForEachTest.h +++ b/dash/test/algorithm/ForEachTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__FOR_EACH_TEST_H_ #define DASH__TEST__FOR_EACH_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" #include diff --git a/dash/test/GenerateTest.cc b/dash/test/algorithm/GenerateTest.cc similarity index 100% rename from dash/test/GenerateTest.cc rename to dash/test/algorithm/GenerateTest.cc diff --git a/dash/test/GenerateTest.h b/dash/test/algorithm/GenerateTest.h similarity index 95% rename from dash/test/GenerateTest.h rename to dash/test/algorithm/GenerateTest.h index 287378ef8..ead302e91 100644 --- a/dash/test/GenerateTest.h +++ b/dash/test/algorithm/GenerateTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__GENERATE_TEST_H_ #define DASH__TEST__GENERATE_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" #include diff --git a/dash/test/LocalRangeTest.cc b/dash/test/algorithm/LocalRangeTest.cc similarity index 100% rename from dash/test/LocalRangeTest.cc rename to dash/test/algorithm/LocalRangeTest.cc diff --git a/dash/test/LocalRangeTest.h b/dash/test/algorithm/LocalRangeTest.h similarity index 94% rename from dash/test/LocalRangeTest.h rename to dash/test/algorithm/LocalRangeTest.h index 8ed8b385c..0b0d33fe4 100644 --- a/dash/test/LocalRangeTest.h +++ b/dash/test/algorithm/LocalRangeTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__LOCAL_RANGE_TEST_H_ #define DASH__TEST__LOCAL_RANGE_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for local range conversions like dash::local_range. diff --git a/dash/test/MaxElementTest.cc b/dash/test/algorithm/MaxElementTest.cc similarity index 100% rename from dash/test/MaxElementTest.cc rename to dash/test/algorithm/MaxElementTest.cc diff --git a/dash/test/MaxElementTest.h b/dash/test/algorithm/MaxElementTest.h similarity index 95% rename from dash/test/MaxElementTest.h rename to dash/test/algorithm/MaxElementTest.h index ef7c955ab..bd108bd99 100644 --- a/dash/test/MaxElementTest.h +++ b/dash/test/algorithm/MaxElementTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__MAX_ELEMENT_TEST_H_ #define DASH__TEST__MAX_ELEMENT_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" #include diff --git a/dash/test/MinElementTest.cc b/dash/test/algorithm/MinElementTest.cc similarity index 100% rename from dash/test/MinElementTest.cc rename to dash/test/algorithm/MinElementTest.cc diff --git a/dash/test/MinElementTest.h b/dash/test/algorithm/MinElementTest.h similarity index 95% rename from dash/test/MinElementTest.h rename to dash/test/algorithm/MinElementTest.h index 26bd63ed1..d84e99845 100644 --- a/dash/test/MinElementTest.h +++ b/dash/test/algorithm/MinElementTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__MIN_ELEMENT_TEST_H_ #define DASH__TEST__MIN_ELEMENT_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" #include diff --git a/dash/test/STLAlgorithmTest.cc b/dash/test/algorithm/STLAlgorithmTest.cc similarity index 98% rename from dash/test/STLAlgorithmTest.cc rename to dash/test/algorithm/STLAlgorithmTest.cc index 4d60253fb..6a3b0d719 100644 --- a/dash/test/STLAlgorithmTest.cc +++ b/dash/test/algorithm/STLAlgorithmTest.cc @@ -1,6 +1,7 @@ #include "STLAlgorithmTest.h" +#include #include #include @@ -96,7 +97,7 @@ TEST_F(STLAlgorithmTest, StdCopyGlobalToGlobal) { for (int l = 0; l < array_a.size(); l++) { DASH_LOG_DEBUG_VAR("STLAlgorithmTest.StdCopyGlobalToGlobal", - dash::internal::typestr(array_b[l])); + dash::typestr(array_b[l])); array_b[l] = array_a[l]; } DASH_LOG_DEBUG_VAR("STLAlgorithmTest.StdCopyGlobalToGlobal", array_b); diff --git a/dash/test/STLAlgorithmTest.h b/dash/test/algorithm/STLAlgorithmTest.h similarity index 94% rename from dash/test/STLAlgorithmTest.h rename to dash/test/algorithm/STLAlgorithmTest.h index 891fb215f..f4ad6b480 100644 --- a/dash/test/STLAlgorithmTest.h +++ b/dash/test/algorithm/STLAlgorithmTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__STL_ALGORITHM_TEST_H_ #define DASH__TEST__STL_ALGORITHM_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** diff --git a/dash/test/SUMMATest.cc b/dash/test/algorithm/SUMMATest.cc similarity index 95% rename from dash/test/SUMMATest.cc rename to dash/test/algorithm/SUMMATest.cc index 6c93531a9..32ca143d2 100644 --- a/dash/test/SUMMATest.cc +++ b/dash/test/algorithm/SUMMATest.cc @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -20,12 +21,16 @@ TEST_F(SUMMATest, Deduction) { SKIP_TEST_IF_NO_SUMMA(); + if (dash::size() % 2 != 0) { + SKIP_TEST_MSG("SUMMATest requires multiple of 2 units"); + } + size_t num_units = dash::Team::All().size(); size_t team_size_x = num_units; size_t team_size_y = 1; - size_t extent_cols = num_units; - size_t extent_rows = num_units; + size_t extent_cols = num_units * 20; + size_t extent_rows = num_units * 20; #if 0 // For explicit definition of data distribution: @@ -70,8 +75,10 @@ TEST_F(SUMMATest, Deduction) }); } - LOG_MESSAGE("Deduced pattern: " - "size(%lu,%lu) tilesize(%lu,%lu) teamsize(%lu,%lu) disttype(%d,%d)", + LOG_MESSAGE("Deduced pattern: %s " + "size(%lu,%lu) tilesize(%lu,%lu) " + "teamsize(%lu,%lu) disttype(%d,%d)", + dash::typestr(pattern).c_str(), pattern.extent(0), pattern.extent(1), pattern.block(0).extent(0), @@ -142,8 +149,8 @@ TEST_F(SUMMATest, Deduction) // Expected to be resolved to SUMMA version of dash::mmult: LOG_MESSAGE("Calling dash::mmult ..."); dash::mmult(matrix_a, - matrix_b, - matrix_c); + matrix_b, + matrix_c); if (dash::myid().id == 0) { dash::test::print_matrix("summa.matrix A", matrix_a, 3); diff --git a/dash/test/SUMMATest.h b/dash/test/algorithm/SUMMATest.h similarity index 93% rename from dash/test/SUMMATest.h rename to dash/test/algorithm/SUMMATest.h index 45e560c42..9116b4e28 100644 --- a/dash/test/SUMMATest.h +++ b/dash/test/algorithm/SUMMATest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__SUMMA_TEST_H_ #define DASH__TEST__SUMMA_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for algorithm \c dash::summa. diff --git a/dash/test/TransformTest.cc b/dash/test/algorithm/TransformTest.cc similarity index 100% rename from dash/test/TransformTest.cc rename to dash/test/algorithm/TransformTest.cc diff --git a/dash/test/TransformTest.h b/dash/test/algorithm/TransformTest.h similarity index 94% rename from dash/test/TransformTest.h rename to dash/test/algorithm/TransformTest.h index 0bba6b82d..e355c02a4 100644 --- a/dash/test/TransformTest.h +++ b/dash/test/algorithm/TransformTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__TRANSFORM_TEST_H_ #define DASH__TEST__TRANSFORM_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::transform diff --git a/dash/test/UniversalMemberTest.cc b/dash/test/bits/UniversalMemberTest.cc similarity index 100% rename from dash/test/UniversalMemberTest.cc rename to dash/test/bits/UniversalMemberTest.cc diff --git a/dash/test/UniversalMemberTest.h b/dash/test/bits/UniversalMemberTest.h similarity index 94% rename from dash/test/UniversalMemberTest.h rename to dash/test/bits/UniversalMemberTest.h index c3a5a20b0..40cb84e76 100644 --- a/dash/test/UniversalMemberTest.h +++ b/dash/test/bits/UniversalMemberTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__UTIL_TEST_H_ #define DASH__TEST__UTIL_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for the DASH helper types. diff --git a/dash/test/ArrayLargeStructTest.cc b/dash/test/container/ArrayLargeStructTest.cc similarity index 97% rename from dash/test/ArrayLargeStructTest.cc rename to dash/test/container/ArrayLargeStructTest.cc index 761d9bb72..eaa7d481c 100644 --- a/dash/test/ArrayLargeStructTest.cc +++ b/dash/test/container/ArrayLargeStructTest.cc @@ -2,7 +2,7 @@ #include #include "ArrayLargeStructTest.h" -#include "TestBase.h" +#include "../TestBase.h" #include diff --git a/dash/test/ArrayLargeStructTest.h b/dash/test/container/ArrayLargeStructTest.h similarity index 78% rename from dash/test/ArrayLargeStructTest.h rename to dash/test/container/ArrayLargeStructTest.h index 73c823a6f..45a3bb6b5 100644 --- a/dash/test/ArrayLargeStructTest.h +++ b/dash/test/container/ArrayLargeStructTest.h @@ -3,7 +3,7 @@ #include -#include "TestBase.h" +#include "../TestBase.h" #if defined (DASH_ENABLE_REGRESSION_TEST) @@ -30,13 +30,8 @@ class ArrayLargeStruct : public dash::test::TestBase { ArrayLargeStruct() : _dash_id(0), - _dash_size(0) { - LOG_MESSAGE(">>> Test suite: ArrayLargeStruct"); - } - - virtual ~ArrayLargeStruct() { - LOG_MESSAGE("<<< Closing test suite: ArrayLargeStruct"); - } + _dash_size(0) + { } virtual void SetUp() { dash::test::TestBase::SetUp(); diff --git a/dash/test/ArrayTest.cc b/dash/test/container/ArrayTest.cc similarity index 99% rename from dash/test/ArrayTest.cc rename to dash/test/container/ArrayTest.cc index e548af189..56885652d 100644 --- a/dash/test/ArrayTest.cc +++ b/dash/test/container/ArrayTest.cc @@ -8,7 +8,7 @@ #include #include -#include "TestBase.h" +#include "../TestBase.h" #include "ArrayTest.h" diff --git a/dash/test/ArrayTest.h b/dash/test/container/ArrayTest.h similarity index 84% rename from dash/test/ArrayTest.h rename to dash/test/container/ArrayTest.h index 6d376f809..a54419d7d 100644 --- a/dash/test/ArrayTest.h +++ b/dash/test/container/ArrayTest.h @@ -3,7 +3,7 @@ #include -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::Array @@ -26,10 +26,6 @@ class ArrayTest : public dash::test::TestBase { _dash_size = dash::size(); _num_elem = 100; } - - virtual void TearDown() { - dash::test::TestBase::TearDown(); - } }; #endif // DASH__TEST__ARRAY_TEST_H_ diff --git a/dash/test/ListTest.cc b/dash/test/container/ListTest.cc similarity index 100% rename from dash/test/ListTest.cc rename to dash/test/container/ListTest.cc diff --git a/dash/test/ListTest.h b/dash/test/container/ListTest.h similarity index 93% rename from dash/test/ListTest.h rename to dash/test/container/ListTest.h index 8786e9236..4c46443e8 100644 --- a/dash/test/ListTest.h +++ b/dash/test/container/ListTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__LIST_TEST_H_ #define DASH__TEST__LIST_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::List diff --git a/dash/test/MatrixTest.cc b/dash/test/container/MatrixTest.cc similarity index 100% rename from dash/test/MatrixTest.cc rename to dash/test/container/MatrixTest.cc diff --git a/dash/test/MatrixTest.h b/dash/test/container/MatrixTest.h similarity index 93% rename from dash/test/MatrixTest.h rename to dash/test/container/MatrixTest.h index 4ab5f526f..3914bca7d 100644 --- a/dash/test/MatrixTest.h +++ b/dash/test/container/MatrixTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__MATRIX_TEST_H_ #define DASH__TEST__MATRIX_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::Matrix diff --git a/dash/test/SharedTest.cc b/dash/test/container/SharedTest.cc similarity index 100% rename from dash/test/SharedTest.cc rename to dash/test/container/SharedTest.cc diff --git a/dash/test/SharedTest.h b/dash/test/container/SharedTest.h similarity index 93% rename from dash/test/SharedTest.h rename to dash/test/container/SharedTest.h index e20d0639a..7c21ec2f3 100644 --- a/dash/test/SharedTest.h +++ b/dash/test/container/SharedTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__SHARED_TEST_H_ #define DASH__TEST__SHARED_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::Shared diff --git a/dash/test/UnorderedMapTest.cc b/dash/test/container/UnorderedMapTest.cc similarity index 99% rename from dash/test/UnorderedMapTest.cc rename to dash/test/container/UnorderedMapTest.cc index 366be23d7..96fe32d09 100644 --- a/dash/test/UnorderedMapTest.cc +++ b/dash/test/container/UnorderedMapTest.cc @@ -1,6 +1,7 @@ #include "UnorderedMapTest.h" +#include #include #include @@ -531,7 +532,7 @@ TEST_F(UnorderedMapTest, MappedAtomics) DASH_LOG_DEBUG("UnorderedMapTest.Local", "return type of map.find(key):", - dash::internal::typestr(found)); + dash::typestr(found)); EXPECT_NE_U(map.end(), found); map_value found_value = *found; diff --git a/dash/test/UnorderedMapTest.h b/dash/test/container/UnorderedMapTest.h similarity index 90% rename from dash/test/UnorderedMapTest.h rename to dash/test/container/UnorderedMapTest.h index fe429a790..ff5ea2de3 100644 --- a/dash/test/UnorderedMapTest.h +++ b/dash/test/container/UnorderedMapTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__UNORDERED_MAP_TEST_H_ #define DASH__TEST__UNORDERED_MAP_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::UnorderedMap diff --git a/dash/test/DARTCollectiveTest.cc b/dash/test/dart/DARTCollectiveTest.cc similarity index 100% rename from dash/test/DARTCollectiveTest.cc rename to dash/test/dart/DARTCollectiveTest.cc diff --git a/dash/test/DARTCollectiveTest.h b/dash/test/dart/DARTCollectiveTest.h similarity index 58% rename from dash/test/DARTCollectiveTest.h rename to dash/test/dart/DARTCollectiveTest.h index 6b9181fe0..3fbb0fa68 100644 --- a/dash/test/DARTCollectiveTest.h +++ b/dash/test/dart/DARTCollectiveTest.h @@ -1,25 +1,15 @@ #ifndef DASH__TEST__DART_COLLECTIVE_TEST_H_ #define DASH__TEST__DART_COLLECTIVE_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for onesided operations provided by DART. */ class DARTCollectiveTest : public dash::test::TestBase { protected: - size_t _dash_id; - size_t _dash_size; - - DARTCollectiveTest() - : _dash_id(0), - _dash_size(0) { - LOG_MESSAGE(">>> Test suite: DARTCollectiveTest"); - } - - virtual ~DARTCollectiveTest() { - LOG_MESSAGE("<<< Closing test suite: DARTCollectiveTest"); - } + size_t _dash_id = 0; + size_t _dash_size = 0; virtual void SetUp() { dash::test::TestBase::SetUp(); diff --git a/dash/test/DARTLocalityTest.cc b/dash/test/dart/DARTLocalityTest.cc similarity index 96% rename from dash/test/DARTLocalityTest.cc rename to dash/test/dart/DARTLocalityTest.cc index 132a099ff..b721c89af 100644 --- a/dash/test/DARTLocalityTest.cc +++ b/dash/test/dart/DARTLocalityTest.cc @@ -119,7 +119,9 @@ TEST_F(DARTLocalityTest, ExcludeLocalityDomain) dart_domain_clone(loc_team_all_orig, &loc_team_all_copy)); dart_unit_locality_t * ul; - EXPECT_EQ_U(DART_OK, dart_unit_locality(DART_TEAM_ALL, _dash_id, &ul)); + EXPECT_EQ_U( + DART_OK, + dart_unit_locality(DART_TEAM_ALL, dash::myid().id, &ul)); // Remove the active unit's domain: const char * excluded_domain = ul->domain_tag; @@ -145,7 +147,9 @@ TEST_F(DARTLocalityTest, UnitLocality) DASH_LOG_TRACE("DARTLocalityTest.Domains", "get local unit locality descriptor"); dart_unit_locality_t * ul; - EXPECT_EQ_U(DART_OK, dart_unit_locality(DART_TEAM_ALL, _dash_id, &ul)); + EXPECT_EQ_U( + DART_OK, + dart_unit_locality(DART_TEAM_ALL, dash::myid().id, &ul)); DASH_LOG_TRACE("DARTLocalityTest.Domains", "pointer to local unit locality descriptor:", ul); DASH_LOG_TRACE_VAR("DARTLocalityTest.UnitLocality", *ul); @@ -161,7 +165,7 @@ TEST_F(DARTLocalityTest, UnitLocality) DASH_LOG_TRACE_VAR("DARTLocalityTest.UnitLocality", ul->hwinfo.min_threads); DASH_LOG_TRACE_VAR("DARTLocalityTest.UnitLocality", ul->hwinfo.max_threads); - EXPECT_EQ_U(_dash_id, ul->unit.id); + EXPECT_EQ_U(dash::myid().id, ul->unit.id); // Units may group multiple cores: EXPECT_GE_U(ul->hwinfo.cpu_id, -1); // -1 if unknown, >= 0 if set @@ -211,7 +215,7 @@ TEST_F(DARTLocalityTest, Domains) TEST_F(DARTLocalityTest, ScopeDomains) { - if (0 != dash::myid()) { + if (0 != dash::myid().id) { return; } diff --git a/dash/test/dart/DARTLocalityTest.h b/dash/test/dart/DARTLocalityTest.h new file mode 100644 index 000000000..976f03582 --- /dev/null +++ b/dash/test/dart/DARTLocalityTest.h @@ -0,0 +1,13 @@ +#ifndef DASH__TEST__DART_LOCALITY_TEST_H_ +#define DASH__TEST__DART_LOCALITY_TEST_H_ + +#include "../TestBase.h" + + +/** + * Test fixture for onesided operations provided by DART. + */ +class DARTLocalityTest : public dash::test::TestBase { +}; + +#endif // DASH__TEST__DART_LOCALITY_TEST_H_ diff --git a/dash/test/DARTMemAllocTest.cc b/dash/test/dart/DARTMemAllocTest.cc similarity index 85% rename from dash/test/DARTMemAllocTest.cc rename to dash/test/dart/DARTMemAllocTest.cc index bb7bae827..c080568ae 100644 --- a/dash/test/DARTMemAllocTest.cc +++ b/dash/test/dart/DARTMemAllocTest.cc @@ -23,15 +23,15 @@ TEST_F(DARTMemAllocTest, LocalAlloc) dart_gptr_getaddr(gptr, (void**)&baseptr)); for (size_t i = 0; i < block_size; ++i) { - baseptr[i] = _dash_id; + baseptr[i] = dash::myid().id; } - dash::Array arr(_dash_size); + dash::Array arr(dash::size()); arr.local[0] = gptr; arr.barrier(); value_t neighbor_val; - size_t neighbor_id = (_dash_id + 1) % _dash_size; + size_t neighbor_id = (dash::myid().id + 1) % dash::size(); dart_storage_t ds = dash::dart_storage(1); ASSERT_EQ_U( DART_OK, @@ -64,12 +64,12 @@ TEST_F(DARTMemAllocTest, SegmentReuseTest) int16_t segid = gptr.segid; // check that all allocations have the same segment ID - dash::Array arr(_dash_size); + dash::Array arr(dash::size()); arr.local[0] = gptr; arr.barrier(); - if (_dash_id == 0) { - for (int i = 0; i < _dash_size; ++i) { - ASSERT_EQ_U( + if (dash::myid() == 0) { + for (int i = 0; i < dash::size(); ++i) { + EXPECT_EQ_U( gptr.segid, static_cast(arr[i]).segid); } @@ -86,8 +86,8 @@ TEST_F(DARTMemAllocTest, SegmentReuseTest) ASSERT_NE_U(gptr2.segid, gptr.segid); arr.local[0] = gptr2; arr.barrier(); - if (_dash_id == 0) { - for (int i = 0; i < _dash_size; ++i) { + if (dash::myid() == 0) { + for (int i = 0; i < dash::size(); ++i) { ASSERT_EQ_U( gptr2.segid, static_cast(arr[i]).segid); diff --git a/dash/test/dart/DARTMemAllocTest.h b/dash/test/dart/DARTMemAllocTest.h new file mode 100644 index 000000000..61d48a8f5 --- /dev/null +++ b/dash/test/dart/DARTMemAllocTest.h @@ -0,0 +1,13 @@ +#ifndef DASH__TEST__DART_ONESIDED_TEST_H_ +#define DASH__TEST__DART_ONESIDED_TEST_H_ + +#include "../TestBase.h" + + +/** + * Test fixture for onesided operations provided by DART. + */ +class DARTMemAllocTest : public dash::test::TestBase { +}; + +#endif // DASH__TEST__DART_ONESIDED_TEST_H_ diff --git a/dash/test/DARTOnesidedTest.cc b/dash/test/dart/DARTOnesidedTest.cc similarity index 91% rename from dash/test/DARTOnesidedTest.cc rename to dash/test/dart/DARTOnesidedTest.cc index 5421eab20..029f67bbb 100644 --- a/dash/test/DARTOnesidedTest.cc +++ b/dash/test/dart/DARTOnesidedTest.cc @@ -9,7 +9,7 @@ TEST_F(DARTOnesidedTest, GetBlockingSingleBlock) { typedef int value_t; const size_t block_size = 10; - size_t num_elem_total = _dash_size * block_size; + size_t num_elem_total = dash::size() * block_size; dash::Array array(num_elem_total, dash::BLOCKED); // Array to store local copy: int local_array[block_size]; @@ -19,7 +19,7 @@ TEST_F(DARTOnesidedTest, GetBlockingSingleBlock) } array.barrier(); // Unit to copy values from: - dart_unit_t unit_src = (dash::myid() + 1) % _dash_size; + dart_unit_t unit_src = (dash::myid() + 1) % dash::size(); // Global start index of block to copy: int g_src_index = unit_src * block_size; // Copy values: @@ -42,9 +42,9 @@ TEST_F(DARTOnesidedTest, GetBlockingTwoBlocks) typedef int value_t; const size_t block_size = 10; const size_t num_elem_copy = 2 * block_size; - size_t num_elem_total = _dash_size * block_size; + size_t num_elem_total = dash::size() * block_size; dash::Array array(num_elem_total, dash::BLOCKED); - if (_dash_size < 2) { + if (dash::size() < 2) { return; } // Array to store local copy: @@ -74,10 +74,10 @@ TEST_F(DARTOnesidedTest, GetHandleAllRemote) { typedef int value_t; const size_t block_size = 5000; - size_t num_elem_copy = (_dash_size - 1) * block_size; - size_t num_elem_total = _dash_size * block_size; + size_t num_elem_copy = (dash::size() - 1) * block_size; + size_t num_elem_total = dash::size() * block_size; dash::Array array(num_elem_total, dash::BLOCKED); - if (_dash_size < 2) { + if (dash::size() < 2) { return; } // Array to store local copy: @@ -93,7 +93,7 @@ TEST_F(DARTOnesidedTest, GetHandleAllRemote) LOG_MESSAGE("Requesting remote blocks"); // Copy values from all non-local blocks: size_t block = 0; - for (size_t u = 0; u < _dash_size; ++u) { + for (size_t u = 0; u < dash::size(); ++u) { if (u != static_cast(dash::myid())) { LOG_MESSAGE("Requesting block %zu from unit %zu", block, u); dart_handle_t handle; diff --git a/dash/test/dart/DARTOnesidedTest.h b/dash/test/dart/DARTOnesidedTest.h new file mode 100644 index 000000000..6d804eeda --- /dev/null +++ b/dash/test/dart/DARTOnesidedTest.h @@ -0,0 +1,13 @@ +#ifndef DASH__TEST__DART_ONESIDED_TEST_H_ +#define DASH__TEST__DART_ONESIDED_TEST_H_ + +#include "../TestBase.h" + + +/** + * Test fixture for onesided operations provided by DART. + */ +class DARTOnesidedTest : public dash::test::TestBase { +}; + +#endif // DASH__TEST__DART_ONESIDED_TEST_H_ diff --git a/dash/test/ThreadsafetyTest.cc b/dash/test/dart/ThreadsafetyTest.cc similarity index 100% rename from dash/test/ThreadsafetyTest.cc rename to dash/test/dart/ThreadsafetyTest.cc diff --git a/dash/test/ThreadsafetyTest.h b/dash/test/dart/ThreadsafetyTest.h similarity index 96% rename from dash/test/ThreadsafetyTest.h rename to dash/test/dart/ThreadsafetyTest.h index f9696f98a..1fb026e6d 100644 --- a/dash/test/ThreadsafetyTest.h +++ b/dash/test/dart/ThreadsafetyTest.h @@ -1,7 +1,7 @@ #ifndef DASH_DASH_TEST_THREADSAFETYTEST_H_ #define DASH_DASH_TEST_THREADSAFETYTEST_H_ -#include "TestBase.h" +#include "../TestBase.h" #ifdef DASH_ENABLE_OPENMP #include diff --git a/dash/test/HDF5ArrayTest.cc b/dash/test/io/HDF5ArrayTest.cc similarity index 100% rename from dash/test/HDF5ArrayTest.cc rename to dash/test/io/HDF5ArrayTest.cc diff --git a/dash/test/HDF5ArrayTest.h b/dash/test/io/HDF5ArrayTest.h similarity index 97% rename from dash/test/HDF5ArrayTest.h rename to dash/test/io/HDF5ArrayTest.h index 95a472a4b..1eca0d89d 100644 --- a/dash/test/HDF5ArrayTest.h +++ b/dash/test/io/HDF5ArrayTest.h @@ -3,7 +3,7 @@ #ifdef DASH_ENABLE_HDF5 -#include "TestBase.h" +#include "../TestBase.h" // for CustomType test #include "hdf5.h" diff --git a/dash/test/HDF5MatrixTest.cc b/dash/test/io/HDF5MatrixTest.cc similarity index 100% rename from dash/test/HDF5MatrixTest.cc rename to dash/test/io/HDF5MatrixTest.cc diff --git a/dash/test/HDF5MatrixTest.h b/dash/test/io/HDF5MatrixTest.h similarity index 97% rename from dash/test/HDF5MatrixTest.h rename to dash/test/io/HDF5MatrixTest.h index 4954d3c23..824431bf1 100644 --- a/dash/test/HDF5MatrixTest.h +++ b/dash/test/io/HDF5MatrixTest.h @@ -3,7 +3,7 @@ #ifndef DASH__TEST__HDF5_MATRIX_TEST_H__INCLUDED #define DASH__TEST__HDF5_MATRIX_TEST_H__INCLUDED -#include "TestBase.h" +#include "../TestBase.h" class HDF5MatrixTest : public dash::test::TestBase { protected: diff --git a/dash/test/GlobAsyncRefTest.cc b/dash/test/iterator/GlobAsyncRefTest.cc similarity index 100% rename from dash/test/GlobAsyncRefTest.cc rename to dash/test/iterator/GlobAsyncRefTest.cc diff --git a/dash/test/GlobAsyncRefTest.h b/dash/test/iterator/GlobAsyncRefTest.h similarity index 94% rename from dash/test/GlobAsyncRefTest.h rename to dash/test/iterator/GlobAsyncRefTest.h index 4e7fcd518..8dcc89add 100644 --- a/dash/test/GlobAsyncRefTest.h +++ b/dash/test/iterator/GlobAsyncRefTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__GLOB_ASYNC_REF_TEST_H_ #define DASH__TEST__GLOB_ASYNC_REF_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for non-blocking operations using \c dash::GlobAsyncRef. diff --git a/dash/test/GlobStencilIterTest.cc b/dash/test/iterator/GlobStencilIterTest.cc similarity index 100% rename from dash/test/GlobStencilIterTest.cc rename to dash/test/iterator/GlobStencilIterTest.cc diff --git a/dash/test/GlobStencilIterTest.h b/dash/test/iterator/GlobStencilIterTest.h similarity index 93% rename from dash/test/GlobStencilIterTest.h rename to dash/test/iterator/GlobStencilIterTest.h index 2d0627082..0995a8032 100644 --- a/dash/test/GlobStencilIterTest.h +++ b/dash/test/iterator/GlobStencilIterTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__GLOB_STENCIL_ITER_TEST_H_ #define DASH__TEST__GLOB_STENCIL_ITER_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::GlobStencilIter. diff --git a/dash/test/CollectiveAllocatorTest.cc b/dash/test/memory/CollectiveAllocatorTest.cc similarity index 100% rename from dash/test/CollectiveAllocatorTest.cc rename to dash/test/memory/CollectiveAllocatorTest.cc diff --git a/dash/test/CollectiveAllocatorTest.h b/dash/test/memory/CollectiveAllocatorTest.h similarity index 51% rename from dash/test/CollectiveAllocatorTest.h rename to dash/test/memory/CollectiveAllocatorTest.h index ce4351426..011cbad56 100644 --- a/dash/test/CollectiveAllocatorTest.h +++ b/dash/test/memory/CollectiveAllocatorTest.h @@ -1,27 +1,16 @@ #ifndef DASH__TEST__ARRAY_TEST_H_ #define DASH__TEST__ARRAY_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::CollectiveAllocator */ class CollectiveAllocatorTest : public dash::test::TestBase { protected: - size_t _dash_id; - size_t _dash_size; - int _num_elem; - - CollectiveAllocatorTest() - : _dash_id(0), - _dash_size(0), - _num_elem(0) { - LOG_MESSAGE(">>> Test suite: CollectiveAllocatorTest"); - } - - virtual ~CollectiveAllocatorTest() { - LOG_MESSAGE("<<< Closing test suite: CollectiveAllocatorTest"); - } + size_t _dash_id = 0; + size_t _dash_size = 0; + int _num_elem = 0; virtual void SetUp() { dash::test::TestBase::SetUp(); diff --git a/dash/test/GlobDynamicMemTest.cc b/dash/test/memory/GlobDynamicMemTest.cc similarity index 100% rename from dash/test/GlobDynamicMemTest.cc rename to dash/test/memory/GlobDynamicMemTest.cc diff --git a/dash/test/GlobDynamicMemTest.h b/dash/test/memory/GlobDynamicMemTest.h similarity index 95% rename from dash/test/GlobDynamicMemTest.h rename to dash/test/memory/GlobDynamicMemTest.h index 61bce9e05..eb6b981e2 100644 --- a/dash/test/GlobDynamicMemTest.h +++ b/dash/test/memory/GlobDynamicMemTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__GLOB_DYNAMIC_MEM_TEST_H_ #define DASH__TEST__GLOB_DYNAMIC_MEM_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::GlobDynamicMem diff --git a/dash/test/GlobMemTest.cc b/dash/test/memory/GlobMemTest.cc similarity index 100% rename from dash/test/GlobMemTest.cc rename to dash/test/memory/GlobMemTest.cc diff --git a/dash/test/GlobMemTest.h b/dash/test/memory/GlobMemTest.h similarity index 93% rename from dash/test/GlobMemTest.h rename to dash/test/memory/GlobMemTest.h index 992426ae4..bb6fb7d46 100644 --- a/dash/test/GlobMemTest.h +++ b/dash/test/memory/GlobMemTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__GLOBMEM_TEST_H_ #define DASH__TEST__GLOBMEM_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::GlobMem diff --git a/dash/test/LocalAllocatorTest.cc b/dash/test/memory/LocalAllocatorTest.cc similarity index 100% rename from dash/test/LocalAllocatorTest.cc rename to dash/test/memory/LocalAllocatorTest.cc diff --git a/dash/test/LocalAllocatorTest.h b/dash/test/memory/LocalAllocatorTest.h similarity index 94% rename from dash/test/LocalAllocatorTest.h rename to dash/test/memory/LocalAllocatorTest.h index cc1c7bf37..c10cf81dd 100644 --- a/dash/test/LocalAllocatorTest.h +++ b/dash/test/memory/LocalAllocatorTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__LOCALALLOC_TEST_H_ #define DASH__TEST__LOCALALLOC_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::LocalAllocator diff --git a/dash/test/ConstexprTest.cc b/dash/test/meta/ConstexprTest.cc similarity index 85% rename from dash/test/ConstexprTest.cc rename to dash/test/meta/ConstexprTest.cc index 1b117caf5..c3e89554c 100644 --- a/dash/test/ConstexprTest.cc +++ b/dash/test/meta/ConstexprTest.cc @@ -11,15 +11,26 @@ TEST_F(ConstexprTest, Accumulate) { constexpr std::array arr = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; - constexpr int acc = dash::ce::accumulate( - arr, 0, 9, - 100, dash::ce::plus); - - if (dash::myid() == 0) { - DASH_LOG_DEBUG_VAR("ConstexprTest.Accumulate", acc); + { + constexpr int acc = dash::ce::accumulate( + arr, 0, 9, + 100, dash::ce::plus); + + if (dash::myid() == 0) { + DASH_LOG_DEBUG_VAR("ConstexprTest.Accumulate", acc); + EXPECT_EQ_U(136, acc); + } + } + { + constexpr int acc = dash::ce::accumulate( + arr, 2, 8, + 100, dash::ce::plus); + + if (dash::myid() == 0) { + DASH_LOG_DEBUG_VAR("ConstexprTest.Accumulate", acc); + EXPECT_EQ_U(127, acc); + } } - - EXPECT_EQ_U(136, acc); } TEST_F(ConstexprTest, Append) diff --git a/dash/test/ConstexprTest.h b/dash/test/meta/ConstexprTest.h similarity index 56% rename from dash/test/ConstexprTest.h rename to dash/test/meta/ConstexprTest.h index e1b7be468..6f0245ca2 100644 --- a/dash/test/ConstexprTest.h +++ b/dash/test/meta/ConstexprTest.h @@ -1,22 +1,12 @@ #ifndef DASH__TEST__CONSTEXPR_TEST_H__INCLUDED #define DASH__TEST__CONSTEXPR_TEST_H__INCLUDED -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for the DASH Constexpr concept */ class ConstexprTest : public dash::test::TestBase { -protected: - - ConstexprTest() { - LOG_MESSAGE(">>> Test suite: ConstexprTest"); - } - - virtual ~ConstexprTest() { - LOG_MESSAGE("<<< Closing test suite: ConstexprTest"); - } - }; #endif // DASH__TEST__CONSTEXPR_TEST_H__INCLUDED diff --git a/dash/test/meta/RangeTest.cc b/dash/test/meta/RangeTest.cc new file mode 100644 index 000000000..5150a860a --- /dev/null +++ b/dash/test/meta/RangeTest.cc @@ -0,0 +1,96 @@ + +#include "RangeTest.h" + +#include + +#include +#include +#include + +#include + +#include +#include + + + +TEST_F(RangeTest, RangeTraits) +{ + dash::Array array(dash::size() * 10); + auto v_sub = dash::sub(0, 10, array); + auto i_sub = dash::index(v_sub); + auto v_ssub = dash::sub(0, 5, (dash::sub(0, 10, array))); + auto v_loc = dash::local(array); + auto i_loc = dash::index(dash::local(array)); +// auto v_gloc = dash::global(dash::local(array)); +// auto i_glo = dash::global(dash::index(dash::local(array))); + auto v_bsub = *dash::begin(dash::blocks(v_sub)); + + static_assert(dash::is_range< + dash::Array + >::value == true, + "dash::is_range::value not matched"); + + static_assert(dash::is_range< + typename dash::Array::local_type + >::value == true, + "dash::is_range::value not matched"); + + static_assert(dash::is_range< + typename dash::Array::iterator + >::value == false, + "dash::is_range>::value not matched"); + static_assert(dash::is_range::value == true, + "range type trait for dash::Array not matched"); + static_assert(dash::is_range::value == true, + "range type trait for local(dash::Array) not matched"); + static_assert(dash::is_range::value == true, + "range type trait for sub(dash::Array) not matched"); + static_assert(dash::is_range::value == true, + "range type trait for sub(sub(dash::Array)) not matched"); + static_assert(dash::is_range::value == true, + "range type trait for begin(blocks(sub(dash::Array))) " + "not matched"); + static_assert(dash::is_range::value == true, + "range type trait for index(sub(dash::Array)) not matched"); + static_assert(dash::is_range::value == true, + "range type trait for index(local(dash::Array)) not matched"); + + // Index set iterators implement random access iterator concept: + // + static_assert(std::is_same< + typename std::iterator_traits< + decltype(i_sub.begin()) + >::iterator_category, + std::random_access_iterator_tag + >::value == true, + "iterator trait iterator_category of " + "index(local(dash::Array))::iterator not matched"); + static_assert(std::is_same< + typename std::iterator_traits< + decltype(i_loc.begin()) + >::iterator_category, + std::random_access_iterator_tag + >::value == true, + "iterator trait iterator_category of " + "index(local(dash::Array))::iterator not matched"); +//static_assert(std::is_same< +// typename std::iterator_traits< +// decltype(i_glo.begin()) +// >::iterator_category, +// std::random_access_iterator_tag +// >::value == true, +// "iterator trait iterator_category of " +// "global(index(local(dash::Array)))::iterator not matched"); + + static_assert( + dash::is_range::value == true, + "dash::is_range>::value not matched"); + + auto l_range = dash::make_range(array.local.begin(), + array.local.end()); + static_assert( + dash::is_range::value == true, + "dash::is_range::value not matched"); +} + diff --git a/dash/test/RangeTest.h b/dash/test/meta/RangeTest.h similarity index 93% rename from dash/test/RangeTest.h rename to dash/test/meta/RangeTest.h index 50035bd6a..789efa436 100644 --- a/dash/test/RangeTest.h +++ b/dash/test/meta/RangeTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__RANGE_TEST_H_ #define DASH__TEST__RANGE_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for the DASH Range concept diff --git a/dash/test/BlockPatternTest.cc b/dash/test/pattern/BlockPatternTest.cc similarity index 99% rename from dash/test/BlockPatternTest.cc rename to dash/test/pattern/BlockPatternTest.cc index eb65e68a7..3f4bc9305 100644 --- a/dash/test/BlockPatternTest.cc +++ b/dash/test/pattern/BlockPatternTest.cc @@ -1,6 +1,6 @@ #include "BlockPatternTest.h" -#include "TestBase.h" +#include "../TestBase.h" #include @@ -8,20 +8,9 @@ #include #include -#include +#include -namespace dash { - -template < - dash::dim_t NumDimensions, - dash::MemArrange Arrangement = dash::ROW_MAJOR, - typename IndexType = dash::default_index_t -> -using Pattern = dash::BlockPattern; - -} // namespace dash - TEST_F(BlockPatternTest, SimpleConstructor) { diff --git a/dash/test/BlockPatternTest.h b/dash/test/pattern/BlockPatternTest.h similarity index 69% rename from dash/test/BlockPatternTest.h rename to dash/test/pattern/BlockPatternTest.h index fcc05063e..2e6a7394b 100644 --- a/dash/test/BlockPatternTest.h +++ b/dash/test/pattern/BlockPatternTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__BLOCK_PATTERN_TEST_H_ #define DASH__TEST__BLOCK_PATTERN_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** @@ -14,13 +14,8 @@ class BlockPatternTest : public dash::test::TestBase { BlockPatternTest() : _dash_size(0), - _num_elem(23) { - LOG_MESSAGE(">>> Test suite: BlockPatternTest"); - } - - virtual ~BlockPatternTest() { - LOG_MESSAGE("<<< Closing test suite: BlockPatternTest"); - } + _num_elem(23) + { } virtual void SetUp() { dash::test::TestBase::SetUp(); diff --git a/dash/test/CSRPatternTest.cc b/dash/test/pattern/CSRPatternTest.cc similarity index 100% rename from dash/test/CSRPatternTest.cc rename to dash/test/pattern/CSRPatternTest.cc diff --git a/dash/test/CSRPatternTest.h b/dash/test/pattern/CSRPatternTest.h similarity index 90% rename from dash/test/CSRPatternTest.h rename to dash/test/pattern/CSRPatternTest.h index c3001014f..d65ba2e91 100644 --- a/dash/test/CSRPatternTest.h +++ b/dash/test/pattern/CSRPatternTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__CSR_Pattern_TEST_H_ #define DASH__TEST__CSR_Pattern_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for dash::CSRPattern diff --git a/dash/test/LoadBalancePatternTest.cc b/dash/test/pattern/LoadBalancePatternTest.cc similarity index 100% rename from dash/test/LoadBalancePatternTest.cc rename to dash/test/pattern/LoadBalancePatternTest.cc diff --git a/dash/test/LoadBalancePatternTest.h b/dash/test/pattern/LoadBalancePatternTest.h similarity index 95% rename from dash/test/LoadBalancePatternTest.h rename to dash/test/pattern/LoadBalancePatternTest.h index 78fc89e6d..48e4308b7 100644 --- a/dash/test/LoadBalancePatternTest.h +++ b/dash/test/pattern/LoadBalancePatternTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__LOAD_BALANCE_PATTERN_TEST_H_ #define DASH__TEST__LOAD_BALANCE_PATTERN_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** diff --git a/dash/test/MakePatternTest.cc b/dash/test/pattern/MakePatternTest.cc similarity index 100% rename from dash/test/MakePatternTest.cc rename to dash/test/pattern/MakePatternTest.cc diff --git a/dash/test/MakePatternTest.h b/dash/test/pattern/MakePatternTest.h similarity index 94% rename from dash/test/MakePatternTest.h rename to dash/test/pattern/MakePatternTest.h index 280748930..0fa66105a 100644 --- a/dash/test/MakePatternTest.h +++ b/dash/test/pattern/MakePatternTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__MAKE_PATTERN_TEST_H_ #define DASH__TEST__MAKE_PATTERN_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for function dash::make_pattern. diff --git a/dash/test/SeqTilePatternTest.cc b/dash/test/pattern/SeqTilePatternTest.cc similarity index 100% rename from dash/test/SeqTilePatternTest.cc rename to dash/test/pattern/SeqTilePatternTest.cc diff --git a/dash/test/SeqTilePatternTest.h b/dash/test/pattern/SeqTilePatternTest.h similarity index 94% rename from dash/test/SeqTilePatternTest.h rename to dash/test/pattern/SeqTilePatternTest.h index 52ca835d2..50446400d 100644 --- a/dash/test/SeqTilePatternTest.h +++ b/dash/test/pattern/SeqTilePatternTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__SEQ_TILE_PATTERN_TEST_H_ #define DASH__TEST__SEQ_TILE_PATTERN_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::Pattern diff --git a/dash/test/ShiftTilePatternTest.cc b/dash/test/pattern/ShiftTilePatternTest.cc similarity index 100% rename from dash/test/ShiftTilePatternTest.cc rename to dash/test/pattern/ShiftTilePatternTest.cc diff --git a/dash/test/ShiftTilePatternTest.h b/dash/test/pattern/ShiftTilePatternTest.h similarity index 94% rename from dash/test/ShiftTilePatternTest.h rename to dash/test/pattern/ShiftTilePatternTest.h index 7990b5c92..b53f8736d 100644 --- a/dash/test/ShiftTilePatternTest.h +++ b/dash/test/pattern/ShiftTilePatternTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__SHIFT_TILE_PATTERN_TEST_H_ #define DASH__TEST__SHIFT_TILE_PATTERN_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::ShiftTilePattern diff --git a/dash/test/TilePatternTest.cc b/dash/test/pattern/TilePatternTest.cc similarity index 100% rename from dash/test/TilePatternTest.cc rename to dash/test/pattern/TilePatternTest.cc diff --git a/dash/test/TilePatternTest.h b/dash/test/pattern/TilePatternTest.h similarity index 94% rename from dash/test/TilePatternTest.h rename to dash/test/pattern/TilePatternTest.h index 454854f47..3dfc72dc7 100644 --- a/dash/test/TilePatternTest.h +++ b/dash/test/pattern/TilePatternTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__TILE_PATTERN_TEST_H_ #define DASH__TEST__TILE_PATTERN_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::Pattern diff --git a/dash/test/AutobalanceTest.cc b/dash/test/team/AutobalanceTest.cc similarity index 99% rename from dash/test/AutobalanceTest.cc rename to dash/test/team/AutobalanceTest.cc index 0749af33f..6362dc04e 100644 --- a/dash/test/AutobalanceTest.cc +++ b/dash/test/team/AutobalanceTest.cc @@ -3,7 +3,7 @@ #include #include "AutobalanceTest.h" -#include "TestBase.h" +#include "../TestBase.h" #include #include diff --git a/dash/test/AutobalanceTest.h b/dash/test/team/AutobalanceTest.h similarity index 69% rename from dash/test/AutobalanceTest.h rename to dash/test/team/AutobalanceTest.h index b3b11b52a..099db7b64 100644 --- a/dash/test/AutobalanceTest.h +++ b/dash/test/team/AutobalanceTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__AUTOBALANCE_TEST_H_ #define DASH__TEST__AUTOBALANCE_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::Autobalance @@ -13,13 +13,8 @@ class AutobalanceTest : public dash::test::TestBase { AutobalanceTest() : _dash_id(0), - _dash_size(0) { - LOG_MESSAGE(">>> Test suite: AutobalanceTest"); - } - - virtual ~AutobalanceTest() { - LOG_MESSAGE("<<< Closing test suite: AutobalanceTest"); - } + _dash_size(0) + { } virtual void SetUp() { dash::test::TestBase::SetUp(); diff --git a/dash/test/TeamLocalityTest.cc b/dash/test/team/TeamLocalityTest.cc similarity index 100% rename from dash/test/TeamLocalityTest.cc rename to dash/test/team/TeamLocalityTest.cc diff --git a/dash/test/TeamLocalityTest.h b/dash/test/team/TeamLocalityTest.h similarity index 90% rename from dash/test/TeamLocalityTest.h rename to dash/test/team/TeamLocalityTest.h index 0af6f80f1..3c3a108ba 100644 --- a/dash/test/TeamLocalityTest.h +++ b/dash/test/team/TeamLocalityTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__TEAM_LOCALITY_TEST_H_ #define DASH__TEST__TEAM_LOCALITY_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::TeamLocality diff --git a/dash/test/TeamSpecTest.cc b/dash/test/team/TeamSpecTest.cc similarity index 100% rename from dash/test/TeamSpecTest.cc rename to dash/test/team/TeamSpecTest.cc diff --git a/dash/test/TeamSpecTest.h b/dash/test/team/TeamSpecTest.h similarity index 92% rename from dash/test/TeamSpecTest.h rename to dash/test/team/TeamSpecTest.h index 7f6eaa251..15d816c56 100644 --- a/dash/test/TeamSpecTest.h +++ b/dash/test/team/TeamSpecTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__TEAM_SPEC_TEST_H_ #define DASH__TEST__TEAM_SPEC_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::TeamSpec diff --git a/dash/test/TeamTest.cc b/dash/test/team/TeamTest.cc similarity index 100% rename from dash/test/TeamTest.cc rename to dash/test/team/TeamTest.cc diff --git a/dash/test/TeamTest.h b/dash/test/team/TeamTest.h similarity index 91% rename from dash/test/TeamTest.h rename to dash/test/team/TeamTest.h index f91ce0606..d6fe410d9 100644 --- a/dash/test/TeamTest.h +++ b/dash/test/team/TeamTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__TEAM_TEST_H_ #define DASH__TEST__TEAM_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** diff --git a/dash/test/UnitIdTest.cc b/dash/test/team/UnitIdTest.cc similarity index 100% rename from dash/test/UnitIdTest.cc rename to dash/test/team/UnitIdTest.cc diff --git a/dash/test/UnitIdTest.h b/dash/test/team/UnitIdTest.h similarity index 92% rename from dash/test/UnitIdTest.h rename to dash/test/team/UnitIdTest.h index 57595b786..1f124bb07 100644 --- a/dash/test/UnitIdTest.h +++ b/dash/test/team/UnitIdTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__UNIT_ID_TEST_H__INCLUDED #define DASH__TEST__UNIT_ID_TEST_H__INCLUDED -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class DASH unit id types. diff --git a/dash/test/AtomicTest.cc b/dash/test/types/AtomicTest.cc similarity index 99% rename from dash/test/AtomicTest.cc rename to dash/test/types/AtomicTest.cc index be36a56a0..5448d8381 100644 --- a/dash/test/AtomicTest.cc +++ b/dash/test/types/AtomicTest.cc @@ -10,7 +10,7 @@ #include #include -#include "TestBase.h" +#include "../TestBase.h" #include "AtomicTest.h" #include diff --git a/dash/test/AtomicTest.h b/dash/test/types/AtomicTest.h similarity index 68% rename from dash/test/AtomicTest.h rename to dash/test/types/AtomicTest.h index 718fd6391..981e54ccd 100644 --- a/dash/test/AtomicTest.h +++ b/dash/test/types/AtomicTest.h @@ -3,7 +3,7 @@ #include -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::Atomic @@ -15,22 +15,14 @@ class AtomicTest : public dash::test::TestBase { AtomicTest() : _dash_id(0), - _dash_size(0) { - } - - virtual ~AtomicTest() { - LOG_MESSAGE("<<< Closing test suite: AtomicTest"); - } + _dash_size(0) + { } virtual void SetUp() { dash::test::TestBase::SetUp(); _dash_id = dash::myid(); _dash_size = dash::size(); } - - virtual void TearDown() { - dash::test::TestBase::TearDown(); - } }; #endif // DASH__TEST__ATOMIC_TEST_H_ diff --git a/dash/test/CartesianTest.cc b/dash/test/types/CartesianTest.cc similarity index 100% rename from dash/test/CartesianTest.cc rename to dash/test/types/CartesianTest.cc diff --git a/dash/test/CartesianTest.h b/dash/test/types/CartesianTest.h similarity index 70% rename from dash/test/CartesianTest.h rename to dash/test/types/CartesianTest.h index 6eadba9b0..20f6512e4 100644 --- a/dash/test/CartesianTest.h +++ b/dash/test/types/CartesianTest.h @@ -1,21 +1,13 @@ #ifndef DASH__TEST__CARTESIAN_TEST_H_ #define DASH__TEST__CARTESIAN_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::Cartesian */ class CartesianTest : public dash::test::TestBase { -protected: - - CartesianTest() { - } - - virtual ~CartesianTest() { - } - }; #endif // DASH__TEST__CARTESIAN_TEST_H_ diff --git a/dash/test/DomainTest.cc b/dash/test/types/DomainTest.cc similarity index 91% rename from dash/test/DomainTest.cc rename to dash/test/types/DomainTest.cc index fd6e71b05..32088f9ba 100644 --- a/dash/test/DomainTest.cc +++ b/dash/test/types/DomainTest.cc @@ -8,7 +8,7 @@ TEST_F(DomainTest, Basic3Dim) { - if (_dash_id != 0) { return; } + if (dash::myid() != 0) { return; } dash::Domain<3, int> dom({ {0,10}, {10,20}, {5,10} }); diff --git a/dash/test/types/DomainTest.h b/dash/test/types/DomainTest.h new file mode 100644 index 000000000..7ea1d8205 --- /dev/null +++ b/dash/test/types/DomainTest.h @@ -0,0 +1,12 @@ +#ifndef DASH__TEST__DOMAIN_TEST_H_ +#define DASH__TEST__DOMAIN_TEST_H_ + +#include "../TestBase.h" + +/** + * Test fixture for class dash::Domain + */ +class DomainTest : public dash::test::TestBase { +}; + +#endif // DASH__TEST__DOMAIN_TEST_H_ diff --git a/dash/test/ConfigTest.cc b/dash/test/util/ConfigTest.cc similarity index 100% rename from dash/test/ConfigTest.cc rename to dash/test/util/ConfigTest.cc diff --git a/dash/test/ConfigTest.h b/dash/test/util/ConfigTest.h similarity index 70% rename from dash/test/ConfigTest.h rename to dash/test/util/ConfigTest.h index db9a6ab46..690643b2e 100644 --- a/dash/test/ConfigTest.h +++ b/dash/test/util/ConfigTest.h @@ -1,19 +1,12 @@ #ifndef DASH__TEST__CONFIG_TEST_H_ #define DASH__TEST__CONFIG_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for class dash::Config */ class ConfigTest : public dash::test::TestBase { -protected: - - ConfigTest() { - } - - virtual ~ConfigTest() { - } }; #endif // DASH__TEST__CONFIG_TEST_H_ diff --git a/dash/test/view/NViewTest.cc b/dash/test/view/NViewTest.cc new file mode 100644 index 000000000..9e537facb --- /dev/null +++ b/dash/test/view/NViewTest.cc @@ -0,0 +1,917 @@ + +#include "NViewTest.h" + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + + +namespace dash { +namespace test { + + template + void initialize_matrix(MatrixT & matrix) { + if (dash::myid() == 0) { + for(size_t i = 0; i < matrix.extent(0); ++i) { + for(size_t k = 0; k < matrix.extent(1); ++k) { + matrix[i][k] = (i + 1) * 0.100 + (k + 1) * 0.001; + } + } + } + matrix.barrier(); + + for(size_t i = 0; i < matrix.local_size(); ++i) { + matrix.lbegin()[i] += dash::myid(); + } + matrix.barrier(); + } + + template + void print_nview( + const std::string & name, + const NViewType & nview) { + using value_t = typename NViewType::value_type; + auto view_nrows = nview.extents()[0]; + auto view_ncols = nview.extents()[1]; + auto nindex = dash::index(nview); + for (int r = 0; r < view_nrows; ++r) { + std::ostringstream row_ss; + for (int c = 0; c < view_ncols; ++c) { + int offset = r * view_ncols + c; + row_ss << std::fixed << std::setw(2) + << nindex[offset] + << ":" + << std::fixed << std::setprecision(3) + << static_cast(nview[offset]) + << " "; + } + DASH_LOG_DEBUG("NViewTest.print_nview", + name, "[", r, "]", row_ss.str()); + } + } + + template + std::vector + region_values(const NViewType & view, const dash::ViewSpec<2> & vs) { + auto nvalues = vs.size(); + using value_t = typename NViewType::value_type; + std::vector values; + values.reserve(nvalues); + dash::CartesianIndexSpace<2> cart(view.extents()); + for (int i = 0; i < nvalues; i++) { + auto coords = cart.coords(i, vs); + auto index = cart.at(coords); + values.push_back(static_cast(view.begin()[index])); + } + return values; + } +} +} + +using dash::test::range_str; + +TEST_F(NViewTest, ViewTraits) +{ + { + dash::Matrix matrix( + dash::SizeSpec<2>( + dash::size() * 10, + dash::size() * 10), + dash::DistributionSpec<2>( + dash::NONE, + dash::TILE(10)), + dash::Team::All(), + dash::TeamSpec<2>( + 1, + dash::size())); + + auto v_sub = dash::sub<0>(0, 10, matrix); + auto i_sub = dash::index(v_sub); + auto v_ssub = dash::sub<0>(0, 5, (dash::sub<1>(0, 10, matrix))); + auto v_loc = dash::local(matrix); + auto v_lsub = dash::local(dash::sub<1>(0, 10, matrix)); + auto v_sblk = dash::blocks(dash::sub<0>(0, 10, matrix)); + + static_assert( + dash::view_traits::rank::value == 2, + "view traits rank for dash::Matrix not matched"); + static_assert( + dash::view_traits::rank::value == 2, + "view traits rank for blocks(sub(dash::Matrix)) not matched"); + + static_assert( + dash::view_traits::is_view::value == true, + "view traits is_view for sub(dash::Matrix) not matched"); + static_assert( + dash::view_traits::is_view::value == true, + "view traits is_view for sub(sub(dash::Matrix)) not matched"); + static_assert( + dash::view_traits::is_view::value == true, + "view traits is_view for local(sub(dash::Matrix)) not matched"); + + static_assert( + dash::view_traits::is_origin::value == true, + "view traits is_origin for local(dash::Matrix) not matched"); + static_assert( + dash::view_traits::is_origin::value == false, + "view traits is_origin for sub(dash::Matrix) not matched"); + static_assert( + dash::view_traits::is_origin::value == false, + "view traits is_origin for sub(sub(dash::Matrix)) not matched"); + static_assert( + dash::view_traits::is_origin::value == false, + "view traits is_origin for local(sub(dash::Matrix)) not matched"); + + static_assert( + dash::view_traits::is_local::value == true, + "view traits is_local for local(dash::Matrix) not matched"); + static_assert( + dash::view_traits::is_local::value == true, + "view traits is_local for local(sub(dash::Matrix)) not matched"); + } + { + dash::NArray narray( + dash::SizeSpec<2>( + dash::size() * 10, + dash::size() * 10), + dash::DistributionSpec<2>( + dash::NONE, + dash::BLOCKCYCLIC(10)), + dash::Team::All(), + dash::TeamSpec<2>( + 1, + dash::size())); + + auto v_sub = dash::sub<0>(0, 10, narray); + auto i_sub = dash::index(v_sub); + auto v_ssub = dash::sub<0>(0, 5, (dash::sub<1>(0, 10, narray))); + auto v_loc = dash::local(narray); + auto v_lsub = dash::local(dash::sub<1>(0, 10, narray)); + auto v_sblk = dash::blocks(dash::sub<0>(0, 10, narray)); + + static_assert( + dash::view_traits::rank::value == 2, + "view traits rank for dash::NArray not matched"); + static_assert( + dash::view_traits::rank::value == 2, + "view traits rank for blocks(sub(dash::NArray)) not matched"); + + static_assert( + dash::view_traits::is_view::value == true, + "view traits is_view for sub(dash::NArray) not matched"); + static_assert( + dash::view_traits::is_view::value == true, + "view traits is_view for sub(sub(dash::NArray)) not matched"); + static_assert( + dash::view_traits::is_view::value == true, + "view traits is_view for local(sub(dash::NArray)) not matched"); + + static_assert( + dash::view_traits::is_origin::value == true, + "view traits is_origin for local(dash::NArray) not matched"); + static_assert( + dash::view_traits::is_origin::value == false, + "view traits is_origin for sub(dash::NArray) not matched"); + static_assert( + dash::view_traits::is_origin::value == false, + "view traits is_origin for sub(sub(dash::NArray)) not matched"); + static_assert( + dash::view_traits::is_origin::value == false, + "view traits is_origin for local(sub(dash::NArray)) not matched"); + + static_assert( + dash::view_traits::is_local::value == true, + "view traits is_local for local(dash::NArray) not matched"); + static_assert( + dash::view_traits::is_local::value == true, + "view traits is_local for local(sub(dash::NArray)) not matched"); + } +} + +TEST_F(NViewTest, MatrixBlocked1DimSingle) +{ + auto nunits = dash::size(); + + int block_rows = 3; + int block_cols = 4; + + if (nunits < 2) { block_cols = 8; } + + int nrows = 2 * block_rows; + int ncols = nunits * block_cols; + + // columns distributed in blocks of same size: + // + // 0 0 0 | 1 1 1 | 2 2 2 | ... + // 0 0 0 | 1 1 1 | 2 2 2 | ... + // 0 0 0 | 1 1 1 | 2 2 2 | ... + // + dash::Matrix mat( + dash::SizeSpec<2>( + nrows, + ncols), + dash::DistributionSpec<2>( + dash::NONE, + dash::TILE(block_cols)), + dash::Team::All(), + dash::TeamSpec<2>( + 1, + nunits)); + + dash::test::initialize_matrix(mat); + + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "Matrix initialized"); + + if (dash::myid() == 0) { + dash::test::print_nview("matrix", dash::sub<0>(0, mat.extent(0), mat)); + } + mat.barrier(); + + // select first 2 matrix rows: + auto nview_total = dash::sub<0>(0, mat.extent(0), mat); + auto nview_local = dash::local(nview_total); + auto nview_rows_g = dash::sub<0>(1, 3, mat); + auto nview_cols_g = dash::sub<1>(2, 7, mat); + + if (dash::myid() == 0) { + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "mat ->", + "offsets:", mat.offsets(), + "extents:", mat.extents(), + "size:", mat.size()); + + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "sub<0>(1,3, mat) ->", + "offsets:", nview_rows_g.offsets(), + "extents:", nview_rows_g.extents(), + "size:", nview_rows_g.size()); + dash::test::print_nview("nview_rows_g", nview_rows_g); + + auto exp_nview_rows_g = dash::test::region_values( + mat, {{ 1,0 }, { 2,mat.extent(1) }} ); + + EXPECT_TRUE_U( + dash::test::expect_range_values_equal( + exp_nview_rows_g, nview_rows_g)); + + EXPECT_EQ_U(2, nview_rows_g.extent<0>()); + EXPECT_EQ_U(mat.extent(1), nview_rows_g.extent<1>()); + + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "sub<1>(2,7, mat) ->", + "offsets:", nview_cols_g.offsets(), + "extents:", nview_cols_g.extents(), + "size:", nview_cols_g.size(), + "strided:", dash::index(nview_cols_g).is_strided()); + dash::test::print_nview("nview_cols_g", nview_cols_g); + + auto exp_nview_cols_g = dash::test::region_values( + mat, {{ 0,2 }, { mat.extent(0),5 }} ); + EXPECT_TRUE_U( + dash::test::expect_range_values_equal( + exp_nview_cols_g, nview_cols_g)); + + EXPECT_EQ_U(mat.extent(0), nview_cols_g.extent<0>()); + EXPECT_EQ_U(5, nview_cols_g.extent<1>()); + } + + mat.barrier(); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSingle", + mat.local_size()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSingle", + mat.pattern().local_size()); + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "local(mat) ->", + dash::typestr(nview_local)); + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "local(mat) ->", + "it:", dash::typestr(nview_local.begin())); + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "local(mat) ->", + "offsets:", nview_local.offsets(), + "extents:", nview_local.extents(), + "size:", nview_local.size()); + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "index(local(mat)) ->", + "strided:", dash::index(nview_local).is_strided(), + "pat.lbeg:", dash::index(nview_local).pattern().lbegin(), + "pat.lend:", dash::index(nview_local).pattern().lend(), + "distance:", dash::distance(nview_local.begin(), + nview_local.end())); + dash::test::print_nview("nview_local", nview_local); + + mat.barrier(); + + auto nview_cols_l = dash::sub<1>(2,4, dash::local(dash::sub<0>(0,6, mat))); + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "cols(local(mat)) ->", + dash::typestr(nview_cols_l)); + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "cols(local(mat)) ->", + "it:", dash::typestr(nview_cols_l.begin())); + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "cols(local(mat)) ->", + "offsets:", nview_cols_l.offsets(), + "extents:", nview_cols_l.extents(), + "size:", nview_cols_l.size()); + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "index(cols(local(mat))) ->", + "strided:", dash::index(nview_cols_l).is_strided(), + "pat.lbeg:", dash::index(nview_cols_l).pattern().lbegin(), + "pat.lend:", dash::index(nview_cols_l).pattern().lend(), + "distance:", dash::distance(nview_cols_l.begin(), + nview_cols_l.end())); + dash::test::print_nview("cols_local_v", nview_cols_l); + + mat.barrier(); + + auto nview_rows_l = dash::sub<0>(2,4, dash::local(dash::sub<0>(0,6, mat))); + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "rows(local(mat)) ->", + dash::typestr(nview_rows_l)); + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "rows(local(mat)) ->", + "it:", dash::typestr(nview_rows_l.begin())); + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "rows(local(mat)) ->", + "offsets:", nview_rows_l.offsets(), + "extents:", nview_rows_l.extents(), + "size:", nview_rows_l.size()); + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "index(rows(local(mat))) ->", + "strided:", dash::index(nview_rows_l).is_strided(), + "pat.lbeg:", dash::index(nview_rows_l).pattern().lbegin(), + "pat.lend:", dash::index(nview_rows_l).pattern().lend(), + "distance:", dash::distance(nview_rows_l.begin(), + nview_rows_l.end())); + dash::test::print_nview("rows_local_v", nview_rows_l); + + return; + + EXPECT_EQ_U(mat.local_size(), dash::distance(nview_local.begin(), + nview_local.end())); + EXPECT_EQ_U(mat.local_size(), nview_local.size()); + EXPECT_EQ_U(mat.local_size(), dash::index(nview_local).size()); + + EXPECT_EQ_U(mat.extent(0), nview_local.extent<0>()); + EXPECT_EQ_U(block_cols, nview_local.extent<1>()); +} + +TEST_F(NViewTest, MatrixBlocked1DimBlocks) +{ + auto nunits = dash::size(); + + int block_rows = 3; + int block_cols = 2; + + if (nunits < 2) { block_cols = 8; } + + int nrows = nunits * block_rows; + int ncols = nunits * block_cols; + + // columns distributed in blocks of same size: + // + // 0 0 0 | 1 1 1 | 2 2 2 | ... + // 0 0 0 | 1 1 1 | 2 2 2 | ... + // 0 0 0 | 1 1 1 | 2 2 2 | ... + // + dash::Matrix mat_cb( + dash::SizeSpec<2>( + nrows, + ncols), + dash::DistributionSpec<2>( + dash::NONE, + dash::TILE(block_cols)), + dash::Team::All(), + dash::TeamSpec<2>( + 1, + nunits)); + + dash::test::initialize_matrix(mat_cb); + + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "Matrix mat_cb initialized"); + + if (dash::myid() == 0) { + auto && v_mat_cb = dash::sub<0>(0, mat_cb.extent(0), mat_cb); + auto && cb_blocks = dash::blocks(v_mat_cb); + EXPECT_EQ_U(nunits, cb_blocks.size()); + + int bi = 0; + for (auto block : cb_blocks) { + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "column block", bi, ":", range_str(block)); + bi++; + } + } + + // rows distributed in blocks of same size: + // + // 0 0 0 0 0 0 0 ... + // 0 0 0 0 0 0 0 ... + // ----------------- + // 1 1 1 1 1 1 1 ... + // 1 1 1 1 1 1 1 ... + // + dash::Matrix mat_rb( + dash::SizeSpec<2>( + nrows, + ncols), + dash::DistributionSpec<2>( + dash::TILE(block_rows), + dash::NONE), + dash::Team::All(), + dash::TeamSpec<2>( + 1, + nunits)); + + dash::test::initialize_matrix(mat_rb); + + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "Matrix mat_rb initialized"); + + if (dash::myid() == 0) { + auto v_mat_rb = dash::sub<0>(0, mat_rb.extent(0), mat_rb); + auto rb_blocks = dash::blocks(v_mat_rb); + EXPECT_EQ_U(nunits, rb_blocks.size()); + + int bi = 0; + for (auto block : rb_blocks) { + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSingle", + "row block", bi, ":", range_str(block)); + bi++; + } + } +} + +TEST_F(NViewTest, MatrixBlocked1DimChained) +{ + auto nunits = dash::size(); + + int block_rows = 3; + int block_cols = 4; + + if (nunits < 2) { block_cols = 8; } + + int nrows = 2 * block_rows; + int ncols = nunits * block_cols; + + // columns distributed in blocks of same size: + // + // 0 0 0 | 1 1 1 | 2 2 2 | ... + // 0 0 0 | 1 1 1 | 2 2 2 | ... + // 0 0 0 | 1 1 1 | 2 2 2 | ... + // + dash::Matrix mat( + dash::SizeSpec<2>( + nrows, + ncols), + dash::DistributionSpec<2>( + dash::NONE, + dash::TILE(block_cols)), + dash::Team::All(), + dash::TeamSpec<2>( + 1, + nunits)); + + dash::test::initialize_matrix(mat); + + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimChained", + "Matrix initialized"); + + // select first 2 matrix rows: + auto nview_total = dash::sub<0>(0, mat.extent(0), mat); + auto nview_local = dash::local(nview_total); + + if (dash::myid() == 0) { + dash::test::print_nview("matrix.view", nview_total); + } + mat.barrier(); + + dash::test::print_nview("nview_local", nview_local); + mat.barrier(); + + auto nview_rows_g = dash::sub<0>(1, 3, mat); + auto nview_cols_g = dash::sub<1>(2, 7, mat); + + auto nview_cr_s_g = dash::sub<1>(2, 7, dash::sub<0>(1, 3, mat)); + auto nview_rc_s_g = dash::sub<0>(1, 3, dash::sub<1>(2, 7, mat)); + + EXPECT_EQ_U(2, nview_rows_g.extent<0>()); + EXPECT_EQ_U(mat.extent(1), nview_rows_g.extent<1>()); + + EXPECT_EQ_U(nview_rc_s_g.extents(), nview_cr_s_g.extents()); + EXPECT_EQ_U(nview_rc_s_g.offsets(), nview_cr_s_g.offsets()); + + if (dash::myid() == 0) { + dash::test::print_nview("nview_rows_g", nview_rows_g); + dash::test::print_nview("nview_cols_g", nview_cols_g); + + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimChained", + "sub<1>(2,7, sub<0>(1,3, mat) ->", + "offsets:", nview_cr_s_g.offsets(), + "extents:", nview_cr_s_g.extents(), + "size:", nview_cr_s_g.size()); + dash::test::print_nview("nview_cr_s_g", nview_cr_s_g); + + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimChained", + "sub<0>(1,3, sub<1>(2,7, mat) ->", + "offsets:", nview_rc_s_g.offsets(), + "extents:", nview_rc_s_g.extents(), + "size:", nview_rc_s_g.size()); + dash::test::print_nview("nview_rc_s_g", nview_rc_s_g); + + auto exp_nview_cr_s_g = dash::test::region_values( + mat, {{ 1,2 }, { 2,5 }} ); + EXPECT_TRUE_U( + dash::test::expect_range_values_equal( + exp_nview_cr_s_g, nview_cr_s_g)); + + auto exp_nview_rc_s_g = dash::test::region_values( + mat, {{ 1,2 }, { 2,5 }} ); + EXPECT_TRUE_U( + dash::test::expect_range_values_equal( + exp_nview_rc_s_g, nview_rc_s_g)); + } + mat.barrier(); + + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimChained", "== nview_rows_l"); + auto nview_rows_l = dash::local(nview_rows_g); + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimChained", + "extents:", nview_rows_l.extents(), + "offsets:", nview_rows_l.offsets()); + +// EXPECT_EQ_U(2, nview_rows_l.extent<0>()); +// EXPECT_EQ_U(block_cols, nview_rows_l.extent<1>()); +// +// dash::test::print_nview("nview_rows_l", nview_rows_l); + + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimChained", "== nview_cols_l"); + auto nview_cols_l = dash::local(nview_cols_g); + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimChained", + "extents:", nview_cols_l.extents(), + "offsets:", nview_cols_l.offsets()); + +// dash::test::print_nview("nview_cols_l", nview_cols_l); +} + +TEST_F(NViewTest, MatrixBlocked1DimSub) +{ + auto nunits = dash::size(); + + int block_rows = 4; + int block_cols = 3; + + int nrows = nunits * block_rows; + int ncols = nunits * block_cols; + + // columns distributed in blocks of same size: + // + // 0 0 0 | 1 1 1 | 2 2 2 | ... + // 0 0 0 | 1 1 1 | 2 2 2 | ... + // 0 0 0 | 1 1 1 | 2 2 2 | ... + // + dash::Matrix mat( + dash::SizeSpec<2>( + nrows, + ncols), + dash::DistributionSpec<2>( + dash::NONE, + dash::TILE(block_cols)), + dash::Team::All(), + dash::TeamSpec<2>( + 1, + nunits)); + + dash::test::initialize_matrix(mat); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", mat.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", + mat.pattern().local_extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", + mat.pattern().local_size()); + + if (dash::myid() == 0) { + auto all_sub = dash::sub<0>( + 0, mat.extents()[0], + mat); + + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSub", + dash::typestr(all_sub)); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", all_sub.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", all_sub.extent(0)); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", all_sub.extent(1)); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", all_sub.size(0)); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", all_sub.size(1)); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", + index(all_sub).size()); + + dash::test::print_nview("mat_view", all_sub); + } + + mat.barrier(); + + // -- Sub-Section ---------------------------------- + // + + if (dash::myid() == 0) { + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", mat.extents()); + + auto tmp = dash::sub<1>(1, mat.extent(1) - 1, + mat); + auto nview_sub = dash::sub<0>(1, mat.extent(0) - 1, + tmp); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", nview_sub.offsets()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", nview_sub.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", nview_sub.extent(0)); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", nview_sub.extent(1)); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", nview_sub.size(0)); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", nview_sub.size(1)); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", + index(nview_sub).size()); + + dash::test::print_nview("nview_sub", nview_sub); + + auto nview_rows = nview_sub.extent<0>(); + auto nview_cols = nview_sub.extent<1>(); + + EXPECT_EQ_U(nview_rows, nview_sub.extent(0)); + EXPECT_EQ_U(nview_rows, mat.extent(0) - 2); + EXPECT_EQ_U(nview_cols, nview_sub.extent(1)); + EXPECT_EQ_U(nview_cols, mat.extent(1) - 2); + + auto exp_nview_sub = dash::test::region_values( + mat, + { { 1,1 }, + { mat.extent(0) - 2, mat.extent(1) - 2 } }); + EXPECT_TRUE_U( + dash::test::expect_range_values_equal( + exp_nview_sub, nview_sub)); + } + + // -- Local View ----------------------------------- + // + + auto lsub_view = dash::local( + dash::sub<0>( + 0, mat.extents()[0], + mat)); + + EXPECT_EQ_U(2, decltype(lsub_view)::rank::value); + EXPECT_EQ_U(2, lsub_view.ndim()); + + int lrows = lsub_view.extent<0>(); + int lcols = lsub_view.extent<1>(); + + DASH_LOG_DEBUG("NViewTest.MatrixBlocked1DimSub", + dash::typestr(lsub_view)); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", lsub_view.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", lsub_view.extent(0)); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", lsub_view.extent(1)); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", lsub_view.size(0)); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", lsub_view.size(1)); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", lsub_view.size()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", + index(lsub_view).size()); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", + lsub_view.begin().pos()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", + lsub_view.end().pos()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlocked1DimSub", + (lsub_view.end() - lsub_view.begin())); + + EXPECT_EQ_U(mat.local_size(), lrows * lcols); + + dash::test::print_nview("lsub_view", lsub_view); +} + +TEST_F(NViewTest, MatrixBlockCyclic1DimSub) +{ + auto nunits = dash::size(); + + int block_rows = 4; + int block_cols = 2; + + int nrows = block_rows; + int ncols = nunits * block_cols * 2; + + // columns distributed in blocks of same size: + // + // 0 0 | 1 1 | 2 2 | 0 0 .... + // 0 0 | 1 1 | 2 2 | 0 0 .... + // 0 0 | 1 1 | 2 2 | 0 0 .... + // + dash::Matrix mat( + dash::SizeSpec<2>( + nrows, + ncols), + dash::DistributionSpec<2>( + dash::NONE, + dash::TILE(block_cols)), + dash::Team::All(), + dash::TeamSpec<2>( + 1, + nunits)); + + dash::test::initialize_matrix(mat); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", mat.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", + mat.pattern().local_extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", + mat.pattern().local_size()); + + if (dash::myid() == 0) { + auto all_sub = dash::sub<0>( + 0, mat.extents()[0], + mat); + + DASH_LOG_DEBUG("NViewTest.MatrixBlockCyclic1DSub", + dash::typestr(all_sub)); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", all_sub.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", all_sub.offsets()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", + index(all_sub).size()); + + dash::test::print_nview("mat_view", all_sub); + + auto nview_rows = dash::sub<0>(1, mat.extent(0) - 1, mat); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", + nview_rows.offsets()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", + nview_rows.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", + index(nview_rows).size()); + + dash::test::print_nview("nview_rows", nview_rows); + + auto nview_cols = dash::sub<1>(1, mat.extent(1) - 1, mat); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", + nview_cols.offsets()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", + nview_cols.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", + index(nview_cols).size()); + + dash::test::print_nview("nview_cols", nview_cols); + + auto nview_blocks = dash::blocks(mat); + + int bi = 0; + for (const auto & block : nview_blocks) { + DASH_LOG_DEBUG("NViewTest.MatrixBlockCyclic1DSingle", + "block", bi, ":", "extents:", block.extents(), + range_str(block)); + bi++; + } + } + mat.barrier(); + + auto mat_loc = dash::local(dash::sub<0>(0, mat.extent(0), mat)); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", mat_loc.offsets()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", mat_loc.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", + index(mat_loc).size()); + + dash::test::print_nview("mat_loc", mat_loc); + + mat.barrier(); + + auto loc_rows = dash::local(dash::sub<0>(1, mat.extent(0) - 1, mat)); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", loc_rows.offsets()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", loc_rows.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", + index(loc_rows).size()); + + //dash::test::print_nview("loc_rows", loc_rows); + + mat.barrier(); + + auto loc_cols = local(dash::sub<1>(1, mat.extent(1) - 1, mat)); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", loc_cols.offsets()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", loc_cols.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic1DSub", + index(loc_cols).size()); + + //dash::test::print_nview("loc_cols", loc_cols); +} + +TEST_F(NViewTest, MatrixBlockCyclic2DimSub) +{ + auto nunits = dash::size(); + + int block_rows = 2; + int block_cols = 2; + + int nrows = nunits * block_rows; + int ncols = nunits * block_cols * 2; + + if (nunits % 2 == 0 && nunits > 2) { + nrows /= 2; + } + + auto team_spec = dash::TeamSpec<2>( + nunits, + 1); + team_spec.balance_extents(); + + auto pattern = dash::TilePattern<2>( + dash::SizeSpec<2>( + nrows, + ncols), + dash::DistributionSpec<2>( + dash::TILE(block_rows), + dash::TILE(block_cols)), + team_spec); + + using pattern_t = decltype(pattern); + using index_t = typename pattern_t::index_type; + + // columns distributed in blocks of same size: + // + // 0 0 | 1 1 | 2 2 | 0 0 ... + // 0 0 | 1 1 | 2 2 | 0 0 ... + // ----+-----+-----+---- + // 1 1 | 2 2 | 0 0 | 1 1 ... + // 1 1 | 2 2 | 0 0 | 1 1 ... + // ... ... ... ... + // + dash::Matrix mat(pattern); + + dash::test::initialize_matrix(mat); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic2DSub", mat.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic2DSub", team_spec.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic2DSub", + mat.pattern().local_extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic2DSub", + mat.pattern().local_size()); + + if (dash::myid() == 0) { + auto all_sub = dash::sub<0>( + 0, mat.extents()[0], + mat); + + DASH_LOG_DEBUG("NViewTest.MatrixBlockCyclic2DSub", + dash::typestr(all_sub)); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic2DSub", all_sub.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic2DSub", all_sub.offsets()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic2DSub", + index(all_sub).size()); + + dash::test::print_nview("mat_view", all_sub); + + auto nview_rows = dash::sub<0>(1, mat.extent(0) - 1, mat); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic2DSub", + nview_rows.offsets()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic2DSub", + nview_rows.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic2DSub", + index(nview_rows).size()); + + dash::test::print_nview("nview_rows", nview_rows); + + auto nview_cols = dash::sub<1>(1, mat.extent(1) - 1, mat); + + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic2DSub", + nview_cols.offsets()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic2DSub", + nview_cols.extents()); + DASH_LOG_DEBUG_VAR("NViewTest.MatrixBlockCyclic2DSub", + index(nview_cols).size()); + + dash::test::print_nview("nview_cols", nview_cols); + + auto nview_blocks = dash::blocks(mat); + + int bi = 0; + for (const auto & block : nview_blocks) { + DASH_LOG_DEBUG("NViewTest.MatrixBlockCyclic2DSingle", + "block", bi, ":", "extents:", block.extents(), + range_str(block)); + bi++; + } + } + mat.barrier(); +} diff --git a/dash/test/NViewTest.h b/dash/test/view/NViewTest.h similarity index 93% rename from dash/test/NViewTest.h rename to dash/test/view/NViewTest.h index 964fcfae0..0ed505b1e 100644 --- a/dash/test/NViewTest.h +++ b/dash/test/view/NViewTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__NVIEW_TEST_H_ #define DASH__TEST__NVIEW_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for the DASH View concept diff --git a/dash/test/view/ViewTest.cc b/dash/test/view/ViewTest.cc new file mode 100644 index 000000000..2af628856 --- /dev/null +++ b/dash/test/view/ViewTest.cc @@ -0,0 +1,1885 @@ + +#include "ViewTest.h" + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + + +namespace dash { +namespace test { + + class seq_pos_t { + public: + int unit; + int lindex; + int lblock; + int gindex; + int marker; + + constexpr bool operator==(const seq_pos_t & rhs) const { + return &rhs == this || + ( unit == rhs.unit && + lindex == rhs.lindex && + lblock == rhs.lblock && + gindex == rhs.gindex && + marker == rhs.marker ); + } + }; + + std::ostream & operator<<(std::ostream & os, const seq_pos_t & sp) { + std::ostringstream ss; + if (sp.marker != 0) { + ss << "<" << sp.marker << "> "; + } + ss << "u" << sp.unit + << "b" << sp.lblock + << "l" << sp.lindex; + return operator<<(os, ss.str()); + } + + template + auto initialize_array(ArrayT & array) + -> typename std::enable_if< + std::is_floating_point::value, + void >::type + { + auto block_size = array.pattern().blocksize(0); + for (auto li = 0; li != array.local.size(); ++li) { + auto block_lidx = li / block_size; + auto block_gidx = (block_lidx * dash::size()) + dash::myid().id; + auto gi = (block_gidx * block_size) + (li % block_size); + array.local[li] = // unit + (1.0000 * dash::myid().id) + + // local offset + (0.0001 * (li+1)) + + // global offset + (0.0100 * gi); + } + array.barrier(); + } + + template + auto initialize_array(ArrayT & array) + -> typename std::enable_if< + std::is_same::value, + void >::type + { + auto block_size = array.pattern().blocksize(0); + for (auto li = 0; li != array.local.size(); ++li) { + auto block_lidx = li / block_size; + auto block_gidx = (block_lidx * dash::size()) + dash::myid().id; + auto gi = (block_gidx * block_size) + (li % block_size); + seq_pos_t val { + static_cast(dash::myid().id), // unit + static_cast(li), // local offset + static_cast(block_lidx), // local block index + static_cast(gi), // global offset + 0 // marker + }; + array.local[li] = val; + } + array.barrier(); + DASH_LOG_TRACE("ViewTest.initialize_array", "Array initialized"); + } + +} +} + +using dash::test::range_str; +using dash::test::seq_pos_t; + + +TEST_F(ViewTest, ViewTraits) +{ + dash::Array array(dash::size() * 10); + auto v_sub = dash::sub(0, 10, array); + auto i_sub = dash::index(v_sub); + auto v_ssub = dash::sub(0, 5, (dash::sub(0, 10, array))); + auto v_loc = dash::local(array); + auto v_lsub = dash::local(dash::sub(0, 10, array)); + auto v_bsub = *dash::begin(dash::blocks(v_sub)); + + static_assert( + dash::view_traits::is_local::value == false, + "view traits is_local for dash::Array not matched"); + static_assert( + dash::view_traits::is_view::value == false, + "view traits is_view for dash::Array not matched"); + static_assert( + dash::view_traits::is_view::value == true, + "view traits is_view for sub(sub(dash::Array)) not matched"); + static_assert( + dash::view_traits::is_view::value == true, + "view traits is_view for local(sub(dash::Array)) not matched"); + + // Local container proxy types are not considered views as they do + // not specify an index set: + static_assert( + dash::view_traits::is_view::value == false, + "view traits is_view for local(dash::Array) not matched"); + static_assert( + dash::view_traits::is_view::value == false, + "view traits is_view for index(sub(dash::Array)) not matched"); + static_assert( + dash::view_traits::is_view::value == true, + "view traits is_view for begin(blocks(dash::Array)) not matched"); + + static_assert( + dash::view_traits::is_origin::value == true, + "view traits is_origin for dash::Array not matched"); + static_assert( + dash::view_traits::is_origin::value == false, + "view traits is_origin for sub(dash::Array) not matched"); + static_assert( + dash::view_traits::is_origin::value == true, + "view traits is_origin for index(sub(dash::Array)) not matched"); + static_assert( + dash::view_traits::is_origin::value == false, + "view traits is_origin for begin(blocks(sub(dash::Array))) " + "not matched"); + static_assert( + dash::view_traits::is_origin::value == false, + "view traits is_origin for sub(sub(dash::Array)) not matched"); + static_assert( + dash::view_traits::is_origin::value == true, + "view traits is_origin for local(dash::Array) not matched"); + static_assert( + dash::view_traits::is_origin::value == false, + "view traits is_local for local(sub(dash::Array)) not matched"); + + static_assert( + dash::view_traits::is_local::value == true, + "view traits is_local for local(dash::Array) not matched"); + static_assert( + dash::view_traits::is_local::value == true, + "view traits is_local for local(sub(dash::Array)) not matched"); + + static_assert( + dash::view_traits::rank::value == 1, + "rank of array different from 1"); + static_assert( + dash::view_traits::rank::value == 1, + "rank of sub(array) different from 1"); + static_assert( + dash::view_traits::rank::value == 1, + "rank of sub(sub(array)) different from 1"); + static_assert( + dash::view_traits::rank::value == 1, + "rank of local(array) different from 1"); +} + +TEST_F(ViewTest, NestedTemporaries) +{ + typedef float value_t; + + int block_size = 15; + int array_size = dash::size() * block_size; + + dash::Array a(array_size); + dash::test::initialize_array(a); + + if (dash::myid() != 0) { + return; + } + + DASH_LOG_DEBUG_VAR("ViewTest.NestedTemporaries", + range_str(a)); + + auto gview_sub = dash::sub(1, array_size - 2, a); + DASH_LOG_DEBUG_VAR("ViewTest.NestedTemporaries", range_str(gview_sub)); + + auto gview_ssub = dash::sub(1, array_size - 3, + dash::sub(1, array_size - 2, a)); + DASH_LOG_DEBUG_VAR("ViewTest.NestedTemporaries", range_str(gview_ssub)); + + auto gview_lref = dash::sub(1, array_size - 5, + gview_ssub); + DASH_LOG_DEBUG_VAR("ViewTest.NestedTemporaries", range_str(gview_lref)); + + auto gview_temp = dash::sub(1, array_size - 5, + dash::sub(1, array_size - 3, + dash::sub(1, array_size - 2, a))); + DASH_LOG_DEBUG_VAR("ViewTest.NestedTemporaries", range_str(gview_temp)); + + EXPECT_EQ(a.size() - 3 - 3, + gview_lref.size()); + EXPECT_EQ(gview_temp.size(), gview_lref.size()); + + int v_idx = 0; + for (const auto & view_elem : gview_temp) { + EXPECT_EQ(static_cast(a[v_idx + 3]), + static_cast(view_elem)); + ++v_idx; + } +} + +TEST_F(ViewTest, ArrayBlockedPatternGlobalView) +{ + int block_size = 3; + int array_size = dash::size() * block_size; + int block_begin_gidx = block_size * dash::myid(); + int block_end_gidx = block_size * (dash::myid() + 1); + + dash::Array a(array_size); + dash::test::initialize_array(a); + + if (dash::myid() == 0) { + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternGlobalView", + range_str(a)); + } + a.barrier(); + + // View to global index range of local block: + auto block_gview = dash::sub(block_begin_gidx, + block_end_gidx, + a); + EXPECT_EQ(block_size, block_gview.size()); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternGlobalView", + range_str(block_gview)); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternGlobalView", + block_gview.begin()); + + EXPECT_TRUE_U(std::equal(a.begin() + block_begin_gidx, + a.begin() + block_end_gidx, + block_gview.begin())); + + // Origin of block view is array: + auto & block_domain = dash::domain(block_gview); + + EXPECT_EQ(array_size, block_domain.size()); + EXPECT_EQ(a.begin(), dash::begin(block_domain)); + EXPECT_EQ(a.end(), dash::end(block_domain)); + + auto view_begin_gidx = dash::index(dash::begin(block_gview)); + auto view_end_gidx = dash::index(dash::end(block_gview)); + + EXPECT_EQ(block_begin_gidx, view_begin_gidx); + EXPECT_EQ(block_end_gidx, view_end_gidx); +} + +TEST_F(ViewTest, ArrayBlockedPatternChainedGlobalView) +{ + int block_size = 7; + int array_size = dash::size() * block_size; + int block_begin_gidx = block_size * dash::myid(); + int block_end_gidx = block_size * (dash::myid() + 1); + + dash::Array a(array_size); + dash::test::initialize_array(a); + + if (dash::myid() == 0) { + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternChainedGlobalView", + range_str(a)); + } + a.barrier(); + + // View to global index range of local block: + auto l_block_gview = dash::sub(block_begin_gidx, + block_end_gidx, + a); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternChainedGlobalView", + range_str(l_block_gview)); + EXPECT_TRUE_U( + std::equal(l_block_gview.begin(), + l_block_gview.end(), + a.local.begin())); + + // View to global index range spanning over local block: + int block_outer_begin_gidx = (dash::myid() == 0 + ? block_begin_gidx + : block_begin_gidx - 2); + int block_outer_end_gidx = (dash::myid() == dash::size() - 1 + ? block_end_gidx + : block_end_gidx + 2); + auto block_gview_outer = dash::sub(block_outer_begin_gidx, + block_outer_end_gidx, + a); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternChainedGlobalView", + range_str(block_gview_outer)); + + EXPECT_EQ_U(block_outer_end_gidx - block_outer_begin_gidx, + block_gview_outer.size()); + + // Sub-range in block from block index 2 to -2: + auto block_gview_inner = dash::sub(2, + block_size - 2, + l_block_gview); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternChainedGlobalView", + range_str(block_gview_inner)); + + EXPECT_EQ(block_size - 4, block_gview_inner.size()); + EXPECT_EQ(block_begin_gidx + 2, + dash::index(dash::begin(block_gview_inner))); + EXPECT_EQ(block_begin_gidx + block_size - 2, + dash::index(dash::end(block_gview_inner))); + + // Origin of inner view is outer view: + auto & block_gview_inner_domain = dash::domain(block_gview_inner); + EXPECT_TRUE_U( + std::equal(l_block_gview.begin(), + l_block_gview.end(), + block_gview_inner_domain.begin())); + + // Origin of outer view is array: + auto & block_gview_outer_domain = dash::domain(block_gview_outer); + EXPECT_EQ(a.begin(), dash::begin(block_gview_outer_domain)); + EXPECT_EQ(a.end(), dash::end(block_gview_outer_domain)); +} + +TEST_F(ViewTest, ArrayBlockCyclicPatternGlobalView) +{ + int block_size = 5; + int blocks_per_unit = 3; + int array_size = dash::size() * block_size * blocks_per_unit + + (block_size * 2) + - 2; + int block_begin_gidx = block_size * dash::myid(); + int block_end_gidx = block_size * (dash::myid() + 1); + + dash::Array a(array_size, dash::BLOCKCYCLIC(block_size)); + dash::test::initialize_array(a); + + if (dash::myid() == 0) { + auto blocks_view = dash::blocks(dash::sub(0, a.size(), a)); + int b_idx = 0; + for (auto block : blocks_view) { + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternGlobalView", + "a.block[", b_idx, "]:", range_str(block)); + ++b_idx; + } + } + a.barrier(); + + // View to global index range of local block: + auto block_gview = dash::sub(block_begin_gidx, + block_end_gidx, + a); + + EXPECT_EQ(block_size, block_gview.size()); + + // Origin of block view is array: + auto & block_domain = dash::domain(block_gview); + EXPECT_EQ(a.begin(), dash::begin(block_domain)); + EXPECT_EQ(a.end(), dash::end(block_domain)); + + // --- blocks(sub(array)) ---------------------------------------------- + // + if (dash::myid() == 0) { + auto sub_begin_gidx = block_size / 2; + auto sub_end_gidx = a.size() - (block_size / 2); + auto sub_view = dash::sub(sub_begin_gidx, sub_end_gidx, a); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternGlobalView", + range_str(sub_view)); + + auto blocks_sub_view = dash::blocks( + dash::sub( + sub_begin_gidx, + sub_end_gidx, + a)); + int b_idx = 0; + int begin_idx = sub_begin_gidx; + int num_blocks = a.pattern().blockspec().size(); + for (auto block : blocks_sub_view) { + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternGlobalView", + "a.sub.block[", b_idx, "]:", range_str(block)); + int exp_block_size = block_size; + if (b_idx == 0) { + exp_block_size -= (block_size / 2); // 5 - 2 = 3 + } else if (b_idx == num_blocks - 1) { + exp_block_size -= 2 * (block_size / 2); // 5 - 2*2 = 1 + } + + EXPECT_EQ(exp_block_size, block.size()); + EXPECT_EQ(exp_block_size, block.end() - block.begin()); + EXPECT_TRUE(std::equal(a.begin() + begin_idx, + a.begin() + begin_idx + exp_block_size, + block.begin())); + + begin_idx += exp_block_size; + ++b_idx; + } + EXPECT_EQ(num_blocks, b_idx); + } +} + +TEST_F(ViewTest, ArrayBlockCyclicPatternLocalSub) +{ + int block_size = 4; + // minimum number of blocks per unit: + int blocks_per_unit = 2; + // two extra blocks, last block underfilled: + int array_size = dash::size() * block_size * blocks_per_unit + + (block_size * 2) + - 2; + int num_blocks = (dash::size() * blocks_per_unit) + + 2; + int num_local_blocks = dash::size() == 1 + ? num_blocks + : ( dash::myid() < 2 + ? blocks_per_unit + 1 + : blocks_per_unit ); + + dash::Array a(array_size, dash::BLOCKCYCLIC(block_size)); + dash::test::initialize_array(a); + + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternLocalSub", + "array:", range_str(a)); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternLocalSub", + "local(array):", range_str(dash::local(a))); + + // sub(local(array)) + // + { + auto l_begin = block_size / 2; + auto l_end = a.lsize() - (block_size / 2); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternLocalSub", "==", + "sub(", l_begin, ",", l_end, ", local(array))"); + + auto s_l_view = dash::sub( + block_size / 2, + a.lsize() - (block_size / 2), + dash::local( + a)); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternLocalSub", + "lbegin:", l_begin, "lend:", l_end); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternLocalSub", + range_str(s_l_view)); + + EXPECT_EQ_U(l_end - l_begin, s_l_view.size()); + EXPECT_TRUE_U(std::equal(a.lbegin() + l_begin, + a.lbegin() + l_end, + s_l_view.begin())); + } + a.barrier(); + + // local(sub(array)) + // + { + auto l_begin = 0; + auto l_end = a.lsize(); + if (a.pattern().unit_at(0) == dash::myid().id) { + l_begin += block_size / 2; + } + if (a.pattern().unit_at(a.size() - 1) == dash::myid().id) { + l_end -= block_size / 2; + } + + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternLocalSub", "==", + "local(sub(", + (block_size / 2), ",", (a.size() - (block_size / 2)), + ", array))"); + auto l_s_view = dash::local( + dash::sub( + block_size / 2, + a.size() - (block_size / 2), + a)); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternLocalSub", + "lbegin:", l_begin, "lend:", l_end); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternLocalSub", + range_str(l_s_view)); + + EXPECT_EQ_U(l_end - l_begin, l_s_view.size()); + EXPECT_TRUE_U(std::equal(a.lbegin() + l_begin, + a.lbegin() + l_end, + l_s_view.begin())); + } + a.barrier(); + + // sub(local(sub(array))) + // + { + auto l_begin = 0; + auto l_end = a.lsize(); + if (a.pattern().unit_at(0) == dash::myid().id) { + l_begin += block_size / 2; + } + if (a.pattern().unit_at(a.size() - 1) == dash::myid().id) { + l_end -= block_size / 2; + } + l_begin += 1; + l_end -= 1; + + auto l_s_view = dash::local( + dash::sub( + block_size / 2, + a.size() - (block_size / 2), + a)); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternLocalSub", "==", + "sub(", 1, ",", l_s_view.size() - 1, + ", local(sub(", + (block_size / 2), ",", (a.size() - (block_size / 2)), + ", array)))"); + + auto s_l_s_view = dash::sub( + 1, + l_s_view.size() - 1, + l_s_view); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternLocalSub", + "lbegin:", l_begin, "lend:", l_end); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternLocalSub", + range_str(s_l_s_view)); + + EXPECT_EQ_U(l_end - l_begin, s_l_s_view.size()); + EXPECT_TRUE_U(std::equal(a.lbegin() + l_begin, + a.lbegin() + l_end, + s_l_s_view.begin())); + } + a.barrier(); +} + +TEST_F(ViewTest, ArrayBlockCyclicPatternLocalBlocks) +{ + int block_size = 5; + // minimum number of blocks per unit: + int blocks_per_unit = 3; + // two extra blocks, last block underfilled: + int array_size = dash::size() * block_size * blocks_per_unit + + (block_size * 2) + - 2; + int num_blocks = (dash::size() * blocks_per_unit) + + 2; + int num_local_blocks = dash::size() == 1 + ? num_blocks + : ( dash::myid() < 2 + ? blocks_per_unit + 1 + : blocks_per_unit ); + + dash::Array a(array_size, dash::BLOCKCYCLIC(block_size)); + dash::test::initialize_array(a); + + // local(blocks(array)) + // + { + int l_b_idx; + int l_idx; + + auto blocks_view = dash::blocks(a); + if (dash::myid() == 0) { + for (auto block : blocks_view) { + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternLocalBlocks", "----", + "blocks_view", range_str(block)); + } + } + a.barrier(); + + EXPECT_EQ_U(num_blocks, blocks_view.size()); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalBlocks", + dash::typestr(blocks_view)); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalBlocks", + dash::typestr(blocks_view.begin())); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalBlocks", + blocks_view.size()); + + auto l_blocks_view = dash::local( + dash::blocks(a) ); + EXPECT_EQ_U(num_local_blocks, l_blocks_view.size()); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalBlocks", + dash::typestr(l_blocks_view)); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalBlocks", + l_blocks_view.size()); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalBlocks", + dash::typestr(l_blocks_view.begin())); + + l_b_idx = 0; + l_idx = 0; + for (const auto & l_block : l_blocks_view) { + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternLocalBlocks", + "l_block[", l_b_idx, "]:", range_str(l_block)); + EXPECT_TRUE_U(std::equal(a.lbegin() + l_idx, + a.lbegin() + l_idx + l_block.size(), + l_block.begin())); + ++l_b_idx; + l_idx += l_block.size(); + } + EXPECT_EQ_U(l_idx, a.lsize()); + } + a.barrier(); + + // blocks(local(array)) + // + { + int l_b_idx = 0; + int l_idx = 0; + + auto blocks_l_view = dash::blocks( + dash::local(a)); + for (const auto & block_l : blocks_l_view) { + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternLocalBlocks", + "block_l[", l_b_idx, "]:", range_str(block_l)); + EXPECT_TRUE_U(std::equal(a.lbegin() + l_idx, + a.lbegin() + l_idx + block_l.size(), + block_l.begin())); + ++l_b_idx; + l_idx += block_l.size(); + } + EXPECT_EQ_U(l_idx, a.lsize()); + } +} + +TEST_F(ViewTest, ArrayBlockCyclicPatternSubLocalBlocks) +{ + int block_size = 5; + // minimum number of blocks per unit: + int blocks_per_unit = 2; + // two extra blocks, last block underfilled: + int array_size = dash::size() * block_size * blocks_per_unit + + (block_size * 2) + - 2; + int num_blocks = (dash::size() * blocks_per_unit) + + 2; + int num_local_blocks = dash::size() == 1 + ? num_blocks + : ( dash::myid() < 2 + ? blocks_per_unit + 1 + : blocks_per_unit ); + + dash::Array a(array_size, dash::BLOCKCYCLIC(block_size)); + dash::test::initialize_array(a); + + // local(blocks(array)) + // + { + auto l_blocks_view = dash::local( + dash::blocks( + a)); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + dash::typestr(l_blocks_view)); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + l_blocks_view.size()); + + EXPECT_EQ_U(num_local_blocks, l_blocks_view.size()); + + int l_b_idx = 0; + int l_idx = 0; + for (const auto & l_block : l_blocks_view) { + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "l_block[", l_b_idx, "]:", range_str(l_block)); + + EXPECT_TRUE_U(std::equal(a.local.begin() + l_idx, + a.local.begin() + l_idx + l_block.size(), + l_block.begin())); + + ++l_b_idx; + l_idx += l_block.size(); + } + EXPECT_EQ_U(a.lsize(), l_idx); + } + a.barrier(); + + if (dash::myid() == 0) { + auto sub_view = dash::sub( + block_size / 2, + a.size() - (block_size / 2), + a); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + range_str(sub_view)); + } + a.barrier(); + + // local(sub(array)) + // + { + auto l_sub_view = dash::local( + dash::sub( + block_size / 2, + a.size() - (block_size / 2), + a)); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + dash::typestr(l_sub_view)); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + l_sub_view.size()); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + range_str(l_sub_view)); + int g_idx; + int l_idx = 0; + for (g_idx = block_size / 2; + g_idx != a.size() - (block_size / 2); + ++g_idx) { + float * lp = (a.begin() + g_idx).local(); + if (l_idx < l_sub_view.size() && lp != nullptr) { + EXPECT_EQ_U(*lp, static_cast(l_sub_view[l_idx])); + ++l_idx; + } + } + int exp_l_idx = a.lsize(); + if (dash::myid().id == a.pattern().unit_at(0)) { + // Owner of first global block: + exp_l_idx -= (block_size / 2); + } + if (dash::myid().id == a.pattern().unit_at(a.size() - 1)) { + // Owner of last global block: + exp_l_idx -= (block_size / 2); + } + EXPECT_EQ_U(exp_l_idx, l_idx); + } + a.barrier(); + + // local(blocks(sub(array))) + // + { + int l_b_idx; + int l_idx; + auto sub_view = dash::sub( + block_size / 2, + a.size() - (block_size / 2), + a); + auto blocks_sub_view = dash::blocks( + dash::sub( + block_size / 2, + a.size() - (block_size / 2), + a)); + if (dash::myid() == 0) { + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "type(blocks_sub_view):", + dash::typestr(blocks_sub_view)); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "type(blocks_sub_view::domain_type):", + dash::typestr< + typename decltype(blocks_sub_view)::domain_type + >()); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "type(blocks_sub_view::local_type):", + dash::typestr< + typename decltype(blocks_sub_view)::local_type + >()); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "type(blocks_sub_view::origin_type):", + dash::typestr< + typename decltype(blocks_sub_view)::origin_type + >()); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "type(blocks_sub_view[0]):", + dash::typestr(blocks_sub_view[0])); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + blocks_sub_view.size()); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + dash::index(blocks_sub_view).is_strided()); + int b_idx = 0; + int idx = 0; + for (auto block : blocks_sub_view) { + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "blocks_sub[", b_idx, "]", range_str(block)); + ++b_idx; + } + } + a.barrier(); + + EXPECT_EQ_U(num_blocks, blocks_sub_view.size()); + + auto l_blocks_sub_view = dash::local( + blocks_sub_view); + + if (dash::myid() == 0) { + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "type(l_blocks_sub_view):", + dash::typestr(l_blocks_sub_view)); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "type(l_blocks_sub_view::domain_type):", + dash::typestr< + typename decltype(l_blocks_sub_view)::domain_type + >()); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "type(l_blocks_sub_view::local_type):", + dash::typestr< + typename decltype(l_blocks_sub_view)::local_type + >()); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "type(l_blocks_sub_view::origin_type):", + dash::typestr< + typename decltype(l_blocks_sub_view)::origin_type + >()); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "type(l_blocks_sub_view[0]):", + dash::typestr(l_blocks_sub_view[0])); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "type(l_blocks_sub_view[0].origin):", + dash::typestr(dash::origin( + l_blocks_sub_view[0]))); + } + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + l_blocks_sub_view.size()); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + dash::index(l_blocks_sub_view).is_strided()); + + EXPECT_EQ_U(num_local_blocks, l_blocks_sub_view.size()); + + std::vector l_blocks_sub_values; + + l_b_idx = 0; + l_idx = 0; + for (const auto & l_block : l_blocks_sub_view) { + auto l_block_index = dash::index(l_block); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "l_block_sub[", l_b_idx, "]", + range_str(l_block)); + EXPECT_EQ_U(dash::distance(l_block.begin(), l_block.end()), + l_block.size()); + EXPECT_EQ_U(l_block_index.size(), l_block.size()); + + l_blocks_sub_values.insert(l_blocks_sub_values.end(), + l_block.begin(), + l_block.end()); + ++l_b_idx; + l_idx += l_block.size(); + } + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "l_idx:", l_idx, "l_b_idx:", l_b_idx); + DASH_LOG_DEBUG("ViewTest.ArrayBlockCyclicPatternSubLocalBlocks", + "l_blocks_sub:", l_blocks_sub_values); + + EXPECT_EQ_U(dash::local(sub_view).size(), + l_blocks_sub_values.size()); + EXPECT_TRUE_U(std::equal(l_blocks_sub_values.begin(), + l_blocks_sub_values.end(), + dash::local(sub_view).begin())); + a.barrier(); + + int exp_l_idx = a.lsize(); + if (dash::myid().id == a.pattern().unit_at(0)) { + // Owner of first global block: + exp_l_idx -= (block_size / 2); + } + if (dash::myid().id == a.pattern().unit_at(a.size() - 1)) { + // Owner of last global block: + exp_l_idx -= (block_size / 2); + } + EXPECT_EQ_U(exp_l_idx, l_idx); + EXPECT_EQ_U(num_local_blocks, l_b_idx); + } + a.barrier(); +} + +TEST_F(ViewTest, IndexSet) +{ + typedef float value_t; + typedef dash::default_index_t index_t; + + int block_size = 3; + int blocks_per_unit = 3; + int array_size = dash::size() + * (blocks_per_unit * block_size); + + dash::Array> + array(array_size, dash::TILE(block_size)); + dash::test::initialize_array(array); + + auto sub_begin_gidx = block_size / 2; + auto sub_end_gidx = array_size - (block_size / 2); + + // ---- sub(array) ---------------------------------------------------- + // + if (dash::myid() == 0) { + std::vector values(array.begin(), array.end()); + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", values); + + auto sub_gview = dash::sub( + sub_begin_gidx, + sub_end_gidx, + array); + + auto sub_index = dash::index(sub_gview); + + EXPECT_EQ_U( + dash::distance( + array.begin() + sub_begin_gidx, + array.begin() + sub_end_gidx), + dash::distance( + sub_gview.begin(), + sub_gview.end()) ); + EXPECT_TRUE_U( + std::equal( + array.begin() + sub_begin_gidx, + array.begin() + sub_end_gidx, + sub_gview.begin()) ); + + DASH_LOG_DEBUG("ViewTest.IndexSet", "---- sub(", + sub_begin_gidx, ",", sub_end_gidx, ")"); + + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", sub_index); + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", sub_index.pre().first()); + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", sub_index.pre().last()); + + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", range_str(sub_gview)); + + EXPECT_EQ_U(array_size - (2 * (block_size / 2)), sub_gview.size()); + EXPECT_EQ_U(array_size - (2 * (block_size / 2)), sub_index.size()); + + EXPECT_TRUE_U(std::equal(array.begin() + (block_size / 2), + array.begin() + array_size - (block_size / 2), + sub_gview.begin())); + } + array.barrier(); + + // ---- local(all(array)) --------------------------------------------- + // + auto all_gview = dash::sub( + 0, array_size, + array); + auto l_all_gview = dash::local(all_gview); + auto l_all_index = dash::index(l_all_gview); + + DASH_LOG_DEBUG("ViewTest.IndexSet", "---- local(sub(", + 0, ",", array_size, "))"); + + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", l_all_index); + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", l_all_gview); + + array.barrier(); + + // ---- local(sub(array)) --------------------------------------------- + // + auto locsub_gview = dash::local( + dash::sub( + sub_begin_gidx, + sub_end_gidx, + array)); + auto locsub_index = dash::index(locsub_gview); + + DASH_LOG_DEBUG("ViewTest.IndexSet", "---- local(sub(", + sub_begin_gidx, ",", sub_end_gidx, "))"); + + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", locsub_index); + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", locsub_index.pre().first()); + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", locsub_index.pre().last()); + + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", locsub_gview); + + array.barrier(); + + // ---- sub(sub(array)) ----------------------------------------------- + // + if (dash::myid() == 0) { + auto subsub_begin_idx = 3; + auto subsub_end_idx = subsub_begin_idx + block_size; + + auto subsub_gview = dash::sub( + subsub_begin_idx, + subsub_end_idx, + dash::sub( + sub_begin_gidx, + sub_end_gidx, + array)); + auto subsub_index = dash::index(subsub_gview); + + DASH_LOG_DEBUG("ViewTest.IndexSet", "---- sub(sub(", + sub_begin_gidx, ",", sub_end_gidx, ") ", + subsub_begin_idx, ",", subsub_end_idx, ")"); + + auto subsub_begin_gidx = sub_begin_gidx + subsub_begin_idx; + auto subsub_end_gidx = sub_begin_gidx + subsub_end_idx; + + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", subsub_index); + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", subsub_index.pre().first()); + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", subsub_index.pre().last()); + + std::vector subsub_values(subsub_gview.begin(), + subsub_gview.end()); + DASH_LOG_DEBUG_VAR("ViewTest.IndexSet", subsub_values); + + EXPECT_EQ_U( + dash::distance( + array.begin() + subsub_begin_gidx, + array.begin() + subsub_end_gidx), + dash::distance( + subsub_gview.begin(), + subsub_gview.end()) ); + EXPECT_TRUE_U( + std::equal( + array.begin() + subsub_begin_gidx, + array.begin() + subsub_end_gidx, + subsub_gview.begin()) ); + } +} + +TEST_F(ViewTest, LocalBlocksView1Dim) +{ + typedef float value_t; + typedef dash::default_index_t index_t; + + int block_size = 4; + int blocks_per_unit = 2; + int array_size = dash::size() + * (blocks_per_unit * block_size) + + (block_size * 3 / 2); + + dash::Array array(array_size, dash::BLOCKCYCLIC(block_size)); + dash::test::initialize_array(array); + + if (dash::myid() == 0) { + std::vector values(array.begin(), array.end()); + DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", values); + } + array.barrier(); + + auto lblocks_view = dash::local( + dash::blocks( + array)); + // DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", lblocks_view); + + auto lblocks_index = dash::index(lblocks_view); + DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", lblocks_index); + + auto blocksl_view = dash::blocks( + dash::local( + array)); + // DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", blocksl_view); + + auto blocksl_index = dash::index(blocksl_view); + DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", blocksl_index); + + auto lsize = array.pattern().local_extent(0); + auto l_beg = array.pattern().global_index(array.team().myid(), + {{ 0 }} ); + auto l_end = array.pattern().global_index(array.team().myid(), + {{ lsize }} ); + auto n_lblocks = dash::math::div_ceil(array.lsize(), block_size); + + DASH_LOG_DEBUG("ViewTest.LocalBlocksView1Dim", + "n_lblocks:", n_lblocks, "l_beg:", l_beg, "l_end:", l_end); + + EXPECT_EQ_U(n_lblocks, blocksl_view.size()); + EXPECT_EQ_U(n_lblocks, blocksl_index.size()); + + int b_idx = 0; + for (const auto & block : blocksl_view) { + auto block_index = dash::index(block); + + DASH_LOG_DEBUG("ViewTest.LocalBlocksView1Dim", + "---- local block", b_idx); + + std::vector block_indices(block_index.begin(), + block_index.end()); + DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", block_indices); + //DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", block); + + std::vector block_values(block.begin(), block.end()); + DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", block_values); + + auto lblock_size = array.pattern().local_block(b_idx).extents()[0]; + auto lblock_gbegin = array.pattern().local_block(b_idx).offsets()[0]; + + EXPECT_EQ_U(lblock_size, block.size()); + for (auto bi = 0; bi < lblock_size; ++bi) { + EXPECT_EQ_U(static_cast(array[bi + lblock_gbegin]), + static_cast(block[bi])); + } + b_idx++; + } + + dash::Array array_bal( + dash::size() * block_size, + dash::BLOCKCYCLIC(block_size)); + dash::test::initialize_array(array_bal); + + auto sub_view = dash::sub( + block_size / 2, + array.size() - (block_size / 2), + array_bal); + auto blockssub_view = dash::blocks(sub_view); + auto lblockssub_view = dash::local(blockssub_view); + + auto lblockssub_index = dash::index(lblockssub_view); + + DASH_LOG_DEBUG_VAR("ViewTest.LocalBlocksView1Dim", lblockssub_index); +} + +TEST_F(ViewTest, BlocksView1Dim) +{ + typedef float value_t; + typedef dash::default_index_t index_t; + + int block_size = 3; + int blocks_per_unit = 3; + int array_size = dash::size() + * (blocks_per_unit * block_size) + // unbalanced size, last block underfilled: + - (block_size / 2); + + int sub_left_begin_gidx = 0; + int sub_left_end_gidx = array_size - (block_size / 2) - 1; + int sub_right_begin_gidx = (block_size * 3) / 2; + int sub_right_end_gidx = array_size; + + dash::Array array(array_size, dash::BLOCKCYCLIC(block_size)); + dash::test::initialize_array(array); + + if (dash::myid() == 0) { + std::vector values(array.begin(), array.end()); + DASH_LOG_DEBUG_VAR("ViewTest.BlocksView1Dim", values); + } + array.barrier(); + + auto array_blocks = dash::blocks( + dash::sub<0>(0, array.size(), + array)); + + DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", + "array.blocks.size:", array_blocks.size(), + "=", array_blocks.end() - array_blocks.begin(), + "=", dash::index(array_blocks).size()); + + EXPECT_EQ_U(array_blocks.size(), + array_blocks.end() - array_blocks.begin()); + + array.barrier(); + + if (dash::myid() == 0) { + DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "blocks(array):", + "index(blocks).begin, index(blocks).end:", + "(", *(dash::index(array_blocks).begin()), + ",", *(dash::index(array_blocks).end()), + ")", "size:", array_blocks.size(), + "=", array_blocks.end() - array_blocks.begin(), + "=", "indices:", dash::index(array_blocks).size()); + + int b_idx = 0; + for (auto b_it = array_blocks.begin(); + b_it != array_blocks.end(); ++b_it, ++b_idx) { + auto && block = *b_it; + EXPECT_EQ_U(b_idx, b_it.pos()); + + DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "--", + "block[", b_idx, "]:", + dash::typestr(block)); + DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "----", + "p.offsets:", array.pattern().block(b_idx).offsets()[0], + "p.extents:", array.pattern().block(b_idx).extents()[0], + "->", dash::index(array_blocks)[b_idx], + "index(block).begin, index(block).end:", + "(", *(dash::begin(dash::index(block))), + ",", *(dash::end(dash::index(block))), + ")", "size:", block.size(), + "=", "indices:", dash::index(block).size()); + + DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "----", + range_str(block)); + + EXPECT_EQ_U(( b_idx < array_blocks.size() - 1 + ? block_size + : block_size - (block_size / 2) ), + block.size()); + EXPECT_TRUE_U( + std::equal(array.begin() + (b_idx * block_size), + array.begin() + (b_idx * block_size) + block.size(), + block.begin())); + } + } + array.barrier(); + + // View to first two thirds of global array: + auto gview_left = dash::sub(sub_left_begin_gidx, + sub_left_end_gidx, + array); + // View to last two thirds of global array: + auto gview_right = dash::sub(sub_right_begin_gidx, + sub_right_end_gidx, + array); + + auto gview_isect = dash::intersect(gview_left, gview_right); + + EXPECT_EQ_U(sub_left_end_gidx - sub_right_begin_gidx, + gview_isect.size()); + + if (dash::myid() == 0) { + DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "index(gview_isect(array)):", + "(begin, first, last, end):", + "(", *(dash::index(gview_isect).begin()), + ",", dash::index(gview_isect).first(), + ",", dash::index(gview_isect).last(), + ",", *(dash::index(gview_isect).end()), + ")", "size:", dash::index(gview_isect).size()); + + DASH_LOG_DEBUG_VAR("ViewTest.BlocksView1Dim", range_str(gview_isect)); + } + array.barrier(); + + EXPECT_TRUE_U( + std::equal(array.begin() + sub_right_begin_gidx, + array.begin() + sub_left_end_gidx, + gview_isect.begin())); + + auto gview_blocks = dash::blocks(gview_isect); + + static_assert( + dash::view_traits< + std::remove_reference< decltype(gview_blocks) >::type + >::is_view::value == true, + "view traits is_view for blocks(dash::Array) not matched"); + + array.barrier(); + + if (dash::myid() == 0) { + DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", + "index(blocks(gview_isect(array))):", + "(begin, first, last, end):", + "(", *(dash::index(gview_blocks).begin()), + ",", dash::index(gview_blocks).first(), + ",", dash::index(gview_blocks).last(), + ",", *(dash::index(gview_blocks).end()), + ")", "size:", dash::index(gview_blocks).size()); + + std::vector gview_blocks_values; + + int b_idx = 0; + for (auto block : gview_blocks) { + DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "--", + "block[", b_idx, "]:", + dash::typestr(block)); + DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "----", + "p.offsets:", array.pattern().block(b_idx).offsets()[0], + "p.extents:", array.pattern().block(b_idx).extents()[0], + "->", (dash::index(gview_blocks)[b_idx]), + "index(block.begin, block.end):", + "(", *(dash::index(block).begin()), + ",", *(dash::index(block).end()), ")", + "size:", dash::index(block).size()); + + DASH_LOG_DEBUG("ViewTest.BlocksView1Dim", "----", + range_str(block)); + + gview_blocks_values.insert(gview_blocks_values.end(), + block.begin(), + block.end()); + b_idx++; + } + EXPECT_EQ_U(gview_isect.size(), + gview_blocks_values.size()); + EXPECT_TRUE(std::equal(gview_isect.begin(), + gview_isect.end(), + gview_blocks_values.begin())); + } +} + +TEST_F(ViewTest, Intersect1DimSingle) +{ + int block_size = 13; + int array_size = dash::size() * block_size + // unbalanced size: + + 2; + + int sub_left_begin_gidx = 0; + int sub_left_end_gidx = (array_size * 2) / 3; + int sub_right_begin_gidx = (array_size * 1) / 3; + int sub_right_end_gidx = array_size; + + dash::Array array(array_size); + + for (auto li = 0; li != array.local.size(); ++li) { + array.local[li] = (1000 * (dash::myid() + 1)) + + (100 * li) + + (dash::myid() * block_size) + li; + } + array.barrier(); + + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", array); + + // View to first two thirds of global array: + auto gview_left = dash::sub(sub_left_begin_gidx, + sub_left_end_gidx, + array); + // View to last two thirds of global array: + auto gview_right = dash::sub(sub_right_begin_gidx, + sub_right_end_gidx, + array); + + auto gview_isect = dash::intersect(gview_left, gview_right); + + auto gindex_isect = dash::index(gview_isect); + + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", gview_isect); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", gindex_isect); + + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", array.size()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", gview_left.size()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", gview_right.size()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", gview_isect.size()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", *gindex_isect.begin()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", *gindex_isect.end()); + + EXPECT_EQ_U(sub_left_end_gidx - sub_left_begin_gidx, + gview_left.size()); + EXPECT_EQ_U(sub_right_end_gidx - sub_right_begin_gidx, + gview_right.size()); + EXPECT_EQ_U(sub_left_end_gidx - sub_right_begin_gidx, + gview_isect.size()); + + for (int isect_idx = 0; isect_idx < gview_isect.size(); isect_idx++) { + EXPECT_EQ_U(static_cast(array[sub_right_begin_gidx + isect_idx]), + static_cast(gview_isect[isect_idx])); + } + + auto lview_isect = dash::local(gview_isect); + auto lindex_isect = dash::index(lview_isect); + + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", *lindex_isect.begin()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimSingle", *lindex_isect.end()); +} + +TEST_F(ViewTest, Intersect1DimChain) +{ + int block_size = 4; + int blocks_per_unit = 3; + int array_size = dash::size() + * (blocks_per_unit * block_size) + // unbalanced size, last block underfilled: + - (block_size / 2); + + int sub_left_begin_gidx = 0; + int sub_left_end_gidx = array_size - (block_size / 2); + int sub_right_begin_gidx = (block_size / 2); + int sub_right_end_gidx = array_size; + + dash::Array array(array_size, + dash::BLOCKCYCLIC(block_size)); + dash::test::initialize_array(array); + + DASH_LOG_DEBUG("ViewTest.Intersect1DimChain", + "array initialized"); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", array.size()); + + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + dash::index(dash::local(array))); + //DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + // dash::global(dash::index(dash::local(array)))); + + array.barrier(); + + // View to first two thirds of global array: + auto gview_left = dash::sub(sub_left_begin_gidx, + sub_left_end_gidx, + array); + // View to last two thirds of global array: + auto gview_right = dash::sub(sub_right_begin_gidx, + sub_right_end_gidx, + array); + + auto gview_isect = dash::intersect(gview_left, gview_right); + + auto gindex_isect = dash::index(gview_isect); + + if (dash::myid() == 0) { + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + dash::typestr(gview_isect)); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", gview_left.size()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", gview_right.size()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", gview_isect.size()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", *gindex_isect.begin()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", *gindex_isect.end()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", range_str(gview_isect)); + + EXPECT_TRUE_U(std::equal(array.begin() + sub_right_begin_gidx, + array.begin() + sub_left_end_gidx, + gview_isect.begin())); + } + array.barrier(); + + auto exp_isect_n = sub_left_end_gidx - sub_right_begin_gidx; + + EXPECT_EQ_U(exp_isect_n, gview_isect.size()); + EXPECT_EQ_U(exp_isect_n, gindex_isect.size()); + EXPECT_EQ_U(exp_isect_n, + dash::distance(gindex_isect.begin(), gindex_isect.end())); + EXPECT_EQ_U(exp_isect_n, + dash::distance(gview_isect.begin(), gview_isect.end())); + EXPECT_EQ_U(sub_right_begin_gidx, *gindex_isect.begin()); + EXPECT_EQ_U(sub_left_end_gidx, *gindex_isect.end()); + + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + array.pattern().local_size()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + array.pattern().global(0)); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + array.pattern().global(array.pattern().local_size())); + + auto lview_isect = dash::local(gview_isect); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + dash::typestr(lview_isect.begin())); + + auto lindex_isect = dash::index(lview_isect); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + dash::typestr(lindex_isect)); + + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + lindex_isect.domain_block_gidx_last()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + lindex_isect.domain_block_lidx_last()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + lindex_isect.local_block_gidx_last()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + lindex_isect.local_block_gidx_at_block_lidx( + lindex_isect.domain_block_lidx_last())); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + lindex_isect.local_block_gidx_at_block_lidx( + lindex_isect.domain_block_lidx_last() - 1)); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + lindex_isect.pattern().local_block(1) + .range(0).begin); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + lindex_isect.pattern().local_block(1) + .range(0).end); + + array.barrier(); + + //auto lrange_isect = dash::local_index_range( + // array.begin() + sub_right_begin_gidx, + // array.begin() + sub_left_end_gidx); + //DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", lrange_isect.begin); + //DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", lrange_isect.end); + + static_assert( + dash::detail::has_type_domain_type::value, + "Type trait has_type_domain_type not matched " + "for index(local(intersect(...))) "); + + auto lindex_isect_dom = dash::domain(lindex_isect); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", + dash::typestr(lindex_isect_dom)); + + static_assert( + dash::is_range::value, + "View trait is_range not matched for index(local(intersect(...)))"); + + auto lindex_isect_dom_pre = dash::domain(lindex_isect).pre(); + + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", lindex_isect); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", lindex_isect_dom); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", lindex_isect_dom_pre); + EXPECT_TRUE_U( + dash::test::expect_range_values_equal( + dash::domain(lindex_isect), + lindex_isect.domain())); + + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", lview_isect.size()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", lindex_isect.size()); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", range_str(lview_isect)); + + auto && lindex_pattern = lindex_isect.pattern(); + auto lindex_last_lblock_idx = lindex_pattern.local_block_at( + lindex_pattern.coords( + lindex_pattern.lend() - 1)).index; + auto lindex_last_lblock = lindex_pattern.local_block( + lindex_last_lblock_idx); + auto lindex_last_dblock_idx = lindex_pattern.local_block_at( + lindex_pattern.coords( + lindex_isect.domain().last())).index; + auto lindex_last_dblock = lindex_pattern.local_block( + lindex_last_dblock_idx); + + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", lindex_last_lblock_idx); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", lindex_last_lblock); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", lindex_last_dblock_idx); + DASH_LOG_DEBUG_VAR("ViewTest.Intersect1DimChain", lindex_last_dblock); + + int lidx = 0; + for (auto gidx = sub_right_begin_gidx; + gidx < sub_left_end_gidx; + ++gidx) { + auto lptr = (array.begin() + gidx).local(); + if (nullptr != lptr) { + EXPECT_EQ_U(*lptr, lview_isect[lidx]); + ++lidx; + } + } + EXPECT_EQ_U(lidx, lview_isect.size()); +} + +TEST_F(ViewTest, ArrayBlockedPatternLocalView) +{ + int block_size = 7; + int array_size = dash::size() * block_size; + int lblock_begin_gidx = block_size * dash::myid(); + int lblock_end_gidx = lblock_begin_gidx + block_size; + + dash::Array array(array_size); + initialize_array(array); + + DASH_LOG_DEBUG("ViewTest.ArrayBlockedPatternLocalView", + "array initialized"); + + if (dash::myid() == 0) { + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + array.pattern().size()); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + array.pattern().blockspec().size()); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + array.pattern().local_size()); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + range_str(array)); + } + array.barrier(); + + // View index sets: + auto l_begin_gidx = array.pattern().global(0); + + DASH_LOG_DEBUG("ViewTest.ArrayBlockedPatternLocalView", + "index(sub(", + l_begin_gidx, ",", l_begin_gidx + block_size, ", a ))"); + + auto g_sub_view = dash::sub( + l_begin_gidx, + l_begin_gidx + block_size, + array ); + + auto g_sub_index = dash::index( + dash::sub( + l_begin_gidx, + l_begin_gidx + block_size, + array) ); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + *g_sub_index.begin()); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + *g_sub_index.end()); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + range_str(g_sub_view)); + + EXPECT_EQ_U(block_size, g_sub_view.size()); + EXPECT_EQ_U(block_size, g_sub_view.end() - g_sub_view.begin()); + + EXPECT_EQ_U(block_size, g_sub_index.size()); + EXPECT_EQ_U(block_size, g_sub_index.end() - g_sub_index.begin()); + EXPECT_EQ_U(l_begin_gidx, *g_sub_index.begin()); + EXPECT_EQ_U(l_begin_gidx + block_size, *g_sub_index.end()); + + DASH_LOG_DEBUG("ViewTest.ArrayBlockedPatternLocalView", + "index(local(sub(", + l_begin_gidx, ",", l_begin_gidx + block_size, ", a )))"); + + auto l_sub_view = dash::local( + dash::sub( + l_begin_gidx, + l_begin_gidx + block_size, + array) ); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + range_str(l_sub_view)); + + auto l_sub_index = dash::index( + dash::local( + dash::sub( + l_begin_gidx, + l_begin_gidx + block_size, + array) ) ); + EXPECT_EQ_U(block_size, l_sub_view.size()); + EXPECT_EQ_U(block_size, l_sub_index.size()); + EXPECT_EQ_U(block_size, array.lsize()); + + EXPECT_TRUE_U( + std::equal(array.local.begin(), + array.local.end(), + l_sub_view.begin())); + + auto l_idx_set_begin = *dash::begin(l_sub_index); + auto l_idx_set_end = *dash::end(l_sub_index); + + EXPECT_EQ(0, l_idx_set_begin); + EXPECT_EQ(0 + block_size, l_idx_set_end); + + // Use case: + // + // array [ ... | 0 1 2 3 4 5 6 7 8 9 | ... ] + // : | | : + // sub : '---------' : + // | : : | + // local '---------------------' + // | | + // '----.----' + // | + // local(sub(array)) + // + { + DASH_LOG_DEBUG("ViewTest.ArrayBlockedPatternLocalView", + "--------- inner ---------"); + int sub_begin_gidx = lblock_begin_gidx + 2; + int sub_end_gidx = lblock_end_gidx - 2; + + // View to global index range of local block: + auto sub_lblock = dash::sub(sub_begin_gidx, + sub_end_gidx, + array); + + static_assert( + !dash::view_traits::is_local::value, + "sub(range) expected have type trait local = false"); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + range_str(sub_lblock)); + + EXPECT_EQ(block_size - 4, sub_lblock.size()); + EXPECT_EQ(sub_lblock.size(), + dash::end(sub_lblock) - dash::begin(sub_lblock)); + + auto l_sub_lblock = dash::local(sub_lblock); + + static_assert( + dash::view_traits::is_local::value, + "local(sub(range)) expected have type trait local = true"); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + range_str(l_sub_lblock)); + + EXPECT_EQ(sub_lblock.size(), l_sub_lblock.size()); + EXPECT_EQ(l_sub_lblock.size(), + dash::end(l_sub_lblock) - dash::begin(l_sub_lblock)); + + EXPECT_EQ(array.pattern().at( + dash::index(sub_lblock)[0]), + dash::index(l_sub_lblock)[0]); + EXPECT_EQ(dash::index(sub_lblock).size(), + dash::index(l_sub_lblock).size()); + + for (int lsi = 0; lsi != sub_lblock.size(); lsi++) { + auto sub_elem = sub_lblock[lsi]; + auto l_sub_elem = l_sub_lblock[lsi]; + EXPECT_EQ(sub_elem, l_sub_elem); + } + + auto sub_l_sub_lblock = dash::sub( + 1, l_sub_lblock.size() - 2, + l_sub_lblock); + + static_assert( + dash::view_traits::is_local::value, + "sub(local(sub(range))) expected have type trait local = true"); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + range_str(sub_l_sub_lblock)); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + l_sub_lblock.size()); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + sub_l_sub_lblock.size()); + + EXPECT_EQ(sub_l_sub_lblock.size(), l_sub_lblock.size() - 1 - 2); + EXPECT_EQ( + sub_l_sub_lblock.size(), + dash::end(sub_l_sub_lblock) - dash::begin(sub_l_sub_lblock)); + + for (int slsi = 0; slsi < sub_l_sub_lblock.size(); slsi++) { + auto sub_l_sub_elem = sub_l_sub_lblock[slsi]; + auto l_sub_elem = l_sub_lblock[slsi+1]; + EXPECT_EQ(l_sub_elem, sub_l_sub_elem); + } + } + { + DASH_LOG_DEBUG("ViewTest.ArrayBlockedPatternLocalView", + "------- local inner -----"); + + auto sub_local_view = dash::sub( + 2, array.lsize() - 1, + dash::local( + array)); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + range_str(sub_local_view)); + + EXPECT_EQ_U(array.lsize() - 2 - 1, + sub_local_view.size()); + + EXPECT_TRUE_U( + std::equal(array.lbegin() + 2, + array.lbegin() + array.lsize() - 1, + sub_local_view.begin())); + } + // Use case: + // + // array [ .. | 0 1 2 3 4 5 6 7 8 9 | ... ] + // | : : | + // sub '---------------------' + // : : + // local '---------' + // | | + // '----.----' + // | + // local(sub(array)) + // + { + DASH_LOG_DEBUG("ViewTest.ArrayBlockedPatternLocalView", + "--------- outer ---------"); + int sub_begin_gidx = lblock_begin_gidx; + int sub_end_gidx = lblock_end_gidx; + + if (dash::myid() > 0) { + sub_begin_gidx -= 2; + } + if (dash::myid() < dash::size() - 1) { + sub_end_gidx += 3; + } + + // View to global index range of local block: + auto sub_block = dash::sub(sub_begin_gidx, + sub_end_gidx, + array); + static_assert( + !dash::view_traits::is_local::value, + "sub(range) expected have type trait local = false"); + + EXPECT_EQ_U(sub_end_gidx - sub_begin_gidx, sub_block.size()); + EXPECT_EQ_U(sub_block.size(), + dash::end(sub_block) - dash::begin(sub_block)); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + range_str(sub_block)); + + EXPECT_TRUE_U( + std::equal(array.begin() + sub_begin_gidx, + array.begin() + sub_end_gidx, + sub_block.begin())); + + auto l_sub_block = dash::local(sub_block); + auto l_sub_block_index = dash::index(dash::local(sub_block)); + + static_assert( + dash::view_traits::is_local::value, + "local(sub(range)) expected have type trait local = true"); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + range_str(l_sub_block)); + + int exp_l_sub_block_size = array.lsize(); + + EXPECT_EQ_U(l_sub_block_index.size(), l_sub_block.size()); + // EXPECT_EQ_U(exp_l_sub_block_size, l_sub_block.size()); + EXPECT_EQ_U(l_sub_block.size(), + dash::distance(l_sub_block.begin(), l_sub_block.end())); + + EXPECT_TRUE_U( + std::equal(array.local.begin(), array.local.end(), + l_sub_block.begin())); + + // Applying dash::local twice without interleaving dash::global + // expected to have no effect: + auto sub_l_sub_block = dash::sub(1,4, dash::local(l_sub_block)); + + static_assert( + dash::view_traits::is_local::value, + "sub(local(sub(range))) expected have type trait local = true"); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockedPatternLocalView", + range_str(sub_l_sub_block)); + + EXPECT_EQ_U(3, sub_l_sub_block.size()); + EXPECT_EQ_U(sub_l_sub_block.size(), + dash::end(sub_l_sub_block) - dash::begin(sub_l_sub_block)); + + EXPECT_TRUE_U( + std::equal(array.local.begin() + 1, + array.local.begin() + 4, + sub_l_sub_block.begin())); + } +} + +TEST_F(ViewTest, ArrayBlockCyclicPatternLocalView) +{ + int block_size = 3; + int nblocks_per_unit = 2; + int array_size = dash::size() * block_size * nblocks_per_unit; + + dash::Array array(array_size, dash::BLOCKCYCLIC(block_size)); + + for (auto li = 0; li != array.local.size(); ++li) { + array.local[li] = (100 * (dash::myid() + 1)) + + (li) + + ((dash::myid() * nblocks_per_unit * block_size) + + li) * + 0.01; + } + + array.barrier(); + + int sub_begin_gidx = 2; + int sub_end_gidx = array.size() - 2; + + auto sub_range = dash::sub(sub_begin_gidx, + sub_end_gidx, + array); + + if (dash::myid() == 0) { + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalView", + range_str(sub_range)); + + EXPECT_EQ_U(sub_end_gidx - sub_begin_gidx, + sub_range.size()); + EXPECT_EQ_U(sub_range.size(), + dash::distance(sub_range.begin(), sub_range.end())); + EXPECT_TRUE(std::equal(array.begin() + sub_begin_gidx, + array.begin() + sub_end_gidx, + sub_range.begin())); + } + array.barrier(); + + for (int si = 0; si != sub_range.size(); si++) { + double sub_elem = sub_range[si]; + double arr_elem = array[si + sub_begin_gidx]; + EXPECT_EQ(arr_elem, sub_elem); + } + + auto lsub_range = dash::local(sub_range); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalView", + lsub_range.size()); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalView", + dash::index(lsub_range).size()); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalView", + *dash::begin(dash::index(lsub_range))); + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalView", + *dash::end(dash::index(lsub_range))); + + DASH_LOG_DEBUG_VAR("ViewTest.ArrayBlockCyclicPatternLocalView", + range_str(lsub_range)); + + int lsi = 0; + for (int si = 0; si != sub_range.size(); si++) { + auto git = (sub_range.begin() + si); + double * lp = git.local(); + if (lp != nullptr) { + double lsub_elem = *lp; + double arr_elem = array[si + sub_begin_gidx]; + EXPECT_EQ(arr_elem, lsub_elem); + lsi++; + } + } +} + +/* +TEST_F(ViewTest, ArrayBlockedPatternViewUnion) +{ + int block_size = 37; + int array_size = dash::size() * block_size; + + int block_a_begin_gidx = (block_size / 2) * (dash::myid() + 0); + int block_a_end_gidx = (block_size / 2) * (dash::myid() + 1); + int block_b_begin_gidx = (block_size / 2) * (dash::myid() + 1); + int block_b_end_gidx = (block_size / 2) * (dash::myid() + 2); + + dash::Array a(array_size); + + auto block_a_gview = dash::sub(block_a_begin_gidx, + block_a_end_gidx, + a); + auto block_b_gview = dash::sub(block_b_begin_gidx, + block_b_end_gidx, + a); + auto block_views_union = dash::set_union({ + block_a_gview, + block_b_gview + }); +} +*/ diff --git a/dash/test/ViewTest.h b/dash/test/view/ViewTest.h similarity index 89% rename from dash/test/ViewTest.h rename to dash/test/view/ViewTest.h index cca5a7d10..19d30cf11 100644 --- a/dash/test/ViewTest.h +++ b/dash/test/view/ViewTest.h @@ -1,7 +1,7 @@ #ifndef DASH__TEST__VIEW_TEST_H_ #define DASH__TEST__VIEW_TEST_H_ -#include "TestBase.h" +#include "../TestBase.h" /** * Test fixture for the DASH View concept