diff --git a/circle.yml b/circle.yml index df5ac695f..a9ac258ac 100644 --- a/circle.yml +++ b/circle.yml @@ -21,6 +21,8 @@ test: parallel: true - bash ./dash/scripts/circleci/run-docker.sh Minimal: parallel: true + - bash ./dash/scripts/circleci/run-docker.sh Nasty: + parallel: true - grep "FAIL" ./dash-ci.log && (echo "Full log:" ; cat ./dash-ci.log ; exit 1) || exit 0: parallel: true post: diff --git a/dart-impl/mpi/src/dart_communication.c b/dart-impl/mpi/src/dart_communication.c index e12d94751..1f3503a40 100644 --- a/dart-impl/mpi/src/dart_communication.c +++ b/dart-impl/mpi/src/dart_communication.c @@ -741,7 +741,8 @@ dart_ret_t dart_put_blocking( baseptr = dart_sharedmem_local_baseptr_set[i]; } baseptr += offset; - DART_LOG_DEBUG("dart_put_blocking: memcpy %zu bytes", nelem * dart_mpi_sizeof_datatype(dtype)); + DART_LOG_DEBUG("dart_put_blocking: memcpy %zu bytes", + nelem * dart_mpi_sizeof_datatype(dtype)); memcpy(baseptr, (char*)src, nelem * dart_mpi_sizeof_datatype(dtype)); return DART_OK; } @@ -784,13 +785,13 @@ dart_ret_t dart_put_blocking( */ DART_LOG_DEBUG("dart_put_blocking: MPI_Put"); if (MPI_Put(src, - nelem, - mpi_dtype, - target_unitid_rel, - disp_rel, - nelem, - mpi_dtype, - win) + nelem, + mpi_dtype, + target_unitid_rel, + disp_rel, + nelem, + mpi_dtype, + win) != MPI_SUCCESS) { DART_LOG_ERROR("dart_put_blocking ! MPI_Put failed"); return DART_ERR_INVAL; diff --git a/dart-impl/mpi/src/dart_initialization.c b/dart-impl/mpi/src/dart_initialization.c index 206eebfc9..d49393c5e 100644 --- a/dart-impl/mpi/src/dart_initialization.c +++ b/dart-impl/mpi/src/dart_initialization.c @@ -283,7 +283,8 @@ dart_ret_t dart_exit() DART_LOG_DEBUG("%2d: dart_exit()", unitid); if (dart_adapt_teamlist_convert(DART_TEAM_ALL, &index) == -1) { - DART_LOG_ERROR("%2d: dart_exit: dart_adapt_teamlist_convert failed", unitid); + DART_LOG_ERROR("%2d: dart_exit: dart_adapt_teamlist_convert failed", + unitid); return DART_ERR_OTHER; } @@ -302,12 +303,17 @@ dart_ret_t dart_exit() /* -- Free up all the resources for dart programme -- */ MPI_Win_free(&dart_win_local_alloc); #if !defined(DART_MPI_DISABLE_SHARED_WINDOWS) + /* Has MPI shared windows: */ MPI_Win_free(&dart_sharedmem_win_local_alloc); MPI_Comm_free(&(team_data->sharedmem_comm)); +#else + /* No MPI shared windows: */ + if (dart_mempool_localalloc) { + MPI_Free_mem(dart_mempool_localalloc); + } #endif MPI_Win_free(&team_data->window); - dart_buddy_delete(dart_localpool); #if !defined(DART_MPI_DISABLE_SHARED_WINDOWS) free(team_data->sharedmem_tab); diff --git a/dash/include/dash/Array.h b/dash/include/dash/Array.h index 2c8fbbe2e..260d9a5b4 100644 --- a/dash/include/dash/Array.h +++ b/dash/include/dash/Array.h @@ -772,6 +772,32 @@ class Array allocate(m_pattern); } + /** + * Copy constructor is deleted to prevent unintentional copies of - usually + * huge - distributed arrays. + * + * To create a copy of a \c dash::Array instance, instantiate the copy + * instance explicitly and use \c dash::copy to clone elements. + * + * Example: + * + * \code + * dash::Array a1(1024 * dash::size()); + * dash::fill(a1.begin(), a1.end(), 123); + * + * // create copy of array a1: + * dash::Array a2(a1.size()); + * dash::copy(a1.begin(), a1.end(), a2.begin()); + * \endcode + */ + Array(const self_t & other) = delete; + + /** + * Move constructor is deleted as move semantics are non-trivial for + * distributed arrays. + */ + Array(self_t && other) = delete; + /** * Destructor, deallocates array elements. */ @@ -782,6 +808,32 @@ class Array DASH_LOG_TRACE_VAR("Array.~Array >", this); } + /** + * Move assignment operator is deleted as move semantics are non-trivial + * for distributed arrays. + */ + self_t & operator=(self_t && other) = delete; + + /** + * Assignment operator is deleted to prevent unintentional copies of + * - usually huge - distributed arrays. + * + * To create a copy of a \c dash::Array instance, instantiate the copy + * instance explicitly and use \c dash::copy to clone elements. + * + * Example: + * + * \code + * dash::Array a1(1024 * dash::size()); + * dash::fill(a1.begin(), a1.end(), 123); + * + * // create copy of array a1: + * dash::Array a2(a1.size()); + * dash::copy(a1.begin(), a1.end(), a2.begin()); + * \endcode + */ + self_t & operator=(const self_t & rhs) = delete; + /** * View at block at given global block offset. */ @@ -1014,7 +1066,12 @@ class Array void barrier() const { DASH_LOG_TRACE_VAR("Array.barrier()", m_team); - m_team->barrier(); + if (nullptr != m_globmem) { + m_globmem->flush_all(); + } + if (nullptr != m_team && *m_team != dash::Team::Null()) { + m_team->barrier(); + } DASH_LOG_TRACE("Array.barrier >", "passed barrier"); } @@ -1106,7 +1163,7 @@ class Array } // Remove this function from team deallocator list to avoid // double-free: - m_pattern.team().unregister_deallocator( + m_team->unregister_deallocator( this, std::bind(&Array::deallocate, this)); // Actual destruction of the array instance: DASH_LOG_TRACE_VAR("Array.deallocate()", m_globmem); @@ -1139,7 +1196,7 @@ class Array // Allocate local memory of identical size on every unit: DASH_LOG_TRACE_VAR("Array._allocate", m_lcapacity); DASH_LOG_TRACE_VAR("Array._allocate", m_lsize); - m_globmem = new glob_mem_type(m_lcapacity, m_pattern.team()); + m_globmem = new glob_mem_type(m_lcapacity, *m_team); // Global iterators: m_begin = iterator(m_globmem, m_pattern); m_end = iterator(m_begin) + m_size; @@ -1199,7 +1256,7 @@ class Array // Allocate local memory of identical size on every unit: DASH_LOG_TRACE_VAR("Array._allocate", m_lcapacity); DASH_LOG_TRACE_VAR("Array._allocate", m_lsize); - m_globmem = new glob_mem_type(local_elements, pattern.team()); + m_globmem = new glob_mem_type(local_elements, *m_team); // Global iterators: m_begin = iterator(m_globmem, pattern); m_end = iterator(m_begin) + m_size; @@ -1213,7 +1270,7 @@ class Array DASH_LOG_TRACE_VAR("Array._allocate", m_lsize); // Register deallocator of this array instance at the team // instance that has been used to initialized it: - pattern.team().register_deallocator( + m_team->register_deallocator( this, std::bind(&Array::deallocate, this)); // Assure all units are synchronized after allocation, otherwise // other units might start working on the array before allocation @@ -1235,7 +1292,7 @@ class Array /// Element distribution pattern PatternType m_pattern; /// Global memory allocation and -access - glob_mem_type * m_globmem; + glob_mem_type * m_globmem = nullptr; /// Iterator to initial element in the array iterator m_begin; /// Iterator to final element in the array @@ -1247,9 +1304,9 @@ class Array /// Number allocated local elements in the array size_type m_lcapacity; /// Native pointer to first local element in the array - ElementType * m_lbegin; + ElementType * m_lbegin = nullptr; /// Native pointer past last local element in the array - ElementType * m_lend; + ElementType * m_lend = nullptr; }; diff --git a/dash/include/dash/allocator/CollectiveAllocator.h b/dash/include/dash/allocator/CollectiveAllocator.h index 701a9b1f4..20c92d34b 100644 --- a/dash/include/dash/allocator/CollectiveAllocator.h +++ b/dash/include/dash/allocator/CollectiveAllocator.h @@ -171,6 +171,9 @@ class CollectiveAllocator * Allocates \c num_local_elem local elements at every unit in global * memory space. * + * \return Global pointer to allocated memory range, or \c DART_GPTR_NULL + * if \c num_local_elem is 0 or less. + * * \see DashAllocatorConcept */ pointer allocate(size_type num_local_elem) diff --git a/dash/scripts/circleci/run-docker.sh b/dash/scripts/circleci/run-docker.sh index 68f466040..5e08f8f23 100644 --- a/dash/scripts/circleci/run-docker.sh +++ b/dash/scripts/circleci/run-docker.sh @@ -1,6 +1,6 @@ #!/bin/bash -MPIENVS=(mpich openmpi openmpi2) +MPIENVS=(mpich openmpi) BUILD_CONFIG=$1 DASH_ENV_EXPORTS="export DASH_MAKE_PROCS='4'; export DASH_MAX_UNITS='3'; export DASH_BUILDEX='OFF';" diff --git a/dash/scripts/dash-ci-deploy.sh b/dash/scripts/dash-ci-deploy.sh index ecfe762a2..e03266b2e 100755 --- a/dash/scripts/dash-ci-deploy.sh +++ b/dash/scripts/dash-ci-deploy.sh @@ -138,7 +138,7 @@ elif [ "$BUILD_TYPE" = "Minimal" ]; then -DENABLE_COMPILER_WARNINGS=ON \ -DENABLE_LT_OPTIMIZATION=OFF \ -DENABLE_ASSERTIONS=OFF \ - -DENABLE_SHARED_WINDOWS=ON \ + -DENABLE_SHARED_WINDOWS=OFF \ -DENABLE_UNIFIED_MEMORY_MODEL=ON \ -DENABLE_DEFAULT_INDEX_TYPE_LONG=OFF \ -DENABLE_LOGGING=OFF \ @@ -166,7 +166,7 @@ elif [ "$BUILD_TYPE" = "Nasty" ]; then -DINSTALL_PREFIX=$INSTALL_PATH \ -DDART_IMPLEMENTATIONS=mpi \ -DENABLE_ASSERTIONS=OFF \ - -DENABLE_SHARED_WINDOWS=ON \ + -DENABLE_SHARED_WINDOWS=OFF \ -DENABLE_UNIFIED_MEMORY_MODEL=ON \ -DENABLE_DEFAULT_INDEX_TYPE_LONG=ON \ -DENABLE_LOGGING=OFF \ diff --git a/dash/test/AccumulateTest.h b/dash/test/AccumulateTest.h index e051f98af..9e4b10c6b 100644 --- a/dash/test/AccumulateTest.h +++ b/dash/test/AccumulateTest.h @@ -3,11 +3,12 @@ #include #include +#include "TestBase.h" /** * Test fixture for class dash::accumulate */ -class AccumulateTest : public ::testing::Test { +class AccumulateTest : public dash::test::TestBase { protected: size_t _dash_id; size_t _dash_size; @@ -23,18 +24,13 @@ class AccumulateTest : public ::testing::Test { } virtual void SetUp() { - dash::init(&TESTENV.argc, &TESTENV.argv); + dash::test::TestBase::SetUp(); _dash_id = dash::myid(); _dash_size = dash::size(); - LOG_MESSAGE("===> Running test case with %d units ...", - _dash_size); } virtual void TearDown() { - dash::Team::All().barrier(); - LOG_MESSAGE("<=== Finished test case with %d units", - _dash_size); - dash::finalize(); + dash::test::TestBase::TearDown(); } }; diff --git a/dash/test/ArrayLargeStructTest.h b/dash/test/ArrayLargeStructTest.h index aecb366b3..035225c3b 100644 --- a/dash/test/ArrayLargeStructTest.h +++ b/dash/test/ArrayLargeStructTest.h @@ -23,7 +23,7 @@ typedef struct DGNode_s { /** * Test fixture for class dash::Array */ -class ArrayLargeStruct : public ::testing::Test { +class ArrayLargeStruct : public dash::test::TestBase { protected: size_t _dash_id; size_t _dash_size; @@ -39,18 +39,13 @@ class ArrayLargeStruct : public ::testing::Test { } virtual void SetUp() { - dash::init(&TESTENV.argc, &TESTENV.argv); + dash::test::TestBase::SetUp(); _dash_id = dash::myid(); _dash_size = dash::size(); - LOG_MESSAGE("===> Running test case with %d units ...", - _dash_size); } virtual void TearDown() { - dash::Team::All().barrier(); - LOG_MESSAGE("<=== Finished test case with %d units", - _dash_size); - dash::finalize(); + dash::test::TestBase::TearDown(); } }; diff --git a/dash/test/ArrayTest.cc b/dash/test/ArrayTest.cc index d2eedc248..809a65d33 100644 --- a/dash/test/ArrayTest.cc +++ b/dash/test/ArrayTest.cc @@ -1,12 +1,30 @@ #include #include + #include "TestBase.h" #include "ArrayTest.h" + // global var dash::Array array_global; -TEST_F(ArrayTest, Allocation) +TEST_F(ArrayTest, Declaration) +{ + dash::Array array_local(19 * dash::size(), dash::BLOCKED); +} + +TEST_F(ArrayTest, AllocateEmptyLocal) +{ + if (dash::size() < 2) { + SKIP_TEST_MSG("requires at least 2 units"); + } + + int block_size = 19; + dash::Array array_local(block_size * (dash::size() - 1), + dash::BLOCKCYCLIC(block_size)); +} + +TEST_F(ArrayTest, DelayedAllocation) { dash::Array array_local; @@ -52,7 +70,8 @@ TEST_F(ArrayTest, SingleWriteMultipleRead) ASSERT_EQ(array_size, arr6.size()); // Fill arrays with incrementing values if (_dash_id == 0) { - LOG_MESSAGE("Assigning array values"); + DASH_LOG_DEBUG("ArrayTest.SingleWriteMultipleRead", + "writing array values"); for (size_t i = 0; i < array_size; ++i) { arr1[i] = i; arr2[i] = i; @@ -63,6 +82,8 @@ TEST_F(ArrayTest, SingleWriteMultipleRead) } } // Units waiting for value initialization + DASH_LOG_DEBUG("ArrayTest.SingleWriteMultipleRead", + "waiting for unit 0 to write array values"); dash::Team::All().barrier(); // Read and assert values in arrays for (size_t i = 0; i < array_size; ++i) { @@ -141,9 +162,15 @@ TEST_F(ArrayTest, PatternAllocate) dash::TeamSpec<1>(), dash::Team::All()); + DASH_LOG_DEBUG("ArrayTest.PatternAllocate", + "allocating array from pattern"); array.allocate(pattern); + DASH_LOG_DEBUG("ArrayTest.PatternAllocate", + "array pattern leaving scope"); } + DASH_LOG_DEBUG("ArrayTest.PatternAllocate", + "filling array"); // Fill dash::for_each_with_index( array.begin(), @@ -182,10 +209,11 @@ TEST_F(ArrayTest, TeamSplit) } auto & myteam = team_all.split(2); - auto array_a = dash::Array(ext_x, myteam); + dash::Array array_a(ext_x, myteam); array_a.barrier(); // Check if array is allocated ASSERT_NE_U(array_a.lbegin(), nullptr); team_all.barrier(); } + diff --git a/dash/test/ArrayTest.h b/dash/test/ArrayTest.h index 38bdab783..2518f8ad7 100644 --- a/dash/test/ArrayTest.h +++ b/dash/test/ArrayTest.h @@ -9,7 +9,7 @@ /** * Test fixture for class dash::Array */ -class ArrayTest : public ::testing::Test { +class ArrayTest : public dash::test::TestBase { protected: size_t _dash_id; size_t _dash_size; @@ -27,19 +27,14 @@ class ArrayTest : public ::testing::Test { } virtual void SetUp() { - dash::init(&TESTENV.argc, &TESTENV.argv); + dash::test::TestBase::SetUp(); _dash_id = dash::myid(); _dash_size = dash::size(); _num_elem = 100; - LOG_MESSAGE("===> Running test case with %d units ...", - _dash_size); } virtual void TearDown() { - dash::Team::All().barrier(); - LOG_MESSAGE("<=== Finished test case with %d units", - _dash_size); - dash::finalize(); + dash::test::TestBase::TearDown(); } }; diff --git a/dash/test/AtomicTest.h b/dash/test/AtomicTest.h index 6c10d2c7d..d04a7cba8 100644 --- a/dash/test/AtomicTest.h +++ b/dash/test/AtomicTest.h @@ -9,7 +9,7 @@ /** * Test fixture for class dash::Atomic */ -class AtomicTest : public ::testing::Test { +class AtomicTest : public dash::test::TestBase { protected: size_t _dash_id; size_t _dash_size; @@ -17,8 +17,6 @@ class AtomicTest : public ::testing::Test { AtomicTest() : _dash_id(0), _dash_size(0) { - LOG_MESSAGE(">>> Test suite: AtomicTest"); - LOG_MESSAGE(">>> Hostname: %s PID: %d", _hostname().c_str(), _pid()); } virtual ~AtomicTest() { @@ -26,17 +24,13 @@ class AtomicTest : public ::testing::Test { } virtual void SetUp() { - dash::init(&TESTENV.argc, &TESTENV.argv); + dash::test::TestBase::SetUp(); _dash_id = dash::myid(); _dash_size = dash::size(); - dash::barrier(); - LOG_MESSAGE("===> Running test case with %d units ...", _dash_size); } virtual void TearDown() { - dash::barrier(); - LOG_MESSAGE("<=== Finished test case with %d units", _dash_size); - dash::finalize(); + dash::test::TestBase::TearDown(); } protected: diff --git a/dash/test/CopyTest.cc b/dash/test/CopyTest.cc index f741d1b43..035faee73 100644 --- a/dash/test/CopyTest.cc +++ b/dash/test/CopyTest.cc @@ -358,19 +358,40 @@ TEST_F(CopyTest, BlockingLocalToGlobalBlock) dash::Array array(num_elem_total, dash::BLOCKED); // Local range to copy: int local_range[num_elem_per_unit]; + int target_range[num_elem_per_unit]; // Assign initial values: [ 1000, 1001, 1002, ... 2000, 2001, ... ] for (auto l = 0; l < num_elem_per_unit; ++l) { - array.local[l] = 0; + array.local[l] = ((dash::myid() + 1) * 10000) + (l * 10); local_range[l] = ((dash::myid() + 1) * 1000) + l; } array.barrier(); + // Block- and global offset of target range: + auto block_offset = _dash_size - 1 - dash::myid(); + auto global_offset = block_offset * num_elem_per_unit; + + // First, create local copy of remote target region and check + // its initial values: + dash::copy(array.begin() + global_offset, + array.begin() + global_offset + num_elem_per_unit, + target_range); + + for (auto l = 0; l < num_elem_per_unit; ++l) { + int target_unit_id = _dash_size - 1 - dash::myid(); + int expected_value = ((target_unit_id + 1) * 10000) + (l * 10); + // Test values when obtained from dash::copy: + EXPECT_EQ_U(expected_value, + target_range[l]); + // Test values when obtained from single dart_get requests: + EXPECT_EQ_U(expected_value, + static_cast(array[global_offset + l])); + } + array.barrier(); + // Copy values from local range to remote global range. // All units (u) copy into block (nblocks-1-u), so unit 0 copies into // last block. - auto block_offset = _dash_size - 1 - dash::myid(); - auto global_offset = block_offset * num_elem_per_unit; dash::copy(local_range, local_range + num_elem_per_unit, array.begin() + global_offset); @@ -381,12 +402,14 @@ TEST_F(CopyTest, BlockingLocalToGlobalBlock) EXPECT_EQ_U(local_range[l], static_cast(array[global_offset + l])); } + + array.barrier(); } TEST_F(CopyTest, AsyncLocalToGlobPtr) { // Copy all elements contained in a single, continuous block. - const int num_elem_per_unit = 50; + const int num_elem_per_unit = 5; size_t num_elem_total = _dash_size * num_elem_per_unit; // Global target range: @@ -408,13 +431,18 @@ TEST_F(CopyTest, AsyncLocalToGlobPtr) auto global_offset = block_offset * num_elem_per_unit; dash::GlobPtr gptr_dest((array.begin() + global_offset).dart_gptr()); + LOG_MESSAGE("CopyTest.AsyncLocalToGlobPtr: call copy_async"); + auto copy_fut = dash::copy_async(local_range, local_range + num_elem_per_unit, gptr_dest); // Blocks until remote completion: + LOG_MESSAGE("CopyTest.AsyncLocalToGlobPtr: call fut.wait"); copy_fut.wait(); + array.barrier(); + for (auto l = 0; l < num_elem_per_unit; ++l) { // Compare local buffer and global array dest range: EXPECT_EQ_U(local_range[l], diff --git a/dash/test/HDF5ArrayTest.cc b/dash/test/HDF5ArrayTest.cc index ec3365726..ed299d850 100644 --- a/dash/test/HDF5ArrayTest.cc +++ b/dash/test/HDF5ArrayTest.cc @@ -119,7 +119,7 @@ TEST_F(HDF5ArrayTest, StoreLargeDashArray) TEST_F(HDF5ArrayTest, AutoGeneratePattern) { { - auto array_a = dash::Array(dash::size() * 2); + dash::Array array_a(dash::size() * 2); // Fill fill_array(array_a); dash::barrier(); @@ -146,7 +146,7 @@ TEST_F(HDF5ArrayTest, PreAllocation) { int ext_x = dash::size() * 2; { - auto array_a = dash::Array(ext_x); + dash::Array array_a(ext_x); // Fill fill_array(array_a, dash::myid()); dash::barrier(); @@ -158,7 +158,7 @@ TEST_F(HDF5ArrayTest, PreAllocation) StoreHDF::write(array_a, _filename, _dataset, fopts); dash::barrier(); } - auto array_b = dash::Array(ext_x); + dash::Array array_b(ext_x); StoreHDF::read(array_b, _filename, _dataset); dash::barrier(); @@ -170,7 +170,7 @@ TEST_F(HDF5ArrayTest, PreAllocation) TEST_F(HDF5ArrayTest, OutputStreamOpen) { { - auto array_a = dash::Array(dash::size() * 2); + dash::Array array_a(dash::size() * 2); fill_array(array_a); dash::barrier(); @@ -194,8 +194,8 @@ TEST_F(HDF5ArrayTest, UnderfilledPattern) long tilesize; { DASH_LOG_TRACE("HDF5ArrayTest.UnderfilledPattern", "alloc array_a"); - auto array_a = dash::Array(ext_x); - tilesize = array_a.pattern().blocksize(0); + dash::Array array_a(ext_x); + tilesize = array_a.pattern().blocksize(0); // Fill DASH_LOG_TRACE("HDF5ArrayTest.UnderfilledPattern", "fill array_a"); fill_array(array_a); @@ -237,7 +237,7 @@ TEST_F(HDF5ArrayTest, UnderfilledPatPreAllocate) { int ext_x = dash::size() * 5 + 1; { - auto array_a = dash::Array(ext_x); + dash::Array array_a(ext_x); // Fill fill_array(array_a); dash::barrier(); @@ -248,7 +248,7 @@ TEST_F(HDF5ArrayTest, UnderfilledPatPreAllocate) StoreHDF::write(array_a, _filename, _dataset, fopts); dash::barrier(); } - auto array_b = dash::Array(ext_x); + dash::Array array_b(ext_x); StoreHDF::read(array_b, _filename, _dataset); dash::barrier(); @@ -268,8 +268,8 @@ TEST_F(HDF5ArrayTest, MultipleDatasets) int secret_a = 10; double secret_b = 3; { - auto array_a = dash::Array(ext_x); - auto array_b = dash::Array(ext_x*2); + dash::Array array_a(ext_x); + dash::Array array_b(ext_x*2); // Fill fill_array(array_a, secret_a); @@ -302,8 +302,8 @@ TEST_F(HDF5ArrayTest, ModifyDataset) double secret_a = 10; double secret_b = 3; { - auto array_a = dash::Array(ext_x); - auto array_b = dash::Array(ext_x); + dash::Array array_a(ext_x); + dash::Array array_b(ext_x); // Fill fill_array(array_a, secret_a); @@ -332,38 +332,38 @@ TEST_F(HDF5ArrayTest, ModifyDataset) TEST_F(HDF5ArrayTest, StreamCreationFlags) { -int ext_x = dash::size() * 5; -double secret = 10; -{ - auto array_a = dash::Array(ext_x); + int ext_x = dash::size() * 5; + double secret = 10; + { + dash::Array array_a(ext_x); - // Fill - fill_array(array_a, secret); - dash::barrier(); + // Fill + fill_array(array_a, secret); + dash::barrier(); - // Set option + // Set option - OutputStream os(_filename, DeviceMode::app); - os << dio::dataset("settwo") - << dio::setpattern_key("custom_dash_pattern") - << dio::store_pattern() - << array_a - << dio::modify_dataset() - << array_a; + OutputStream os(_filename, DeviceMode::app); + os << dio::dataset("settwo") + << dio::setpattern_key("custom_dash_pattern") + << dio::store_pattern() + << array_a + << dio::modify_dataset() + << array_a; - dash::barrier(); -} -dash::Array array_b; -InputStream is(_filename); -is >> dio::dataset("settwo") - >> dio::setpattern_key("custom_dash_pattern") - >> dio::restore_pattern() - >> array_b; + dash::barrier(); + } + dash::Array array_b; + InputStream is(_filename); + is >> dio::dataset("settwo") + >> dio::setpattern_key("custom_dash_pattern") + >> dio::restore_pattern() + >> array_b; -dash::barrier(); + dash::barrier(); -// Verify data -verify_array(array_b, secret); + // Verify data + verify_array(array_b, secret); } TEST_F(HDF5ArrayTest, GroupTest) @@ -371,9 +371,9 @@ TEST_F(HDF5ArrayTest, GroupTest) int ext_x = dash::size() * 5; double secret[] = {10,11,12}; { - auto array_a = dash::Array(ext_x); - auto array_b = dash::Array(ext_x); - auto array_c = dash::Array(ext_x); + dash::Array array_a(ext_x); + dash::Array array_b(ext_x); + dash::Array array_c(ext_x); // Fill fill_array(array_a, secret[0]); @@ -438,7 +438,7 @@ TEST_F(HDF5ArrayTest, TeamSplit) if (myteam.position() == 0) { { - auto array_a = dash::Array(ext_x, myteam); + dash::Array array_a(ext_x, myteam); // Array has to be allocated EXPECT_NE_U(array_a.lbegin() , nullptr); @@ -455,7 +455,7 @@ TEST_F(HDF5ArrayTest, TeamSplit) team_all.barrier(); if (myteam.position() == 1) { - auto array_a = dash::Array(ext_x, myteam); + dash::Array array_a(ext_x, myteam); array_a.barrier(); fill_array(array_a, secret); diff --git a/dash/test/TeamTest.cc b/dash/test/TeamTest.cc index fb8ffe55e..f02dc52da 100644 --- a/dash/test/TeamTest.cc +++ b/dash/test/TeamTest.cc @@ -3,7 +3,7 @@ #include #include #include -#include +#include #include "TestBase.h" #include "TeamTest.h" @@ -31,46 +31,59 @@ TEST_F(TeamTest, Deallocate) { TEST_F(TeamTest, SplitTeamSync) { auto & team_all = dash::Team::All(); - if(team_all.size() < 2){ - SKIP_TEST(); + + if (team_all.size() < 2) { + SKIP_TEST_MSG("requires at least 2 units"); } - if(!team_all.is_leaf()){ - LOG_MESSAGE("team is already splitted. Skip test"); - SKIP_TEST(); + if (!team_all.is_leaf()) { + SKIP_TEST_MSG("team is already splitted. Skip test"); } LOG_MESSAGE("team_all contains %d units", team_all.size()); auto & team_core = team_all.split(2); - LOG_MESSAGE("team_core (%d) contains %d units", team_core.dart_id(), team_core.size()); + LOG_MESSAGE("team_core (%d) contains %d units", + team_core.dart_id(), team_core.size()); + + if (team_core.num_siblings() < 2) { + SKIP_TEST_MSG("Team::All().split(2) resulted in < 2 groups"); + } ASSERT_EQ_U(team_all, dash::Team::All()); - if(team_core.dart_id() == 1){ - LOG_MESSAGE("Unit %d: I am in team %d", team_core.myid(), team_core.dart_id()); + if (team_core.dart_id() == 1) { + LOG_MESSAGE("Unit %d: I am in team %d", + team_core.myid(), team_core.dart_id()); + usleep(1000 * 1000); - if(team_core.myid() == 0){ + if (team_core.myid() == 0) { std::ofstream outfile ("test.txt"); - } + } } LOG_MESSAGE("team_all.myid(): %d, team_core.myid(): %d, dash::myid(): %d", team_all.myid(), team_core.myid(), dash::myid()); LOG_MESSAGE("team_all.position(): %d, team_core.position(): %d", team_all.position(), team_core.position()); - LOG_MESSAGE("team_all.dart_id(): %d, team_core.dart_id(): %d", - team_all.dart_id(), team_core.dart_id()); + LOG_MESSAGE("team_all.dart_id(): %d, team_core.dart_id(): %d", + team_all.dart_id(), team_core.dart_id()); team_all.barrier(); - if(team_core.position() == 0){ - LOG_MESSAGE("Unit %d: I am in team %d", team_core.myid(), team_core.dart_id()); - if(team_core.myid() == 0){ + + if (team_core.position() == 0) { + LOG_MESSAGE("Unit %d: I am in team %d", + team_core.myid(), team_core.dart_id()); + + if (team_core.myid() == 0) { std::ifstream infile("test.txt"); bool file_exists = infile.good(); ASSERT_EQ_U(file_exists, true); } } + team_all.barrier(); - if(team_all.myid() == 0){ + + if (team_all.myid() == 0) { std::remove("test.txt"); } } + diff --git a/dash/test/TeamTest.h b/dash/test/TeamTest.h index 56db3d2c5..6f2b3c67f 100644 --- a/dash/test/TeamTest.h +++ b/dash/test/TeamTest.h @@ -4,10 +4,13 @@ #include #include +#include "TestBase.h" + + /** * Test fixture for class dash::Team */ -class TeamTest : public ::testing::Test { +class TeamTest : public dash::test::TestBase { protected: TeamTest() { @@ -16,13 +19,6 @@ class TeamTest : public ::testing::Test { virtual ~TeamTest() { } - virtual void SetUp() { - dash::init(&TESTENV.argc, &TESTENV.argv); - } - - virtual void TearDown() { - dash::finalize(); - } }; #endif // DASH__TEST__TEAM_TEST_H_ diff --git a/dash/test/TestBase.h b/dash/test/TestBase.h index a86bd48b3..dea1f9e34 100644 --- a/dash/test/TestBase.h +++ b/dash/test/TestBase.h @@ -96,4 +96,31 @@ extern void ColoredPrintf( }\ return + +namespace dash { +namespace test { + +class TestBase : public ::testing::Test { + + protected: + + virtual void SetUp() { + LOG_MESSAGE("===> Running test case with %d units ...", dash::size()); + dash::init(&TESTENV.argc, &TESTENV.argv); + LOG_MESSAGE("-==- DASH initialized"); + } + + virtual void TearDown() { + LOG_MESSAGE("-==- Test case finished at unit %d", dash::myid()); + dash::Team::All().barrier(); + LOG_MESSAGE("-==- Finalize DASH at unit %d", dash::myid()); + dash::finalize(); + LOG_MESSAGE("<=== Finished test case with %d units", dash::size()); + } +}; + +} // namespace test +} // namespace dash + + #endif // DASH__TEST__TEST_BASE_H_