Skip to content

Commit

Permalink
Merge branch 'bug-118-threadsafety' of github.com:dash-project/dash i…
Browse files Browse the repository at this point in the history
…nto bug-118-threadsafety
  • Loading branch information
devreal committed Feb 13, 2017
2 parents 459d416 + 76e59cc commit eba464a
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 52 deletions.
52 changes: 35 additions & 17 deletions dash/include/dash/TeamSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <dash/internal/Logging.h>

#include <array>
#include <set>
#include <algorithm>
#include <sstream>
#include <iostream>
Expand Down Expand Up @@ -218,39 +219,56 @@ class TeamSpec :
DASH_LOG_TRACE_VAR("TeamSpec({extents})", this->_extents);
}

/**
* Tries to equally distribute the units across the dimensions.
* The number of units is determined by the current state of the extents.
*
* \b Example:
*
* \code
* TeamSpec<3> ts({ 21,2,3 }); // extents 21x2x3 == 126 units
* ts.balance_extents(); // extents 7x6x3
* \endcode
*/
void balance_extents()
{
DASH_LOG_TRACE_VAR("TeamSpec.balance_extents()", this->_extents);
DASH_LOG_TRACE_VAR("TeamSpec.balance_extents()", size());
if(MaxDimensions <= 1) {
return;
}

std::multiset<SizeType> new_extents;

SizeType num_units = 1;
for (auto d = 0; d < MaxDimensions; ++d) {
num_units *= this->_extents[d];
this->_extents[d] = 1;
new_extents.insert(1);
}
_is_linear = false;

// Find best surface-to-volume for two-dimensional team:
// Find best surface-to-volume:
auto teamsize_prime_factors = dash::math::factorize(num_units);
SizeType surface = 0;
for (auto it : teamsize_prime_factors) {
DASH_LOG_TRACE("TeamSpec.balance_extents",
"factor:", it.first, "x", it.second);
for (auto i = 1; i < it.second + 1; ++i) {
SizeType extent_x = it.first * this->_extents[0];
SizeType extent_y = num_units / extent_x;
SizeType surface_new = (2 * extent_x) + (2 * extent_y);
DASH_LOG_TRACE("TeamSpec.balance_extents", "Testing extents",
extent_x, "x", extent_y, " - surface:", surface_new);
if (surface == 0 || surface_new < surface) {
surface = surface_new;
this->_extents[0] = extent_x;
this->_extents[1] = extent_y;
}
// 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) {
DASH_LOG_TRACE("TeamSpec.balance_extents()",
"factor:", it->first, "x", it->second);
for (auto i = 1; i < it->second + 1; ++i) {
new_extents.insert(it->first * *new_extents.begin());
new_extents.erase(new_extents.begin());
}
}

int d = 0;
for (auto it = new_extents.rbegin(); it != new_extents.rend(); ++it, ++d) {
this->_extents[d] = *it;
}

this->resize(this->_extents);
update_rank();
DASH_LOG_TRACE_VAR("TeamSpec.balance_extents ->", this->_extents);
DASH_LOG_TRACE_VAR("TeamSpec.balance_extents() ->", this->_extents);
}

/**
Expand Down
57 changes: 26 additions & 31 deletions dash/include/dash/map/UnorderedMapGlobIter.h
Original file line number Diff line number Diff line change
Expand Up @@ -184,12 +184,12 @@ class UnorderedMapGlobIter
return *this;
}

inline bool operator==(std::nullptr_t) const noexcept
constexpr bool operator==(std::nullptr_t) const noexcept
{
return _is_nullptr;
}

inline bool operator!=(std::nullptr_t) const noexcept
constexpr bool operator!=(std::nullptr_t) const noexcept
{
return !_is_nullptr;
}
Expand All @@ -209,7 +209,7 @@ class UnorderedMapGlobIter
*
* \return A global reference to the element at the iterator's position
*/
operator pointer() const
constexpr operator pointer() const
{
return pointer(dart_gptr());
}
Expand All @@ -220,15 +220,12 @@ class UnorderedMapGlobIter
* \return A DART global pointer to the element at the iterator's
* position
*/
dart_gptr_t dart_gptr() const
constexpr dart_gptr_t dart_gptr() const
{
DASH_LOG_TRACE_VAR("UnorderedMapGlobIter.dart_gptr()", _idx);
dart_gptr_t dart_gptr = _map->globmem().at(
_idx_unit_id,
_idx_local_idx)
.dart_gptr();
DASH_LOG_TRACE_VAR("UnorderedMapGlobIter.dart_gptr >", dart_gptr);
return dart_gptr;
return _map->globmem().at(
_idx_unit_id,
_idx_local_idx)
.dart_gptr();
}

/**
Expand Down Expand Up @@ -285,7 +282,7 @@ class UnorderedMapGlobIter
* Checks whether the element referenced by this global iterator is in
* the calling unit's local memory.
*/
inline bool is_local() const noexcept
constexpr bool is_local() const noexcept
{
return (_myid == _idx_unit_id);
}
Expand All @@ -302,7 +299,6 @@ class UnorderedMapGlobIter
return (_map->lbegin() + _idx_local_idx);
}

