diff --git a/CHANGELOG.md b/CHANGELOG.md index 9fb5ed6..6071c8b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,18 @@ Change Log for libSplash ================================================================ +Release 1.2.4 +------------- +**Date:** 2015-01-25 + +This release fixes a bug with parallel NULL reads. + +**Bug Fixes** + + - Fix Null-Access Parallel Read Hang #148 + - Fix compile error on Red Hat #147 + + Release 1.2.3 ------------- **Date:** 2014-10-14 diff --git a/src/DCDataSet.cpp b/src/DCDataSet.cpp index e554ce0..d612fe4 100644 --- a/src/DCDataSet.cpp +++ b/src/DCDataSet.cpp @@ -453,7 +453,7 @@ namespace splash // dst buffer is allowed to be NULL // in this case, only the size of the dataset is returned // if the dataset is empty, return just its size as there is nothing to read - if ((dst != NULL) && (getNDims() > 0)) + if (getNDims() > 0) { log_msg(3, "\n ndims = %llu\n" @@ -480,18 +480,23 @@ namespace splash if (dst_dataspace < 0) throw DCException(getExceptionString("read: Failed to create target dataspace")); - if (H5Sselect_hyperslab(dst_dataspace, H5S_SELECT_SET, dstOffset.getPointer(), NULL, - srcSize.getPointer(), NULL) < 0 || - H5Sselect_valid(dst_dataspace) <= 0) - throw DCException(getExceptionString("read: Target dataspace hyperslab selection is not valid!")); - - if (H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, srcOffset.getPointer(), NULL, - srcSize.getPointer(), NULL) < 0 || - H5Sselect_valid(dataspace) <= 0) - throw DCException(getExceptionString("read: Source dataspace hyperslab selection is not valid!")); + if (!dst) { + H5Sselect_none(dst_dataspace); + } else { + if (H5Sselect_hyperslab(dst_dataspace, H5S_SELECT_SET, dstOffset.getPointer(), NULL, + srcSize.getPointer(), NULL) < 0 || + H5Sselect_valid(dst_dataspace) <= 0) + throw DCException(getExceptionString("read: Target dataspace hyperslab selection is not valid!")); + } - if (srcSize.getScalarSize() == 0) + if (!dst || srcSize.getScalarSize() == 0) { H5Sselect_none(dataspace); + } else { + if (H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, srcOffset.getPointer(), NULL, + srcSize.getPointer(), NULL) < 0 || + H5Sselect_valid(dataspace) <= 0) + throw DCException(getExceptionString("read: Source dataspace hyperslab selection is not valid!")); + } if (H5Dread(dataset, this->datatype, dst_dataspace, dataspace, dsetReadProperties, dst) < 0) throw DCException(getExceptionString("read: Failed to read dataset")); diff --git a/src/include/splash/core/DCHelper.hpp b/src/include/splash/core/DCHelper.hpp index e133fbc..bdf682d 100644 --- a/src/include/splash/core/DCHelper.hpp +++ b/src/include/splash/core/DCHelper.hpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -147,7 +148,7 @@ namespace splash while (current_chunk_size < target_chunk_size) { // test if increasing chunk size optimizes towards target chunk size - size_t chunk_diff = std::abs(target_chunk_size - (current_chunk_size * 2)); + size_t chunk_diff = abs(target_chunk_size - (current_chunk_size * 2)); if (chunk_diff >= last_chunk_diff) break; diff --git a/src/include/splash/version.hpp b/src/include/splash/version.hpp index 08a5095..bcaf99b 100644 --- a/src/include/splash/version.hpp +++ b/src/include/splash/version.hpp @@ -1,5 +1,5 @@ /** - * Copyright 2013-2014 Felix Schmitt, Axel Huebl + * Copyright 2013-2015 Felix Schmitt, Axel Huebl * * This file is part of libSplash. * @@ -26,7 +26,7 @@ /** the splash version reflects the changes in API */ #define SPLASH_VERSION_MAJOR 1 #define SPLASH_VERSION_MINOR 2 -#define SPLASH_VERSION_PATCH 3 +#define SPLASH_VERSION_PATCH 4 /** we can always handle files from the same major release * changes in the minor number have to be backwards compatible diff --git a/tests/Parallel_ZeroAccessTest.cpp b/tests/Parallel_ZeroAccessTest.cpp index f61758b..18de06b 100644 --- a/tests/Parallel_ZeroAccessTest.cpp +++ b/tests/Parallel_ZeroAccessTest.cpp @@ -84,6 +84,8 @@ void Parallel_ZeroAccessTest::testZeroAccess() /* test loops */ for (size_t loop = 0; loop < NUM_TEST_LOOPS; ++loop) { + int64_t *nullData = NULL; + /* clear data buffer */ for (size_t i = 0; i < dataSize; ++i) data[i] = -1; @@ -91,8 +93,10 @@ void Parallel_ZeroAccessTest::testZeroAccess() /* set and write number of data elements for this round */ size_t elements = 0; size_t zeroAccess = rand() % 2; - if (!zeroAccess) - elements = (rand() % dataSize) + 1; + if (!zeroAccess) { + elements = (rand() % dataSize) + 1; + nullData = new int64_t[elements]; + } size_t readElements = 100000; for (size_t i = 0; i < elements; ++i) @@ -149,8 +153,19 @@ void Parallel_ZeroAccessTest::testZeroAccess() /* read data for comparison */ pdc->read(10, Dimensions(readElements, 1, 1), Dimensions(myOffset, 0, 0), "data", sizeRead, data); - + CPPUNIT_ASSERT(sizeRead == Dimensions(elements, 1, 1)); + + /* read data, use NULL ptr if none elements to read */ + pdc->read(10, Dimensions(readElements, 1, 1), Dimensions(myOffset, 0, 0), + "data", sizeRead, nullData); + + CPPUNIT_ASSERT(sizeRead == Dimensions(elements, 1, 1)); + + if (nullData) + { + delete[] nullData; + } for (size_t i = 0; i < dataSize; ++i) {