Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion dash/include/dash/GlobAsyncRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,12 @@ class GlobAsyncRef
typename ElementT >
friend class GlobAsyncRef;

private:
public:
typedef GlobAsyncRef<T>
self_t;

typedef T value_type;

typedef typename std::remove_const<T>::type
nonconst_value_type;

Expand Down Expand Up @@ -279,6 +281,15 @@ class GlobAsyncRef
return this->_gptr;
}

/**
* Disallow implicit comparison with other global references.
*/
template <class ValueT>
bool operator==(const GlobAsyncRef<ValueT> & other) = delete;

template <class ValueT>
bool operator!=(const GlobAsyncRef<ValueT> & other) = delete;

/**
* Flush all pending asynchronous operations on this asynchronous reference.
*/
Expand Down
17 changes: 15 additions & 2 deletions dash/include/dash/GlobRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,25 @@ class GlobRef
return t;
}

constexpr bool operator==(const_value_type & value) const
template <typename ValueT>
bool operator==(const GlobRef<ValueT> & other) const {
ValueT val = other.get();
return operator==(val);
}

template <typename ValueT>
bool operator!=(const GlobRef<ValueT> & other) const {
return !(*this == other);
}

template<typename ValueT>
constexpr bool operator==(const ValueT& value) const
{
return static_cast<T>(*this) == value;
}

constexpr bool operator!=(const_value_type & value) const
template<typename ValueT>
constexpr bool operator!=(const ValueT& value) const
{
return !(*this == value);
}
Expand Down
19 changes: 3 additions & 16 deletions dash/include/dash/atomic/GlobAtomicRef.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ template<typename T>
class Shared;

/**
* Specialization for atomic values. All atomic operations are
* Specialization for atomic values. All atomic operations are
* \c const as the \c GlobRef does not own the atomic values.
*/
template<typename T>
Expand Down Expand Up @@ -102,19 +102,6 @@ class GlobRef<dash::Atomic<T>>

self_t & operator=(const self_t & other) = delete;

inline bool operator==(const self_t & other) const noexcept
{
return _gptr == other._gptr;
}

inline bool operator!=(const self_t & other) const noexcept
{
return !(*this == other);
}

inline bool operator==(const T & value) const = delete;
inline bool operator!=(const T & value) const = delete;

operator T() const {
return load();
}
Expand Down Expand Up @@ -256,9 +243,9 @@ class GlobRef<dash::Atomic<T>>
/**
* Atomically compares the value with the value of expected and if thosei
* are bitwise-equal, replaces the former with desired.
*
*
* \return True if value is exchanged
*
*
* \see \c dash::atomic::compare_exchange
*/
bool compare_exchange(const T & expected, const T & desired) const {
Expand Down
14 changes: 13 additions & 1 deletion dash/test/container/ArrayTest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,6 @@ TEST_F(ArrayTest, MoveSemantics){
}
}