#if 0
/**
* Conversion to local bucket iterator.
*/
Expand All @@ -314,7 +310,6 @@ class UnorderedMapGlobIter
}
return (_map->lbegin() + _idx_local_idx);
}
#endif

/**
* Unit and local offset at the iterator's position.
Expand All @@ -330,23 +325,23 @@ class UnorderedMapGlobIter
/**
* Map iterator to global index domain.
*/
inline self_t global() const noexcept
constexpr self_t global() const noexcept
{
return *this;
}

/**
* Position of the iterator in global index space.
*/
inline index_type pos() const noexcept
constexpr index_type pos() const noexcept
{
return _idx;
}

/**
* Position of the iterator in global index range.
*/
inline index_type gpos() const noexcept
constexpr index_type gpos() const noexcept
{
return _idx;
}
Expand Down Expand Up @@ -390,14 +385,14 @@ class UnorderedMapGlobIter
}

template<typename K_, typename M_, typename H_, typename P_, typename A_>
inline bool operator==(
constexpr bool operator==(
const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const noexcept
{
return (this == std::addressof(other) || _idx == other._idx);
}

template<typename K_, typename M_, typename H_, typename P_, typename A_>
inline bool operator!=(
constexpr bool operator!=(
const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const noexcept
{
return !(*this == other);
Expand Down Expand Up @@ -429,42 +424,42 @@ class UnorderedMapGlobIter
return res;
}

inline index_type operator+(
const self_t & other) const
constexpr index_type operator+(
const self_t & other) const noexcept
{
return _idx + other._idx;
}

inline index_type operator-(
const self_t & other) const
constexpr index_type operator-(
const self_t & other) const noexcept
{
return _idx - other._idx;
}

template<typename K_, typename M_, typename H_, typename P_, typename A_>
inline bool operator<(
const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const
constexpr bool operator<(
const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const noexcept
{
return (_idx < other._idx);
}

template<typename K_, typename M_, typename H_, typename P_, typename A_>
inline bool operator<=(
const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const
constexpr bool operator<=(
const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const noexcept
{
return (_idx <= other._idx);
}

template<typename K_, typename M_, typename H_, typename P_, typename A_>
inline bool operator>(
const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const
constexpr bool operator>(
const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const noexcept
{
return (_idx > other._idx);
}

template<typename K_, typename M_, typename H_, typename P_, typename A_>
inline bool operator>=(
const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const
constexpr bool operator>=(
const UnorderedMapGlobIter<K_, M_, H_, P_, A_> & other) const noexcept
{
return (_idx >= other._idx);
}
Expand Down
4 changes: 2 additions & 2 deletions dash/scripts/docker-testing/openmpi2/dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ RUN cd papi*/src/ \
&& make install

# Openmpi 2.0
ADD https://www.open-mpi.org/software/ompi/v2.0/downloads/openmpi-2.0.1.tar.gz ompi.tgz
ADD https://www.open-mpi.org/software/ompi/v2.0/downloads/openmpi-2.0.2.tar.gz ompi.tgz
RUN tar -xf ompi.tgz
RUN cd openmpi* \
&& ./configure --prefix=/opt/openmpi \
Expand All @@ -53,7 +53,7 @@ ENV LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${PAPI_BASE}/lib:${HDF5_BASE}/l
ENV MPI_EXEC_FLAGS='--allow-run-as-root'
ENV VERBOSE_CI='true'
# Workaround for issue #63
ENV GTEST_FILTER="-SharedTest.AtomicAdd:TransformTest.Array*"
#ENV GTEST_FILTER="-SharedTest.AtomicAdd:TransformTest.Array*"

# Set workdir to dash home
WORKDIR /opt/dash
4 changes: 2 additions & 2 deletions dash/scripts/docker-testing/openmpi2_vg/dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ FROM ubuntu:latest

MAINTAINER The DASH Team <[email protected]>

RUN apt-get update -y
RUN apt-get update -y --fix-missing
RUN apt-get install -y \
git \
build-essential \
Expand All @@ -30,7 +30,7 @@ ENV VALGRIND_BASE=/opt/valgrind
ENV PATH=${PATH}:${VALGRIND_BASE}/bin

# Openmpi 2.0
ADD https://www.open-mpi.org/software/ompi/v2.0/downloads/openmpi-2.0.1.tar.gz ompi.tgz
ADD https://www.open-mpi.org/software/ompi/v2.0/downloads/openmpi-2.0.2.tar.gz ompi.tgz
RUN tar -xf ompi.tgz
RUN cd openmpi* \
&& ./configure --prefix=/opt/openmpi \
Expand Down
37 changes: 37 additions & 0 deletions dash/test/TeamSpecTest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,40 @@ TEST_F(TeamSpecTest, Ranks)
ASSERT_EQ(dash::size(), teamspec.size());

}

TEST_F(TeamSpecTest, BalanceExtents)
{
DASH_TEST_LOCAL_ONLY();

dash::TeamSpec<1> ts_1d(dash::Team::All());
ASSERT_EQ(dash::size(), ts_1d.num_units(0));
ts_1d.balance_extents();
ASSERT_EQ(dash::size(), ts_1d.num_units(0));

std::array<long unsigned int, 2> extents_2d{ 12*12, 1 };
dash::TeamSpec<2> ts_2d(extents_2d);
ts_2d.balance_extents();
ASSERT_EQ(2, ts_2d.rank());
ASSERT_EQ(12, ts_2d.num_units(0));
ASSERT_EQ(12, ts_2d.num_units(1));
ASSERT_EQ(144, ts_2d.size());

std::array<long unsigned int, 3> extents_3d_ideal{ 3*3*3, 1, 1 };
dash::TeamSpec<3> ts_3d_ideal(extents_3d_ideal);
ts_3d_ideal.balance_extents();
ASSERT_EQ(3, ts_3d_ideal.rank());
ASSERT_EQ(3, ts_3d_ideal.num_units(0));
ASSERT_EQ(3, ts_3d_ideal.num_units(1));
ASSERT_EQ(3, ts_3d_ideal.num_units(2));
ASSERT_EQ(27, ts_3d_ideal.size());

std::array<long unsigned int, 3> extents_3d{ 12, 5, 7 };
dash::TeamSpec<3> ts_3d(extents_3d);
ts_3d.balance_extents();
// The extents [10,7,6] should be minimal
ASSERT_EQ(3, ts_3d.rank());
ASSERT_GE(10, ts_3d.num_units(0));
ASSERT_GE(10, ts_3d.num_units(1));
ASSERT_GE(10, ts_3d.num_units(2));
ASSERT_EQ(12*5*7, ts_3d.size());
}

0 comments on commit eba464a

Please sign in to comment.