Commit 99ace678 authored by Kenneth Leiter's avatar Kenneth Leiter

ENH: Rethink XdmfWriter / XdmfCoreWriter distinction and move XdmfSet to...

ENH: Rethink XdmfWriter / XdmfCoreWriter distinction and move XdmfSet to XdmfArray conversion in XdmfSet's traverse method.  If conversion is unneeded then do not traverse XdmfSet.
parent af488332
......@@ -26,7 +26,6 @@ set(XdmfSources
XdmfTime
XdmfTopology
XdmfTopologyType
XdmfWriter
)
add_library(Xdmf ${XdmfSources})
......
......@@ -16,6 +16,7 @@ swig -v -c++ -python -o XdmfPython.cpp Xdmf.i
#include <XdmfInformation.hpp>
#include <XdmfItem.hpp>
#include <XdmfItemProperty.hpp>
#include <XdmfSystemUtils.hpp>
#include <XdmfVisitor.hpp>
#include <XdmfWriter.hpp>
......@@ -87,6 +88,12 @@ swig -v -c++ -python -o XdmfPython.cpp Xdmf.i
}
}
%include std_set.i
%template(std_set_uint) std::set<unsigned int>;
// Abstract Base Classes
%template() Loki::Visitor<XdmfSet>;
// Shared Pointer Templates
%shared_ptr(XdmfAttribute)
%shared_ptr(XdmfAttributeCenter)
......
......@@ -45,7 +45,7 @@ unsigned int XdmfGeometry::getNumberPoints() const
{
return 0;
}
return this->getArray()->getSize() / mGeometryType->getDimensions();
return this->getArray()->size() / mGeometryType->getDimensions();
}
boost::shared_ptr<const XdmfGeometryType> XdmfGeometry::getType() const
......
......@@ -57,16 +57,11 @@ std::string XdmfSet::getName() const
return mName;
}
boost::shared_ptr<const XdmfSetType> XdmfSet::getSetType() const
boost::shared_ptr<const XdmfSetType> XdmfSet::getType() const
{
return mSetType;
}
bool XdmfSet::isInitialized() const
{
return this->size() > 0;
}
void XdmfSet::populateItem(const std::map<std::string, std::string> & itemProperties, std::vector<boost::shared_ptr<XdmfItem> > & childItems)
{
std::map<std::string, std::string>::const_iterator name = itemProperties.find("Name");
......@@ -84,7 +79,7 @@ void XdmfSet::populateItem(const std::map<std::string, std::string> & itemProper
{
if(array->isInitialized())
{
for(unsigned int i=0; i<array->getSize(); ++i)
for(unsigned int i=0; i<array->size(); ++i)
{
this->insert(array->getValueCopy<unsigned int>(i));
}
......@@ -104,7 +99,7 @@ void XdmfSet::read()
{
boost::shared_ptr<XdmfArray> setValues = XdmfArray::New();
mHDF5Controller->read(setValues.get());
for(unsigned int i=0; i<setValues->getSize(); ++i)
for(unsigned int i=0; i<setValues->size(); ++i)
{
this->insert(setValues->getValueCopy<unsigned int>(i));
}
......@@ -126,7 +121,7 @@ void XdmfSet::setName(const std::string & name)
mName= name;
}
void XdmfSet::setSetType(const boost::shared_ptr<const XdmfSetType> setType)
void XdmfSet::setType(const boost::shared_ptr<const XdmfSetType> setType)
{
mSetType = setType;
}
......@@ -137,5 +132,21 @@ std::size_t XdmfSet::size() const
{
return std::set<unsigned int>::size();
}
return mHDF5Controller->getSize();
else if(mHDF5Controller)
{
return mHDF5Controller->getSize();
}
return 0;
}
void XdmfSet::traverse(const boost::shared_ptr<XdmfBaseVisitor> visitor) const
{
boost::shared_ptr<XdmfArray> setValues = XdmfArray::New();
setValues->reserve(std::set<unsigned int>::size());
for(XdmfSet::const_iterator iter = this->begin(); iter != this->end(); ++iter)
{
setValues->pushBack(*iter);
}
setValues->setHDF5Controller(mHDF5Controller);
setValues->accept(visitor);
}
......@@ -22,8 +22,6 @@ class XdmfSet : public XdmfItem,
public:
// TODO: isInitialized is broken the way it is coded. Always if size == 0 it is uninitialized...
/**
* Create a new XdmfSet.
*
......@@ -66,12 +64,7 @@ public:
*
* @return XdmfSetType of this set.
*/
boost::shared_ptr<const XdmfSetType> getSetType() const;
/**
* Returns whether the set is initialized (contains values in memory).
*/
bool isInitialized() const;
boost::shared_ptr<const XdmfSetType> getType() const;
/**
* Read data from disk into memory.
......@@ -102,13 +95,17 @@ public:
*
* @param setType the XdmfSetType to set.
*/
void setSetType(const boost::shared_ptr<const XdmfSetType> setType);
void setType(const boost::shared_ptr<const XdmfSetType> setType);
std::size_t size() const;
protected:
void traverse(const boost::shared_ptr<XdmfBaseVisitor> visitor) const;
XdmfSet();
protected:
virtual void populateItem(const std::map<std::string, std::string> & itemProperties, std::vector<boost::shared_ptr<XdmfItem> > & childItems);
private:
......
......@@ -51,7 +51,7 @@ unsigned int XdmfTopology::getNumberElements() const
{
return 0;
}
return this->getArray()->getSize() / mTopologyType->getNodesPerElement();
return this->getArray()->size() / mTopologyType->getNodesPerElement();
}
boost::shared_ptr<const XdmfTopologyType> XdmfTopology::getType() const
......
// Kenneth Leiter
// Xdmf Smart Pointer Test
#include "XdmfArray.hpp"
#include "XdmfSet.hpp"
#include "XdmfWriter.hpp"
#include <iostream>
boost::shared_ptr<XdmfWriter> XdmfWriter::New(const std::string & xmlFilePath)
{
boost::shared_ptr<XdmfWriter> p(new XdmfWriter(xmlFilePath));
return p;
}
boost::shared_ptr<XdmfWriter> XdmfWriter::New(const std::string & xmlFilePath, const boost::shared_ptr<XdmfHDF5Writer> hdf5Writer)
{
boost::shared_ptr<XdmfWriter> p(new XdmfWriter(xmlFilePath, hdf5Writer));
return p;
}
XdmfWriter::XdmfWriter(const std::string & xmlFilePath) :
XdmfCoreWriter(xmlFilePath)
{
}
XdmfWriter::XdmfWriter(const std::string & xmlFilePath, boost::shared_ptr<XdmfHDF5Writer> hdf5Writer) :
XdmfCoreWriter(xmlFilePath, hdf5Writer)
{
}
XdmfWriter::~XdmfWriter()
{
}
void XdmfWriter::visit(XdmfSet & set, const boost::shared_ptr<XdmfBaseVisitor> visitor)
{
XdmfCoreWriter::visit(dynamic_cast<XdmfItem &>(set), visitor);
boost::shared_ptr<XdmfArray> setValues = XdmfArray::New();
if(set.isInitialized())
{
setValues->reserve(set.size());
for(XdmfSet::const_iterator iter = set.begin(); iter != set.end(); ++iter)
{
setValues->pushBack(*iter);
}
}
setValues->setHDF5Controller(set.getHDF5Controller());
XdmfCoreWriter::moveToLastWrittenNode();
XdmfCoreWriter::visit(*setValues.get(), visitor);
XdmfCoreWriter::moveToParentNode();
}
#ifndef XDMFWRITER_HPP_
#define XDMFWRITER_HPP_
// Forward Declarations
class XdmfSet;
// Includes
#include "XdmfCoreWriter.hpp"
/**
* @brief Traverse the Xdmf graph and write light and heavy data stored to disk.
*
* XdmfWriter visits each node of an Xdmf graph structure and writes data to disk. Writing begins by calling the
* accept() operation on any XdmfItem and supplying this writer as the parameter. The XdmfItem as well as all children
* attached to the XdmfItem are written to disk. Heavy data is written to HDF5 format using the XdmfHDF5Writer and light
* data is written to XML.
*
* By default, the XdmfWriter writes all heavy data to a single heavy data file specified by the XdmfHDF5Writer.
* If a dataset is encountered that resides in a different heavy data file on disk, the dataset is read from disk and written
* to the new hdf5 file. If this is undesired, the XdmfWriter can be set to DistributedHeavyData mode in which the writer
* will automatically reference any hdf5 dataset even if it resides in a different file than the one currently being written to.
* written.
*/
class XdmfWriter : public XdmfCoreWriter,
public Loki::Visitor<XdmfSet> {
public:
/**
* Create a new XdmfWriter to write Xdmf data to disk. This will create its own hdf5 writer based on the xmlFileName.
* For example, if supplied "output.xmf" the created hdf5 writer would write to file "output.h5".
*
* @param xmlFilePath the path to the xml file to write to.
* @return the new XdmfWriter.
*/
static boost::shared_ptr<XdmfWriter> New(const std::string & xmlFilePath);
/**
* Create a new XdmfWriter to write Xdmf data to disk. This will utilize the supplied hdf5Writer to write any
* heavy data to disk.
*
* @param xmlFilePath the path to the xml file to write to.
* @param hdf5Writer the heavy data writer to use when writing.
* @return the new XdmfWriter.
*/
static boost::shared_ptr<XdmfWriter> New(const std::string & xmlFilePath, const boost::shared_ptr<XdmfHDF5Writer> hdf5Writer);
virtual ~XdmfWriter();
/**
* Write an XdmfSet to disk
*
* @param set an XdmfSet to write to disk.
* @param visitor a smart pointer to this visitor --- aids in grid traversal.
*/
void visit(XdmfSet & set, const boost::shared_ptr<XdmfBaseVisitor> visitor);
protected:
XdmfWriter(const std::string & xmlFilePath);
XdmfWriter(const std::string & xmlFilePath, boost::shared_ptr<XdmfHDF5Writer> hdf5Writer);
private:
XdmfWriter(const XdmfWriter & writer); // Not implemented.
void operator=(const XdmfWriter & writer); // Not implemented.
};
#endif /* XDMFWRITER_HPP_ */
......@@ -25,7 +25,6 @@ set(XdmfCoreSources
XdmfArrayType
XdmfCoreItemFactory
XdmfCoreReader
XdmfCoreWriter
XdmfDataItem
XdmfHDF5Controller
XdmfHDF5Writer
......@@ -34,6 +33,7 @@ set(XdmfCoreSources
XdmfItemProperty
XdmfSystemUtils
XdmfVisitor
XdmfWriter
)
add_library(XdmfCore ${XdmfCoreSources})
......
......@@ -164,20 +164,6 @@ public:
}
};
class XdmfArray::GetSize : public boost::static_visitor<unsigned int> {
public:
GetSize()
{
}
template<typename T>
unsigned int operator()(const boost::shared_ptr<std::vector<T> > & array) const
{
return array->size();
}
};
class XdmfArray::GetValuesPointer : public boost::static_visitor<const void * const> {
public:
......@@ -315,6 +301,20 @@ private:
const unsigned int mSize;
};
class XdmfArray::Size : public boost::static_visitor<unsigned int> {
public:
Size()
{
}
template<typename T>
unsigned int operator()(const boost::shared_ptr<std::vector<T> > & array) const
{
return array->size();
}
};
boost::shared_ptr<XdmfArray> XdmfArray::New()
{
boost::shared_ptr<XdmfArray> p(new XdmfArray());
......@@ -401,7 +401,7 @@ std::map<std::string, std::string> XdmfArray::getItemProperties() const
arrayProperties["Format"] = "XML";
}
std::stringstream size;
size << this->getSize();
size << this->size();
arrayProperties["Dimensions"] = size.str();
if(mName.compare("") != 0)
{
......@@ -422,23 +422,6 @@ std::string XdmfArray::getName() const
return mName;
}
unsigned int XdmfArray::getSize() const
{
if(mHaveArray)
{
return boost::apply_visitor(GetSize(), mArray);
}
else if(mHaveArrayPointer)
{
return mArrayPointerNumValues;
}
else if(mHDF5Controller)
{
return mHDF5Controller->getSize();
}
return 0;
}
boost::shared_ptr<const XdmfArrayType> XdmfArray::getType() const
{
if(mHaveArray)
......@@ -691,6 +674,23 @@ void XdmfArray::setName(const std::string & name)
mName = name;
}
std::size_t XdmfArray::size() const
{
if(mHaveArray)
{
return boost::apply_visitor(Size(), mArray);
}
else if(mHaveArrayPointer)
{
return mArrayPointerNumValues;
}
else if(mHDF5Controller)
{
return mHDF5Controller->getSize();
}
return 0;
}
void XdmfArray::swap(const boost::shared_ptr<XdmfArray> array)
{
ArrayVariant tmpArray = array->mArray;
......
......@@ -59,7 +59,6 @@ public:
virtual ~XdmfArray();
LOKI_DEFINE_VISITABLE(XdmfArray, XdmfItem)
friend class XdmfHDF5Writer;
static const std::string ItemTag;
/**
......@@ -128,13 +127,6 @@ public:
*/
std::string getName() const;
/**
* Get the number of values stored in this array.
*
* @return the number of values stored in this array.
*/
unsigned int getSize() const;
/**
* Get the data type of this array.
*
......@@ -293,6 +285,13 @@ public:
template<typename T>
void setValues(const boost::shared_ptr<std::vector<T> > array);
/**
* Get the number of values stored in this array.
*
* @return the number of values stored in this array.
*/
std::size_t size() const;
/**
* Exchange the contents of the vector with the contents of this XdmfArray. No copy is made. The internal arrays are swapped.
*
......@@ -338,7 +337,6 @@ private:
class Erase;
class GetCapacity;
class GetHDF5Type;
class GetSize;
class GetType;
template <typename T>
......@@ -348,6 +346,7 @@ private:
class GetValuesString;
class InternalizeArrayPointer;
class NewArray;
struct NullDeleter;
template <typename T>
class PushBack;
......@@ -357,7 +356,7 @@ private:
template <typename T>
class Resize;
struct NullDeleter;
class Size;
/**
* After setValues(const T * const array) is called, XdmfArray stores a pointer that is not allowed to be modified through
......
......@@ -7,17 +7,17 @@ swig -v -c++ -python -o XdmfCorePython.cpp XdmfCore.i
%{
#include <XdmfArray.hpp>
#include <XdmfArrayType.hpp>
#include <XdmfCoreHDF5Writer.hpp>
#include <XdmfCoreItemFactory.hpp>
#include <XdmfCoreReader.hpp>
#include <XdmfCoreWriter.hpp>
#include <XdmfDataItem.hpp>
#include <XdmfHDF5Controller.hpp>
#include <XdmfHDF5Writer.hpp>
#include <XdmfInformation.hpp>
#include <XdmfItem.hpp>
#include <XdmfItemProperty.hpp>
#include <XdmfSystemUtils.hpp>
#include <XdmfVisitor.hpp>
#include <XdmfWriter.hpp>
%}
%include boost_shared_ptr.i
......@@ -25,12 +25,18 @@ swig -v -c++ -python -o XdmfCorePython.cpp XdmfCore.i
%include std_vector.i
%include loki/Visitor.h
// Abstract Base Classes
%template() Loki::BaseVisitable<void>;
%template() Loki::Visitor<XdmfArray>;
%template() Loki::Visitor<XdmfItem>;
// Shared Pointer Templates
%shared_ptr(XdmfArray)
%shared_ptr(XdmfArrayType)
%shared_ptr(XdmfBaseVisitor)
%shared_ptr(XdmfCoreItemFactory)
%shared_ptr(XdmfCoreReader)
%shared_ptr(XdmfCoreWriter)
%shared_ptr(XdmfDataItem)
%shared_ptr(XdmfHDF5Controller)
%shared_ptr(XdmfHDF5Writer)
......@@ -38,12 +44,6 @@ swig -v -c++ -python -o XdmfCorePython.cpp XdmfCore.i
%shared_ptr(XdmfItem)
%shared_ptr(XdmfItemProperty)
%shared_ptr(XdmfVisitor)
%shared_ptr(XdmfWriter)
// Abstract Base Classes
%template() Loki::BaseVisitable<void>;
%template() Loki::Visitor<XdmfArray>;
%template() Loki::Visitor<XdmfItem>;
%include XdmfItem.hpp
%include XdmfDataItem.hpp
......@@ -52,10 +52,10 @@ swig -v -c++ -python -o XdmfCorePython.cpp XdmfCore.i
%include XdmfCoreItemFactory.hpp
%include XdmfCoreReader.hpp
%include XdmfCoreWriter.hpp
%include XdmfInformation.hpp
%include XdmfHDF5Controller.hpp
%include XdmfHDF5Writer.hpp
%include XdmfWriter.hpp
%include XdmfArray.hpp
%include XdmfArrayType.hpp
......
......@@ -33,7 +33,7 @@ void XdmfDataItem::populateItem(const std::map<std::string, std::string> & itemP
{
if(boost::shared_ptr<XdmfArray> array = boost::shared_dynamic_cast<XdmfArray>(*iter))
{
if(mArray->getSize() == 0)
if(mArray->size() == 0)
{
this->setArray(array);
}
......@@ -44,9 +44,9 @@ void XdmfDataItem::populateItem(const std::map<std::string, std::string> & itemP
{
mArray->read();
}
const unsigned int oldSize = mArray->getSize();
mArray->resize(oldSize + array->getSize(), 0);
mArray->copyValues(oldSize, array, 0, array->getSize(), 1, 1);
const unsigned int oldSize = mArray->size();
mArray->resize(oldSize + array->size(), 0);
mArray->copyValues(oldSize, array, 0, array->size(), 1, 1);
}
}
}
......
......@@ -4,6 +4,7 @@
#include <hdf5.h>
#include <sstream>
#include "XdmfArray.hpp"
#include "XdmfArrayType.hpp"
#include "XdmfHDF5Controller.hpp"
#include "XdmfHDF5Writer.hpp"
......@@ -28,71 +29,6 @@ public:
Mode mMode;
};
class XdmfHDF5Writer::GetHDF5Type : public boost::static_visitor <hid_t> {
public:
GetHDF5Type()
{
}
hid_t getHDF5Type(const char * const) const
{
return H5T_NATIVE_CHAR;
}
hid_t getHDF5Type(const short * const) const
{
return H5T_NATIVE_SHORT;
}
hid_t getHDF5Type(const int * const) const
{
return H5T_NATIVE_INT;
}
hid_t getHDF5Type(const long * const) const
{
return H5T_NATIVE_LONG;
}
hid_t getHDF5Type(const float * const) const
{
return H5T_NATIVE_FLOAT;
}
hid_t getHDF5Type(const double * const) const
{
return H5T_NATIVE_DOUBLE;
}
hid_t getHDF5Type(const unsigned char * const) const
{
return H5T_NATIVE_UCHAR;
}
hid_t getHDF5Type(const unsigned short * const) const
{
return H5T_NATIVE_USHORT;
}
hid_t getHDF5Type(const unsigned int * const) const
{
return H5T_NATIVE_UINT;
}
template<typename T>
hid_t operator()(const boost::shared_ptr<std::vector<T> > & array) const
{
return this->getHDF5Type(&(array.get()->operator[](0)));
}
template<typename T>
hid_t operator()(const boost::shared_array<const T> & array) const
{
return this->getHDF5Type(array.get());
}
};
boost::shared_ptr<XdmfHDF5Writer> XdmfHDF5Writer::New(const std::string & hdf5FilePath)
{
boost::shared_ptr<XdmfHDF5Writer> p(new XdmfHDF5Writer(hdf5FilePath));
......@@ -128,13 +64,48 @@ void XdmfHDF5Writer::visit(XdmfArray & array, const boost::shared_ptr<XdmfBaseVi
{
hid_t datatype = -1;
if(array.mHaveArray)
if(array.isInitialized())
{
datatype = boost::apply_visitor(GetHDF5Type(), array.mArray);
}
else if(array.mHaveArrayPointer)
{
datatype = boost::apply_visitor(GetHDF5Type(), array.mArrayPointer);
if(array.getType() == XdmfArrayType::Int8())
{
datatype = H5T_NATIVE_CHAR;
}
else if(array.getType() == XdmfArrayType::Int16())
{
datatype = H5T_NATIVE_SHORT;
}
else if(array.getType() == XdmfArrayType::Int32())
{
datatype = H5T_NATIVE_INT;
}
else if(array.getType() == XdmfArrayType::Int64())
{
datatype = H5T_NATIVE_LONG;
}
else if(array.getType() == XdmfArrayType::Float32())
{
datatype = H5T_NATIVE_FLOAT;
}
else if(array.getType() == XdmfArrayType::Float64())
{
datatype = H5T_NATIVE_DOUBLE;
}
else if(array.getType() == XdmfArrayType::UInt8())
{
datatype = H5T_NATIVE_UCHAR;
}
else if(array.getType() == XdmfArrayType::UInt16())
{
datatype = H5T_NATIVE_USHORT;
}
else if(array.getType() == XdmfArrayType::UInt32())
{
datatype = H5T_NATIVE_UINT;
}
else
{
assert(false);
}
}
if(datatype != -1)
......@@ -142,11 +113,11 @@ void XdmfHDF5Writer::visit(XdmfArray & array, const boost::shared_ptr<XdmfBaseVi
std::string hdf5FilePath = mImpl->mFilePath;
std::stringstream dataSetPath;
if((mImpl->mMode == Overwrite || mImpl->mMode == Append) && array.mHDF5Controller)
if((mImpl->mMode == Overwrite || mImpl->mMode == Append) && array.getHDF5Controller())
{
// Write to the previous dataset
dataSetPath << array.mHDF5Controller->getDataSetPath();
hdf5FilePath = array.mHDF5Controller->getFilePath();
dataSetPath << array.getHDF5Controller()->getDataSetPath();
hdf5FilePath = array.getHDF5Controller()->getFilePath();
}
else
{
......@@ -155,7 +126,7 @@ void XdmfHDF5Writer::visit(XdmfArray & array, const boost::shared_ptr<XdmfBaseVi
// Open a hdf5 dataset and write to it on disk.
herr_t status;
hsize_t size = array.getSize();
hsize_t size = array.size();
hid_t hdf5Handle;
// Save old error handler and turn off error handling for now
......@@ -228,9 +199,9 @@ void XdmfHDF5Writer::visit(XdmfArray & array, const boost::shared_ptr<XdmfBaseVi
H5Eset_auto2(0, old_func, old_client_data);
// Attach a new controller to the array if needed.
if(mImpl->mMode == Default || !array.mHDF5Controller)
if(mImpl->mMode == Default || !array.getHDF5Controller())
{
boost::shared_ptr<XdmfHDF5Controller> newDataSetController = XdmfHDF5Controller::New(hdf5FilePath, dataSetPath.str(), array.getSize(), array.getType());
boost::shared_ptr<XdmfHDF5Controller> newDataSetController = XdmfHDF5Controller::New(hdf5FilePath, dataSetPath.str(), array.size(), array.getType());
array.setHDF5Controller(newDataSetController);
mImpl->mDataSetId++;
}
......
......@@ -16,7 +16,7 @@ class XdmfArray;
* disk. It will also attach an XdmfHDF5Controller to all XdmfArrays that it writes to disk.
*
* There are three modes of operation for this writer:
* Default - All initialized XdmfArrays are written to new hdf5 datasets irregardless of whether they
* Default - All initialized XdmfArrays are written to new hdf5 datasets regardless of whether they
* are attached to another hdf5 dataset on disk via an XdmfHDF5Controller.
* Overwrite - If an initialized XdmfArray is attached to an hdf5 dataset via an XdmfHDF5Contoller the writer
* will write values to that location, overwriting all previous written values.
......@@ -82,9 +82,6 @@ private:
*/
class XdmfHDF5WriterImpl;
// Variant Visitor Operation
class GetHDF5Type;
XdmfHDF5Writer(const XdmfHDF5Writer & hdf5Writer); // Not implemented.
void operator=(const XdmfHDF5Writer & hdf5Writer); // Not implemented.
......
......@@ -4,20 +4,20 @@
#include <libxml/tree.h>
#include <sstream>
#include "XdmfArray.hpp"
#include "XdmfCoreWriter.hpp"
#include "XdmfItem.hpp"
#include "XdmfHDF5Controller.hpp"
#include "XdmfHDF5Writer.hpp"
#include "XdmfSystemUtils.hpp"
#include "XdmfWriter.hpp"
/**
* PIMPL
*/
class XdmfCoreWriter::XdmfCoreWriterImpl {
class XdmfWriter::XdmfWriterImpl {
public:
XdmfCoreWriterImpl(const std::string & xmlFilePath, const boost::shared_ptr<