Commit b08e5675 authored by Andrew J. Burns (Cont's avatar Andrew J. Burns (Cont

Merge branch 'master' of /data/Repository/Xdmf2 into ajb-dev

parents 7755f6b8 521435d9
......@@ -96,13 +96,13 @@ if(XDMF_BUILD_DSM)
find_package(H5FDdsm REQUIRED NO_MODULE)
if(H5FDdsm_FOUND)
include_directories(${H5FD_DSM_INCLUDE_DIR})
get_filename_component(H5FD_DSM_LIBRARY_DIR
"${H5FD_DSM_INCLUDE_DIR}/../lib" REALPATH)
set(XDMF_LIBRARY_DIRS ${XDMF_LIBRARY_DIRS} ${H5FD_DSM_LIBRARY_DIR})
include_directories(${H5FDdsm_INCLUDE_DIR})
get_filename_component(H5FDdsm_LIBRARY_DIR
"${H5FDdsm_INCLUDE_DIR}/../lib" REALPATH)
set(XDMF_LIBRARY_DIRS ${XDMF_LIBRARY_DIRS} ${H5FDdsm_LIBRARY_DIR})
get_property(h5fddsm_lib_location TARGET H5FDdsm PROPERTY LOCATION)
set(H5FD_DSM_LIBRARIES ${h5fddsm_lib_location})
set(XDMF_LIBRARIES ${XDMF_LIBRARIES} ${H5FD_DSM_LIBRARIES})
set(H5FDdsm_LIBRARIES ${h5fddsm_lib_location})
set(XDMF_LIBRARIES ${XDMF_LIBRARIES} ${H5FDdsm_LIBRARIES})
else(H5FDdsm_FOUND)
message(SEND_ERROR
"Cannot find HDF5 DSM! Please set H5FDdsm_DIR and configure again.")
......
......@@ -824,6 +824,7 @@ XdmfArray::populateItem(const std::map<std::string, std::string> & itemPropertie
0),
std::vector<unsigned int>(mDimensions.size(),
1),
mDimensions,
mDimensions);
}
else if(formatVal.compare("XML") == 0) {
......
......@@ -25,9 +25,9 @@
#include <sstream>
#include "XdmfArray.hpp"
#include "XdmfArrayType.hpp"
#include "XdmfError.hpp"
#include "XdmfHDF5Controller.hpp"
#include "XdmfSystemUtils.hpp"
#include "XdmfError.hpp"
shared_ptr<XdmfHDF5Controller>
XdmfHDF5Controller::New(const std::string & hdf5FilePath,
......@@ -35,14 +35,17 @@ XdmfHDF5Controller::New(const std::string & hdf5FilePath,
const shared_ptr<const XdmfArrayType> type,
const std::vector<unsigned int> & start,
const std::vector<unsigned int> & stride,
const std::vector<unsigned int> & count)
const std::vector<unsigned int> & dimensions,
const std::vector<unsigned int> & dataspaceDimensions)
{
shared_ptr<XdmfHDF5Controller> p(new XdmfHDF5Controller(hdf5FilePath,
dataSetPath,
type,
start,
stride,
count));
shared_ptr<XdmfHDF5Controller>
p(new XdmfHDF5Controller(hdf5FilePath,
dataSetPath,
type,
start,
stride,
dimensions,
dataspaceDimensions));
return p;
}
......@@ -51,18 +54,16 @@ XdmfHDF5Controller::XdmfHDF5Controller(const std::string & hdf5FilePath,
const shared_ptr<const XdmfArrayType> type,
const std::vector<unsigned int> & start,
const std::vector<unsigned int> & stride,
const std::vector<unsigned int> & count) :
const std::vector<unsigned int> & dimensions,
const std::vector<unsigned int> & dataspaceDimensions) :
XdmfHeavyDataController(hdf5FilePath,
dataSetPath,
type,
count),
mStart(start),
mStride(stride)
start,
stride,
dimensions,
dataspaceDimensions)
{
if(!(mStart.size() == mStride.size() && mStride.size() == mDimensions.size()))
XdmfError::message(XdmfError::FATAL,
"mStart, mStride, mDimensions must all be of equal "
"length in XdmfHDF5Controller constructor");
}
XdmfHDF5Controller::~XdmfHDF5Controller()
......
......@@ -67,8 +67,11 @@ public:
* the hdf5 data set.
* @param stride the number of elements to move in each dimension from the
* hdf5 data set.
* @param count the number of elements to select in each dimension from the
* hdf5 data set. (size in each dimension)
* @param dimensions the number of elements to select in each
* dimension from the hdf5 data set. (size in each dimension)
* @param dataspaceDimensions the number of elements in the entire
* hdf5 data set (may be larger that dimensions if using
* hyperslabs).
*
* @return new HDF5 Controller.
*/
......@@ -78,7 +81,8 @@ public:
const shared_ptr<const XdmfArrayType> type,
const std::vector<unsigned int> & start,
const std::vector<unsigned int> & stride,
const std::vector<unsigned int> & count);
const std::vector<unsigned int> & dimensions,
const std::vector<unsigned int> & dataspaceDimensions);
virtual std::string getName() const;
......@@ -91,7 +95,8 @@ protected:
const shared_ptr<const XdmfArrayType> type,
const std::vector<unsigned int> & start,
const std::vector<unsigned int> & stride,
const std::vector<unsigned int> & count);
const std::vector<unsigned int> & dimensions,
const std::vector<unsigned int> & dataspaceDimensions);
void read(XdmfArray * const array, const int fapl);
......@@ -100,9 +105,6 @@ private:
XdmfHDF5Controller(const XdmfHDF5Controller &); // Not implemented.
void operator=(const XdmfHDF5Controller &); // Not implemented.
const std::vector<unsigned int> mStart;
const std::vector<unsigned int> mStride;
};
#endif /* XDMFHDF5CONTROLLER_HPP_ */
......@@ -31,16 +31,19 @@ XdmfHDF5ControllerDSM::New(const std::string & hdf5FilePath,
const shared_ptr<const XdmfArrayType> type,
const std::vector<unsigned int> & start,
const std::vector<unsigned int> & stride,
const std::vector<unsigned int> & count,
const std::vector<unsigned int> & dimensions,
const std::vector<unsigned int> & datspaceDimensions,
H5FDdsmBuffer * const dsmBuffer)
{
shared_ptr<XdmfHDF5ControllerDSM> p(new XdmfHDF5ControllerDSM(hdf5FilePath,
dataSetPath,
type,
start,
stride,
count,
dsmBuffer));
shared_ptr<XdmfHDF5ControllerDSM>
p(new XdmfHDF5ControllerDSM(hdf5FilePath,
dataSetPath,
type,
start,
stride,
dimensions,
datspaceDimensions,
dsmBuffer));
return p;
}
......@@ -49,9 +52,16 @@ XdmfHDF5ControllerDSM::XdmfHDF5ControllerDSM(const std::string & hdf5FilePath,
const shared_ptr<const XdmfArrayType> type,
const std::vector<unsigned int> & start,
const std::vector<unsigned int> & stride,
const std::vector<unsigned int> & count,
const std::vector<unsigned int> & dimensions,
const std::vector<unsigned int> & dataspaceDimensions,
H5FDdsmBuffer * const dsmBuffer) :
XdmfHDF5Controller(hdf5FilePath, dataSetPath, type, start, stride, count),
XdmfHDF5Controller(hdf5FilePath,
dataSetPath,
type,
start,
stride,
dimensions,
dataspaceDimensions),
mDSMBuffer(dsmBuffer)
{
}
......@@ -71,7 +81,7 @@ void XdmfHDF5ControllerDSM::read(XdmfArray * const array)
hid_t fapl = H5Pcreate(H5P_FILE_ACCESS);
// Use DSM driver
H5Pset_fapl_dsm(fapl, MPI_COMM_WORLD, mDSMBuffer);
H5Pset_fapl_dsm(fapl, MPI_COMM_WORLD, mDSMBuffer, 0);
// Read from DSM Buffer
XdmfHDF5Controller::read(array, fapl);
......
......@@ -137,7 +137,8 @@ public:
const shared_ptr<const XdmfArrayType> type,
const std::vector<unsigned int> & start,
const std::vector<unsigned int> & stride,
const std::vector<unsigned int> & count,
const std::vector<unsigned int> & dimensions,
const std::vector<unsigned int> & dataspaceDimensions,
H5FDdsmBuffer * const dsmBuffer);
std::string getName() const;
......@@ -151,7 +152,8 @@ protected:
const shared_ptr<const XdmfArrayType> type,
const std::vector<unsigned int> & start,
const std::vector<unsigned int> & stride,
const std::vector<unsigned int> & count,
const std::vector<unsigned int> & dimensions,
const std::vector<unsigned int> & dataspaceDimensions,
H5FDdsmBuffer * const dsmBuffer);
private:
......
......@@ -60,7 +60,6 @@ public:
openFile(const std::string & filePath,
const int fapl)
{
if(mHDF5Handle >= 0) {
// Perhaps we should throw a warning.
closeFile();
......@@ -129,14 +128,16 @@ XdmfHDF5Writer::createHDF5Controller(const std::string & hdf5FilePath,
const shared_ptr<const XdmfArrayType> type,
const std::vector<unsigned int> & start,
const std::vector<unsigned int> & stride,
const std::vector<unsigned int> & count)
const std::vector<unsigned int> & dimensions,
const std::vector<unsigned int> & dataspaceDimensions)
{
return XdmfHDF5Controller::New(hdf5FilePath,
dataSetPath,
type,
start,
stride,
count);
dimensions,
dataspaceDimensions);
}
void
......@@ -169,7 +170,6 @@ void
XdmfHDF5Writer::write(XdmfArray & array,
const int fapl)
{
hid_t datatype = -1;
if(array.isInitialized()) {
......@@ -212,18 +212,29 @@ XdmfHDF5Writer::write(XdmfArray & array,
std::stringstream dataSetPath;
if((mMode == Overwrite || mMode == Append)
&& array.getHeavyDataController()) {
shared_ptr<XdmfHeavyDataController> heavyDataController =
array.getHeavyDataController();
const std::vector<unsigned int> & dimensions = array.getDimensions();
std::vector<unsigned int> dataspaceDimensions = dimensions;
std::vector<unsigned int> start(dimensions.size(), 0);
std::vector<unsigned int> stride(dimensions.size(), 1);
if((mMode == Overwrite || mMode == Append || mMode == Hyperslab)
&& heavyDataController) {
// Write to the previous dataset
dataSetPath << array.getHeavyDataController()->getDataSetPath();
hdf5FilePath = array.getHeavyDataController()->getFilePath();
dataSetPath << heavyDataController->getDataSetPath();
hdf5FilePath = heavyDataController->getFilePath();
if(mMode == Hyperslab) {
dataspaceDimensions = heavyDataController->getDataspaceDimensions();
start = heavyDataController->getStart();
stride = heavyDataController->getStride();
}
}
else {
dataSetPath << "Data" << mDataSetId;
}
const std::vector<unsigned int> & dimensions = array.getDimensions();
// Open a hdf5 dataset and write to it on disk.
herr_t status;
hsize_t size = array.getSize();
......@@ -261,75 +272,109 @@ XdmfHDF5Writer::write(XdmfArray & array,
}
}
}
// Restore previous error handler
H5Eset_auto2(0, old_func, old_client_data);
hid_t dataspace = H5S_ALL;
hid_t memspace = H5S_ALL;
std::vector<hsize_t> current_dims(dimensions.begin(), dimensions.end());
std::vector<hsize_t> current_dims(dataspaceDimensions.begin(),
dataspaceDimensions.end());
if(dataset < 0) {
std::vector<hsize_t> maximum_dims(dimensions.size(), H5S_UNLIMITED);
memspace = H5Screate_simple(dimensions.size(),
&current_dims[0],
&maximum_dims[0]);
dataspace = H5Screate_simple(dimensions.size(),
&current_dims[0],
&maximum_dims[0]);
hid_t property = H5Pcreate(H5P_DATASET_CREATE);
std::vector<hsize_t> chunk_size(dimensions.size(), 1024);
status = H5Pset_chunk(property, dimensions.size(), &chunk_size[0]);
dataset = H5Dcreate(mImpl->mHDF5Handle,
dataSetPath.str().c_str(),
datatype,
memspace,
dataspace,
H5P_DEFAULT,
property,
H5P_DEFAULT);
status = H5Pclose(property);
}
else {
if(mMode == Append) {
// Need to resize dataset to fit new data
if(mMode == Append) {
// Get size of old dataset
dataspace = H5Dget_space(dataset);
hssize_t datasize = H5Sget_simple_extent_npoints(dataspace);
status = H5Sclose(dataspace);
// Resize to fit size of old and new data.
hsize_t newSize = size + datasize;
status = H5Dset_extent(dataset, &newSize);
// Select hyperslab to write to.
memspace = H5Screate_simple(1, &size, NULL);
dataspace = H5Dget_space(dataset);
hsize_t start = datasize;
status = H5Sselect_hyperslab(dataspace,
H5S_SELECT_SET,
&start,
NULL,
&size,
NULL) ;
}
else {
// Overwriting - dataset rank must remain the same (hdf5 constraint)
hid_t dataspace = H5Dget_space(dataset);
const unsigned int ndims = H5Sget_simple_extent_ndims(dataspace);
if(ndims != current_dims.size())
XdmfError::message(XdmfError::FATAL, \
"Data set rank different -- ndims != "
"current_dims.size() -- in "
"XdmfHDF5Writer::write");
status = H5Dset_extent(dataset, &current_dims[0]);
if(status < 0) {
XdmfError::message(XdmfError::FATAL,
"H5Dset_extent returned failure in "
"XdmfHDF5Writer::write -- status: " + status);
}
// Get size of old dataset
dataspace = H5Dget_space(dataset);
hssize_t datasize = H5Sget_simple_extent_npoints(dataspace);
status = H5Sclose(dataspace);
// Resize to fit size of old and new data.
hsize_t newSize = size + datasize;
status = H5Dset_extent(dataset, &newSize);
// Select hyperslab to write to.
memspace = H5Screate_simple(1, &size, NULL);
dataspace = H5Dget_space(dataset);
hsize_t start = datasize;
status = H5Sselect_hyperslab(dataspace,
H5S_SELECT_SET,
&start,
NULL,
&size,
NULL);
}
else if(mMode == Overwrite) {
// Overwriting - dataset rank must remain the same (hdf5 constraint)
dataspace = H5Dget_space(dataset);
const unsigned int ndims = H5Sget_simple_extent_ndims(dataspace);
if(ndims != current_dims.size())
XdmfError::message(XdmfError::FATAL, \
"Data set rank different -- ndims != "
"current_dims.size() -- in "
"XdmfHDF5Writer::write");
status = H5Dset_extent(dataset, &current_dims[0]);
dataspace = H5Dget_space(dataset);
}
else if(mMode == Hyperslab) {
// Hyperslab - dataset rank must remain the same (hdf5 constraint)
dataspace = H5Dget_space(dataset);
const unsigned int ndims = H5Sget_simple_extent_ndims(dataspace);
if(ndims != current_dims.size())
XdmfError::message(XdmfError::FATAL, \
"Data set rank different -- ndims != "
"current_dims.size() -- in "
"XdmfHDF5Writer::write");
status = H5Dset_extent(dataset, &current_dims[0]);
dataspace = H5Dget_space(dataset);
std::vector<hsize_t> count(dimensions.begin(),
dimensions.end());
std::vector<hsize_t> currStride(stride.begin(),
stride.end());
std::vector<hsize_t> currStart(start.begin(),
start.end());
memspace = H5Screate_simple(count.size(),
&(count[0]),
NULL);
status = H5Sselect_hyperslab(dataspace,
H5S_SELECT_SET,
&currStart[0],
&currStride[0],
&count[0],
NULL) ;
if(status < 0) {
XdmfError::message(XdmfError::FATAL,
"H5Dset_extent returned failure in "
"XdmfHDF5Writer::write -- status: " + status);
}
}
status = H5Dwrite(dataset,
datatype,
memspace,
......@@ -359,18 +404,19 @@ XdmfHDF5Writer::write(XdmfArray & array,
shared_ptr<XdmfHDF5Controller>();
unsigned int newSize = array.getSize();
if(mMode == Append && array.getHeavyDataController()) {
newSize = array.getSize() + array.getHeavyDataController()->getSize();
if(mMode == Append && heavyDataController) {
newSize = array.getSize() + heavyDataController->getSize();
newDataController =
this->createHDF5Controller(hdf5FilePath,
dataSetPath.str(),
array.getArrayType(),
std::vector<unsigned int>(1, 0),
std::vector<unsigned int>(1, 1),
std::vector<unsigned int>(1, newSize),
std::vector<unsigned int>(1, newSize));
}
if(mMode == Default || !array.getHeavyDataController()) {
if(mMode == Default || !heavyDataController) {
++mDataSetId;
}
......@@ -379,11 +425,10 @@ XdmfHDF5Writer::write(XdmfArray & array,
this->createHDF5Controller(hdf5FilePath,
dataSetPath.str(),
array.getArrayType(),
std::vector<unsigned int>(dimensions.size(),
0),
std::vector<unsigned int>(dimensions.size(),
1),
dimensions);
start,
stride,
dimensions,
dataspaceDimensions);
}
array.setHeavyDataController(newDataController);
......
......@@ -99,8 +99,11 @@ protected:
* the hdf5 data set.
* @param stride the number of elements to move in each dimension from the
* hdf5 data set.
* @param count the number of elements to select in each dimension from the
* hdf5 data set. (size in each dimension)
* @param dimensions the number of elements to select in each
* dimension from the hdf5 data set. (size in each dimension)
* @param dataspaceDimensions the number of elements in the entire
* hdf5 data set (may be larger that dimensions if using
* hyperslabs).
*
* @return new HDF5 Controller.
*/
......@@ -110,7 +113,8 @@ protected:
const shared_ptr<const XdmfArrayType> type,
const std::vector<unsigned int> & start,
const std::vector<unsigned int> & stride,
const std::vector<unsigned int> & count);
const std::vector<unsigned int> & dimensions,
const std::vector<unsigned int> & dataspaceDimensions);
/**
* Open hdf5 file with a fapl.
......
......@@ -53,14 +53,16 @@ XdmfHDF5WriterDSM::createHDF5Controller(const std::string & hdf5FilePath,
const shared_ptr<const XdmfArrayType> type,
const std::vector<unsigned int> & start,
const std::vector<unsigned int> & stride,
const std::vector<unsigned int> & count)
const std::vector<unsigned int> & dimensions,
const std::vector<unsigned int> & dataspaceDimensions)
{
return XdmfHDF5ControllerDSM::New(hdf5FilePath,
dataSetPath,
type,
start,
stride,
count,
dimensions,
dataspaceDimensions,
mDSMBuffer);
}
......@@ -71,7 +73,6 @@ XdmfHDF5WriterDSM::closeFile()
herr_t status = H5Pclose(mFAPL);
mFAPL = -1;
}
XdmfHDF5Writer::closeFile();
}
......@@ -86,7 +87,7 @@ XdmfHDF5WriterDSM::openFile()
mFAPL = H5Pcreate(H5P_FILE_ACCESS);
// Use DSM driver
H5Pset_fapl_dsm(mFAPL, MPI_COMM_WORLD, mDSMBuffer);
H5Pset_fapl_dsm(mFAPL, MPI_COMM_WORLD, mDSMBuffer, 0);
XdmfHDF5Writer::openFile(mFAPL);
}
......@@ -95,13 +96,14 @@ void XdmfHDF5WriterDSM::visit(XdmfArray & array,
const shared_ptr<XdmfBaseVisitor>)
{
bool closeFAPL = false;
if(mFAPL < 0) {
// Set file access property list for DSM
mFAPL = H5Pcreate(H5P_FILE_ACCESS);
// Use DSM driver
H5Pset_fapl_dsm(mFAPL, MPI_COMM_WORLD, mDSMBuffer);
H5Pset_fapl_dsm(mFAPL, MPI_COMM_WORLD, mDSMBuffer, 0);
closeFAPL = true;
}
......
......@@ -99,7 +99,8 @@ protected:
const shared_ptr<const XdmfArrayType> type,
const std::vector<unsigned int> & start,
const std::vector<unsigned int> & stride,
const std::vector<unsigned int> & count);
const std::vector<unsigned int> & dimensions,
const std::vector<unsigned int> & dataspaceDimensions);
private:
......
......@@ -23,18 +23,30 @@
#include <functional>
#include <numeric>
#include "XdmfError.hpp"
#include "XdmfHeavyDataController.hpp"
#include "XdmfSystemUtils.hpp"
XdmfHeavyDataController::XdmfHeavyDataController(const std::string & filePath,
const std::string & dataSetPath,
const shared_ptr<const XdmfArrayType> type,
const std::vector<unsigned int> & dimensions) :
const std::vector<unsigned int> & start,
const std::vector<unsigned int> & stride,
const std::vector<unsigned int> & dimensions,
const std::vector<unsigned int> & dataspaceDimensions) :
mDataSetPath(dataSetPath),
mDataspaceDimensions(dataspaceDimensions),
mDimensions(dimensions),
mFilePath(filePath),
mStart(start),
mStride(stride),
mType(type)
{
if(!(mStart.size() == mStride.size() &&
mStride.size() == mDimensions.size()))
XdmfError::message(XdmfError::FATAL,
"mStart, mStride, mDimensions must all be of equal "
"length in XdmfHeavyDataController constructor");
}
XdmfHeavyDataController::~XdmfHeavyDataController()
......@@ -47,6 +59,12 @@ XdmfHeavyDataController::getDataSetPath() const
return mDataSetPath;
}
std::vector<unsigned int>
XdmfHeavyDataController::getDataspaceDimensions() const
{
return mDataspaceDimensions;
}
std::vector<unsigned int> XdmfHeavyDataController::getDimensions() const
{
return mDimensions;
......@@ -67,6 +85,18 @@ XdmfHeavyDataController::getSize() const
std::multiplies<unsigned int>());
}
std::vector<unsigned int>
XdmfHeavyDataController::getStart() const
{
return mStart;
}
std::vector<unsigned int>
XdmfHeavyDataController::getStride() const
{
return mStride;
}
shared_ptr<const XdmfArrayType>
XdmfHeavyDataController::getType() const
{
......
......@@ -77,6 +77,17 @@ public:
*/
std::string getDataSetPath() const;
/**
* Get the dimensions of the dataspace owned by this
* controller. This is the dimension of the entire heavy dataset,
* which may be larger than the dimensions of the array (if reading
* a piece of a larger dataset).
*
* @return a vector containing the size in each dimension of the dataspace
* owned by this controller.
*/
std::vector<unsigned int> getDataspaceDimensions() const;
/**