TEST_F(ArrayTest, ElementCompare){
using value_t = int;
using array_t = dash::Array<value_t>;
Expand All @@ -285,6 +284,19 @@ TEST_F(ArrayTest, ElementCompare){
array_t arr(dash::size());

dash::fill(arr.begin(), arr.end(), 0);
arr.barrier();

ASSERT_EQ_U(arr[0], arr[1]);

ASSERT_EQ_U(0, arr[dash::myid()]);
ASSERT_EQ_U(arr[dash::myid()], 0);
ASSERT_EQ_U(arr[dash::myid()], 0UL);

dash::barrier();
arr[dash::myid()] = dash::myid();
ASSERT_EQ_U(dash::myid(), arr[dash::myid()]);
dash::barrier();
if (dash::myid() > 0) {
ASSERT_NE_U(arr[0], arr[dash::myid()]);
}
}
62 changes: 42 additions & 20 deletions dash/test/types/AtomicTest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ TEST_F(AtomicTest, AlgorithmVariant){
for(int i=0; i<dash::size(); ++i){
dash::atomic::add(array[i], i+1);
}

dash::barrier();

for(int i=0; i<dash::size(); ++i){
Expand All @@ -354,7 +354,7 @@ TEST_F(AtomicTest, AtomicInContainer){
array[i].add(i+1);
matrix[i].add(i+1);
}

dash::barrier();

LOG_MESSAGE("Trivial Type: is_atomic_type %d",
Expand Down Expand Up @@ -386,26 +386,26 @@ TEST_F(AtomicTest, AtomicInterface){
array[1]++;
--(array[2]);
array[3]--;

dash::barrier();
ASSERT_EQ_U(array[0].load(), dash::size());
ASSERT_EQ_U(array[1].load(), dash::size());
ASSERT_EQ_U(array[2].load(), -dash::size());
ASSERT_EQ_U(array[3].load(), -dash::size());

dash::barrier();

if(dash::myid() == 0){
auto oldval = array[3].exchange(1);
ASSERT_EQ_U(oldval, -dash::size());
}
dash::barrier();
ASSERT_EQ_U(array[3].load(), 1);
dash::barrier();

value_t myid = static_cast<value_t>(dash::myid().id);
value_t id_right = (myid + 1) % dash::size();

array[myid].store(myid);
array.barrier();
ASSERT_EQ_U(id_right, array[id_right].load());
Expand All @@ -430,48 +430,48 @@ TEST_F(AtomicTest, AtomicInterface){

TEST_F(AtomicTest, MutexInterface){
dash::Mutex mx;

dash::Shared<int> shared(dash::team_unit_t{0});

if(dash::myid() == 0){
shared.set(0);
}

mx.lock();
int tmp = shared.get();
std::this_thread::sleep_for(std::chrono::microseconds(100));
shared.set(tmp + 1);
LOG_MESSAGE("Before %d, after %d", tmp, static_cast<int>(shared.get()));
// I guess here a flush is required, blocked by issue 322
mx.unlock();

dash::barrier();

while(!mx.try_lock()){ }
// lock aquired
tmp = shared.get();
std::this_thread::sleep_for(std::chrono::microseconds(100));
shared.set(tmp + 1);
mx.unlock();

dash::barrier();

if(dash::myid() == 0){
int result = shared.get();
EXPECT_EQ_U(result, static_cast<int>(dash::size()*2));
}

dash::barrier();

// this even works with std::lock_guard
{
std::lock_guard<dash::Mutex> lg(mx);
int tmp = shared.get();
shared.set(tmp + 1);
}

dash::barrier();

if(dash::myid() == 0){
int result = shared.get();
EXPECT_EQ_U(result, static_cast<int>(dash::size())*3);
Expand All @@ -491,8 +491,6 @@ TEST_F(AtomicTest, AtomicSignal){
array_t array(dash::size());
dash::fill(array.begin(), array.end(), 0);

int neighbor = (dash::myid() + 1) % dash::size();

if (dash::myid() != 0) {
// send the signal
array[0].add(1);
Expand All @@ -507,3 +505,27 @@ TEST_F(AtomicTest, AtomicSignal){
ASSERT_GT_U(count, 0);
}
}

TEST_F(AtomicTest, ElementCompare){
using value_t = int;
using atom_t = dash::Atomic<value_t>;
using array_t = dash::Array<atom_t>;

if (dash::size() < 2) {
SKIP_TEST_MSG("At least 2 units required");
}

array_t array(dash::size());
dash::fill(array.begin(), array.end(), 0);
dash::barrier();

ASSERT_EQ_U(0, array[dash::myid()]);
ASSERT_EQ_U(0UL, array[dash::myid()]);
ASSERT_EQ_U(array[dash::myid()], 0);
ASSERT_EQ_U(array[dash::myid()], 0UL);
// forbidden
//ASSERT_EQ_U(array[0], array[dash::myid()]);

// OK
ASSERT_EQ_U(array[0].get(), array[dash::myid()]);
}