Commit 1c4b3e25 authored by Andrew J. Burns (Cont's avatar Andrew J. Burns (Cont
Browse files

changes to fortran for polylines and file splitting works for single dimensional arrays

parent b8e830bf
......@@ -392,7 +392,7 @@ public:
{
unsigned int size = mStartIndex + mNumValues;
if(mArrayStride > 1) {
size = mStartIndex + mNumValues * mArrayStride - 1;
size = mStartIndex + mNumValues * mArrayStride - (mStartIndex%mArrayStride);
}
if(array->size() < size) {
array->resize(size);
......@@ -1757,12 +1757,21 @@ void
XdmfArray::read()
{
if(mHeavyDataControllers.size() > 0) {
mHeavyDataControllers[0]->read(this);
for (int i = 1; i < mHeavyDataControllers.size(); i++)
this->release();
for (int i = 0; i < mHeavyDataControllers.size(); i++)
{
shared_ptr<XdmfArray> tempArray = XdmfArray::New();
mHeavyDataControllers[i]->read(tempArray.get());
this->insert(this->getSize(), tempArray, 0, tempArray->getSize());
unsigned int startsTotal = 0;
unsigned int strideTotal = 1;
unsigned int dimTotal = 1;
for (int j = 0; j < mHeavyDataControllers[i]->getDimensions().size(); j++) {
strideTotal *= mHeavyDataControllers[i]->getStride()[j];
startsTotal += dimTotal * mHeavyDataControllers[i]->getStart()[j];
dimTotal *= mHeavyDataControllers[i]->getDimensions()[j];
}
this->insert(mHeavyDataControllers[i]->getArrayOffset() + startsTotal, tempArray, 0, dimTotal, strideTotal, 1);
}
}
}
......
......@@ -433,35 +433,8 @@ XdmfHDF5Writer::write(XdmfArray & array,
// might need to check after all as overwrite might expand data size.
//might need to check for hyperslab, if the data wasn't alloted yet.
bool splittingPossible = false;
//check if splitting is necessary
if (mMode == Overwrite) {//might need a split if data written is larger than data alotted
splittingPossible = true;
}
if (mMode == Default) {//new data set is created with each call
splittingPossible = true;
}
if (mMode == Append) {//data is added onto end of sets
splittingPossible = true;
}
if (mMode == Hyperslab) {//splitting is only required if the slab is not set up yet
//check if slab already exists
int numData = mImpl->openFile(hdf5FilePath,
fapl);
if (numData > 0) {//if it already exists the file does not need to be split.
splittingPossible = false;
}
else {
splittingPossible = true;
}
}
//this is the file splitting algorithm
if (mImpl->mHDF5FileSizeLimit > 0 && splittingPossible) {//only if the file limit is positive, disabled if 0 or negative
//repeat until a suitable file is found
bool suitableFound = false;
unsigned int currentDimension = 0;
unsigned int previousDimension = currentDimension;
if (mImpl->mHDF5FileSizeLimit > 0) {//only if the file limit is positive, disabled if 0 or negative
unsigned int previousDataSize = 0;
std::vector<unsigned int> previousDimensions;
......@@ -481,6 +454,7 @@ XdmfHDF5Writer::write(XdmfArray & array,
{
containedInController *= dataspaceDimensions[j];
}
hssize_t hyperslabSize = 0;
while (amountAlreadyWritten < containedInController) {
......@@ -489,7 +463,6 @@ XdmfHDF5Writer::write(XdmfArray & array,
std::vector<unsigned int> partialDimensions;
std::vector<unsigned int> partialDataSizes;
std::stringstream testFile;
if (mImpl->mFileIndex == 0) {//if sequentially named files need to be created or referenced
testFile << checkFileName << "." << checkFileExt;
......@@ -497,7 +470,6 @@ XdmfHDF5Writer::write(XdmfArray & array,
else {
testFile << checkFileName << mImpl->mFileIndex << "." << checkFileExt;
}
int sizeOffset = 0;
FILE *checkFile = NULL;
int fileSize = 0;//if the file doesn't exist the size is 0 because there's no data
// get the file stream
......@@ -509,7 +481,7 @@ XdmfHDF5Writer::write(XdmfArray & array,
fileSize = ftell(checkFile);
//if overwrite subtract previous data size.
if (mMode == Overwrite) {
if (mMode == Overwrite || mMode == Hyperslab) {
//find previous data size
mImpl->openFile(testFile.str(),
fapl);
......@@ -523,15 +495,27 @@ XdmfHDF5Writer::write(XdmfArray & array,
if(checkspace != H5S_ALL) {
status = H5Sclose(checkspace);
}
fileSize = fileSize - checksize;//remove previous set's size, since it's overwritten
if (fileSize < 0) {
fileSize = 0;
if (mMode == Overwrite) {
fileSize = fileSize - checksize;//remove previous set's size, since it's overwritten
if (fileSize < 0) {
fileSize = 0;
}
if (fileSize == 0) {
fileSize += 800;
}
}
else if (mMode == Hyperslab) {
hyperslabSize = checksize;
printf("size of existing hyperslab = %d\n", hyperslabSize);
}
}
if (fileSize == 0) {
fileSize += 800;
}
fclose(checkFile);
}
else if (previousDataSize == 0) {
sizeOffset += 800;//base size of an hdf5 file is 800
fileSize += 800;//base size of an hdf5 file is 800
}
// close stream and release buffer
//check size to see if it's within range
......@@ -847,7 +831,6 @@ if (closeDatatype == true) //closetype is only true if strings are being used, i
}
//move to next file
mImpl->mFileIndex++;
previousDataSize = 0;
}
}
else
......@@ -882,7 +865,8 @@ else
break;
}
unsigned int dataItemSize = array.getArrayType()->getElementSize();
unsigned int dataItemSize = array.getArrayType()->getElementSize();
//if remaining size is less than available space, just write all of what's left
if ((remainingValues * dataItemSize) + previousDataSize + fileSize < mImpl->mHDF5FileSizeLimit*(1024*1024))
......@@ -988,12 +972,17 @@ else
else//otherwise, take remaining size and start removing dimensions until the dimension block is less, then take a fraction of the dimension
{
//calculate the number of values of the data type you're using will fit
(mImpl->mHDF5FileSizeLimit*(1024*1024) - (previousDataSize + fileSize)));
unsigned int usableSpace = (mImpl->mHDF5FileSizeLimit*(1024*1024) - (previousDataSize + fileSize)) / dataItemSize;
if (mImpl->mHDF5FileSizeLimit*(1024*1024) < (previousDataSize + fileSize))
unsigned int usableSpace = (mImpl->mHDF5FileSizeLimit*(1024*1024) - fileSize) / dataItemSize;
printf("fileSize = %d\n", fileSize);
printf("previousDataSize = %d\n", previousDataSize);
if (mImpl->mHDF5FileSizeLimit*(1024*1024) < fileSize)
{
usableSpace = 0;
}
printf("usableSpace = %d\n", usableSpace);
usableSpace += hyperslabSize-previousDataSize;
printf("usableSpace after adjustment = %d\n", usableSpace);
//if the array hasn't been split
if (amountAlreadyWritten == 0)
{
......@@ -1028,8 +1017,14 @@ else
partialDimensions.push_back(dimensions[j]);
partialDataSizes.push_back(dataspaceDimensions[j]);
}
partialStarts.push_back(start[j]);
if (start[j] > numBlocks)
{
partialStarts.push_back(numBlocks-1);
}
else
{
partialStarts.push_back(start[j]);
}
partialStrides.push_back(stride[j]);
partialDataSizes.push_back(numBlocks);
if (dimensions[j] == dataspaceDimensions[j])//this is for non-hyperslab and specific cases of hyperslab
......@@ -1039,11 +1034,16 @@ else
else
{//for hyperslab in general
//determine how many values from the array will fit into the blocks being used with the dimensions specified
unsigned int displacement = (numBlocks - start[j]) / stride[j];
if (numBlocks - (displacement * stride[j]) - start[j] > 0)
unsigned int displacement = numBlocks / stride[j];
if (((int)displacement * (int)stride[j]) + (start[j] % stride[j]) < numBlocks)
{
displacement++;
}
}
displacement -= start[j]/stride[j];
if (start[j] > numBlocks)
{
displacement = 0;
}
if (dimensions[j] <= displacement)//if there are less values than there are space for, just write all of them.
{
partialDimensions.push_back(dimensions[j]);
......@@ -1105,11 +1105,16 @@ else
partialDataSizes.push_back(numBlocks);
//determine how many values from the array will fit into the blocks being used
//with the dimensions specified
unsigned int displacement = (numBlocks - newStart) / stride[j];
if (numBlocks - (displacement * stride[j]) - newStart > 0)
unsigned int displacement = numBlocks / stride[j];
if (((int)displacement * (int)stride[j]) + (newStart % stride[j]) < numBlocks)
{
displacement++;
}
displacement -= newStart/stride[j];
if (newStart > numBlocks)
{
displacement = 0;
}
if ((dimensions[j] - previousDimensions[j]) <= displacement)
{//if there are less values than there are space for, just write all of them.
partialDimensions.push_back(dimensions[j] - previousDimensions[j]);
......@@ -1143,10 +1148,12 @@ else
}
}
//move to next file
printf("moving to the next file\n");
mImpl->mFileIndex++;
}
}
if (partialDimensions.size() > 0)
{//building the array to be written
int containedInDimensions = 1;//count moved
......@@ -1170,13 +1177,12 @@ if (partialDimensions.size() > 0)
startOffset = 0;
}
containedInPriorDimensions += startOffset;
int dimensionTotal = 1;
for (int j = 0; j < dimensions.size(); j++)
{
dimensionTotal *= dimensions[j];
}
int dimensionTotal = 1;
for (int j = 0; j < dimensions.size(); j++)
{
dimensionTotal *= dimensions[j];
}
//start = partialStarts multiplied together + amount already written
//stride = strides multiplied together
......@@ -1190,11 +1196,8 @@ if (partialDimensions.size() > 0)
}
if (containedInDimensions*totalStride + containedInPriorDimensions == dimensionTotal)
if (containedInDimensions > 0)
{
controllerIndexOffset += dimensionTotal;
}
shared_ptr<XdmfArray> partialArray = XdmfArray::New();
if (datatype == H5T_NATIVE_CHAR){
......@@ -1284,6 +1287,14 @@ if (partialDimensions.size() > 0)
dimensionsWritten.push_back(partialDimensions);
dataSizesWritten.push_back(partialDataSizes);
arrayOffsetsWritten.push_back(containedInPriorDimensions);
}
if (containedInDimensions*totalStride + containedInPriorDimensions == dimensionTotal)
{
controllerIndexOffset += dimensionTotal;
}
//for hyperslab the space is controlled by the dataspace dimensions
//so use that since the dimensions should be equal to the dataspace dimensions in all other variations
......@@ -1537,6 +1548,7 @@ if (mMode == Append) {
{
i++;
mImpl->mFileIndex = origFileIndex;
controllerIndexOffset = 0;
}
}
......
......@@ -47,9 +47,16 @@ int main(int, char **)
writtenArray->accept(arrayWriter);
writtenArray->release();
printf("after release\narray contains: %s\n", writtenArray->getValuesString());
writtenArray->read();
printf("%s\n\n", writtenArray->getValuesString());
//printf("%s\n", writtenArray->getValuesString());
printf("array size = %d\n", writtenArray->getSize());
for (int i = 0; i < writtenArray->getSize(); i++)
{
if (i != writtenArray->getValue<int>(i))
{
printf("%d doesn't match %d\n", i, writtenArray->getValue<int>(i));
}
}
return 0;
}
......@@ -5890,6 +5890,7 @@ XdmfFortran::write(const char * const xmlFilePath, const int datalimit, const bo
shared_ptr<XdmfWriter> writer = XdmfWriter::New(xmlFilePath);
writer->setLightDataLimit(datalimit);
writer->getHeavyDataWriter()->setReleaseData(release);
shared_dynamic_cast<XdmfHDF5Writer>(writer->getHeavyDataWriter())->setFileSizeLimit(1);
mDomain->accept(writer);
}
......@@ -5908,6 +5909,26 @@ XdmfFortran::read(const char * const xmlFilePath)
mDomain = shared_dynamic_cast<XdmfDomain>(reader->read( xmlFilePath ));
}
//temporary fix, hopefully
int
XdmfFortran::setTopologyPolyline(const unsigned int nodesPerElement,
const unsigned int numValues,
const int arrayType,
const void * const connectivityValues)
{
mTopology = XdmfTopology::New();
mTopology->setType(XdmfTopologyType::Polyline(nodesPerElement));
// insert connectivity values into array
writeToArray(mTopology,
numValues,
arrayType,
connectivityValues);
const int id = mPreviousTopologies.size();
mPreviousTopologies.push_back(mTopology);
return id;
}
//
// C++ will mangle the name based on the argument list. This tells the
// compiler not to mangle the name so we can call it from 'C' (but
......@@ -6042,15 +6063,14 @@ extern "C"
int * topologyType,
int * numValues,
int * arrayType,
void * connectivityValues,
int * numVals)
void * connectivityValues)
{
XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
return xdmfFortran->setTopology(*topologyType,
*numValues,
*arrayType,
connectivityValues,
*numVals);
0);
}
......@@ -7229,5 +7249,19 @@ extern "C"
xdmfFortran->read( xmlFilePath );
}
}
int
XdmfSetTopologyPolyline(long * pointer,
int * nodesPerElement,
int * numValues,
int * arrayType,
void * connectivityValues)
{
XdmfFortran * xdmfFortran = reinterpret_cast<XdmfFortran *>(*pointer);
return xdmfFortran->setTopologyPolyline(*nodesPerElement,
*numValues,
*arrayType,
connectivityValues);
}
}
......@@ -164,6 +164,8 @@ class XdmfUnstructuredGrid;
#define XdmfWriteHDF5 xdmfwritehdf5_
#define XdmfSetTopologyPolyline xdmfsettopologypolyline_
#define XdmfRetrieveNumDomainGridCollections xdmfretrievenumdomaingridcollections_
#define XdmfRetrieveNumGridCollectionGridCollections xdmfretrievenumgridcollectiongridcollections_
......@@ -2196,6 +2198,23 @@ public:
void read(const char * const xmlFilePath);
/**
* Set the topology (connectivity data) for a polyline that will be
* added to the next grid.
*
* @param nodesPerElement number of nodes in the polyline.
* @param numValues number of connectivity values to copy.
* @param arrayType type of connectivity values.
* @param connectivityValues array of connectivity values.
*
* @return int providing id to fortran if reusing.
*/
int setTopologyPolyline(const unsigned int nodesPerElement,
const unsigned int numValues,
const int arrayType,
const void * const connectivityValues);
private:
shared_ptr<XdmfDomain> mDomain;
......
......@@ -165,7 +165,7 @@ PROGRAM XdmfFortranExample
CALL XDMFADDGRID(obj, 'Identical'//CHAR(0), XDMF_GRID_TYPE_UNSTRUCTURED)
CALL XDMFCLOSEGRIDCOLLECTION(obj)
!! CALL XDMFWRITEHDF5(obj, 'my_output.h5'//CHAR(0))
CALL XDMFWRITE(obj, filename)
CALL XDMFWRITE(obj, filename, 10, .TRUE.)
CALL XDMFCLOSE(obj)
......
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