diff --git a/.travis.yml b/.travis.yml index d2498e3..6130842 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,6 +42,7 @@ before_script: - lsb_release -a - echo "$SRC" - ls -hal $SRC + - ls -hal /usr/include # PPA providing hdf5 >= 1.8.6 and OpenMPI >= 1.5.1 # -> remove legacy hdf5 and mpi packages/deps from travis - sudo apt-get remove -qq libhdf5* libopenmpi* openmpi-bin @@ -58,4 +59,10 @@ before_script: - sudo apt-get install -qq -f libboost-program-options-dev - sudo apt-get -t o=LP-PPA-james-page-openmpi install -q -f $APTMPI - sudo apt-get -t o=LP-PPA-axel-huebl-libsplash install -q -f $APTHDF5 + - sudo apt-get install python-numpy cython + - sudo -H pip install --upgrade pip +# numpy and cython should be already satisfied + - export HDF5_DIR=/usr + - export C_INCLUDE_PATH=/usr/lib/openmpi/include + - pip install --user h5py - mkdir -p $BUILD ~/lib diff --git a/doc/INSTALL.md b/doc/INSTALL.md index cdcabf8..640817b 100644 --- a/doc/INSTALL.md +++ b/doc/INSTALL.md @@ -17,7 +17,8 @@ To use the CMakeLists.txt file which comes with the source code, you must have The splashtools and some tests also require an **MPI 2.2** compatible MPI library, e.g. **OpenMPI 1.5.1** or higher. -Tests require the development version of the **CppUnit** library. +Our *tests* require the development version of the **CppUnit** library and +python support for `h5py` & `numpy`. Compiling diff --git a/src/include/splash/basetypes/ColTypeBool.hpp b/src/include/splash/basetypes/ColTypeBool.hpp index 045e8da..8fc49ac 100644 --- a/src/include/splash/basetypes/ColTypeBool.hpp +++ b/src/include/splash/basetypes/ColTypeBool.hpp @@ -1,5 +1,5 @@ /** - * Copyright 2013 Felix Schmitt, René Widera + * Copyright 2013, 2015 Felix Schmitt, René Widera, Axel Huebl * * This file is part of libSplash. * @@ -8,6 +8,7 @@ * the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. + * * libSplash is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the @@ -18,7 +19,6 @@ * and the GNU Lesser General Public License along with libSplash. * If not, see . */ - #ifndef COLTYPEBOOL_H @@ -35,8 +35,15 @@ class ColTypeBool : public CollectionType ColTypeBool() { - const hsize_t dim[] = {sizeof (bool)}; - this->type = H5Tarray_create(H5T_NATIVE_B8, 1, dim); + // 8 bit (very) short int, see + // http://www.hdfgroup.org/HDF5/doc/RM/PredefDTypes.html + // this is a h5py compatible implementation for bool, see: + // http://docs.h5py.org/en/latest/faq.html + this->type = H5Tenum_create(H5T_NATIVE_INT8); + const char *names[2] = {"true", "false"}; + const int64_t val[2] = {1, 0}; + H5Tenum_insert(this->type, names[0], &val[0]); + H5Tenum_insert(this->type, names[1], &val[1]); } ~ColTypeBool() diff --git a/src/include/splash/version.hpp b/src/include/splash/version.hpp index bcaf99b..04fc3fb 100644 --- a/src/include/splash/version.hpp +++ b/src/include/splash/version.hpp @@ -31,7 +31,7 @@ /** we can always handle files from the same major release * changes in the minor number have to be backwards compatible */ -#define SPLASH_FILE_FORMAT_MAJOR 2 -#define SPLASH_FILE_FORMAT_MINOR 1 +#define SPLASH_FILE_FORMAT_MAJOR 3 +#define SPLASH_FILE_FORMAT_MINOR 0 #endif /* VERSION_HPP */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d37e177..c79cc02 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -108,3 +108,8 @@ FOREACH(TEST_FILE ${TEST_FILES}) TARGET_LINK_LIBRARIES(${FILE}.out ${LIBS}) ENDFOREACH() + +# copy scripts to "build" dir for easy testing +FILE(COPY readBool.py DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +FILE(COPY run_tests DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) +FILE(COPY run_parallel_tests DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/tests/SimpleDataTest.cpp b/tests/SimpleDataTest.cpp index 4df28dc..acb286f 100644 --- a/tests/SimpleDataTest.cpp +++ b/tests/SimpleDataTest.cpp @@ -40,7 +40,8 @@ using namespace splash; SimpleDataTest::SimpleDataTest() : ctUInt32(), -ctUInt64() +ctUInt64(), +ctBool() { dataCollector = new SerialDataCollector(10); srand(time(NULL)); @@ -74,9 +75,13 @@ bool SimpleDataTest::subtestWriteRead(Dimensions gridSize, Dimensions borderSize // initial part of the test: data is written to the file, once with and once // without borders uint64_t *dataWrite = new uint64_t[bufferSize]; + bool *boolWrite = new bool[bufferSize]; for (uint64_t i = 0; i < bufferSize; i++) + { dataWrite[i] = i; + boolWrite[i] = ( i%2 == 0 ); + } dataCollector->write(10, ctUInt64, dimensions, Selection(gridSize), "deep/folders/data", dataWrite); datasetNames.insert("deep/folders/data"); @@ -85,6 +90,13 @@ bool SimpleDataTest::subtestWriteRead(Dimensions gridSize, Dimensions borderSize borderSize), "deep/folders/data_without_borders", dataWrite); datasetNames.insert("deep/folders/data_without_borders"); + dataCollector->write(10, ctBool, dimensions, Selection(gridSize), "deep/folders/data_bool", boolWrite); + datasetNames.insert("deep/folders/data_bool"); + + dataCollector->write(20, ctBool, dimensions, Selection(gridSize, smallGridSize, + borderSize), "deep/folders/data_bool_without_borders", boolWrite); + datasetNames.insert("deep/folders/data_bool_without_borders"); + dataCollector->close(); // first part of the test: read data with borders to a cleared @@ -103,6 +115,9 @@ bool SimpleDataTest::subtestWriteRead(Dimensions gridSize, Dimensions borderSize int32_t *ids = NULL; size_t numIDs = 0; dataCollector->getEntryIDs(NULL, &numIDs); +#if defined TESTS_DEBUG + printf("number of entry IDs=%d\n", numIDs); +#endif CPPUNIT_ASSERT(numIDs == 2); ids = new int32_t[numIDs]; dataCollector->getEntryIDs(ids, NULL); @@ -110,7 +125,7 @@ bool SimpleDataTest::subtestWriteRead(Dimensions gridSize, Dimensions borderSize for (uint32_t j = 0; j < numIDs; ++j) { dataCollector->getEntriesForID(ids[j], NULL, &numEntries); - CPPUNIT_ASSERT(numEntries == 1); + CPPUNIT_ASSERT(numEntries == 2); entries = new DataCollector::DCEntry[numEntries]; dataCollector->getEntriesForID(ids[j], entries, NULL); @@ -129,8 +144,12 @@ bool SimpleDataTest::subtestWriteRead(Dimensions gridSize, Dimensions borderSize delete[] ids; uint64_t *dataRead = new uint64_t[bufferSize]; + bool *boolRead = new bool[bufferSize]; for (uint64_t i = 0; i < bufferSize; i++) + { dataRead[i] = UINT64_MAX; + boolRead[i] = false; + } Dimensions resultSize; dataCollector->read(10, "deep/folders/data", resultSize, dataRead); @@ -138,17 +157,31 @@ bool SimpleDataTest::subtestWriteRead(Dimensions gridSize, Dimensions borderSize for (uint32_t i = 0; i < 3; i++) CPPUNIT_ASSERT(resultSize[i] == gridSize[i]); + dataCollector->read(10, "deep/folders/data_bool", resultSize, boolRead); + for (uint64_t i = 0; i < bufferSize; i++) + { if (dataRead[i] != dataWrite[i]) { #if defined TESTS_DEBUG - std::cout << i << ": " << dataRead[i] << " != exptected " << dataWrite[i] << std::endl; + std::cout << i << ": " << dataRead[i] << " != expected " << dataWrite[i] << std::endl; +#endif + resultsCorrect = false; + break; + } + if (boolRead[i] != boolWrite[i]) + { +#if defined TESTS_DEBUG + std::cout << i << ": " << boolRead[i] << " != expected " << boolWrite[i] << std::endl; #endif resultsCorrect = false; break; } + } delete[] dataRead; + delete[] boolRead; + delete[] boolWrite; CPPUNIT_ASSERT_MESSAGE("simple write/read failed", resultsCorrect); diff --git a/tests/include/SimpleDataTest.h b/tests/include/SimpleDataTest.h index fbde3f6..5152b53 100644 --- a/tests/include/SimpleDataTest.h +++ b/tests/include/SimpleDataTest.h @@ -34,8 +34,8 @@ class SimpleDataTest : public CPPUNIT_NS::TestFixture { CPPUNIT_TEST_SUITE(SimpleDataTest); - CPPUNIT_TEST(testWriteRead); CPPUNIT_TEST(testNullWrite); + CPPUNIT_TEST(testWriteRead); CPPUNIT_TEST_SUITE_END(); @@ -63,6 +63,7 @@ class SimpleDataTest : public CPPUNIT_NS::TestFixture ColTypeUInt32 ctUInt32; ColTypeUInt64 ctUInt64; + ColTypeBool ctBool; DataCollector *dataCollector; }; diff --git a/tests/readBool.py b/tests/readBool.py new file mode 100755 index 0000000..3f5e2cb --- /dev/null +++ b/tests/readBool.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python +# +# Copyright 2015 Axel Huebl +# +# This file is part of libSplash. +# +# libSplash is free software: you can redistribute it and/or modify +# it under the terms of of either the GNU General Public License or +# the GNU Lesser General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# libSplash is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License and the GNU Lesser General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# and the GNU Lesser General Public License along with libSplash. +# If not, see . +# + +import h5py +import numpy as np + +f = h5py.File("h5/testWriteRead_0_0_0.h5", "r") +data = f["data/10/deep/folders/data_bool"] + +len = data.size +data1d = data[:,:,:].reshape(len) + +for i in np.arange(len): + val = ( i%2 == 0 ); + if data1d[i] != val: + exit(1) + +exit(0) diff --git a/tests/run_tests b/tests/run_tests index fe0f8b6..4bfa7f2 100755 --- a/tests/run_tests +++ b/tests/run_tests @@ -26,6 +26,7 @@ function testMPI() } testSerial ./SimpleDataTest.cpp.out "Testing simple data read/write..." +testSerial ./readBool.py "Testing h5py compatible read..." testSerial ./AttributesTest.cpp.out "Testing reading/writing attributes..."