Commit ad47d6ab authored by Chuck Atkins's avatar Chuck Atkins

ADIOS: Properly handle variable sized data.

Rework the ADIOS writer and reader to properly address arrays that change size
across timesteps.

Change-Id: I1612308accc36213cb2d21705088a058aba2d591
parent e2737bb7
/*=========================================================================
Program: Visualization Toolkit
Module: ADIOSAttribute.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include <cstdlib>
#include "ADIOSAttribute.h"
namespace ADIOS
{
//----------------------------------------------------------------------------
Attribute::Attribute(ADIOS_FILE *f, int id)
: Id(id), Name(f->attr_namelist[id])
{
int err, typeSize;
err = adios_get_attr_byid(f, id, &this->Type, &typeSize, &this->Value);
ReadError::TestEq(0, err);
}
//----------------------------------------------------------------------------
Attribute::~Attribute()
{
if(this->Value)
{
std::free(this->Value);
}
}
//----------------------------------------------------------------------------
const int& Attribute::GetId() const
{
return this->Id;
}
//----------------------------------------------------------------------------
const ADIOS_DATATYPES& Attribute::GetType() const
{
return this->Type;
}
//----------------------------------------------------------------------------
const std::string& Attribute::GetName(void) const
{
return this->Name;
}
//----------------------------------------------------------------------------
template<>
const std::string Attribute::GetValue<std::string>() const
{
ReadError::TestEq(this->Type, adios_string, "Invalid type");
return reinterpret_cast<const char*>(this->Value);
}
} // End namespace ADIOS
......@@ -12,34 +12,45 @@
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME ADIOSAttribute - The utility class wrapping static ADIOS sttributes
#ifndef _ADIOSAttribute_h
#define _ADIOSAttribute_h
#include <string>
#include <vector>
#include <adios_types.h>
struct ADIOSAttributeImpl;
#include <adios_read.h>
#include "ADIOSUtilities.h"
//----------------------------------------------------------------------------
class ADIOSAttribute
namespace ADIOS
{
class Attribute
{
public:
ADIOSAttribute(ADIOSAttributeImpl *impl);
~ADIOSAttribute(void);
Attribute(ADIOS_FILE *f, int id);
~Attribute(void);
const int& GetId() const;
const ADIOS_DATATYPES& GetType() const;
const std::string& GetName(void) const;
int GetId(void) const;
ADIOS_DATATYPES GetType(void) const;
template<typename T>
T GetValue(void) const;
private:
ADIOSAttributeImpl *Impl;
const T GetValue() const
{
ReadError::TestEq(this->Type, Type::NativeToADIOS<T>(), "Invalid type");
return *reinterpret_cast<const T*>(this->Value);
}
protected:
int Id;
ADIOS_DATATYPES Type;
std::string Name;
void* Value;
};
template<> const std::string Attribute::GetValue<std::string>() const;
} // End namespace ADIOS
#endif // _ADIOSAttribute_h
// VTK-HeaderTest-Exclude: ADIOSAttribute.h
/*=========================================================================
Program: Visualization Toolkit
Module: ADIOSDefs.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "ADIOSDefs.h"
namespace ADIOS
......
/*=========================================================================
Program: Visualization Toolkit
Module: ADIOSDefs.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#ifndef __ADIOSDefs_h
#define __ADIOSDefs_h
......
This diff is collapsed.
......@@ -17,35 +17,32 @@
#ifndef _ADIOSReader_h
#define _ADIOSReader_h
#include <stdexcept>
#include <string>
#include <vector>
#include <utility>
#include <adios_mpi.h>
#include <adios_read.h>
#include "ADIOSAttribute.h"
#include "ADIOSDefs.h"
#include "ADIOSScalar.h"
#include "ADIOSVarInfo.h"
#include "ADIOSAttribute.h"
class ADIOSReader
namespace ADIOS
{
class Reader
{
public:
static bool SetCommunicator(MPI_Comm);
static bool SetReadMethod(ADIOS::ReadMethod, const std::string&);
protected:
struct Context;
Context *ReaderContext;
static bool SetReadMethod(ReadMethod, const std::string&);
public:
ADIOSReader();
~ADIOSReader();
Reader();
~Reader();
// Description:
// Open the ADIOS file and cache the variable names and scalar data
void OpenFile(const std::string &fileName);
void Open(const std::string &fileName);
// Description:
// Retrieve the total number of seps
......@@ -53,30 +50,21 @@ public:
// Description:
// Retrieve a list of attributes
const std::vector<ADIOSAttribute*>& GetAttributes() const;
const std::vector<const Attribute*>& GetAttributes() const;
// Description:
// Retrieve a list of scalars and thier associated metadata
const std::vector<ADIOSScalar*>& GetScalars() const;
const std::vector<const Scalar*>& GetScalars() const;
// Description:
// Retrieve a list of arrays and thier associated metadata
const std::vector<ADIOSVarInfo*>& GetArrays() const;
// Description:
// Schedule array data to be read. Data will be read with ReadArrays.
// step specified the time step index to read and block specifies the
// write block index to read (-1 means use whatever your current mpi rank is)
template<typename T>
void ScheduleReadArray(const std::string &path, T *data, int step,
int block=-1);
const std::vector<const VarInfo*>& GetArrays() const;
// Description:
// Schedule array data to be read. Data will be read with ReadArrays.
// step specified the time step index to read and block specifies the
// write block index to read (-1 means use whatever your current mpi rank is)
template<typename T>
void ScheduleReadArray(int id, T *data, int step, int block=-1);
void ScheduleReadArray(int id, void *data, int step, int block);
// Description:
// Perform all scheduled array read operations
......@@ -86,11 +74,16 @@ public:
// Whether or not the file / stream is already open
bool IsOpen() const;
protected:
struct ADIOSReaderImpl;
private:
// Initialization context to manage one-time init and finalize of ADIOS
struct InitContext;
InitContext *Ctx;
ADIOSReaderImpl *Impl;
// ADIOS specific implementation details (file handles, group sizes, etc.)
struct ReaderImpl;
ReaderImpl *Impl;
};
} // End anmespace ADIOS
#endif
// VTK-HeaderTest-Exclude: ADIOSReader.h
#include <cstring>
/*=========================================================================
#include "ADIOSScalar.h"
#include "ADIOSUtilities.h"
Program: Visualization Toolkit
Module: ADIOSScalar.cxx
#include <adios_read.h>
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
template<typename T>
void DecodeValues(ADIOS_FILE *f, const ADIOS_VARINFO *v,
std::vector<void*> &values)
{
for(int t = 0; t < v->nsteps; ++t)
{
std::vector<T> *data = new std::vector<T>(v->nblocks[t]);
values[t] = data;
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
for(int b = 0; b < v->nblocks[t]; ++b)
{
ADIOS_SELECTION *s = adios_selection_writeblock(b);
adios_schedule_read_byid(f, s, v->varid, t, 1, &(*data)[b]);
adios_perform_reads(f, 1);
adios_selection_delete(s);
}
}
}
=========================================================================*/
//----------------------------------------------------------------------------
ADIOSScalar::ADIOSScalar(ADIOS_FILE *f, ADIOS_VARINFO *v)
: Id(v->varid), Type(ADIOSUtilities::TypeADIOSToVTK(v->type)),
NumSteps(v->nsteps), Name(f->var_namelist[v->varid]), Values(v->nsteps)
{
int err;
#include <complex>
#include <stdexcept>
#include <adios_read.h>
err = adios_inq_var_stat(f, v, 1, 1);
ADIOSUtilities::TestReadErrorEq<int>(0, err);
#include "ADIOSScalar.h"
err = adios_inq_var_blockinfo(f, v);
ADIOSUtilities::TestReadErrorEq<int>(0, err);
namespace ADIOS
{
switch(v->type)
//----------------------------------------------------------------------------
Scalar::Scalar(ADIOS_FILE *f, ADIOS_VARINFO *v)
: VarInfo(f, v), Values(NULL)
{
// Allocate memory
switch(this->Type)
{
case adios_byte: DecodeValues<int8_t>(f, v, this->Values);
case adios_byte:
this->Values = new int8_t[v->sum_nblocks];
break;
case adios_short: DecodeValues<int16_t>(f, v, this->Values);
case adios_short:
this->Values = new int16_t[v->sum_nblocks];
break;
case adios_integer: DecodeValues<int32_t>(f, v, this->Values);
case adios_integer:
this->Values = new int32_t[v->sum_nblocks];
break;
case adios_long: DecodeValues<vtkIdType>(f, v, this->Values);
case adios_long:
this->Values = new int64_t[v->sum_nblocks];
break;
case adios_unsigned_byte: DecodeValues<uint8_t>(f, v, this->Values);
case adios_unsigned_byte:
this->Values = new uint8_t[v->sum_nblocks];
break;
case adios_unsigned_short: DecodeValues<uint16_t>(f, v, this->Values);
case adios_unsigned_short:
this->Values = new uint16_t[v->sum_nblocks];
break;
case adios_unsigned_integer: DecodeValues<uint32_t>(f, v, this->Values);
case adios_unsigned_integer:
this->Values = new uint32_t[v->sum_nblocks];
break;
case adios_unsigned_long: DecodeValues<uint64_t>(f, v, this->Values);
case adios_unsigned_long:
this->Values = new uint64_t[v->sum_nblocks];
break;
case adios_real: DecodeValues<float>(f, v, this->Values);
case adios_real:
this->Values = new float[v->sum_nblocks];
break;
case adios_double: DecodeValues<double>(f, v, this->Values);
case adios_double:
this->Values = new double[v->sum_nblocks];
break;
case adios_complex:
this->Values = new std::complex<float>[v->sum_nblocks];
break;
case adios_double_complex:
this->Values = new std::complex<double>[v->sum_nblocks];
break;
default: break;
}
size_t tSize = Type::SizeOf(this->Type);
// Read all blocks and steps
int err;
char *rawPtr = reinterpret_cast<char *>(this->Values);
for(size_t s = 0; s < v->nsteps; ++s)
{
for(size_t b = 0; b < v->nblocks[s]; ++b)
{
ADIOS_SELECTION *sel = adios_selection_writeblock(b);
ReadError::TestNe<ADIOS_SELECTION*>(NULL, sel);
err = adios_schedule_read_byid(f, sel, v->varid, s, 1, rawPtr);
ReadError::TestEq(0, err);
err = adios_perform_reads(f, 1);
ReadError::TestEq(0, err);
adios_selection_delete(sel);
rawPtr += tSize;
}
}
}
//----------------------------------------------------------------------------
template<typename T>
void Cleanup(std::vector<void*>& values)
Scalar::~Scalar()
{
for(std::vector<void*>::iterator i = values.begin(); i != values.end(); ++i)
if(!this->Values)
{
delete reinterpret_cast<std::vector<T>*>(*i);
*i = NULL;
return;
}
values.clear();
}
ADIOSScalar::~ADIOSScalar(void)
{
switch(this->Type)
{
case VTK_TYPE_INT8: Cleanup<int8_t>(this->Values); break;
case VTK_TYPE_INT16: Cleanup<int16_t>(this->Values); break;
case VTK_TYPE_INT32: Cleanup<int32_t>(this->Values); break;
case VTK_ID_TYPE: Cleanup<vtkIdType>(this->Values); break;
case VTK_TYPE_UINT8: Cleanup<uint8_t>(this->Values); break;
case VTK_TYPE_UINT16: Cleanup<uint16_t>(this->Values); break;
case VTK_TYPE_UINT32: Cleanup<uint32_t>(this->Values); break;
case VTK_TYPE_UINT64: Cleanup<uint64_t>(this->Values); break;
case VTK_TYPE_FLOAT32: Cleanup<float>(this->Values); break;
case VTK_TYPE_FLOAT64: Cleanup<double>(this->Values); break;
case adios_byte:
delete[] reinterpret_cast<int8_t*>(this->Values);
break;
case adios_short:
delete[] reinterpret_cast<int16_t*>(this->Values);
break;
case adios_integer:
delete[] reinterpret_cast<int32_t*>(this->Values);
break;
case adios_long:
delete[] reinterpret_cast<int64_t*>(this->Values);
break;
case adios_unsigned_byte:
delete[] reinterpret_cast<uint8_t*>(this->Values);
break;
case adios_unsigned_short:
delete[] reinterpret_cast<uint16_t*>(this->Values);
break;
case adios_unsigned_integer:
delete[] reinterpret_cast<uint32_t*>(this->Values);
break;
case adios_unsigned_long:
delete[] reinterpret_cast<uint64_t*>(this->Values);
break;
case adios_real:
delete[] reinterpret_cast<float*>(this->Values);
break;
case adios_double:
delete[] reinterpret_cast<double*>(this->Values);
break;
case adios_complex:
delete[] reinterpret_cast<std::complex<float>*>(this->Values);
break;
case adios_double_complex:
delete[] reinterpret_cast<std::complex<double>*>(this->Values);
break;
default: break;
}
}
//----------------------------------------------------------------------------
template<typename TN>
const std::vector<TN>& ADIOSScalar::GetValues(int step) const
{
if(ADIOSUtilities::TypeNativeToVTK<TN>::T != this->Type)
{
throw std::invalid_argument("Incompatible type");
}
return *reinterpret_cast<std::vector<TN>*>(this->Values[step]);
}
#define INSTANTIATE(T) \
template const std::vector<T>& ADIOSScalar::GetValues(int) const;
INSTANTIATE(int8_t)
INSTANTIATE(int16_t)
INSTANTIATE(int32_t)
INSTANTIATE(vtkIdType)
INSTANTIATE(uint8_t)
INSTANTIATE(uint16_t)
INSTANTIATE(uint32_t)
INSTANTIATE(uint64_t)
INSTANTIATE(float)
INSTANTIATE(double)
#undef INSTANTIATE
} // End namespace ADIOS
......@@ -20,32 +20,33 @@
#include <string>
#include <vector>
#include <vtkType.h>
#include "ADIOSUtilities.h"
#include <adios_read.h>
#include "ADIOSVarInfo.h"
//----------------------------------------------------------------------------
class ADIOSScalar
namespace ADIOS
{
public:
ADIOSScalar(ADIOS_FILE *f, ADIOS_VARINFO *v);
~ADIOSScalar(void);
std::string GetName(void) const { return this->Name; }
int GetId(void) const { return this->Id; }
int GetType(void) const { return this->Type; }
int GetNumSteps(void) const { return this->NumSteps; }
class Scalar : public VarInfo
{
public:
Scalar(ADIOS_FILE *f, ADIOS_VARINFO *v);
virtual ~Scalar(void);
template<typename T>
const std::vector<T>& GetValues(int step) const;
private:
int Id;
int Type;
int NumSteps;
const std::string Name;
std::vector<void *> Values; // void* is actualy std::vector<T>
const T& GetValue(size_t step, size_t block) const
{
ReadError::TestEq(this->Type, Type::NativeToADIOS<T>(), "Invalid type");
const int blockId = this->GetBlockId(step, block);
return reinterpret_cast<const T*>(this->Values)[blockId];
}
protected:
void *Values;
};
} // End namespace ADIOS
#endif // _ADIOSScalar_h
// VTK-HeaderTest-Exclude: ADIOSScalar.h
/*=========================================================================
Program: Visualization Toolkit
Module: ADIOSUtilities.cxx
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include <vtkType.h>
#include <adios.h>
#include <adios_read.h>
#include "ADIOSUtilities.h"
#include <stdint.h>
#include <limits>
#include <complex>
#include <string>
namespace ADIOS
{
//----------------------------------------------------------------------------
WriteError::WriteError(const std::string& msg)
: std::runtime_error(msg.empty() ? adios_get_last_errmsg() : msg)
{
if(msg.empty())
{
adios_clear_error();
}
}
//----------------------------------------------------------------------------
ReadError::ReadError(const std::string& msg)
: std::runtime_error(msg.empty() ? adios_errmsg() : msg)
{
}
namespace Type
{
//----------------------------------------------------------------------------
template<> ADIOS_DATATYPES SizeToInt<1>() { return adios_byte; }
template<> ADIOS_DATATYPES SizeToInt<2>() { return adios_short; }
template<> ADIOS_DATATYPES SizeToInt<4>() { return adios_integer; }
template<> ADIOS_DATATYPES SizeToInt<8>() { return adios_long; }
template<> ADIOS_DATATYPES SizeToUInt<1>() { return adios_unsigned_byte; }
template<> ADIOS_DATATYPES SizeToUInt<2>() { return adios_unsigned_short; }
template<> ADIOS_DATATYPES SizeToUInt<4>() { return adios_unsigned_integer; }
template<> ADIOS_DATATYPES SizeToUInt<8>() { return adios_unsigned_long; }
//----------------------------------------------------------------------------
#define INSTANTIATE(TN, TA) \
template<> ADIOS_DATATYPES ADIOSUtilities::TypeNativeToADIOS<TN>::T = TA;
template<> ADIOS_DATATYPES NativeToADIOS<TN>() { return TA; }
INSTANTIATE(int8_t, adios_byte)
INSTANTIATE(int16_t, adios_short)
INSTANTIATE(int32_t, adios_integer)
//INSTANTIATE(int64_t, adios_long)
INSTANTIATE(int64_t, adios_long)
INSTANTIATE(uint8_t, adios_unsigned_byte)
INSTANTIATE(uint16_t, adios_unsigned_short)
INSTANTIATE(uint32_t, adios_unsigned_integer)
INSTANTIATE(uint64_t, adios_unsigned_long)
INSTANTIATE(vtkIdType, adios_long)
INSTANTIATE(float, adios_real)
INSTANTIATE(double, adios_double)
INSTANTIATE(std::complex<float>, adios_complex)
......@@ -22,70 +71,8 @@ INSTANTIATE(std::complex<double>, adios_double_complex)
INSTANTIATE(std::string, adios_string)
#undef INSTANTIATE
#define INSTANTIATE(TN, TV) \
template<> int ADIOSUtilities::TypeNativeToVTK<TN>::T = TV;
INSTANTIATE(int8_t, VTK_TYPE_INT8)
INSTANTIATE(int16_t, VTK_TYPE_INT16)
INSTANTIATE(int32_t, VTK_TYPE_INT32)
//INSTANTIATE(int64_t, VTK_TYPE_INT64)
INSTANTIATE(uint8_t, VTK_TYPE_UINT8)
INSTANTIATE(uint16_t, VTK_TYPE_UINT16)
INSTANTIATE(uint32_t, VTK_TYPE_UINT32)
INSTANTIATE(uint64_t, VTK_TYPE_UINT64)
INSTANTIATE(vtkIdType, VTK_ID_TYPE)
INSTANTIATE(float, VTK_FLOAT)
INSTANTIATE(double, VTK_DOUBLE)
INSTANTIATE(std::string, VTK_STRING)
#undef INSTANTIATE
ADIOS_DATATYPES ADIOSUtilities::TypeVTKToADIOS(int tv)
{
switch(tv)
{
case VTK_TYPE_INT8: return adios_byte;
case VTK_TYPE_INT16: return adios_short;
case VTK_TYPE_INT32: return adios_integer;
case VTK_TYPE_INT64: return adios_long;
case VTK_TYPE_UINT8: return adios_unsigned_byte;
case VTK_TYPE_UINT16: return adios_unsigned_short;
case VTK_TYPE_UINT32: return adios_unsigned_integer;
case VTK_TYPE_UINT64: return adios_unsigned_long;
case VTK_FLOAT: return adios_real;
case VTK_DOUBLE: return adios_double;
case VTK_STRING: return adios_string;
case VTK_ID_TYPE:
switch(sizeof(vtkIdType))
{
case 1: return adios_byte;
case 2: return adios_short;
case 4: return adios_integer;
case 8: return adios_long;
default: return adios_unknown;
}
default: return adios_unknown;
}
}
int ADIOSUtilities::TypeADIOSToVTK(ADIOS_DATATYPES ta)
{
switch(ta)
{
case adios_byte: return VTK_TYPE_INT8;
case adios_short: return VTK_TYPE_INT16;
case adios_integer: return VTK_TYPE_INT32;
case adios_long: return VTK_ID_TYPE;
case adios_unsigned_byte: return VTK_TYPE_UINT8;
case adios_unsigned_short: return VTK_TYPE_UINT16;
case adios_unsigned_integer: return VTK_TYPE_UINT32;
case adios_unsigned_long: return VTK_TYPE_UINT64;
case adios_real: return VTK_FLOAT;
case adios_double: return VTK_DOUBLE;
case adios_string: return VTK_STRING;
default: return -1;
}
}
size_t ADIOSUtilities::TypeSize(ADIOS_DATATYPES ta)
//----------------------------------------------------------------------------
size_t SizeOf(ADIOS_DATATYPES ta)
{
switch(ta)
{
......@@ -105,3 +92,15 @@ size_t ADIOSUtilities::TypeSize(ADIOS_DATATYPES ta)
default: return 0;
}
}
//----------------------------------------------------------------------------
bool IsInt(ADIOS_DATATYPES ta)
{
return ta == adios_byte || ta == adios_short ||
ta == adios_integer || ta == adios_long ||
ta == adios_unsigned_byte || ta == adios_unsigned_short ||
ta == adios_unsigned_integer || ta == adios_unsigned_long;
}
} // End namespace Tye
} // End namespace ADIOS
/*=========================================================================
Program: Visualization Toolkit
Module: ADIOSUtilities.h
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even