Commit a7f5d5c0 authored by Kenneth Leiter's avatar Kenneth Leiter

ENH: Remove group creation when writing HDF5 files. The group paths depend on how the xml

was structured when the dataset was written and we want to fully separate dealing with light and heavy
data when creating Xdmf files.  This will allow us to move towards complete separation of
heavy and light data writing, a Create -> Write -> Release -> Create -> Write -> Release -> Write XML
workflow.
parent 27e3b6ed
......@@ -24,12 +24,14 @@ public:
{
herr_t status = H5Fclose(mHDF5Handle);
};
std::vector<std::string> mDataHierarchy;
hid_t mHDF5Handle;
std::string mHeavyFileName;
std::string mLastWrittenDataSet;
static int mDataSetId;
};
int XdmfHDF5Writer::XdmfHDF5WriterImpl::mDataSetId = 0;
class XdmfHDF5Writer::GetHDF5Type : public boost::static_visitor <hid_t> {
public:
......@@ -107,70 +109,11 @@ XdmfHDF5Writer::~XdmfHDF5Writer()
std::cout << "Deleted XdmfHDF5Writer " << this << std::endl;
}
std::string XdmfHDF5Writer::createHDF5Group(std::stringstream & groupPath, int index)
{
groupPath << "/" << mImpl->mDataHierarchy[index];
hid_t handle = H5Gopen(mImpl->mHDF5Handle, groupPath.str().c_str(), H5P_DEFAULT);
if(handle < 0)
{
// Open failed, create a new group
handle = H5Gcreate(mImpl->mHDF5Handle, groupPath.str().c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
}
H5Gclose(handle);
// + 2 because the last value in mDataHierarchy == dataset name
if(index + 2 < mImpl->mDataHierarchy.size())
{
return createHDF5Group(groupPath, index + 1);
}
return groupPath.str().c_str();
}
std::string XdmfHDF5Writer::getHDF5GroupHandle()
{
if(mImpl->mDataHierarchy.size() > 1)
{
// Save old error handler and turn off error handling for now
H5E_auto_t old_func;
void* old_client_data;
H5Eget_auto(0, &old_func, &old_client_data);
H5Eset_auto2(0, NULL, NULL);
std::stringstream emptyPath;
std::string handle = createHDF5Group(emptyPath);
// Restore previous error handler
H5Eset_auto2(0, old_func, old_client_data);
return handle;
}
return "";
}
std::string XdmfHDF5Writer::getLastWrittenDataSet() const
{
return mImpl->mLastWrittenDataSet;
}
void XdmfHDF5Writer::popDataHierarchy()
{
mImpl->mDataHierarchy.pop_back();
}
void XdmfHDF5Writer::pushDataHierarchy(const XdmfItem & item)
{
const std::map<std::string, std::string> itemProperties = item.getItemProperties();
std::map<std::string, std::string>::const_iterator name = itemProperties.find("Name");
if(name == itemProperties.end())
{
mImpl->mDataHierarchy.push_back(item.getItemTag());
}
else
{
mImpl->mDataHierarchy.push_back(name->second);
}
}
void XdmfHDF5Writer::visit(XdmfArray & array, boost::shared_ptr<Loki::BaseVisitor> visitor)
{
hid_t datatype = -1;
......@@ -185,35 +128,25 @@ void XdmfHDF5Writer::visit(XdmfArray & array, boost::shared_ptr<Loki::BaseVisito
if(datatype != -1)
{
std::stringstream dataSetName;
dataSetName << "Data" << mImpl->mDataSetId;
// Open a hdf5 dataset and write to it on disk.
herr_t status;
hsize_t size = array.getSize();
hid_t dataspace = H5Screate_simple(1, &size, NULL);
hid_t handle = mImpl->mHDF5Handle;
std::string groupName = getHDF5GroupHandle();
if(groupName.compare("") != 0)
{
handle = H5Gopen(mImpl->mHDF5Handle, groupName.c_str(), H5P_DEFAULT);
}
hid_t dataset = H5Dcreate(handle, mImpl->mDataHierarchy.back().c_str(), datatype, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
hid_t dataset = H5Dcreate(mImpl->mHDF5Handle, dataSetName.str().c_str(), datatype, dataspace, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
status = H5Dwrite(dataset, datatype, H5S_ALL, H5S_ALL, H5P_DEFAULT, array.getValuesPointer());
if(groupName.compare("") != 0)
{
H5Gclose(handle);
}
status = H5Dclose(dataset);
status = H5Sclose(dataspace);
std::stringstream dataSetName;
dataSetName << mImpl->mHeavyFileName << ":" << groupName << "/" << mImpl->mDataHierarchy.back();
mImpl->mLastWrittenDataSet = dataSetName.str();
std::stringstream writtenDataSetName;
writtenDataSetName << mImpl->mHeavyFileName << ":" << dataSetName.str();
mImpl->mLastWrittenDataSet = writtenDataSetName.str();
mImpl->mDataSetId++;
}
else
{
mImpl->mLastWrittenDataSet = "";
}
mImpl->mLastWrittenDataSet = "";
}
void XdmfHDF5Writer::visit(XdmfItem & item, boost::shared_ptr<Loki::BaseVisitor> visitor)
{
this->pushDataHierarchy(item);
item.traverse(visitor);
this->popDataHierarchy();
}
......@@ -33,23 +33,6 @@ public:
*/
std::string getLastWrittenDataSet() const;
/**
* Pop a string from the data hierarchy. This should be called whenever an XdmfItem is finished
* traversal, including in light data writers that work in conjunction with this heavy data writer.
*/
void popDataHierarchy();
/**
* Push a string associated with this XdmfItem to the dataHierarchy. This should be called
* whenever an XdmfItem is traversed, including in light data writers that work in conjunction
* with this heavy data writer. The data hierarchy ensures that HDF5 datasets are created at
* correct locations in the hdf5 file. This string is either the item property "Name" or the
* item tag.
*
* @param item the XdmfItem being traversed.
*/
void pushDataHierarchy(const XdmfItem & item);
/**
* Write an XdmfArray to HDF5.
*
......@@ -58,14 +41,6 @@ public:
*/
void visit(XdmfArray & array, boost::shared_ptr<Loki::BaseVisitor> visitor);
/**
* Traverse an XdmfItem structure in order to find XdmfArrays to write to HDF5.
*
* @param item an XdmfItem to traverse.
* @param visitor a smart pointer to this visitor --- aids in grid traversal.
*/
void visit(XdmfItem & item, boost::shared_ptr<Loki::BaseVisitor> visitor);
protected:
/**
......@@ -89,25 +64,6 @@ private:
XdmfHDF5Writer(const XdmfHDF5Writer & hdf5Writer); // Not implemented.
void operator=(const XdmfHDF5Writer & hdf5Writer); // Not implemented.
/**
* Create a new HDF5 group if needed based on the dataHierarchy. This is a recursive function used by getHDF5GroupHandle to construct
* new hdf5 groups.
*
* @param groupPath the current place in the dataHierarchy being processed.
* @param index the index in the dataHierarchy being processed.
*
* @return a string containing the path to the created group.
*/
std::string createHDF5Group(std::stringstream & groupPath, int index = 0);
/**
* Get a handle to a hdf5 group to write into. Uses the dataHierarchy to construct an appropriate hdf5 group name
* at the current point in writing.
*
* @return a string containing the path to the created group.
*/
std::string getHDF5GroupHandle();
XdmfHDF5WriterImpl * mImpl;
};
......
......@@ -90,8 +90,6 @@ void XdmfWriter::visit(XdmfItem & item, boost::shared_ptr<Loki::BaseVisitor> vis
{
xmlNewProp(mImpl->mXMLCurrentNode, (xmlChar*)iter->first.c_str(), (xmlChar*)iter->second.c_str());
}
mImpl->mHDF5Writer->pushDataHierarchy(item);
item.traverse(visitor);
mImpl->mHDF5Writer->popDataHierarchy();
mImpl->mXMLCurrentNode = parentNode;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment