From 51d113e63f1b7042e3b36effe31e0744cec5d318 Mon Sep 17 00:00:00 2001 From: Chuck Atkins <chuck.atkins@kitware.com> Date: Tue, 28 Mar 2017 16:15:36 -0400 Subject: [PATCH] Reformat with clang-format --- bindings/python/include/ADIOSPy.h | 46 +- bindings/python/include/EnginePy.h | 63 +- bindings/python/include/MethodPy.h | 37 +- bindings/python/include/VariablePy.h | 35 +- bindings/python/include/adiosPyFunctions.h | 77 +- bindings/python/src/ADIOSPy.cpp | 101 +- bindings/python/src/EnginePy.cpp | 138 ++- bindings/python/src/MethodPy.cpp | 102 +- bindings/python/src/VariablePy.cpp | 41 +- bindings/python/src/adiosPyFunctions.cpp | 76 +- bindings/python/src/glueBoostPython.cpp | 94 +- bindings/python/src/gluePyBind11.cpp | 64 +- doc/API_design/API_example_use.cpp | 735 ++++++------ examples/globalArray/globalArrayNoXML.cpp | 167 +-- examples/globalArray/globalArrayXML.cpp | 125 +- examples/globalArray/globalArrayZeroCopy.cpp | 205 ++-- examples/groupless/basic/reader.cpp | 306 ++--- examples/groupless/basic/writer.cpp | 245 ++-- examples/groupless/compound/reader.cpp | 363 +++--- examples/groupless/compound/writer.cpp | 258 ++-- .../groupless/multistep/reader_allsteps.cpp | 341 +++--- .../groupless/multistep/reader_stepping.cpp | 322 ++--- .../groupless/multistep/writer_multistep.cpp | 261 +++-- examples/heatTransfer/HeatTransfer.cpp | 371 +++--- examples/heatTransfer/HeatTransfer.h | 49 +- examples/heatTransfer/IO.h | 15 +- examples/heatTransfer/IO_adios1.cpp | 91 +- examples/heatTransfer/IO_adios2.cpp | 148 +-- examples/heatTransfer/IO_ascii.cpp | 92 +- examples/heatTransfer/IO_hdf5_a.cpp | 82 +- examples/heatTransfer/Settings.cpp | 136 +-- examples/heatTransfer/Settings.h | 63 +- examples/heatTransfer/main.cpp | 164 ++- .../hello/adios1Writer/helloADIOS1Writer.cpp | 176 +-- .../adios1Writer/helloADIOS1Writer_nompi.cpp | 140 +-- examples/hello/bpReader/helloBPReader.cpp | 92 +- .../hello/bpReader/helloBPReader_nompi.cpp | 77 +- examples/hello/bpWriter/helloBPWriter.cpp | 168 +-- .../hello/bpWriter/helloBPWriter_nompi.cpp | 140 +-- examples/hello/compound/helloCompound.cpp | 158 +-- .../hello/compound/helloCompound_nompi.cpp | 144 +-- .../datamanReader/helloDataManReader.cpp | 138 +-- .../helloDataManReader_nompi.cpp | 122 +- .../datamanWriter/helloDataManWriter.cpp | 165 +-- .../helloDataManWriter_nompi.cpp | 135 ++- examples/hello/timeBP/timeBPWriter.cpp | 181 +-- examples/hello/timeBP/timeBPWriter_nompi.cpp | 147 +-- examples/solidfluid/solidfluid_read.cpp | 465 ++++---- examples/solidfluid/solidfluid_write.cpp | 342 +++--- .../solidfluid/solidfluid_write_nompi.cpp | 332 +++--- examples/xmlParser/xmlParser.cpp | 70 +- include/ADIOS.h | 1037 +++++++++-------- include/ADIOSTypes.h | 26 +- include/ADIOS_C.h | 33 +- include/ADIOS_CPP.h | 7 +- include/capsule/heap/STLVector.h | 56 +- include/capsule/shmem/ShmSystemV.h | 78 +- include/core/Attribute.h | 9 +- include/core/Capsule.h | 59 +- include/core/Engine.h | 864 +++++++------- include/core/Method.h | 177 +-- include/core/Profiler.h | 133 ++- include/core/Support.h | 46 +- include/core/Transform.h | 30 +- include/core/Transport.h | 114 +- include/core/Variable.h | 152 +-- include/core/VariableBase.h | 145 +-- include/core/VariableCompound.h | 66 +- include/engine/adios1/ADIOS1Reader.h | 163 +-- include/engine/adios1/ADIOS1Writer.h | 186 +-- include/engine/bp/BPFileReader.h | 163 +-- include/engine/bp/BPFileWriter.h | 274 +++-- include/engine/dataman/DataManReader.h | 193 +-- include/engine/dataman/DataManWriter.h | 269 +++-- include/format/BP1.h | 463 ++++---- include/format/BP1Aggregator.h | 55 +- include/format/BP1Writer.h | 857 +++++++------- include/functions/adiosFunctions.h | 170 +-- include/functions/adiosTemplates.h | 316 ++--- include/functions/capsuleTemplates.h | 42 +- include/mpidummy.h | 118 +- include/transform/BZip2.h | 31 +- include/transport/file/FStream.h | 28 +- include/transport/file/FileDescriptor.h | 23 +- include/transport/file/FilePointer.h | 32 +- include/transport/file/MPI_File.h | 32 +- include/transport/wan/MdtmMan.h | 217 ++-- 87 files changed, 7984 insertions(+), 7285 deletions(-) diff --git a/bindings/python/include/ADIOSPy.h b/bindings/python/include/ADIOSPy.h index 584526e80..50b21a849 100644 --- a/bindings/python/include/ADIOSPy.h +++ b/bindings/python/include/ADIOSPy.h @@ -8,22 +8,22 @@ #ifndef ADIOSPY_H_ #define ADIOSPY_H_ -#include <string> -#include <memory> //std::shared_ptr #include <map> +#include <memory> //std::shared_ptr +#include <string> #ifdef HAVE_BOOSTPYTHON - #include "boost/python.hpp" +#include "boost/python.hpp" #endif #ifdef HAVE_PYBIND11 - #include "pybind11/pybind11.h" +#include "pybind11/pybind11.h" #endif #include "ADIOS.h" -#include "adiosPyFunctions.h" //ListToVector, VectorToList -#include "VariablePy.h" #include "MethodPy.h" +#include "VariablePy.h" +#include "adiosPyFunctions.h" //ListToVector, VectorToList namespace adios { @@ -39,41 +39,33 @@ using pyList = pybind11::list; using pyObject = pybind11::object; #endif - class EnginePy; - class ADIOSPy : public ADIOS { public: + ADIOSPy(MPI_Comm mpiComm, const bool debug); + ~ADIOSPy(); - ADIOSPy( MPI_Comm mpiComm, const bool debug ); - ~ADIOSPy( ); + void HelloMPI(); ///< says hello from rank/size for testing - void HelloMPI( ); ///< says hello from rank/size for testing + VariablePy DefineVariablePy(const std::string name, + const pyList localDimensionsPy = pyList(), + const pyList globalDimensionsPy = pyList(), + const pyList globalOffsetsPy = pyList()); - VariablePy DefineVariablePy( const std::string name, const pyList localDimensionsPy = pyList(), - const pyList globalDimensionsPy = pyList(), const pyList globalOffsetsPy = pyList() ); + MethodPy &DeclareMethodPy(const std::string methodName); - MethodPy& DeclareMethodPy( const std::string methodName ); - - EnginePy OpenPy( const std::string name, const std::string accessMode, const MethodPy& method, pyObject py_comm = pyObject() ); - - void DefineVariableType( VariablePy& variablePy ); + EnginePy OpenPy(const std::string name, const std::string accessMode, + const MethodPy &method, pyObject py_comm = pyObject()); + void DefineVariableType(VariablePy &variablePy); private: - - std::set<std::string> m_VariablesPyNames; - + std::set<std::string> m_VariablesPyNames; }; - - - - -} //end namespace - +} // end namespace #endif /* ADIOSPY_H_ */ diff --git a/bindings/python/include/EnginePy.h b/bindings/python/include/EnginePy.h index 9955d7b64..0f7e3e87b 100644 --- a/bindings/python/include/EnginePy.h +++ b/bindings/python/include/EnginePy.h @@ -14,14 +14,14 @@ #endif #ifdef HAVE_PYBIND11 -#include "pybind11/pybind11.h" #include "pybind11/numpy.h" +#include "pybind11/pybind11.h" #endif #include "ADIOSPy.h" -#include "core/Engine.h" #include "VariablePy.h" #include "adiosPyFunctions.h" +#include "core/Engine.h" namespace adios { @@ -35,52 +35,45 @@ using pyArray = pybind11::array; using dtype = pybind11::dtype; #endif - class EnginePy { public: + EnginePy(ADIOSPy &adiosPy); - EnginePy( ADIOSPy& adiosPy ); - - ~EnginePy( ); + ~EnginePy(); - std::shared_ptr<Engine> m_Engine; + std::shared_ptr<Engine> m_Engine; - void WritePy( VariablePy& variable, const pyArray& array ); + void WritePy(VariablePy &variable, const pyArray &array); - void Advance( ); + void Advance(); - void Close( ); + void Close(); - void GetEngineType( ) const; + void GetEngineType() const; private: - - ADIOSPy& m_ADIOSPy; - bool m_IsVariableTypeDefined = false; - - template< class T > - void DefineVariableInADIOS( VariablePy& variable ) - { - auto& var = m_ADIOSPy.DefineVariable<T>( variable.m_Name, variable.m_LocalDimensions, - variable.m_GlobalDimensions, variable.m_GlobalOffsets ); - variable.m_VariablePtr = &var; - variable.m_IsVariableDefined = true; - } - - template< class T > - void WriteVariableInADIOS( VariablePy& variable, const pyArray& array ) - { - m_Engine->Write( *reinterpret_cast<Variable<T>*>( variable.m_VariablePtr ), PyArrayToPointer<T>( array ) ); - } - + ADIOSPy &m_ADIOSPy; + bool m_IsVariableTypeDefined = false; + + template <class T> void DefineVariableInADIOS(VariablePy &variable) + { + auto &var = m_ADIOSPy.DefineVariable<T>( + variable.m_Name, variable.m_LocalDimensions, + variable.m_GlobalDimensions, variable.m_GlobalOffsets); + variable.m_VariablePtr = &var; + variable.m_IsVariableDefined = true; + } + + template <class T> + void WriteVariableInADIOS(VariablePy &variable, const pyArray &array) + { + m_Engine->Write(*reinterpret_cast<Variable<T> *>(variable.m_VariablePtr), + PyArrayToPointer<T>(array)); + } }; - -} //end namespace - - - +} // end namespace #endif /* ENGINEPY_H_ */ diff --git a/bindings/python/include/MethodPy.h b/bindings/python/include/MethodPy.h index 77ca9471b..05ad461ec 100644 --- a/bindings/python/include/MethodPy.h +++ b/bindings/python/include/MethodPy.h @@ -9,15 +9,14 @@ #define METHODPY_H_ #ifdef HAVE_BOOSTPYTHON - #include "boost/python.hpp" +#include "boost/python.hpp" #endif #ifdef HAVE_PYBIND11 - #include "pybind11/pybind11.h" - #include "pybind11/cast.h" +#include "pybind11/cast.h" +#include "pybind11/pybind11.h" #endif - #include "core/Method.h" namespace adios @@ -35,34 +34,26 @@ using pyTuple = pybind11::tuple; using pyDict = pybind11::dict; #endif - class MethodPy : public Method { public: + MethodPy(const std::string type, const bool debugMode); - MethodPy( const std::string type, const bool debugMode ); - - ~MethodPy( ); - + ~MethodPy(); - #ifdef HAVE_BOOSTPYTHON - static pyObject SetParametersPy( pyTuple args, pyDict kwargs ); - static pyObject AddTransportPy( pyTuple args, pyDict kwargs ); - #endif - - - #ifdef HAVE_PYBIND11 - void SetParametersPyBind11( pybind11::kwargs kwargs ); - void AddTransportPyBind11( const std::string type, pybind11::kwargs kwargs ); - #endif +#ifdef HAVE_BOOSTPYTHON + static pyObject SetParametersPy(pyTuple args, pyDict kwargs); + static pyObject AddTransportPy(pyTuple args, pyDict kwargs); +#endif - void PrintAll( ) const; +#ifdef HAVE_PYBIND11 + void SetParametersPyBind11(pybind11::kwargs kwargs); + void AddTransportPyBind11(const std::string type, pybind11::kwargs kwargs); +#endif + void PrintAll() const; }; - - } - #endif /* METHODPY_H_ */ diff --git a/bindings/python/include/VariablePy.h b/bindings/python/include/VariablePy.h index 934b3b523..5abc36d39 100644 --- a/bindings/python/include/VariablePy.h +++ b/bindings/python/include/VariablePy.h @@ -8,8 +8,8 @@ #ifndef VARIABLEPY_H_ #define VARIABLEPY_H_ -#include "core/Variable.h" #include "adiosPyFunctions.h" +#include "core/Variable.h" namespace adios { @@ -22,36 +22,31 @@ using pyList = boost::python::list; using pyList = pybind11::list; #endif - class VariablePy { public: + VariablePy(const std::string name, const pyList localDimensionsPy, + const pyList globalDimensionsPy, const pyList globalOffsetsPy); - VariablePy( const std::string name, const pyList localDimensionsPy, const pyList globalDimensionsPy, const pyList globalOffsetsPy ); + ~VariablePy(); - ~VariablePy( ); + void SetLocalDimensions(const pyList list); - void SetLocalDimensions( const pyList list ); + void SetGlobalDimensionsAndOffsets(const pyList globalDimensions, + const pyList globalOffsets); - void SetGlobalDimensionsAndOffsets( const pyList globalDimensions, const pyList globalOffsets ); + Dims GetLocalDimensions(); - Dims GetLocalDimensions( ); + void *m_VariablePtr = nullptr; + bool m_IsVariableDefined = false; - void* m_VariablePtr = nullptr; - bool m_IsVariableDefined = false; - - const std::string m_Name; - Dims m_LocalDimensions; - Dims m_GlobalDimensions; - Dims m_GlobalOffsets; + const std::string m_Name; + Dims m_LocalDimensions; + Dims m_GlobalDimensions; + Dims m_GlobalOffsets; }; - - -} //end namespace - - - +} // end namespace #endif /* BINDINGS_PYTHON_INCLUDE_VARIABLEPY_H_ */ diff --git a/bindings/python/include/adiosPyFunctions.h b/bindings/python/include/adiosPyFunctions.h index 1f3167929..7ae5b1a5f 100644 --- a/bindings/python/include/adiosPyFunctions.h +++ b/bindings/python/include/adiosPyFunctions.h @@ -8,21 +8,20 @@ #ifndef ADIOSPYFUNCTIONS_H_ #define ADIOSPYFUNCTIONS_H_ -#include <vector> #include <map> #include <string> +#include <vector> #ifdef HAVE_BOOSTPYTHON - #include "boost/python.hpp" - #include "boost/python/numpy.hpp" +#include "boost/python.hpp" +#include "boost/python/numpy.hpp" #endif #ifdef HAVE_PYBIND11 - #include "pybind11/pybind11.h" - #include "pybind11/numpy.h" +#include "pybind11/numpy.h" +#include "pybind11/pybind11.h" #endif - namespace adios { @@ -51,62 +50,56 @@ using pyObject = pybind11::object; * @param list input boost python list from python program * @return Dims (std::vector<std::size_t>) object than can be passed to python */ -Dims ListToVector( const pyList& list ); +Dims ListToVector(const pyList &list); #ifdef HAVE_BOOSTPYTHON -std::map<std::string, std::string> DictToMap( const pyDict& dictionary ); +std::map<std::string, std::string> DictToMap(const pyDict &dictionary); #endif #ifdef HAVE_PYBIND11 -std::map<std::string, std::string> KwargsToMap( const pybind11::kwargs& dictionary ); +std::map<std::string, std::string> +KwargsToMap(const pybind11::kwargs &dictionary); #endif - -template< class T > -const T* PyArrayToPointer( const pyArray& array ) +template <class T> const T *PyArrayToPointer(const pyArray &array) { - #ifdef HAVE_BOOSTPYTHON - return reinterpret_cast<const T*>( array.get_data() ); - #endif +#ifdef HAVE_BOOSTPYTHON + return reinterpret_cast<const T *>(array.get_data()); +#endif - #ifdef HAVE_PYBIND11 - return reinterpret_cast<const T*>( array.data() ); - #endif +#ifdef HAVE_PYBIND11 + return reinterpret_cast<const T *>(array.data()); +#endif } -template< class T > -bool IsType( const pyArray& array ) +template <class T> bool IsType(const pyArray &array) { - #ifdef HAVE_BOOSTPYTHON - if( array.get_dtype() == dtype::get_builtin<T>() ) return true; - #endif +#ifdef HAVE_BOOSTPYTHON + if (array.get_dtype() == dtype::get_builtin<T>()) + return true; +#endif - #ifdef HAVE_PYBIND11 - if( pybind11::isinstance<pybind11::array_t<T>>( array ) ) return true; - #endif +#ifdef HAVE_PYBIND11 + if (pybind11::isinstance<pybind11::array_t<T>>(array)) + return true; +#endif - return false; + return false; } - -template< class T, class U> -T PyCast( U object ) +template <class T, class U> T PyCast(U object) { - #ifdef HAVE_BOOSTPYTHON - return boost::python::extract<T>( object ); - #endif +#ifdef HAVE_BOOSTPYTHON + return boost::python::extract<T>(object); +#endif - #ifdef HAVE_PYBIND11 - return pybind11::cast<T>( object ); - #endif +#ifdef HAVE_PYBIND11 + return pybind11::cast<T>(object); +#endif } +bool IsEmpty(pyObject object); -bool IsEmpty( pyObject object ); - - -} //end namespace - - +} // end namespace #endif /* ADIOSPYFUNCTIONS_H_ */ diff --git a/bindings/python/src/ADIOSPy.cpp b/bindings/python/src/ADIOSPy.cpp index f92bc8a6d..5ca37239b 100644 --- a/bindings/python/src/ADIOSPy.cpp +++ b/bindings/python/src/ADIOSPy.cpp @@ -15,72 +15,69 @@ namespace adios { - -ADIOSPy::ADIOSPy( MPI_Comm mpiComm, const bool debug ): - ADIOS( mpiComm, adios::Verbose::ERROR, debug ) -{ } - - -ADIOSPy::~ADIOSPy( ) -{ } - - -void ADIOSPy::HelloMPI( ) +ADIOSPy::ADIOSPy(MPI_Comm mpiComm, const bool debug) + : ADIOS(mpiComm, adios::Verbose::ERROR, debug) { - std::cout << "Hello ADIOSPy from rank " << m_RankMPI << "/" << m_SizeMPI << "\n"; } +ADIOSPy::~ADIOSPy() {} -MethodPy& ADIOSPy::DeclareMethodPy( const std::string methodName ) +void ADIOSPy::HelloMPI() { - Method& method = DeclareMethod( methodName ); - return *reinterpret_cast<MethodPy*>( &method ); + std::cout << "Hello ADIOSPy from rank " << m_RankMPI << "/" << m_SizeMPI + << "\n"; } - -VariablePy ADIOSPy::DefineVariablePy( const std::string name, const pyList localDimensionsPy, - const pyList globalDimensionsPy, const pyList globalOffsetsPy ) +MethodPy &ADIOSPy::DeclareMethodPy(const std::string methodName) { - if( m_DebugMode == true ) - { - if( m_VariablesPyNames.count( name ) == 1 ) - throw std::invalid_argument( "ERROR: Variable " + name + " is already defined\n" ); - } - - m_VariablesPyNames.insert( name ); - return VariablePy( name, localDimensionsPy, globalDimensionsPy, globalOffsetsPy ); + Method &method = DeclareMethod(methodName); + return *reinterpret_cast<MethodPy *>(&method); } -void ADIOSPy::DefineVariableType( VariablePy& variablePy ) +VariablePy ADIOSPy::DefineVariablePy(const std::string name, + const pyList localDimensionsPy, + const pyList globalDimensionsPy, + const pyList globalOffsetsPy) { - + if (m_DebugMode == true) + { + if (m_VariablesPyNames.count(name) == 1) + throw std::invalid_argument("ERROR: Variable " + name + + " is already defined\n"); + } + + m_VariablesPyNames.insert(name); + return VariablePy(name, localDimensionsPy, globalDimensionsPy, + globalOffsetsPy); } +void ADIOSPy::DefineVariableType(VariablePy &variablePy) {} - -EnginePy ADIOSPy::OpenPy( const std::string name, const std::string accessMode, - const MethodPy& method, pyObject py_comm ) +EnginePy ADIOSPy::OpenPy(const std::string name, const std::string accessMode, + const MethodPy &method, pyObject py_comm) { - EnginePy enginePy( *this ); - - bool isEmpty = IsEmpty( py_comm ); - - if( isEmpty == true ) //None - { - enginePy.m_Engine = Open( name, accessMode, method ); - } - else - { - if (import_mpi4py() < 0) throw std::logic_error( "ERROR: could not import mpi4py communicator in Open " + name + "\n" ); - MPI_Comm* comm_p = PyMPIComm_Get( py_comm.ptr() ); - if( comm_p == nullptr ) throw std::invalid_argument( "ERROR: MPI communicator is nullptr in Open " + name + "\n" ); - - enginePy.m_Engine = Open( name, accessMode, *comm_p, method ); - } - - return enginePy; + EnginePy enginePy(*this); + + bool isEmpty = IsEmpty(py_comm); + + if (isEmpty == true) // None + { + enginePy.m_Engine = Open(name, accessMode, method); + } + else + { + if (import_mpi4py() < 0) + throw std::logic_error( + "ERROR: could not import mpi4py communicator in Open " + name + "\n"); + MPI_Comm *comm_p = PyMPIComm_Get(py_comm.ptr()); + if (comm_p == nullptr) + throw std::invalid_argument( + "ERROR: MPI communicator is nullptr in Open " + name + "\n"); + + enginePy.m_Engine = Open(name, accessMode, *comm_p, method); + } + + return enginePy; } - - -} //end namespace +} // end namespace diff --git a/bindings/python/src/EnginePy.cpp b/bindings/python/src/EnginePy.cpp index 790e997e3..eea898233 100644 --- a/bindings/python/src/EnginePy.cpp +++ b/bindings/python/src/EnginePy.cpp @@ -7,7 +7,6 @@ #include <string> - #include "EnginePy.h" #include "adiosPyFunctions.h" @@ -15,75 +14,90 @@ namespace adios { -EnginePy::EnginePy( ADIOSPy& adiosPy ): - m_ADIOSPy{ adiosPy } -{ } - +EnginePy::EnginePy(ADIOSPy &adiosPy) : m_ADIOSPy{adiosPy} {} -EnginePy::~EnginePy( ) -{ } +EnginePy::~EnginePy() {} - -void EnginePy::WritePy( VariablePy& variable, const pyArray& array ) +void EnginePy::WritePy(VariablePy &variable, const pyArray &array) { - if( variable.m_IsVariableDefined == false ) //here define variable - { - if( IsType<char>( array ) ) DefineVariableInADIOS<char>( variable ); - else if( IsType<unsigned char>( array ) ) DefineVariableInADIOS<unsigned char>( variable ); - else if( IsType<short>( array ) ) DefineVariableInADIOS<short>( variable ); - else if( IsType<unsigned short>( array ) ) DefineVariableInADIOS<unsigned short>( variable ); - else if( IsType<int>( array ) ) DefineVariableInADIOS<int>( variable ); - else if( IsType<unsigned int>( array ) ) DefineVariableInADIOS<unsigned int>( variable ); - else if( IsType<long int>( array ) ) DefineVariableInADIOS<long int>( variable ); - else if( IsType<unsigned long int>( array ) ) DefineVariableInADIOS<unsigned long int>( variable ); - else if( IsType<long long int>( array ) ) DefineVariableInADIOS<long long int>( variable ); - else if( IsType<unsigned long long int>( array ) ) DefineVariableInADIOS<unsigned long long int>( variable ); - else if( IsType<float>( array ) ) DefineVariableInADIOS<float>( variable ); - else if( IsType<double>( array ) ) DefineVariableInADIOS<double>( variable ); - else if( IsType<long double>( array ) ) DefineVariableInADIOS<long double>( variable ); - else if( IsType<std::complex<float>>( array ) ) DefineVariableInADIOS<std::complex<float>>( variable ); - else if( IsType<std::complex<double>>( array ) ) DefineVariableInADIOS<std::complex<double>>( variable ); - else if( IsType<std::complex<long double>>( array ) ) DefineVariableInADIOS<std::complex<long double>>( variable ); - } - - if( IsType<char>( array ) ) WriteVariableInADIOS<char>( variable, array ); - else if( IsType<unsigned char>( array ) ) WriteVariableInADIOS<unsigned char>( variable, array ); - else if( IsType<short>( array ) ) WriteVariableInADIOS<short>( variable, array ); - else if( IsType<unsigned short>( array ) ) WriteVariableInADIOS<unsigned short>( variable, array ); - else if( IsType<int>( array ) ) WriteVariableInADIOS<int>( variable, array ); - else if( IsType<unsigned int>( array ) ) WriteVariableInADIOS<unsigned int>( variable, array ); - else if( IsType<long int>( array ) ) WriteVariableInADIOS<long int>( variable, array ); - else if( IsType<unsigned long int>( array ) ) WriteVariableInADIOS<unsigned long int>( variable, array ); - else if( IsType<long long int>( array ) ) WriteVariableInADIOS<long long int>( variable, array ); - else if( IsType<unsigned long long int>( array ) ) WriteVariableInADIOS<unsigned long long int>( variable, array ); - else if( IsType<float>( array ) ) WriteVariableInADIOS<float>( variable, array ); - else if( IsType<double>( array ) ) WriteVariableInADIOS<double>( variable, array ); - else if( IsType<long double>( array ) ) WriteVariableInADIOS<long double>( variable, array ); - else if( IsType<std::complex<float>>( array ) ) WriteVariableInADIOS<std::complex<float>>( variable, array ); - else if( IsType<std::complex<double>>( array ) ) WriteVariableInADIOS<std::complex<double>>( variable, array ); - else if( IsType<std::complex<long double>>( array ) ) WriteVariableInADIOS<std::complex<long double>>( variable, array ); - -} - -void EnginePy::Advance( ) -{ - m_Engine->Advance( ); + if (variable.m_IsVariableDefined == false) // here define variable + { + if (IsType<char>(array)) + DefineVariableInADIOS<char>(variable); + else if (IsType<unsigned char>(array)) + DefineVariableInADIOS<unsigned char>(variable); + else if (IsType<short>(array)) + DefineVariableInADIOS<short>(variable); + else if (IsType<unsigned short>(array)) + DefineVariableInADIOS<unsigned short>(variable); + else if (IsType<int>(array)) + DefineVariableInADIOS<int>(variable); + else if (IsType<unsigned int>(array)) + DefineVariableInADIOS<unsigned int>(variable); + else if (IsType<long int>(array)) + DefineVariableInADIOS<long int>(variable); + else if (IsType<unsigned long int>(array)) + DefineVariableInADIOS<unsigned long int>(variable); + else if (IsType<long long int>(array)) + DefineVariableInADIOS<long long int>(variable); + else if (IsType<unsigned long long int>(array)) + DefineVariableInADIOS<unsigned long long int>(variable); + else if (IsType<float>(array)) + DefineVariableInADIOS<float>(variable); + else if (IsType<double>(array)) + DefineVariableInADIOS<double>(variable); + else if (IsType<long double>(array)) + DefineVariableInADIOS<long double>(variable); + else if (IsType<std::complex<float>>(array)) + DefineVariableInADIOS<std::complex<float>>(variable); + else if (IsType<std::complex<double>>(array)) + DefineVariableInADIOS<std::complex<double>>(variable); + else if (IsType<std::complex<long double>>(array)) + DefineVariableInADIOS<std::complex<long double>>(variable); + } + + if (IsType<char>(array)) + WriteVariableInADIOS<char>(variable, array); + else if (IsType<unsigned char>(array)) + WriteVariableInADIOS<unsigned char>(variable, array); + else if (IsType<short>(array)) + WriteVariableInADIOS<short>(variable, array); + else if (IsType<unsigned short>(array)) + WriteVariableInADIOS<unsigned short>(variable, array); + else if (IsType<int>(array)) + WriteVariableInADIOS<int>(variable, array); + else if (IsType<unsigned int>(array)) + WriteVariableInADIOS<unsigned int>(variable, array); + else if (IsType<long int>(array)) + WriteVariableInADIOS<long int>(variable, array); + else if (IsType<unsigned long int>(array)) + WriteVariableInADIOS<unsigned long int>(variable, array); + else if (IsType<long long int>(array)) + WriteVariableInADIOS<long long int>(variable, array); + else if (IsType<unsigned long long int>(array)) + WriteVariableInADIOS<unsigned long long int>(variable, array); + else if (IsType<float>(array)) + WriteVariableInADIOS<float>(variable, array); + else if (IsType<double>(array)) + WriteVariableInADIOS<double>(variable, array); + else if (IsType<long double>(array)) + WriteVariableInADIOS<long double>(variable, array); + else if (IsType<std::complex<float>>(array)) + WriteVariableInADIOS<std::complex<float>>(variable, array); + else if (IsType<std::complex<double>>(array)) + WriteVariableInADIOS<std::complex<double>>(variable, array); + else if (IsType<std::complex<long double>>(array)) + WriteVariableInADIOS<std::complex<long double>>(variable, array); } +void EnginePy::Advance() { m_Engine->Advance(); } +void EnginePy::Close() { m_Engine->Close(-1); } -void EnginePy::Close( ) +void EnginePy::GetEngineType() const { - m_Engine->Close( -1 ); + std::cout << "Engine type " << m_Engine->m_EngineType << "\n"; } - -void EnginePy::GetEngineType( ) const -{ - std::cout << "Engine type " << m_Engine->m_EngineType << "\n"; -} - - - -} //end namespace +} // end namespace diff --git a/bindings/python/src/MethodPy.cpp b/bindings/python/src/MethodPy.cpp index 88babe0b4..d362c04b8 100644 --- a/bindings/python/src/MethodPy.cpp +++ b/bindings/python/src/MethodPy.cpp @@ -5,7 +5,6 @@ * Author: wfg */ - #include <iostream> #include "MethodPy.h" @@ -22,81 +21,76 @@ namespace py = boost::python; namespace py = pybind11; #endif +MethodPy::MethodPy(const std::string type, const bool debugMode) + : Method(type, debugMode) +{ +} -MethodPy::MethodPy( const std::string type, const bool debugMode ): - Method( type, debugMode ) -{ } - - -MethodPy::~MethodPy( ) -{ } +MethodPy::~MethodPy() {} #ifdef HAVE_BOOSTPYTHON -pyObject MethodPy::SetParametersPy( pyTuple args, pyDict kwargs ) +pyObject MethodPy::SetParametersPy(pyTuple args, pyDict kwargs) { - if( py::len( args ) > 1 ) - throw std::invalid_argument( "ERROR: syntax of Method SetParameters function is incorrect, only use dictionary\n" ); + if (py::len(args) > 1) + throw std::invalid_argument("ERROR: syntax of Method SetParameters " + "function is incorrect, only use dictionary\n"); - MethodPy& self = PyCast<MethodPy&>( args[0] ); - self.m_Parameters = DictToMap( kwargs ); - return args[0]; + MethodPy &self = PyCast<MethodPy &>(args[0]); + self.m_Parameters = DictToMap(kwargs); + return args[0]; } - -pyObject MethodPy::AddTransportPy( pyTuple args, pyDict kwargs ) +pyObject MethodPy::AddTransportPy(pyTuple args, pyDict kwargs) { - if( py::len( args ) != 2 ) - throw std::invalid_argument( "ERROR: syntax of Method AddTransport function is incorrect, only use one string for transport followed by a dictionary for parameters\n" ); - - MethodPy& self = PyCast<MethodPy&>( args[0] ); - const std::string type = PyCast<std::string>( args[1] ); - - auto parameters = DictToMap( kwargs ); - parameters.insert( std::make_pair( "transport", type ) ); - self.m_TransportParameters.push_back( parameters ); - return args[0]; + if (py::len(args) != 2) + throw std::invalid_argument( + "ERROR: syntax of Method AddTransport function is incorrect, only use " + "one string for transport followed by a dictionary for parameters\n"); + + MethodPy &self = PyCast<MethodPy &>(args[0]); + const std::string type = PyCast<std::string>(args[1]); + + auto parameters = DictToMap(kwargs); + parameters.insert(std::make_pair("transport", type)); + self.m_TransportParameters.push_back(parameters); + return args[0]; } #endif - #ifdef HAVE_PYBIND11 -void MethodPy::SetParametersPyBind11( pybind11::kwargs kwargs ) +void MethodPy::SetParametersPyBind11(pybind11::kwargs kwargs) { - this->m_Parameters = KwargsToMap( kwargs ); + this->m_Parameters = KwargsToMap(kwargs); } - -void MethodPy::AddTransportPyBind11( const std::string type, pybind11::kwargs kwargs ) +void MethodPy::AddTransportPyBind11(const std::string type, + pybind11::kwargs kwargs) { - auto parameters = KwargsToMap( kwargs ); - parameters.insert( std::make_pair( "transport", type ) ); - this->m_TransportParameters.push_back( parameters ); + auto parameters = KwargsToMap(kwargs); + parameters.insert(std::make_pair("transport", type)); + this->m_TransportParameters.push_back(parameters); } #endif - - -void MethodPy::PrintAll( ) const +void MethodPy::PrintAll() const { - std::cout << "Method parameters\n"; - for( const auto& param : m_Parameters ) - std::cout << "Parameter: " << param.first << "\t Value: " << param.second << "\n"; + std::cout << "Method parameters\n"; + for (const auto ¶m : m_Parameters) + std::cout << "Parameter: " << param.first << "\t Value: " << param.second + << "\n"; - std::cout << "\n"; - std::cout << "Transport Parameters\n"; + std::cout << "\n"; + std::cout << "Transport Parameters\n"; - for( const auto& transportParameters : m_TransportParameters ) - { - std::cout << "Transport:\n"; - for( const auto& param : transportParameters ) - std::cout << "Parameter: " << param.first << "\t Value: " << param.second << "\n"; + for (const auto &transportParameters : m_TransportParameters) + { + std::cout << "Transport:\n"; + for (const auto ¶m : transportParameters) + std::cout << "Parameter: " << param.first << "\t Value: " << param.second + << "\n"; - std::cout << "\n"; - } + std::cout << "\n"; + } } - - - -} //end namespace - +} // end namespace diff --git a/bindings/python/src/VariablePy.cpp b/bindings/python/src/VariablePy.cpp index 562bbb894..e6c236832 100644 --- a/bindings/python/src/VariablePy.cpp +++ b/bindings/python/src/VariablePy.cpp @@ -5,45 +5,34 @@ * Author: wfg */ - #include "VariablePy.h" - namespace adios { -VariablePy::VariablePy( const std::string name, const pyList localDimensionsPy, - const pyList globalDimensionsPy, const pyList globalOffsetsPy ): - m_Name{ name }, - m_LocalDimensions{ ListToVector( localDimensionsPy ) }, - m_GlobalDimensions{ ListToVector( globalDimensionsPy ) }, - m_GlobalOffsets{ ListToVector( globalOffsetsPy ) } -{ } - - -VariablePy::~VariablePy( ) -{ } - - -void VariablePy::SetLocalDimensions( const pyList list ) +VariablePy::VariablePy(const std::string name, const pyList localDimensionsPy, + const pyList globalDimensionsPy, + const pyList globalOffsetsPy) + : m_Name{name}, m_LocalDimensions{ListToVector(localDimensionsPy)}, + m_GlobalDimensions{ListToVector(globalDimensionsPy)}, + m_GlobalOffsets{ListToVector(globalOffsetsPy)} { -// this->m_Dimensions = ListToVector( list ); - } +VariablePy::~VariablePy() {} -void VariablePy::SetGlobalDimensionsAndOffsets( const pyList globalDimensions, const pyList globalOffsets ) +void VariablePy::SetLocalDimensions(const pyList list) { -// this->m_GlobalDimensions = ListToVector( globalDimensions ); -// this->m_GlobalOffsets = ListToVector( globalOffsets ); + // this->m_Dimensions = ListToVector( list ); } - -Dims VariablePy::GetLocalDimensions( ) +void VariablePy::SetGlobalDimensionsAndOffsets(const pyList globalDimensions, + const pyList globalOffsets) { - return this->m_LocalDimensions; + // this->m_GlobalDimensions = ListToVector( globalDimensions ); + // this->m_GlobalOffsets = ListToVector( globalOffsets ); } +Dims VariablePy::GetLocalDimensions() { return this->m_LocalDimensions; } - -} //end namespace +} // end namespace diff --git a/bindings/python/src/adiosPyFunctions.cpp b/bindings/python/src/adiosPyFunctions.cpp index 80cef254d..b986b7e4d 100644 --- a/bindings/python/src/adiosPyFunctions.cpp +++ b/bindings/python/src/adiosPyFunctions.cpp @@ -8,7 +8,6 @@ #include "adiosPyFunctions.h" - namespace adios { @@ -20,69 +19,66 @@ namespace py = boost::python; namespace py = pybind11; #endif - - -Dims ListToVector( const pyList& list ) +Dims ListToVector(const pyList &list) { - const unsigned int length = py::len( list ); - Dims vec; - vec.reserve( length ); + const unsigned int length = py::len(list); + Dims vec; + vec.reserve(length); - for( unsigned int i=0; i<length;i++ ) - vec.push_back( PyCast<std::size_t>( list[i]) ); + for (unsigned int i = 0; i < length; i++) + vec.push_back(PyCast<std::size_t>(list[i])); - return vec; + return vec; } #ifdef HAVE_BOOSTPYTHON -std::map<std::string, std::string> DictToMap( const pyDict& dictionary ) +std::map<std::string, std::string> DictToMap(const pyDict &dictionary) { - std::map<std::string, std::string> parameters; + std::map<std::string, std::string> parameters; - pyList keys = dictionary.keys(); - const unsigned int length = py::len( keys ); + pyList keys = dictionary.keys(); + const unsigned int length = py::len(keys); - for( unsigned int k = 0; k < length; ++k ) - { - const std::string key( PyCast<std::string>( keys[k] ) ); - const std::string value( PyCast<std::string>( dictionary[ keys[k] ] ) ); - parameters.insert( std::make_pair( key, value ) ); - } + for (unsigned int k = 0; k < length; ++k) + { + const std::string key(PyCast<std::string>(keys[k])); + const std::string value(PyCast<std::string>(dictionary[keys[k]])); + parameters.insert(std::make_pair(key, value)); + } - return parameters; + return parameters; } #endif #ifdef HAVE_PYBIND11 -std::map<std::string, std::string> KwargsToMap( const pybind11::kwargs& kwargs ) +std::map<std::string, std::string> KwargsToMap(const pybind11::kwargs &kwargs) { - std::map<std::string, std::string> parameters; - - for( const auto& pair : kwargs ) - { - const std::string key( PyCast<std::string>( pair.first ) ); - const std::string value( PyCast<std::string>( pair.second ) ); - parameters.insert( std::make_pair( key, value ) ); - } - return parameters; + std::map<std::string, std::string> parameters; + + for (const auto &pair : kwargs) + { + const std::string key(PyCast<std::string>(pair.first)); + const std::string value(PyCast<std::string>(pair.second)); + parameters.insert(std::make_pair(key, value)); + } + return parameters; } #endif - -bool IsEmpty( pyObject object ) +bool IsEmpty(pyObject object) { - bool isEmpty = false; + bool isEmpty = false; #ifdef HAVE_BOOSTPYTHON - if( object == boost::python::object() ) isEmpty = true; + if (object == boost::python::object()) + isEmpty = true; #endif #ifdef HAVE_PYBIND11 - if( object == pybind11::none() ) isEmpty = true; + if (object == pybind11::none()) + isEmpty = true; #endif - return isEmpty; + return isEmpty; } - -} //end namespace - +} // end namespace diff --git a/bindings/python/src/glueBoostPython.cpp b/bindings/python/src/glueBoostPython.cpp index 2adc5af2d..11c8824d4 100644 --- a/bindings/python/src/glueBoostPython.cpp +++ b/bindings/python/src/glueBoostPython.cpp @@ -8,68 +8,64 @@ #include <mpi4py/mpi4py.h> #include "boost/python.hpp" -#include "boost/python/suite/indexing/vector_indexing_suite.hpp" -#include "boost/python/raw_function.hpp" #include "boost/python/numpy.hpp" - +#include "boost/python/raw_function.hpp" +#include "boost/python/suite/indexing/vector_indexing_suite.hpp" #include "ADIOSPy.h" #include "EnginePy.h" #include "adiosPyFunctions.h" - namespace py = boost::python; namespace np = boost::python::numpy; - -adios::ADIOSPy ADIOSPy( py::object py_comm, const bool debug ) +adios::ADIOSPy ADIOSPy(py::object py_comm, const bool debug) { - MPI_Comm* comm_p = PyMPIComm_Get( py_comm.ptr() ); - if (comm_p == NULL) py::throw_error_already_set(); - return adios::ADIOSPy( *comm_p, debug ); + MPI_Comm *comm_p = PyMPIComm_Get(py_comm.ptr()); + if (comm_p == NULL) + py::throw_error_already_set(); + return adios::ADIOSPy(*comm_p, debug); } - using ReturnInternalReference = py::return_internal_reference<>; -BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS( open_overloads, adios::ADIOSPy::OpenPy, 3, 4 ) +BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(open_overloads, adios::ADIOSPy::OpenPy, + 3, 4) - -BOOST_PYTHON_MODULE( ADIOSPy ) +BOOST_PYTHON_MODULE(ADIOSPy) { - if (import_mpi4py() < 0) return; /* Python 2.X */ - - Py_Initialize(); - np::initialize(); - - py::class_< adios::Dims >("Dims") - .def(boost::python::vector_indexing_suite< adios::Dims >() ); - //functions - py::def("ADIOSPy", ADIOSPy ); - - //classes - py::class_<adios::ADIOSPy>("ADIOS", py::no_init ) - .def("HelloMPI", &adios::ADIOSPy::HelloMPI ) - .def("DefineVariable", &adios::ADIOSPy::DefineVariablePy ) - .def("DeclareMethod", &adios::ADIOSPy::DeclareMethodPy, ReturnInternalReference() ) - .def("Open", &adios::ADIOSPy::OpenPy, open_overloads() ) - ; - - py::class_<adios::VariablePy>("Variable", py::no_init ) - .def("SetLocalDimensions", &adios::VariablePy::SetLocalDimensions ) - .def("GetLocalDimensions", &adios::VariablePy::GetLocalDimensions ) - ; - - py::class_<adios::MethodPy>("Method", py::no_init ) - .def("SetParameters", py::raw_function( &adios::MethodPy::SetParametersPy, 1 ) ) - .def("AddTransport", py::raw_function( &adios::MethodPy::AddTransportPy, 1 ) ) - .def("PrintAll", &adios::MethodPy::PrintAll ) - ; - - //Engine - py::class_<adios::EnginePy>("EnginePy", py::no_init ) - .def("Write", &adios::EnginePy::WritePy ) - .def("Advance", &adios::EnginePy::WritePy ) - .def("Close", &adios::EnginePy::Close ) - ; + if (import_mpi4py() < 0) + return; /* Python 2.X */ + + Py_Initialize(); + np::initialize(); + + py::class_<adios::Dims>("Dims").def( + boost::python::vector_indexing_suite<adios::Dims>()); + // functions + py::def("ADIOSPy", ADIOSPy); + + // classes + py::class_<adios::ADIOSPy>("ADIOS", py::no_init) + .def("HelloMPI", &adios::ADIOSPy::HelloMPI) + .def("DefineVariable", &adios::ADIOSPy::DefineVariablePy) + .def("DeclareMethod", &adios::ADIOSPy::DeclareMethodPy, + ReturnInternalReference()) + .def("Open", &adios::ADIOSPy::OpenPy, open_overloads()); + + py::class_<adios::VariablePy>("Variable", py::no_init) + .def("SetLocalDimensions", &adios::VariablePy::SetLocalDimensions) + .def("GetLocalDimensions", &adios::VariablePy::GetLocalDimensions); + + py::class_<adios::MethodPy>("Method", py::no_init) + .def("SetParameters", + py::raw_function(&adios::MethodPy::SetParametersPy, 1)) + .def("AddTransport", + py::raw_function(&adios::MethodPy::AddTransportPy, 1)) + .def("PrintAll", &adios::MethodPy::PrintAll); + + // Engine + py::class_<adios::EnginePy>("EnginePy", py::no_init) + .def("Write", &adios::EnginePy::WritePy) + .def("Advance", &adios::EnginePy::WritePy) + .def("Close", &adios::EnginePy::Close); } - diff --git a/bindings/python/src/gluePyBind11.cpp b/bindings/python/src/gluePyBind11.cpp index d7ee0456c..40ef1127d 100644 --- a/bindings/python/src/gluePyBind11.cpp +++ b/bindings/python/src/gluePyBind11.cpp @@ -14,51 +14,47 @@ #include "ADIOSPy.h" #include "EnginePy.h" - namespace py = pybind11; - -adios::ADIOSPy ADIOSPy( py::object py_comm, const bool debug ) +adios::ADIOSPy ADIOSPy(py::object py_comm, const bool debug) { - MPI_Comm* comm_p = PyMPIComm_Get( py_comm.ptr() ); - if( comm_p == NULL ) py::error_already_set(); - return adios::ADIOSPy( *comm_p, debug ); + MPI_Comm *comm_p = PyMPIComm_Get(py_comm.ptr()); + if (comm_p == NULL) + py::error_already_set(); + return adios::ADIOSPy(*comm_p, debug); } - -PYBIND11_PLUGIN( ADIOSPy ) +PYBIND11_PLUGIN(ADIOSPy) { - if (import_mpi4py() < 0) throw std::runtime_error("ERROR: mpi4py not loaded correctly\n"); /* Python 2.X */ - - py::module m( "ADIOSPy", "ADIOS Python bindings using pybind11" ); + if (import_mpi4py() < 0) + throw std::runtime_error( + "ERROR: mpi4py not loaded correctly\n"); /* Python 2.X */ - m.def("ADIOSPy", &ADIOSPy, "Function that creates an ADIOS object" ); + py::module m("ADIOSPy", "ADIOS Python bindings using pybind11"); - py::class_<adios::ADIOSPy>( m, "ADIOS" ) - .def("HelloMPI", &adios::ADIOSPy::HelloMPI ) - .def("DefineVariable", &adios::ADIOSPy::DefineVariablePy ) - .def("DeclareMethod", &adios::ADIOSPy::DeclareMethodPy, py::return_value_policy::reference_internal ) - .def("Open", &adios::ADIOSPy::OpenPy ) - ; + m.def("ADIOSPy", &ADIOSPy, "Function that creates an ADIOS object"); - py::class_<adios::VariablePy>( m, "Variable") - .def("SetLocalDimensions", &adios::VariablePy::SetLocalDimensions ) - .def("GetLocalDimensions", &adios::VariablePy::GetLocalDimensions ) - ; + py::class_<adios::ADIOSPy>(m, "ADIOS") + .def("HelloMPI", &adios::ADIOSPy::HelloMPI) + .def("DefineVariable", &adios::ADIOSPy::DefineVariablePy) + .def("DeclareMethod", &adios::ADIOSPy::DeclareMethodPy, + py::return_value_policy::reference_internal) + .def("Open", &adios::ADIOSPy::OpenPy); - py::class_<adios::MethodPy>( m, "Method") - .def("SetParameters", &adios::MethodPy::SetParametersPyBind11 ) - .def("AddTransport", &adios::MethodPy::AddTransportPyBind11 ) - .def("PrintAll", &adios::MethodPy::PrintAll ) - ; + py::class_<adios::VariablePy>(m, "Variable") + .def("SetLocalDimensions", &adios::VariablePy::SetLocalDimensions) + .def("GetLocalDimensions", &adios::VariablePy::GetLocalDimensions); - //Engine - py::class_<adios::EnginePy>( m, "Engine") - .def("Write", &adios::EnginePy::WritePy ) - .def("Advance", &adios::EnginePy::WritePy ) - .def("Close", &adios::EnginePy::Close ) - ; + py::class_<adios::MethodPy>(m, "Method") + .def("SetParameters", &adios::MethodPy::SetParametersPyBind11) + .def("AddTransport", &adios::MethodPy::AddTransportPyBind11) + .def("PrintAll", &adios::MethodPy::PrintAll); + // Engine + py::class_<adios::EnginePy>(m, "Engine") + .def("Write", &adios::EnginePy::WritePy) + .def("Advance", &adios::EnginePy::WritePy) + .def("Close", &adios::EnginePy::Close); - return m.ptr(); + return m.ptr(); } diff --git a/doc/API_design/API_example_use.cpp b/doc/API_design/API_example_use.cpp index 57333e030..af3fbdbdd 100644 --- a/doc/API_design/API_example_use.cpp +++ b/doc/API_design/API_example_use.cpp @@ -1,350 +1,433 @@ -/* Fake example for Current API by design, incorrect as code but describes most of the ideas */ +/* Fake example for Current API by design, incorrect as code but describes most + * of the ideas */ #include <mpi.h> #include "ADIOS.h" - -void cb_AsyncWriteAdvanceCompleted( std::shared_ptr<adios::Engine> writer ) +void cb_AsyncWriteAdvanceCompleted(std::shared_ptr<adios::Engine> writer) { - std::cout << "AdvanceAsync() completed. We can modify our zero-copy variables\n"; + std::cout + << "AdvanceAsync() completed. We can modify our zero-copy variables\n"; } -void cb_AsyncReadAdvanceCompleted( std::shared_ptr<adios::Engine> writer ) +void cb_AsyncReadAdvanceCompleted(std::shared_ptr<adios::Engine> writer) { - std::cout << "AdvanceAsync() completed. We have new data to read and we have the lock on it\n"; + std::cout << "AdvanceAsync() completed. We have new data to read and we have " + "the lock on it\n"; } -int main( int argc, char* argv[]) +int main(int argc, char *argv[]) { - //Application variables - MPI_Comm comm = MPI_COMM_WORLD; - const unsigned int NX = 10; - double Temperature[1][NX+2]; // We will want to write only Nx elements, skipping the first and last (think ghost cells) - std::vector<float> RaggedArray; - - int Nparts, nproc; - - // Global class/object that serves for init, finalize and provides ADIOS functions - adios::ADIOS adios( "config.xml", comm, /*verbose=*/adios::INFO, /*debugflag=*/false ); - - /************* - * WRITE API - *************/ - - /* Method - * We associate Engines and Transports and user settings into an object called Method. - * ADIOS checks if it is defined by the user in the config file, and fills it out if it is. - */ - - adios::Method& wmethod = adios.DeclareMethod( "WriteMethod" ); - if( ! wmethod.isUserDefined() ) - { - // if not defined by user, we can change the default settings - wmethod.SetEngine( "BP" ); // BP is the default engine - wmethod.AllowThreads( 1 ); // no threading for data processing (except for staging) - wmethod.AddTransport( "File", "lucky=yes" ); // ISO-POSIX file is the default transport - wmethod.AddTransport( "Staging" ); //"The" staging method developed in ECP - wmethod.SetParameters("have_metadata_file","yes" ); // Passing parameters to the engine - wmethod.SetParameters( "Aggregation", (nproc+1)/2 ); // number of aggregators - wmethod.SetParameters( "verbose", adios::Verbose::WARN ); // Verbosity level for this engine and what it calls - } - - - //Define variables with transformations. - adios::Variable<unsigned int>& varNX = adios.DefineVariable<unsigned int>( "NX" ); // global single-value across processes - auto& varNproc = adios.DefineVariable<int>( "nproc", adios::Dims{adios::GLOBAL_VALUE} ); // same def for global value - adios::Variable<int>& varNparts = adios.DefineVariable<int>( "Nparts", adios::Dims{adios::LOCAL_VALUE} ); // a single-value different on every process - adios::Variable<double>& var2D = adios.DefineVariable<double>( "Temperature", adios::Dims{nproc,NX} ); // 2D global array, 1D decomposition - adios::Variable<float>& varRagged = adios.DefineVariable<float>( "Ragged", adios::Dims{nproc,adios::VARYING_DIMENSION} ); // ragged array - - - //add transform to variable - adios::Transform zfp = adios::transform::ZFP(); - var2D.AddTransform( zfp, "accuracy=0.001" ); - - // open...write.write.write...advance...write.write.write...advance... ...close cycle - // "w" create/overwrite on open, "a" append at open, "u" open for update (does not increase step), "r" open for read. - std::shared_ptr<adios::Engine> writer = adios.Open( "myNumbers.bp", "w", comm, wmethod, adios::IOMode::INDEPENDENT); - - if( writer == nullptr ) - throw std::ios_base::failure( "ERROR: failed to open ADIOS writer\n" ); - - // Zero-Copy API: Define a variable with local dimensions now, and make ADIOS allocate it inside its buffers - // This requires an engine created. The variable will be deallocated in writer->Close() - // Calling varZeroCopy.SetSelection() later should throw an exception, i.e. modification is not allowed - // 2D global array, 1D decomposition - adios::Variable<double>& varZeroCopy = adios.DefineVariable<double>( "ZC", adios::Dims{nproc,NX}, adios::Dims{1,NX}, adios::Dims{rank,0} ); - double fillValue = -1.0; - double * const myVarZC = writer->AllocateVariable<double>( varZeroCopy, fillValue ); - - - for (int step = 0; step < 10; ++step) { - // write scalar value - writer->Write<int>( varNparts, Nparts ); - - // Make a selection to describe the local dimensions of the variable we write and - // its offsets in the global spaces. This could have been done in adios.DefineVariable() - adios::Selection sel = adios.SelectionBoundingBox( {1,NX}, {rank,NX} ); // local dims and offsets; both as list - var2D.SetSelection( sel ); // Shall we call it SetSpaceSelection, SetOutputSelection? - - // Select the area that we want to write from the data pointer we pass to the writer - // Think HDF5 memspace, just not hyperslabs yet, only a bounding box selection - // Engine will copy this bounding box from the data pointer into the buffer. Size of the bounding box should match the - // "space" selection which was given above. Default memspace is the full selection. - adios::Selection memspace = adios.SelectionBoundingBox( {1,NX}, {0,1} ); // local dims and offsets; both as list - var2D.SetMemorySelection( memspace ); - - writer->Write<double>( var2D, *Temperature ); - - // Indicate we are done for this step. - // N-to-M Aggregation, disk I/O will be performed during this call, unless - // time aggregation postpones all of that to some later step. - // When Advance() returns, user can overwrite its Zero Copy variables. - // Internal buffer is freed only if there are no Zero Copy variables and there is no time aggregation going on - writer->Advance(); // same as AppendMode - writer->Advance( adios::APPEND, 0.0 ); // append new step at next write - writer->Advance( adios::UPDATE ); // do not increase step; - - // When AdvanceAsync returns, user need to wait for notification that he can overwrite the Zero Copy variables. - writer->AdvanceAsync( adios::APPEND, cb_AsyncWriteAdvanceCompleted ); - - } - - // Called once: indicate that we are done with this output for the run - // Zero Copy variables will be deallocated - writer->Close(); - - - - /************* - * READ API - *************/ - adios::Method& rmethod = adios.DeclareMethod( "ReadMethod" ); - if( ! rmethod.isUserDefined() ) - { - // if not defined by user, we can change the default settings - rmethod.SetEngine( "BP" ); // BP is the default engine - rmethod.AddTransport( "Staging" ); //"The" staging method developed in ECP - rmethod.SetParameters( "Aggregation", (nproc+1)/2 ); // number of aggregators - rmethod.SetParameters( "verbose", adios::Verbose::WARN ); // Verbosity level for this engine and what it calls - } - - // 1. Open a stream, where every reader can see everything in a stream (so that they can read a global array) - // Blocking read of a variable - try - { - // These method settings are developer-only, not available to the user - rmethod.SetReadMultiplexPattern( adios::GLOBAL_READERS ); // Each reader process sees everything from the stream - rmethod.SetStreamOpenMode( adios::WAITFORSTREAM ); // In Open(), wait for the first step appear (default) - - // Open a stream - std::shared_ptr<adios::Engine> reader = - adios.Open( "filename.bp", "r", comm, rmethod, adios::IOMode::COLLECTIVE, - /*timeout_sec=*/ 300.0); // wait this long for the stream, return error afterwards - - /* Variable names are available as a vector of strings */ - std::cout << "List of variables in file: " << reader->VariableNames() << "\n"; - /* read a Global scalar which has a single value in a step */ - reader->Read<unsigned int>( "NX", NX ); - - // inquiry about a variable, whose name we know - adios::Variable<double> var2D = reader->InquireVariableDouble( "Temperature" ); - std::vector<std::size_t> gdims = var2D.GetGlobalDimensions(); - int nsteps = var2D.GetSteps(); - - struct adios::BlockInfo blocks = reader.InquiryVariableBlockInfo( reader, var2D ); // get per-writer size info - // this is adios1 ADIOS_VARBLOCK - struct adios::Statistics stats = reader.InquiryVariableStat( reader, var2D, perstepstat, perblockstat ); // get min/max statistics - // this is adios1 ADIOS_VARSTAT - - while( true ) - { - // Make a selection to describe the local dimensions of the variable we READ and - // its offsets in the global spaces - adios::Selection bbsel = adios.SelectionBoundingBox( {1,NX}, {0,0} ); // local dims and offsets; both as list - var2D.SetSelection( bbsel ); - adios::Selection memspace = adios.SelectionBoundingBox( {1,NX}, {0,1} ); // local dims and offsets; both as list - var2D.SetMemorySelection( memspace ); - reader->Read<double>(var2D, *Temperature); - //var2D, Temperature ); - - // Better for staging to schedule several reads at once - reader->ScheduleRead<double>( var2D, *Temperature ); - reader->PerformReads( adios::BLOCKINGREAD ); - - // promise to not read more from this step/item - reader->Release(); - - // want to move on to the next available step/item - reader->Advance(adios::NEXT_AVAILABLE); // default - reader->Advance(adios::LATEST_AVAILABLE); // interested only in the latest data - } - // Close file/stream - reader->Close(); - } - catch( adios::end_of_stream& e ) + // Application variables + MPI_Comm comm = MPI_COMM_WORLD; + const unsigned int NX = 10; + double Temperature[1][NX + 2]; // We will want to write only Nx elements, + // skipping the first and last (think ghost + // cells) + std::vector<float> RaggedArray; + + int Nparts, nproc; + + // Global class/object that serves for init, finalize and provides ADIOS + // functions + adios::ADIOS adios("config.xml", comm, /*verbose=*/adios::INFO, + /*debugflag=*/false); + + /************* + * WRITE API + *************/ + + /* Method + * We associate Engines and Transports and user settings into an object called + * Method. + * ADIOS checks if it is defined by the user in the config file, and fills it + * out if it is. + */ + + adios::Method &wmethod = adios.DeclareMethod("WriteMethod"); + if (!wmethod.isUserDefined()) + { + // if not defined by user, we can change the default settings + wmethod.SetEngine("BP"); // BP is the default engine + wmethod.AllowThreads( + 1); // no threading for data processing (except for staging) + wmethod.AddTransport( + "File", "lucky=yes"); // ISO-POSIX file is the default transport + wmethod.AddTransport("Staging"); //"The" staging method developed in ECP + wmethod.SetParameters("have_metadata_file", + "yes"); // Passing parameters to the engine + wmethod.SetParameters("Aggregation", + (nproc + 1) / 2); // number of aggregators + wmethod.SetParameters("verbose", adios::Verbose::WARN); // Verbosity level + // for this engine + // and what it calls + } + + // Define variables with transformations. + adios::Variable<unsigned int> &varNX = adios.DefineVariable<unsigned int>( + "NX"); // global single-value across processes + auto &varNproc = adios.DefineVariable<int>( + "nproc", adios::Dims{adios::GLOBAL_VALUE}); // same def for global value + adios::Variable<int> &varNparts = adios.DefineVariable<int>( + "Nparts", + adios::Dims{ + adios::LOCAL_VALUE}); // a single-value different on every process + adios::Variable<double> &var2D = adios.DefineVariable<double>( + "Temperature", + adios::Dims{nproc, NX}); // 2D global array, 1D decomposition + adios::Variable<float> &varRagged = adios.DefineVariable<float>( + "Ragged", adios::Dims{nproc, adios::VARYING_DIMENSION}); // ragged array + + // add transform to variable + adios::Transform zfp = adios::transform::ZFP(); + var2D.AddTransform(zfp, "accuracy=0.001"); + + // open...write.write.write...advance...write.write.write...advance... + // ...close cycle + // "w" create/overwrite on open, "a" append at open, "u" open for update (does + // not increase step), "r" open for read. + std::shared_ptr<adios::Engine> writer = adios.Open( + "myNumbers.bp", "w", comm, wmethod, adios::IOMode::INDEPENDENT); + + if (writer == nullptr) + throw std::ios_base::failure("ERROR: failed to open ADIOS writer\n"); + + // Zero-Copy API: Define a variable with local dimensions now, and make ADIOS + // allocate it inside its buffers + // This requires an engine created. The variable will be deallocated in + // writer->Close() + // Calling varZeroCopy.SetSelection() later should throw an exception, i.e. + // modification is not allowed + // 2D global array, 1D decomposition + adios::Variable<double> &varZeroCopy = adios.DefineVariable<double>( + "ZC", adios::Dims{nproc, NX}, adios::Dims{1, NX}, adios::Dims{rank, 0}); + double fillValue = -1.0; + double *const myVarZC = + writer->AllocateVariable<double>(varZeroCopy, fillValue); + + for (int step = 0; step < 10; ++step) + { + // write scalar value + writer->Write<int>(varNparts, Nparts); + + // Make a selection to describe the local dimensions of the variable we + // write and + // its offsets in the global spaces. This could have been done in + // adios.DefineVariable() + adios::Selection sel = adios.SelectionBoundingBox( + {1, NX}, {rank, NX}); // local dims and offsets; both as list + var2D.SetSelection( + sel); // Shall we call it SetSpaceSelection, SetOutputSelection? + + // Select the area that we want to write from the data pointer we pass to + // the writer + // Think HDF5 memspace, just not hyperslabs yet, only a bounding box + // selection + // Engine will copy this bounding box from the data pointer into the buffer. + // Size of the bounding box should match the + // "space" selection which was given above. Default memspace is the full + // selection. + adios::Selection memspace = adios.SelectionBoundingBox( + {1, NX}, {0, 1}); // local dims and offsets; both as list + var2D.SetMemorySelection(memspace); + + writer->Write<double>(var2D, *Temperature); + + // Indicate we are done for this step. + // N-to-M Aggregation, disk I/O will be performed during this call, unless + // time aggregation postpones all of that to some later step. + // When Advance() returns, user can overwrite its Zero Copy variables. + // Internal buffer is freed only if there are no Zero Copy variables and + // there is no time aggregation going on + writer->Advance(); // same as AppendMode + writer->Advance(adios::APPEND, 0.0); // append new step at next write + writer->Advance(adios::UPDATE); // do not increase step; + + // When AdvanceAsync returns, user need to wait for notification that he can + // overwrite the Zero Copy variables. + writer->AdvanceAsync(adios::APPEND, cb_AsyncWriteAdvanceCompleted); + } + + // Called once: indicate that we are done with this output for the run + // Zero Copy variables will be deallocated + writer->Close(); + + /************* + * READ API + *************/ + adios::Method &rmethod = adios.DeclareMethod("ReadMethod"); + if (!rmethod.isUserDefined()) + { + // if not defined by user, we can change the default settings + rmethod.SetEngine("BP"); // BP is the default engine + rmethod.AddTransport("Staging"); //"The" staging method developed in ECP + rmethod.SetParameters("Aggregation", + (nproc + 1) / 2); // number of aggregators + rmethod.SetParameters("verbose", adios::Verbose::WARN); // Verbosity level + // for this engine + // and what it calls + } + + // 1. Open a stream, where every reader can see everything in a stream (so + // that they can read a global array) + // Blocking read of a variable + try + { + // These method settings are developer-only, not available to the user + rmethod.SetReadMultiplexPattern(adios::GLOBAL_READERS); // Each reader + // process sees + // everything from + // the stream + rmethod.SetStreamOpenMode(adios::WAITFORSTREAM); // In Open(), wait for the + // first step appear + // (default) + + // Open a stream + std::shared_ptr<adios::Engine> reader = + adios.Open("filename.bp", "r", comm, rmethod, adios::IOMode::COLLECTIVE, + /*timeout_sec=*/300.0); // wait this long for the stream, + // return error afterwards + + /* Variable names are available as a vector of strings */ + std::cout << "List of variables in file: " << reader->VariableNames() + << "\n"; + /* read a Global scalar which has a single value in a step */ + reader->Read<unsigned int>("NX", NX); + + // inquiry about a variable, whose name we know + adios::Variable<double> var2D = + reader->InquireVariableDouble("Temperature"); + std::vector<std::size_t> gdims = var2D.GetGlobalDimensions(); + int nsteps = var2D.GetSteps(); + + struct adios::BlockInfo blocks = reader.InquiryVariableBlockInfo( + reader, var2D); // get per-writer size info + // this is adios1 ADIOS_VARBLOCK + struct adios::Statistics stats = reader.InquiryVariableStat( + reader, var2D, perstepstat, perblockstat); // get min/max statistics + // this is adios1 ADIOS_VARSTAT + + while (true) { - // Reached end of stream, end processing loop - // Close file/stream - reader->Close(); + // Make a selection to describe the local dimensions of the variable we + // READ and + // its offsets in the global spaces + adios::Selection bbsel = adios.SelectionBoundingBox( + {1, NX}, {0, 0}); // local dims and offsets; both as list + var2D.SetSelection(bbsel); + adios::Selection memspace = adios.SelectionBoundingBox( + {1, NX}, {0, 1}); // local dims and offsets; both as list + var2D.SetMemorySelection(memspace); + reader->Read<double>(var2D, *Temperature); + // var2D, Temperature ); + + // Better for staging to schedule several reads at once + reader->ScheduleRead<double>(var2D, *Temperature); + reader->PerformReads(adios::BLOCKINGREAD); + + // promise to not read more from this step/item + reader->Release(); + + // want to move on to the next available step/item + reader->Advance(adios::NEXT_AVAILABLE); // default + reader->Advance( + adios::LATEST_AVAILABLE); // interested only in the latest data } - catch( adios::file_not_found& e ) + // Close file/stream + reader->Close(); + } + catch (adios::end_of_stream &e) + { + // Reached end of stream, end processing loop + // Close file/stream + reader->Close(); + } + catch (adios::file_not_found &e) + { + // File/stream does not exist, quit + } + + // 2. Open a stream, where each item from the writers will get to a single + // reader only + // If the writers are collective, that means a whole steps go to different + // readers + // If the writers are independent, that means each writer's output goes to + // different readers + // Also show here ScheduleRead/PerformRead + // try + { + rmethod.SetReadMultiplexPattern(adios::FIFO_READERS); // Each reader process + // sees everything + // from the stream + rmethod.SetStreamOpenMode(adios::WAITFORSTREAM); // In Open(), wait for the + // first step appear + // (default) + + // Open a stream + std::shared_ptr<adios::Engine> reader = adios.Open( + "filename.bp", "r", comm, rmethod, adios::IOMode::INDEPENDENT, + /*timeout_sec=*/300.0); // wait this long for the stream, return error + // afterwards + + while (true) { - // File/stream does not exist, quit + // Make a selection to describe the local dimensions of the variable we + // READ and + // its offsets in the global spaces if we know this somehow + adios::Selection bbsel = adios.SelectionBoundingBox( + {1, NX}, {0, 0}); // local dims and offsets; both as list + var2D->SetSelection(bbsel); + reader->Read<double>(var2D, *Temperature); + + // Let ADIOS allocate space for the incoming (per-writer) item + double *data = reader->Read<double>(var2D); + + // promise to not read more from this step/item + reader->Release(); + + // want to move on to the next available step/item + reader->Advance(); // default + reader->Advance(adios::LATEST_AVAILABLE); // This should be an error, or + // could it make sense? } - - - - // 2. Open a stream, where each item from the writers will get to a single reader only - // If the writers are collective, that means a whole steps go to different readers - // If the writers are independent, that means each writer's output goes to different readers - // Also show here ScheduleRead/PerformRead - //try + reader->Close(); + } + + // 3. Open a stream and return immediately, not waiting for data to appear + // In this mode we cannot inquiry variables, but can schedule reads + // try + { + rmethod.SetReadMultiplexPattern(adios::GLOBAL_READERS); // Each reader + // process sees + // everything from + // the stream + rmethod.SetStreamOpenMode(adios::NOWAITFORSTREAM); // In Open(), wait for + // the first step appear + // (default) + + // Open a stream + std::shared_ptr<adios::Engine> reader = adios.Open( + "filename.bp", "r", comm, rmethod, adios::IOMode::INDEPENDENT); + + while (true) { - rmethod.SetReadMultiplexPattern( adios::FIFO_READERS ); // Each reader process sees everything from the stream - rmethod.SetStreamOpenMode( adios::WAITFORSTREAM ); // In Open(), wait for the first step appear (default) - // Open a stream - std::shared_ptr<adios::Engine> reader = - adios.Open( "filename.bp", "r", comm, rmethod, adios::IOMode::INDEPENDENT, - /*timeout_sec=*/ 300.0 ); // wait this long for the stream, return error afterwards - - while( true ) + // Let ADIOS allocate space for the incoming (per-writer) item + reader->ScheduleRead(); // read whatever comes + + // One way is to handle the incoming data through a callback (which will + // be called in a thread) + // void cb( const void *data, std::string doid, std::string var, + // std::string dtype, std::vector<std::size_t> varshape ); + // void cb( adios::VARCHUNK * chunk ); // see adios1 for VARCHUNK + reader->SetReadCallback(cb); + reader->PerformReads(adios::NONBLOCKINGREAD); + + // Another way is checking back manually like in adios1 and processing + // chunks + reader->PerformReads(adios::NONBLOCKINGREAD); + int ck; + adios::VARCHUNK *chunk; + try + { + while ((ck = reader->CheckReads(&chunk)) > 0) { - // Make a selection to describe the local dimensions of the variable we READ and - // its offsets in the global spaces if we know this somehow - adios::Selection bbsel = adios.SelectionBoundingBox( {1,NX}, {0,0} ); // local dims and offsets; both as list - var2D->SetSelection( bbsel ); - reader->Read<double>( var2D, *Temperature ); - - // Let ADIOS allocate space for the incoming (per-writer) item - double * data = reader->Read<double>( var2D ); - - // promise to not read more from this step/item - reader->Release(); - - // want to move on to the next available step/item - reader->Advance(); // default - reader->Advance(adios::LATEST_AVAILABLE); // This should be an error, or could it make sense? + if (chunk) + { + // process the chunk first + // ... + // free memory of chunk (not the data!) + adios::FreeChunk(chunk); + } + else + { + // no chunk was returned, slow down a little + sleep(1); + } } - reader->Close(); + } + catch (std::exception &e) + { + // some error happened while getting a chunk + } + + reader->Release(); + + // When AdvanceAsync returns new data is not yet available. + // A callback will tell us when we have the new data (and we have the lock + // on it to read) + writer->AdvanceAsync(adios::NEXT_AVAILABLE, cb_AsyncReadAdvanceCompleted); + // Do we need more fine grained control? Like this function does not get + // the lock and so + // do we need to call Advance() to get the lock? } - - - // 3. Open a stream and return immediately, not waiting for data to appear - // In this mode we cannot inquiry variables, but can schedule reads - //try - { - rmethod.SetReadMultiplexPattern( adios::GLOBAL_READERS ); // Each reader process sees everything from the stream - rmethod.SetStreamOpenMode( adios::NOWAITFORSTREAM ); // In Open(), wait for the first step appear (default) - - // Open a stream - std::shared_ptr<adios::Engine> reader = - adios.Open( "filename.bp", "r", comm, rmethod, adios::IOMode::INDEPENDENT ); - - while( true ) - { - - // Let ADIOS allocate space for the incoming (per-writer) item - reader->ScheduleRead(); // read whatever comes - - // One way is to handle the incoming data through a callback (which will be called in a thread) - // void cb( const void *data, std::string doid, std::string var, std::string dtype, std::vector<std::size_t> varshape ); - // void cb( adios::VARCHUNK * chunk ); // see adios1 for VARCHUNK - reader->SetReadCallback( cb ); - reader->PerformReads( adios::NONBLOCKINGREAD ); - - // Another way is checking back manually like in adios1 and processing chunks - reader->PerformReads( adios::NONBLOCKINGREAD ); - int ck; - adios::VARCHUNK * chunk; - try - { - while ( (ck = reader->CheckReads( &chunk )) > 0) { - if (chunk) { - // process the chunk first - // ... - // free memory of chunk (not the data!) - adios::FreeChunk(chunk); - } else { - // no chunk was returned, slow down a little - sleep(1); - } - } - } - catch( std::exception& e ) - { - // some error happened while getting a chunk - } - - reader->Release(); - - // When AdvanceAsync returns new data is not yet available. - // A callback will tell us when we have the new data (and we have the lock on it to read) - writer->AdvanceAsync( adios::NEXT_AVAILABLE, cb_AsyncReadAdvanceCompleted ); - // Do we need more fine grained control? Like this function does not get the lock and so - // do we need to call Advance() to get the lock? - } - reader->Close(); - } - // Note: chunk reading also works if scheduling reads for specific variables - - - // 4. Open it as file and see all steps at once. - // Allow for reading multiple steps of a variable into a contiguous array - try - { - rmethod.AddTransport( "BP" ); // Set a file engine here. Shall we have RemoveTransport() too? - - // Open a file with all steps immediately available - std::shared_ptr<adios::Engine> reader = - adios.OpenFileReader( "filename.bp", comm, rmethod, adios::COLLECTIVE_IO ); - - /* NX */ - /* There is a single value for each step. We can read all into a 1D array with a step selection. - * Steps are not automatically presented as an array dimension and read does not read it as array. - */ - // We can also just conveniently get the first step with a simple read statement. - reader->Read<unsigned int>( "NX", &NX ); // read a Global scalar which has a single value in a step - reader->Read<unsigned int>( varNX, &NX ); // read a Global scalar which has a single value in a step - - - adios::Variable<void> varNXread = reader->InquireVariable("NX"); - adios::Variable<unsigned int> varNXreadint = reader->InquireVariableInt("NX"); - std::vector<unsigned int> Nxs( varNXread.GetSteps() ); // number of steps available - // make a StepSelection to select multiple steps. Args: From, #of consecutive steps - adios::StepSelection stepsNx( 0, varNXread.GetSteps() ); - // ? How do we make a selection for an arbitrary list of steps ? - varNXread.SetStepSelection( stepsNx ); - reader->Read<unsigned int>( varNXreadint, Nxs.data()); - reader->Read<void>( varNXread, Nxs.data()); - - auto itmax = std::max_element(std::begin(Nxs), std::end(Nxs)); - auto itmin = std::min_element(std::begin(Nxs), std::end(Nxs)); - if (*itmin != *itmax) - { - throw std::ios_base::failure( "ERROR: NX is not the same at all steps!\n" ); - } - - - /* Nparts */ - // Nparts local scalar is presented as a 1D array of nproc elements. - // We can read all steps into a 2D array of nproc * nsteps - adios::Variable<void> varNpartsread = reader->InquireVariable("Nparts"); - std::vector<int> partsV( Nproc * varNpartsread->GetSteps() ); - varNpartsread->SetStepSelection( - adios.StepSelection( 0, varNpartsread.GetSteps() ) - ); - reader->Read<int>( "Nparts", partsV.data() ); - reader->Read<void>( varNpartsread, partsV.data() ); // missing spatial selection = whole array at each step - - // Close file/stream - reader->Close(); - } - catch( adios::file_not_found& e ) + reader->Close(); + } + // Note: chunk reading also works if scheduling reads for specific variables + + // 4. Open it as file and see all steps at once. + // Allow for reading multiple steps of a variable into a contiguous array + try + { + rmethod.AddTransport( + "BP"); // Set a file engine here. Shall we have RemoveTransport() too? + + // Open a file with all steps immediately available + std::shared_ptr<adios::Engine> reader = adios.OpenFileReader( + "filename.bp", comm, rmethod, adios::COLLECTIVE_IO); + + /* NX */ + /* There is a single value for each step. We can read all into a 1D array + * with a step selection. + * Steps are not automatically presented as an array dimension and read does + * not read it as array. + */ + // We can also just conveniently get the first step with a simple read + // statement. + reader->Read<unsigned int>( + "NX", &NX); // read a Global scalar which has a single value in a step + reader->Read<unsigned int>( + varNX, &NX); // read a Global scalar which has a single value in a step + + adios::Variable<void> varNXread = reader->InquireVariable("NX"); + adios::Variable<unsigned int> varNXreadint = + reader->InquireVariableInt("NX"); + std::vector<unsigned int> Nxs( + varNXread.GetSteps()); // number of steps available + // make a StepSelection to select multiple steps. Args: From, #of + // consecutive steps + adios::StepSelection stepsNx(0, varNXread.GetSteps()); + // ? How do we make a selection for an arbitrary list of steps ? + varNXread.SetStepSelection(stepsNx); + reader->Read<unsigned int>(varNXreadint, Nxs.data()); + reader->Read<void>(varNXread, Nxs.data()); + + auto itmax = std::max_element(std::begin(Nxs), std::end(Nxs)); + auto itmin = std::min_element(std::begin(Nxs), std::end(Nxs)); + if (*itmin != *itmax) { - // File/stream does not exist, quit + throw std::ios_base::failure("ERROR: NX is not the same at all steps!\n"); } - return 0; + /* Nparts */ + // Nparts local scalar is presented as a 1D array of nproc elements. + // We can read all steps into a 2D array of nproc * nsteps + adios::Variable<void> varNpartsread = reader->InquireVariable("Nparts"); + std::vector<int> partsV(Nproc * varNpartsread->GetSteps()); + varNpartsread->SetStepSelection( + adios.StepSelection(0, varNpartsread.GetSteps())); + reader->Read<int>("Nparts", partsV.data()); + reader->Read<void>( + varNpartsread, + partsV.data()); // missing spatial selection = whole array at each step + + // Close file/stream + reader->Close(); + } + catch (adios::file_not_found &e) + { + // File/stream does not exist, quit + } + + return 0; } diff --git a/examples/globalArray/globalArrayNoXML.cpp b/examples/globalArray/globalArrayNoXML.cpp index b90054b0c..ad9e4df18 100644 --- a/examples/globalArray/globalArrayNoXML.cpp +++ b/examples/globalArray/globalArrayNoXML.cpp @@ -5,109 +5,116 @@ * Author: pnorbert */ -#include <stdexcept> -#include <mpi.h> -#include <iostream> #include <fstream> +#include <iostream> +#include <mpi.h> +#include <stdexcept> #include <string> #include <vector> #include "../../include/ADIOS.h" -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - int rank, size; - const int NX = 10; - double t[NX]; - std::vector<double> p(NX); - MPI_Comm comm=MPI_COMM_WORLD; + int rank, size; + const int NX = 10; + double t[NX]; + std::vector<double> p(NX); + MPI_Comm comm = MPI_COMM_WORLD; - MPI_Init (&argc, &argv); - MPI_Comm_rank (comm, &rank); - MPI_Comm_size (comm, &size); - - try - { - // ADIOS manager object creation. MPI must be initialized - adios::ADIOS adios( "globalArrayNoXML.xml", comm, true ); + MPI_Init(&argc, &argv); + MPI_Comm_rank(comm, &rank); + MPI_Comm_size(comm, &size); - // set a maximum buffersize that ADIOS can use (for one group). - // multiple groups may use each such buffersize if they are overlapped or - // use time-aggregation or use zero-copy staging + try + { + // ADIOS manager object creation. MPI must be initialized + adios::ADIOS adios("globalArrayNoXML.xml", comm, true); - // Define Group and its variables - // The group's transport can be defined at runtime in the input XML file - adios.CreateGroup ("arrays"); + // set a maximum buffersize that ADIOS can use (for one group). + // multiple groups may use each such buffersize if they are overlapped or + // use time-aggregation or use zero-copy staging - // Set the maximum buffersize for this group. This must happen before - // defining a zero copy variable, which will cause the group's internal buffer - // allocated (during the variable definition call) - //adios.SetMaxBuffersize ("arrays", 10000000); + // Define Group and its variables + // The group's transport can be defined at runtime in the input XML file + adios.CreateGroup("arrays"); - adios.CreateVariable ("arrays", "NX", "int"); // scalar variable - adios.CreateVariable ("arrays", "size", "int"); - adios.CreateVariable ("arrays", "size", "rank"); + // Set the maximum buffersize for this group. This must happen before + // defining a zero copy variable, which will cause the group's internal + // buffer + // allocated (during the variable definition call) + // adios.SetMaxBuffersize ("arrays", 10000000); - // define a 2D array with 1D decomposition - adios.CreateVariable ("arrays", "temperature", "double", "1,NX", "NONE", "size,NX", "rank,0"); + adios.CreateVariable("arrays", "NX", "int"); // scalar variable + adios.CreateVariable("arrays", "size", "int"); + adios.CreateVariable("arrays", "size", "rank"); -// // set a variable-level transformation for this variable -// adios.SetVariableTransform ("arrays", "temperature", "none"); + // define a 2D array with 1D decomposition + adios.CreateVariable("arrays", "temperature", "double", "1,NX", "NONE", + "size,NX", "rank,0"); - adios.CreateVariable ("arrays", "pressure", "std::vector<double>", "1,NX", "size,NX", "rank,0" ); + // // set a variable-level transformation for this variable + // adios.SetVariableTransform ("arrays", "temperature", "none"); - // set a group-level transport - adios.SetTransport ( "arrays", "time-aggregate" ); // no options passed here + adios.CreateVariable("arrays", "pressure", "std::vector<double>", "1,NX", + "size,NX", "rank,0"); - //Get Monitor info - std::ofstream logStream( "info_" + std::to_string(rank) + ".log" ); - adios.MonitorGroups( logStream ); + // set a group-level transport + adios.SetTransport("arrays", "time-aggregate"); // no options passed here - adios.Open("arrays", "globalArray.bp", "w", 100000000 ); + // Get Monitor info + std::ofstream logStream("info_" + std::to_string(rank) + ".log"); + adios.MonitorGroups(logStream); - for (int it = 1; it <= 13; it++) - { + adios.Open("arrays", "globalArray.bp", "w", 100000000); - for (int i = 0; i < NX; i++) - { - t[i] = it*100.0 + rank*NX + i; - p[i] = it*1000.0 + rank*NX + i; - } - -// if (it==1) -// -// else -// adios.Open("arrays", "globalArray.bp", "a", 100000000 ); - - //uint64_t adios_groupsize, adios_totalsize; - // adios_groupsize = 4 + 4 + 4 + 2*NX*sizeof(double); - // adios_totalsize = adios.GroupSize("arrays", adios_groupsize); - - adios.Write ("arrays", "NX", &NX); - adios.Write ("arrays", "size", &size); - adios.Write ("arrays", "rank", &rank); - adios.Write ("arrays", "temperature", t); - adios.Write ("arrays", "pressure", &p); - - MPI_Barrier (comm); - if (rank==0) printf("Timestep %d written\n", it); - } - - adios.Close ("arrays"); + for (int it = 1; it <= 13; it++) + { - MPI_Barrier (comm); - // need barrier before we destroy the ADIOS object here automatically - if (rank==0) printf("Finalize adios\n"); + for (int i = 0; i < NX; i++) + { + t[i] = it * 100.0 + rank * NX + i; + p[i] = it * 1000.0 + rank * NX + i; + } + + // if (it==1) + // + // else + // adios.Open("arrays", "globalArray.bp", "a", 100000000 ); + + // uint64_t adios_groupsize, adios_totalsize; + // adios_groupsize = 4 + 4 + 4 + 2*NX*sizeof(double); + // adios_totalsize = adios.GroupSize("arrays", adios_groupsize); + + adios.Write("arrays", "NX", &NX); + adios.Write("arrays", "size", &size); + adios.Write("arrays", "rank", &rank); + adios.Write("arrays", "temperature", t); + adios.Write("arrays", "pressure", &p); + + MPI_Barrier(comm); + if (rank == 0) + printf("Timestep %d written\n", it); } - catch( std::exception& e ) //need to think carefully how to handle C++ exceptions with MPI to avoid deadlocking + + adios.Close("arrays"); + + MPI_Barrier(comm); + // need barrier before we destroy the ADIOS object here automatically + if (rank == 0) + printf("Finalize adios\n"); + } + catch (std::exception &e) // need to think carefully how to handle C++ + // exceptions with MPI to avoid deadlocking + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << e.what() << "\n"; - } + std::cout << e.what() << "\n"; } + } - if (rank==0) printf("Finalize MPI\n"); - MPI_Finalize (); - return 0; + if (rank == 0) + printf("Finalize MPI\n"); + MPI_Finalize(); + return 0; } diff --git a/examples/globalArray/globalArrayXML.cpp b/examples/globalArray/globalArrayXML.cpp index 82b9e9e0a..ce91c974f 100644 --- a/examples/globalArray/globalArrayXML.cpp +++ b/examples/globalArray/globalArrayXML.cpp @@ -5,86 +5,91 @@ * Author: pnorbert */ -#include <stdexcept> -#include <mpi.h> -#include <iostream> #include <fstream> +#include <iostream> +#include <mpi.h> +#include <stdexcept> #include <string> #include <vector> #include "../../include/ADIOS.h" -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - int rank, size; - const int NX = 10; - double t[NX]; - std::vector<double> p(NX); - MPI_Comm comm=MPI_COMM_WORLD; + int rank, size; + const int NX = 10; + double t[NX]; + std::vector<double> p(NX); + MPI_Comm comm = MPI_COMM_WORLD; - MPI_Init (&argc, &argv); - MPI_Comm_rank (comm, &rank); - MPI_Comm_size (comm, &size); + MPI_Init(&argc, &argv); + MPI_Comm_rank(comm, &rank); + MPI_Comm_size(comm, &size); - try - { - // ADIOS manager object creation. MPI must be initialized - adios::ADIOS adios( "globalArrayXML.xml", comm, true ); + try + { + // ADIOS manager object creation. MPI must be initialized + adios::ADIOS adios("globalArrayXML.xml", comm, true); - adios::ADIOS_OUTPUT &ckptfile = adios.Open( "globalArray.bp", comm, "a", "POSIX"); + adios::ADIOS_OUTPUT &ckptfile = + adios.Open("globalArray.bp", comm, "a", "POSIX"); - adios::ADIOS_OUTPUT ckptfile( "globalArray.bp", subcomm, "a", "POSIX"); - //adios::ADIOS_OUTPUT *ckptfile = adios.Open( "globalArray.bp", "POSIX"); + adios::ADIOS_OUTPUT ckptfile("globalArray.bp", subcomm, "a", "POSIX"); + // adios::ADIOS_OUTPUT *ckptfile = adios.Open( "globalArray.bp", "POSIX"); - //Get Monitor info - std::ofstream logStream( "info_" + std::to_string(rank) + ".log" ); - adios.MonitorGroups( logStream ); + // Get Monitor info + std::ofstream logStream("info_" + std::to_string(rank) + ".log"); + adios.MonitorGroups(logStream); - for (int it = 1; it <= 13; it++) - { + for (int it = 1; it <= 13; it++) + { - for (int i = 0; i < NX; i++) - { - t[i] = it*100.0 + rank*NX + i; - p[i] = it*1000.0 + rank*NX + i; - } + for (int i = 0; i < NX; i++) + { + t[i] = it * 100.0 + rank * NX + i; + p[i] = it * 1000.0 + rank * NX + i; + } -// if (it==1) -// adios.Open("arrays", "globalArray.bp", "w"); -// else -// adios.Open("arrays", "globalArray.bp", "a"); + // if (it==1) + // adios.Open("arrays", "globalArray.bp", "w"); + // else + // adios.Open("arrays", "globalArray.bp", "a"); - //uint64_t adios_groupsize, adios_totalsize; - // adios_groupsize = 4 + 4 + 4 + 2*NX*sizeof(double); - // adios_totalsize = adios.GroupSize("arrays", adios_groupsize); + // uint64_t adios_groupsize, adios_totalsize; + // adios_groupsize = 4 + 4 + 4 + 2*NX*sizeof(double); + // adios_totalsize = adios.GroupSize("arrays", adios_groupsize); - ckptfile.Write ("NX", &NX); - ckptfile.Write ("pressure", &p); - //adios.Write ("arrays", "NX", &NX); - //adios.Write ("arrays", "size", &size); - //adios.Write ("arrays", "rank", &rank); - //adios.Write ("arrays", "temperature", t); - //adios.Write ("arrays", "pressure", &p); + ckptfile.Write("NX", &NX); + ckptfile.Write("pressure", &p); + // adios.Write ("arrays", "NX", &NX); + // adios.Write ("arrays", "size", &size); + // adios.Write ("arrays", "rank", &rank); + // adios.Write ("arrays", "temperature", t); + // adios.Write ("arrays", "pressure", &p); - //adios.Close ("arrays"); - ckptfile.PerformIO(); - MPI_Barrier (comm); - if (rank==0) printf("Timestep %d written\n", it); - } - MPI_Barrier (comm); - ckptfile.Close(); - // need barrier before we destroy the ADIOS object here automatically - if (rank==0) printf("Finalize adios\n"); + // adios.Close ("arrays"); + ckptfile.PerformIO(); + MPI_Barrier(comm); + if (rank == 0) + printf("Timestep %d written\n", it); } - catch( std::exception& e ) //need to think carefully how to handle C++ exceptions with MPI to avoid deadlocking + MPI_Barrier(comm); + ckptfile.Close(); + // need barrier before we destroy the ADIOS object here automatically + if (rank == 0) + printf("Finalize adios\n"); + } + catch (std::exception &e) // need to think carefully how to handle C++ + // exceptions with MPI to avoid deadlocking + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << e.what() << "\n"; - } + std::cout << e.what() << "\n"; } + } - if (rank==0) printf("Finalize MPI\n"); - MPI_Finalize (); - return 0; + if (rank == 0) + printf("Finalize MPI\n"); + MPI_Finalize(); + return 0; } diff --git a/examples/globalArray/globalArrayZeroCopy.cpp b/examples/globalArray/globalArrayZeroCopy.cpp index 9a5716591..116c6bcca 100644 --- a/examples/globalArray/globalArrayZeroCopy.cpp +++ b/examples/globalArray/globalArrayZeroCopy.cpp @@ -5,117 +5,120 @@ * Author: pnorbert */ -#include <stdexcept> -#include <mpi.h> -#include <iostream> #include <fstream> +#include <iostream> +#include <mpi.h> +#include <stdexcept> #include <string> #include <vector> #include "../../include/ADIOS.h" -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - int rank, size; - const int NX = 10; - MPI_Comm comm=MPI_COMM_WORLD; - - MPI_Init (&argc, &argv); - MPI_Comm_rank (comm, &rank); - MPI_Comm_size (comm, &size); - - try + int rank, size; + const int NX = 10; + MPI_Comm comm = MPI_COMM_WORLD; + + MPI_Init(&argc, &argv); + MPI_Comm_rank(comm, &rank); + MPI_Comm_size(comm, &size); + + try + { + // ADIOS manager object creation. MPI must be initialized + adios::ADIOS adios("globalArrayNoXML.xml", comm, true); + + // set a maximum buffersize that ADIOS can use (for one group). + // multiple groups may use each such buffersize if they are overlapped or + // use time-aggregation or use zero-copy staging + adios.SetMaxBuffersize(100000000); + + // Define Group and its variables + // The group's transport can be defined at runtime in the input XML file + adios.CreateGroup("arrays", adios_stat_default); + + // Set the maximum buffersize for this group. This must happen before + // defining a zero copy variable, which will cause the group's internal + // buffer + // allocated (during the variable definition call) + adios.SetMaxBuffersize("arrays", 10000000); + + adios.DefineVariable("arrays", "NX", "int"); // scalar variable + adios.DefineVariable("arrays", "size", "int"); + adios.DefineVariable("arrays", "size", "rank"); + + // Define and allocate a 2D array with 1D decomposition and get back a + // pre-allocated typed pointer. + // The size of the array must be known at this point, so no scalar variables + // can + // be used for its dimensions. + std::string ldim = "1," + std::to_string(NX); // == "1,10" if NX==10 + std::string gdim = std::to_string(size) + "," + std::to_string(NX); + std::string offs = std::to_string(rank) + ",0"; + + double *t = adios.DefineZeroCopyVariable("arrays", "temperature", "double", + ldim, gdim, offs); + + // set a variable-level transformation for this variable + adios.SetVariableTransform("arrays", "temperature", "none"); + + std::vector<double> p = adios.DefineZeroCopyVariable( + "arrays", "pressure", "std::vector<double>", ldim, gdim, offs); + + // set a group-level transformation + adios.SetGroupTransform("arrays", "time-aggregate", + ""); // no options passed here + + // Get Monitor info + std::ofstream logStream("info_" + std::to_string(rank) + ".log"); + adios.MonitorGroups(logStream); + + for (int it = 1; it <= 13; it++) { - // ADIOS manager object creation. MPI must be initialized - adios::ADIOS adios( "globalArrayNoXML.xml", comm, true ); - - // set a maximum buffersize that ADIOS can use (for one group). - // multiple groups may use each such buffersize if they are overlapped or - // use time-aggregation or use zero-copy staging - adios.SetMaxBuffersize (100000000); - - // Define Group and its variables - // The group's transport can be defined at runtime in the input XML file - adios.CreateGroup ("arrays", adios_stat_default); - - // Set the maximum buffersize for this group. This must happen before - // defining a zero copy variable, which will cause the group's internal buffer - // allocated (during the variable definition call) - adios.SetMaxBuffersize ("arrays", 10000000); - - adios.DefineVariable ("arrays", "NX", "int"); // scalar variable - adios.DefineVariable ("arrays", "size", "int"); - adios.DefineVariable ("arrays", "size", "rank"); - - // Define and allocate a 2D array with 1D decomposition and get back a - // pre-allocated typed pointer. - // The size of the array must be known at this point, so no scalar variables can - // be used for its dimensions. - std::string ldim = "1," + std::to_string(NX); // == "1,10" if NX==10 - std::string gdim = std::to_string(size) + "," + std::to_string(NX); - std::string offs = std::to_string(rank) + ",0"; - - double *t = adios.DefineZeroCopyVariable( - "arrays", "temperature", "double", - ldim, gdim, offs); - - // set a variable-level transformation for this variable - adios.SetVariableTransform ("arrays", "temperature", "none"); - - std::vector<double> p = adios.DefineZeroCopyVariable( - "arrays", "pressure", "std::vector<double>", - ldim, gdim, offs); - - // set a group-level transformation - adios.SetGroupTransform ("arrays", "time-aggregate", ""); // no options passed here - - - - //Get Monitor info - std::ofstream logStream( "info_" + std::to_string(rank) + ".log" ); - adios.MonitorGroups( logStream ); - - for (int it = 1; it <= 13; it++) - { - - for (int i = 0; i < NX; i++) - { - t[i] = it*100.0 + rank*NX + i; - p[i] = it*1000.0 + rank*NX + i; - } - - if (it==1) - adios.Open("arrays", "globalArray.bp", "w"); - else - adios.Open("arrays", "globalArray.bp", "a"); - - //uint64_t adios_groupsize, adios_totalsize; - // adios_groupsize = 4 + 4 + 4 + 2*NX*sizeof(double); - // adios_totalsize = adios.GroupSize("arrays", adios_groupsize); - - adios.Write ("arrays", "NX", &NX); - adios.Write ("arrays", "size", &size); - adios.Write ("arrays", "rank", &rank); - adios.Write ("arrays", "temperature", t); - adios.Write ("arrays", "pressure", &p); - - adios.Close ("arrays"); - MPI_Barrier (comm); - if (rank==0) printf("Timestep %d written\n", it); - } - MPI_Barrier (comm); - // need barrier before we destroy the ADIOS object here automatically - if (rank==0) printf("Finalize adios\n"); + + for (int i = 0; i < NX; i++) + { + t[i] = it * 100.0 + rank * NX + i; + p[i] = it * 1000.0 + rank * NX + i; + } + + if (it == 1) + adios.Open("arrays", "globalArray.bp", "w"); + else + adios.Open("arrays", "globalArray.bp", "a"); + + // uint64_t adios_groupsize, adios_totalsize; + // adios_groupsize = 4 + 4 + 4 + 2*NX*sizeof(double); + // adios_totalsize = adios.GroupSize("arrays", adios_groupsize); + + adios.Write("arrays", "NX", &NX); + adios.Write("arrays", "size", &size); + adios.Write("arrays", "rank", &rank); + adios.Write("arrays", "temperature", t); + adios.Write("arrays", "pressure", &p); + + adios.Close("arrays"); + MPI_Barrier(comm); + if (rank == 0) + printf("Timestep %d written\n", it); } - catch( std::exception& e ) //need to think carefully how to handle C++ exceptions with MPI to avoid deadlocking + MPI_Barrier(comm); + // need barrier before we destroy the ADIOS object here automatically + if (rank == 0) + printf("Finalize adios\n"); + } + catch (std::exception &e) // need to think carefully how to handle C++ + // exceptions with MPI to avoid deadlocking + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << e.what() << "\n"; - } + std::cout << e.what() << "\n"; } + } - if (rank==0) printf("Finalize MPI\n"); - MPI_Finalize (); - return 0; + if (rank == 0) + printf("Finalize MPI\n"); + MPI_Finalize(); + return 0; } diff --git a/examples/groupless/basic/reader.cpp b/examples/groupless/basic/reader.cpp index ccbde8911..fde99ee87 100644 --- a/examples/groupless/basic/reader.cpp +++ b/examples/groupless/basic/reader.cpp @@ -5,176 +5,186 @@ * Author: pnorbert */ -#include <vector> #include <iostream> +#include <vector> -#include <mpi.h> #include "ADIOS_CPP.h" +#include <mpi.h> - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - int rank, nproc; - MPI_Init( &argc, &argv ); - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); - MPI_Comm_size( MPI_COMM_WORLD, &nproc); - const bool adiosDebug = true; - - adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); - - //Application variable - std::vector<double> NiceArray; - std::vector<float> RaggedArray; - unsigned int Nx; - int Nparts; - int Nwriters; - - try + int rank, nproc; + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); + const bool adiosDebug = true; + + adios::ADIOS adios(MPI_COMM_WORLD, adiosDebug); + + // Application variable + std::vector<double> NiceArray; + std::vector<float> RaggedArray; + unsigned int Nx; + int Nparts; + int Nwriters; + + try + { + // Define method for engine creation + // 1. Get method def from config file or define new one + adios::Method &bpReaderSettings = adios.GetMethod("input"); + if (bpReaderSettings.undeclared()) { - //Define method for engine creation - // 1. Get method def from config file or define new one - adios::Method& bpReaderSettings = adios.GetMethod( "input" ); - if( bpReaderSettings.undeclared() ) - { - // if not defined by user, we can change the default settings - bpReaderSettings.SetEngine( "BP" ); // BP is the default engine - } - - //Create engine smart pointer due to polymorphism, - // Default behavior - // auto bpReader = adios.Open( "myNumbers.bp", "r" ); - // this would just open with a default transport, which is "BP" - auto bpReader = adios.Open( "myNumbers.bp", "r", bpReaderSettings ); - - // All the above is same as default use: - //auto bpReader = adios.Open( "myNumbers.bp", "r"); - - if( bpReader == nullptr ) - throw std::ios_base::failure( "ERROR: failed to open ADIOS bpReader\n" ); - - - /* Variable names are available as a vector of strings */ - std::cout << "List of variables in file: " << bpReader->VariableNames << "\n"; - - /* NX */ - bpReader->Read<unsigned int>( "NX", Nx ); // read a Global scalar which has a single value in a step - - /* nproc */ - bpReader->Read<int>( "nproc", Nwriters ); // also a global scalar - - - /* Nparts */ - // Nparts local scalar is presented as a 1D array of Nwriters elements. - // We need to read a specific value the same way as reading from any 1D array. - // Make a single-value selection to describe our rank's position in the - // 1D array of Nwriters values. - if( rank < Nwriters ) - { - std::shared_ptr<adios::Variable> varNparts = bpReader.InquiryVariable("Nparts"); - std::unique_ptr<adios::Selection> selNparts = adios.SelectionBoundingBox( {1}, {rank} ); - varNparts->SetSelection( selNparts ); - bpReader->Read<int>( varNparts, Nparts ); - } - // or we could just read the whole array by every process - std::vector<int> partsV( Nwriters ); - bpReader->Read<int>( "Nparts", partsV.data() ); // read with string name, no selection => read whole array - - std::vector<int> partsV; - bpReader->Read<int>( "Nparts", partsV); // read with string name, no selection => read whole array - (Nwriters == partsV.size()) + // if not defined by user, we can change the default settings + bpReaderSettings.SetEngine("BP"); // BP is the default engine + } - /* Nice */ - // inquiry about a variable, whose name we know - std::shared_ptr<adios::Variable> varNice = bpReader.InquiryVariable("Nice"); + // Create engine smart pointer due to polymorphism, + // Default behavior + // auto bpReader = adios.Open( "myNumbers.bp", "r" ); + // this would just open with a default transport, which is "BP" + auto bpReader = adios.Open("myNumbers.bp", "r", bpReaderSettings); - if( varNice == nullptr ) - throw std::ios_base::failure( "ERROR: failed to find variable 'myDoubles' in input file\n" ); + // All the above is same as default use: + // auto bpReader = adios.Open( "myNumbers.bp", "r"); - // ? how do we know about the type? std::string varNice->m_Type - uint64_t gdim = varNice->m_GlobalDimensions[0]; // ?member var or member func? - uint64_t ldim = gdim / nproc; - uint64_t offs = rank * ldim; - if( rank == nproc-1 ) - { - ldim = gdim - (ldim * gdim); - } + if (bpReader == nullptr) + throw std::ios_base::failure("ERROR: failed to open ADIOS bpReader\n"); - NiceArray.reserve(ldim); + /* Variable names are available as a vector of strings */ + std::cout << "List of variables in file: " << bpReader->VariableNames + << "\n"; - // Make a 1D selection to describe the local dimensions of the variable we READ and - // its offsets in the global spaces - std::unique_ptr<adios::Selection> bbsel = adios.SelectionBoundingBox( {ldim}, {offs} ); // local dims and offsets; both as list - varNice->SetSelection( bbsel ); - bpReader->Read<double>( varNice, NiceArray.data() ); + /* NX */ + bpReader->Read<unsigned int>( + "NX", Nx); // read a Global scalar which has a single value in a step + /* nproc */ + bpReader->Read<int>("nproc", Nwriters); // also a global scalar + /* Nparts */ + // Nparts local scalar is presented as a 1D array of Nwriters elements. + // We need to read a specific value the same way as reading from any 1D + // array. + // Make a single-value selection to describe our rank's position in the + // 1D array of Nwriters values. + if (rank < Nwriters) + { + std::shared_ptr<adios::Variable> varNparts = + bpReader.InquiryVariable("Nparts"); + std::unique_ptr<adios::Selection> selNparts = + adios.SelectionBoundingBox({1}, {rank}); + varNparts->SetSelection(selNparts); + bpReader->Read<int>(varNparts, Nparts); + } + // or we could just read the whole array by every process + std::vector<int> partsV(Nwriters); + bpReader->Read<int>( + "Nparts", + partsV + .data()); // read with string name, no selection => read whole array + + std::vector<int> partsV; + bpReader->Read<int>( + "Nparts", + partsV); // read with string name, no selection => read whole array + (Nwriters == partsV.size()) - /* Ragged */ + /* Nice */ // inquiry about a variable, whose name we know - std::shared_ptr<adios::Variable<void> > varRagged = bpReader.InquiryVariable("Ragged"); - if( varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION) - { - throw std::ios_base::failure( "Unexpected condition: Ragged array's fast dimension " - "is supposed to be VARYING_DIMENSION\n" ); - } - // We have here varRagged->sum_nblocks, nsteps, nblocks[], global - if( rank < varRagged->nblocks[0] ) // same as rank < Nwriters in this example - { - // get per-writer size information - varRagged->InquiryBlocks(); - // now we have the dimensions per block - - unsigned long long int ldim = varRagged->blockinfo[rank].m_Dimensions[1]; - RaggedArray.resize( ldim ); - - std::unique_ptr<adios::Selection> wbsel = adios.SelectionWriteblock( rank ); - varRagged->SetSelection( wbsel ); - bpReader->Read<float>( varRagged, RaggedArray.data() ); - - // We can use bounding box selection as well - std::unique_ptr<adios::Selection> rbbsel = adios.SelectionBoundingBox( {1,ldim}, {rank,0} ); - varRagged->SetSelection( rbbsel ); - bpReader->Read<float>( varRagged, RaggedArray.data() ); - } - - /* Extra help to process Ragged */ - int maxRaggedDim = varRagged->GetMaxGlobalDimensions(1); // contains the largest - std::vector<int> raggedDims = varRagged->GetVaryingGlobalDimensions(1); // contains all individual sizes in that dimension - - - // Close file/stream - bpReader->Close(); - } - catch( std::invalid_argument& e ) + std::shared_ptr<adios::Variable> + varNice = bpReader.InquiryVariable("Nice"); + + if (varNice == nullptr) + throw std::ios_base::failure( + "ERROR: failed to find variable 'myDoubles' in input file\n"); + + // ? how do we know about the type? std::string varNice->m_Type + uint64_t gdim = + varNice->m_GlobalDimensions[0]; // ?member var or member func? + uint64_t ldim = gdim / nproc; + uint64_t offs = rank * ldim; + if (rank == nproc - 1) { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + ldim = gdim - (ldim * gdim); } - catch( std::ios_base::failure& e ) + + NiceArray.reserve(ldim); + + // Make a 1D selection to describe the local dimensions of the variable we + // READ and + // its offsets in the global spaces + std::unique_ptr<adios::Selection> bbsel = adios.SelectionBoundingBox( + {ldim}, {offs}); // local dims and offsets; both as list + varNice->SetSelection(bbsel); + bpReader->Read<double>(varNice, NiceArray.data()); + + /* Ragged */ + // inquiry about a variable, whose name we know + std::shared_ptr<adios::Variable<void>> varRagged = + bpReader.InquiryVariable("Ragged"); + if (varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION) { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + throw std::ios_base::failure( + "Unexpected condition: Ragged array's fast dimension " + "is supposed to be VARYING_DIMENSION\n"); } - catch( std::exception& e ) + // We have here varRagged->sum_nblocks, nsteps, nblocks[], global + if (rank < varRagged->nblocks[0]) // same as rank < Nwriters in this example { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + // get per-writer size information + varRagged->InquiryBlocks(); + // now we have the dimensions per block + + unsigned long long int ldim = varRagged->blockinfo[rank].m_Dimensions[1]; + RaggedArray.resize(ldim); + + std::unique_ptr<adios::Selection> wbsel = adios.SelectionWriteblock(rank); + varRagged->SetSelection(wbsel); + bpReader->Read<float>(varRagged, RaggedArray.data()); + + // We can use bounding box selection as well + std::unique_ptr<adios::Selection> rbbsel = + adios.SelectionBoundingBox({1, ldim}, {rank, 0}); + varRagged->SetSelection(rbbsel); + bpReader->Read<float>(varRagged, RaggedArray.data()); } - MPI_Finalize( ); + /* Extra help to process Ragged */ + int maxRaggedDim = + varRagged->GetMaxGlobalDimensions(1); // contains the largest + std::vector<int> raggedDims = varRagged->GetVaryingGlobalDimensions( + 1); // contains all individual sizes in that dimension + + // Close file/stream + bpReader->Close(); + } + catch (std::invalid_argument &e) + { + if (rank == 0) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch (std::ios_base::failure &e) + { + if (rank == 0) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch (std::exception &e) + { + if (rank == 0) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } - return 0; + MPI_Finalize(); + return 0; } - - - diff --git a/examples/groupless/basic/writer.cpp b/examples/groupless/basic/writer.cpp index bc3606985..49832c9f4 100644 --- a/examples/groupless/basic/writer.cpp +++ b/examples/groupless/basic/writer.cpp @@ -5,141 +5,156 @@ * Author: pnorbert */ -#include <vector> #include <iostream> +#include <vector> -#include <mpi.h> #include "ADIOS_CPP.h" +#include <mpi.h> -namespace adios { - typedef enum { - VARYING_DIMENSION = -1, - LOCAL_VALUE = 0, - GLOBAL_VALUE = 1 - }; +namespace adios +{ +typedef enum { VARYING_DIMENSION = -1, LOCAL_VALUE = 0, GLOBAL_VALUE = 1 }; } -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - int rank, nproc; - MPI_Init( &argc, &argv ); - MPI_Comm_rank( MPI_COMM_WORLD, &rank); - MPI_Comm_size( MPI_COMM_WORLD, &nproc); - const bool adiosDebug = true; - - adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); - - //Application variable - const unsigned int Nx = 10; - const int Nparts = rand()%6 + 5; // random size per process, 5..10 each - - std::vector<double> NiceArray( Nx ); - for( int i=0; i < Nx; i++ ) + int rank, nproc; + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); + const bool adiosDebug = true; + + adios::ADIOS adios(MPI_COMM_WORLD, adiosDebug); + + // Application variable + const unsigned int Nx = 10; + const int Nparts = rand() % 6 + 5; // random size per process, 5..10 each + + std::vector<double> NiceArray(Nx); + for (int i = 0; i < Nx; i++) + { + NiceArray[i] = rank * Nx + (double)i; + } + + std::vector<float> RaggedArray(Nparts); + for (int i = 0; i < Nparts; i++) + { + RaggedArray[i] = rank * Nx + (float)i; + } + + try + { + // Define group and variables with transforms, variables don't have + // functions, only group can access variables + adios::Variable<unsigned int> &varNX = adios.DefineVariable<unsigned int>( + "NX"); // global single-value across processes + adios::Variable<int> &varNproc = adios.DefineVariable<int>( + "nproc", adios::GLOBAL_VALUE); // same def for global value + adios::Variable<int> &varNparts = adios.DefineVariable<int>( + "Nparts", + adios::LOCAL_VALUE); // a single-value different on every process + adios::Variable<double> &varNice = + adios.DefineVariable<double>("Nice", {nproc * Nx}); // 1D global array + adios::Variable<float> &varRagged = adios.DefineVariable<float>( + "Ragged", {nproc, adios::VARYING_DIMENSION}); // ragged array + + // add transform to variable in group...not executed (just testing API) + adios::Transform bzip2 = adios::transform::BZIP2(); + varNice->AddTransform(bzip2, 1); + + // Define method for engine creation + // 1. Get method def from config file or define new one + adios::Method &bpWriterSettings = adios.GetMethod("output"); + if (bpWriterSettings.undeclared()) { - NiceArray[i] = rank*Nx + (double)i; + // if not defined by user, we can change the default settings + bpWriterSettings.SetEngine("BP"); // BP is the default engine + bpWriterSettings.AddTransport( + "File", "lucky=yes"); // ISO-POSIX file is the default transport + // Passing parameters to the transport + bpWriterSettings.SetParameters("have_metadata_file", + "yes"); // Passing parameters to the engine + bpWriterSettings.SetParameters("Aggregation", + (nproc + 1) / 2); // number of aggregators } - std::vector<float> RaggedArray( Nparts ); - for( int i=0; i < Nparts; i++ ) - { - RaggedArray[i] = rank*Nx + (float)i; - } + // Open returns a smart pointer to Engine containing the Derived class + // Writer + // "w" means we overwrite any existing file on disk, but AdvanceStep will + // append steps later. + auto bpWriter = adios.Open("myNumbers.bp", "w", bpWriterSettings); + if (bpWriter == nullptr) + throw std::ios_base::failure("ERROR: failed to open ADIOS bpWriter\n"); - try + if (rank == 0) { - //Define group and variables with transforms, variables don't have functions, only group can access variables - adios::Variable<unsigned int>& varNX = adios.DefineVariable<unsigned int>( "NX" ); // global single-value across processes - adios::Variable<int>& varNproc = adios.DefineVariable<int>( "nproc", adios::GLOBAL_VALUE ); // same def for global value - adios::Variable<int>& varNparts = adios.DefineVariable<int>( "Nparts", adios::LOCAL_VALUE ); // a single-value different on every process - adios::Variable<double>& varNice = adios.DefineVariable<double>( "Nice", {nproc*Nx} ); // 1D global array - adios::Variable<float>& varRagged = adios.DefineVariable<float>( "Ragged", {nproc,adios::VARYING_DIMENSION} ); // ragged array - - //add transform to variable in group...not executed (just testing API) - adios::Transform bzip2 = adios::transform::BZIP2( ); - varNice->AddTransform( bzip2, 1 ); - - //Define method for engine creation - // 1. Get method def from config file or define new one - adios::Method& bpWriterSettings = adios.GetMethod( "output" ); - if( bpWriterSettings.undeclared() ) - { - // if not defined by user, we can change the default settings - bpWriterSettings.SetEngine( "BP" ); // BP is the default engine - bpWriterSettings.AddTransport( "File", "lucky=yes" ); // ISO-POSIX file is the default transport - // Passing parameters to the transport - bpWriterSettings.SetParameters("have_metadata_file","yes" ); // Passing parameters to the engine - bpWriterSettings.SetParameters( "Aggregation", (nproc+1)/2 ); // number of aggregators - } - - //Open returns a smart pointer to Engine containing the Derived class Writer - // "w" means we overwrite any existing file on disk, but AdvanceStep will append steps later. - auto bpWriter = adios.Open( "myNumbers.bp", "w", bpWriterSettings ); - - if( bpWriter == nullptr ) - throw std::ios_base::failure( "ERROR: failed to open ADIOS bpWriter\n" ); - - if( rank == 0 ) - { - // Writing a global scalar from only one process - bpWriter->Write<unsigned int>( varNX, Nx ); - } - // Writing a local scalar on every process. Will be shown at reading as a 1D array - bpWriter->Write<int>( varNparts, Nparts ); - - // Writing a global scalar on every process is useless. Information will be thrown away - // and only rank 0's data will be in the output - bpWriter->Write<int>( varNproc, nproc ); - - // Make a 1D selection to describe the local dimensions of the variable we write and - // its offsets in the global spaces - adios::Selection& sel = adios.SelectionBoundingBox( {Nx}, {rank*Nx} ); // local dims and offsets; both as list - varNice.SetSelection( sel ); - bpWriter->Write<double>( varNice, NiceArray.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived - - adios::Selection& lsel = adios.SelectionBoundingBox( {1,Nparts}, {rank,0} ); - varRagged.SetSelection( sel ); - bpWriter->Write<float>( varRagged, RaggedArray.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived - - // Indicate we are done for this step - // N-to-M Aggregation, disk I/O will be performed during this call, unless - // time aggregation postpones all of that to some later step - bpWriter->Advance( ); - bpWriter->AdvanceAsync( callback_func_to_notify_me ); - - // Called once: indicate that we are done with this output for the run - bpWriter->Close( ); + // Writing a global scalar from only one process + bpWriter->Write<unsigned int>(varNX, Nx); } - catch( std::invalid_argument& e ) + // Writing a local scalar on every process. Will be shown at reading as a 1D + // array + bpWriter->Write<int>(varNparts, Nparts); + + // Writing a global scalar on every process is useless. Information will be + // thrown away + // and only rank 0's data will be in the output + bpWriter->Write<int>(varNproc, nproc); + + // Make a 1D selection to describe the local dimensions of the variable we + // write and + // its offsets in the global spaces + adios::Selection &sel = adios.SelectionBoundingBox( + {Nx}, {rank * Nx}); // local dims and offsets; both as list + varNice.SetSelection(sel); + bpWriter->Write<double>(varNice, NiceArray.data()); // Base class Engine own + // the Write<T> that + // will call overloaded + // Write from Derived + + adios::Selection &lsel = adios.SelectionBoundingBox({1, Nparts}, {rank, 0}); + varRagged.SetSelection(sel); + bpWriter->Write<float>(varRagged, RaggedArray.data()); // Base class Engine + // own the Write<T> + // that will call + // overloaded Write + // from Derived + + // Indicate we are done for this step + // N-to-M Aggregation, disk I/O will be performed during this call, unless + // time aggregation postpones all of that to some later step + bpWriter->Advance(); + bpWriter->AdvanceAsync(callback_func_to_notify_me); + + // Called once: indicate that we are done with this output for the run + bpWriter->Close(); + } + catch (std::invalid_argument &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::ios_base::failure& e ) + } + catch (std::ios_base::failure &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::exception& e ) + } + catch (std::exception &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } + } - MPI_Finalize( ); - - return 0; + MPI_Finalize(); + return 0; } - - - diff --git a/examples/groupless/compound/reader.cpp b/examples/groupless/compound/reader.cpp index 16c78cd7a..fae2c7583 100644 --- a/examples/groupless/compound/reader.cpp +++ b/examples/groupless/compound/reader.cpp @@ -5,198 +5,209 @@ * Author: eisen, modified from basic by pnorbert */ -#include <vector> #include <iostream> +#include <vector> -#include <mpi.h> #include "ADIOS_CPP.h" +#include <mpi.h> - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - int rank, nproc; - MPI_Init( &argc, &argv ); - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); - MPI_Comm_size( MPI_COMM_WORLD, &nproc); - const bool adiosDebug = true; - - adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); - - // Application variable - // GSE === user-defined structure - // - // Like HDF5 example, read with a subset of the structure that was written. - // Easily handled by FFS and HDF5, but ambitious for ADIOS - typedef struct s2_t { - double c; - int a; - }; - unsigned int Nx; - int Nparts; - int Nwriters; - - try + int rank, nproc; + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); + const bool adiosDebug = true; + + adios::ADIOS adios(MPI_COMM_WORLD, adiosDebug); + + // Application variable + // GSE === user-defined structure + // + // Like HDF5 example, read with a subset of the structure that was written. + // Easily handled by FFS and HDF5, but ambitious for ADIOS + typedef struct s2_t + { + double c; + int a; + }; + unsigned int Nx; + int Nparts; + int Nwriters; + + try + { + // Define method for engine creation + // 1. Get method def from config file or define new one + adios::Method &bpReaderSettings = adios.GetMethod("input"); + if (bpReaderSettings.undeclared()) { - //Define method for engine creation - // 1. Get method def from config file or define new one - adios::Method& bpReaderSettings = adios.GetMethod( "input" ); - if( bpReaderSettings.undeclared() ) - { - // if not defined by user, we can change the default settings - bpReaderSettings.SetEngine( "BP" ); // BP is the default engine - } - - //Create engine smart pointer due to polymorphism, - // Default behavior - // auto bpReader = adios.Open( "myNumbers.bp", "r" ); - // this would just open with a default transport, which is "BP" - auto bpReader = adios.Open( "myNumbers.bp", "r", bpReaderSettings ); - - // All the above is same as default use: - //auto bpReader = adios.Open( "myNumbers.bp", "r"); - - if( bpReader == nullptr ) - throw std::ios_base::failure( "ERROR: failed to open ADIOS bpReader\n" ); - - - /* Variable names are available as a vector of strings */ - std::cout << "List of variables in file: " << bpReader->VariableNames << "\n"; - - /* NX */ - bpReader->Read<unsigned int>( "NX", Nx ); // read a Global scalar which has a single value in a step - - /* nproc */ - bpReader->Read<int>( "nproc", Nwriters ); // also a global scalar - - - /* Nparts */ - // Nparts local scalar is presented as a 1D array of Nwriters elements. - // We need to read a specific value the same way as reading from any 1D array. - // Make a single-value selection to describe our rank's position in the - // 1D array of Nwriters values. - if( rank < Nwriters ) - { - std::shared_ptr<adios::Variable> varNparts = bpReader.InquiryVariable("Nparts"); - std::unique_ptr<adios::Selection> selNparts = adios.SelectionBoundingBox( {1}, {rank} ); - varNparts->SetSelection( selNparts ); - bpReader->Read<int>( varNparts, Nparts ); - } - // or we could just read the whole array by every process - std::vector<int> partsV( Nwriters ); - bpReader->Read<int>( "Nparts", partsV.data() ); // read with string name, no selection => read whole array - - std::vector<int> partsV; - bpReader->Read<int>( "Nparts", partsV); // read with string name, no selection => read whole array - (Nwriters == partsV.size()) + // if not defined by user, we can change the default settings + bpReaderSettings.SetEngine("BP"); // BP is the default engine + } + + // Create engine smart pointer due to polymorphism, + // Default behavior + // auto bpReader = adios.Open( "myNumbers.bp", "r" ); + // this would just open with a default transport, which is "BP" + auto bpReader = adios.Open("myNumbers.bp", "r", bpReaderSettings); + + // All the above is same as default use: + // auto bpReader = adios.Open( "myNumbers.bp", "r"); + + if (bpReader == nullptr) + throw std::ios_base::failure("ERROR: failed to open ADIOS bpReader\n"); + + /* Variable names are available as a vector of strings */ + std::cout << "List of variables in file: " << bpReader->VariableNames + << "\n"; + + /* NX */ + bpReader->Read<unsigned int>( + "NX", Nx); // read a Global scalar which has a single value in a step + + /* nproc */ + bpReader->Read<int>("nproc", Nwriters); // also a global scalar + + /* Nparts */ + // Nparts local scalar is presented as a 1D array of Nwriters elements. + // We need to read a specific value the same way as reading from any 1D + // array. + // Make a single-value selection to describe our rank's position in the + // 1D array of Nwriters values. + if (rank < Nwriters) + { + std::shared_ptr<adios::Variable> varNparts = + bpReader.InquiryVariable("Nparts"); + std::unique_ptr<adios::Selection> selNparts = + adios.SelectionBoundingBox({1}, {rank}); + varNparts->SetSelection(selNparts); + bpReader->Read<int>(varNparts, Nparts); + } + // or we could just read the whole array by every process + std::vector<int> partsV(Nwriters); + bpReader->Read<int>( + "Nparts", + partsV + .data()); // read with string name, no selection => read whole array + + std::vector<int> partsV; + bpReader->Read<int>( + "Nparts", + partsV); // read with string name, no selection => read whole array + (Nwriters == partsV.size()) /* Nice */ // inquiry about a variable, whose name we know - /* GSE === compound type declaration borrowed heavily from HDF5 style */ - adios::CompType mtype( sizeof(s2_t) ); - mtype.insertMember( "c_name", OFFSET(s2_t, c), PredType::NATIVE_DOUBLE); - mtype.insertMember( "a_name", OFFSET(s2_t, a), PredType::NATIVE_INT); - - /* - * GSE === this is a bit conceptually different. There was no real - * check in the prior API that the variable in the file was in any way - * "compatible" with how we planned to read it. This could be done - * here, by providing the details of the structure that we are - * prepared to read in the inquiryVariable, or if we had an API that - * allowed more introspection, we could perhaps support a query on the - * adios::Variable and a later operation that informed it of the data - * type that we were prepared to extract from it. - */ - std::shared_ptr<adios::Variable> varNice = bpReader.InquiryVariable("Nice", mtype); - - if( varNice == nullptr ) - throw std::ios_base::failure( "ERROR: failed to find variable 'myDoubles' in input file\n" ); - - // ? how do we know about the type? std::string varNice->m_Type - uint64_t gdim = varNice->m_GlobalDimensions[0]; // ?member var or member func? - uint64_t ldim = gdim / nproc; - uint64_t offs = rank * ldim; - if( rank == nproc-1 ) - { - ldim = gdim - (ldim * gdim); - } - - NiceArray.reserve(ldim); - - // Make a 1D selection to describe the local dimensions of the variable we READ and - // its offsets in the global spaces - std::unique_ptr<adios::Selection> bbsel = adios.SelectionBoundingBox( {ldim}, {offs} ); // local dims and offsets; both as list - varNice->SetSelection( bbsel ); - // GSE === Again, templated here? - bpReader->Read<s2_t>( varNice, NiceArray.data() ); - - - - /* Ragged */ - // inquiry about a variable, whose name we know - std::shared_ptr<adios::Variable<void> > varRagged = bpReader.InquiryVariable("Ragged"); - if( varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION) - { - throw std::ios_base::failure( "Unexpected condition: Ragged array's fast dimension " - "is supposed to be VARYING_DIMENSION\n" ); - } - // We have here varRagged->sum_nblocks, nsteps, nblocks[], global - if( rank < varRagged->nblocks[0] ) // same as rank < Nwriters in this example - { - // get per-writer size information - varRagged->InquiryBlocks(); - // now we have the dimensions per block - - unsigned long long int ldim = varRagged->blockinfo[rank].m_Dimensions[1]; - RaggedArray.resize( ldim ); - - std::unique_ptr<adios::Selection> wbsel = adios.SelectionWriteblock( rank ); - varRagged->SetSelection( wbsel ); - bpReader->Read<float>( varRagged, RaggedArray.data() ); - - // We can use bounding box selection as well - std::unique_ptr<adios::Selection> rbbsel = adios.SelectionBoundingBox( {1,ldim}, {rank,0} ); - varRagged->SetSelection( rbbsel ); - bpReader->Read<float>( varRagged, RaggedArray.data() ); - } - - /* Extra help to process Ragged */ - int maxRaggedDim = varRagged->GetMaxGlobalDimensions(1); // contains the largest - std::vector<int> raggedDims = varRagged->GetVaryingGlobalDimensions(1); // contains all individual sizes in that dimension - - - // Close file/stream - bpReader->Close(); - } - catch( std::invalid_argument& e ) + /* GSE === compound type declaration borrowed heavily from HDF5 style */ + adios::CompType mtype(sizeof(s2_t)); + mtype.insertMember("c_name", OFFSET(s2_t, c), PredType::NATIVE_DOUBLE); + mtype.insertMember("a_name", OFFSET(s2_t, a), PredType::NATIVE_INT); + + /* + * GSE === this is a bit conceptually different. There was no real + * check in the prior API that the variable in the file was in any way + * "compatible" with how we planned to read it. This could be done + * here, by providing the details of the structure that we are + * prepared to read in the inquiryVariable, or if we had an API that + * allowed more introspection, we could perhaps support a query on the + * adios::Variable and a later operation that informed it of the data + * type that we were prepared to extract from it. + */ + std::shared_ptr<adios::Variable> varNice = + bpReader.InquiryVariable("Nice", mtype); + + if (varNice == nullptr) + throw std::ios_base::failure( + "ERROR: failed to find variable 'myDoubles' in input file\n"); + + // ? how do we know about the type? std::string varNice->m_Type + uint64_t gdim = + varNice->m_GlobalDimensions[0]; // ?member var or member func? + uint64_t ldim = gdim / nproc; + uint64_t offs = rank * ldim; + if (rank == nproc - 1) { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + ldim = gdim - (ldim * gdim); } - catch( std::ios_base::failure& e ) + + NiceArray.reserve(ldim); + + // Make a 1D selection to describe the local dimensions of the variable we + // READ and + // its offsets in the global spaces + std::unique_ptr<adios::Selection> bbsel = adios.SelectionBoundingBox( + {ldim}, {offs}); // local dims and offsets; both as list + varNice->SetSelection(bbsel); + // GSE === Again, templated here? + bpReader->Read<s2_t>(varNice, NiceArray.data()); + + /* Ragged */ + // inquiry about a variable, whose name we know + std::shared_ptr<adios::Variable<void>> varRagged = + bpReader.InquiryVariable("Ragged"); + if (varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION) { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + throw std::ios_base::failure( + "Unexpected condition: Ragged array's fast dimension " + "is supposed to be VARYING_DIMENSION\n"); } - catch( std::exception& e ) + // We have here varRagged->sum_nblocks, nsteps, nblocks[], global + if (rank < varRagged->nblocks[0]) // same as rank < Nwriters in this example { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + // get per-writer size information + varRagged->InquiryBlocks(); + // now we have the dimensions per block + + unsigned long long int ldim = varRagged->blockinfo[rank].m_Dimensions[1]; + RaggedArray.resize(ldim); + + std::unique_ptr<adios::Selection> wbsel = adios.SelectionWriteblock(rank); + varRagged->SetSelection(wbsel); + bpReader->Read<float>(varRagged, RaggedArray.data()); + + // We can use bounding box selection as well + std::unique_ptr<adios::Selection> rbbsel = + adios.SelectionBoundingBox({1, ldim}, {rank, 0}); + varRagged->SetSelection(rbbsel); + bpReader->Read<float>(varRagged, RaggedArray.data()); } - MPI_Finalize( ); + /* Extra help to process Ragged */ + int maxRaggedDim = + varRagged->GetMaxGlobalDimensions(1); // contains the largest + std::vector<int> raggedDims = varRagged->GetVaryingGlobalDimensions( + 1); // contains all individual sizes in that dimension + + // Close file/stream + bpReader->Close(); + } + catch (std::invalid_argument &e) + { + if (rank == 0) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch (std::ios_base::failure &e) + { + if (rank == 0) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch (std::exception &e) + { + if (rank == 0) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } - return 0; + MPI_Finalize(); + return 0; } - - - diff --git a/examples/groupless/compound/writer.cpp b/examples/groupless/compound/writer.cpp index e5d7e7307..086d8e1a7 100644 --- a/examples/groupless/compound/writer.cpp +++ b/examples/groupless/compound/writer.cpp @@ -5,149 +5,159 @@ * Author: pnorbert */ -#include <vector> #include <iostream> +#include <vector> -#include <mpi.h> #include "ADIOS_CPP.h" +#include <mpi.h> -namespace adios { - typedef enum { - VARYING_DIMENSION = -1, - LOCAL_VALUE = 0, - GLOBAL_VALUE = 1 - }; +namespace adios +{ +typedef enum { VARYING_DIMENSION = -1, LOCAL_VALUE = 0, GLOBAL_VALUE = 1 }; } -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - int rank, nproc; - MPI_Init( &argc, &argv ); - MPI_Comm_rank( MPI_COMM_WORLD, &rank); - MPI_Comm_size( MPI_COMM_WORLD, &nproc); - const bool adiosDebug = true; - - adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); - - //Application variable - const unsigned int Nx = 10; - // GSE === user-defined structure - typedef struct s1_t { - int a; - float b; - double c; - }; - const int Nparts = rand()%6 + 5; // random size per process, 5..10 each - - std::vector<s1_t> NiceArray( Nx ); - for( int i=0; i < Nx; i++ ) + int rank, nproc; + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); + const bool adiosDebug = true; + + adios::ADIOS adios(MPI_COMM_WORLD, adiosDebug); + + // Application variable + const unsigned int Nx = 10; + // GSE === user-defined structure + typedef struct s1_t + { + int a; + float b; + double c; + }; + const int Nparts = rand() % 6 + 5; // random size per process, 5..10 each + + std::vector<s1_t> NiceArray(Nx); + for (int i = 0; i < Nx; i++) + { + NiceArray.push_back(ss1_t()); + NiceArray[i].a = rank * Nx + (double)i; + NiceArray[i].b = 100.0 * rank * Nx + 100.0 * (double)i; + NiceArray[i].c = 10000.0 * rank * Nx + 10000.0 * (double)i; + } + + try + { + /* GSE === compound type declaration borrowed heavily from HDF5 style */ + adios::CompType mtype(sizeof(s1_t)); + mtype.insertMember("a_name", OFFSET(s1_t, a), PredType::NATIVE_INT); + mtype.insertMember("c_name", OFFSET(s1_t, c), PredType::NATIVE_DOUBLE); + mtype.insertMember("b_name", OFFSET(s1_t, b), PredType::NATIVE_FLOAT); + + // Define group and variables with transforms, variables don't have + // functions, only group can access variables + adios::Variable<unsigned int> &varNX = adios.DefineVariable<unsigned int>( + "NX"); // global single-value across processes + adios::Variable<int> &varNproc = adios.DefineVariable<int>( + "nproc", adios::GLOBAL_VALUE); // same def for global value + adios::Variable<int> &varNparts = adios.DefineVariable<int>( + "Nparts", + adios::LOCAL_VALUE); // a single-value different on every process + + // GSE === template necessary or useful here? Extra argument for + // previously-built compound type information */ + adios::Variable<s1_t> &varNice = adios.DefineVariable<s1_t>( + "Nice", {nproc * Nx}, mtype); // 1D global array + + // add transform to variable in group...not executed (just testing API) + adios::Transform bzip2 = adios::transform::BZIP2(); + varNice->AddTransform(bzip2, 1); + + // Define method for engine creation + // 1. Get method def from config file or define new one + adios::Method &bpWriterSettings = adios.GetMethod("output"); + if (bpWriterSettings.undeclared()) { - NiceArray.push_back(ss1_t()); - NiceArray[i].a = rank*Nx + (double)i; - NiceArray[i].b = 100.0*rank*Nx + 100.0*(double)i; - NiceArray[i].c = 10000.0*rank*Nx + 10000.0*(double)i; + // if not defined by user, we can change the default settings + bpWriterSettings.SetEngine("BP"); // BP is the default engine + bpWriterSettings.AddTransport( + "File", "lucky=yes"); // ISO-POSIX file is the default transport + // Passing parameters to the transport + bpWriterSettings.SetParameters("have_metadata_file", + "yes"); // Passing parameters to the engine + bpWriterSettings.SetParameters("Aggregation", + (nproc + 1) / 2); // number of aggregators } + // Open returns a smart pointer to Engine containing the Derived class + // Writer + // "w" means we overwrite any existing file on disk, but AdvanceStep will + // append steps later. + auto bpWriter = adios.Open("myNumbers.bp", "w", bpWriterSettings); - try + if (bpWriter == nullptr) + throw std::ios_base::failure("ERROR: failed to open ADIOS bpWriter\n"); + + if (rank == 0) { - /* GSE === compound type declaration borrowed heavily from HDF5 style */ - adios::CompType mtype( sizeof(s1_t) ); - mtype.insertMember( "a_name", OFFSET(s1_t, a), PredType::NATIVE_INT); - mtype.insertMember( "c_name", OFFSET(s1_t, c), PredType::NATIVE_DOUBLE); - mtype.insertMember( "b_name", OFFSET(s1_t, b), PredType::NATIVE_FLOAT); - - //Define group and variables with transforms, variables don't have functions, only group can access variables - adios::Variable<unsigned int>& varNX = adios.DefineVariable<unsigned int>( "NX" ); // global single-value across processes - adios::Variable<int>& varNproc = adios.DefineVariable<int>( "nproc", adios::GLOBAL_VALUE ); // same def for global value - adios::Variable<int>& varNparts = adios.DefineVariable<int>( "Nparts", adios::LOCAL_VALUE ); // a single-value different on every process - - // GSE === template necessary or useful here? Extra argument for previously-built compound type information */ - adios::Variable<s1_t>& varNice = adios.DefineVariable<s1_t>( "Nice", {nproc*Nx}, mtype ); // 1D global array - - //add transform to variable in group...not executed (just testing API) - adios::Transform bzip2 = adios::transform::BZIP2( ); - varNice->AddTransform( bzip2, 1 ); - - //Define method for engine creation - // 1. Get method def from config file or define new one - adios::Method& bpWriterSettings = adios.GetMethod( "output" ); - if( bpWriterSettings.undeclared() ) - { - // if not defined by user, we can change the default settings - bpWriterSettings.SetEngine( "BP" ); // BP is the default engine - bpWriterSettings.AddTransport( "File", "lucky=yes" ); // ISO-POSIX file is the default transport - // Passing parameters to the transport - bpWriterSettings.SetParameters("have_metadata_file","yes" ); // Passing parameters to the engine - bpWriterSettings.SetParameters( "Aggregation", (nproc+1)/2 ); // number of aggregators - } - - //Open returns a smart pointer to Engine containing the Derived class Writer - // "w" means we overwrite any existing file on disk, but AdvanceStep will append steps later. - auto bpWriter = adios.Open( "myNumbers.bp", "w", bpWriterSettings ); - - if( bpWriter == nullptr ) - throw std::ios_base::failure( "ERROR: failed to open ADIOS bpWriter\n" ); - - if( rank == 0 ) - { - // Writing a global scalar from only one process - bpWriter->Write<unsigned int>( varNX, Nx ); - } - // Writing a local scalar on every process. Will be shown at reading as a 1D array - bpWriter->Write<int>( varNparts, Nparts ); - - // Writing a global scalar on every process is useless. Information will be thrown away - // and only rank 0's data will be in the output - bpWriter->Write<int>( varNproc, nproc ); - - // Make a 1D selection to describe the local dimensions of the variable we write and - // its offsets in the global spaces - adios::Selection& sel = adios.SelectionBoundingBox( {Nx}, {rank*Nx} ); // local dims and offsets; both as list - varNice.SetSelection( sel ); - - // GSE === Template useful or necessary here? We have to treat this as a void* inside ADIOS... - bpWriter->Write<sl_t>( varNice, NiceArray.data() ); - - // Indicate we are done for this step - // N-to-M Aggregation, disk I/O will be performed during this call, unless - // time aggregation postpones all of that to some later step - bpWriter->Advance( ); - bpWriter->AdvanceAsync( callback_func_to_notify_me ); - - // Called once: indicate that we are done with this output for the run - bpWriter->Close( ); + // Writing a global scalar from only one process + bpWriter->Write<unsigned int>(varNX, Nx); } - catch( std::invalid_argument& e ) + // Writing a local scalar on every process. Will be shown at reading as a 1D + // array + bpWriter->Write<int>(varNparts, Nparts); + + // Writing a global scalar on every process is useless. Information will be + // thrown away + // and only rank 0's data will be in the output + bpWriter->Write<int>(varNproc, nproc); + + // Make a 1D selection to describe the local dimensions of the variable we + // write and + // its offsets in the global spaces + adios::Selection &sel = adios.SelectionBoundingBox( + {Nx}, {rank * Nx}); // local dims and offsets; both as list + varNice.SetSelection(sel); + + // GSE === Template useful or necessary here? We have to treat this as a + // void* inside ADIOS... + bpWriter->Write<sl_t>(varNice, NiceArray.data()); + + // Indicate we are done for this step + // N-to-M Aggregation, disk I/O will be performed during this call, unless + // time aggregation postpones all of that to some later step + bpWriter->Advance(); + bpWriter->AdvanceAsync(callback_func_to_notify_me); + + // Called once: indicate that we are done with this output for the run + bpWriter->Close(); + } + catch (std::invalid_argument &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::ios_base::failure& e ) + } + catch (std::ios_base::failure &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::exception& e ) + } + catch (std::exception &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } + } - MPI_Finalize( ); - - return 0; + MPI_Finalize(); + return 0; } - - - diff --git a/examples/groupless/multistep/reader_allsteps.cpp b/examples/groupless/multistep/reader_allsteps.cpp index 46415c1bb..8d4c42199 100644 --- a/examples/groupless/multistep/reader_allsteps.cpp +++ b/examples/groupless/multistep/reader_allsteps.cpp @@ -5,194 +5,197 @@ * Author: pnorbert */ -#include <vector> #include <iostream> +#include <vector> -#include <mpi.h> #include "ADIOS_CPP.h" +#include <mpi.h> - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - int rank, nproc; - MPI_Init( &argc, &argv ); - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); - MPI_Comm_size( MPI_COMM_WORLD, &nproc); - const bool adiosDebug = true; - - adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); - - //Application variable - std::vector<double> NiceArray; - std::vector<float> RaggedArray; - - int Nparts; - int Nwriters; - int Nsteps; - - try + int rank, nproc; + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); + const bool adiosDebug = true; + + adios::ADIOS adios(MPI_COMM_WORLD, adiosDebug); + + // Application variable + std::vector<double> NiceArray; + std::vector<float> RaggedArray; + + int Nparts; + int Nwriters; + int Nsteps; + + try + { + // Define method for engine creation + // 1. Get method def from config file or define new one + adios::Method &bpReaderSettings = adios.GetMethod("input"); + if (bpReaderSettings.undeclared()) { - //Define method for engine creation - // 1. Get method def from config file or define new one - adios::Method& bpReaderSettings = adios.GetMethod( "input" ); - if( bpReaderSettings.undeclared() ) - { - // if not defined by user, we can change the default settings - bpReaderSettings.SetEngine( "BP" ); // BP is the default engine - // By default we see all steps available in a file, so the next line is not needed - bpReaderSettings.SetParameters ("Stepping", false); - } - - //Create engine smart pointer due to polymorphism, - // Default behavior - // auto bpReader = adios.Open( "myNumbers.bp", "r" ); - // this would just open with a default transport, which is "BP" - auto bpReader = adios.Open( "myNumbers.bp", "r", bpReaderSettings ); - - // All the above is same as default use: - //auto bpReader = adios.Open( "myNumbers.bp", "r"); - - if( bpReader == nullptr ) - throw std::ios_base::failure( "ERROR: failed to open ADIOS bpReader\n" ); - - - /* Note: there is no global number of steps. Each variable has its own number of steps */ - - /* NX */ - /* There is a single value for each step. We can read all into a 1D array with a step selection. - * We can also just conveniently get the first with a simple read statement. - * Steps are not automatically presented as an array dimension and read does not read it as array. - */ - unsigned int Nx; - bpReader->Read<unsigned int>( "NX", &Nx ); // read a Global scalar which has a single value in a step - - std::shared_ptr<adios::Variable<void> > varNx = bpReader.InquiryVariable("Nx"); - std::vector<int> Nxs( varNx->nsteps() ); // number of steps available - // make a StepSelection to select multiple steps. Args: From, #of consecutive steps - std::unique_ptr<adios::StepSelection> stepsNx = adios.StepSelection( 0, varNx->nsteps() ); - // ? How do we make a selection for an arbitrary list of steps ? - varNX.SetStepSelection( stepsNx ); - bpReader->Read<unsigned int>( varNx, Nxs.data() ); - - auto itmax = std::max_element(std::begin(Nxs), std::end(Nxs)); - auto itmin = std::min_element(std::begin(Nxs), std::end(Nxs)); - if (*itmin != *itmax) - { - throw std::ios_base::failure( "ERROR: NX is not the same at all steps!\n" ); - } - - - /* nproc */ - bpReader->Read<int>( "nproc", &Nwriters ); // also a global scalar - - - - /* Nparts */ - // Nparts local scalar is presented as a 1D array of Nwriters elements. - // We can read all steps into a 2D array of nproc * Nwriters - std::shared_ptr<adios::Variable<void> > varNparts = bpReader.InquiryVariable("Nparts"); - std::vector<int> partsV( Nproc*Nwriters ); - varNparts->SetStepSelection( - adios.StepSelection( 0, varNparts->nsteps() ) - ); - bpReader->Read<int>( varNparts, partsV.data() ); // missing spatial selection = whole array at each step - - - - - /* Nice */ - // inquiry about a variable, whose name we know - std::shared_ptr<adios::Variable<void> > varNice = bpReader.InquiryVariable("Nice"); - - if( varNice == nullptr ) - throw std::ios_base::failure( "ERROR: failed to find variable 'myDoubles' in input file\n" ); - - // ? how do we know about the type? std::string varNice->m_Type - unsigned long long int gdim = varMyDoubles->m_GlobalDimensions[0]; // ?member var or member func? - unsigned long long int ldim = gdim / nproc; - unsigned long long int offs = rank * ldim; - if( rank == nproc-1 ) - { - ldim = gdim - (ldim * gdim); - } - - NiceArray.reserve(ldim); - - // Make a 1D selection to describe the local dimensions of the variable we READ and - // its offsets in the global spaces - std::unique_ptr<adios::Selection> bbsel = adios.SelectionBoundingBox( {ldim}, {offs} ); // local dims and offsets; both as list - bpReader->Read<double>( "Nice", bbsel, NiceArray.data() ); // Base class Engine own the Read<T> that will call overloaded Read from Derived - - - - /* Ragged */ - // inquiry about a variable, whose name we know - std::shared_ptr<adios::Variable<void> > varRagged = bpReader.InquiryVariable("Ragged"); - if( varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION) - { - throw std::ios_base::failure( "Unexpected condition: Ragged array's fast dimension " - "is supposed to be VARYING_DIMENSION\n" ); - } - // We have here varRagged->sum_nblocks, nsteps, nblocks[], global - if( rank < varRagged->nblocks[0] ) // same as rank < Nwriters in this example - { - // get per-writer size information - varRagged->InquiryBlocks(); - // now we have the dimensions per block - - unsigned long long int ldim = varRagged->blockinfo[rank].m_Dimensions[0]; - RaggedArray.resize( ldim ); - - std::unique_ptr<adios::Selection> wbsel = adios.SelectionWriteblock( rank ); - bpReader->Read<float>( "Ragged", wbsel, RaggedArray.data() ); - - // We can use bounding box selection as well - std::unique_ptr<adios::Selection> rbbsel = adios.SelectionBoundingBox( {1,ldim}, {rank,0} ); - bpReader->Read<float>( "Ragged", rbbsel, RaggedArray.data() ); - } - - /* Extra help to process Ragged */ - int maxRaggedDim = varRagged->GetMaxGlobalDimensions(1); // contains the largest - std::vector<int> raggedDims = varRagged->GetVaryingGlobalDimensions(1); // contains all individual sizes in that dimension + // if not defined by user, we can change the default settings + bpReaderSettings.SetEngine("BP"); // BP is the default engine + // By default we see all steps available in a file, so the next line is + // not needed + bpReaderSettings.SetParameters("Stepping", false); + } + // Create engine smart pointer due to polymorphism, + // Default behavior + // auto bpReader = adios.Open( "myNumbers.bp", "r" ); + // this would just open with a default transport, which is "BP" + auto bpReader = adios.Open("myNumbers.bp", "r", bpReaderSettings); + + // All the above is same as default use: + // auto bpReader = adios.Open( "myNumbers.bp", "r"); + + if (bpReader == nullptr) + throw std::ios_base::failure("ERROR: failed to open ADIOS bpReader\n"); + + /* Note: there is no global number of steps. Each variable has its own + * number of steps */ + + /* NX */ + /* There is a single value for each step. We can read all into a 1D array + * with a step selection. + * We can also just conveniently get the first with a simple read statement. + * Steps are not automatically presented as an array dimension and read does + * not read it as array. + */ + unsigned int Nx; + bpReader->Read<unsigned int>( + "NX", &Nx); // read a Global scalar which has a single value in a step + + std::shared_ptr<adios::Variable<void>> varNx = + bpReader.InquiryVariable("Nx"); + std::vector<int> Nxs(varNx->nsteps()); // number of steps available + // make a StepSelection to select multiple steps. Args: From, #of + // consecutive steps + std::unique_ptr<adios::StepSelection> stepsNx = + adios.StepSelection(0, varNx->nsteps()); + // ? How do we make a selection for an arbitrary list of steps ? + varNX.SetStepSelection(stepsNx); + bpReader->Read<unsigned int>(varNx, Nxs.data()); + + auto itmax = std::max_element(std::begin(Nxs), std::end(Nxs)); + auto itmin = std::min_element(std::begin(Nxs), std::end(Nxs)); + if (*itmin != *itmax) + { + throw std::ios_base::failure("ERROR: NX is not the same at all steps!\n"); + } + /* nproc */ + bpReader->Read<int>("nproc", &Nwriters); // also a global scalar + + /* Nparts */ + // Nparts local scalar is presented as a 1D array of Nwriters elements. + // We can read all steps into a 2D array of nproc * Nwriters + std::shared_ptr<adios::Variable<void>> varNparts = + bpReader.InquiryVariable("Nparts"); + std::vector<int> partsV(Nproc * Nwriters); + varNparts->SetStepSelection(adios.StepSelection(0, varNparts->nsteps())); + bpReader->Read<int>( + varNparts, + partsV.data()); // missing spatial selection = whole array at each step + + /* Nice */ + // inquiry about a variable, whose name we know + std::shared_ptr<adios::Variable<void>> varNice = + bpReader.InquiryVariable("Nice"); + + if (varNice == nullptr) + throw std::ios_base::failure( + "ERROR: failed to find variable 'myDoubles' in input file\n"); + + // ? how do we know about the type? std::string varNice->m_Type + unsigned long long int gdim = + varMyDoubles->m_GlobalDimensions[0]; // ?member var or member func? + unsigned long long int ldim = gdim / nproc; + unsigned long long int offs = rank * ldim; + if (rank == nproc - 1) + { + ldim = gdim - (ldim * gdim); + } + NiceArray.reserve(ldim); + + // Make a 1D selection to describe the local dimensions of the variable we + // READ and + // its offsets in the global spaces + std::unique_ptr<adios::Selection> bbsel = adios.SelectionBoundingBox( + {ldim}, {offs}); // local dims and offsets; both as list + bpReader->Read<double>("Nice", bbsel, + NiceArray.data()); // Base class Engine own the + // Read<T> that will call + // overloaded Read from Derived + + /* Ragged */ + // inquiry about a variable, whose name we know + std::shared_ptr<adios::Variable<void>> varRagged = + bpReader.InquiryVariable("Ragged"); + if (varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION) + { + throw std::ios_base::failure( + "Unexpected condition: Ragged array's fast dimension " + "is supposed to be VARYING_DIMENSION\n"); + } + // We have here varRagged->sum_nblocks, nsteps, nblocks[], global + if (rank < varRagged->nblocks[0]) // same as rank < Nwriters in this example + { + // get per-writer size information + varRagged->InquiryBlocks(); + // now we have the dimensions per block + unsigned long long int ldim = varRagged->blockinfo[rank].m_Dimensions[0]; + RaggedArray.resize(ldim); - // Close file/stream - bpReader->Close(); + std::unique_ptr<adios::Selection> wbsel = adios.SelectionWriteblock(rank); + bpReader->Read<float>("Ragged", wbsel, RaggedArray.data()); + // We can use bounding box selection as well + std::unique_ptr<adios::Selection> rbbsel = + adios.SelectionBoundingBox({1, ldim}, {rank, 0}); + bpReader->Read<float>("Ragged", rbbsel, RaggedArray.data()); } - catch( std::invalid_argument& e ) + + /* Extra help to process Ragged */ + int maxRaggedDim = + varRagged->GetMaxGlobalDimensions(1); // contains the largest + std::vector<int> raggedDims = varRagged->GetVaryingGlobalDimensions( + 1); // contains all individual sizes in that dimension + + // Close file/stream + bpReader->Close(); + } + catch (std::invalid_argument &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::ios_base::failure& e ) + } + catch (std::ios_base::failure &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::exception& e ) + } + catch (std::exception &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } + } - MPI_Finalize( ); - - return 0; + MPI_Finalize(); + return 0; } - - - diff --git a/examples/groupless/multistep/reader_stepping.cpp b/examples/groupless/multistep/reader_stepping.cpp index 3bf7022e9..f86dc95a7 100644 --- a/examples/groupless/multistep/reader_stepping.cpp +++ b/examples/groupless/multistep/reader_stepping.cpp @@ -5,187 +5,193 @@ * Author: pnorbert */ -#include <vector> #include <iostream> +#include <vector> -#include <mpi.h> #include "ADIOS_CPP.h" +#include <mpi.h> - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - int rank, nproc; - MPI_Init( &argc, &argv ); - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); - MPI_Comm_size( MPI_COMM_WORLD, &nproc); - const bool adiosDebug = true; - - adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); - - //Application variable - std::vector<double> NiceArray; - std::vector<float> RaggedArray; - unsigned int Nx; - int Nparts; - int Nwriters; - int Nsteps; + int rank, nproc; + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); + const bool adiosDebug = true; + + adios::ADIOS adios(MPI_COMM_WORLD, adiosDebug); + + // Application variable + std::vector<double> NiceArray; + std::vector<float> RaggedArray; + unsigned int Nx; + int Nparts; + int Nwriters; + int Nsteps; + + try + { + // Define method for engine creation + // 1. Get method def from config file or define new one + adios::Method &bpReaderSettings = adios.GetMethod("input"); + if (bpReaderSettings.undeclared()) + { + // if not defined by user, we can change the default settings + bpReaderSettings.SetEngine("BP"); // BP is the default engine + bpReaderSettings.SetParameters("Stepping", + true); // see only one step at a time + } + // Create engine smart pointer due to polymorphism, + // Default behavior + // auto bpReader = adios.Open( "myNumbers.bp", "r" ); + // this would just open with a default transport, which is "BP" try { - //Define method for engine creation - // 1. Get method def from config file or define new one - adios::Method& bpReaderSettings = adios.GetMethod( "input" ); - if( bpReaderSettings.undeclared() ) + auto bpReader = adios.Open("myNumbers.bp", "r", bpReaderSettings); + + while (true) + { + /* NX */ + bpReader->Read<unsigned int>( + "NX", + &Nx); // read a Global scalar which has a single value in a step + + /* nproc */ + bpReader->Read<int>("nproc", &Nwriters); // also a global scalar + + /* Nparts */ + // Nparts local scalar is presented as a 1D array of Nwriters elements. + // We can read all as a 1D array + std::vector<int> partsV(Nwriters); + bpReader->Read<int>( + "Nparts", + &partsV); // read with string name, no selection => read whole array + + /* Nice */ + // inquiry about a variable, whose name we know + std::shared_ptr<adios::Variable<void>> varNice = + bpReader.InquiryVariable("Nice"); + + if (varNice == nullptr) + throw std::ios_base::failure( + "ERROR: failed to find variable 'myDoubles' in input file\n"); + + // ? how do we know about the type? std::string varNice->m_Type + unsigned long long int gdim = + varMyDoubles->m_GlobalDimensions[0]; // ?member var or member func? + unsigned long long int ldim = gdim / nproc; + unsigned long long int offs = rank * ldim; + if (rank == nproc - 1) { - // if not defined by user, we can change the default settings - bpReaderSettings.SetEngine( "BP" ); // BP is the default engine - bpReaderSettings.SetParameters ("Stepping", true); // see only one step at a time + ldim = gdim - (ldim * gdim); } - //Create engine smart pointer due to polymorphism, - // Default behavior - // auto bpReader = adios.Open( "myNumbers.bp", "r" ); - // this would just open with a default transport, which is "BP" - try + NiceArray.reserve(ldim); + + // Make a 1D selection to describe the local dimensions of the variable + // we READ and + // its offsets in the global spaces + std::unique_ptr<adios::Selection> bbsel = adios.SelectionBoundingBox( + {ldim}, {offs}); // local dims and offsets; both as list + varNice->SetSelection(bbsel); + bpReader->Read<double>(varNice, NiceArray.data()); + + /* Ragged */ + // inquiry about a variable, whose name we know + std::shared_ptr<adios::Variable<void>> varRagged = + bpReader.InquiryVariable("Ragged"); + if (varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION) { - auto bpReader = adios.Open( "myNumbers.bp", "r", bpReaderSettings ); - - while (true) - { - /* NX */ - bpReader->Read<unsigned int>( "NX", &Nx ); // read a Global scalar which has a single value in a step - - /* nproc */ - bpReader->Read<int>( "nproc", &Nwriters ); // also a global scalar - - - /* Nparts */ - // Nparts local scalar is presented as a 1D array of Nwriters elements. - // We can read all as a 1D array - std::vector<int> partsV( Nwriters ); - bpReader->Read<int>( "Nparts", &partsV ); // read with string name, no selection => read whole array - - - /* Nice */ - // inquiry about a variable, whose name we know - std::shared_ptr<adios::Variable<void> > varNice = bpReader.InquiryVariable("Nice"); - - if( varNice == nullptr ) - throw std::ios_base::failure( "ERROR: failed to find variable 'myDoubles' in input file\n" ); - - // ? how do we know about the type? std::string varNice->m_Type - unsigned long long int gdim = varMyDoubles->m_GlobalDimensions[0]; // ?member var or member func? - unsigned long long int ldim = gdim / nproc; - unsigned long long int offs = rank * ldim; - if( rank == nproc-1 ) - { - ldim = gdim - (ldim * gdim); - } - - NiceArray.reserve(ldim); - - // Make a 1D selection to describe the local dimensions of the variable we READ and - // its offsets in the global spaces - std::unique_ptr<adios::Selection> bbsel = adios.SelectionBoundingBox( {ldim}, {offs} ); // local dims and offsets; both as list - varNice->SetSelection( bbsel ); - bpReader->Read<double>( varNice, NiceArray.data() ); - - - /* Ragged */ - // inquiry about a variable, whose name we know - std::shared_ptr<adios::Variable<void> > varRagged = bpReader.InquiryVariable("Ragged"); - if( varRagged->m_GlobalDimensions[1] != adios::VARYING_DIMENSION) - { - throw std::ios_base::failure( "Unexpected condition: Ragged array's fast dimension " - "is supposed to be VARYING_DIMENSION\n" ); - } - // We have here varRagged->sum_nblocks, nsteps, nblocks[], global - if( rank < varRagged->nblocks[0] ) // same as rank < Nwriters in this example - { - // get per-writer size information - varRagged->InquiryBlocks(); - // now we have the dimensions per block - - unsigned long long int ldim = varRagged->blockinfo[rank].m_Dimensions[0]; - RaggedArray.resize( ldim ); - - std::unique_ptr<adios::Selection> wbsel = adios.SelectionWriteblock( rank ); - varRagged->SetSelection( wbsel ); - bpReader->Read<float>( varRagged, RaggedArray.data() ); - - // We can use bounding box selection as well - std::unique_ptr<adios::Selection> rbbsel = adios.SelectionBoundingBox( {1,ldim}, {rank,0} ); - varRagged->SetSelection( rbbsel ); - bpReader->Read<float>( varRagged, RaggedArray.data() ); - } - - /* Extra help to process Ragged */ - int maxRaggedDim = varRagged->GetMaxGlobalDimensions(1); // contains the largest - std::vector<int> raggedDims = varRagged->GetVaryingGlobalDimensions(1); // contains all individual sizes in that dimension - - - - // promise to not read more from this step - bpReader->Release(); + throw std::ios_base::failure( + "Unexpected condition: Ragged array's fast dimension " + "is supposed to be VARYING_DIMENSION\n"); + } + // We have here varRagged->sum_nblocks, nsteps, nblocks[], global + if (rank < + varRagged->nblocks[0]) // same as rank < Nwriters in this example + { + // get per-writer size information + varRagged->InquiryBlocks(); + // now we have the dimensions per block + + unsigned long long int ldim = + varRagged->blockinfo[rank].m_Dimensions[0]; + RaggedArray.resize(ldim); + + std::unique_ptr<adios::Selection> wbsel = + adios.SelectionWriteblock(rank); + varRagged->SetSelection(wbsel); + bpReader->Read<float>(varRagged, RaggedArray.data()); + + // We can use bounding box selection as well + std::unique_ptr<adios::Selection> rbbsel = + adios.SelectionBoundingBox({1, ldim}, {rank, 0}); + varRagged->SetSelection(rbbsel); + bpReader->Read<float>(varRagged, RaggedArray.data()); + } - // want to move on to the next available step - //bpReader->Advance(adios::NextStep); - //bpReader->Advance(adios::LatestStep); - bpReader->Advance(); // default is adios::NextStep + /* Extra help to process Ragged */ + int maxRaggedDim = + varRagged->GetMaxGlobalDimensions(1); // contains the largest + std::vector<int> raggedDims = varRagged->GetVaryingGlobalDimensions( + 1); // contains all individual sizes in that dimension - } + // promise to not read more from this step + bpReader->Release(); - // Close file/stream - bpReader->Close(); + // want to move on to the next available step + // bpReader->Advance(adios::NextStep); + // bpReader->Advance(adios::LatestStep); + bpReader->Advance(); // default is adios::NextStep + } - } - catch( adios::end_of_stream& e ) - { - if( rank == 0 ) - { - std::cout << "Reached end of stream, end processing loop.\n"; - } - // Close file/stream - bpReader->Close(); - } - catch( adios::file_not_found& e ) - { - if( rank == 0 ) - { - std::cout << "File/stream does not exist, quit.\n"; - } - } + // Close file/stream + bpReader->Close(); } - catch( std::invalid_argument& e ) + catch (adios::end_of_stream &e) { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + if (rank == 0) + { + std::cout << "Reached end of stream, end processing loop.\n"; + } + // Close file/stream + bpReader->Close(); } - catch( std::ios_base::failure& e ) + catch (adios::file_not_found &e) { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + if (rank == 0) + { + std::cout << "File/stream does not exist, quit.\n"; + } } - catch( std::exception& e ) + } + catch (std::invalid_argument &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } + } + catch (std::ios_base::failure &e) + { + if (rank == 0) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } + catch (std::exception &e) + { + if (rank == 0) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + } - MPI_Finalize( ); - - return 0; + MPI_Finalize(); + return 0; } - - - diff --git a/examples/groupless/multistep/writer_multistep.cpp b/examples/groupless/multistep/writer_multistep.cpp index 89eba61d4..e9b167b43 100644 --- a/examples/groupless/multistep/writer_multistep.cpp +++ b/examples/groupless/multistep/writer_multistep.cpp @@ -5,146 +5,165 @@ * Author: pnorbert */ -#include <vector> #include <iostream> +#include <vector> -#include <mpi.h> #include "ADIOS_CPP.h" +#include <mpi.h> -namespace adios { - typedef enum { - VARYING_DIMENSION = -1, - LOCAL_VALUE = 0, - GLOBAL_VALUE = 1 - }; +namespace adios +{ +typedef enum { VARYING_DIMENSION = -1, LOCAL_VALUE = 0, GLOBAL_VALUE = 1 }; } -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - int rank, nproc; - MPI_Init( &argc, &argv ); - MPI_Comm_rank( MPI_COMM_WORLD, &rank); - MPI_Comm_size( MPI_COMM_WORLD, &nproc); - const bool adiosDebug = true; - const int NSTEPS = 5; - - adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); - - //Application variable - const unsigned int Nx = 10; - int Nparts; // random size per process, 5..10 each - - std::vector<double> NiceArray( Nx ); - for( int i=0; i < Nx; i++ ) + int rank, nproc; + MPI_Init(&argc, &argv); + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); + const bool adiosDebug = true; + const int NSTEPS = 5; + + adios::ADIOS adios(MPI_COMM_WORLD, adiosDebug); + + // Application variable + const unsigned int Nx = 10; + int Nparts; // random size per process, 5..10 each + + std::vector<double> NiceArray(Nx); + for (int i = 0; i < Nx; i++) + { + NiceArray[i] = rank * Nx + (double)i; + } + + std::vector<float> RaggedArray; + + try + { + // Define group and variables with transforms, variables don't have + // functions, only group can access variables + adios::Variable<unsigned int> &varNX = adios.DefineVariable<unsigned int>( + "NX"); // global single-value across processes + adios::Variable<int> &varNproc = adios.DefineVariable<int>( + "nproc", adios::GLOBAL_VALUE); // same def for global value + adios::Variable<int> &varNparts = adios.DefineVariable<int>( + "Nparts", + adios::LOCAL_VALUE); // a single-value different on every process + adios::Variable<double> &varNice = + adios.DefineVariable<double>("Nice", {nproc * Nx}); // 1D global array + adios::Variable<float> &varRagged = adios.DefineVariable<float>( + "Ragged", {nproc, adios::VARYING_DIMENSION}); // ragged array + + // add transform to variable in group...not executed (just testing API) + adios::Transform bzip2 = adios::transform::BZIP2(); + varNice->AddTransform(bzip2, 1); + + // Define method for engine creation + // 1. Get method def from config file or define new one + adios::Method &bpWriterSettings = adios.GetMethod("output"); + if (bpWriterSettings.undeclared()) { - NiceArray[i] = rank*Nx + (double)i; + // if not defined by user, we can change the default settings + bpWriterSettings.SetEngine("BP"); // BP is the default engine + bpWriterSettings.AddTransport( + "File", "lucky=yes"); // ISO-POSIX file is the default transport + // Passing parameters to the transport + bpWriterSettings.SetParameters("have_metadata_file", + "yes"); // Passing parameters to the engine + bpWriterSettings.SetParameters("Aggregation", + (nproc + 1) / 2); // number of aggregators } - std::vector<float> RaggedArray; + // Open returns a smart pointer to Engine containing the Derived class + // Writer + // "w" means we overwrite any existing file on disk, but AdvanceStep will + // append steps later. + auto bpWriter = adios.Open("myNumbers.bp", "w", bpWriterSettings); + + if (bpWriter == nullptr) + throw std::ios_base::failure("ERROR: failed to open ADIOS bpWriter\n"); - try + for (int step; step < NSTEPS; step++) { - //Define group and variables with transforms, variables don't have functions, only group can access variables - adios::Variable<unsigned int>& varNX = adios.DefineVariable<unsigned int>( "NX" ); // global single-value across processes - adios::Variable<int>& varNproc = adios.DefineVariable<int>( "nproc", adios::GLOBAL_VALUE ); // same def for global value - adios::Variable<int>& varNparts = adios.DefineVariable<int>( "Nparts", adios::LOCAL_VALUE ); // a single-value different on every process - adios::Variable<double>& varNice = adios.DefineVariable<double>( "Nice", {nproc*Nx} ); // 1D global array - adios::Variable<float>& varRagged = adios.DefineVariable<float>( "Ragged", {nproc,adios::VARYING_DIMENSION} ); // ragged array - - //add transform to variable in group...not executed (just testing API) - adios::Transform bzip2 = adios::transform::BZIP2( ); - varNice->AddTransform( bzip2, 1 ); - - //Define method for engine creation - // 1. Get method def from config file or define new one - adios::Method& bpWriterSettings = adios.GetMethod( "output" ); - if( bpWriterSettings.undeclared() ) - { - // if not defined by user, we can change the default settings - bpWriterSettings.SetEngine( "BP" ); // BP is the default engine - bpWriterSettings.AddTransport( "File", "lucky=yes" ); // ISO-POSIX file is the default transport - // Passing parameters to the transport - bpWriterSettings.SetParameters("have_metadata_file","yes" ); // Passing parameters to the engine - bpWriterSettings.SetParameters( "Aggregation", (nproc+1)/2 ); // number of aggregators - } - - //Open returns a smart pointer to Engine containing the Derived class Writer - // "w" means we overwrite any existing file on disk, but AdvanceStep will append steps later. - auto bpWriter = adios.Open( "myNumbers.bp", "w", bpWriterSettings ); - - if( bpWriter == nullptr ) - throw std::ios_base::failure( "ERROR: failed to open ADIOS bpWriter\n" ); - - for ( int step; step < NSTEPS; step++ ) - { - int Nparts = rand()%6 + 5; // random size per process, 5..10 each - RaggedArray.reserve(Nparts); - for( int i=0; i < Nparts; i++ ) - { - RaggedArray[i] = rank*Nx + (float)i; - } - - if( rank == 0 ) - { - // Writing a global scalar from only one process - bpWriter->Write<unsigned int>( varNX, &Nx ); - } - // Writing a local scalar on every process. Will be shown at reading as a 1D array - bpWriter->Write<int>( varNparts, &Nparts ); - - // Writing a global scalar on every process is useless. Information will be thrown away - // and only rank 0's data will be in the output - bpWriter->Write<int>( varNproc, &nproc ); - - // Make a 1D selection to describe the local dimensions of the variable we write and - // its offsets in the global spaces - adios::Selection& sel = adios.SelectionBoundingBox( {Nx}, {rank*Nx} ); // local dims and offsets; both as list - NiceArray.SetSelection( sel ); - bpWriter->Write<double>( varNice, NiceArray.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived - - adios::Selection& lsel = adios.SelectionBoundingBox( {1,Nparts}, {rank,0} ); - RaggedArray.SetSelection( sel ); - bpWriter->Write<float>( varRagged, RaggedArray.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived - - // Indicate we are done for this step - // N-to-M Aggregation, disk I/O will be performed during this call, unless - // time aggregation postpones all of that to some later step - bpWriter->Advance( ); - } - - // Called once: indicate that we are done with this output for the run - bpWriter->Close( ); + int Nparts = rand() % 6 + 5; // random size per process, 5..10 each + RaggedArray.reserve(Nparts); + for (int i = 0; i < Nparts; i++) + { + RaggedArray[i] = rank * Nx + (float)i; + } + + if (rank == 0) + { + // Writing a global scalar from only one process + bpWriter->Write<unsigned int>(varNX, &Nx); + } + // Writing a local scalar on every process. Will be shown at reading as a + // 1D array + bpWriter->Write<int>(varNparts, &Nparts); + + // Writing a global scalar on every process is useless. Information will + // be thrown away + // and only rank 0's data will be in the output + bpWriter->Write<int>(varNproc, &nproc); + + // Make a 1D selection to describe the local dimensions of the variable we + // write and + // its offsets in the global spaces + adios::Selection &sel = adios.SelectionBoundingBox( + {Nx}, {rank * Nx}); // local dims and offsets; both as list + NiceArray.SetSelection(sel); + bpWriter->Write<double>(varNice, NiceArray.data()); // Base class Engine + // own the Write<T> + // that will call + // overloaded Write + // from Derived + + adios::Selection &lsel = + adios.SelectionBoundingBox({1, Nparts}, {rank, 0}); + RaggedArray.SetSelection(sel); + bpWriter->Write<float>(varRagged, RaggedArray.data()); // Base class + // Engine own the + // Write<T> that + // will call + // overloaded Write + // from Derived + + // Indicate we are done for this step + // N-to-M Aggregation, disk I/O will be performed during this call, unless + // time aggregation postpones all of that to some later step + bpWriter->Advance(); } - catch( std::invalid_argument& e ) + + // Called once: indicate that we are done with this output for the run + bpWriter->Close(); + } + catch (std::invalid_argument &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::ios_base::failure& e ) + } + catch (std::ios_base::failure &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::exception& e ) + } + catch (std::exception &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } + } - MPI_Finalize( ); - - return 0; + MPI_Finalize(); + return 0; } - - - diff --git a/examples/heatTransfer/HeatTransfer.cpp b/examples/heatTransfer/HeatTransfer.cpp index fd6d84f6c..d37f21b31 100644 --- a/examples/heatTransfer/HeatTransfer.cpp +++ b/examples/heatTransfer/HeatTransfer.cpp @@ -9,217 +9,223 @@ */ #include <mpi.h> -#include <stdexcept> -#include <memory> -#include <iostream> #include <iomanip> -#include <string> +#include <iostream> #include <math.h> - +#include <memory> +#include <stdexcept> +#include <string> #include "HeatTransfer.h" - -HeatTransfer::HeatTransfer( const Settings& settings ) -: m_s{settings} +HeatTransfer::HeatTransfer(const Settings &settings) : m_s{settings} { - m_T1 = new double*[ m_s.ndx+2 ]; - m_T1[0] = new double[ (m_s.ndx+2) * (m_s.ndy+2) ]; - m_T2 = new double*[ m_s.ndx+2 ]; - m_T2[0] = new double[ (m_s.ndx+2) * (m_s.ndy+2) ]; - for (unsigned int i = 1; i < m_s.ndx+2; i++) - { - m_T1[i] = m_T1[i-1] + m_s.ndy+2; - m_T2[i] = m_T2[i-1] + m_s.ndy+2; - } - m_TCurrent = m_T1; - m_TNext = m_T2; + m_T1 = new double *[m_s.ndx + 2]; + m_T1[0] = new double[(m_s.ndx + 2) * (m_s.ndy + 2)]; + m_T2 = new double *[m_s.ndx + 2]; + m_T2[0] = new double[(m_s.ndx + 2) * (m_s.ndy + 2)]; + for (unsigned int i = 1; i < m_s.ndx + 2; i++) + { + m_T1[i] = m_T1[i - 1] + m_s.ndy + 2; + m_T2[i] = m_T2[i - 1] + m_s.ndy + 2; + } + m_TCurrent = m_T1; + m_TNext = m_T2; } HeatTransfer::~HeatTransfer() { - delete[] m_T1[0]; - delete[] m_T1; - delete[] m_T2[0]; - delete[] m_T2; + delete[] m_T1[0]; + delete[] m_T1; + delete[] m_T2[0]; + delete[] m_T2; } - void HeatTransfer::init(bool init_with_rank) { - if (init_with_rank) - { - for (unsigned int i = 0; i < m_s.ndx+2; i++) - for (unsigned int j = 0; j < m_s.ndy+2; j++) - m_T1[i][j] = m_s.rank; - } - else - { - const double hx = 2.0 * 4.0*atan(1.0)/m_s.ndx; - const double hy = 2.0 * 4.0*atan(1.0)/m_s.ndy; - - double x, y; - for (unsigned int i = 0; i < m_s.ndx+2; i++) - { - x = 0.0 + hx*(i-1); - for (unsigned int j = 0; j < m_s.ndy+2; j++) - { - y = 0.0 + hy*(j-1); - m_T1[i][j] = cos(8*x) + cos(6*x) - cos(4*x) + cos(2*x) - cos(x) + - sin(8*y) - sin(6*y) + sin(4*y) - sin(2*y) + sin(y); - } - } - } - m_TCurrent = m_T1; - m_TNext = m_T2; + if (init_with_rank) + { + for (unsigned int i = 0; i < m_s.ndx + 2; i++) + for (unsigned int j = 0; j < m_s.ndy + 2; j++) + m_T1[i][j] = m_s.rank; + } + else + { + const double hx = 2.0 * 4.0 * atan(1.0) / m_s.ndx; + const double hy = 2.0 * 4.0 * atan(1.0) / m_s.ndy; + + double x, y; + for (unsigned int i = 0; i < m_s.ndx + 2; i++) + { + x = 0.0 + hx * (i - 1); + for (unsigned int j = 0; j < m_s.ndy + 2; j++) + { + y = 0.0 + hy * (j - 1); + m_T1[i][j] = cos(8 * x) + cos(6 * x) - cos(4 * x) + cos(2 * x) - + cos(x) + sin(8 * y) - sin(6 * y) + sin(4 * y) - + sin(2 * y) + sin(y); + } + } + } + m_TCurrent = m_T1; + m_TNext = m_T2; } void HeatTransfer::printT(std::string message, MPI_Comm comm) const { - int rank, size; - int tag = 1; - int token; - MPI_Status status; - MPI_Comm_rank( comm, &rank ); - MPI_Comm_size( comm, &size ); - if( rank > 0) - { - MPI_Recv(&token, 1, MPI_INT, rank-1, tag, comm, &status); - } - - std::cout << "Rank " << rank << " " << message << std::endl; - for (unsigned int i = 0; i < m_s.ndx+2; i++) - { - std::cout << " T[" << i << "][] = "; - for (unsigned int j = 0; j < m_s.ndy+2; j++) - { - std::cout << std::setw(6) << m_TCurrent[i][j]; - } - std::cout << std::endl; - } - std::cout << std::flush << std::endl; - - if( rank < size-1) - { - MPI_Send(&token, 1, MPI_INT, rank+1, tag, comm); - } + int rank, size; + int tag = 1; + int token; + MPI_Status status; + MPI_Comm_rank(comm, &rank); + MPI_Comm_size(comm, &size); + if (rank > 0) + { + MPI_Recv(&token, 1, MPI_INT, rank - 1, tag, comm, &status); + } + + std::cout << "Rank " << rank << " " << message << std::endl; + for (unsigned int i = 0; i < m_s.ndx + 2; i++) + { + std::cout << " T[" << i << "][] = "; + for (unsigned int j = 0; j < m_s.ndy + 2; j++) + { + std::cout << std::setw(6) << m_TCurrent[i][j]; + } + std::cout << std::endl; + } + std::cout << std::flush << std::endl; + + if (rank < size - 1) + { + MPI_Send(&token, 1, MPI_INT, rank + 1, tag, comm); + } } - void HeatTransfer::switchCurrentNext() { - double **tmp = m_TCurrent; - m_TCurrent = m_TNext; - m_TNext = tmp; + double **tmp = m_TCurrent; + m_TCurrent = m_TNext; + m_TNext = tmp; } void HeatTransfer::iterate() { - for( unsigned int i = 1; i <= m_s.ndx; ++i) + for (unsigned int i = 1; i <= m_s.ndx; ++i) + { + for (unsigned int j = 1; j <= m_s.ndy; ++j) { - for( unsigned int j = 1; j <= m_s.ndy; ++j) - { - m_TNext[i][j] = - omega/4*(m_TCurrent[i-1][j] + - m_TCurrent[i+1][j] + - m_TCurrent[i][j-1] + - m_TCurrent[i][j+1]) + - (1.0-omega)*m_TCurrent[i][j]; - } + m_TNext[i][j] = + omega / 4 * (m_TCurrent[i - 1][j] + m_TCurrent[i + 1][j] + + m_TCurrent[i][j - 1] + m_TCurrent[i][j + 1]) + + (1.0 - omega) * m_TCurrent[i][j]; } - switchCurrentNext(); + } + switchCurrentNext(); } void HeatTransfer::heatEdges() { - // Heat the whole global edges - if( m_s.posx==0 ) - for( unsigned int j = 0; j < m_s.ndy+2; ++j) - m_TCurrent[0][j]= edgetemp; - - if( m_s.posx==m_s.npx-1 ) - for( unsigned int j = 0; j < m_s.ndy+2; ++j) - m_TCurrent[m_s.ndx+1][j]= edgetemp; - - if (m_s.posy==0) - for( unsigned int i = 0; i < m_s.ndx+2; ++i) - m_TCurrent[i][0]= edgetemp; - - if (m_s.posy==m_s.npy-1) - for( unsigned int i = 0; i < m_s.ndx+2; ++i) - m_TCurrent[i][m_s.ndy+1]= edgetemp; + // Heat the whole global edges + if (m_s.posx == 0) + for (unsigned int j = 0; j < m_s.ndy + 2; ++j) + m_TCurrent[0][j] = edgetemp; + + if (m_s.posx == m_s.npx - 1) + for (unsigned int j = 0; j < m_s.ndy + 2; ++j) + m_TCurrent[m_s.ndx + 1][j] = edgetemp; + + if (m_s.posy == 0) + for (unsigned int i = 0; i < m_s.ndx + 2; ++i) + m_TCurrent[i][0] = edgetemp; + + if (m_s.posy == m_s.npy - 1) + for (unsigned int i = 0; i < m_s.ndx + 2; ++i) + m_TCurrent[i][m_s.ndy + 1] = edgetemp; } -void HeatTransfer::exchange( MPI_Comm comm ) +void HeatTransfer::exchange(MPI_Comm comm) { - // Exchange ghost cells, in the order left-right-up-down - - double * send_x = new double[m_s.ndx+2]; - double * recv_x = new double[m_s.ndx+2]; - - // send to left + receive from right - int tag = 1; - MPI_Status status; - if( m_s.rank_left >= 0 ) - { - std::cout << "Rank " << m_s.rank << " send left to rank " << m_s.rank_left << std::endl; - for( unsigned int i = 0; i < m_s.ndx+2; ++i) - send_x[i] = m_TCurrent[i][1]; - MPI_Send(send_x, m_s.ndx+2, MPI_REAL8, m_s.rank_left, tag, comm); - } - if( m_s.rank_right >= 0 ) - { - std::cout << "Rank " << m_s.rank << " receive from right from rank " << m_s.rank_right << std::endl; - MPI_Recv(recv_x, m_s.ndx+2, MPI_REAL8, m_s.rank_right, tag, comm, &status); - for( unsigned int i = 0; i < m_s.ndx+2; ++i) - m_TCurrent[i][m_s.ndy+1] = recv_x[i]; - } - - // send to right + receive from left - tag = 2; - if( m_s.rank_right >= 0 ) - { - std::cout << "Rank " << m_s.rank << " send right to rank " << m_s.rank_right << std::endl; - for( unsigned int i = 0; i < m_s.ndx+2; ++i) - send_x[i] = m_TCurrent[i][m_s.ndy]; - MPI_Send(send_x, m_s.ndx+2, MPI_REAL8, m_s.rank_right, tag, comm); - } - if( m_s.rank_left >= 0 ) - { - std::cout << "Rank " << m_s.rank << " receive from left from rank " << m_s.rank_left << std::endl; - MPI_Recv(recv_x, m_s.ndx+2, MPI_REAL8, m_s.rank_left, tag, comm, &status); - for( unsigned int i = 0; i < m_s.ndx+2; ++i) - m_TCurrent[i][0] = recv_x[i]; - } - - // send down + receive from above - tag = 3; - if( m_s.rank_down >= 0 ) - { - std::cout << "Rank " << m_s.rank << " send down to rank " << m_s.rank_down << std::endl; - MPI_Send(m_TCurrent[m_s.ndx], m_s.ndy+2, MPI_REAL8, m_s.rank_down, tag, comm); - } - if ( m_s.rank_up >= 0 ) - { - std::cout << "Rank " << m_s.rank << " receive from above from rank " << m_s.rank_up << std::endl; - MPI_Recv(m_TCurrent[0], m_s.ndy+2, MPI_REAL8, m_s.rank_up, tag, comm, &status); - } - - // send up + receive from below - tag = 4; - if( m_s.rank_up >= 0 ) - { - std::cout << "Rank " << m_s.rank << " send up to rank " << m_s.rank_up << std::endl; - MPI_Send(m_TCurrent[1], m_s.ndy+2, MPI_REAL8, m_s.rank_up, tag, comm); - } - if ( m_s.rank_down >= 0 ) - { - std::cout << "Rank " << m_s.rank << " receive from below from rank " << m_s.rank_down << std::endl; - MPI_Recv(m_TCurrent[m_s.ndx+1], m_s.ndy+2, MPI_REAL8, m_s.rank_down, tag, comm, &status); - } - - delete[] send_x; - delete[] recv_x; + // Exchange ghost cells, in the order left-right-up-down + + double *send_x = new double[m_s.ndx + 2]; + double *recv_x = new double[m_s.ndx + 2]; + + // send to left + receive from right + int tag = 1; + MPI_Status status; + if (m_s.rank_left >= 0) + { + std::cout << "Rank " << m_s.rank << " send left to rank " << m_s.rank_left + << std::endl; + for (unsigned int i = 0; i < m_s.ndx + 2; ++i) + send_x[i] = m_TCurrent[i][1]; + MPI_Send(send_x, m_s.ndx + 2, MPI_REAL8, m_s.rank_left, tag, comm); + } + if (m_s.rank_right >= 0) + { + std::cout << "Rank " << m_s.rank << " receive from right from rank " + << m_s.rank_right << std::endl; + MPI_Recv(recv_x, m_s.ndx + 2, MPI_REAL8, m_s.rank_right, tag, comm, + &status); + for (unsigned int i = 0; i < m_s.ndx + 2; ++i) + m_TCurrent[i][m_s.ndy + 1] = recv_x[i]; + } + + // send to right + receive from left + tag = 2; + if (m_s.rank_right >= 0) + { + std::cout << "Rank " << m_s.rank << " send right to rank " << m_s.rank_right + << std::endl; + for (unsigned int i = 0; i < m_s.ndx + 2; ++i) + send_x[i] = m_TCurrent[i][m_s.ndy]; + MPI_Send(send_x, m_s.ndx + 2, MPI_REAL8, m_s.rank_right, tag, comm); + } + if (m_s.rank_left >= 0) + { + std::cout << "Rank " << m_s.rank << " receive from left from rank " + << m_s.rank_left << std::endl; + MPI_Recv(recv_x, m_s.ndx + 2, MPI_REAL8, m_s.rank_left, tag, comm, &status); + for (unsigned int i = 0; i < m_s.ndx + 2; ++i) + m_TCurrent[i][0] = recv_x[i]; + } + + // send down + receive from above + tag = 3; + if (m_s.rank_down >= 0) + { + std::cout << "Rank " << m_s.rank << " send down to rank " << m_s.rank_down + << std::endl; + MPI_Send(m_TCurrent[m_s.ndx], m_s.ndy + 2, MPI_REAL8, m_s.rank_down, tag, + comm); + } + if (m_s.rank_up >= 0) + { + std::cout << "Rank " << m_s.rank << " receive from above from rank " + << m_s.rank_up << std::endl; + MPI_Recv(m_TCurrent[0], m_s.ndy + 2, MPI_REAL8, m_s.rank_up, tag, comm, + &status); + } + + // send up + receive from below + tag = 4; + if (m_s.rank_up >= 0) + { + std::cout << "Rank " << m_s.rank << " send up to rank " << m_s.rank_up + << std::endl; + MPI_Send(m_TCurrent[1], m_s.ndy + 2, MPI_REAL8, m_s.rank_up, tag, comm); + } + if (m_s.rank_down >= 0) + { + std::cout << "Rank " << m_s.rank << " receive from below from rank " + << m_s.rank_down << std::endl; + MPI_Recv(m_TCurrent[m_s.ndx + 1], m_s.ndy + 2, MPI_REAL8, m_s.rank_down, + tag, comm, &status); + } + + delete[] send_x; + delete[] recv_x; } #include <cstring> @@ -229,10 +235,11 @@ void HeatTransfer::exchange( MPI_Comm comm ) */ std::vector<double> HeatTransfer::data_noghost() const { - std::vector<double>d( m_s.ndx * m_s.ndy ); - for( unsigned int i = 1; i <= m_s.ndx; ++i ) - { - std::memcpy( &d[(i-1)*m_s.ndy], m_TCurrent[i]+1, m_s.ndy*sizeof(double)); - } - return d; + std::vector<double> d(m_s.ndx * m_s.ndy); + for (unsigned int i = 1; i <= m_s.ndx; ++i) + { + std::memcpy(&d[(i - 1) * m_s.ndy], m_TCurrent[i] + 1, + m_s.ndy * sizeof(double)); + } + return d; } diff --git a/examples/heatTransfer/HeatTransfer.h b/examples/heatTransfer/HeatTransfer.h index 09589e8ae..74ec07d3a 100644 --- a/examples/heatTransfer/HeatTransfer.h +++ b/examples/heatTransfer/HeatTransfer.h @@ -16,31 +16,34 @@ class HeatTransfer { public: - HeatTransfer( const Settings& settings ); // Create two 2D arrays with ghost cells to compute - ~HeatTransfer(); - void init(bool init_with_rank); // set up array values with either rank or real demo values - void iterate(); // one local calculation step - void heatEdges(); // reset the heat values at the global edge - void exchange( MPI_Comm comm ); // send updates to neighbors - - // return a single value at index i,j. 0 <= i <= ndx+2, 0 <= j <= ndy+2 - double T( int i, int j) const {return m_TCurrent[i][j];}; - // return (1D) pointer to current T data, ndx+2 * ndy+2 elements - double *data() const {return m_TCurrent[0];}; - // return (1D) pointer to current T data without ghost cells, ndx*ndy elements - std::vector<double> data_noghost() const; - - void printT(std::string message, MPI_Comm comm) const; // debug: print local TCurrent on stdout + HeatTransfer(const Settings &settings); // Create two 2D arrays with ghost + // cells to compute + ~HeatTransfer(); + void init(bool init_with_rank); // set up array values with either rank or + // real demo values + void iterate(); // one local calculation step + void heatEdges(); // reset the heat values at the global edge + void exchange(MPI_Comm comm); // send updates to neighbors + + // return a single value at index i,j. 0 <= i <= ndx+2, 0 <= j <= ndy+2 + double T(int i, int j) const { return m_TCurrent[i][j]; }; + // return (1D) pointer to current T data, ndx+2 * ndy+2 elements + double *data() const { return m_TCurrent[0]; }; + // return (1D) pointer to current T data without ghost cells, ndx*ndy elements + std::vector<double> data_noghost() const; + + void printT(std::string message, + MPI_Comm comm) const; // debug: print local TCurrent on stdout private: - const double edgetemp = 3.0; // temperature at the edges of the global plate - const double omega = 0.8; // weight for current temp is (1-omega) in iteration - double **m_T1; // 2D array (ndx+2) * (ndy+2) size, including ghost cells - double **m_T2; // another 2D array - double **m_TCurrent; // pointer to T1 or T2 - double **m_TNext; // pointer to T2 or T1 - const Settings& m_s; - void switchCurrentNext(); // switch the current array with the next array + const double edgetemp = 3.0; // temperature at the edges of the global plate + const double omega = 0.8; // weight for current temp is (1-omega) in iteration + double **m_T1; // 2D array (ndx+2) * (ndy+2) size, including ghost cells + double **m_T2; // another 2D array + double **m_TCurrent; // pointer to T1 or T2 + double **m_TNext; // pointer to T2 or T1 + const Settings &m_s; + void switchCurrentNext(); // switch the current array with the next array }; #endif /* HEATTRANSFER_H_ */ diff --git a/examples/heatTransfer/IO.h b/examples/heatTransfer/IO.h index 789a4482b..5acec1f6a 100644 --- a/examples/heatTransfer/IO.h +++ b/examples/heatTransfer/IO.h @@ -8,20 +8,21 @@ #ifndef IO_H_ #define IO_H_ -#include <mpi.h> -#include "Settings.h" #include "HeatTransfer.h" +#include "Settings.h" +#include <mpi.h> class IO { public: - IO( const Settings& s, MPI_Comm comm ); - ~IO(); - void write( int step, const HeatTransfer& ht, const Settings& s, MPI_Comm comm ); - + IO(const Settings &s, MPI_Comm comm); + ~IO(); + void write(int step, const HeatTransfer &ht, const Settings &s, + MPI_Comm comm); + private: - std::string m_outputfilename; + std::string m_outputfilename; }; #endif /* IO_H_ */ diff --git a/examples/heatTransfer/IO_adios1.cpp b/examples/heatTransfer/IO_adios1.cpp index 8d3a4a9e4..ebf15ea9e 100644 --- a/examples/heatTransfer/IO_adios1.cpp +++ b/examples/heatTransfer/IO_adios1.cpp @@ -5,9 +5,9 @@ * Author: Norbert Podhorszki */ -#include <string> -#include <iostream> #include <iomanip> +#include <iostream> +#include <string> #include "IO.h" #include "adios.h" @@ -15,59 +15,58 @@ static int64_t group; static int rank_saved; -IO::IO( const Settings& s, MPI_Comm comm ) +IO::IO(const Settings &s, MPI_Comm comm) { - rank_saved = s.rank; - m_outputfilename = s.outputfile + ".bp"; - adios_init_noxml( comm ); - adios_declare_group( &group, "heat", "", adios_stat_default ); - adios_select_method( group, "MPI", "", "" ); + rank_saved = s.rank; + m_outputfilename = s.outputfile + ".bp"; + adios_init_noxml(comm); + adios_declare_group(&group, "heat", "", adios_stat_default); + adios_select_method(group, "MPI", "", ""); - adios_define_var( group, "gndx", "", adios_integer, "", "", ""); - adios_define_var( group, "gndy", "", adios_integer, "", "", ""); + adios_define_var(group, "gndx", "", adios_integer, "", "", ""); + adios_define_var(group, "gndy", "", adios_integer, "", "", ""); - std::string ldims( std::to_string( s.ndx ) + "," + std::to_string( s.ndy )); - std::string gdims( std::to_string( s.gndx ) + "," + std::to_string( s.gndy )); - std::string offs( std::to_string( s.offsx ) + "," + std::to_string( s.offsy )); - uint64_t T_id; - T_id = adios_define_var( group, "T", "", adios_double, - ldims.c_str(), gdims.c_str(), offs.c_str() ); + std::string ldims(std::to_string(s.ndx) + "," + std::to_string(s.ndy)); + std::string gdims(std::to_string(s.gndx) + "," + std::to_string(s.gndy)); + std::string offs(std::to_string(s.offsx) + "," + std::to_string(s.offsy)); + uint64_t T_id; + T_id = adios_define_var(group, "T", "", adios_double, ldims.c_str(), + gdims.c_str(), offs.c_str()); - adios_set_transform( T_id, "none"); - //adios_set_transform( T_id, "zfp:accuracy=0.001"); + adios_set_transform(T_id, "none"); + // adios_set_transform( T_id, "zfp:accuracy=0.001"); } -IO::~IO() -{ - adios_finalize(rank_saved); -} +IO::~IO() { adios_finalize(rank_saved); } -void IO::write( int step, const HeatTransfer& ht, const Settings& s, MPI_Comm comm ) +void IO::write(int step, const HeatTransfer &ht, const Settings &s, + MPI_Comm comm) { - char mode[2] = "w"; - if (step > 0) - { - mode[0] = 'a'; - } + char mode[2] = "w"; + if (step > 0) + { + mode[0] = 'a'; + } - // for time measurements, let's synchronize the processes - MPI_Barrier( comm ); - double time_start = MPI_Wtime(); + // for time measurements, let's synchronize the processes + MPI_Barrier(comm); + double time_start = MPI_Wtime(); - int64_t f; - adios_open( &f, "heat", m_outputfilename.c_str(), mode, comm); - adios_write( f, "gndx", &s.gndx); - adios_write( f, "gndy", &s.gndy); - adios_write( f, "T", ht.data_noghost().data() ); - adios_close( f ); + int64_t f; + adios_open(&f, "heat", m_outputfilename.c_str(), mode, comm); + adios_write(f, "gndx", &s.gndx); + adios_write(f, "gndy", &s.gndy); + adios_write(f, "T", ht.data_noghost().data()); + adios_close(f); - MPI_Barrier( comm ); - double total_time = MPI_Wtime() - time_start; - uint64_t adios_totalsize = 2*sizeof(int) + 2*s.ndx*s.ndy*sizeof(double); - uint64_t sizeMB = adios_totalsize * s.nproc/1024/1024/1024; // size in MB - uint64_t mbs = sizeMB/total_time; - if (s.rank==0) - std::cout << "Step " << step << ": " << m_outputfilename - << " " << sizeMB << " " << total_time << "" << mbs << std::endl; + MPI_Barrier(comm); + double total_time = MPI_Wtime() - time_start; + uint64_t adios_totalsize = + 2 * sizeof(int) + 2 * s.ndx * s.ndy * sizeof(double); + uint64_t sizeMB = + adios_totalsize * s.nproc / 1024 / 1024 / 1024; // size in MB + uint64_t mbs = sizeMB / total_time; + if (s.rank == 0) + std::cout << "Step " << step << ": " << m_outputfilename << " " << sizeMB + << " " << total_time << "" << mbs << std::endl; } - diff --git a/examples/heatTransfer/IO_adios2.cpp b/examples/heatTransfer/IO_adios2.cpp index 9d27e7c39..acb22b01b 100644 --- a/examples/heatTransfer/IO_adios2.cpp +++ b/examples/heatTransfer/IO_adios2.cpp @@ -11,86 +11,96 @@ #include <string> static int rank_saved; -adios::ADIOS * ad = nullptr; +adios::ADIOS *ad = nullptr; std::shared_ptr<adios::Engine> bpWriter; -adios::Variable<double> * varT = nullptr; +adios::Variable<double> *varT = nullptr; -IO::IO( const Settings& s, MPI_Comm comm ) +IO::IO(const Settings &s, MPI_Comm comm) { - rank_saved = s.rank; - m_outputfilename = s.outputfile + ".bp"; - ad = new adios::ADIOS( "adios2.xml", comm, adios::Verbose::INFO ); - - //Define method for engine creation - // 1. Get method def from config file or define new one - - adios::Method& bpWriterSettings = ad->DeclareMethod( "output" ); - if( ! bpWriterSettings.isUserDefined()) - { - // if not defined by user, we can change the default settings - bpWriterSettings.SetEngine( "BP" ); // BP is the default engine - bpWriterSettings.AllowThreads( 1 ); // allow 1 extra thread for data processing - bpWriterSettings.AddTransport( "File", "lucky=yes" ); // ISO-POSIX file is the default transport - // Passing parameters to the transport - bpWriterSettings.SetParameters("have_metadata_file","yes" ); // Passing parameters to the engine - bpWriterSettings.SetParameters( "Aggregation", std::to_string((s.nproc+1)/2) ); // number of aggregators - } - - - // define T as 2D global array - varT = &ad->DefineVariable<double>( - "T", - {s.gndx,s.gndy}, // Global dimensions - {s.ndx,s.ndy}, // local size, could be defined later using SetSelection() - {s.offsx,s.offsy} // offset of the local array in the global space - ); - - - //add transform to variable - //adios::Transform tr = adios::transform::BZIP2( ); - //varT.AddTransform( tr, "" ); - // varT.AddTransform( tr,"accuracy=0.001" ); // for ZFP - - bpWriter = ad->Open( m_outputfilename, "w", comm, bpWriterSettings, adios::IOMode::COLLECTIVE); - - if( bpWriter == nullptr ) - throw std::ios_base::failure( "ERROR: failed to open ADIOS bpWriter\n" ); - - + rank_saved = s.rank; + m_outputfilename = s.outputfile + ".bp"; + ad = new adios::ADIOS("adios2.xml", comm, adios::Verbose::INFO); + + // Define method for engine creation + // 1. Get method def from config file or define new one + + adios::Method &bpWriterSettings = ad->DeclareMethod("output"); + if (!bpWriterSettings.isUserDefined()) + { + // if not defined by user, we can change the default settings + bpWriterSettings.SetEngine("BP"); // BP is the default engine + bpWriterSettings.AllowThreads( + 1); // allow 1 extra thread for data processing + bpWriterSettings.AddTransport( + "File", "lucky=yes"); // ISO-POSIX file is the default transport + // Passing parameters to the transport + bpWriterSettings.SetParameters("have_metadata_file", + "yes"); // Passing parameters to the engine + bpWriterSettings.SetParameters( + "Aggregation", + std::to_string((s.nproc + 1) / 2)); // number of aggregators + } + + // define T as 2D global array + varT = &ad->DefineVariable<double>( + "T", {s.gndx, s.gndy}, // Global dimensions + {s.ndx, s.ndy}, // local size, could be defined later using SetSelection() + {s.offsx, s.offsy} // offset of the local array in the global space + ); + + // add transform to variable + // adios::Transform tr = adios::transform::BZIP2( ); + // varT.AddTransform( tr, "" ); + // varT.AddTransform( tr,"accuracy=0.001" ); // for ZFP + + bpWriter = ad->Open(m_outputfilename, "w", comm, bpWriterSettings, + adios::IOMode::COLLECTIVE); + + if (bpWriter == nullptr) + throw std::ios_base::failure("ERROR: failed to open ADIOS bpWriter\n"); } IO::~IO() { - bpWriter->Close(); - delete ad; + bpWriter->Close(); + delete ad; } -void /*IO::*/old_style_write(int step, const HeatTransfer& ht, const Settings& s, MPI_Comm comm ) +void /*IO::*/ old_style_write(int step, const HeatTransfer &ht, + const Settings &s, MPI_Comm comm) { - bpWriter->Write<double>( *varT, ht.data_noghost().data()); - bpWriter->Advance( ); + bpWriter->Write<double>(*varT, ht.data_noghost().data()); + bpWriter->Advance(); } -void IO::write(int step, const HeatTransfer& ht, const Settings& s, MPI_Comm comm ) +void IO::write(int step, const HeatTransfer &ht, const Settings &s, + MPI_Comm comm) { - /* This selection is redundant and not required, since we defined - * the selection already in DefineVariable(). It is here just as an example. - */ - // Make a selection to describe the local dimensions of the variable we write and - // its offsets in the global spaces. This could have been done in adios.DefineVariable() - adios::Selection sel = adios.SelectionBoundingBox( {s.ndx,s.ndy}, {s.offsx,s.offsy} ); // local dims and offsets; both as list - var2D.SetSelection( sel ); - - /* Select the area that we want to write from the data pointer we pass to the writer. - Think HDF5 memspace, just not hyperslabs, only a bounding box selection. - Engine will copy this bounding box from the data pointer into the output buffer. - Size of the bounding box should match the "space" selection which was given above. - Default memspace is always the full selection. - */ - adios::Selection memspace = adios.SelectionBoundingBox( {s.ndx,s.ndy}, {1,1} ); - var2D.SetMemorySelection( memspace ); - - bpWriter->Write<double>( *varT, ht.data()); - bpWriter->Advance( ); + /* This selection is redundant and not required, since we defined + * the selection already in DefineVariable(). It is here just as an example. + */ + // Make a selection to describe the local dimensions of the variable we write + // and + // its offsets in the global spaces. This could have been done in + // adios.DefineVariable() + adios::Selection sel = adios.SelectionBoundingBox( + {s.ndx, s.ndy}, + {s.offsx, s.offsy}); // local dims and offsets; both as list + var2D.SetSelection(sel); + + /* Select the area that we want to write from the data pointer we pass to the + writer. + Think HDF5 memspace, just not hyperslabs, only a bounding box selection. + Engine will copy this bounding box from the data pointer into the output + buffer. + Size of the bounding box should match the "space" selection which was given + above. + Default memspace is always the full selection. + */ + adios::Selection memspace = + adios.SelectionBoundingBox({s.ndx, s.ndy}, {1, 1}); + var2D.SetMemorySelection(memspace); + + bpWriter->Write<double>(*varT, ht.data()); + bpWriter->Advance(); } - diff --git a/examples/heatTransfer/IO_ascii.cpp b/examples/heatTransfer/IO_ascii.cpp index 01bd6d2ed..1bf55d5bb 100644 --- a/examples/heatTransfer/IO_ascii.cpp +++ b/examples/heatTransfer/IO_ascii.cpp @@ -5,71 +5,71 @@ * Author: Norbert Podhorszki */ -#include <iostream> -#include <iomanip> #include <fstream> +#include <iomanip> +#include <iostream> #include "IO.h" static std::ofstream of; static std::streambuf *buf; -IO::IO( const Settings& s, MPI_Comm comm ) +IO::IO(const Settings &s, MPI_Comm comm) { - m_outputfilename = s.outputfile; + m_outputfilename = s.outputfile; - if (m_outputfilename == "cout") - { - buf = std::cout.rdbuf(); - } - else - { - int rank; - MPI_Comm_rank( comm, &rank ); - std::string rs = std::to_string(rank); - of.open(m_outputfilename + rs + ".txt"); - buf = of.rdbuf(); - } + if (m_outputfilename == "cout") + { + buf = std::cout.rdbuf(); + } + else + { + int rank; + MPI_Comm_rank(comm, &rank); + std::string rs = std::to_string(rank); + of.open(m_outputfilename + rs + ".txt"); + buf = of.rdbuf(); + } } IO::~IO() { - if (m_outputfilename != "cout") - { - of.close(); - } + if (m_outputfilename != "cout") + { + of.close(); + } } -void IO::write( int step, const HeatTransfer& ht, const Settings& s, MPI_Comm comm) +void IO::write(int step, const HeatTransfer &ht, const Settings &s, + MPI_Comm comm) { - std::ostream out(buf); - if( step == 0) + std::ostream out(buf); + if (step == 0) + { + out << "rank=" << s.rank << " size=" << s.ndx << "x" << s.ndy + << " offsets=" << s.offsx << ":" << s.offsy << " step=" << step + << std::endl; + out << " time row columns " << s.offsy << "..." << s.offsy + s.ndy - 1 + << std::endl; + out << " "; + for (int j = 1; j <= s.ndy; ++j) { - out << "rank=" << s.rank - << " size=" << s.ndx << "x" << s.ndy - << " offsets=" << s.offsx << ":" << s.offsy - << " step=" << step << std::endl; - out << " time row columns " << s.offsy << "..." << s.offsy+s.ndy-1 << std::endl; - out << " "; - for (int j = 1; j <= s.ndy; ++j) { - out << std::setw(9) << s.offsy+j-1; - } - out << "\n--------------------------------------------------------------\n"; - } - else - { - out << std::endl; + out << std::setw(9) << s.offsy + j - 1; } + out << "\n--------------------------------------------------------------\n"; + } + else + { + out << std::endl; + } - for (int i = 1; i <= s.ndx; ++i) + for (int i = 1; i <= s.ndx; ++i) + { + out << std::setw(5) << step << std::setw(5) << s.offsx + i - 1; + for (int j = 1; j <= s.ndy; ++j) { - out << std::setw(5) << step << std::setw(5) << s.offsx+i-1; - for (int j = 1; j <= s.ndy; ++j) - { - out << std::setw(9) << ht.T(i,j); - } - out << std::endl; + out << std::setw(9) << ht.T(i, j); } - + out << std::endl; + } } - diff --git a/examples/heatTransfer/IO_hdf5_a.cpp b/examples/heatTransfer/IO_hdf5_a.cpp index 387260628..6126ce78a 100644 --- a/examples/heatTransfer/IO_hdf5_a.cpp +++ b/examples/heatTransfer/IO_hdf5_a.cpp @@ -1,59 +1,59 @@ /* * IO_hdf5_a.cpp * - * Write output with sequential HDF5, one file per process, one separate set per timestep + * Write output with sequential HDF5, one file per process, one separate set per + * timestep * * Created on: Feb 2017 * Author: Norbert Podhorszki */ -#include <iostream> -#include <iomanip> #include <fstream> +#include <iomanip> +#include <iostream> #include <string> #include "IO.h" #include "hdf5.h" +IO::IO(const Settings &s, MPI_Comm comm) : m_outputfilename{s.outputfile} {} -IO::IO( const Settings& s, MPI_Comm comm ) -:m_outputfilename{s.outputfile} -{ -} - -IO::~IO() -{ -} +IO::~IO() {} -void IO::write( int step, const HeatTransfer& ht, const Settings& s, MPI_Comm comm) +void IO::write(int step, const HeatTransfer &ht, const Settings &s, + MPI_Comm comm) { - std::string rs = std::to_string(s.rank); - std::string ts = std::to_string(step); - std::string fname = s.outputfile + "." + rs + "." + ts + ".h5"; - - // for time measurements, let's synchronize the processes - MPI_Barrier( comm ); - double time_start = MPI_Wtime(); - - hsize_t dims[2] = {static_cast<hsize_t>(s.ndx), static_cast<hsize_t>(s.ndy)}; - - hid_t space = H5Screate_simple( 2, dims, NULL ); - hid_t file = H5Fcreate( fname.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT ); - hid_t dset = H5Dcreate( file, "T", H5T_NATIVE_DOUBLE, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT ); - - H5Dwrite( dset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, ht.data_noghost().data()); - - H5Dclose( dset ); - H5Sclose( space ); - H5Fclose( file ); - - MPI_Barrier( comm ); - double total_time = MPI_Wtime() - time_start; - uint64_t adios_totalsize = 2*sizeof(int) + 2*s.ndx*s.ndy*sizeof(double); - uint64_t sizeMB = adios_totalsize * s.nproc/1024/1024/1024; // size in MB - uint64_t mbs = sizeMB/total_time; - if (s.rank==0) - std::cout << "Step " << step << ": " << m_outputfilename - << " " << sizeMB << " " << total_time << "" << mbs << std::endl; + std::string rs = std::to_string(s.rank); + std::string ts = std::to_string(step); + std::string fname = s.outputfile + "." + rs + "." + ts + ".h5"; + + // for time measurements, let's synchronize the processes + MPI_Barrier(comm); + double time_start = MPI_Wtime(); + + hsize_t dims[2] = {static_cast<hsize_t>(s.ndx), static_cast<hsize_t>(s.ndy)}; + + hid_t space = H5Screate_simple(2, dims, NULL); + hid_t file = + H5Fcreate(fname.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT); + hid_t dset = H5Dcreate(file, "T", H5T_NATIVE_DOUBLE, space, H5P_DEFAULT, + H5P_DEFAULT, H5P_DEFAULT); + + H5Dwrite(dset, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT, + ht.data_noghost().data()); + + H5Dclose(dset); + H5Sclose(space); + H5Fclose(file); + + MPI_Barrier(comm); + double total_time = MPI_Wtime() - time_start; + uint64_t adios_totalsize = + 2 * sizeof(int) + 2 * s.ndx * s.ndy * sizeof(double); + uint64_t sizeMB = + adios_totalsize * s.nproc / 1024 / 1024 / 1024; // size in MB + uint64_t mbs = sizeMB / total_time; + if (s.rank == 0) + std::cout << "Step " << step << ": " << m_outputfilename << " " << sizeMB + << " " << total_time << "" << mbs << std::endl; } - diff --git a/examples/heatTransfer/Settings.cpp b/examples/heatTransfer/Settings.cpp index 8910cbc83..fdf37d5d7 100644 --- a/examples/heatTransfer/Settings.cpp +++ b/examples/heatTransfer/Settings.cpp @@ -5,85 +5,77 @@ * Author: Norbert Podhorszki */ - - -#include <errno.h> #include <cstdlib> +#include <errno.h> #include "Settings.h" - -static unsigned int convertToUint( std::string varName, char *arg ) -{ - char *end; - int retval = std::strtoll( arg, &end, 10); - if( end[0] || errno == ERANGE ) - { - throw std::invalid_argument( "Invalid value given for " + varName + ": " - + std::string(arg) ); - } - if( retval < 0 ) - { - throw std::invalid_argument( "Negative value given for " + varName + ": " - + std::string(arg) ); - } - return (unsigned int) retval; -} - -Settings::Settings( int argc, char* argv [], int rank, int nproc ) -: rank{rank} +static unsigned int convertToUint(std::string varName, char *arg) { - if (argc < 8) - { - throw std::invalid_argument( "Not enough arguments" ); - } - this->nproc = (unsigned int) nproc; - - outputfile = argv[1]; - npx = convertToUint("N", argv[2]); - npy = convertToUint("M", argv[3]); - ndx = convertToUint("nx", argv[4]); - ndy = convertToUint("ny", argv[5]); - steps = convertToUint("steps", argv[6]); - iterations = convertToUint("iterations", argv[7]); - - if( npx * npy != this->nproc ) - { - throw std::invalid_argument( "N*M must equal the number of processes" ); - } - - // calculate global array size and the local offsets in that global space - gndx = npx * ndx; - gndy = npy * ndy; - posx = rank % npx; - posy = rank / npx; - offsx = posx * ndx; - offsy = posy * ndy; - - // determine neighbors - if( posx == 0 ) - rank_left = -1; - else - rank_left = rank-1; - - if( posx == npx-1 ) - rank_right = -1; - else - rank_right = rank+1; - - if( posy == 0 ) - rank_up = -1; - else - rank_up = rank - npx; - - if( posy == npy-1 ) - rank_down = -1; - else - rank_down = rank + npx; - + char *end; + int retval = std::strtoll(arg, &end, 10); + if (end[0] || errno == ERANGE) + { + throw std::invalid_argument("Invalid value given for " + varName + ": " + + std::string(arg)); + } + if (retval < 0) + { + throw std::invalid_argument("Negative value given for " + varName + ": " + + std::string(arg)); + } + return (unsigned int)retval; } -Settings::~Settings() +Settings::Settings(int argc, char *argv[], int rank, int nproc) : rank{rank} { + if (argc < 8) + { + throw std::invalid_argument("Not enough arguments"); + } + this->nproc = (unsigned int)nproc; + + outputfile = argv[1]; + npx = convertToUint("N", argv[2]); + npy = convertToUint("M", argv[3]); + ndx = convertToUint("nx", argv[4]); + ndy = convertToUint("ny", argv[5]); + steps = convertToUint("steps", argv[6]); + iterations = convertToUint("iterations", argv[7]); + + if (npx * npy != this->nproc) + { + throw std::invalid_argument("N*M must equal the number of processes"); + } + + // calculate global array size and the local offsets in that global space + gndx = npx * ndx; + gndy = npy * ndy; + posx = rank % npx; + posy = rank / npx; + offsx = posx * ndx; + offsy = posy * ndy; + + // determine neighbors + if (posx == 0) + rank_left = -1; + else + rank_left = rank - 1; + + if (posx == npx - 1) + rank_right = -1; + else + rank_right = rank + 1; + + if (posy == 0) + rank_up = -1; + else + rank_up = rank - npx; + + if (posy == npy - 1) + rank_down = -1; + else + rank_down = rank + npx; } +Settings::~Settings() {} diff --git a/examples/heatTransfer/Settings.h b/examples/heatTransfer/Settings.h index 26ec50e18..5a8dabf88 100644 --- a/examples/heatTransfer/Settings.h +++ b/examples/heatTransfer/Settings.h @@ -14,38 +14,37 @@ class Settings { public: - // user arguments - std::string outputfile; - unsigned int npx; // Number of processes in X (slow) dimension - unsigned int npy; // Number of processes in Y (fast) dimension - unsigned int ndx; // Local array size in X dimension per process - unsigned int ndy; // Local array size in y dimension per process - unsigned int steps; // Number of output steps - unsigned int iterations; // Number of computing iterations between steps - - // calculated values from those arguments and number of processes - unsigned int gndx; // Global array size in slow dimension - unsigned int gndy; // Global array size in fast dimension - // X dim positions: rank 0, npx, 2npx... are in the same X position - // Y dim positions: npx number of consecutive processes belong to one row (npx columns) - unsigned int posx; // Position of this process in X dimension - unsigned int posy; // Position of this process in Y dimension - unsigned int offsx; // Offset of local array in X dimension on this process - unsigned int offsy; // Offset of local array in Y dimension on this process - - int rank; // MPI rank - unsigned int nproc; // number of processors - - // neighbors by their MPI ranks, -1 if there is no such neighbor - int rank_left; - int rank_right; - int rank_up; - int rank_down; - - Settings( int argc, char* argv [], int rank, int nproc ); - ~Settings(); - + // user arguments + std::string outputfile; + unsigned int npx; // Number of processes in X (slow) dimension + unsigned int npy; // Number of processes in Y (fast) dimension + unsigned int ndx; // Local array size in X dimension per process + unsigned int ndy; // Local array size in y dimension per process + unsigned int steps; // Number of output steps + unsigned int iterations; // Number of computing iterations between steps + + // calculated values from those arguments and number of processes + unsigned int gndx; // Global array size in slow dimension + unsigned int gndy; // Global array size in fast dimension + // X dim positions: rank 0, npx, 2npx... are in the same X position + // Y dim positions: npx number of consecutive processes belong to one row (npx + // columns) + unsigned int posx; // Position of this process in X dimension + unsigned int posy; // Position of this process in Y dimension + unsigned int offsx; // Offset of local array in X dimension on this process + unsigned int offsy; // Offset of local array in Y dimension on this process + + int rank; // MPI rank + unsigned int nproc; // number of processors + + // neighbors by their MPI ranks, -1 if there is no such neighbor + int rank_left; + int rank_right; + int rank_up; + int rank_down; + + Settings(int argc, char *argv[], int rank, int nproc); + ~Settings(); }; - #endif /* SETTINGS_H_ */ diff --git a/examples/heatTransfer/main.cpp b/examples/heatTransfer/main.cpp index 22fd919ce..6d787b8f9 100644 --- a/examples/heatTransfer/main.cpp +++ b/examples/heatTransfer/main.cpp @@ -9,101 +9,97 @@ */ #include <mpi.h> -#include <stdexcept> -#include <memory> #include <iostream> +#include <memory> +#include <stdexcept> #include <string> - -#include "Settings.h" -#include "IO.h" #include "HeatTransfer.h" +#include "IO.h" +#include "Settings.h" void printUsage() { - std::cout << "Usage: heatTransfer output N M nx ny steps iterations\n" - << " output: name of output file\n" - << " N: number of processes in X dimension\n" - << " M: number of processes in Y dimension\n" - << " nx: local array size in X dimension per processor\n" - << " ny: local array size in Y dimension per processor\n" - << " steps: the total number of steps to output\n" - << " iterations: one step consist of this many iterations\n\n"; + std::cout << "Usage: heatTransfer output N M nx ny steps iterations\n" + << " output: name of output file\n" + << " N: number of processes in X dimension\n" + << " M: number of processes in Y dimension\n" + << " nx: local array size in X dimension per processor\n" + << " ny: local array size in Y dimension per processor\n" + << " steps: the total number of steps to output\n" + << " iterations: one step consist of this many iterations\n\n"; } - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - MPI_Init( &argc, &argv ); - /* World comm spans all applications started with the same aprun command - on a Cray XK6. So we have to split and create the local - 'world' communicator for heat_transfer only. - In normal start-up, the communicator will just equal the MPI_COMM_WORLD. - */ - - int wrank, wnproc; - MPI_Comm_rank( MPI_COMM_WORLD, &wrank ); - MPI_Comm_size( MPI_COMM_WORLD, &wnproc ); - MPI_Barrier( MPI_COMM_WORLD ); - - const unsigned int color = 1; - MPI_Comm mpiHeatTransferComm; - MPI_Comm_split( MPI_COMM_WORLD, color, wrank, &mpiHeatTransferComm ); - - int rank, nproc; - MPI_Comm_rank( mpiHeatTransferComm, &rank ); - MPI_Comm_size( mpiHeatTransferComm, &nproc ); - - try + MPI_Init(&argc, &argv); + /* World comm spans all applications started with the same aprun command + on a Cray XK6. So we have to split and create the local + 'world' communicator for heat_transfer only. + In normal start-up, the communicator will just equal the MPI_COMM_WORLD. + */ + + int wrank, wnproc; + MPI_Comm_rank(MPI_COMM_WORLD, &wrank); + MPI_Comm_size(MPI_COMM_WORLD, &wnproc); + MPI_Barrier(MPI_COMM_WORLD); + + const unsigned int color = 1; + MPI_Comm mpiHeatTransferComm; + MPI_Comm_split(MPI_COMM_WORLD, color, wrank, &mpiHeatTransferComm); + + int rank, nproc; + MPI_Comm_rank(mpiHeatTransferComm, &rank); + MPI_Comm_size(mpiHeatTransferComm, &nproc); + + try + { + double timeStart = MPI_Wtime(); + Settings settings(argc, argv, rank, nproc); + HeatTransfer ht(settings); + IO io(settings, mpiHeatTransferComm); + + ht.init(true); + ht.printT("Initialized T:", mpiHeatTransferComm); + ht.heatEdges(); + // ht.exchange( mpiHeatTransferComm ); + ht.printT("Heated T:", mpiHeatTransferComm); + io.write(0, ht, settings, mpiHeatTransferComm); + + for (unsigned int t = 1; t <= settings.steps; ++t) { - double timeStart = MPI_Wtime(); - Settings settings( argc, argv, rank, nproc ); - HeatTransfer ht( settings ); - IO io( settings, mpiHeatTransferComm ); - - ht.init(true); - ht.printT("Initialized T:", mpiHeatTransferComm); + if (rank == 0) + std::cout << "Step " << t << ":\n"; + for (unsigned int iter = 1; iter <= settings.iterations; ++iter) + { + ht.iterate(); + ht.exchange(mpiHeatTransferComm); ht.heatEdges(); - //ht.exchange( mpiHeatTransferComm ); - ht.printT("Heated T:", mpiHeatTransferComm); - io.write( 0, ht, settings, mpiHeatTransferComm ); - - for( unsigned int t = 1; t <= settings.steps; ++t ) - { - if( rank == 0 ) - std::cout << "Step " << t << ":\n"; - for( unsigned int iter = 1; iter <= settings.iterations; ++iter ) - { - ht.iterate(); - ht.exchange( mpiHeatTransferComm ); - ht.heatEdges(); - } - io.write( t, ht, settings, mpiHeatTransferComm ); - } - MPI_Barrier( mpiHeatTransferComm ); - - double timeEnd = MPI_Wtime(); - if( rank == 0 ) - std::cout << "Total runtime = " << timeEnd-timeStart << "s\n"; - + } + io.write(t, ht, settings, mpiHeatTransferComm); } - catch( std::invalid_argument& e ) // command-line argument errors - { - std::cout << e.what() << std::endl; - printUsage(); - } - catch( std::ios_base::failure& e ) //I/O failure (e.g. file not found) - { - std::cout << "I/O base exception caught\n"; - std::cout << e.what() << std::endl; - } - catch( std::exception& e ) //All other exceptions - { - std::cout << "Exception caught\n"; - std::cout << e.what() << std::endl; - } - - MPI_Finalize(); - return 0; + MPI_Barrier(mpiHeatTransferComm); + + double timeEnd = MPI_Wtime(); + if (rank == 0) + std::cout << "Total runtime = " << timeEnd - timeStart << "s\n"; + } + catch (std::invalid_argument &e) // command-line argument errors + { + std::cout << e.what() << std::endl; + printUsage(); + } + catch (std::ios_base::failure &e) // I/O failure (e.g. file not found) + { + std::cout << "I/O base exception caught\n"; + std::cout << e.what() << std::endl; + } + catch (std::exception &e) // All other exceptions + { + std::cout << "Exception caught\n"; + std::cout << e.what() << std::endl; + } + + MPI_Finalize(); + return 0; } - diff --git a/examples/hello/adios1Writer/helloADIOS1Writer.cpp b/examples/hello/adios1Writer/helloADIOS1Writer.cpp index 18d26d34d..7420df8bd 100644 --- a/examples/hello/adios1Writer/helloADIOS1Writer.cpp +++ b/examples/hello/adios1Writer/helloADIOS1Writer.cpp @@ -5,101 +5,113 @@ * Author: wfg */ - - -#include <vector> #include <iostream> - +#include <vector> #include <mpi.h> - #include "ADIOS_CPP.h" - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - MPI_Init( &argc, &argv ); - int rank, nproc; - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); - MPI_Comm_size( MPI_COMM_WORLD, &nproc ); - const bool adiosDebug = true; - adios::ADIOS adios( MPI_COMM_WORLD, adios::Verbose::INFO, adiosDebug ); - - //Application variable - float frank = (float)rank; - std::vector<double> myDoubles = { frank, frank+0.1f, frank+0.2f, frank+0.3f, frank+0.4f, frank+0.5f, - frank+0.6f, frank+0.7f, frank+0.8f, frank+0.9f }; - const std::size_t Nx = myDoubles.size(); - - const std::size_t rows = 3; - const std::size_t columns = 3; - - std::vector<float> myMatrix; - myMatrix.reserve( rows * columns ); - myMatrix.push_back( frank+0.0 ); myMatrix.push_back( frank+0.1 ), myMatrix.push_back( frank+0.2 ); - myMatrix.push_back( frank+0.3 ); myMatrix.push_back( frank+0.4 ), myMatrix.push_back( frank+0.5 ); - myMatrix.push_back( frank+0.6 ); myMatrix.push_back( frank+0.7 ), myMatrix.push_back( frank+0.8 ); - - frank = -(float)rank; - std::vector<float> myMatrix2 = {frank-0.1f, frank-0.2f, frank-0.3f, - frank-0.4f, frank-0.5f, frank-0.6f, - frank-0.7f, frank-0.8f, frank-0.9f }; - - try - { - //Define variable and local size - adios::Variable<double>& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {1,Nx}, {nproc,Nx}, {rank,0} ); - adios::Variable<float>& ioMyMatrix = adios.DefineVariable<float>( "myMatrix", {rows,columns}, {nproc*rows,columns}, {rank*rows,0} ); - adios::Variable<float>& ioMyMatrix2 = adios.DefineVariable<float>( "myMatrix2", {rows,columns}, {rows,nproc*columns}, {0,rank*columns} ); - - //Define method for engine creation, it is basically straight-forward parameters - adios::Method& bpWriterSettings = adios.DeclareMethod( "SingleFile" ); //default method type is BPWriter - bpWriterSettings.SetEngine( "ADIOS1Writer" ); - bpWriterSettings.SetParameters( "profile_units=mus" ); - bpWriterSettings.AddTransport( "File", "profile_units=mus", "have_metadata_file=no" ); //uses default POSIX library - - //Create engine smart pointer due to polymorphism, - //Open returns a smart pointer to Engine containing the Derived class Writer - auto bpWriter = adios.Open( "myDoubles.bp", "w", bpWriterSettings, adios::IOMode::COLLECTIVE ); - - if( bpWriter == nullptr ) - throw std::ios_base::failure( "ERROR: couldn't create bpWriter at Open\n" ); - - bpWriter->Write<double>( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived - - bpWriter->Write<float>( ioMyMatrix, myMatrix.data() ); - bpWriter->Write<float>( ioMyMatrix2, myMatrix2.data() ); - - bpWriter->Close( ); - } - catch( std::invalid_argument& e ) + MPI_Init(&argc, &argv); + int rank, nproc; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + MPI_Comm_size(MPI_COMM_WORLD, &nproc); + const bool adiosDebug = true; + adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::INFO, adiosDebug); + + // Application variable + float frank = (float)rank; + std::vector<double> myDoubles = { + frank, frank + 0.1f, frank + 0.2f, frank + 0.3f, frank + 0.4f, + frank + 0.5f, frank + 0.6f, frank + 0.7f, frank + 0.8f, frank + 0.9f}; + const std::size_t Nx = myDoubles.size(); + + const std::size_t rows = 3; + const std::size_t columns = 3; + + std::vector<float> myMatrix; + myMatrix.reserve(rows * columns); + myMatrix.push_back(frank + 0.0); + myMatrix.push_back(frank + 0.1), myMatrix.push_back(frank + 0.2); + myMatrix.push_back(frank + 0.3); + myMatrix.push_back(frank + 0.4), myMatrix.push_back(frank + 0.5); + myMatrix.push_back(frank + 0.6); + myMatrix.push_back(frank + 0.7), myMatrix.push_back(frank + 0.8); + + frank = -(float)rank; + std::vector<float> myMatrix2 = {frank - 0.1f, frank - 0.2f, frank - 0.3f, + frank - 0.4f, frank - 0.5f, frank - 0.6f, + frank - 0.7f, frank - 0.8f, frank - 0.9f}; + + try + { + // Define variable and local size + adios::Variable<double> &ioMyDoubles = adios.DefineVariable<double>( + "myDoubles", {1, Nx}, {nproc, Nx}, {rank, 0}); + adios::Variable<float> &ioMyMatrix = adios.DefineVariable<float>( + "myMatrix", {rows, columns}, {nproc * rows, columns}, {rank * rows, 0}); + adios::Variable<float> &ioMyMatrix2 = adios.DefineVariable<float>( + "myMatrix2", {rows, columns}, {rows, nproc * columns}, + {0, rank * columns}); + + // Define method for engine creation, it is basically straight-forward + // parameters + adios::Method &bpWriterSettings = + adios.DeclareMethod("SingleFile"); // default method type is BPWriter + bpWriterSettings.SetEngine("ADIOS1Writer"); + bpWriterSettings.SetParameters("profile_units=mus"); + bpWriterSettings.AddTransport( + "File", "profile_units=mus", + "have_metadata_file=no"); // uses default POSIX library + + // Create engine smart pointer due to polymorphism, + // Open returns a smart pointer to Engine containing the Derived class + // Writer + auto bpWriter = adios.Open("myDoubles.bp", "w", bpWriterSettings, + adios::IOMode::COLLECTIVE); + + if (bpWriter == nullptr) + throw std::ios_base::failure("ERROR: couldn't create bpWriter at Open\n"); + + bpWriter->Write<double>(ioMyDoubles, myDoubles.data()); // Base class Engine + // own the Write<T> + // that will call + // overloaded Write + // from Derived + + bpWriter->Write<float>(ioMyMatrix, myMatrix.data()); + bpWriter->Write<float>(ioMyMatrix2, myMatrix2.data()); + + bpWriter->Close(); + } + catch (std::invalid_argument &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::ios_base::failure& e ) + } + catch (std::ios_base::failure &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::exception& e ) + } + catch (std::exception &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } + } - MPI_Finalize( ); - - return 0; + MPI_Finalize(); + return 0; } diff --git a/examples/hello/adios1Writer/helloADIOS1Writer_nompi.cpp b/examples/hello/adios1Writer/helloADIOS1Writer_nompi.cpp index c78fd0878..eff97abab 100644 --- a/examples/hello/adios1Writer/helloADIOS1Writer_nompi.cpp +++ b/examples/hello/adios1Writer/helloADIOS1Writer_nompi.cpp @@ -5,76 +5,80 @@ * Author: wfg */ -#include <vector> #include <iostream> +#include <vector> #include "ADIOS_CPP.h" - -int main( int argc, char* argv [] ) - { - const bool adiosDebug = true; - adios::ADIOS adios( adiosDebug ); - - //Application variable - std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - const std::size_t Nx = myDoubles.size(); - - const std::size_t rows = 3; - const std::size_t columns = 3; - std::vector<float> myMatrix = { 1, 2, 3, - 4, 5, 6, - 7, 8, 9 }; - - std::vector<float> myMatrix2 = { -1, -2, -3, - -4, -5, -6, - -7, -8, -9 }; - - try - { - //Define variable and local size - adios::Variable<double>& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", adios::Dims{Nx} ); - adios::Variable<float>& ioMyMatrix = adios.DefineVariable<float>( "myMatrix", adios::Dims{rows,columns} ); - adios::Variable<float>& ioMyMatrix2 = adios.DefineVariable<float>( "myMatrix2", adios::Dims{rows,columns} ); - adios::Variable<float>& ioMyMatrix3 = adios.DefineVariable<float>( "myMatrix3", adios::Dims{rows,columns} ); - - //Define method for engine creation, it is basically straight-forward parameters - adios::Method& bpWriterSettings = adios.DeclareMethod( "SinglePOSIXFile" ); //default method type is Writer - bpWriterSettings.SetParameters( "profile_units=mus" ); - bpWriterSettings.AddTransport( "File", "have_metadata_file=yes", "profile_units=mus" ); - - //Create engine smart pointer due to polymorphism, - //Open returns a smart pointer to Engine containing the Derived class Writer - auto bpFileWriter = adios.Open( "myDoubles_nompi.bp", "w", bpWriterSettings, adios::IOMode::COLLECTIVE ); - - if( bpFileWriter == nullptr ) - throw std::ios_base::failure( "ERROR: couldn't create bpWriter at Open\n" ); - - bpFileWriter->Write<double>( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived - bpFileWriter->Write<float>( ioMyMatrix, myMatrix.data() ); //2d Example - bpFileWriter->Write<float>( ioMyMatrix2, myMatrix2.data() ); //2d Example - bpFileWriter->Write<float>( ioMyMatrix3, myMatrix2.data() ); //2d Example - bpFileWriter->Close( ); - // - } - catch( std::invalid_argument& e ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - catch( std::ios_base::failure& e ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - catch( std::exception& e ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - - return 0; +int main(int argc, char *argv[]) +{ + const bool adiosDebug = true; + adios::ADIOS adios(adiosDebug); + + // Application variable + std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myDoubles.size(); + + const std::size_t rows = 3; + const std::size_t columns = 3; + std::vector<float> myMatrix = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + + std::vector<float> myMatrix2 = {-1, -2, -3, -4, -5, -6, -7, -8, -9}; + + try + { + // Define variable and local size + adios::Variable<double> &ioMyDoubles = + adios.DefineVariable<double>("myDoubles", adios::Dims{Nx}); + adios::Variable<float> &ioMyMatrix = + adios.DefineVariable<float>("myMatrix", adios::Dims{rows, columns}); + adios::Variable<float> &ioMyMatrix2 = + adios.DefineVariable<float>("myMatrix2", adios::Dims{rows, columns}); + adios::Variable<float> &ioMyMatrix3 = + adios.DefineVariable<float>("myMatrix3", adios::Dims{rows, columns}); + + // Define method for engine creation, it is basically straight-forward + // parameters + adios::Method &bpWriterSettings = + adios.DeclareMethod("SinglePOSIXFile"); // default method type is Writer + bpWriterSettings.SetParameters("profile_units=mus"); + bpWriterSettings.AddTransport("File", "have_metadata_file=yes", + "profile_units=mus"); + + // Create engine smart pointer due to polymorphism, + // Open returns a smart pointer to Engine containing the Derived class + // Writer + auto bpFileWriter = adios.Open("myDoubles_nompi.bp", "w", bpWriterSettings, + adios::IOMode::COLLECTIVE); + + if (bpFileWriter == nullptr) + throw std::ios_base::failure("ERROR: couldn't create bpWriter at Open\n"); + + bpFileWriter->Write<double>( + ioMyDoubles, myDoubles.data()); // Base class Engine own the Write<T> + // that will call overloaded Write from + // Derived + bpFileWriter->Write<float>(ioMyMatrix, myMatrix.data()); // 2d Example + bpFileWriter->Write<float>(ioMyMatrix2, myMatrix2.data()); // 2d Example + bpFileWriter->Write<float>(ioMyMatrix3, myMatrix2.data()); // 2d Example + bpFileWriter->Close(); + // + } + catch (std::invalid_argument &e) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::ios_base::failure &e) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::exception &e) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + + return 0; } - - - diff --git a/examples/hello/bpReader/helloBPReader.cpp b/examples/hello/bpReader/helloBPReader.cpp index bb1bc35d9..020883c90 100644 --- a/examples/hello/bpReader/helloBPReader.cpp +++ b/examples/hello/bpReader/helloBPReader.cpp @@ -5,67 +5,63 @@ * Author: wfg */ - - -#include <vector> #include <iostream> - +#include <vector> #include <mpi.h> - #include "ADIOS_CPP.h" - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - MPI_Init( &argc, &argv ); - int rank; - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); - const bool adiosDebug = true; - adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); - - try + MPI_Init(&argc, &argv); + int rank; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + const bool adiosDebug = true; + adios::ADIOS adios(MPI_COMM_WORLD, adiosDebug); + + try + { + // Define method for engine creation, it is basically straight-forward + // parameters + adios::Method &bpReaderSettings = + adios.DeclareMethod("SingleFile"); // default method type is BPWriter + bpReaderSettings.AddTransport("File"); // uses default POSIX library + + // Create engine smart pointer due to polymorphism, + // Open returns a smart pointer to Engine containing the Derived class + // Writer + auto bpReader = adios.Open("myDoubles_nompi.bp", "r", bpReaderSettings); + + if (bpReader == nullptr) + throw std::ios_base::failure("ERROR: couldn't create bpReader at Open\n"); + } + catch (std::invalid_argument &e) + { + if (rank == 0) { - //Define method for engine creation, it is basically straight-forward parameters - adios::Method& bpReaderSettings = adios.DeclareMethod( "SingleFile" ); //default method type is BPWriter - bpReaderSettings.AddTransport( "File" ); //uses default POSIX library - - //Create engine smart pointer due to polymorphism, - //Open returns a smart pointer to Engine containing the Derived class Writer - auto bpReader = adios.Open( "myDoubles_nompi.bp", "r", bpReaderSettings ); - - if( bpReader == nullptr ) - throw std::ios_base::failure( "ERROR: couldn't create bpReader at Open\n" ); - + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::invalid_argument& e ) + } + catch (std::ios_base::failure &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::ios_base::failure& e ) + } + catch (std::exception &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::exception& e ) - { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - } - - MPI_Finalize( ); + } - return 0; + MPI_Finalize(); + return 0; } diff --git a/examples/hello/bpReader/helloBPReader_nompi.cpp b/examples/hello/bpReader/helloBPReader_nompi.cpp index b5e437dea..d214e968b 100644 --- a/examples/hello/bpReader/helloBPReader_nompi.cpp +++ b/examples/hello/bpReader/helloBPReader_nompi.cpp @@ -5,48 +5,47 @@ * Author: wfg */ -#include <vector> #include <iostream> +#include <vector> #include "ADIOS_CPP.h" - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - const bool adiosDebug = true; - adios::ADIOS adios( adiosDebug ); - - try - { - //Define method for engine creation, it is basically straight-forward parameters - adios::Method& bpReaderSettings = adios.DeclareMethod( "SingleFile" ); //default method type is BPWriter/BPReader - bpReaderSettings.AddTransport( "File" ); //uses default POSIX library - - //Create engine smart pointer due to polymorphism, - //Open returns a smart pointer to Engine containing the Derived class Writer - auto bpReader = adios.Open( "myDoubles.bp", "r", bpReaderSettings ); - - if( bpReader == nullptr ) - throw std::ios_base::failure( "ERROR: couldn't create bpReader at Open\n" ); - } - catch( std::invalid_argument& e ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - catch( std::ios_base::failure& e ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - catch( std::exception& e ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - - return 0; + const bool adiosDebug = true; + adios::ADIOS adios(adiosDebug); + + try + { + // Define method for engine creation, it is basically straight-forward + // parameters + adios::Method &bpReaderSettings = adios.DeclareMethod( + "SingleFile"); // default method type is BPWriter/BPReader + bpReaderSettings.AddTransport("File"); // uses default POSIX library + + // Create engine smart pointer due to polymorphism, + // Open returns a smart pointer to Engine containing the Derived class + // Writer + auto bpReader = adios.Open("myDoubles.bp", "r", bpReaderSettings); + + if (bpReader == nullptr) + throw std::ios_base::failure("ERROR: couldn't create bpReader at Open\n"); + } + catch (std::invalid_argument &e) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::ios_base::failure &e) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::exception &e) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + + return 0; } - - - diff --git a/examples/hello/bpWriter/helloBPWriter.cpp b/examples/hello/bpWriter/helloBPWriter.cpp index 063dae3e1..3f54ee9f6 100644 --- a/examples/hello/bpWriter/helloBPWriter.cpp +++ b/examples/hello/bpWriter/helloBPWriter.cpp @@ -5,102 +5,110 @@ * Author: wfg */ - - -#include <vector> #include <iostream> - +#include <vector> #include <mpi.h> - #include "ADIOS_CPP.h" - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - MPI_Init( &argc, &argv ); - int rank; - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); - const bool adiosDebug = true; - adios::ADIOS adios( MPI_COMM_WORLD, adios::Verbose::INFO, adiosDebug ); - - //Application variable - std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - const std::size_t Nx = myDoubles.size(); - - const std::size_t rows = 3; - const std::size_t columns = 3; - - std::vector<float> myMatrix; - if( rank % 2 == 0 ) //even rank + MPI_Init(&argc, &argv); + int rank; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + const bool adiosDebug = true; + adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::INFO, adiosDebug); + + // Application variable + std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myDoubles.size(); + + const std::size_t rows = 3; + const std::size_t columns = 3; + + std::vector<float> myMatrix; + if (rank % 2 == 0) // even rank + { + myMatrix.reserve(rows * columns); + myMatrix.push_back(1); + myMatrix.push_back(2), myMatrix.push_back(3); + myMatrix.push_back(4); + myMatrix.push_back(5), myMatrix.push_back(6); + myMatrix.push_back(7); + myMatrix.push_back(8), myMatrix.push_back(8); + } + + std::vector<float> myMatrix2 = {-1, -2, -3, -4, -5, -6, -7, -8, -9}; + + try + { + // Define variable and local size + adios::Variable<double> &ioMyDoubles = + adios.DefineVariable<double>("myDoubles", {Nx}); + adios::Variable<float> &ioMyMatrix = + adios.DefineVariable<float>("myMatrix", {rows, columns}); + adios::Variable<float> &ioMyMatrix2 = + adios.DefineVariable<float>("myMatrix2", {rows, columns}); + + // Define method for engine creation, it is basically straight-forward + // parameters + adios::Method &bpWriterSettings = + adios.DeclareMethod("SingleFile"); // default method type is BPWriter + bpWriterSettings.SetParameters("profile_units=mus"); + bpWriterSettings.AddTransport( + "File", "profile_units=mus", + "have_metadata_file=no"); // uses default POSIX library + + // Create engine smart pointer due to polymorphism, + // Open returns a smart pointer to Engine containing the Derived class + // Writer + auto bpWriter = adios.Open("myDoubles.bp", "w", bpWriterSettings, + adios::IOMode::COLLECTIVE); + + if (bpWriter == nullptr) + throw std::ios_base::failure("ERROR: couldn't create bpWriter at Open\n"); + + bpWriter->Write<double>(ioMyDoubles, myDoubles.data()); // Base class Engine + // own the Write<T> + // that will call + // overloaded Write + // from Derived + + if (rank % 2 == 0) // even rank { - myMatrix.reserve( rows * columns ); - myMatrix.push_back( 1 ); myMatrix.push_back( 2 ), myMatrix.push_back( 3 ); - myMatrix.push_back( 4 ); myMatrix.push_back( 5 ), myMatrix.push_back( 6 ); - myMatrix.push_back( 7 ); myMatrix.push_back( 8 ), myMatrix.push_back( 8 ); + bpWriter->Write<float>(ioMyMatrix, myMatrix.data()); + bpWriter->Write<float>(ioMyMatrix2, myMatrix2.data()); } - std::vector<float> myMatrix2 = { -1, -2, -3, - -4, -5, -6, - -7, -8, -9 }; - - try - { - //Define variable and local size - adios::Variable<double>& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {Nx} ); - adios::Variable<float>& ioMyMatrix = adios.DefineVariable<float>( "myMatrix", {rows,columns} ); - adios::Variable<float>& ioMyMatrix2 = adios.DefineVariable<float>( "myMatrix2", {rows,columns} ); - - //Define method for engine creation, it is basically straight-forward parameters - adios::Method& bpWriterSettings = adios.DeclareMethod( "SingleFile" ); //default method type is BPWriter - bpWriterSettings.SetParameters( "profile_units=mus" ); - bpWriterSettings.AddTransport( "File", "profile_units=mus", "have_metadata_file=no" ); //uses default POSIX library - - //Create engine smart pointer due to polymorphism, - //Open returns a smart pointer to Engine containing the Derived class Writer - auto bpWriter = adios.Open( "myDoubles.bp", "w", bpWriterSettings, adios::IOMode::COLLECTIVE ); - - if( bpWriter == nullptr ) - throw std::ios_base::failure( "ERROR: couldn't create bpWriter at Open\n" ); - - bpWriter->Write<double>( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived - - if( rank % 2 == 0 ) //even rank - { - bpWriter->Write<float>( ioMyMatrix, myMatrix.data() ); - bpWriter->Write<float>( ioMyMatrix2, myMatrix2.data() ); - } - - bpWriter->Close( ); - } - catch( std::invalid_argument& e ) + bpWriter->Close(); + } + catch (std::invalid_argument &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::ios_base::failure& e ) + } + catch (std::ios_base::failure &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::exception& e ) + } + catch (std::exception &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } + } - MPI_Finalize( ); - - return 0; + MPI_Finalize(); + return 0; } diff --git a/examples/hello/bpWriter/helloBPWriter_nompi.cpp b/examples/hello/bpWriter/helloBPWriter_nompi.cpp index c78fd0878..eff97abab 100644 --- a/examples/hello/bpWriter/helloBPWriter_nompi.cpp +++ b/examples/hello/bpWriter/helloBPWriter_nompi.cpp @@ -5,76 +5,80 @@ * Author: wfg */ -#include <vector> #include <iostream> +#include <vector> #include "ADIOS_CPP.h" - -int main( int argc, char* argv [] ) - { - const bool adiosDebug = true; - adios::ADIOS adios( adiosDebug ); - - //Application variable - std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - const std::size_t Nx = myDoubles.size(); - - const std::size_t rows = 3; - const std::size_t columns = 3; - std::vector<float> myMatrix = { 1, 2, 3, - 4, 5, 6, - 7, 8, 9 }; - - std::vector<float> myMatrix2 = { -1, -2, -3, - -4, -5, -6, - -7, -8, -9 }; - - try - { - //Define variable and local size - adios::Variable<double>& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", adios::Dims{Nx} ); - adios::Variable<float>& ioMyMatrix = adios.DefineVariable<float>( "myMatrix", adios::Dims{rows,columns} ); - adios::Variable<float>& ioMyMatrix2 = adios.DefineVariable<float>( "myMatrix2", adios::Dims{rows,columns} ); - adios::Variable<float>& ioMyMatrix3 = adios.DefineVariable<float>( "myMatrix3", adios::Dims{rows,columns} ); - - //Define method for engine creation, it is basically straight-forward parameters - adios::Method& bpWriterSettings = adios.DeclareMethod( "SinglePOSIXFile" ); //default method type is Writer - bpWriterSettings.SetParameters( "profile_units=mus" ); - bpWriterSettings.AddTransport( "File", "have_metadata_file=yes", "profile_units=mus" ); - - //Create engine smart pointer due to polymorphism, - //Open returns a smart pointer to Engine containing the Derived class Writer - auto bpFileWriter = adios.Open( "myDoubles_nompi.bp", "w", bpWriterSettings, adios::IOMode::COLLECTIVE ); - - if( bpFileWriter == nullptr ) - throw std::ios_base::failure( "ERROR: couldn't create bpWriter at Open\n" ); - - bpFileWriter->Write<double>( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived - bpFileWriter->Write<float>( ioMyMatrix, myMatrix.data() ); //2d Example - bpFileWriter->Write<float>( ioMyMatrix2, myMatrix2.data() ); //2d Example - bpFileWriter->Write<float>( ioMyMatrix3, myMatrix2.data() ); //2d Example - bpFileWriter->Close( ); - // - } - catch( std::invalid_argument& e ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - catch( std::ios_base::failure& e ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - catch( std::exception& e ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - - return 0; +int main(int argc, char *argv[]) +{ + const bool adiosDebug = true; + adios::ADIOS adios(adiosDebug); + + // Application variable + std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myDoubles.size(); + + const std::size_t rows = 3; + const std::size_t columns = 3; + std::vector<float> myMatrix = {1, 2, 3, 4, 5, 6, 7, 8, 9}; + + std::vector<float> myMatrix2 = {-1, -2, -3, -4, -5, -6, -7, -8, -9}; + + try + { + // Define variable and local size + adios::Variable<double> &ioMyDoubles = + adios.DefineVariable<double>("myDoubles", adios::Dims{Nx}); + adios::Variable<float> &ioMyMatrix = + adios.DefineVariable<float>("myMatrix", adios::Dims{rows, columns}); + adios::Variable<float> &ioMyMatrix2 = + adios.DefineVariable<float>("myMatrix2", adios::Dims{rows, columns}); + adios::Variable<float> &ioMyMatrix3 = + adios.DefineVariable<float>("myMatrix3", adios::Dims{rows, columns}); + + // Define method for engine creation, it is basically straight-forward + // parameters + adios::Method &bpWriterSettings = + adios.DeclareMethod("SinglePOSIXFile"); // default method type is Writer + bpWriterSettings.SetParameters("profile_units=mus"); + bpWriterSettings.AddTransport("File", "have_metadata_file=yes", + "profile_units=mus"); + + // Create engine smart pointer due to polymorphism, + // Open returns a smart pointer to Engine containing the Derived class + // Writer + auto bpFileWriter = adios.Open("myDoubles_nompi.bp", "w", bpWriterSettings, + adios::IOMode::COLLECTIVE); + + if (bpFileWriter == nullptr) + throw std::ios_base::failure("ERROR: couldn't create bpWriter at Open\n"); + + bpFileWriter->Write<double>( + ioMyDoubles, myDoubles.data()); // Base class Engine own the Write<T> + // that will call overloaded Write from + // Derived + bpFileWriter->Write<float>(ioMyMatrix, myMatrix.data()); // 2d Example + bpFileWriter->Write<float>(ioMyMatrix2, myMatrix2.data()); // 2d Example + bpFileWriter->Write<float>(ioMyMatrix3, myMatrix2.data()); // 2d Example + bpFileWriter->Close(); + // + } + catch (std::invalid_argument &e) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::ios_base::failure &e) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::exception &e) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + + return 0; } - - - diff --git a/examples/hello/compound/helloCompound.cpp b/examples/hello/compound/helloCompound.cpp index c34e3f5b4..9409faebf 100644 --- a/examples/hello/compound/helloCompound.cpp +++ b/examples/hello/compound/helloCompound.cpp @@ -5,100 +5,104 @@ * Author: wfg */ -#include <vector> +#include <cstddef> // offsetof #include <iostream> -#include <cstddef> // offsetof - +#include <vector> #include <mpi.h> - #include "ADIOS_CPP.h" - struct Particle { - char Type[10]; ///< alpha, beta, gamma, etc. - double Position[3]; ///< x, y, z - double Velocity[3]; ///< Vx, Vy, Vz + char Type[10]; ///< alpha, beta, gamma, etc. + double Position[3]; ///< x, y, z + double Velocity[3]; ///< Vx, Vy, Vz }; - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - MPI_Init( &argc, &argv ); - int rank; - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); - const bool adiosDebug = true; - adios::ADIOS adios( MPI_COMM_WORLD, adiosDebug ); - - //Application variable - std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - const std::size_t Nx = myDoubles.size(); - - Particle myParticle; - sprintf( myParticle.Type, "%s", "photon" ); - myParticle.Position[0] = 0; - myParticle.Position[1] = 1; - myParticle.Position[2] = 2; - - myParticle.Velocity[0] = 10; - myParticle.Velocity[1] = 11; - myParticle.Velocity[2] = 12; - - try - { - //Define variable and local size - adios::Variable<double>& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", adios::Dims{Nx} ); - - adios::VariableCompound& ioMyParticle = adios.DefineVariableCompound<Particle>( "myParticle", adios::Dims{1} ); - ioMyParticle.InsertMember<std::string>( "Type", offsetof(Particle,Type) ); - ioMyParticle.InsertMember<std::vector<double>>( "Position", offsetof(Particle,Position) ); - ioMyParticle.InsertMember<std::vector<double>>( "Velocity", offsetof(Particle,Velocity) ); - - //Define method for engine creation, it is basically straight-forward parameters - adios::Method& bpWriterSettings = adios.DeclareMethod( "SingleFile" ); //default method type is BPWriter - bpWriterSettings.AddTransport( "File", "have_metadata_file=yes" ); //uses default POSIX library - - //Create engine smart pointer due to polymorphism, - //Open returns a smart pointer to Engine containing the Derived class Writer - auto bpWriter = adios.Open( "myDoubles.bp", "w", bpWriterSettings ); - - if( bpWriter == nullptr ) - throw std::ios_base::failure( "ERROR: couldn't create bpWriter at Open\n" ); - - bpWriter->Write( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived - bpWriter->Close( ); - } - catch( std::invalid_argument& e ) + MPI_Init(&argc, &argv); + int rank; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + const bool adiosDebug = true; + adios::ADIOS adios(MPI_COMM_WORLD, adiosDebug); + + // Application variable + std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myDoubles.size(); + + Particle myParticle; + sprintf(myParticle.Type, "%s", "photon"); + myParticle.Position[0] = 0; + myParticle.Position[1] = 1; + myParticle.Position[2] = 2; + + myParticle.Velocity[0] = 10; + myParticle.Velocity[1] = 11; + myParticle.Velocity[2] = 12; + + try + { + // Define variable and local size + adios::Variable<double> &ioMyDoubles = + adios.DefineVariable<double>("myDoubles", adios::Dims{Nx}); + + adios::VariableCompound &ioMyParticle = + adios.DefineVariableCompound<Particle>("myParticle", adios::Dims{1}); + ioMyParticle.InsertMember<std::string>("Type", offsetof(Particle, Type)); + ioMyParticle.InsertMember<std::vector<double>>( + "Position", offsetof(Particle, Position)); + ioMyParticle.InsertMember<std::vector<double>>( + "Velocity", offsetof(Particle, Velocity)); + + // Define method for engine creation, it is basically straight-forward + // parameters + adios::Method &bpWriterSettings = + adios.DeclareMethod("SingleFile"); // default method type is BPWriter + bpWriterSettings.AddTransport( + "File", "have_metadata_file=yes"); // uses default POSIX library + + // Create engine smart pointer due to polymorphism, + // Open returns a smart pointer to Engine containing the Derived class + // Writer + auto bpWriter = adios.Open("myDoubles.bp", "w", bpWriterSettings); + + if (bpWriter == nullptr) + throw std::ios_base::failure("ERROR: couldn't create bpWriter at Open\n"); + + bpWriter->Write(ioMyDoubles, myDoubles.data()); // Base class Engine own the + // Write<T> that will call + // overloaded Write from + // Derived + bpWriter->Close(); + } + catch (std::invalid_argument &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::ios_base::failure& e ) + } + catch (std::ios_base::failure &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::exception& e ) + } + catch (std::exception &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } + } - MPI_Finalize( ); - - return 0; + MPI_Finalize(); + return 0; } - - diff --git a/examples/hello/compound/helloCompound_nompi.cpp b/examples/hello/compound/helloCompound_nompi.cpp index 1bb0cb1a9..4f8f18a6b 100644 --- a/examples/hello/compound/helloCompound_nompi.cpp +++ b/examples/hello/compound/helloCompound_nompi.cpp @@ -5,83 +5,87 @@ * Author: wfg */ -#include <vector> -#include <iostream> -#include <cstddef> // offsetof +#include <cstddef> // offsetof #include <cstdio> +#include <iostream> +#include <vector> #include "ADIOS_CPP.h" - struct Particle { - char Type[10]; ///< alpha, beta, gamma, etc. - double Position[3]; ///< x, y, z - double Velocity[3]; ///< Vx, Vy, Vz + char Type[10]; ///< alpha, beta, gamma, etc. + double Position[3]; ///< x, y, z + double Velocity[3]; ///< Vx, Vy, Vz }; - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - const bool adiosDebug = true; - adios::ADIOS adios( adiosDebug ); - - //Application variable - std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - const std::size_t Nx = myDoubles.size(); - - Particle myParticle; - sprintf( myParticle.Type, "%s", "photon" ); - myParticle.Position[0] = 0; - myParticle.Position[1] = 1; - myParticle.Position[2] = 2; - - myParticle.Velocity[0] = 10; - myParticle.Velocity[1] = 11; - myParticle.Velocity[2] = 12; - - try - { - //Define variable and local size - adios::Variable<double>& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", adios::Dims{Nx} ); - - adios::VariableCompound& ioMyParticle = adios.DefineVariableCompound<Particle>( "myParticle" ); - ioMyParticle.InsertMember<char>( "Type", offsetof(Particle,Type) ); - ioMyParticle.InsertMember<double>( "Position", offsetof(Particle,Position) ); - ioMyParticle.InsertMember<double>( "Velocity", offsetof(Particle,Velocity) ); - - //Define method for engine creation, it is basically straight-forward parameters - adios::Method& bpWriterSettings = adios.DeclareMethod( "SingleFile" ); //default method type is BPWriter - bpWriterSettings.AddTransport( "File", "have_metadata_file=yes" ); //uses default POSIX library - - //Create engine smart pointer due to polymorphism, - //Open returns a smart pointer to Engine containing the Derived class Writer - auto bpWriter = adios.Open( "myDoubles.bp", "w", bpWriterSettings ); - - if( bpWriter == nullptr ) - throw std::ios_base::failure( "ERROR: couldn't create bpWriter at Open\n" ); - - bpWriter->Write( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived - bpWriter->Close( ); - } - catch( std::invalid_argument& e ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - catch( std::ios_base::failure& e ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - catch( std::exception& e ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - - return 0; - + const bool adiosDebug = true; + adios::ADIOS adios(adiosDebug); + + // Application variable + std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myDoubles.size(); + + Particle myParticle; + sprintf(myParticle.Type, "%s", "photon"); + myParticle.Position[0] = 0; + myParticle.Position[1] = 1; + myParticle.Position[2] = 2; + + myParticle.Velocity[0] = 10; + myParticle.Velocity[1] = 11; + myParticle.Velocity[2] = 12; + + try + { + // Define variable and local size + adios::Variable<double> &ioMyDoubles = + adios.DefineVariable<double>("myDoubles", adios::Dims{Nx}); + + adios::VariableCompound &ioMyParticle = + adios.DefineVariableCompound<Particle>("myParticle"); + ioMyParticle.InsertMember<char>("Type", offsetof(Particle, Type)); + ioMyParticle.InsertMember<double>("Position", offsetof(Particle, Position)); + ioMyParticle.InsertMember<double>("Velocity", offsetof(Particle, Velocity)); + + // Define method for engine creation, it is basically straight-forward + // parameters + adios::Method &bpWriterSettings = + adios.DeclareMethod("SingleFile"); // default method type is BPWriter + bpWriterSettings.AddTransport( + "File", "have_metadata_file=yes"); // uses default POSIX library + + // Create engine smart pointer due to polymorphism, + // Open returns a smart pointer to Engine containing the Derived class + // Writer + auto bpWriter = adios.Open("myDoubles.bp", "w", bpWriterSettings); + + if (bpWriter == nullptr) + throw std::ios_base::failure("ERROR: couldn't create bpWriter at Open\n"); + + bpWriter->Write(ioMyDoubles, myDoubles.data()); // Base class Engine own the + // Write<T> that will call + // overloaded Write from + // Derived + bpWriter->Close(); + } + catch (std::invalid_argument &e) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::ios_base::failure &e) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::exception &e) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + + return 0; } - - diff --git a/examples/hello/datamanReader/helloDataManReader.cpp b/examples/hello/datamanReader/helloDataManReader.cpp index 44c597fac..bed40a1f0 100644 --- a/examples/hello/datamanReader/helloDataManReader.cpp +++ b/examples/hello/datamanReader/helloDataManReader.cpp @@ -5,97 +5,101 @@ * Author: wfg */ - - -#include <vector> -#include <iostream> //std::cout, std::endl -#include <string> -#include <numeric> //std::accumulate #include <functional> //std::multiplies - +#include <iostream> //std::cout, std::endl +#include <numeric> //std::accumulate +#include <string> +#include <vector> #include <mpi.h> - #include "ADIOS_CPP.h" -void getcb( const void *data, std::string doid, std::string var, std::string dtype, std::vector<std::size_t> varshape ) +void getcb(const void *data, std::string doid, std::string var, + std::string dtype, std::vector<std::size_t> varshape) { - std::cout << "data object ID = " << doid << "\n"; //do you need to flush? - std::cout << "variable name = " << var << "\n"; - std::cout << "data type = " << dtype << "\n"; + std::cout << "data object ID = " << doid << "\n"; // do you need to flush? + std::cout << "variable name = " << var << "\n"; + std::cout << "data type = " << dtype << "\n"; - std::size_t varsize = std::accumulate(varshape.begin(), varshape.end(), 1, std::multiplies<std::size_t>()); + std::size_t varsize = std::accumulate(varshape.begin(), varshape.end(), 1, + std::multiplies<std::size_t>()); - for( unsigned int i=0; i < varsize; ++i ) - std::cout << ((float*)data)[i] << " "; - std::cout << std::endl; + for (unsigned int i = 0; i < varsize; ++i) + std::cout << ((float *)data)[i] << " "; + std::cout << std::endl; } -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - MPI_Init( &argc, &argv ); - int rank; - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); - const bool adiosDebug = true; - adios::ADIOS adios( MPI_COMM_WORLD, adios::Verbose::WARN, adiosDebug ); - - try + MPI_Init(&argc, &argv); + int rank; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + const bool adiosDebug = true; + adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::WARN, adiosDebug); + + try + { + // Define method for engine creation, it is basically straight-forward + // parameters + adios::Method &datamanSettings = adios.DeclareMethod("WAN"); + if (!datamanSettings.isUserDefined()) { - //Define method for engine creation, it is basically straight-forward parameters - adios::Method& datamanSettings = adios.DeclareMethod( "WAN" ); - if( ! datamanSettings.isUserDefined()) - { - // if not defined by user, we can change the default settings - datamanSettings.SetEngine( "DataManReader" ); - datamanSettings.SetParameters( "peer-to-peer=yes" ); - datamanSettings.AddTransport( "Mdtm", "localIP=128.0.0.0.1", "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); - //datamanSettings.AddTransport( "ZeroMQ", "localIP=128.0.0.0.1.1", "remoteIP=128.0.0.0.2.1", "tolerances=1,2,3" ); not yet supported , will throw an exception - } - - //Create engine smart pointer to DataManReader Engine due to polymorphism, - //Open returns a smart pointer to Engine containing the Derived class DataManReader - auto datamanReader = adios.Open( "myDoubles.bp", "r", datamanSettings, adios::IOMode::INDEPENDENT ); + // if not defined by user, we can change the default settings + datamanSettings.SetEngine("DataManReader"); + datamanSettings.SetParameters("peer-to-peer=yes"); + datamanSettings.AddTransport("Mdtm", "localIP=128.0.0.0.1", + "remoteIP=128.0.0.0.2", "tolerances=1,2,3"); + // datamanSettings.AddTransport( "ZeroMQ", "localIP=128.0.0.0.1.1", + // "remoteIP=128.0.0.0.2.1", "tolerances=1,2,3" ); not yet supported , + // will throw an exception + } - if( datamanReader == nullptr ) - throw std::ios_base::failure( "ERROR: failed to create DataMan I/O engine at Open\n" ); + // Create engine smart pointer to DataManReader Engine due to polymorphism, + // Open returns a smart pointer to Engine containing the Derived class + // DataManReader + auto datamanReader = adios.Open("myDoubles.bp", "r", datamanSettings, + adios::IOMode::INDEPENDENT); - datamanReader->SetCallBack( getcb ); + if (datamanReader == nullptr) + throw std::ios_base::failure( + "ERROR: failed to create DataMan I/O engine at Open\n"); - adios::Variable<double>* ioMyDoubles = datamanReader->InquireVariableDouble( "ioMyDoubles" ); - if( ioMyDoubles == nullptr ) - std::cout << "Variable ioMyDoubles not read...yet\n"; + datamanReader->SetCallBack(getcb); - datamanReader->Close( ); + adios::Variable<double> *ioMyDoubles = + datamanReader->InquireVariableDouble("ioMyDoubles"); + if (ioMyDoubles == nullptr) + std::cout << "Variable ioMyDoubles not read...yet\n"; - } - catch( std::invalid_argument& e ) + datamanReader->Close(); + } + catch (std::invalid_argument &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::ios_base::failure& e ) + } + catch (std::ios_base::failure &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::exception& e ) + } + catch (std::exception &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } + } - MPI_Finalize( ); - - return 0; + MPI_Finalize(); + return 0; } diff --git a/examples/hello/datamanReader/helloDataManReader_nompi.cpp b/examples/hello/datamanReader/helloDataManReader_nompi.cpp index 56e3ba1ae..278431bd8 100644 --- a/examples/hello/datamanReader/helloDataManReader_nompi.cpp +++ b/examples/hello/datamanReader/helloDataManReader_nompi.cpp @@ -5,78 +5,90 @@ * Author: wfg */ -#include <vector> #include <iostream> #include <numeric> +#include <vector> #include "ADIOS_CPP.h" -void getcb( const void *data, std::string doid, std::string var, std::string dtype, std::vector<std::size_t> varshape ) +void getcb(const void *data, std::string doid, std::string var, + std::string dtype, std::vector<std::size_t> varshape) { - std::cout << "data object ID = " << doid << "\n"; //do you need to flush? - std::cout << "variable name = " << var << "\n"; - std::cout << "data type = " << dtype << "\n"; + std::cout << "data object ID = " << doid << "\n"; // do you need to flush? + std::cout << "variable name = " << var << "\n"; + std::cout << "data type = " << dtype << "\n"; - std::size_t varsize = std::accumulate(varshape.begin(), varshape.end(), 1, std::multiplies<std::size_t>()); + std::size_t varsize = std::accumulate(varshape.begin(), varshape.end(), 1, + std::multiplies<std::size_t>()); - for( unsigned int i=0; i < varsize; ++i ) - std::cout << ((float*)data)[i] << " "; - std::cout << std::endl; + for (unsigned int i = 0; i < varsize; ++i) + std::cout << ((float *)data)[i] << " "; + std::cout << std::endl; } -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - const bool adiosDebug = true; - adios::ADIOS adios( adios::Verbose::WARN, adiosDebug ); - - try + const bool adiosDebug = true; + adios::ADIOS adios(adios::Verbose::WARN, adiosDebug); + + try + { + // Define method for engine creation, it is basically straight-forward + // parameters + adios::Method &datamanSettings = adios.DeclareMethod("WAN"); + if (!datamanSettings.isUserDefined()) { - //Define method for engine creation, it is basically straight-forward parameters - adios::Method& datamanSettings = adios.DeclareMethod( "WAN" ); - if( ! datamanSettings.isUserDefined()) - { - // if not defined by user, we can change the default settings - datamanSettings.SetEngine( "DataManReader" ); - datamanSettings.SetParameters( "real_time=yes", "method_type=stream", "method=zmq", "local_ip=127.0.0.1", "remote_ip=127.0.0.1", "local_port=12307", "remote_port=12306" ); - //datamanSettings.AddTransport( "Mdtm", "localIP=128.0.0.0.1", "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); - //datamanSettings.AddTransport( "ZeroMQ", "localIP=128.0.0.0.1.1", "remoteIP=128.0.0.0.2.1", "tolerances=1,2,3" ); not yet supported , will throw an exception - } - - //Create engine smart pointer to DataManReader Engine due to polymorphism, - //Open returns a smart pointer to Engine containing the Derived class DataManReader - auto datamanReader = adios.Open( "myDoubles.bp", "r", datamanSettings, adios::IOMode::INDEPENDENT ); - - if( datamanReader == nullptr ) - throw std::ios_base::failure( "ERROR: failed to create DataMan I/O engine at Open\n" ); + // if not defined by user, we can change the default settings + datamanSettings.SetEngine("DataManReader"); + datamanSettings.SetParameters("real_time=yes", "method_type=stream", + "method=zmq", "local_ip=127.0.0.1", + "remote_ip=127.0.0.1", "local_port=12307", + "remote_port=12306"); + // datamanSettings.AddTransport( "Mdtm", "localIP=128.0.0.0.1", + // "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); + // datamanSettings.AddTransport( "ZeroMQ", "localIP=128.0.0.0.1.1", + // "remoteIP=128.0.0.0.2.1", "tolerances=1,2,3" ); not yet supported , + // will throw an exception + } - datamanReader->SetCallBack( getcb ); + // Create engine smart pointer to DataManReader Engine due to polymorphism, + // Open returns a smart pointer to Engine containing the Derived class + // DataManReader + auto datamanReader = adios.Open("myDoubles.bp", "r", datamanSettings, + adios::IOMode::INDEPENDENT); - while(1){} + if (datamanReader == nullptr) + throw std::ios_base::failure( + "ERROR: failed to create DataMan I/O engine at Open\n"); - adios::Variable<double>* ioMyDoubles = datamanReader->InquireVariableDouble( "ioMyDoubles" ); - if( ioMyDoubles == nullptr ) - std::cout << "Variable ioMyDoubles not read...yet\n"; + datamanReader->SetCallBack(getcb); - datamanReader->Close( ); - } - catch( std::invalid_argument& e ) + while (1) { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - catch( std::ios_base::failure& e ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - catch( std::exception& e ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; } - return 0; + adios::Variable<double> *ioMyDoubles = + datamanReader->InquireVariableDouble("ioMyDoubles"); + if (ioMyDoubles == nullptr) + std::cout << "Variable ioMyDoubles not read...yet\n"; + + datamanReader->Close(); + } + catch (std::invalid_argument &e) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::ios_base::failure &e) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::exception &e) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + + return 0; } - - - diff --git a/examples/hello/datamanWriter/helloDataManWriter.cpp b/examples/hello/datamanWriter/helloDataManWriter.cpp index 942fdf11e..44876132f 100644 --- a/examples/hello/datamanWriter/helloDataManWriter.cpp +++ b/examples/hello/datamanWriter/helloDataManWriter.cpp @@ -5,99 +5,108 @@ * Author: wfg */ - - -#include <vector> #include <iostream> - +#include <vector> #include <mpi.h> - #include "ADIOS_CPP.h" - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - MPI_Init( &argc, &argv ); - int rank; - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); - const bool adiosDebug = true; - adios::ADIOS adios( MPI_COMM_WORLD, adios::Verbose::WARN, adiosDebug ); - - //Application variable - std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - const std::size_t Nx = myDoubles.size(); - - std::vector<std::complex<float>> myCFloats; - myCFloats.reserve( 3 ); - myCFloats.emplace_back( 1, 3 ); - myCFloats.emplace_back( 2, 2 ); - myCFloats.emplace_back( 3, 1 ); - - try + MPI_Init(&argc, &argv); + int rank; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + const bool adiosDebug = true; + adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::WARN, adiosDebug); + + // Application variable + std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myDoubles.size(); + + std::vector<std::complex<float>> myCFloats; + myCFloats.reserve(3); + myCFloats.emplace_back(1, 3); + myCFloats.emplace_back(2, 2); + myCFloats.emplace_back(3, 1); + + try + { + // Define variable and local size + auto ioMyDoubles = adios.DefineVariable<double>("myDoubles", {Nx}); + auto ioMyCFloats = + adios.DefineVariable<std::complex<float>>("myCFloats", {3}); + + // Define method for engine creation, it is basically straight-forward + // parameters + adios::Method &datamanSettings = adios.DeclareMethod("WAN"); + if (!datamanSettings.isUserDefined()) { - //Define variable and local size - auto ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {Nx} ); - auto ioMyCFloats = adios.DefineVariable<std::complex<float>>( "myCFloats", {3} ); - - //Define method for engine creation, it is basically straight-forward parameters - adios::Method& datamanSettings = adios.DeclareMethod( "WAN" ); - if( ! datamanSettings.isUserDefined()) - { - // if not defined by user, we can change the default settings - datamanSettings.SetEngine("DatamanWriter"); - datamanSettings.SetParameters( "peer-to-peer=yes", "real_time=yes", "compress=no" ); - datamanSettings.AddTransport( "Mdtm", "localIP=128.0.0.0.1", "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); - //datamanSettings.AddTransport( "file", "name=myfile.bp", "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); - //datamanSettings.AddTransport( "file", "name=myfile.bp", "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); - //datamanSettings.AddTransport( "Mdtm", "localIP=128.0.0.0.1", "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); - //datamanSettings.AddTransport( "ZeroMQ", "localIP=128.0.0.0.1", "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); - //datamanSettings.AddTransport( "ZeroMQ", "localIP=128.0.0.0.1.1", "remoteIP=128.0.0.0.2.1", "tolerances=1,2,3" ); not yet supported, will throw an exception - } - - //Create engine smart pointer to DataMan Engine due to polymorphism, - //Open returns a smart pointer to Engine containing the Derived class DataMan - - //adios::DataManWriter datamanWriter; - - auto datamanWriter = adios.Open( "myDoubles.bp", "w", datamanSettings, adios::IOMode::INDEPENDENT ); - - if( datamanWriter == nullptr ) - throw std::ios_base::failure( "ERROR: failed to create DataMan I/O engine at Open\n" ); - - datamanWriter->Write<double>( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived - datamanWriter->Write<std::complex<float>>( ioMyCFloats, myCFloats.data() ); - datamanWriter->Close( ); - + // if not defined by user, we can change the default settings + datamanSettings.SetEngine("DatamanWriter"); + datamanSettings.SetParameters("peer-to-peer=yes", "real_time=yes", + "compress=no"); + datamanSettings.AddTransport("Mdtm", "localIP=128.0.0.0.1", + "remoteIP=128.0.0.0.2", "tolerances=1,2,3"); + // datamanSettings.AddTransport( "file", "name=myfile.bp", + // "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); + // datamanSettings.AddTransport( "file", "name=myfile.bp", + // "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); + // datamanSettings.AddTransport( "Mdtm", "localIP=128.0.0.0.1", + // "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); + // datamanSettings.AddTransport( "ZeroMQ", "localIP=128.0.0.0.1", + // "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); + // datamanSettings.AddTransport( "ZeroMQ", "localIP=128.0.0.0.1.1", + // "remoteIP=128.0.0.0.2.1", "tolerances=1,2,3" ); not yet supported, will + // throw an exception } - catch( std::invalid_argument& e ) + + // Create engine smart pointer to DataMan Engine due to polymorphism, + // Open returns a smart pointer to Engine containing the Derived class + // DataMan + + // adios::DataManWriter datamanWriter; + + auto datamanWriter = adios.Open("myDoubles.bp", "w", datamanSettings, + adios::IOMode::INDEPENDENT); + + if (datamanWriter == nullptr) + throw std::ios_base::failure( + "ERROR: failed to create DataMan I/O engine at Open\n"); + + datamanWriter->Write<double>( + ioMyDoubles, myDoubles.data()); // Base class Engine own the Write<T> + // that will call overloaded Write from + // Derived + datamanWriter->Write<std::complex<float>>(ioMyCFloats, myCFloats.data()); + datamanWriter->Close(); + } + catch (std::invalid_argument &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::ios_base::failure& e ) + } + catch (std::ios_base::failure &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::exception& e ) + } + catch (std::exception &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } + } - MPI_Finalize( ); - - return 0; + MPI_Finalize(); + return 0; } diff --git a/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp b/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp index e9bec44d8..7010c088a 100644 --- a/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp +++ b/examples/hello/datamanWriter/helloDataManWriter_nompi.cpp @@ -5,79 +5,92 @@ * Author: wfg */ -#include <vector> #include <iostream> +#include <vector> #include "ADIOS_CPP.h" - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - const bool adiosDebug = true; - adios::ADIOS adios( adios::Verbose::WARN, adiosDebug ); - - //Application variable - std::vector<float> myFloats = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - const std::size_t Nx = myDoubles.size(); - - std::vector<std::complex<float>> myCFloats; - myCFloats.reserve( 3 ); - myCFloats.emplace_back( 1, 3 ); - myCFloats.emplace_back( 2, 2 ); - myCFloats.emplace_back( 3, 1 ); - - try - { - //Define variable and local size - //Define variable and local size - auto ioMyFloats = adios.DefineVariable<float>( "myfloats", adios::Dims{Nx} ); - auto ioMyFloat = adios.DefineVariable<float>( "myfloat", adios::Dims{1} ); -// auto& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", adios::Dims{Nx} ); -// auto& ioMyCFloats = adios.DefineVariable<std::complex<float>>( "myCFloats", {3} ); + const bool adiosDebug = true; + adios::ADIOS adios(adios::Verbose::WARN, adiosDebug); - //Define method for engine creation, it is basically straight-forward parameters - adios::Method& datamanSettings = adios.DeclareMethod( "WAN" ); - if( ! datamanSettings.isUserDefined()) - { - // if not defined by user, we can change the default settings - datamanSettings.SetEngine( "DataManWriter" ); - datamanSettings.SetParameters( "real_time=yes", "method_type=stream", "method=dump", "monitoring=yes", "local_ip=127.0.0.1", "remote_ip=127.0.0.1", "local_port=12306", "remote_port=12307" ); - //datamanSettings.AddTransport( "Mdtm", "localIP=128.0.0.0.1", "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); - //datamanSettings.AddTransport( "ZeroMQ", "localIP=128.0.0.0.1.1", "remoteIP=128.0.0.0.2.1", "tolerances=1,2,3" ); not yet supported , will throw an exception - } + // Application variable + std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myDoubles.size(); - //Create engine smart pointer to DataMan Engine due to polymorphism, - //Open returns a smart pointer to Engine containing the Derived class DataMan - auto datamanWriter = adios.Open( "myDoubles.bp", "w", datamanSettings, adios::IOMode::INDEPENDENT ); + std::vector<std::complex<float>> myCFloats; + myCFloats.reserve(3); + myCFloats.emplace_back(1, 3); + myCFloats.emplace_back(2, 2); + myCFloats.emplace_back(3, 1); - if( datamanWriter == nullptr ) - throw std::ios_base::failure( "ERROR: failed to create DataMan I/O engine at Open\n" ); + try + { + // Define variable and local size + // Define variable and local size + auto ioMyFloats = adios.DefineVariable<float>("myfloats", adios::Dims{Nx}); + auto ioMyFloat = adios.DefineVariable<float>("myfloat", adios::Dims{1}); + // auto& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", + // adios::Dims{Nx} ); + // auto& ioMyCFloats = adios.DefineVariable<std::complex<float>>( + // "myCFloats", {3} ); - datamanWriter->Write<float>( ioMyFloats, myFloats.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived - const float num = 1.12; - datamanWriter->Write<float>( ioMyFloat, &num ); // Base class Engine own the Write<T> that will call overloaded Write from Derived -// datamanWriter->Write( ioMyCFloats, myCFloats.data() ); - datamanWriter->Close( ); - } - catch( std::invalid_argument& e ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - catch( std::ios_base::failure& e ) + // Define method for engine creation, it is basically straight-forward + // parameters + adios::Method &datamanSettings = adios.DeclareMethod("WAN"); + if (!datamanSettings.isUserDefined()) { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - catch( std::exception& e ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; + // if not defined by user, we can change the default settings + datamanSettings.SetEngine("DataManWriter"); + datamanSettings.SetParameters("real_time=yes", "method_type=stream", + "method=dump", "monitoring=yes", + "local_ip=127.0.0.1", "remote_ip=127.0.0.1", + "local_port=12306", "remote_port=12307"); + // datamanSettings.AddTransport( "Mdtm", "localIP=128.0.0.0.1", + // "remoteIP=128.0.0.0.2", "tolerances=1,2,3" ); + // datamanSettings.AddTransport( "ZeroMQ", "localIP=128.0.0.0.1.1", + // "remoteIP=128.0.0.0.2.1", "tolerances=1,2,3" ); not yet supported , + // will throw an exception } - return 0; -} + // Create engine smart pointer to DataMan Engine due to polymorphism, + // Open returns a smart pointer to Engine containing the Derived class + // DataMan + auto datamanWriter = adios.Open("myDoubles.bp", "w", datamanSettings, + adios::IOMode::INDEPENDENT); + if (datamanWriter == nullptr) + throw std::ios_base::failure( + "ERROR: failed to create DataMan I/O engine at Open\n"); + datamanWriter->Write<float>( + ioMyFloats, myFloats.data()); // Base class Engine own the Write<T> that + // will call overloaded Write from Derived + const float num = 1.12; + datamanWriter->Write<float>(ioMyFloat, &num); // Base class Engine own the + // Write<T> that will call + // overloaded Write from + // Derived + // datamanWriter->Write( ioMyCFloats, myCFloats.data() ); + datamanWriter->Close(); + } + catch (std::invalid_argument &e) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::ios_base::failure &e) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::exception &e) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + return 0; +} diff --git a/examples/hello/timeBP/timeBPWriter.cpp b/examples/hello/timeBP/timeBPWriter.cpp index 771a9ebec..90ffa6e47 100644 --- a/examples/hello/timeBP/timeBPWriter.cpp +++ b/examples/hello/timeBP/timeBPWriter.cpp @@ -5,109 +5,116 @@ * Author: wfg */ - -#include <vector> #include <iostream> +#include <vector> #include <mpi.h> - #include "ADIOS_CPP.h" - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - MPI_Init( &argc, &argv ); - int rank; - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); - const bool adiosDebug = true; - adios::ADIOS adios( MPI_COMM_WORLD, adios::Verbose::ERROR, adiosDebug ); - - //Application variable - std::vector<double> myDoubles = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - const std::size_t Nx = myDoubles.size(); - - const std::size_t rows = 3; - const std::size_t columns = 3; - - std::vector<float> myMatrix; - if( rank % 2 == 0 ) //even rank + MPI_Init(&argc, &argv); + int rank; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); + const bool adiosDebug = true; + adios::ADIOS adios(MPI_COMM_WORLD, adios::Verbose::ERROR, adiosDebug); + + // Application variable + std::vector<double> myDoubles = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myDoubles.size(); + + const std::size_t rows = 3; + const std::size_t columns = 3; + + std::vector<float> myMatrix; + if (rank % 2 == 0) // even rank + { + myMatrix.reserve(rows * columns); + myMatrix.push_back(1); + myMatrix.push_back(2), myMatrix.push_back(3); + myMatrix.push_back(4); + myMatrix.push_back(5), myMatrix.push_back(6); + myMatrix.push_back(7); + myMatrix.push_back(8), myMatrix.push_back(8); + } + + std::vector<float> myMatrix2 = {-1, -2, -3, -4, -5, -6, -7, -8, -9}; + + try + { + // Define variable and local size + adios::Variable<double> &ioMyDoubles = + adios.DefineVariable<double>("myDoubles", {Nx}); + adios::Variable<float> &ioMyMatrix = + adios.DefineVariable<float>("myMatrix", {rows, columns}); + adios::Variable<float> &ioMyMatrix2 = + adios.DefineVariable<float>("myMatrix2", {rows, columns}); + + // Define method for engine creation, it is basically straight-forward + // parameters + adios::Method &bpWriterSettings = + adios.DeclareMethod("MyMethod"); // default method type is BPWriter + bpWriterSettings.SetParameters("profile_units=mus"); + bpWriterSettings.AddTransport( + "File", "profile_units=mus", + "have_metadata_file=no"); // uses default POSIX library + + // Create engine smart pointer due to polymorphism, + // Open returns a smart pointer to Engine containing the Derived class + // Writer + auto bpWriter = adios.Open("time.bp", "w", bpWriterSettings); + + if (bpWriter == nullptr) + throw std::ios_base::failure("ERROR: couldn't create bpWriter at Open\n"); + + for (unsigned int t = 0; t < 10; ++t) { - myMatrix.reserve( rows * columns ); - myMatrix.push_back( 1 ); myMatrix.push_back( 2 ), myMatrix.push_back( 3 ); - myMatrix.push_back( 4 ); myMatrix.push_back( 5 ), myMatrix.push_back( 6 ); - myMatrix.push_back( 7 ); myMatrix.push_back( 8 ), myMatrix.push_back( 8 ); + myDoubles[0] = t; + bpWriter->Write<double>( + ioMyDoubles, myDoubles.data()); // Base class Engine own the Write<T> + // that will call overloaded Write + // from Derived + + if (rank % 2 == 0) // even rank + { + myMatrix[0] = t; + myMatrix2[0] = t; + + bpWriter->Write<float>(ioMyMatrix, myMatrix.data()); + bpWriter->Write<float>(ioMyMatrix2, myMatrix2.data()); + } + bpWriter->Advance(); } - std::vector<float> myMatrix2 = { -1, -2, -3, - -4, -5, -6, - -7, -8, -9 }; - - try - { - //Define variable and local size - adios::Variable<double>& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {Nx} ); - adios::Variable<float>& ioMyMatrix = adios.DefineVariable<float>( "myMatrix", {rows,columns} ); - adios::Variable<float>& ioMyMatrix2 = adios.DefineVariable<float>( "myMatrix2", {rows,columns} ); - - //Define method for engine creation, it is basically straight-forward parameters - adios::Method& bpWriterSettings = adios.DeclareMethod( "MyMethod" ); //default method type is BPWriter - bpWriterSettings.SetParameters( "profile_units=mus" ); - bpWriterSettings.AddTransport( "File", "profile_units=mus", "have_metadata_file=no" ); //uses default POSIX library - - //Create engine smart pointer due to polymorphism, - //Open returns a smart pointer to Engine containing the Derived class Writer - auto bpWriter = adios.Open( "time.bp", "w", bpWriterSettings ); - - if( bpWriter == nullptr ) - throw std::ios_base::failure( "ERROR: couldn't create bpWriter at Open\n" ); - - - for( unsigned int t = 0; t < 10; ++t ) - { - myDoubles[0] = t; - bpWriter->Write<double>( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived - - if( rank % 2 == 0 ) //even rank - { - myMatrix[0] = t; - myMatrix2[0] = t; - - bpWriter->Write<float>( ioMyMatrix, myMatrix.data() ); - bpWriter->Write<float>( ioMyMatrix2, myMatrix2.data() ); - } - bpWriter->Advance(); - } - - bpWriter->Close( ); - } - catch( std::invalid_argument& e ) + bpWriter->Close(); + } + catch (std::invalid_argument &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::ios_base::failure& e ) + } + catch (std::ios_base::failure &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } - catch( std::exception& e ) + } + catch (std::exception &e) + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; } + } - MPI_Finalize( ); - - return 0; + MPI_Finalize(); + return 0; } diff --git a/examples/hello/timeBP/timeBPWriter_nompi.cpp b/examples/hello/timeBP/timeBPWriter_nompi.cpp index d85a1b523..c887af83c 100644 --- a/examples/hello/timeBP/timeBPWriter_nompi.cpp +++ b/examples/hello/timeBP/timeBPWriter_nompi.cpp @@ -5,82 +5,89 @@ * Author: wfg */ - -#include <vector> #include <iostream> +#include <vector> #include "ADIOS_CPP.h" - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - const bool adiosDebug = true; - adios::ADIOS adios( adios::Verbose::ERROR, adiosDebug ); - - //Application variable - std::vector<double> myDoubles = { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - const std::size_t Nx = myDoubles.size(); - - const std::size_t rows = 3; - const std::size_t columns = 3; - - std::vector<float> myMatrix; - myMatrix.reserve( rows * columns ); - myMatrix.push_back( 1 ); myMatrix.push_back( 2 ), myMatrix.push_back( 3 ); - myMatrix.push_back( 4 ); myMatrix.push_back( 5 ), myMatrix.push_back( 6 ); - myMatrix.push_back( 7 ); myMatrix.push_back( 8 ), myMatrix.push_back( 8 ); - - - std::vector<float> myMatrix2 = { -1, -2, -3, - -4, -5, -6, - -7, -8, -9 }; - - try + const bool adiosDebug = true; + adios::ADIOS adios(adios::Verbose::ERROR, adiosDebug); + + // Application variable + std::vector<double> myDoubles = {10, 1, 2, 3, 4, 5, 6, 7, 8, 9}; + const std::size_t Nx = myDoubles.size(); + + const std::size_t rows = 3; + const std::size_t columns = 3; + + std::vector<float> myMatrix; + myMatrix.reserve(rows * columns); + myMatrix.push_back(1); + myMatrix.push_back(2), myMatrix.push_back(3); + myMatrix.push_back(4); + myMatrix.push_back(5), myMatrix.push_back(6); + myMatrix.push_back(7); + myMatrix.push_back(8), myMatrix.push_back(8); + + std::vector<float> myMatrix2 = {-1, -2, -3, -4, -5, -6, -7, -8, -9}; + + try + { + // Define variable and local size + adios::Variable<double> &ioMyDoubles = + adios.DefineVariable<double>("myDoubles", {Nx}); + adios::Variable<float> &ioMyMatrix = + adios.DefineVariable<float>("myMatrix", {rows, columns}); + adios::Variable<float> &ioMyMatrix2 = + adios.DefineVariable<float>("myMatrix2", {rows, columns}); + + // Define method for engine creation, it is basically straight-forward + // parameters + adios::Method &bpWriterSettings = + adios.DeclareMethod("SingleFile"); // default method type is BPWriter + bpWriterSettings.SetParameters("profile_units=mus"); + bpWriterSettings.AddTransport( + "File", "profile_units=mus", + "have_metadata_file=no"); // uses default POSIX library + + // Create object directly rather than using polymorphism with ADIOS.Open + adios::BPFileWriter bpWriter(adios, "time_nompi.bp", "w", adios.m_MPIComm, + bpWriterSettings); + + for (unsigned int t = 0; t < 3; ++t) { - //Define variable and local size - adios::Variable<double>& ioMyDoubles = adios.DefineVariable<double>( "myDoubles", {Nx} ); - adios::Variable<float>& ioMyMatrix = adios.DefineVariable<float>( "myMatrix", {rows,columns} ); - adios::Variable<float>& ioMyMatrix2 = adios.DefineVariable<float>( "myMatrix2", {rows,columns} ); - - //Define method for engine creation, it is basically straight-forward parameters - adios::Method& bpWriterSettings = adios.DeclareMethod( "SingleFile" ); //default method type is BPWriter - bpWriterSettings.SetParameters( "profile_units=mus" ); - bpWriterSettings.AddTransport( "File", "profile_units=mus", "have_metadata_file=no" ); //uses default POSIX library - - //Create object directly rather than using polymorphism with ADIOS.Open - adios::BPFileWriter bpWriter( adios, "time_nompi.bp", "w", adios.m_MPIComm, bpWriterSettings ); - - for( unsigned int t = 0; t < 3; ++t ) - { - myDoubles[0] = t; // t * -1; - myMatrix[0] = t; - myMatrix2[0] = t; - - bpWriter.Write( ioMyDoubles, myDoubles.data() ); // Base class Engine own the Write<T> that will call overloaded Write from Derived - bpWriter.Write( ioMyMatrix, myMatrix.data() ); - bpWriter.Write( ioMyMatrix2, myMatrix2.data() ); - bpWriter.Advance(); - } - - bpWriter.Close( ); - } - catch( std::invalid_argument& e ) - { - std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - + myDoubles[0] = t; // t * -1; + myMatrix[0] = t; + myMatrix2[0] = t; + + bpWriter.Write(ioMyDoubles, myDoubles.data()); // Base class Engine own + // the Write<T> that will + // call overloaded Write + // from Derived + bpWriter.Write(ioMyMatrix, myMatrix.data()); + bpWriter.Write(ioMyMatrix2, myMatrix2.data()); + bpWriter.Advance(); } - catch( std::ios_base::failure& e ) - { - std::cout << "System exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - catch( std::exception& e ) - { - std::cout << "Exception, STOPPING PROGRAM\n"; - std::cout << e.what() << "\n"; - } - - return 0; + bpWriter.Close(); + } + catch (std::invalid_argument &e) + { + std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::ios_base::failure &e) + { + std::cout << "System exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + catch (std::exception &e) + { + std::cout << "Exception, STOPPING PROGRAM\n"; + std::cout << e.what() << "\n"; + } + + return 0; } diff --git a/examples/solidfluid/solidfluid_read.cpp b/examples/solidfluid/solidfluid_read.cpp index 9d1a51491..062d165ec 100644 --- a/examples/solidfluid/solidfluid_read.cpp +++ b/examples/solidfluid/solidfluid_read.cpp @@ -5,284 +5,299 @@ * Author: pnorbert */ -#include <stdexcept> -#include <mpi.h> -#include <iostream> #include <fstream> +#include <iostream> +#include <mpi.h> +#include <stdexcept> #include <string> #include <vector> #include "ADIOS_OOP.h" - -struct MYDATA { - int NX; - double *t; - std::vector<double> p; +struct MYDATA +{ + int NX; + double *t; + std::vector<double> p; }; const int N = 10; struct MYDATA solid, fluid; -MPI_Comm comm=MPI_COMM_WORLD; -int rank, size; +MPI_Comm comm = MPI_COMM_WORLD; +int rank, size; -void read_ckpt (adios::ADIOS adios, struct MYDATA &solid, struct MYDATA &fluid) +void read_ckpt(adios::ADIOS adios, struct MYDATA &solid, struct MYDATA &fluid) { - try { - // Open an input which was written with an expected Method - // The write transport is associated with the group in the XML - // ADIOS pairs that with the corresponding read transport - // "r" is required to indicate we are reading - auto ckptfile = adios.Open("checkpoint.bp", "r", comm, "checkpoint"); - // We can also manually set the read transport - //auto ckptfile = adios.Open("checkpoint.bp", adios::READ_METHOD_BP, "r", comm); - - // Note: we only see a single step in the input but the checkpoint has - // only one step anyway. This makes this code simple - - // simple immediate read of a scalar - ckptfile->ReadScalar("solid/NX", &solid.NX); - // solid.NX is filled at this point - - // scheduled version of read of another scalar - // //ckptfile->ScheduleRead ("fluid/NX", &fluid.NX); - // //ckptfile->Read(); // perform reading now - ckptfile->Read("fluid/NX", &fluid.NX); - // fluid.NX is filled at this point - - solid.t = new double(solid.NX); - solid.p = std::vector<double>(solid.NX); - - fluid.t = new double(fluid.NX); - fluid.p = std::vector<double>(fluid.NX); - - adios::ADIOS_SELECTION_WRITEBLOCK sel(rank); - adios.Read (ckptfile, sel, "solid/temperature", solid.t); - adios.Read (ckptfile, sel, "solid/pressure", solid.p); - adios.Read (ckptfile, sel, "fluid/temperature", fluid.t); - // force checking if the allocated space equals to the size of the selection: - adios.Read (ckptfile, sel, "fluid/pressure", fluid.p, fluid.NX*sizeof(double)); - adios.Read(ckptfile, true); // true: blocking read, which is also default - adios.Close(ckptfile); // Should this do Read() if user misses or should we complain? - } - catch ( std::exception& e ) //need to think carefully how to handle C++ exceptions with MPI to avoid deadlocking + try + { + // Open an input which was written with an expected Method + // The write transport is associated with the group in the XML + // ADIOS pairs that with the corresponding read transport + // "r" is required to indicate we are reading + auto ckptfile = adios.Open("checkpoint.bp", "r", comm, "checkpoint"); + // We can also manually set the read transport + // auto ckptfile = adios.Open("checkpoint.bp", adios::READ_METHOD_BP, "r", + // comm); + + // Note: we only see a single step in the input but the checkpoint has + // only one step anyway. This makes this code simple + + // simple immediate read of a scalar + ckptfile->ReadScalar("solid/NX", &solid.NX); + // solid.NX is filled at this point + + // scheduled version of read of another scalar + // //ckptfile->ScheduleRead ("fluid/NX", &fluid.NX); + // //ckptfile->Read(); // perform reading now + ckptfile->Read("fluid/NX", &fluid.NX); + // fluid.NX is filled at this point + + solid.t = new double(solid.NX); + solid.p = std::vector<double>(solid.NX); + + fluid.t = new double(fluid.NX); + fluid.p = std::vector<double>(fluid.NX); + + adios::ADIOS_SELECTION_WRITEBLOCK sel(rank); + adios.Read(ckptfile, sel, "solid/temperature", solid.t); + adios.Read(ckptfile, sel, "solid/pressure", solid.p); + adios.Read(ckptfile, sel, "fluid/temperature", fluid.t); + // force checking if the allocated space equals to the size of the + // selection: + adios.Read(ckptfile, sel, "fluid/pressure", fluid.p, + fluid.NX * sizeof(double)); + adios.Read(ckptfile, true); // true: blocking read, which is also default + adios.Close(ckptfile); // Should this do Read() if user misses or should we + // complain? + } + catch (std::exception &e) // need to think carefully how to handle C++ + // exceptions with MPI to avoid deadlocking + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << e.what() << "\n"; - } + std::cout << e.what() << "\n"; } + } } -void read_solid (adios::ADIOS adios, struct MYDATA &solid) +void read_solid(adios::ADIOS adios, struct MYDATA &solid) { - float timeout_sec = 1.0; - int retval = 0; - - - try { - // Open a file for input, no group defined - // A reading transport should be defined if not file based - // "r" is required to indicate we are reading - int solidfile = adios.Open("solid.bp", "r", comm); //, ADIOS_LOCKMODE_NONE, timeout_sec); - //int solidfile = adios.Open("solid.bp", adios::READ_METHOD_BP, "r", comm); - /* process file here... */ - const adios::ADIOS_VARINFO &v = adios.InqVar (solidfile, "temperature"); - v.GetBlockInfo(); - - printf ("ndim = %d\n", v.ndim); - //printf ("nsteps = %d\n", v.nsteps); - printf ("dims[%" PRIu64 "][%" PRIu64 "]\n", v.dims[0], v.dims[1]); - - uint64_t slice_size = v.dims[0]/size; - - if (rank == size-1) - slice_size = slice_size + v.dims[0]%size; - - start[0] = rank * slice_size; - count[0] = slice_size; - start[1] = 0; - count[1] = v.dims[1]; - - auto data = std::make_unique<double[]>(slice_size * v.dims[1] * 8); - - adios::ADIOS_SELECTION_BOUNDINGBOX sel(v.ndim, start, count); - - /* Processing loop over the steps (we are already in the first one) */ - while (adios_errno != err_end_of_stream) { - steps++; // steps start counting from 1 - - solidfile.ScheduleRead (sel, "temperature", solid.t); - solidfile.Read(true); - - if (rank == 0) - printf ("--------- Step: %d --------------------------------\n", - solidfile.getCurrentStep()); - - printf("rank=%d: [0:%" PRIu64 ",0:%" PRIu64 "] = [", rank, v.dims[0], v.dims[1]); - for (i = 0; i < slice_size; i++) { - printf (" ["); - for (j = 0; j < v.dims[1]; j++) { - printf ("%g ", *((double *)data + i * v.dims[1] + j)); - } - printf ("]"); - } - printf (" ]\n\n"); - - // advance to 1) next available step with 2) blocking wait - solidfile.AdvanceStep (false, timeout_sec); - if (adios_errno == err_step_notready) - { - printf ("rank %d: No new step arrived within the timeout. Quit. %s\n", - rank, adios_errmsg()); - break; // quit while loop - } + float timeout_sec = 1.0; + int retval = 0; - } - solidfile.Close(); + try + { + // Open a file for input, no group defined + // A reading transport should be defined if not file based + // "r" is required to indicate we are reading + int solidfile = adios.Open("solid.bp", "r", + comm); //, ADIOS_LOCKMODE_NONE, timeout_sec); + // int solidfile = adios.Open("solid.bp", adios::READ_METHOD_BP, "r", comm); + /* process file here... */ + const adios::ADIOS_VARINFO &v = adios.InqVar(solidfile, "temperature"); + v.GetBlockInfo(); - } - catch ( std::exception& e ) + printf("ndim = %d\n", v.ndim); + // printf ("nsteps = %d\n", v.nsteps); + printf("dims[%" PRIu64 "][%" PRIu64 "]\n", v.dims[0], v.dims[1]); + + uint64_t slice_size = v.dims[0] / size; + + if (rank == size - 1) + slice_size = slice_size + v.dims[0] % size; + + start[0] = rank * slice_size; + count[0] = slice_size; + start[1] = 0; + count[1] = v.dims[1]; + + auto data = std::make_unique<double[]>(slice_size * v.dims[1] * 8); + + adios::ADIOS_SELECTION_BOUNDINGBOX sel(v.ndim, start, count); + + /* Processing loop over the steps (we are already in the first one) */ + while (adios_errno != err_end_of_stream) { - if (adios_errno == err_file_not_found) - { - printf ("rank %d: Stream not found after waiting %f seconds: %s\n", - rank, timeout_sec, adios_errmsg()); - retval = adios_errno; - } - else if (adios_errno == err_end_of_stream) + steps++; // steps start counting from 1 + + solidfile.ScheduleRead(sel, "temperature", solid.t); + solidfile.Read(true); + + if (rank == 0) + printf("--------- Step: %d --------------------------------\n", + solidfile.getCurrentStep()); + + printf("rank=%d: [0:%" PRIu64 ",0:%" PRIu64 "] = [", rank, v.dims[0], + v.dims[1]); + for (i = 0; i < slice_size; i++) + { + printf(" ["); + for (j = 0; j < v.dims[1]; j++) { - printf ("rank %d: Stream terminated before open. %s\n", rank, adios_errmsg()); - retval = adios_errno; - } - else if (f == NULL) { - printf ("rank %d: Error at opening stream: %s\n", rank, adios_errmsg()); - retval = adios_errno; + printf("%g ", *((double *)data + i * v.dims[1] + j)); } + printf("]"); + } + printf(" ]\n\n"); + + // advance to 1) next available step with 2) blocking wait + solidfile.AdvanceStep(false, timeout_sec); + if (adios_errno == err_step_notready) + { + printf("rank %d: No new step arrived within the timeout. Quit. %s\n", + rank, adios_errmsg()); + break; // quit while loop + } } + solidfile.Close(); + } + catch (std::exception &e) + { + if (adios_errno == err_file_not_found) + { + printf("rank %d: Stream not found after waiting %f seconds: %s\n", rank, + timeout_sec, adios_errmsg()); + retval = adios_errno; + } + else if (adios_errno == err_end_of_stream) + { + printf("rank %d: Stream terminated before open. %s\n", rank, + adios_errmsg()); + retval = adios_errno; + } + else if (f == NULL) + { + printf("rank %d: Error at opening stream: %s\n", rank, adios_errmsg()); + retval = adios_errno; + } + } } -void read_fluid (adios::ADIOS adios, struct MYDATA &fluid) +void read_fluid(adios::ADIOS adios, struct MYDATA &fluid) { - float timeout_sec = 1.0; - int retval = 0; + float timeout_sec = 1.0; + int retval = 0; - // Open a file for input, no group defined - // A reading transport should be defined if not file based - // "r" is required to indicate we are reading - adios::ADIOS_INPUT fluidfile( comm, "r"); - - try { - fluidfile.Open("fluid.bp"); //, ADIOS_LOCKMODE_NONE, timeout_sec); + // Open a file for input, no group defined + // A reading transport should be defined if not file based + // "r" is required to indicate we are reading + adios::ADIOS_INPUT fluidfile(comm, "r"); - /* process file here... */ - const adios::ADIOS_VARINFO &v = fluidfile.InqVar ("temperature"); - v.GetBlockInfo(); + try + { + fluidfile.Open("fluid.bp"); //, ADIOS_LOCKMODE_NONE, timeout_sec); - printf ("ndim = %d\n", v.ndim); - //printf ("nsteps = %d\n", v.nsteps); - printf ("dims[%" PRIu64 "][%" PRIu64 "]\n", v.dims[0], v.dims[1]); + /* process file here... */ + const adios::ADIOS_VARINFO &v = fluidfile.InqVar("temperature"); + v.GetBlockInfo(); - uint64_t slice_size = v.dims[0]/size; + printf("ndim = %d\n", v.ndim); + // printf ("nsteps = %d\n", v.nsteps); + printf("dims[%" PRIu64 "][%" PRIu64 "]\n", v.dims[0], v.dims[1]); - if (rank == size-1) - slice_size = slice_size + v.dims[0]%size; + uint64_t slice_size = v.dims[0] / size; - start[0] = rank * slice_size; - count[0] = slice_size; - start[1] = 0; - count[1] = v.dims[1]; + if (rank == size - 1) + slice_size = slice_size + v.dims[0] % size; - data = malloc (slice_size * v.dims[1] * 8); + start[0] = rank * slice_size; + count[0] = slice_size; + start[1] = 0; + count[1] = v.dims[1]; - adios::ADIOS_SELECTION_BOUNDINGBOX sel(v.ndim, start, count); + data = malloc(slice_size * v.dims[1] * 8); - /* Processing loop over the steps (we are already in the first one) */ - while (adios_errno != err_end_of_stream) { - steps++; // steps start counting from 1 + adios::ADIOS_SELECTION_BOUNDINGBOX sel(v.ndim, start, count); - fluidfile.ScheduleRead (sel, "temperature", fluid.t); - fluidfile.Read(true); - - if (rank == 0) - printf ("--------- Step: %d --------------------------------\n", - fluidfile.getCurrentStep()); + /* Processing loop over the steps (we are already in the first one) */ + while (adios_errno != err_end_of_stream) + { + steps++; // steps start counting from 1 - printf("rank=%d: [0:%" PRIu64 ",0:%" PRIu64 "] = [", rank, v.dims[0], v.dims[1]); - for (i = 0; i < slice_size; i++) { - printf (" ["); - for (j = 0; j < v.dims[1]; j++) { - printf ("%g ", *((double *)data + i * v.dims[1] + j)); - } - printf ("]"); - } - printf (" ]\n\n"); + fluidfile.ScheduleRead(sel, "temperature", fluid.t); + fluidfile.Read(true); - // advance to 1) next available step with 2) blocking wait - fluidfile.AdvanceStep (false, timeout_sec); - if (adios_errno == err_step_notready) - { - printf ("rank %d: No new step arrived within the timeout. Quit. %s\n", - rank, adios_errmsg()); - break; // quit while loop - } + if (rank == 0) + printf("--------- Step: %d --------------------------------\n", + fluidfile.getCurrentStep()); + printf("rank=%d: [0:%" PRIu64 ",0:%" PRIu64 "] = [", rank, v.dims[0], + v.dims[1]); + for (i = 0; i < slice_size; i++) + { + printf(" ["); + for (j = 0; j < v.dims[1]; j++) + { + printf("%g ", *((double *)data + i * v.dims[1] + j)); } - fluidfile.Close(); - + printf("]"); + } + printf(" ]\n\n"); + + // advance to 1) next available step with 2) blocking wait + fluidfile.AdvanceStep(false, timeout_sec); + if (adios_errno == err_step_notready) + { + printf("rank %d: No new step arrived within the timeout. Quit. %s\n", + rank, adios_errmsg()); + break; // quit while loop + } } - catch ( std::exception& e ) + fluidfile.Close(); + } + catch (std::exception &e) + { + if (adios_errno == err_file_not_found) { - if (adios_errno == err_file_not_found) - { - printf ("rank %d: Stream not found after waiting %f seconds: %s\n", - rank, timeout_sec, adios_errmsg()); - retval = adios_errno; - } - else if (adios_errno == err_end_of_stream) - { - printf ("rank %d: Stream terminated before open. %s\n", rank, adios_errmsg()); - retval = adios_errno; - } - else if (f == NULL) { - printf ("rank %d: Error at opening stream: %s\n", rank, adios_errmsg()); - retval = adios_errno; - } + printf("rank %d: Stream not found after waiting %f seconds: %s\n", rank, + timeout_sec, adios_errmsg()); + retval = adios_errno; + } + else if (adios_errno == err_end_of_stream) + { + printf("rank %d: Stream terminated before open. %s\n", rank, + adios_errmsg()); + retval = adios_errno; + } + else if (f == NULL) + { + printf("rank %d: Error at opening stream: %s\n", rank, adios_errmsg()); + retval = adios_errno; } + } } - -int main (int argc, char ** argv) +int main(int argc, char **argv) { - MPI_Init (&argc, &argv); - MPI_Comm_rank (comm, &rank); - MPI_Comm_size (comm, &size); + MPI_Init(&argc, &argv); + MPI_Comm_rank(comm, &rank); + MPI_Comm_size(comm, &size); - try - { - // ADIOS manager object creation. MPI must be initialized - adios::ADIOS adios( "globalArrayXML.xml", comm, true ); + try + { + // ADIOS manager object creation. MPI must be initialized + adios::ADIOS adios("globalArrayXML.xml", comm, true); - read_ckpt(adios, solid, fluid); + read_ckpt(adios, solid, fluid); - read_solid(adios, solid); + read_solid(adios, solid); - read_fluid(adios, fluid); - } - catch( std::exception& e ) //need to think carefully how to handle C++ exceptions with MPI to avoid deadlocking + read_fluid(adios, fluid); + } + catch (std::exception &e) // need to think carefully how to handle C++ + // exceptions with MPI to avoid deadlocking + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << e.what() << "\n"; - } + std::cout << e.what() << "\n"; } - if (rank==0) - printf ("We have processed %d steps\n", steps); - - free (data); - MPI_Finalize (); + } + if (rank == 0) + printf("We have processed %d steps\n", steps); - return retval; + free(data); + MPI_Finalize(); + return retval; } diff --git a/examples/solidfluid/solidfluid_write.cpp b/examples/solidfluid/solidfluid_write.cpp index a5a2d260c..3db4b432b 100644 --- a/examples/solidfluid/solidfluid_write.cpp +++ b/examples/solidfluid/solidfluid_write.cpp @@ -5,9 +5,9 @@ * Author: pnorbert */ -#include <stdexcept> -#include <iostream> #include <fstream> +#include <iostream> +#include <stdexcept> #include <string> #include <vector> @@ -15,204 +15,220 @@ using adiosFile = std::shared_ptr<adios::Engine>; - -struct MYDATA { - int NX; - double *t; - std::vector<double> p; +struct MYDATA +{ + int NX; + double *t; + std::vector<double> p; }; const int N = 10; struct MYDATA solid, fluid; -MPI_Comm comm=MPI_COMM_WORLD; -int rank, size; - +MPI_Comm comm = MPI_COMM_WORLD; +int rank, size; -void write_data( adiosFile writer, struct MYDATA &data ) +void write_data(adiosFile writer, struct MYDATA &data) { - writer->Write("NX", &data.NX); - writer->Write("rank", &rank); - writer->Write("size", &size); - writer->Write("temperature", data.t); - writer->Write("pressure", data.p.data()); - //writer->Flush(); AdvanceStep()??? + writer->Write("NX", &data.NX); + writer->Write("rank", &rank); + writer->Write("size", &size); + writer->Write("temperature", data.t); + writer->Write("pressure", data.p.data()); + // writer->Flush(); AdvanceStep()??? } -void write_checkpoint( adiosFile ckptfile, const struct MYDATA &solid, const struct MYDATA &fluid ) +void write_checkpoint(adiosFile ckptfile, const struct MYDATA &solid, + const struct MYDATA &fluid) { - try - { - ckptfile->Write ("solid/NX", &solid.NX); - ckptfile->Write ("solid/rank", &rank); - ckptfile->Write ("solid/size", &size); - ckptfile->Write ("solid/temperature", solid.t); - ckptfile->Write ("solid/pressure", &solid.p[0]); - - ckptfile->Write ("fluid/NX", &fluid.NX); - ckptfile->Write ("fluid/rank", &rank); - ckptfile->Write ("fluid/size", &size); - ckptfile->Write ("fluid/temperature", fluid.t); - ckptfile->Write ("fluid/pressure", fluid.p.data()); - //ckptfile->AdvanceStep(); ?? - - } - catch ( std::exception& e ) //need to think carefully how to handle C++ exceptions with MPI to avoid deadlocking + try + { + ckptfile->Write("solid/NX", &solid.NX); + ckptfile->Write("solid/rank", &rank); + ckptfile->Write("solid/size", &size); + ckptfile->Write("solid/temperature", solid.t); + ckptfile->Write("solid/pressure", &solid.p[0]); + + ckptfile->Write("fluid/NX", &fluid.NX); + ckptfile->Write("fluid/rank", &rank); + ckptfile->Write("fluid/size", &size); + ckptfile->Write("fluid/temperature", fluid.t); + ckptfile->Write("fluid/pressure", fluid.p.data()); + // ckptfile->AdvanceStep(); ?? + } + catch (std::exception &e) // need to think carefully how to handle C++ + // exceptions with MPI to avoid deadlocking + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "ERROR: caught an exception from write_checkpoint\n"; - std::cout << e.what() << "\n"; - } + std::cout << "ERROR: caught an exception from write_checkpoint\n"; + std::cout << e.what() << "\n"; } + } } -void write_viz (std::shared_ptr<adios::Engine> vizstream, struct MYDATA &solid, struct MYDATA &fluid) +void write_viz(std::shared_ptr<adios::Engine> vizstream, struct MYDATA &solid, + struct MYDATA &fluid) { - // This stream is not associated with a group, so we must say for each write which group to use - // The output variable is re-defined inside as <groupname>/<varname>, unless given as third string argument - // An array variable's dimension definitions are also re-defined with dimensions <groupname>/<dimensionvar> + // This stream is not associated with a group, so we must say for each write + // which group to use + // The output variable is re-defined inside as <groupname>/<varname>, unless + // given as third string argument + // An array variable's dimension definitions are also re-defined with + // dimensions <groupname>/<dimensionvar> - //vizstream->Write ("solid", "NX", &solid.NX); - //vizstream->Write ("solid", "rank", &rank); - //vizstream->Write ("solid", "size", &size); + // vizstream->Write ("solid", "NX", &solid.NX); + // vizstream->Write ("solid", "rank", &rank); + // vizstream->Write ("solid", "size", &size); - // write solid group's temperature simply as temperature, risking overloading the 'temperature' variable when - // reading from a file + // write solid group's temperature simply as temperature, risking overloading + // the 'temperature' variable when + // reading from a file - //vizstream->Write ("solid", "temperature", "my/tempvarinfile", solid.t); + // vizstream->Write ("solid", "temperature", "my/tempvarinfile", solid.t); - //vizstream->Write ("fluid", "NX", &fluid.NX); - //vizstream->Write ("fluid", "rank", &rank); - //vizstream->Write ("fluid", "size", &size); + // vizstream->Write ("fluid", "NX", &fluid.NX); + // vizstream->Write ("fluid", "rank", &rank); + // vizstream->Write ("fluid", "size", &size); - //vizstream->Write ("fluid", "temperature", "temperature", fluid.t); + // vizstream->Write ("fluid", "temperature", "temperature", fluid.t); - //vizstream->Flush(); // flushes all data to disk; required operation - //vizstream.AdvanceStep(); + // vizstream->Flush(); // flushes all data to disk; required operation + // vizstream.AdvanceStep(); } -void compute (int it, struct MYDATA &solid, struct MYDATA &fluid) +void compute(int it, struct MYDATA &solid, struct MYDATA &fluid) { - for (int i = 0; i < solid.NX; i++) - { - solid.t[i] = it*100.0 + rank*solid.NX + i; - solid.p[i] = it*1000.0 + rank*solid.NX + i; - } - for (int i = 0; i < fluid.NX; i++) - { - fluid.t[i] = it*200.0 + rank*fluid.NX + i; - fluid.p[i] = it*2000.0 + rank*fluid.NX + i; - } + for (int i = 0; i < solid.NX; i++) + { + solid.t[i] = it * 100.0 + rank * solid.NX + i; + solid.p[i] = it * 1000.0 + rank * solid.NX + i; + } + for (int i = 0; i < fluid.NX; i++) + { + fluid.t[i] = it * 200.0 + rank * fluid.NX + i; + fluid.p[i] = it * 2000.0 + rank * fluid.NX + i; + } } -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - MPI_Init (&argc, &argv); - MPI_Comm_rank (comm, &rank); - MPI_Comm_size (comm, &size); - - solid.NX = N; - solid.t = new double[N]; - solid.p = std::vector<double>(N); - - fluid.NX = N; - fluid.t = new double[N]; - fluid.p = std::vector<double>(N); - - try + MPI_Init(&argc, &argv); + MPI_Comm_rank(comm, &rank); + MPI_Comm_size(comm, &size); + + solid.NX = N; + solid.t = new double[N]; + solid.p = std::vector<double>(N); + + fluid.NX = N; + fluid.t = new double[N]; + fluid.p = std::vector<double>(N); + + try + { + // ADIOS manager object creation. MPI must be initialized + adios::ADIOS adios(comm, true); + + adios::Method &fileSettings = + adios.DeclareMethod("Reusable"); // default engine is BP writer + fileSettings.AddTransport("POSIX", "have_metadata_file=no"); + + // Open a file with a Method which has selected a group and a transport in + // the XML. + // "a" will append to an already existing file, "w" would create a new file + // Multiple writes to the same file work as append in this application run + // FIXME: how do we support Update to same step? + + auto solidfile = adios.Open("solid.bp", "w", comm, fileSettings); + + // "solid" is a method but incidentally also a group + // Constructor only creates an object and what is needed there but does not + // open a stream/file + // It can be used to initialize a staging connection if not declared before + // FIXME: which argument can be post-poned into Open() instead of + // constructor? + // solidfile.Open("solid.bp"); + + // Open a file with a Method that has selected a group and an engine in the + // XML + // The transport method(s) are (must be) associated with the engines + // "a" will append to an already existing file, "w" would create a new file + // Multiple writes to the same file work as append in this application run + // FIXME: how do we support Update to same step? + auto fluidfile = adios.Open("fluid.bp", "w", comm, fileSettings); + + auto checkpointFile = adios.Open("checkpoint.bp", "w", comm, fileSettings); + + // int ckptfile = adios.Open("checkpoint.bp", "checkpoint", "w", comm); + // we do not open this here, but every time when needed in a function + + // Another output not associated with a single group, so that we can mix + // variables to it + // adios:handle vizstream = adios.Open( "stream.bp", comm, "w", "STAGING", + // "options to staging method"); + auto vizstream = adios.Open("stream.bp", "w", comm, fileSettings); + + // This creates an empty group inside, and we can write all kinds of + // variables to it + + // Get Monitor info + std::ofstream logStream("info_" + std::to_string(rank) + ".log"); + adios.MonitorVariables(logStream); + + int checkPointSteps = 10; + + for (int it = 1; it <= 100; it++) { - // ADIOS manager object creation. MPI must be initialized - adios::ADIOS adios( comm, true ); - - adios::Method& fileSettings = adios.DeclareMethod( "Reusable" ); //default engine is BP writer - fileSettings.AddTransport( "POSIX", "have_metadata_file=no" ); + compute(it, solid, fluid); - // Open a file with a Method which has selected a group and a transport in the XML. - // "a" will append to an already existing file, "w" would create a new file - // Multiple writes to the same file work as append in this application run - // FIXME: how do we support Update to same step? + write_data(solidfile, solid); + write_data(fluidfile, fluid); - auto solidfile = adios.Open( "solid.bp", "w", comm, fileSettings ); + if (it % checkPointSteps == 0) + { + write_checkpoint(checkpointFile, solid, fluid); - - // "solid" is a method but incidentally also a group - // Constructor only creates an object and what is needed there but does not open a stream/file - // It can be used to initialize a staging connection if not declared before - // FIXME: which argument can be post-poned into Open() instead of constructor? - //solidfile.Open("solid.bp"); - - - // Open a file with a Method that has selected a group and an engine in the XML - // The transport method(s) are (must be) associated with the engines - // "a" will append to an already existing file, "w" would create a new file - // Multiple writes to the same file work as append in this application run - // FIXME: how do we support Update to same step? - auto fluidfile = adios.Open("fluid.bp", "w", comm, fileSettings ); - - auto checkpointFile = adios.Open("checkpoint.bp", "w", comm, fileSettings ); - - //int ckptfile = adios.Open("checkpoint.bp", "checkpoint", "w", comm); - // we do not open this here, but every time when needed in a function - - // Another output not associated with a single group, so that we can mix variables to it - //adios:handle vizstream = adios.Open( "stream.bp", comm, "w", "STAGING", "options to staging method"); - auto vizstream = adios.Open("stream.bp", "w", comm, fileSettings ); - - // This creates an empty group inside, and we can write all kinds of variables to it - - //Get Monitor info - std::ofstream logStream( "info_" + std::to_string(rank) + ".log" ); - adios.MonitorVariables( logStream ); - - int checkPointSteps = 10; - - - for (int it = 1; it <= 100; it++) + MPI_Barrier(comm); + if (rank == 0) { - compute (it, solid, fluid); - - write_data( solidfile, solid ); - write_data( fluidfile, fluid ); - - if (it%checkPointSteps == 0) { - write_checkpoint( checkpointFile, solid, fluid ); - - MPI_Barrier( comm ); - if( rank == 0 ) - { - std::cout << "New checkpoint step, current = " << checkPointSteps << "\n"; - std::cin >> checkPointSteps; - MPI_Bcast( &checkPointSteps, 1, MPI_INT, 0, comm ); - } - MPI_Barrier( comm ); - } - - write_viz(vizstream, solid, fluid); - - MPI_Barrier (comm); - if (rank==0) printf("Timestep %d written\n", it); + std::cout << "New checkpoint step, current = " << checkPointSteps + << "\n"; + std::cin >> checkPointSteps; + MPI_Bcast(&checkPointSteps, 1, MPI_INT, 0, comm); } + MPI_Barrier(comm); + } - solidfile->Close(); - fluidfile->Close(); - vizstream->Close(); + write_viz(vizstream, solid, fluid); - // need barrier before we destroy the ADIOS object here automatically - MPI_Barrier (comm); - if (rank==0) printf("Finalize adios\n"); + MPI_Barrier(comm); + if (rank == 0) + printf("Timestep %d written\n", it); } - catch( std::exception& e ) //need to think carefully how to handle C++ exceptions with MPI to avoid deadlocking + + solidfile->Close(); + fluidfile->Close(); + vizstream->Close(); + + // need barrier before we destroy the ADIOS object here automatically + MPI_Barrier(comm); + if (rank == 0) + printf("Finalize adios\n"); + } + catch (std::exception &e) // need to think carefully how to handle C++ + // exceptions with MPI to avoid deadlocking + { + if (rank == 0) { - if( rank == 0 ) - { - std::cout << "ERROR: " << e.what() << "\n"; - } + std::cout << "ERROR: " << e.what() << "\n"; } + } - delete[] solid.t; - delete[] fluid.t; + delete[] solid.t; + delete[] fluid.t; - if (rank==0) printf("Finalize MPI\n"); - MPI_Finalize (); - return 0; + if (rank == 0) + printf("Finalize MPI\n"); + MPI_Finalize(); + return 0; } diff --git a/examples/solidfluid/solidfluid_write_nompi.cpp b/examples/solidfluid/solidfluid_write_nompi.cpp index ec450fd9a..e2df6f251 100644 --- a/examples/solidfluid/solidfluid_write_nompi.cpp +++ b/examples/solidfluid/solidfluid_write_nompi.cpp @@ -5,9 +5,9 @@ * Author: pnorbert */ -#include <stdexcept> -#include <iostream> #include <fstream> +#include <iostream> +#include <stdexcept> #include <string> #include <vector> @@ -15,203 +15,213 @@ using adiosFile = std::shared_ptr<adios::Engine>; - -struct MYDATA { - int NX; - double *t; - std::vector<double> p; +struct MYDATA +{ + int NX; + double *t; + std::vector<double> p; }; const int N = 10; struct MYDATA solid, fluid; -int rank = 0, size = 1; +int rank = 0, size = 1; - -void set_io_variables( adios::ADIOS& adios, const std::string process ) +void set_io_variables(adios::ADIOS &adios, const std::string process) { - adios.DefineVariable<int>( process + "/NX" ); - adios.DefineVariable<int>( process + "/rank" ); - adios.DefineVariable<int>( process + "/size" ); - adios.DefineVariable<double>( process + "/temperature", adios::Dims{N} ); - adios.DefineVariable<double>( process + "/pressure", adios::Dims{N} ); + adios.DefineVariable<int>(process + "/NX"); + adios.DefineVariable<int>(process + "/rank"); + adios.DefineVariable<int>(process + "/size"); + adios.DefineVariable<double>(process + "/temperature", adios::Dims{N}); + adios.DefineVariable<double>(process + "/pressure", adios::Dims{N}); } - -void write_data( adiosFile writer, const std::string process, struct MYDATA &data) +void write_data(adiosFile writer, const std::string process, + struct MYDATA &data) { - writer->Write( process + "/NX", &data.NX); - writer->Write( process + "/rank", &rank); - writer->Write( process + "/size", &size); - writer->Write( process + "/temperature", data.t ); - writer->Write( process + "/pressure", data.p.data()); - //writer->Flush(); AdvanceStep()??? + writer->Write(process + "/NX", &data.NX); + writer->Write(process + "/rank", &rank); + writer->Write(process + "/size", &size); + writer->Write(process + "/temperature", data.t); + writer->Write(process + "/pressure", data.p.data()); + // writer->Flush(); AdvanceStep()??? } - -void write_checkpoint( adiosFile ckptfile, const struct MYDATA &solid, const struct MYDATA &fluid ) +void write_checkpoint(adiosFile ckptfile, const struct MYDATA &solid, + const struct MYDATA &fluid) { - try + try + { + ckptfile->Write("solid/NX", &solid.NX); + ckptfile->Write("solid/rank", &rank); + ckptfile->Write("solid/size", &size); + ckptfile->Write("solid/temperature", solid.t); + ckptfile->Write("solid/pressure", &solid.p[0]); + + ckptfile->Write("fluid/NX", &fluid.NX); + ckptfile->Write("fluid/rank", &rank); + ckptfile->Write("fluid/size", &size); + ckptfile->Write("fluid/temperature", fluid.t); + ckptfile->Write("fluid/pressure", fluid.p.data()); + // ckptfile->AdvanceStep(); ?? + } + catch (std::exception &e) // need to think carefully how to handle C++ + // exceptions with MPI to avoid deadlocking + { + if (rank == 0) { - ckptfile->Write ("solid/NX", &solid.NX); - ckptfile->Write ("solid/rank", &rank); - ckptfile->Write ("solid/size", &size); - ckptfile->Write ("solid/temperature", solid.t); - ckptfile->Write ("solid/pressure", &solid.p[0]); - - ckptfile->Write ("fluid/NX", &fluid.NX); - ckptfile->Write ("fluid/rank", &rank); - ckptfile->Write ("fluid/size", &size); - ckptfile->Write ("fluid/temperature", fluid.t); - ckptfile->Write ("fluid/pressure", fluid.p.data()); - //ckptfile->AdvanceStep(); ?? - - } - catch ( std::exception& e ) //need to think carefully how to handle C++ exceptions with MPI to avoid deadlocking - { - if( rank == 0 ) - { - std::cout << "ERROR: caught an exception from write_checkpoint\n"; - std::cout << e.what() << "\n"; - } + std::cout << "ERROR: caught an exception from write_checkpoint\n"; + std::cout << e.what() << "\n"; } + } } -void write_viz( adiosFile vizstream, struct MYDATA &solid, struct MYDATA &fluid ) +void write_viz(adiosFile vizstream, struct MYDATA &solid, struct MYDATA &fluid) { - // This stream is not associated with a group, so we must say for each write which group to use - // The output variable is re-defined inside as <groupname>/<varname>, unless given as third string argument - // An array variable's dimension definitions are also re-defined with dimensions <groupname>/<dimensionvar> + // This stream is not associated with a group, so we must say for each write + // which group to use + // The output variable is re-defined inside as <groupname>/<varname>, unless + // given as third string argument + // An array variable's dimension definitions are also re-defined with + // dimensions <groupname>/<dimensionvar> - //vizstream->Write ("solid", "NX", &solid.NX); - //vizstream->Write ("solid", "rank", &rank); - //vizstream->Write ("solid", "size", &size); + // vizstream->Write ("solid", "NX", &solid.NX); + // vizstream->Write ("solid", "rank", &rank); + // vizstream->Write ("solid", "size", &size); - // write solid group's temperature simply as temperature, risking overloading the 'temperature' variable when - // reading from a file + // write solid group's temperature simply as temperature, risking overloading + // the 'temperature' variable when + // reading from a file - //vizstream->Write ("solid", "temperature", "my/tempvarinfile", solid.t); + // vizstream->Write ("solid", "temperature", "my/tempvarinfile", solid.t); - //vizstream->Write ("fluid", "NX", &fluid.NX); - //vizstream->Write ("fluid", "rank", &rank); - //vizstream->Write ("fluid", "size", &size); + // vizstream->Write ("fluid", "NX", &fluid.NX); + // vizstream->Write ("fluid", "rank", &rank); + // vizstream->Write ("fluid", "size", &size); - //vizstream->Write ("fluid", "temperature", "temperature", fluid.t); + // vizstream->Write ("fluid", "temperature", "temperature", fluid.t); - //vizstream->Flush(); // flushes all data to disk; required operation - //vizstream.AdvanceStep(); + // vizstream->Flush(); // flushes all data to disk; required operation + // vizstream.AdvanceStep(); } -void compute (int it, struct MYDATA &solid, struct MYDATA &fluid) +void compute(int it, struct MYDATA &solid, struct MYDATA &fluid) { - for (int i = 0; i < solid.NX; i++) - { - solid.t[i] = it*100.0 + rank*solid.NX + i; - solid.p[i] = it*1000.0 + rank*solid.NX + i; - } - for (int i = 0; i < fluid.NX; i++) - { - fluid.t[i] = it*200.0 + rank*fluid.NX + i; - fluid.p[i] = it*2000.0 + rank*fluid.NX + i; - } + for (int i = 0; i < solid.NX; i++) + { + solid.t[i] = it * 100.0 + rank * solid.NX + i; + solid.p[i] = it * 1000.0 + rank * solid.NX + i; + } + for (int i = 0; i < fluid.NX; i++) + { + fluid.t[i] = it * 200.0 + rank * fluid.NX + i; + fluid.p[i] = it * 2000.0 + rank * fluid.NX + i; + } } -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - solid.NX = N; - solid.t = new double[N]; - solid.p = std::vector<double>(N); - - fluid.NX = N; - fluid.t = new double[N]; - fluid.p = std::vector<double>(N); - - try + solid.NX = N; + solid.t = new double[N]; + solid.p = std::vector<double>(N); + + fluid.NX = N; + fluid.t = new double[N]; + fluid.p = std::vector<double>(N); + + try + { + // ADIOS manager object creation. MPI must be initialized + adios::ADIOS adios(true); + set_io_variables(adios, "solid"); + set_io_variables(adios, "fluid"); + + adios::Method &fileSettings = + adios.DeclareMethod("Reusable"); // default engine is BP writer + fileSettings.AddTransport("POSIX", "have_metadata_file=no"); + + // Open a file with a Method which has selected a group and a transport in + // the XML. + // "a" will append to an already existing file, "w" would create a new file + // Multiple writes to the same file work as append in this application run + // FIXME: how do we support Update to same step? + + auto solidfile = adios.Open("solid.bp", "w", fileSettings); + + // "solid" is a method but incidentally also a group + // Constructor only creates an object and what is needed there but does not + // open a stream/file + // It can be used to initialize a staging connection if not declared before + // FIXME: which argument can be post-poned into Open() instead of + // constructor? + // solidfile.Open("solid.bp"); + + // Open a file with a Method that has selected a group and an engine in the + // XML + // The transport method(s) are (must be) associated with the engines + // "a" will append to an already existing file, "w" would create a new file + // Multiple writes to the same file work as append in this application run + // FIXME: how do we support Update to same step? + auto fluidfile = adios.Open("fluid.bp", "w", fileSettings); + + auto checkpointFile = adios.Open("checkpoint.bp", "w", fileSettings); + + // int ckptfile = adios.Open("checkpoint.bp", "checkpoint", "w", comm); + // we do not open this here, but every time when needed in a function + + // Another output not associated with a single group, so that we can mix + // variables to it + // adios:handle vizstream = adios.Open( "stream.bp", comm, "w", "STAGING", + // "options to staging method"); + auto vizstream = adios.Open("stream.bp", "w", fileSettings); + + // This creates an empty group inside, and we can write all kinds of + // variables to it + + // Get Monitor info + std::ofstream logStream("info_nompi.log"); + adios.MonitorVariables(logStream); + + int checkPointSteps = 10; + + for (int it = 1; it <= 100; it++) { - // ADIOS manager object creation. MPI must be initialized - adios::ADIOS adios( true ); - set_io_variables( adios, "solid" ); - set_io_variables( adios, "fluid" ); - - adios::Method& fileSettings = adios.DeclareMethod( "Reusable" ); //default engine is BP writer - fileSettings.AddTransport( "POSIX", "have_metadata_file=no" ); + compute(it, solid, fluid); - // Open a file with a Method which has selected a group and a transport in the XML. - // "a" will append to an already existing file, "w" would create a new file - // Multiple writes to the same file work as append in this application run - // FIXME: how do we support Update to same step? + write_data(solidfile, "solid", solid); + write_data(fluidfile, "fluid", fluid); - auto solidfile = adios.Open( "solid.bp", "w", fileSettings ); + if (it % checkPointSteps == 0) + { + write_checkpoint(checkpointFile, solid, fluid); - - // "solid" is a method but incidentally also a group - // Constructor only creates an object and what is needed there but does not open a stream/file - // It can be used to initialize a staging connection if not declared before - // FIXME: which argument can be post-poned into Open() instead of constructor? - //solidfile.Open("solid.bp"); - - - // Open a file with a Method that has selected a group and an engine in the XML - // The transport method(s) are (must be) associated with the engines - // "a" will append to an already existing file, "w" would create a new file - // Multiple writes to the same file work as append in this application run - // FIXME: how do we support Update to same step? - auto fluidfile = adios.Open("fluid.bp", "w", fileSettings ); - - auto checkpointFile = adios.Open("checkpoint.bp", "w", fileSettings ); - - //int ckptfile = adios.Open("checkpoint.bp", "checkpoint", "w", comm); - // we do not open this here, but every time when needed in a function - - // Another output not associated with a single group, so that we can mix variables to it - //adios:handle vizstream = adios.Open( "stream.bp", comm, "w", "STAGING", "options to staging method"); - auto vizstream = adios.Open("stream.bp", "w", fileSettings ); - - // This creates an empty group inside, and we can write all kinds of variables to it - - //Get Monitor info - std::ofstream logStream( "info_nompi.log" ); - adios.MonitorVariables( logStream ); - - int checkPointSteps = 10; - - - for (int it = 1; it <= 100; it++) { - compute (it, solid, fluid); - - write_data( solidfile, "solid", solid ); - write_data( fluidfile, "fluid", fluid ); - - if (it%checkPointSteps == 0) { - write_checkpoint( checkpointFile, solid, fluid ); - - { - std::cout << "New checkpoint step, current = " << checkPointSteps << "\n"; - std::cin >> checkPointSteps; - } - - } - - write_viz(vizstream, solid, fluid); - - std::cout << "Timestep " << it << " written\n"; + std::cout << "New checkpoint step, current = " << checkPointSteps + << "\n"; + std::cin >> checkPointSteps; } + } - solidfile->Close(); - fluidfile->Close(); - vizstream->Close(); - checkpointFile->Close(); + write_viz(vizstream, solid, fluid); - // need barrier before we destroy the ADIOS object here automatically ...no! - std::cout << "Finalize adios\n"; - } - catch( std::exception& e ) //need to think carefully how to handle C++ exceptions with MPI to avoid deadlocking - { - std::cout << e.what() << "\n"; + std::cout << "Timestep " << it << " written\n"; } - delete[] solid.t; - delete[] fluid.t; + solidfile->Close(); + fluidfile->Close(); + vizstream->Close(); + checkpointFile->Close(); + + // need barrier before we destroy the ADIOS object here automatically ...no! + std::cout << "Finalize adios\n"; + } + catch (std::exception &e) // need to think carefully how to handle C++ + // exceptions with MPI to avoid deadlocking + { + std::cout << e.what() << "\n"; + } + + delete[] solid.t; + delete[] fluid.t; - return 0; + return 0; } diff --git a/examples/xmlParser/xmlParser.cpp b/examples/xmlParser/xmlParser.cpp index aa1ef1083..fc7354420 100644 --- a/examples/xmlParser/xmlParser.cpp +++ b/examples/xmlParser/xmlParser.cpp @@ -5,61 +5,57 @@ * Author: wfg */ -#include <stdexcept> #include <iostream> +#include <stdexcept> #include <string> #include "../../include/ADIOS.h" #ifdef HAVE_MPI - #include <mpi.h> +#include <mpi.h> #else - #include "../../include/mpidummy.h" - using namespace adios; +#include "../../include/mpidummy.h" +using namespace adios; #endif +static void Usage(); -static void Usage( ); - - -int main( int argc, char* argv [] ) +int main(int argc, char *argv[]) { - MPI_Init( &argc, &argv ); - int rank; - MPI_Comm_rank( MPI_COMM_WORLD, &rank ); + MPI_Init(&argc, &argv); + int rank; + MPI_Comm_rank(MPI_COMM_WORLD, &rank); - try + try + { + if (argc != 2) { - if( argc != 2 ) - { - Usage( ); - } - else - { - const std::string xmlConfigFile( argv[1] ); - adios::ADIOS adios( xmlConfigFile, MPI_COMM_WORLD, true ); - adios.MonitorGroups( std::cout ); - } + Usage(); } - catch( std::exception& e ) + else { - if( rank == 0 ) - { - std::cout << "ERROR: exception caught\n"; - std::cout << e.what() << "\n"; - } + const std::string xmlConfigFile(argv[1]); + adios::ADIOS adios(xmlConfigFile, MPI_COMM_WORLD, true); + adios.MonitorGroups(std::cout); } + } + catch (std::exception &e) + { + if (rank == 0) + { + std::cout << "ERROR: exception caught\n"; + std::cout << e.what() << "\n"; + } + } - MPI_Finalize( ); - return 0; + MPI_Finalize(); + return 0; } - -static void Usage( ) +static void Usage() { - std::cout << "Program to test XML Config file parsing\n"; - std::cout << "Usage: \n"; - std::cout << "\t MPI version: ./xmlParser_mpi xmlConfigFile\n"; - std::cout << "\t Non-MPI version: ./xmlParser_nompi xmlConfigFile\n"; + std::cout << "Program to test XML Config file parsing\n"; + std::cout << "Usage: \n"; + std::cout << "\t MPI version: ./xmlParser_mpi xmlConfigFile\n"; + std::cout << "\t Non-MPI version: ./xmlParser_nompi xmlConfigFile\n"; } - diff --git a/include/ADIOS.h b/include/ADIOS.h index 3009c3eb4..fdace75ad 100644 --- a/include/ADIOS.h +++ b/include/ADIOS.h @@ -9,30 +9,29 @@ #define ADIOS_H_ /// \cond EXCLUDE_FROM_DOXYGEN -#include <string> -#include <vector> +#include <complex> +#include <map> #include <memory> //std::shared_ptr #include <ostream> #include <set> -#include <map> -#include <complex> +#include <string> +#include <vector> /// \endcond #ifdef ADIOS_NOMPI - #include "mpidummy.h" +#include "mpidummy.h" #else - #include <mpi.h> +#include <mpi.h> #endif #include "ADIOSTypes.h" +#include "core/Method.h" +#include "core/Support.h" #include "core/Transform.h" #include "core/Variable.h" #include "core/VariableCompound.h" -#include "core/Method.h" -#include "core/Support.h" #include "functions/adiosTemplates.h" - namespace adios { @@ -44,522 +43,640 @@ class Engine; class ADIOS { -public: // PUBLIC Constructors and Functions define the User Interface with ADIOS - - MPI_Comm m_MPIComm = MPI_COMM_SELF; ///< only used as reference to MPI communicator passed from parallel constructor, MPI_Comm is a pointer itself. Public as called from C - - int m_RankMPI = 0; ///< current MPI rank process - int m_SizeMPI = 1; ///< current MPI processes size - - std::string m_HostLanguage = "C++"; - - /** - * @brief ADIOS empty constructor. Used for non XML config file API calls. - */ - ADIOS( const Verbose verbose = Verbose::WARN, const bool debugMode = false ); - - - /** - * @brief Serial constructor for config file, only allowed and compiled in libadios_nompi.a - * @param configFileName passed to m_ConfigFile - * @param debugMode true: on throws exceptions and do additional checks, false: off (faster, but unsafe) - */ - ADIOS( const std::string configFileName, const Verbose verbose = Verbose::WARN, const bool debugMode = false ); - - /** - * @brief Parallel constructor for XML config file and MPI - * @param configFileName passed to m_XMLConfigFile - * @param mpiComm MPI communicator ...const to be discussed - * @param debugMode true: on, false: off (faster, but unsafe) - */ - - ADIOS( const std::string configFileName, MPI_Comm mpiComm, const Verbose verbose = Verbose::WARN, const bool debugMode = false ); - - - /** - * @brief Parallel MPI communicator without XML config file - * @param mpiComm MPI communicator passed to m_MPIComm* - * @param debugMode true: on, false: off (faster) - */ - ADIOS( MPI_Comm mpiComm, const Verbose verbose = Verbose::WARN, const bool debugMode = false ); - - - - ~ADIOS( ); ///< empty, using STL containers for memory management - - void InitMPI( ); ///< sets rank and size in m_rank and m_Size, respectively. - - /** - * Look for template specialization - * @param name - * @param dimensions - * @param globalDimensions - * @param globalOffsets - * @return - */ - template<class T> inline - Variable<T>& DefineVariable( const std::string name, const Dims dimensions = Dims{1}, - const Dims globalDimensions = Dims( ), - const Dims globalOffsets = Dims() ) - { - throw std::invalid_argument( "ERROR: type not supported for variable " + name + " in call to DefineVariable\n" ); - } - - template<class T> inline - Variable<T>& GetVariable( const std::string name ) - { - throw std::invalid_argument( "ERROR: type not supported for variable " + name + " in call to GetVariable\n" ); - } - - - template<class T> - VariableCompound& DefineVariableCompound( const std::string name, const Dims dimensions = Dims{1}, - const Dims globalDimensions = Dims(), - const Dims globalOffsets = Dims() ) - { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_Compound.size(); - m_Compound.emplace( size, VariableCompound( name, sizeof(T), dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<T>(), size ) ); - return m_Compound.at( size ); - } - - VariableCompound& GetVariableCompound( const std::string name ); - - - /** - * Declares a new method. If the method is defined in the user config file, - * it will be already created during processing the config file, - * the method is set up with the user settings and this function just returns that method. - * Otherwise it will create and return a new Method with default settings. - * Use method.isUserDefined() to distinguish between the two cases. - * @param methodName must be unique - */ - Method& DeclareMethod( const std::string methodName ); - - - /** - * @brief Open to Write, Read. Creates a new engine from previously defined method - * @param streamName unique stream or file name - * @param accessMode "w" or "write", "r" or "read", "a" or "append", "u" or "update" - * @param mpiComm option to modify communicator from ADIOS class constructor - * @param method looks for corresponding Method object in ADIOS to initialize the engine - * @param iomode Independent or collective open/advance by writers/readers? Write() operations are always independent. - * @param timeout_sec Wait some time before reporting on missing stream (i.e. wait for it for a while) - * @return Derived class of base Engine depending on Method parameters, shared_ptr for potential flexibility - */ - std::shared_ptr<Engine> Open( const std::string streamName, const std::string accessMode, MPI_Comm mpiComm, - const Method& method, const IOMode iomode = IOMode::INDEPENDENT, const float timeout_sec = 0.0 ); - - /** - * @brief Open to Write, Read. Creates a new engine from previously defined method. - * Reuses MPI communicator from ADIOS constructor. - * @param streamName unique stream or file name - * @param accessMode "w" or "write", "r" or "read", "a" or "append", "u" or "update" - * @param method contains engine parameters - * @param iomode Independent or collective open/advance by writers/readers? Write() operations are always independent. - * @param timeout_sec Wait some time before reporting on missing stream (i.e. wait for it for a while) - * @return Derived class of base Engine depending on Method parameters, shared_ptr for potential flexibility - */ - std::shared_ptr<Engine> Open( const std::string streamName, const std::string accessMode, - const Method& method, const IOMode iomode = IOMode::INDEPENDENT, const float timeout_sec = 0.0 ); - - - /** - * Version required by the XML config file implementation, searches method inside ADIOS through a unique name - * @param streamName unique stream or file name - * @param accessMode "w" or "write", "r" or "read", "a" or "append" - * @param mpiComm mpi Communicator - * @param methodName used to search method object inside ADIOS object - * @param iomode Independent or collective open/advance by writers/readers? Write() operations are always independent. - * @param timeout_sec Wait some time before reporting on missing stream (i.e. wait for it for a while) - * @return Derived class of base Engine depending on Method parameters, shared_ptr for potential flexibility - */ - std::shared_ptr<Engine> Open( const std::string streamName, const std::string accessMode, MPI_Comm mpiComm, - const std::string methodName, const IOMode iomode = IOMode::INDEPENDENT, const float timeout_sec = 0.0 ); - - /** - * Version required by the XML config file implementation, searches method inside ADIOS through a unique name. - * Reuses ADIOS MPI Communicator from constructor. - * @param streamName unique stream or file name - * @param accessMode "w" or "write", "r" or "read", "a" or "append" - * @param methodName used to search method object inside ADIOS object - * @param iomode Independent or collective open/advance by writers/readers? Write() operations are always independent. - * @param timeout_sec Wait some time before reporting on missing stream (i.e. wait for it for a while) - * @return Derived class of base Engine depending on Method parameters, shared_ptr for potential flexibility - */ - std::shared_ptr<Engine> Open( const std::string streamName, const std::string accessMode, - const std::string methodName, const IOMode iomode = IOMode::INDEPENDENT, - const float timeout_sec = 0.0 ); - - /** - * @brief Open to Read all steps from a file. No streaming, advancing is possible here. All steps in the file - * are immediately available for reading. Creates a new engine from previously defined method. - * @param fileName file name - * @param mpiComm option to modify communicator from ADIOS class constructor - * @param method looks for corresponding Method object in ADIOS to initialize the engine - * @param iomode Independent or collective open/advance by writers/readers? Write() operations are always independent. - * @return Derived class of base Engine depending on Method parameters, shared_ptr for potential flexibility - */ - std::shared_ptr<Engine> OpenFileReader( const std::string fileName, MPI_Comm mpiComm, - const Method& method, const IOMode iomode = IOMode::INDEPENDENT ); - - /** - * @brief Open to Read all steps from a file. No streaming, advancing is possible here. All steps in the file - * are immediately available for reading. Creates a new engine from previously defined method. - * Version required by the XML config file implementation, searches method inside ADIOS through a unique name. - * @param fileName file name - * @param mpiComm option to modify communicator from ADIOS class constructor - * @param methodName used to search method object inside ADIOS object - * @param iomode Independent or collective open/advance by writers/readers? Write() operations are always independent. - * @return Derived class of base Engine depending on Method parameters, shared_ptr for potential flexibility - */ - std::shared_ptr<Engine> OpenFileReader( const std::string fileName, MPI_Comm mpiComm, - const std::string methodName, const IOMode iomode = IOMode::INDEPENDENT ); - - /** - * @brief Dumps groups information to a file stream or standard output. - * Note that either the user closes this fileStream or it's closed at the end. - * @param logStream either std::cout standard output, or a std::ofstream file - */ - void MonitorVariables( std::ostream& logStream ); - - - -protected: //no const to allow default empty and copy constructors - - std::map<unsigned int, Variable<char> > m_Char; - std::map<unsigned int, Variable<unsigned char> > m_UChar; - std::map<unsigned int, Variable<short> > m_Short; - std::map<unsigned int, Variable<unsigned short> > m_UShort; - std::map<unsigned int, Variable<int> > m_Int; - std::map<unsigned int, Variable<unsigned int> > m_UInt; - std::map<unsigned int, Variable<long int> > m_LInt; - std::map<unsigned int, Variable<unsigned long int> > m_ULInt; - std::map<unsigned int, Variable<long long int> > m_LLInt; - std::map<unsigned int, Variable<unsigned long long int> > m_ULLInt; - std::map<unsigned int, Variable<float> > m_Float; - std::map<unsigned int, Variable<double> > m_Double; - std::map<unsigned int, Variable<long double> > m_LDouble; - std::map<unsigned int, Variable<std::complex<float>> > m_CFloat; - std::map<unsigned int, Variable<std::complex<double>> > m_CDouble; - std::map<unsigned int, Variable<std::complex<long double>> > m_CLDouble; - std::map<unsigned int, VariableCompound > m_Compound; - - std::string m_ConfigFile; ///< XML File to be read containing configuration information - bool m_DebugMode = false; ///< if true will do more checks, exceptions, warnings, expect slower code - - //Variables - std::map< std::string, std::pair< std::string, unsigned int > > m_Variables; ///< Makes variable name unique, key: variable name, value: pair.first = type, pair.second = index in corresponding vector of Variable - - std::vector< std::shared_ptr<Transform> > m_Transforms; ///< transforms associated with ADIOS run - - - /** - * @brief List of Methods (engine metadata) defined from either ADIOS XML configuration file or the DeclareMethod function. - * <pre> - * Key: std::string unique method name - * Value: Method class - * </pre> - */ - std::map< std::string, Method > m_Methods; - std::set< std::string > m_EngineNames; ///< set used to check Engine name uniqueness in debug mode - - /** - * @brief Checks for group existence in m_Groups, if failed throws std::invalid_argument exception - * @param itGroup m_Groups iterator, usually from find function - * @param groupName unique name, passed for thrown exception only - * @param hint adds information to thrown exception - */ - void CheckVariableInput( const std::string name, const Dims& dimensions ) const; - - /** - * Checks for variable name, if not found throws an invalid exception - * @param itVariable iterator pointing to the variable name in m_Variables - * @param name variable name - * @param hint message to be thrown for debugging purporses - */ - void CheckVariableName( std::map< std::string, std::pair< std::string, unsigned int > >::const_iterator itVariable, - const std::string name, const std::string hint ) const; - - /** - * @brief Checks for method existence in m_Methods, if failed throws std::invalid_argument exception - * @param itMethod m_Methods iterator, usually from find function - * @param methodName unique name, passed for thrown exception only - * @param hint adds information to thrown exception - */ - void CheckMethod( std::map< std::string, Method >::const_iterator itMethod, - const std::string methodName, const std::string hint ) const; - - template< class T > - unsigned int GetVariableIndex( const std::string name ) - { - auto itVariable = m_Variables.find( name ); - CheckVariableName( itVariable, name, "in call to GetVariable<" + GetType<T>() + ">, or call to GetVariableCompound if <T> = <compound>\n" ); - return itVariable->second.second; - } - +public + : // PUBLIC Constructors and Functions define the User Interface with ADIOS + MPI_Comm m_MPIComm = MPI_COMM_SELF; ///< only used as reference to MPI + ///communicator passed from parallel + ///constructor, MPI_Comm is a pointer + ///itself. Public as called from C + + int m_RankMPI = 0; ///< current MPI rank process + int m_SizeMPI = 1; ///< current MPI processes size + + std::string m_HostLanguage = "C++"; + + /** + * @brief ADIOS empty constructor. Used for non XML config file API calls. + */ + ADIOS(const Verbose verbose = Verbose::WARN, const bool debugMode = false); + + /** + * @brief Serial constructor for config file, only allowed and compiled in + * libadios_nompi.a + * @param configFileName passed to m_ConfigFile + * @param debugMode true: on throws exceptions and do additional checks, + * false: off (faster, but unsafe) + */ + ADIOS(const std::string configFileName, const Verbose verbose = Verbose::WARN, + const bool debugMode = false); + + /** + * @brief Parallel constructor for XML config file and MPI + * @param configFileName passed to m_XMLConfigFile + * @param mpiComm MPI communicator ...const to be discussed + * @param debugMode true: on, false: off (faster, but unsafe) + */ + + ADIOS(const std::string configFileName, MPI_Comm mpiComm, + const Verbose verbose = Verbose::WARN, const bool debugMode = false); + + /** + * @brief Parallel MPI communicator without XML config file + * @param mpiComm MPI communicator passed to m_MPIComm* + * @param debugMode true: on, false: off (faster) + */ + ADIOS(MPI_Comm mpiComm, const Verbose verbose = Verbose::WARN, + const bool debugMode = false); + + ~ADIOS(); ///< empty, using STL containers for memory management + + void InitMPI(); ///< sets rank and size in m_rank and m_Size, respectively. + + /** + * Look for template specialization + * @param name + * @param dimensions + * @param globalDimensions + * @param globalOffsets + * @return + */ + template <class T> + inline Variable<T> &DefineVariable(const std::string name, + const Dims dimensions = Dims{1}, + const Dims globalDimensions = Dims(), + const Dims globalOffsets = Dims()) + { + throw std::invalid_argument("ERROR: type not supported for variable " + + name + " in call to DefineVariable\n"); + } + + template <class T> inline Variable<T> &GetVariable(const std::string name) + { + throw std::invalid_argument("ERROR: type not supported for variable " + + name + " in call to GetVariable\n"); + } + + template <class T> + VariableCompound &DefineVariableCompound(const std::string name, + const Dims dimensions = Dims{1}, + const Dims globalDimensions = Dims(), + const Dims globalOffsets = Dims()) + { + CheckVariableInput(name, dimensions); + const unsigned int size = m_Compound.size(); + m_Compound.emplace(size, VariableCompound(name, sizeof(T), dimensions, + globalDimensions, globalOffsets, + m_DebugMode)); + m_Variables.emplace(name, std::make_pair(GetType<T>(), size)); + return m_Compound.at(size); + } + + VariableCompound &GetVariableCompound(const std::string name); + + /** + * Declares a new method. If the method is defined in the user config file, + * it will be already created during processing the config file, + * the method is set up with the user settings and this function just returns + * that method. + * Otherwise it will create and return a new Method with default settings. + * Use method.isUserDefined() to distinguish between the two cases. + * @param methodName must be unique + */ + Method &DeclareMethod(const std::string methodName); + + /** + * @brief Open to Write, Read. Creates a new engine from previously defined + * method + * @param streamName unique stream or file name + * @param accessMode "w" or "write", "r" or "read", "a" or "append", "u" or + * "update" + * @param mpiComm option to modify communicator from ADIOS class constructor + * @param method looks for corresponding Method object in ADIOS to initialize + * the engine + * @param iomode Independent or collective open/advance by writers/readers? + * Write() operations are always independent. + * @param timeout_sec Wait some time before reporting on missing stream (i.e. + * wait for it for a while) + * @return Derived class of base Engine depending on Method parameters, + * shared_ptr for potential flexibility + */ + std::shared_ptr<Engine> Open(const std::string streamName, + const std::string accessMode, MPI_Comm mpiComm, + const Method &method, + const IOMode iomode = IOMode::INDEPENDENT, + const float timeout_sec = 0.0); + + /** + * @brief Open to Write, Read. Creates a new engine from previously defined + * method. + * Reuses MPI communicator from ADIOS constructor. + * @param streamName unique stream or file name + * @param accessMode "w" or "write", "r" or "read", "a" or "append", "u" or + * "update" + * @param method contains engine parameters + * @param iomode Independent or collective open/advance by writers/readers? + * Write() operations are always independent. + * @param timeout_sec Wait some time before reporting on missing stream (i.e. + * wait for it for a while) + * @return Derived class of base Engine depending on Method parameters, + * shared_ptr for potential flexibility + */ + std::shared_ptr<Engine> Open(const std::string streamName, + const std::string accessMode, + const Method &method, + const IOMode iomode = IOMode::INDEPENDENT, + const float timeout_sec = 0.0); + + /** + * Version required by the XML config file implementation, searches method + * inside ADIOS through a unique name + * @param streamName unique stream or file name + * @param accessMode "w" or "write", "r" or "read", "a" or "append" + * @param mpiComm mpi Communicator + * @param methodName used to search method object inside ADIOS object + * @param iomode Independent or collective open/advance by writers/readers? + * Write() operations are always independent. + * @param timeout_sec Wait some time before reporting on missing stream (i.e. + * wait for it for a while) + * @return Derived class of base Engine depending on Method parameters, + * shared_ptr for potential flexibility + */ + std::shared_ptr<Engine> Open(const std::string streamName, + const std::string accessMode, MPI_Comm mpiComm, + const std::string methodName, + const IOMode iomode = IOMode::INDEPENDENT, + const float timeout_sec = 0.0); + + /** + * Version required by the XML config file implementation, searches method + * inside ADIOS through a unique name. + * Reuses ADIOS MPI Communicator from constructor. + * @param streamName unique stream or file name + * @param accessMode "w" or "write", "r" or "read", "a" or "append" + * @param methodName used to search method object inside ADIOS object + * @param iomode Independent or collective open/advance by writers/readers? + * Write() operations are always independent. + * @param timeout_sec Wait some time before reporting on missing stream (i.e. + * wait for it for a while) + * @return Derived class of base Engine depending on Method parameters, + * shared_ptr for potential flexibility + */ + std::shared_ptr<Engine> Open(const std::string streamName, + const std::string accessMode, + const std::string methodName, + const IOMode iomode = IOMode::INDEPENDENT, + const float timeout_sec = 0.0); + + /** + * @brief Open to Read all steps from a file. No streaming, advancing is + * possible here. All steps in the file + * are immediately available for reading. Creates a new engine from previously + * defined method. + * @param fileName file name + * @param mpiComm option to modify communicator from ADIOS class constructor + * @param method looks for corresponding Method object in ADIOS to initialize + * the engine + * @param iomode Independent or collective open/advance by writers/readers? + * Write() operations are always independent. + * @return Derived class of base Engine depending on Method parameters, + * shared_ptr for potential flexibility + */ + std::shared_ptr<Engine> + OpenFileReader(const std::string fileName, MPI_Comm mpiComm, + const Method &method, + const IOMode iomode = IOMode::INDEPENDENT); + + /** + * @brief Open to Read all steps from a file. No streaming, advancing is + * possible here. All steps in the file + * are immediately available for reading. Creates a new engine from previously + * defined method. + * Version required by the XML config file implementation, searches method + * inside ADIOS through a unique name. + * @param fileName file name + * @param mpiComm option to modify communicator from ADIOS class constructor + * @param methodName used to search method object inside ADIOS object + * @param iomode Independent or collective open/advance by writers/readers? + * Write() operations are always independent. + * @return Derived class of base Engine depending on Method parameters, + * shared_ptr for potential flexibility + */ + std::shared_ptr<Engine> + OpenFileReader(const std::string fileName, MPI_Comm mpiComm, + const std::string methodName, + const IOMode iomode = IOMode::INDEPENDENT); + + /** + * @brief Dumps groups information to a file stream or standard output. + * Note that either the user closes this fileStream or it's closed at the end. + * @param logStream either std::cout standard output, or a std::ofstream file + */ + void MonitorVariables(std::ostream &logStream); + +protected: // no const to allow default empty and copy constructors + std::map<unsigned int, Variable<char>> m_Char; + std::map<unsigned int, Variable<unsigned char>> m_UChar; + std::map<unsigned int, Variable<short>> m_Short; + std::map<unsigned int, Variable<unsigned short>> m_UShort; + std::map<unsigned int, Variable<int>> m_Int; + std::map<unsigned int, Variable<unsigned int>> m_UInt; + std::map<unsigned int, Variable<long int>> m_LInt; + std::map<unsigned int, Variable<unsigned long int>> m_ULInt; + std::map<unsigned int, Variable<long long int>> m_LLInt; + std::map<unsigned int, Variable<unsigned long long int>> m_ULLInt; + std::map<unsigned int, Variable<float>> m_Float; + std::map<unsigned int, Variable<double>> m_Double; + std::map<unsigned int, Variable<long double>> m_LDouble; + std::map<unsigned int, Variable<std::complex<float>>> m_CFloat; + std::map<unsigned int, Variable<std::complex<double>>> m_CDouble; + std::map<unsigned int, Variable<std::complex<long double>>> m_CLDouble; + std::map<unsigned int, VariableCompound> m_Compound; + + std::string m_ConfigFile; ///< XML File to be read containing configuration + ///information + bool m_DebugMode = false; ///< if true will do more checks, exceptions, + ///warnings, expect slower code + + // Variables + std::map<std::string, std::pair<std::string, unsigned int>> + m_Variables; ///< Makes variable name unique, key: variable name, value: + ///pair.first = type, pair.second = index in corresponding + ///vector of Variable + + std::vector<std::shared_ptr<Transform>> + m_Transforms; ///< transforms associated with ADIOS run + + /** + * @brief List of Methods (engine metadata) defined from either ADIOS XML + * configuration file or the DeclareMethod function. + * <pre> + * Key: std::string unique method name + * Value: Method class + * </pre> + */ + std::map<std::string, Method> m_Methods; + std::set<std::string> + m_EngineNames; ///< set used to check Engine name uniqueness in debug mode + + /** + * @brief Checks for group existence in m_Groups, if failed throws + * std::invalid_argument exception + * @param itGroup m_Groups iterator, usually from find function + * @param groupName unique name, passed for thrown exception only + * @param hint adds information to thrown exception + */ + void CheckVariableInput(const std::string name, const Dims &dimensions) const; + + /** + * Checks for variable name, if not found throws an invalid exception + * @param itVariable iterator pointing to the variable name in m_Variables + * @param name variable name + * @param hint message to be thrown for debugging purporses + */ + void CheckVariableName( + std::map<std::string, + std::pair<std::string, unsigned int>>::const_iterator itVariable, + const std::string name, const std::string hint) const; + + /** + * @brief Checks for method existence in m_Methods, if failed throws + * std::invalid_argument exception + * @param itMethod m_Methods iterator, usually from find function + * @param methodName unique name, passed for thrown exception only + * @param hint adds information to thrown exception + */ + void CheckMethod(std::map<std::string, Method>::const_iterator itMethod, + const std::string methodName, const std::string hint) const; + + template <class T> unsigned int GetVariableIndex(const std::string name) + { + auto itVariable = m_Variables.find(name); + CheckVariableName( + itVariable, name, + "in call to GetVariable<" + GetType<T>() + + ">, or call to GetVariableCompound if <T> = <compound>\n"); + return itVariable->second.second; + } }; -//template specializations of DefineVariable: -template<> inline -Variable<char>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +// template specializations of DefineVariable: +template <> +inline Variable<char> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_Char.size(); - m_Char.emplace( size, Variable<char>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<char>(), size ) ); - return m_Char.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_Char.size(); + m_Char.emplace(size, Variable<char>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, std::make_pair(GetType<char>(), size)); + return m_Char.at(size); } - -template<> inline -Variable<unsigned char>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<unsigned char> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_UChar.size(); - m_UChar.emplace( size, Variable<unsigned char>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<unsigned char>(), size ) ); - return m_UChar.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_UChar.size(); + m_UChar.emplace(size, + Variable<unsigned char>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, std::make_pair(GetType<unsigned char>(), size)); + return m_UChar.at(size); } - -template<> inline -Variable<short>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<short> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_Short.size(); - m_Short.emplace( size, Variable<short>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<unsigned char>(), size ) ); - return m_Short.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_Short.size(); + m_Short.emplace(size, Variable<short>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, std::make_pair(GetType<unsigned char>(), size)); + return m_Short.at(size); } - -template<> inline -Variable<unsigned short>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<unsigned short> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_UShort.size(); - m_UShort.emplace( size, Variable<unsigned short>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<unsigned short>(), size ) ); - return m_UShort.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_UShort.size(); + m_UShort.emplace(size, + Variable<unsigned short>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, std::make_pair(GetType<unsigned short>(), size)); + return m_UShort.at(size); } - -template<> inline -Variable<int>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<int> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_Int.size(); - m_Int.emplace( size, Variable<int>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<int>(), size ) ); - return m_Int.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_Int.size(); + m_Int.emplace(size, Variable<int>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, std::make_pair(GetType<int>(), size)); + return m_Int.at(size); } - -template<> inline -Variable<unsigned int>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<unsigned int> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_UInt.size(); - m_UInt.emplace( size, Variable<unsigned int>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<unsigned int>(), size ) ); - return m_UInt.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_UInt.size(); + m_UInt.emplace(size, + Variable<unsigned int>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, std::make_pair(GetType<unsigned int>(), size)); + return m_UInt.at(size); } - -template<> inline -Variable<long int>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<long int> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_LInt.size(); - m_LInt.emplace( size, Variable<long int>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<long int>(), size ) ); - return m_LInt.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_LInt.size(); + m_LInt.emplace(size, Variable<long int>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, std::make_pair(GetType<long int>(), size)); + return m_LInt.at(size); } - -template<> inline -Variable<unsigned long int>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<unsigned long int> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_LInt.size(); - m_ULInt.emplace( size, Variable<unsigned long int>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<unsigned long int>(), size ) ); - return m_ULInt.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_LInt.size(); + m_ULInt.emplace( + size, Variable<unsigned long int>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, std::make_pair(GetType<unsigned long int>(), size)); + return m_ULInt.at(size); } - -template<> inline -Variable<long long int>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<long long int> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_LLInt.size(); - m_LLInt.emplace( size, Variable<long long int>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<long long int>(), size ) ); - return m_LLInt.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_LLInt.size(); + m_LLInt.emplace(size, + Variable<long long int>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, std::make_pair(GetType<long long int>(), size)); + return m_LLInt.at(size); } - -template<> inline -Variable<unsigned long long int>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<unsigned long long int> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_ULLInt.size(); - m_ULLInt.emplace( size, Variable<unsigned long long int>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<unsigned long long int>(), size ) ); - return m_ULLInt.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_ULLInt.size(); + m_ULLInt.emplace( + size, Variable<unsigned long long int>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, + std::make_pair(GetType<unsigned long long int>(), size)); + return m_ULLInt.at(size); } -template<> inline -Variable<float>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<float> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_Float.size(); - m_Float.emplace( size, Variable<float>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<float>(), size ) ); - return m_Float.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_Float.size(); + m_Float.emplace(size, Variable<float>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, std::make_pair(GetType<float>(), size)); + return m_Float.at(size); } - -template<> inline -Variable<double>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<double> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_Double.size(); - m_Double.emplace( size, Variable<double>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<double>(), size ) ); - return m_Double.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_Double.size(); + m_Double.emplace(size, Variable<double>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, std::make_pair(GetType<double>(), size)); + return m_Double.at(size); } - -template<> inline -Variable<long double>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<long double> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_LDouble.size(); - m_LDouble.emplace( size, Variable<long double>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<long double>(), size ) ); - return m_LDouble.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_LDouble.size(); + m_LDouble.emplace(size, + Variable<long double>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, std::make_pair(GetType<long double>(), size)); + return m_LDouble.at(size); } - -template<> inline -Variable<std::complex<float>>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<std::complex<float>> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_CFloat.size(); - m_CFloat.emplace( size, Variable<std::complex<float>>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<std::complex<float>>(), size ) ); - return m_CFloat.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_CFloat.size(); + m_CFloat.emplace( + size, Variable<std::complex<float>>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, + std::make_pair(GetType<std::complex<float>>(), size)); + return m_CFloat.at(size); } - -template<> inline -Variable<std::complex<double>>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<std::complex<double>> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_CDouble.size(); - m_CDouble.emplace( size, Variable<std::complex<double>>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<std::complex<double>>(), size ) ); - return m_CDouble.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_CDouble.size(); + m_CDouble.emplace( + size, Variable<std::complex<double>>(name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace(name, + std::make_pair(GetType<std::complex<double>>(), size)); + return m_CDouble.at(size); } - -template<> inline -Variable<std::complex<long double>>& ADIOS::DefineVariable( const std::string name, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets ) +template <> +inline Variable<std::complex<long double>> & +ADIOS::DefineVariable(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets) { - CheckVariableInput( name, dimensions ); - const unsigned int size = m_CLDouble.size(); - m_CLDouble.emplace( size, Variable<std::complex<long double>>( name, dimensions, globalDimensions, globalOffsets, m_DebugMode ) ); - m_Variables.emplace( name, std::make_pair( GetType<std::complex<long double>>(), size ) ); - return m_CLDouble.at( size ); + CheckVariableInput(name, dimensions); + const unsigned int size = m_CLDouble.size(); + m_CLDouble.emplace(size, Variable<std::complex<long double>>( + name, dimensions, globalDimensions, + globalOffsets, m_DebugMode)); + m_Variables.emplace( + name, std::make_pair(GetType<std::complex<long double>>(), size)); + return m_CLDouble.at(size); } +// Get template specialization +template <> inline Variable<char> &ADIOS::GetVariable(const std::string name) +{ + return m_Char.at(GetVariableIndex<char>(name)); +} -//Get template specialization -template<> inline -Variable<char>& ADIOS::GetVariable( const std::string name ) -{ return m_Char.at( GetVariableIndex<char>(name) ); } - -template<> inline -Variable<unsigned char>& ADIOS::GetVariable( const std::string name ) -{ return m_UChar.at( GetVariableIndex<unsigned char>(name) ); } - -template<> inline -Variable<short>& ADIOS::GetVariable( const std::string name ) -{ return m_Short.at( GetVariableIndex<short>(name) ); } - -template<> inline -Variable<unsigned short>& ADIOS::GetVariable( const std::string name ) -{ return m_UShort.at( GetVariableIndex<unsigned short>(name) ); } +template <> +inline Variable<unsigned char> &ADIOS::GetVariable(const std::string name) +{ + return m_UChar.at(GetVariableIndex<unsigned char>(name)); +} -template<> inline -Variable<int>& ADIOS::GetVariable( const std::string name ) -{ return m_Int.at( GetVariableIndex<int>(name) ); } +template <> inline Variable<short> &ADIOS::GetVariable(const std::string name) +{ + return m_Short.at(GetVariableIndex<short>(name)); +} -template<> inline -Variable<unsigned int>& ADIOS::GetVariable( const std::string name ) -{ return m_UInt.at( GetVariableIndex<unsigned int>(name) ); } +template <> +inline Variable<unsigned short> &ADIOS::GetVariable(const std::string name) +{ + return m_UShort.at(GetVariableIndex<unsigned short>(name)); +} -template<> inline -Variable<long int>& ADIOS::GetVariable( const std::string name ) -{ return m_LInt.at( GetVariableIndex<unsigned int>(name) ); } +template <> inline Variable<int> &ADIOS::GetVariable(const std::string name) +{ + return m_Int.at(GetVariableIndex<int>(name)); +} -template<> inline -Variable<unsigned long int>& ADIOS::GetVariable( const std::string name ) -{ return m_ULInt.at( GetVariableIndex<unsigned long int>(name) ); } +template <> +inline Variable<unsigned int> &ADIOS::GetVariable(const std::string name) +{ + return m_UInt.at(GetVariableIndex<unsigned int>(name)); +} -template<> inline -Variable<long long int>& ADIOS::GetVariable( const std::string name ) -{ return m_LLInt.at( GetVariableIndex<long long int>(name) ); } +template <> +inline Variable<long int> &ADIOS::GetVariable(const std::string name) +{ + return m_LInt.at(GetVariableIndex<unsigned int>(name)); +} -template<> inline -Variable<unsigned long long int>& ADIOS::GetVariable( const std::string name ) -{ return m_ULLInt.at( GetVariableIndex<unsigned long long int>(name) ); } +template <> +inline Variable<unsigned long int> &ADIOS::GetVariable(const std::string name) +{ + return m_ULInt.at(GetVariableIndex<unsigned long int>(name)); +} -template<> inline -Variable<float>& ADIOS::GetVariable( const std::string name ) -{ return m_Float.at( GetVariableIndex<float>(name) ); } +template <> +inline Variable<long long int> &ADIOS::GetVariable(const std::string name) +{ + return m_LLInt.at(GetVariableIndex<long long int>(name)); +} -template<> inline -Variable<double>& ADIOS::GetVariable( const std::string name ) -{ return m_Double.at( GetVariableIndex<double>(name) ); } +template <> +inline Variable<unsigned long long int> & +ADIOS::GetVariable(const std::string name) +{ + return m_ULLInt.at(GetVariableIndex<unsigned long long int>(name)); +} -template<> inline -Variable<long double>& ADIOS::GetVariable( const std::string name ) -{ return m_LDouble.at( GetVariableIndex<long double>(name) ); } +template <> inline Variable<float> &ADIOS::GetVariable(const std::string name) +{ + return m_Float.at(GetVariableIndex<float>(name)); +} -template<> inline -Variable<std::complex<float>>& ADIOS::GetVariable( const std::string name ) -{ return m_CFloat.at( GetVariableIndex<std::complex<float>>(name) ); } +template <> inline Variable<double> &ADIOS::GetVariable(const std::string name) +{ + return m_Double.at(GetVariableIndex<double>(name)); +} -template<> inline -Variable<std::complex<double>>& ADIOS::GetVariable( const std::string name ) -{ return m_CDouble.at( GetVariableIndex<std::complex<double>>(name) ); } +template <> +inline Variable<long double> &ADIOS::GetVariable(const std::string name) +{ + return m_LDouble.at(GetVariableIndex<long double>(name)); +} -template<> inline -Variable<std::complex<long double>>& ADIOS::GetVariable( const std::string name ) -{ return m_CLDouble.at( GetVariableIndex<std::complex<long double>>(name) ); } +template <> +inline Variable<std::complex<float>> &ADIOS::GetVariable(const std::string name) +{ + return m_CFloat.at(GetVariableIndex<std::complex<float>>(name)); +} +template <> +inline Variable<std::complex<double>> & +ADIOS::GetVariable(const std::string name) +{ + return m_CDouble.at(GetVariableIndex<std::complex<double>>(name)); +} -} //end namespace +template <> +inline Variable<std::complex<long double>> & +ADIOS::GetVariable(const std::string name) +{ + return m_CLDouble.at(GetVariableIndex<std::complex<long double>>(name)); +} +} // end namespace #endif /* ADIOS_H_ */ diff --git a/include/ADIOSTypes.h b/include/ADIOSTypes.h index 28761e003..d66faf593 100644 --- a/include/ADIOSTypes.h +++ b/include/ADIOSTypes.h @@ -13,17 +13,27 @@ namespace adios /** Use these values in Dims() when defining variables */ -enum { - VARYING_DIMENSION = -1,//!< VARYING_DIMENSION - LOCAL_VALUE = 0, //!< LOCAL_VALUE - GLOBAL_VALUE = 1 //!< GLOBAL_VALUE +enum +{ + VARYING_DIMENSION = -1, //!< VARYING_DIMENSION + LOCAL_VALUE = 0, //!< LOCAL_VALUE + GLOBAL_VALUE = 1 //!< GLOBAL_VALUE }; -enum class Verbose { ERROR = 0, WARN = 1, INFO = 2, DEBUG = 3 }; - -enum class IOMode { INDEPENDENT = 0, COLLECTIVE = 1 }; +enum class Verbose +{ + ERROR = 0, + WARN = 1, + INFO = 2, + DEBUG = 3 +}; -} //end namespace +enum class IOMode +{ + INDEPENDENT = 0, + COLLECTIVE = 1 +}; +} // end namespace #endif /* ADIOS_TYPES_H_ */ diff --git a/include/ADIOS_C.h b/include/ADIOS_C.h index 43c6c95b9..985d6733f 100644 --- a/include/ADIOS_C.h +++ b/include/ADIOS_C.h @@ -11,39 +11,33 @@ #ifdef ADIOS_NOMPI #define MPI_Comm int #else - #include <mpi.h> +#include <mpi.h> #endif - - typedef void ADIOS; typedef void Method; typedef void Engine; - - #ifdef __cplusplus -extern "C" -{ +extern "C" { #endif /** * ADIOS Init * @param mpicomm MPI communicator from user app */ -void adios_init( MPI_Comm mpiComm ); +void adios_init(MPI_Comm mpiComm); /** * ADIOS Init in debug mode: extra checks * @param mpicomm MPI communicator from user app */ -void adios_init_debug( MPI_Comm mpiComm ); +void adios_init_debug(MPI_Comm mpiComm); /** * Sequential version (nompi) */ -void adios_init_nompi( ); - +void adios_init_nompi(); /** * @@ -52,31 +46,30 @@ void adios_init_nompi( ); * @param mpiComm * @return engine handler */ -int adios_open( const char* fileName, const char* accessMode, MPI_Comm mpiComm ); +int adios_open(const char *fileName, const char *accessMode, MPI_Comm mpiComm); /** * * @param variableName * @param values */ -void adios_write( const char* variableName, const void* values ); +void adios_write(const char *variableName, const void *values); /** * * @param handler */ -void adios_close( const int handler ); - -void adios_finalize( const ADIOS* adiosC ); // deallocate ADIOS pointer - -void adios_monitor_groups( const ADIOS* adiosC ); +void adios_close(const int handler); -void adios_monitor_groups_file( const ADIOS* adiosC, const char* fileName, const char* mode ); +void adios_finalize(const ADIOS *adiosC); // deallocate ADIOS pointer +void adios_monitor_groups(const ADIOS *adiosC); +void adios_monitor_groups_file(const ADIOS *adiosC, const char *fileName, + const char *mode); #ifdef __cplusplus -} //end extern C +} // end extern C #endif #ifdef ADIOS_NOMPI diff --git a/include/ADIOS_CPP.h b/include/ADIOS_CPP.h index 7032eed67..9078d3611 100644 --- a/include/ADIOS_CPP.h +++ b/include/ADIOS_CPP.h @@ -8,21 +8,20 @@ #ifndef ADIOS_CPP_H_ #define ADIOS_CPP_H_ -#include "ADIOSTypes.h" #include "ADIOS.h" +#include "ADIOSTypes.h" #include "core/Method.h" #include "core/Engine.h" #include "core/Transform.h" #include "engine/bp/BPFileWriter.h" -//Will allow to create engines directly (no polymorphism) +// Will allow to create engines directly (no polymorphism) #ifdef HAVE_DATAMAN -#include "engine/dataman/DataManWriter.h" #include "engine/dataman/DataManReader.h" +#include "engine/dataman/DataManWriter.h" #endif #include "transform/BZip2.h" - #endif /* ADIOS_CPP_H_ */ diff --git a/include/capsule/heap/STLVector.h b/include/capsule/heap/STLVector.h index 1ae8ce9f5..440e31179 100644 --- a/include/capsule/heap/STLVector.h +++ b/include/capsule/heap/STLVector.h @@ -12,10 +12,8 @@ #include <vector> /// \endcond - #include "core/Capsule.h" - namespace adios { namespace capsule @@ -28,35 +26,33 @@ class STLVector : public Capsule { public: - - std::vector<char> m_Data; ///< data buffer allocated using the STL in heap memory, default size = 16 Mb - std::vector<char> m_Metadata; ///< metadata buffer allocated using the STL in heap memory, default size = 100 Kb - - /** - * Unique constructor - * @param accessMode read, write or append - * @param rankMPI MPI rank - * @param debugMode true: extra checks, slower - */ - STLVector( const std::string accessMode, const int rankMPI, const bool debugMode = false ); - - ~STLVector( ); - - char* GetData( ); - char* GetMetadata( ); - - std::size_t GetDataSize( ) const; - std::size_t GetMetadataSize( ) const; - - void ResizeData( const std::size_t size ); - void ResizeMetadata( const std::size_t size ); - + std::vector<char> m_Data; ///< data buffer allocated using the STL in heap + ///memory, default size = 16 Mb + std::vector<char> m_Metadata; ///< metadata buffer allocated using the STL in + ///heap memory, default size = 100 Kb + + /** + * Unique constructor + * @param accessMode read, write or append + * @param rankMPI MPI rank + * @param debugMode true: extra checks, slower + */ + STLVector(const std::string accessMode, const int rankMPI, + const bool debugMode = false); + + ~STLVector(); + + char *GetData(); + char *GetMetadata(); + + std::size_t GetDataSize() const; + std::size_t GetMetadataSize() const; + + void ResizeData(const std::size_t size); + void ResizeMetadata(const std::size_t size); }; - -} //end namespace capsule -} //end namespace - - +} // end namespace capsule +} // end namespace #endif /* STLVECTOR_H_ */ diff --git a/include/capsule/shmem/ShmSystemV.h b/include/capsule/shmem/ShmSystemV.h index d13621c17..7766edfbe 100644 --- a/include/capsule/shmem/ShmSystemV.h +++ b/include/capsule/shmem/ShmSystemV.h @@ -2,60 +2,62 @@ #ifndef SHMSYSTEMV_H_ #define SHMSYSTEMV_H_ -#include <sys/types.h> #include <sys/ipc.h> - +#include <sys/types.h> #include "core/Capsule.h" - namespace adios { /** - * Buffer and Metadata are allocated in virtual memory using interprocess communication (IPC) of Unix's System V + * Buffer and Metadata are allocated in virtual memory using interprocess + * communication (IPC) of Unix's System V */ class ShmSystemV : public Capsule { public: - - /** - * Create a Capsule in shared memory using System V shm API - * @param accessMode - * @param pathName used to create the key as a unique identifier - * @param dataSize size of allocated memory segment for data - * @param metadataSize size of allocated memory segment for metadata - * @param debugMode true: extra checks, slower - */ - ShmSystemV( const std::string accessMode, const int rankMPI, const std::string pathName, - const size_t dataSize, const size_t metadataSize, const bool debugMode = false ); - - ~ShmSystemV( ); - - char* GetData( ); ///< return the pointer to the raw data buffer - char* GetMetadata( ); ///< return the pointer to the raw metadata buffer - - std::size_t GetDataSize( ) const; ///< get current data buffer size - std::size_t GetMetadataSize( ) const; ///< get current metadata buffer size - + /** + * Create a Capsule in shared memory using System V shm API + * @param accessMode + * @param pathName used to create the key as a unique identifier + * @param dataSize size of allocated memory segment for data + * @param metadataSize size of allocated memory segment for metadata + * @param debugMode true: extra checks, slower + */ + ShmSystemV(const std::string accessMode, const int rankMPI, + const std::string pathName, const size_t dataSize, + const size_t metadataSize, const bool debugMode = false); + + ~ShmSystemV(); + + char *GetData(); ///< return the pointer to the raw data buffer + char *GetMetadata(); ///< return the pointer to the raw metadata buffer + + std::size_t GetDataSize() const; ///< get current data buffer size + std::size_t GetMetadataSize() const; ///< get current metadata buffer size private: - - char* m_Data = nullptr; ///< reference to a shared memory data buffer created with shmget - const std::size_t m_DataSize; ///< size of the allocated shared memory segment - key_t m_DataKey; ///< key associated with the data buffer, created with ftok - int m_DataShmID; ///< data shared memory buffer id - - char* m_Metadata = nullptr; ///< reference to a shared memory metadata buffer created with shmget - const std::size_t m_MetadataSize; ///< size of the allocated shared memory segment - key_t m_MetadataKey; ///< key associated with the metadata buffer, created with ftok - int m_MetadataShmID; ///< metadata shared memory buffer id - - void CheckShm( ) const; ///< checks if all shared memory allocations are correct, throws std::bad_alloc, called from constructor if debug mode is true + char *m_Data = + nullptr; ///< reference to a shared memory data buffer created with shmget + const std::size_t m_DataSize; ///< size of the allocated shared memory segment + key_t m_DataKey; ///< key associated with the data buffer, created with ftok + int m_DataShmID; ///< data shared memory buffer id + + char *m_Metadata = nullptr; ///< reference to a shared memory metadata buffer + ///created with shmget + const std::size_t + m_MetadataSize; ///< size of the allocated shared memory segment + key_t m_MetadataKey; ///< key associated with the metadata buffer, created + ///with ftok + int m_MetadataShmID; ///< metadata shared memory buffer id + + void CheckShm() const; ///< checks if all shared memory allocations are + ///correct, throws std::bad_alloc, called from + ///constructor if debug mode is true }; -} //end namespace - +} // end namespace #endif /* SHMSYSTEMV_H_ */ diff --git a/include/core/Attribute.h b/include/core/Attribute.h index a35e81bdd..b60cde535 100644 --- a/include/core/Attribute.h +++ b/include/core/Attribute.h @@ -20,13 +20,10 @@ namespace adios */ struct Attribute { - const char TypeID; ///< '0': string, '1': numeric - const std::string Value; ///< information about the attribute + const char TypeID; ///< '0': string, '1': numeric + const std::string Value; ///< information about the attribute }; - -} //end namespace - - +} // end namespace #endif /* ATTRIBUTE_H_ */ diff --git a/include/core/Capsule.h b/include/core/Capsule.h index c04680b02..004d6d9a5 100644 --- a/include/core/Capsule.h +++ b/include/core/Capsule.h @@ -12,7 +12,6 @@ #include <string> /// \endcond - namespace adios { @@ -25,45 +24,45 @@ class Capsule { public: + const std::string m_Type; ///< buffer type + const std::string m_AccessMode; ///< 'w': write, 'r': read, 'a': append - const std::string m_Type; ///< buffer type - const std::string m_AccessMode; ///< 'w': write, 'r': read, 'a': append - - std::size_t m_DataPosition = 0; ///< position in current data buffer (not included data flushed to transports) - std::size_t m_DataAbsolutePosition = 0; ///< includes the data flushed to transports + std::size_t m_DataPosition = 0; ///< position in current data buffer (not + ///included data flushed to transports) + std::size_t m_DataAbsolutePosition = + 0; ///< includes the data flushed to transports - std::size_t m_MetadataPosition = 0; ///< position in metadata buffer + std::size_t m_MetadataPosition = 0; ///< position in metadata buffer - /** - * Base class constructor providing type from derived class and accessMode - * @param type derived class type - * @param accessMode 'w':write, 'r':read, 'a':append - * @param rankMPI current MPI rank - * @param debugMode - */ - Capsule( const std::string type, const std::string accessMode, const int rankMPI, const bool debugMode ); + /** + * Base class constructor providing type from derived class and accessMode + * @param type derived class type + * @param accessMode 'w':write, 'r':read, 'a':append + * @param rankMPI current MPI rank + * @param debugMode + */ + Capsule(const std::string type, const std::string accessMode, + const int rankMPI, const bool debugMode); - virtual ~Capsule( ); + virtual ~Capsule(); - virtual char* GetData( ) = 0; ///< return the pointer to the raw data buffer - virtual char* GetMetadata( ) = 0; ///< return the pointer to the raw metadata buffer + virtual char *GetData() = 0; ///< return the pointer to the raw data buffer + virtual char * + GetMetadata() = 0; ///< return the pointer to the raw metadata buffer - virtual std::size_t GetDataSize( ) const = 0; ///< get current data buffer size - virtual std::size_t GetMetadataSize( ) const = 0; ///< get current metadata buffer size - - virtual void ResizeData( const std::size_t size ); ///< resize data buffer - virtual void ResizeMetadata( const std::size_t size ); ///< resize metadata buffer + virtual std::size_t GetDataSize() const = 0; ///< get current data buffer size + virtual std::size_t + GetMetadataSize() const = 0; ///< get current metadata buffer size + virtual void ResizeData(const std::size_t size); ///< resize data buffer + virtual void + ResizeMetadata(const std::size_t size); ///< resize metadata buffer protected: - - const int m_RankMPI = 0; ///< current MPI rank - const bool m_DebugMode = false; ///< true: extra checks - + const int m_RankMPI = 0; ///< current MPI rank + const bool m_DebugMode = false; ///< true: extra checks }; - - -} //end namespace +} // end namespace #endif /* CAPSULE_H_ */ diff --git a/include/core/Engine.h b/include/core/Engine.h index 7a176b2f4..3e3a900ef 100644 --- a/include/core/Engine.h +++ b/include/core/Engine.h @@ -8,442 +8,496 @@ #ifndef ENGINE_H_ #define ENGINE_H_ - /// \cond EXCLUDE_FROM_DOXYGEN -#include <vector> -#include <string> -#include <memory> //std::shared_ptr +#include <complex> //std::complex #include <map> +#include <memory> //std::shared_ptr +#include <string> #include <utility> //std::pair -#include <complex> //std::complex +#include <vector> /// \endcond #ifdef ADIOS_NOMPI - #include "mpidummy.h" +#include "mpidummy.h" #else - #include <mpi.h> +#include <mpi.h> #endif -#include "ADIOSTypes.h" #include "ADIOS.h" +#include "ADIOSTypes.h" +#include "core/Capsule.h" #include "core/Method.h" -#include "core/Variable.h" -#include "core/VariableCompound.h" +#include "core/Profiler.h" #include "core/Transform.h" #include "core/Transport.h" -#include "core/Capsule.h" -#include "core/Profiler.h" +#include "core/Variable.h" +#include "core/VariableCompound.h" namespace adios { typedef enum { NONBLOCKINGREAD = 0, BLOCKINGREAD = 1 } PerformReadMode; - typedef enum { - APPEND = 0, UPDATE = 1, // writer advance modes - NEXT_AVAILABLE = 2, LATEST_AVAILABLE = 3, // reader advance modes + APPEND = 0, + UPDATE = 1, // writer advance modes + NEXT_AVAILABLE = 2, + LATEST_AVAILABLE = 3, // reader advance modes } AdvanceMode; /** - * Base class for Engine operations managing shared-memory, and buffer and variables transform and transport operations + * Base class for Engine operations managing shared-memory, and buffer and + * variables transform and transport operations */ class Engine { public: - - MPI_Comm m_MPIComm = MPI_COMM_SELF; - - const std::string m_EngineType; ///< from derived class - const std::string m_Name; ///< name used for this engine - const std::string m_AccessMode; ///< accessMode for buffers used by this engine - const Method& m_Method; ///< associated method containing engine metadata - - int m_RankMPI = 0; ///< current MPI rank process - int m_SizeMPI = 1; ///< current MPI processes size - - const std::string m_HostLanguage = "C++"; ///< default host language - - /** - * Unique constructor - * @param adios - * @param engineType - * @param name - * @param accessMode - * @param mpiComm - * @param method - * @param debugMode - * @param nthreads - * @param endMessage - */ - Engine( ADIOS& adios, const std::string engineType, const std::string name, const std::string accessMode, - MPI_Comm mpiComm, const Method& method, const bool debugMode, const unsigned int nthreads, - const std::string endMessage ); - - virtual ~Engine( ); - - - /** @brief Let ADIOS allocate memory for a variable, which can be used by the user. - * - * To decrease the cost of copying memory, a user may let ADIOS allocate the memory for a user-variable, - * according to the definition of an ADIOS-variable. The memory will be part of the ADIOS buffer used - * by the engine and it lives until the engine (file, stream) is closed. - * A variable that has been allocated this way (cannot have its local dimensions changed, and AdvanceAsync() should be - * used instead of Advance() and the user-variable must not be modified by the application until the notification arrives. - * This is required so that any reader can access the written data before the application overwrites it. - * @param var Variable with defined local dimensions and offsets in global space - * @param fillValue Fill the allocated array with this value - * @return A constant pointer to the non-constant allocated array. User should not deallocate this pointer. - */ - template<class T> inline - T * const AllocateVariable( Variable<T>& var, T fillValue = 0 ) - { - throw std::invalid_argument( "ERROR: type not supported for variable " + var->name + " in call to GetVariable\n" ); - } - - /** - * Needed for DataMan Engine - * @param callback function passed from the user - */ - virtual void SetCallBack( std::function<void( const void*, std::string, std::string, std::string, Dims )> callback ); - - /** - * Write function that adds static checking on the variable to be passed by values - * It then calls its corresponding derived class virtual function - * This version uses m_Group to look for the variableName. - * @param variable name of variable to the written - * @param values pointer passed from the application - */ - template< class T > - void Write( Variable<T>& variable, const T* values ) - { - Write( variable, values ); - } - - /** - * String version - * @param variableName - * @param values - */ - template< class T > - void Write( const std::string variableName, const T* values ) - { - Write( variableName, values ); - } - - /** - * Single value version - * @param variable - * @param values - */ - template< class T > - void Write( Variable<T>& variable, const T values ) - { - const T val = values; - Write( variable, &val ); - } - - /** - * Single value version using string as variable handlers, allows rvalues to be passed - * @param variableName - * @param values - */ - template< class T > - void Write( const std::string variableName, const T values ) - { - const T val = values; - Write( variableName, &val ); - } - - virtual void Write( Variable<char>& variable, const char* values ); - virtual void Write( Variable<unsigned char>& variable, const unsigned char* values ); - virtual void Write( Variable<short>& variable, const short* values ); - virtual void Write( Variable<unsigned short>& variable, const unsigned short* values ); - virtual void Write( Variable<int>& variable, const int* values ); - virtual void Write( Variable<unsigned int>& variable, const unsigned int* values ); - virtual void Write( Variable<long int>& variable, const long int* values ); - virtual void Write( Variable<unsigned long int>& variable, const unsigned long int* values ); - virtual void Write( Variable<long long int>& variable, const long long int* values ); - virtual void Write( Variable<unsigned long long int>& variable, const unsigned long long int* values ); - virtual void Write( Variable<float>& variable, const float* values ); - virtual void Write( Variable<double>& variable, const double* values ); - virtual void Write( Variable<long double>& variable, const long double* values ); - virtual void Write( Variable<std::complex<float>>& variable, const std::complex<float>* values ); - virtual void Write( Variable<std::complex<double>>& variable, const std::complex<double>* values ); - virtual void Write( Variable<std::complex<long double>>& variable, const std::complex<long double>* values ); - virtual void Write( VariableCompound& variable, const void* values ); - - - /** - * @brief Write functions can be overridden by derived classes. Base class behavior is to: - * 1) Write to Variable values (m_Values) using the pointer to default group *m_Group set with SetDefaultGroup function - * 2) Transform the data - * 3) Write to all capsules -> data and metadata - * @param variableName - * @param values coming from user app - */ - virtual void Write( const std::string variableName, const char* values ); - virtual void Write( const std::string variableName, const unsigned char* values ); - virtual void Write( const std::string variableName, const short* values ); - virtual void Write( const std::string variableName, const unsigned short* values ); - virtual void Write( const std::string variableName, const int* values ); - virtual void Write( const std::string variableName, const unsigned int* values ); - virtual void Write( const std::string variableName, const long int* values ); - virtual void Write( const std::string variableName, const unsigned long int* values ); - virtual void Write( const std::string variableName, const long long int* values ); - virtual void Write( const std::string variableName, const unsigned long long int* values ); - virtual void Write( const std::string variableName, const float* values ); - virtual void Write( const std::string variableName, const double* values ); - virtual void Write( const std::string variableName, const long double* values ); - virtual void Write( const std::string variableName, const std::complex<float>* values ); - virtual void Write( const std::string variableName, const std::complex<double>* values ); - virtual void Write( const std::string variableName, const std::complex<long double>* values ); - virtual void Write( const std::string variableName, const void* values ); - - /** - * Read function that adds static checking on the variable to be passed by values - * It then calls its corresponding derived class virtual function - * This version uses m_Group to look for the variableName. - * @param variable name of variable to the written - * @param values pointer passed from the application, nullptr not allowed, must use Read(variable) instead intentionally - */ - template< class T > - void Read( Variable<T>& variable, const T* values ) - { - Read( variable, values ); - } - - /** - * String version - * @param variableName - * @param values - */ - template< class T > - void Read( const std::string variableName, const T* values ) - { - Read( variableName, values ); - } - - /** - * Single value version - * @param variable - * @param values - */ - template< class T > - void Read( Variable<T>& variable, const T& values) - { - Read( variable, &values ); - } - - /** - * Single value version using string as variable handlers - * @param variableName - * @param values - */ - template< class T > - void Read( const std::string variableName, const T& values ) - { - Read( variableName, &values ); - } - - /** - * Unallocated version, ADIOS will allocate space for incoming data - * @param variable - */ - template< class T > - void Read( Variable<T>& variable ) - { - Read( variable, nullptr ); - } - - /** - * Unallocated version, ADIOS will allocate space for incoming data - * @param variableName - */ - template< class T > - void Read( const std::string variableName ) - { - Read( variableName, nullptr ); - } - - - virtual void Read( Variable<double>& variable, const double* values ); - - - /** - * Read function that adds static checking on the variable to be passed by values - * It then calls its corresponding derived class virtual function - * This version uses m_Group to look for the variableName. - * @param variable name of variable to the written - * @param values pointer passed from the application - */ - template< class T > - void ScheduleRead( Variable<T>& variable, const T* values ) - { - ScheduleRead( variable, values ); - } - - /** - * String version - * @param variableName - * @param values - */ - template< class T > - void ScheduleRead( const std::string variableName, const T* values ) - { - ScheduleRead( variableName, values ); - } - - /** - * Single value version - * @param variable - * @param values - */ - template< class T > - void ScheduleRead( Variable<T>& variable, const T& values ) - { - ScheduleRead( variable, &values ); - } - - /** - * Single value version using string as variable handlers - * @param variableName - * @param values - */ - template< class T > - void ScheduleRead( const std::string variableName, const T& values ) - { - ScheduleRead( variableName, &values ); - } - - /** - * Unallocated version, ADIOS will allocate space for incoming data - * @param variableName - */ - void ScheduleRead( const std::string variableName ) - { - ScheduleRead( variableName, nullptr ); - } - - /** - * Unallocated unspecified version, ADIOS will receive any variable and will allocate space for incoming data - */ - void ScheduleRead( ) - { - ScheduleRead( nullptr, nullptr ); - } - - virtual void ScheduleRead( Variable<double>& variable, const double* values ); - - /** - * Perform all scheduled reads, either blocking until all reads completed, or return immediately. - * @param mode Blocking or non-blocking modes - */ - void PerformReads( PerformReadMode mode ); - - /** - * Reader application indicates that no more data will be read from the current stream before advancing. - * This is necessary to allow writers to advance as soon as possible. - */ - virtual void Release( ); - - /** - * Indicates that a new step is going to be written as new variables come in. - */ - virtual void Advance( float timeout_sec=0.0 ); - - /** - * Indicates that a new step is going to be written as new variables come in. - * @param mode Advance mode, there are different options for writers and readers - */ - virtual void Advance( AdvanceMode mode, float timeout_sec=0.0 ); - - /** @brief Advance asynchronously and get a callback when readers release access to the buffered step. - * - * User variables that were allocated through AllocateVariable() - * must not be modified until advance is completed. - * @param mode Advance mode, there are different options for writers and readers - * @param callback Will be called when advance is completed. - */ - virtual void AdvanceAsync ( AdvanceMode mode, std::function<void( std::shared_ptr<adios::Engine> )> callback ); - - - //Read API - /** - * Inquires and (optionally) allocates and copies the contents of a variable - * If success: it returns a pointer to the internal stored variable object in ADIOS class. - * If failure: it returns nullptr - * @param name variable name to look for - * @param readIn if true: reads the full variable and payload, allocating values in memory, if false: internal payload is nullptr - * @return success: it returns a pointer to the internal stored variable object in ADIOS class, failure: nullptr - */ - virtual Variable<void>* InquireVariable( const std::string name, const bool readIn = true ); - virtual Variable<char>* InquireVariableChar( const std::string name, const bool readIn = true ); - virtual Variable<unsigned char>* InquireVariableUChar( const std::string name, const bool readIn = true ); - virtual Variable<short>* InquireVariableShort( const std::string name, const bool readIn = true ); - virtual Variable<unsigned short>* InquireVariableUShort( const std::string name, const bool readIn = true ); - virtual Variable<int>* InquireVariableInt( const std::string name, const bool readIn = true ); - virtual Variable<unsigned int>* InquireVariableUInt( const std::string name, const bool readIn = true ); - virtual Variable<long int>* InquireVariableLInt( const std::string name, const bool readIn = true ); - virtual Variable<unsigned long int>* InquireVariableULInt( const std::string name, const bool readIn = true ); - virtual Variable<long long int>* InquireVariableLLInt( const std::string name, const bool readIn = true ); - virtual Variable<unsigned long long int>* InquireVariableULLInt( const std::string name, const bool readIn = true ); - virtual Variable<float>* InquireVariableFloat( const std::string name, const bool readIn = true ); - virtual Variable<double>* InquireVariableDouble( const std::string name, const bool readIn = true ); - virtual Variable<long double>* InquireVariableLDouble( const std::string name, const bool readIn = true ); - virtual Variable<std::complex<float>>* InquireVariableCFloat( const std::string name, const bool readIn = true ); - virtual Variable<std::complex<double>>* InquireVariableCDouble( const std::string name, const bool readIn = true ); - virtual Variable<std::complex<long double>>* InquireVariableCLDouble( const std::string name, const bool readIn = true ); - virtual VariableCompound* InquireVariableCompound( const std::string name, const bool readIn = true ); - - - /** Return the names of all variables present in a stream/file opened for reading - * - * @return a vector of strings - */ - std::vector<std::string> VariableNames(); - - virtual void Close( const int transportIndex = -1 ) = 0; ///< Closes a particular transport, or all if -1 - + MPI_Comm m_MPIComm = MPI_COMM_SELF; + + const std::string m_EngineType; ///< from derived class + const std::string m_Name; ///< name used for this engine + const std::string + m_AccessMode; ///< accessMode for buffers used by this engine + const Method &m_Method; ///< associated method containing engine metadata + + int m_RankMPI = 0; ///< current MPI rank process + int m_SizeMPI = 1; ///< current MPI processes size + + const std::string m_HostLanguage = "C++"; ///< default host language + + /** + * Unique constructor + * @param adios + * @param engineType + * @param name + * @param accessMode + * @param mpiComm + * @param method + * @param debugMode + * @param nthreads + * @param endMessage + */ + Engine(ADIOS &adios, const std::string engineType, const std::string name, + const std::string accessMode, MPI_Comm mpiComm, const Method &method, + const bool debugMode, const unsigned int nthreads, + const std::string endMessage); + + virtual ~Engine(); + + /** @brief Let ADIOS allocate memory for a variable, which can be used by the + * user. + * + * To decrease the cost of copying memory, a user may let ADIOS allocate the + * memory for a user-variable, + * according to the definition of an ADIOS-variable. The memory will be part + * of the ADIOS buffer used + * by the engine and it lives until the engine (file, stream) is closed. + * A variable that has been allocated this way (cannot have its local + * dimensions changed, and AdvanceAsync() should be + * used instead of Advance() and the user-variable must not be modified by the + * application until the notification arrives. + * This is required so that any reader can access the written data before the + * application overwrites it. + * @param var Variable with defined local dimensions and offsets in global + * space + * @param fillValue Fill the allocated array with this value + * @return A constant pointer to the non-constant allocated array. User should + * not deallocate this pointer. + */ + template <class T> + inline T *const AllocateVariable(Variable<T> &var, T fillValue = 0) + { + throw std::invalid_argument("ERROR: type not supported for variable " + + var->name + " in call to GetVariable\n"); + } + + /** + * Needed for DataMan Engine + * @param callback function passed from the user + */ + virtual void SetCallBack(std::function<void(const void *, std::string, + std::string, std::string, Dims)> + callback); + + /** + * Write function that adds static checking on the variable to be passed by + * values + * It then calls its corresponding derived class virtual function + * This version uses m_Group to look for the variableName. + * @param variable name of variable to the written + * @param values pointer passed from the application + */ + template <class T> void Write(Variable<T> &variable, const T *values) + { + Write(variable, values); + } + + /** + * String version + * @param variableName + * @param values + */ + template <class T> void Write(const std::string variableName, const T *values) + { + Write(variableName, values); + } + + /** + * Single value version + * @param variable + * @param values + */ + template <class T> void Write(Variable<T> &variable, const T values) + { + const T val = values; + Write(variable, &val); + } + + /** + * Single value version using string as variable handlers, allows rvalues to + * be passed + * @param variableName + * @param values + */ + template <class T> void Write(const std::string variableName, const T values) + { + const T val = values; + Write(variableName, &val); + } + + virtual void Write(Variable<char> &variable, const char *values); + virtual void Write(Variable<unsigned char> &variable, + const unsigned char *values); + virtual void Write(Variable<short> &variable, const short *values); + virtual void Write(Variable<unsigned short> &variable, + const unsigned short *values); + virtual void Write(Variable<int> &variable, const int *values); + virtual void Write(Variable<unsigned int> &variable, + const unsigned int *values); + virtual void Write(Variable<long int> &variable, const long int *values); + virtual void Write(Variable<unsigned long int> &variable, + const unsigned long int *values); + virtual void Write(Variable<long long int> &variable, + const long long int *values); + virtual void Write(Variable<unsigned long long int> &variable, + const unsigned long long int *values); + virtual void Write(Variable<float> &variable, const float *values); + virtual void Write(Variable<double> &variable, const double *values); + virtual void Write(Variable<long double> &variable, + const long double *values); + virtual void Write(Variable<std::complex<float>> &variable, + const std::complex<float> *values); + virtual void Write(Variable<std::complex<double>> &variable, + const std::complex<double> *values); + virtual void Write(Variable<std::complex<long double>> &variable, + const std::complex<long double> *values); + virtual void Write(VariableCompound &variable, const void *values); + + /** + * @brief Write functions can be overridden by derived classes. Base class + * behavior is to: + * 1) Write to Variable values (m_Values) using the pointer to default group + * *m_Group set with SetDefaultGroup function + * 2) Transform the data + * 3) Write to all capsules -> data and metadata + * @param variableName + * @param values coming from user app + */ + virtual void Write(const std::string variableName, const char *values); + virtual void Write(const std::string variableName, + const unsigned char *values); + virtual void Write(const std::string variableName, const short *values); + virtual void Write(const std::string variableName, + const unsigned short *values); + virtual void Write(const std::string variableName, const int *values); + virtual void Write(const std::string variableName, + const unsigned int *values); + virtual void Write(const std::string variableName, const long int *values); + virtual void Write(const std::string variableName, + const unsigned long int *values); + virtual void Write(const std::string variableName, + const long long int *values); + virtual void Write(const std::string variableName, + const unsigned long long int *values); + virtual void Write(const std::string variableName, const float *values); + virtual void Write(const std::string variableName, const double *values); + virtual void Write(const std::string variableName, const long double *values); + virtual void Write(const std::string variableName, + const std::complex<float> *values); + virtual void Write(const std::string variableName, + const std::complex<double> *values); + virtual void Write(const std::string variableName, + const std::complex<long double> *values); + virtual void Write(const std::string variableName, const void *values); + + /** + * Read function that adds static checking on the variable to be passed by + * values + * It then calls its corresponding derived class virtual function + * This version uses m_Group to look for the variableName. + * @param variable name of variable to the written + * @param values pointer passed from the application, nullptr not allowed, + * must use Read(variable) instead intentionally + */ + template <class T> void Read(Variable<T> &variable, const T *values) + { + Read(variable, values); + } + + /** + * String version + * @param variableName + * @param values + */ + template <class T> void Read(const std::string variableName, const T *values) + { + Read(variableName, values); + } + + /** + * Single value version + * @param variable + * @param values + */ + template <class T> void Read(Variable<T> &variable, const T &values) + { + Read(variable, &values); + } + + /** + * Single value version using string as variable handlers + * @param variableName + * @param values + */ + template <class T> void Read(const std::string variableName, const T &values) + { + Read(variableName, &values); + } + + /** + * Unallocated version, ADIOS will allocate space for incoming data + * @param variable + */ + template <class T> void Read(Variable<T> &variable) + { + Read(variable, nullptr); + } + + /** + * Unallocated version, ADIOS will allocate space for incoming data + * @param variableName + */ + template <class T> void Read(const std::string variableName) + { + Read(variableName, nullptr); + } + + virtual void Read(Variable<double> &variable, const double *values); + + /** + * Read function that adds static checking on the variable to be passed by + * values + * It then calls its corresponding derived class virtual function + * This version uses m_Group to look for the variableName. + * @param variable name of variable to the written + * @param values pointer passed from the application + */ + template <class T> void ScheduleRead(Variable<T> &variable, const T *values) + { + ScheduleRead(variable, values); + } + + /** + * String version + * @param variableName + * @param values + */ + template <class T> + void ScheduleRead(const std::string variableName, const T *values) + { + ScheduleRead(variableName, values); + } + + /** + * Single value version + * @param variable + * @param values + */ + template <class T> void ScheduleRead(Variable<T> &variable, const T &values) + { + ScheduleRead(variable, &values); + } + + /** + * Single value version using string as variable handlers + * @param variableName + * @param values + */ + template <class T> + void ScheduleRead(const std::string variableName, const T &values) + { + ScheduleRead(variableName, &values); + } + + /** + * Unallocated version, ADIOS will allocate space for incoming data + * @param variableName + */ + void ScheduleRead(const std::string variableName) + { + ScheduleRead(variableName, nullptr); + } + + /** + * Unallocated unspecified version, ADIOS will receive any variable and will + * allocate space for incoming data + */ + void ScheduleRead() { ScheduleRead(nullptr, nullptr); } + + virtual void ScheduleRead(Variable<double> &variable, const double *values); + + /** + * Perform all scheduled reads, either blocking until all reads completed, or + * return immediately. + * @param mode Blocking or non-blocking modes + */ + void PerformReads(PerformReadMode mode); + + /** + * Reader application indicates that no more data will be read from the + * current stream before advancing. + * This is necessary to allow writers to advance as soon as possible. + */ + virtual void Release(); + + /** + * Indicates that a new step is going to be written as new variables come in. + */ + virtual void Advance(float timeout_sec = 0.0); + + /** + * Indicates that a new step is going to be written as new variables come in. + * @param mode Advance mode, there are different options for writers and + * readers + */ + virtual void Advance(AdvanceMode mode, float timeout_sec = 0.0); + + /** @brief Advance asynchronously and get a callback when readers release + * access to the buffered step. + * + * User variables that were allocated through AllocateVariable() + * must not be modified until advance is completed. + * @param mode Advance mode, there are different options for writers and + * readers + * @param callback Will be called when advance is completed. + */ + virtual void + AdvanceAsync(AdvanceMode mode, + std::function<void(std::shared_ptr<adios::Engine>)> callback); + + // Read API + /** + * Inquires and (optionally) allocates and copies the contents of a variable + * If success: it returns a pointer to the internal stored variable object in + * ADIOS class. + * If failure: it returns nullptr + * @param name variable name to look for + * @param readIn if true: reads the full variable and payload, allocating + * values in memory, if false: internal payload is nullptr + * @return success: it returns a pointer to the internal stored variable + * object in ADIOS class, failure: nullptr + */ + virtual Variable<void> *InquireVariable(const std::string name, + const bool readIn = true); + virtual Variable<char> *InquireVariableChar(const std::string name, + const bool readIn = true); + virtual Variable<unsigned char> * + InquireVariableUChar(const std::string name, const bool readIn = true); + virtual Variable<short> *InquireVariableShort(const std::string name, + const bool readIn = true); + virtual Variable<unsigned short> * + InquireVariableUShort(const std::string name, const bool readIn = true); + virtual Variable<int> *InquireVariableInt(const std::string name, + const bool readIn = true); + virtual Variable<unsigned int> *InquireVariableUInt(const std::string name, + const bool readIn = true); + virtual Variable<long int> *InquireVariableLInt(const std::string name, + const bool readIn = true); + virtual Variable<unsigned long int> * + InquireVariableULInt(const std::string name, const bool readIn = true); + virtual Variable<long long int> * + InquireVariableLLInt(const std::string name, const bool readIn = true); + virtual Variable<unsigned long long int> * + InquireVariableULLInt(const std::string name, const bool readIn = true); + virtual Variable<float> *InquireVariableFloat(const std::string name, + const bool readIn = true); + virtual Variable<double> *InquireVariableDouble(const std::string name, + const bool readIn = true); + virtual Variable<long double> * + InquireVariableLDouble(const std::string name, const bool readIn = true); + virtual Variable<std::complex<float>> * + InquireVariableCFloat(const std::string name, const bool readIn = true); + virtual Variable<std::complex<double>> * + InquireVariableCDouble(const std::string name, const bool readIn = true); + virtual Variable<std::complex<long double>> * + InquireVariableCLDouble(const std::string name, const bool readIn = true); + virtual VariableCompound *InquireVariableCompound(const std::string name, + const bool readIn = true); + + /** Return the names of all variables present in a stream/file opened for + * reading + * + * @return a vector of strings + */ + std::vector<std::string> VariableNames(); + + virtual void + Close(const int transportIndex = + -1) = 0; ///< Closes a particular transport, or all if -1 protected: - - ADIOS& m_ADIOS; ///< reference to ADIOS object that creates this Engine at Open - std::vector< std::shared_ptr<Transport> > m_Transports; ///< transports managed - const bool m_DebugMode = false; ///< true: additional checks, false: by-pass checks - unsigned int m_nThreads = 0; - const std::string m_EndMessage; ///< added to exceptions to improve debugging - std::set<std::string> m_WrittenVariables; ///< contains the names of the variables that are being written - - virtual void Init( ); ///< Initialize m_Capsules and m_Transports, called from constructor - virtual void InitParameters( ); ///< Initialize parameters from Method, called from Initi in constructor - virtual void InitTransports( ); ///< Initialize transports from Method, called from Init in constructor - - /** - * Used to verify parameters in m_Method containers - * @param itParam iterator to a certain parameter - * @param parameters map of parameters, from m_Method - * @param parameterName used if exception is thrown to provide debugging information - * @param hint used if exception is thrown to provide debugging information - */ - void CheckParameter( const std::map<std::string, std::string>::const_iterator itParam, - const std::map<std::string, std::string>& parameters, - const std::string parameterName, - const std::string hint ) const; - - bool TransportNamesUniqueness( ) const; ///< checks if transport names are unique among the same types (file I/O) - - - /** - * Throws an exception in debug mode if transport index is out of range. - * @param transportIndex must be in the range [ -1 , m_Transports.size()-1 ] - */ - void CheckTransportIndex( const int transportIndex ); - + ADIOS + &m_ADIOS; ///< reference to ADIOS object that creates this Engine at Open + std::vector<std::shared_ptr<Transport>> m_Transports; ///< transports managed + const bool m_DebugMode = + false; ///< true: additional checks, false: by-pass checks + unsigned int m_nThreads = 0; + const std::string m_EndMessage; ///< added to exceptions to improve debugging + std::set<std::string> m_WrittenVariables; ///< contains the names of the + ///variables that are being written + + virtual void + Init(); ///< Initialize m_Capsules and m_Transports, called from constructor + virtual void InitParameters(); ///< Initialize parameters from Method, called + ///from Initi in constructor + virtual void InitTransports(); ///< Initialize transports from Method, called + ///from Init in constructor + + /** + * Used to verify parameters in m_Method containers + * @param itParam iterator to a certain parameter + * @param parameters map of parameters, from m_Method + * @param parameterName used if exception is thrown to provide debugging + * information + * @param hint used if exception is thrown to provide debugging information + */ + void CheckParameter( + const std::map<std::string, std::string>::const_iterator itParam, + const std::map<std::string, std::string> ¶meters, + const std::string parameterName, const std::string hint) const; + + bool TransportNamesUniqueness() const; ///< checks if transport names are + ///unique among the same types (file + ///I/O) + + /** + * Throws an exception in debug mode if transport index is out of range. + * @param transportIndex must be in the range [ -1 , m_Transports.size()-1 ] + */ + void CheckTransportIndex(const int transportIndex); }; - -} //end namespace +} // end namespace #endif /* ENGINE_H_ */ diff --git a/include/core/Method.h b/include/core/Method.h index 0c42b9a91..e90e026de 100644 --- a/include/core/Method.h +++ b/include/core/Method.h @@ -9,9 +9,9 @@ #define METHOD_H_ /// \cond EXCLUDE_FROM_DOXYGEN -#include <vector> -#include <string> #include <map> +#include <string> +#include <vector> /// \endcond #include "ADIOSTypes.h" @@ -21,11 +21,16 @@ namespace adios { typedef enum { - GLOBAL_READERS = 2, ROUNDROBIN_READERS = 3, FIFO_READERS = 4, - OPEN_ALL_STEPS = 5 + GLOBAL_READERS = 2, + ROUNDROBIN_READERS = 3, + FIFO_READERS = 4, + OPEN_ALL_STEPS = 5 } ReadMultiplexPattern; -typedef enum { NOWAITFORSTREAM = 0, WAITFORSTREAM = 1 } StreamOpenMode; // default: wait for stream +typedef enum { + NOWAITFORSTREAM = 0, + WAITFORSTREAM = 1 +} StreamOpenMode; // default: wait for stream /** * Serves as metadata to define an engine @@ -34,83 +39,99 @@ class Method { public: - - const std::string m_Name; ///< Method name (as defined in XML) - const bool m_DebugMode = false; ///< true: on, throws exceptions and do additional checks, false: off, faster, but unsafe - int m_nThreads; - std::string m_Type; ///< Method's engine type - std::map<std::string, std::string> m_Parameters; ///< method parameters - std::vector< std::map<std::string, std::string> > m_TransportParameters; ///< each is a separate Transport containing their own parameters - - /** - * Constructor - * @param name is a label that can be used in the config file to set up the method at runtime - */ - Method( const std::string name, const bool debugMode = false ); - - ~Method( ); - - /** Check if the method was defined by the user in the config file. - * @return true if the method was user-defined, false otherwise when method is set with default parameters - */ - bool isUserDefined(); - - - /** - * Define the engine type - * @param type must be a valid engine type - */ - void SetEngine( const std::string type ); - - - /** - * Set how many threads the engine can use for its operations (e.g. file io, compression, staging). - * If 1 is allowed, no extra threads will be created during the ADIOS calls for asynchronous operations. - * Note that some transports may require and use extra thread(s). See their documentation for their - * requirements. E.g. some staging transports always create an extra thread for communication. - * Set this parameter like you set it for OpenMP, i.e. count one thread for the main process that calls - * ADIOS functions. - * @param number of threads, minimum 1 is required - */ - void AllowThreads( const int nThreads ); - - /** - * Sets parameters for the method in "parameter=value" format - * @param args list of parameters with format "parameter1=value1", ..., "parameterN=valueN" - */ - template< class ...Args> - void SetParameters( Args... args ) - { - std::vector<std::string> parameters = { args... }; - m_Parameters = BuildParametersMap( parameters, m_DebugMode ); - } - - /** - * Adds a transport and its parameters for the method - * @param type must be a supported transport type under /include/transport - * @param args list of parameters for a transport with format "parameter1=value1", ..., "parameterN=valueN" - */ - template< class ...Args> - void AddTransport( const std::string type, Args... args ) - { - std::vector<std::string> parameters = { args... }; - AddTransportParameters( type, parameters ); - } - - void SetReadMultiplexPattern( const ReadMultiplexPattern pattern ); // How to split stream content among readers - void SetStreamOpenMode( const StreamOpenMode mode); // In Read mode, should Open() wait for the first step appear (default) - - void SetVerbose( const Verbose verbose = Verbose::WARN ) { m_Verbose = verbose; }; - Verbose GetVerbose( ) { return m_Verbose; }; + const std::string m_Name; ///< Method name (as defined in XML) + const bool m_DebugMode = false; ///< true: on, throws exceptions and do + ///additional checks, false: off, faster, but + ///unsafe + int m_nThreads; + std::string m_Type; ///< Method's engine type + std::map<std::string, std::string> m_Parameters; ///< method parameters + std::vector<std::map<std::string, std::string>> + m_TransportParameters; ///< each is a separate Transport containing their + ///own parameters + + /** + * Constructor + * @param name is a label that can be used in the config file to set up the + * method at runtime + */ + Method(const std::string name, const bool debugMode = false); + + ~Method(); + + /** Check if the method was defined by the user in the config file. + * @return true if the method was user-defined, false otherwise when method is + * set with default parameters + */ + bool isUserDefined(); + + /** + * Define the engine type + * @param type must be a valid engine type + */ + void SetEngine(const std::string type); + + /** + * Set how many threads the engine can use for its operations (e.g. file io, + * compression, staging). + * If 1 is allowed, no extra threads will be created during the ADIOS calls + * for asynchronous operations. + * Note that some transports may require and use extra thread(s). See their + * documentation for their + * requirements. E.g. some staging transports always create an extra thread + * for communication. + * Set this parameter like you set it for OpenMP, i.e. count one thread for + * the main process that calls + * ADIOS functions. + * @param number of threads, minimum 1 is required + */ + void AllowThreads(const int nThreads); + + /** + * Sets parameters for the method in "parameter=value" format + * @param args list of parameters with format "parameter1=value1", ..., + * "parameterN=valueN" + */ + template <class... Args> void SetParameters(Args... args) + { + std::vector<std::string> parameters = {args...}; + m_Parameters = BuildParametersMap(parameters, m_DebugMode); + } + + /** + * Adds a transport and its parameters for the method + * @param type must be a supported transport type under /include/transport + * @param args list of parameters for a transport with format + * "parameter1=value1", ..., "parameterN=valueN" + */ + template <class... Args> + void AddTransport(const std::string type, Args... args) + { + std::vector<std::string> parameters = {args...}; + AddTransportParameters(type, parameters); + } + + void SetReadMultiplexPattern( + const ReadMultiplexPattern + pattern); // How to split stream content among readers + void SetStreamOpenMode(const StreamOpenMode mode); // In Read mode, should + // Open() wait for the + // first step appear + // (default) + + void SetVerbose(const Verbose verbose = Verbose::WARN) + { + m_Verbose = verbose; + }; + Verbose GetVerbose() { return m_Verbose; }; private: - Verbose m_Verbose = Verbose::WARN; - - void AddTransportParameters( const std::string type, const std::vector<std::string>& parameters ); + Verbose m_Verbose = Verbose::WARN; + void AddTransportParameters(const std::string type, + const std::vector<std::string> ¶meters); }; - -} //end namespace +} // end namespace #endif /* METHOD_H_ */ diff --git a/include/core/Profiler.h b/include/core/Profiler.h index ca446ef3a..1a1d0fad9 100644 --- a/include/core/Profiler.h +++ b/include/core/Profiler.h @@ -19,77 +19,88 @@ class Timer { public: - const std::string Process; - unsigned long long int ProcessTime = 0; - - Timer( const std::string process, const Support::Resolutions resolution ): - Process{ process }, - Resolution{ resolution } - { } - - void SetInitialTime( ) - { - InitialTime = std::chrono::high_resolution_clock::now(); - } - - void SetTime( ) - { - ElapsedTime = std::chrono::high_resolution_clock::now(); - ProcessTime += GetTime( ); - } - - long long int GetTime( ) - { - if( Resolution == Support::Resolutions::mus ) - return std::chrono::duration_cast<std::chrono::microseconds>( ElapsedTime - InitialTime ).count(); - - else if( Resolution == Support::Resolutions::ms ) - return std::chrono::duration_cast<std::chrono::milliseconds>( ElapsedTime - InitialTime ).count(); - - else if( Resolution == Support::Resolutions::s ) - return std::chrono::duration_cast<std::chrono::seconds>( ElapsedTime - InitialTime ).count(); - - else if( Resolution == Support::Resolutions::m ) - return std::chrono::duration_cast<std::chrono::minutes>( ElapsedTime - InitialTime ).count(); - - else if( Resolution == Support::Resolutions::h ) - return std::chrono::duration_cast<std::chrono::hours>( ElapsedTime - InitialTime ).count(); - - return -1; //failure - } - - std::string GetUnits( ) const - { - std::string units; - if( Resolution == Support::Resolutions::mus ) units = "mus"; - else if( Resolution == Support::Resolutions::ms ) units = "ms"; - else if( Resolution == Support::Resolutions::s ) units = "s"; - else if( Resolution == Support::Resolutions::m ) units = "m"; - else if( Resolution == Support::Resolutions::h ) units = "h"; - return units; - } + const std::string Process; + unsigned long long int ProcessTime = 0; + + Timer(const std::string process, const Support::Resolutions resolution) + : Process{process}, Resolution{resolution} + { + } + + void SetInitialTime() + { + InitialTime = std::chrono::high_resolution_clock::now(); + } + + void SetTime() + { + ElapsedTime = std::chrono::high_resolution_clock::now(); + ProcessTime += GetTime(); + } + + long long int GetTime() + { + if (Resolution == Support::Resolutions::mus) + return std::chrono::duration_cast<std::chrono::microseconds>(ElapsedTime - + InitialTime) + .count(); + + else if (Resolution == Support::Resolutions::ms) + return std::chrono::duration_cast<std::chrono::milliseconds>(ElapsedTime - + InitialTime) + .count(); + + else if (Resolution == Support::Resolutions::s) + return std::chrono::duration_cast<std::chrono::seconds>(ElapsedTime - + InitialTime) + .count(); + + else if (Resolution == Support::Resolutions::m) + return std::chrono::duration_cast<std::chrono::minutes>(ElapsedTime - + InitialTime) + .count(); + + else if (Resolution == Support::Resolutions::h) + return std::chrono::duration_cast<std::chrono::hours>(ElapsedTime - + InitialTime) + .count(); + + return -1; // failure + } + + std::string GetUnits() const + { + std::string units; + if (Resolution == Support::Resolutions::mus) + units = "mus"; + else if (Resolution == Support::Resolutions::ms) + units = "ms"; + else if (Resolution == Support::Resolutions::s) + units = "s"; + else if (Resolution == Support::Resolutions::m) + units = "m"; + else if (Resolution == Support::Resolutions::h) + units = "h"; + return units; + } private: - - const Support::Resolutions Resolution; - std::chrono::time_point<std::chrono::high_resolution_clock> InitialTime; - std::chrono::time_point<std::chrono::high_resolution_clock> ElapsedTime; - bool InitialTimeSet = false; + const Support::Resolutions Resolution; + std::chrono::time_point<std::chrono::high_resolution_clock> InitialTime; + std::chrono::time_point<std::chrono::high_resolution_clock> ElapsedTime; + bool InitialTimeSet = false; }; - /** * Utilities for profiling using the chrono header in C++11 */ struct Profiler { - std::vector<Timer> m_Timers; - std::vector<unsigned long long int> m_TotalBytes; - bool m_IsActive = false; + std::vector<Timer> m_Timers; + std::vector<unsigned long long int> m_TotalBytes; + bool m_IsActive = false; }; -} //end namespace - - +} // end namespace #endif /* PROFILER_H_ */ diff --git a/include/core/Support.h b/include/core/Support.h index f8830a258..fb7811e45 100644 --- a/include/core/Support.h +++ b/include/core/Support.h @@ -9,33 +9,45 @@ #define SUPPORT_H_ /// \cond EXCLUDE_FROM_DOXYGEN +#include <array> +#include <map> #include <set> #include <string> -#include <map> -#include <array> /// \endcond namespace adios { - struct Support { - static const std::string Version; ///< current ADIOS version - static const std::set<std::string> HostLanguages; ///< supported languages: C, C++, Fortran, Python, Java - static const std::set<std::string> Numbers; - static const std::set<std::string> Transports; ///< supported transport methods - static const std::set<std::string> Transforms; ///< supported data transform methods - static const std::map<std::string, std::set<std::string> > Datatypes; ///< supported data types, key: host language, value: all supported types - static const std::map<std::string, std::set<std::string> > DatatypesAliases; ///< all supported int aliases, key: C++ type (e.g. int), value: aliases to type in key (e.g. int, integer) - - static const std::set<std::string> FileTransports; ///< file I/O transports - - enum class Resolutions { mus, ms, s, m, h }; + static const std::string Version; ///< current ADIOS version + static const std::set<std::string> + HostLanguages; ///< supported languages: C, C++, Fortran, Python, Java + static const std::set<std::string> Numbers; + static const std::set<std::string> + Transports; ///< supported transport methods + static const std::set<std::string> + Transforms; ///< supported data transform methods + static const std::map<std::string, std::set<std::string>> + Datatypes; ///< supported data types, key: host language, value: all + ///supported types + static const std::map<std::string, std::set<std::string>> + DatatypesAliases; ///< all supported int aliases, key: C++ type (e.g. + ///int), value: aliases to type in key (e.g. int, + ///integer) + + static const std::set<std::string> FileTransports; ///< file I/O transports + + enum class Resolutions + { + mus, + ms, + s, + m, + h + }; }; - -} //end namespace - +} // end namespace #endif /* SUPPORT_H_ */ diff --git a/include/core/Transform.h b/include/core/Transform.h index 3c8a08451..5a5482324 100644 --- a/include/core/Transform.h +++ b/include/core/Transform.h @@ -8,40 +8,38 @@ #ifndef TRANSFORM_H_ #define TRANSFORM_H_ - /// \cond EXCLUDE_FROM_DOXYGEN #include <string> #include <vector> /// \endcond - namespace adios { /** - * Parent class that defines data variable transformations. Used as a member of CVariable + * Parent class that defines data variable transformations. Used as a member of + * CVariable */ class Transform { public: + const std::string m_Method; - const std::string m_Method; - - /** - * Initialize parent method - * @param method zlib, bzip2, szip - */ - Transform( const std::string method ); + /** + * Initialize parent method + * @param method zlib, bzip2, szip + */ + Transform(const std::string method); - virtual ~Transform( ); + virtual ~Transform(); - virtual void Compress( const std::vector<char>& bufferIn, std::vector<char>& bufferOut ); - - virtual void Decompress( const std::vector<char>& bufferIn, std::vector<char>& bufferOut ); + virtual void Compress(const std::vector<char> &bufferIn, + std::vector<char> &bufferOut); + virtual void Decompress(const std::vector<char> &bufferIn, + std::vector<char> &bufferOut); }; - -} //end namespace +} // end namespace #endif /* TRANSFORM_H_ */ diff --git a/include/core/Transport.h b/include/core/Transport.h index 1c2c0d0ba..2d5be92bd 100644 --- a/include/core/Transport.h +++ b/include/core/Transport.h @@ -14,14 +14,13 @@ /// \endcond #ifdef ADIOS_NOMPI - #include "mpidummy.h" +#include "mpidummy.h" #else - #include <mpi.h> +#include <mpi.h> #endif #include "core/Profiler.h" - namespace adios { @@ -29,66 +28,61 @@ class Transport { public: - - const std::string m_Type; ///< transport type from derived class - std::string m_Name; ///< from Open - std::string m_AccessMode; ///< from Open - bool m_IsOpen = false; - - MPI_Comm m_MPIComm = MPI_COMM_SELF; - - int m_RankMPI = 0; ///< current MPI rank process - int m_SizeMPI = 1; ///< current MPI processes size - Profiler m_Profiler; ///< collects information about Open and bytes Transport - - /** - * Base constructor that all derived classes pass - * @param - * @param mpiComm passed to m_MPIComm - * @param debugMode passed to m_DebugMode - */ - Transport( const std::string type, MPI_Comm mpiComm, const bool debugMode ); - - - virtual ~Transport( ); ///< empty destructor, using STL for memory management - - /** - * Open Output file accesing a mode - * @param name name of stream or file - * @param accessMode r or read, w or write, a or append - */ - virtual void Open( const std::string name, const std::string accessMode ) = 0; - - /** - * Set buffer and size for a particular transport - * @param buffer raw data buffer - * @param size raw data buffer size - */ - virtual void SetBuffer( char* buffer, std::size_t size ); - - /** - * Write function for a transport - * @param buffer pointer to buffer to be written - * @param size size of buffer to be written - */ - virtual void Write( const char* buffer, std::size_t size ) = 0; - - virtual void Flush( ); ///< flushes current contents to physical medium without closing the transport - - virtual void Close( ); ///< closes current transport and flushes everything, transport becomes unreachable - - - virtual void InitProfiler( const std::string accessMode, const Support::Resolutions resolution ); + const std::string m_Type; ///< transport type from derived class + std::string m_Name; ///< from Open + std::string m_AccessMode; ///< from Open + bool m_IsOpen = false; + + MPI_Comm m_MPIComm = MPI_COMM_SELF; + + int m_RankMPI = 0; ///< current MPI rank process + int m_SizeMPI = 1; ///< current MPI processes size + Profiler m_Profiler; ///< collects information about Open and bytes Transport + + /** + * Base constructor that all derived classes pass + * @param + * @param mpiComm passed to m_MPIComm + * @param debugMode passed to m_DebugMode + */ + Transport(const std::string type, MPI_Comm mpiComm, const bool debugMode); + + virtual ~Transport(); ///< empty destructor, using STL for memory management + + /** + * Open Output file accesing a mode + * @param name name of stream or file + * @param accessMode r or read, w or write, a or append + */ + virtual void Open(const std::string name, const std::string accessMode) = 0; + + /** + * Set buffer and size for a particular transport + * @param buffer raw data buffer + * @param size raw data buffer size + */ + virtual void SetBuffer(char *buffer, std::size_t size); + + /** + * Write function for a transport + * @param buffer pointer to buffer to be written + * @param size size of buffer to be written + */ + virtual void Write(const char *buffer, std::size_t size) = 0; + + virtual void Flush(); ///< flushes current contents to physical medium without + ///closing the transport + + virtual void Close(); ///< closes current transport and flushes everything, + ///transport becomes unreachable + + virtual void InitProfiler(const std::string accessMode, + const Support::Resolutions resolution); protected: - - const bool m_DebugMode = false; ///< if true: additional checks and exceptions + const bool m_DebugMode = false; ///< if true: additional checks and exceptions }; - - -} //end namespace - - +} // end namespace #endif /* TRANSPORT_H_ */ diff --git a/include/core/Variable.h b/include/core/Variable.h index ec8c636df..9a636909e 100644 --- a/include/core/Variable.h +++ b/include/core/Variable.h @@ -9,103 +9,107 @@ #define VARIABLE_H_ /// \cond EXCLUDE_FROM_DOXYGEN -#include <string> -#include <vector> #include <map> #include <ostream> //std::ostream in MonitorGroups +#include <string> +#include <vector> /// \endcond -#include "core/VariableBase.h" #include "core/Transform.h" - +#include "core/VariableBase.h" namespace adios { - struct TransformData { - Transform& Operation; ///< pointer to transform object - std::map<std::string, std::string> Parameters; ///< transforms parameters - std::vector<std::size_t> Size; ///< vector that carries the sizes after a transformation is applied + Transform &Operation; ///< pointer to transform object + std::map<std::string, std::string> Parameters; ///< transforms parameters + std::vector<std::size_t> + Size; ///< vector that carries the sizes after a transformation is applied }; /** - * @param Base (parent) class for template derived (child) class CVariable. Required to put CVariable objects in STL containers. + * @param Base (parent) class for template derived (child) class CVariable. + * Required to put CVariable objects in STL containers. */ -template< class T > -class Variable : public VariableBase +template <class T> class Variable : public VariableBase { public: - - const T* m_AppValues = nullptr; ///< pointer to values passed from user in ADIOS Write, it might change in ADIOS Read - - std::vector< TransformData > m_Transforms; ///< associated transforms, sequence determines application order, e.g. first Transforms[0] then Transforms[1]. Pointer used as reference (no memory management). - - Variable<T>( const std::string name, const Dims dimensions, const Dims globalDimensions, const Dims globalOffsets, - const bool debugMode ): - VariableBase( name, GetType<T>(), sizeof(T), dimensions, globalDimensions, globalOffsets, debugMode ) - { - if( m_Dimensions == Dims{1} ) - m_IsScalar = true; - } - - template< class ...Args> - void AddTransform( Transform& transform, Args... args ) - { - std::vector<std::string> parameters = { args... }; - m_Transforms.emplace_back( transform, BuildParametersMap( parameters, m_DebugMode ) ); //need to check - } - - /** Return the global dimensions of the variable - * @return vector of std::size_t values - */ - std::vector<std::size_t> GetGlobalDimensions(); - - /** Return the number of steps available for the variable - * @return Number of steps - */ - int GetSteps(); - - void Monitor( std::ostream& logInfo ) const noexcept + const T *m_AppValues = nullptr; ///< pointer to values passed from user in + ///ADIOS Write, it might change in ADIOS Read + + std::vector<TransformData> m_Transforms; ///< associated transforms, sequence + ///determines application order, e.g. + ///first Transforms[0] then + ///Transforms[1]. Pointer used as + ///reference (no memory management). + + Variable<T>(const std::string name, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets, + const bool debugMode) + : VariableBase(name, GetType<T>(), sizeof(T), dimensions, + globalDimensions, globalOffsets, debugMode) + { + if (m_Dimensions == Dims{1}) + m_IsScalar = true; + } + + template <class... Args> void AddTransform(Transform &transform, Args... args) + { + std::vector<std::string> parameters = {args...}; + m_Transforms.emplace_back( + transform, + BuildParametersMap(parameters, m_DebugMode)); // need to check + } + + /** Return the global dimensions of the variable + * @return vector of std::size_t values + */ + std::vector<std::size_t> GetGlobalDimensions(); + + /** Return the number of steps available for the variable + * @return Number of steps + */ + int GetSteps(); + + void Monitor(std::ostream &logInfo) const noexcept + { + logInfo << "Variable: " << m_Name << "\n"; + logInfo << "Type: " << m_Type << "\n"; + logInfo << "Size: " << TotalSize() << " elements\n"; + logInfo << "Payload: " << PayLoadSize() << " bytes\n"; + + if (m_AppValues != nullptr) { - logInfo << "Variable: " << m_Name << "\n"; - logInfo << "Type: " << m_Type << "\n"; - logInfo << "Size: " << TotalSize() << " elements\n"; - logInfo << "Payload: " << PayLoadSize() << " bytes\n"; - - if( m_AppValues != nullptr ) + logInfo << "Values (first 10 or max_size): \n"; + std::size_t size = TotalSize(); + if (size > 10) + size = 10; + + if (m_Type.find("complex") != m_Type.npos) // it's complex + { + for (unsigned int i = 0; i < size; ++i) { - logInfo << "Values (first 10 or max_size): \n"; - std::size_t size = TotalSize(); - if( size > 10 ) - size = 10; - - if( m_Type.find("complex") != m_Type.npos ) //it's complex - { - for( unsigned int i = 0; i < size; ++i ) - { - logInfo << "( " << std::real( m_AppValues[i] ) << " , " << std::imag( m_AppValues[i] ) << " ) "; - } - } - else - { - for( unsigned int i = 0; i < size; ++i ) - { - logInfo << m_AppValues[i] << " "; - } - } - - logInfo << " ..."; + logInfo << "( " << std::real(m_AppValues[i]) << " , " + << std::imag(m_AppValues[i]) << " ) "; } - logInfo << "\n"; - } + } + else + { + for (unsigned int i = 0; i < size; ++i) + { + logInfo << m_AppValues[i] << " "; + } + } + logInfo << " ..."; + } + logInfo << "\n"; + } }; - -} //end namespace - +} // end namespace #endif /* VARIABLE_H_ */ diff --git a/include/core/VariableBase.h b/include/core/VariableBase.h index 4dddf13b7..87ca02a21 100644 --- a/include/core/VariableBase.h +++ b/include/core/VariableBase.h @@ -9,16 +9,15 @@ #define VARIABLEBASE_H_ /// \cond EXCLUDE_FROM_DOXYGEN -#include <vector> -#include <string> -#include <sstream> #include <iterator> +#include <sstream> +#include <string> +#include <vector> /// \endcond #include "functions/adiosFunctions.h" //GetTotalSize #include "functions/adiosTemplates.h" //GetType<T> - namespace adios { @@ -28,88 +27,72 @@ class VariableBase { public: - - const std::string m_Name; ///< variable name - const std::string m_Type; ///< variable type - const std::size_t m_ElementSize; ///< Variable -> sizeof(T), VariableCompound -> from constructor - - bool m_IsScalar = false; - const bool m_IsDimension = false; - - - VariableBase( const std::string name, const std::string type, const std::size_t elementSize, - const Dims dimensions, const Dims globalDimensions, const Dims globalOffsets, - const bool debugMode ): - m_Name{ name }, - m_Type{ type }, - m_ElementSize{ elementSize }, - m_Dimensions{ dimensions }, - m_GlobalDimensions{ globalDimensions }, - m_GlobalOffsets{ globalOffsets }, - m_DebugMode{ debugMode } - { } - - virtual ~VariableBase( ) - { } - - - std::size_t DimensionsSize( ) const noexcept - { - return m_Dimensions.size(); - } - - /** - * Returns the payload size in bytes - * @return TotalSize * sizeof(T) - */ - std::size_t PayLoadSize( ) const noexcept - { - return GetTotalSize( m_Dimensions ) * m_ElementSize; - } - - /** - * Returns the total size - * @return number of elements - */ - std::size_t TotalSize( ) const noexcept - { - return GetTotalSize( m_Dimensions ); - } - - -//protected: off for now - - Dims m_Dimensions; ///< array of local dimensions - Dims m_GlobalDimensions; ///< array of global dimensions - Dims m_GlobalOffsets; ///< array of global offsets - const bool m_DebugMode = false; - - - std::string GetDimensionAsString() { return dimsToString( m_Dimensions ); } - std::string GetGlobalDimensionAsString() { return dimsToString( m_GlobalDimensions ); } - std::string GetOffsetsAsString() { return dimsToString( m_GlobalOffsets ); } - + const std::string m_Name; ///< variable name + const std::string m_Type; ///< variable type + const std::size_t m_ElementSize; ///< Variable -> sizeof(T), VariableCompound + ///-> from constructor + + bool m_IsScalar = false; + const bool m_IsDimension = false; + + VariableBase(const std::string name, const std::string type, + const std::size_t elementSize, const Dims dimensions, + const Dims globalDimensions, const Dims globalOffsets, + const bool debugMode) + : m_Name{name}, m_Type{type}, m_ElementSize{elementSize}, + m_Dimensions{dimensions}, m_GlobalDimensions{globalDimensions}, + m_GlobalOffsets{globalOffsets}, m_DebugMode{debugMode} + { + } + + virtual ~VariableBase() {} + + std::size_t DimensionsSize() const noexcept { return m_Dimensions.size(); } + + /** + * Returns the payload size in bytes + * @return TotalSize * sizeof(T) + */ + std::size_t PayLoadSize() const noexcept + { + return GetTotalSize(m_Dimensions) * m_ElementSize; + } + + /** + * Returns the total size + * @return number of elements + */ + std::size_t TotalSize() const noexcept { return GetTotalSize(m_Dimensions); } + + // protected: off for now + + Dims m_Dimensions; ///< array of local dimensions + Dims m_GlobalDimensions; ///< array of global dimensions + Dims m_GlobalOffsets; ///< array of global offsets + const bool m_DebugMode = false; + + std::string GetDimensionAsString() { return dimsToString(m_Dimensions); } + std::string GetGlobalDimensionAsString() + { + return dimsToString(m_GlobalDimensions); + } + std::string GetOffsetsAsString() { return dimsToString(m_GlobalOffsets); } private: - std::string dimsToString( Dims dims ) + std::string dimsToString(Dims dims) + { + std::ostringstream oss; + if (!dims.empty()) { - std::ostringstream oss; - if (!dims.empty()) - { - // Convert all but the last element to avoid a trailing "," - std::copy(dims.begin(), dims.end()-1, - std::ostream_iterator<std::size_t>(oss, ",")); - // Now add the last element with no delimiter - oss << dims.back(); - } - return oss.str(); + // Convert all but the last element to avoid a trailing "," + std::copy(dims.begin(), dims.end() - 1, + std::ostream_iterator<std::size_t>(oss, ",")); + // Now add the last element with no delimiter + oss << dims.back(); } + return oss.str(); + } }; - - - - } - #endif /* VARIABLEBASE_H_ */ diff --git a/include/core/VariableCompound.h b/include/core/VariableCompound.h index 1fda61ab4..35194f0f9 100644 --- a/include/core/VariableCompound.h +++ b/include/core/VariableCompound.h @@ -15,53 +15,47 @@ namespace adios struct CompoundElement { - const std::string m_Name; - const std::size_t m_Offset; - const std::string m_Type; + const std::string m_Name; + const std::size_t m_Offset; + const std::string m_Type; }; - /** - * @param Base (parent) class for template derived (child) class CVariable. Required to put CVariable objects in STL containers. + * @param Base (parent) class for template derived (child) class CVariable. + * Required to put CVariable objects in STL containers. */ class VariableCompound : public VariableBase { public: - - const void* m_AppValue = nullptr; - - - VariableCompound( const std::string name, const std::size_t sizeOfStruct, const Dims dimensions, - const Dims globalDimensions, const Dims globalOffsets, const bool debugMode ): - VariableBase( name, "compound", sizeOfStruct, dimensions, globalDimensions, globalOffsets, debugMode ) - { } - - template< class U > - void InsertMember( const std::string name, const std::size_t offset ) - { - m_Elements.push_back( CompoundElement{ name, offset, GetType<U>() } ); - } - - void Monitor( std::ostream& logInfo ) const noexcept - { - logInfo << "Variable Compound: " << m_Name << "\n"; - logInfo << "Type: " << m_Type << "\n"; - logInfo << "Size: " << TotalSize() << " elements\n"; - logInfo << "Payload: " << PayLoadSize() << " bytes\n"; - } - + const void *m_AppValue = nullptr; + + VariableCompound(const std::string name, const std::size_t sizeOfStruct, + const Dims dimensions, const Dims globalDimensions, + const Dims globalOffsets, const bool debugMode) + : VariableBase(name, "compound", sizeOfStruct, dimensions, + globalDimensions, globalOffsets, debugMode) + { + } + + template <class U> + void InsertMember(const std::string name, const std::size_t offset) + { + m_Elements.push_back(CompoundElement{name, offset, GetType<U>()}); + } + + void Monitor(std::ostream &logInfo) const noexcept + { + logInfo << "Variable Compound: " << m_Name << "\n"; + logInfo << "Type: " << m_Type << "\n"; + logInfo << "Size: " << TotalSize() << " elements\n"; + logInfo << "Payload: " << PayLoadSize() << " bytes\n"; + } private: - - std::vector<CompoundElement> m_Elements; ///< vector of element types - + std::vector<CompoundElement> m_Elements; ///< vector of element types }; - - - -} //end namespace - +} // end namespace #endif /* VARIABLECOMPOUND_H_ */ diff --git a/include/engine/adios1/ADIOS1Reader.h b/include/engine/adios1/ADIOS1Reader.h index 7a91b9a6c..a5e0c071d 100644 --- a/include/engine/adios1/ADIOS1Reader.h +++ b/include/engine/adios1/ADIOS1Reader.h @@ -14,91 +14,108 @@ #include "core/Engine.h" -//supported capsules +// supported capsules #include "capsule/heap/STLVector.h" - namespace adios { - class BPFileReader : public Engine { public: - - /** - * Constructor for single BP capsule engine, writes in BP format into a single heap capsule - * @param name unique name given to the engine - * @param accessMode - * @param mpiComm - * @param method - * @param debugMode - * @param hostLanguage - */ - BPFileReader( ADIOS& adios, const std::string name, const std::string accessMode, MPI_Comm mpiComm, - const Method& method, const IOMode iomode, const float timeout_sec, - const bool debugMode = false, const unsigned int nthreads = 1 ); - - ~BPFileReader( ); - - - Variable<void>* InquireVariable( const std::string name, const bool readIn = true ); - Variable<char>* InquireVariableChar( const std::string name, const bool readIn = true ); - Variable<unsigned char>* InquireVariableUChar( const std::string name, const bool readIn = true ); - Variable<short>* InquireVariableShort( const std::string name, const bool readIn = true ); - Variable<unsigned short>* InquireVariableUShort( const std::string name, const bool readIn = true ); - Variable<int>* InquireVariableInt( const std::string name, const bool readIn = true ); - Variable<unsigned int>* InquireVariableUInt( const std::string name, const bool readIn = true ); - Variable<long int>* InquireVariableLInt( const std::string name, const bool readIn = true ); - Variable<unsigned long int>* InquireVariableULInt( const std::string name, const bool readIn = true ); - Variable<long long int>* InquireVariableLLInt( const std::string name, const bool readIn = true ); - Variable<unsigned long long int>* InquireVariableULLInt( const std::string name, const bool readIn = true ); - Variable<float>* InquireVariableFloat( const std::string name, const bool readIn = true ); - Variable<double>* InquireVariableDouble( const std::string name, const bool readIn = true ); - Variable<long double>* InquireVariableLDouble( const std::string name, const bool readIn = true ); - Variable<std::complex<float>>* InquireVariableCFloat( const std::string name, const bool readIn = true ); - Variable<std::complex<double>>* InquireVariableCDouble( const std::string name, const bool readIn = true ); - Variable<std::complex<long double>>* InquireVariableCLDouble( const std::string name, const bool readIn = true ); - - /** - * Not implemented - * @param name - * @param readIn - * @return - */ - VariableCompound* InquireVariableCompound( const std::string name, const bool readIn = true ); - - - void Close( const int transportIndex = -1 ); + /** + * Constructor for single BP capsule engine, writes in BP format into a single + * heap capsule + * @param name unique name given to the engine + * @param accessMode + * @param mpiComm + * @param method + * @param debugMode + * @param hostLanguage + */ + BPFileReader(ADIOS &adios, const std::string name, + const std::string accessMode, MPI_Comm mpiComm, + const Method &method, const IOMode iomode, + const float timeout_sec, const bool debugMode = false, + const unsigned int nthreads = 1); + + ~BPFileReader(); + + Variable<void> *InquireVariable(const std::string name, + const bool readIn = true); + Variable<char> *InquireVariableChar(const std::string name, + const bool readIn = true); + Variable<unsigned char> *InquireVariableUChar(const std::string name, + const bool readIn = true); + Variable<short> *InquireVariableShort(const std::string name, + const bool readIn = true); + Variable<unsigned short> *InquireVariableUShort(const std::string name, + const bool readIn = true); + Variable<int> *InquireVariableInt(const std::string name, + const bool readIn = true); + Variable<unsigned int> *InquireVariableUInt(const std::string name, + const bool readIn = true); + Variable<long int> *InquireVariableLInt(const std::string name, + const bool readIn = true); + Variable<unsigned long int> *InquireVariableULInt(const std::string name, + const bool readIn = true); + Variable<long long int> *InquireVariableLLInt(const std::string name, + const bool readIn = true); + Variable<unsigned long long int> * + InquireVariableULLInt(const std::string name, const bool readIn = true); + Variable<float> *InquireVariableFloat(const std::string name, + const bool readIn = true); + Variable<double> *InquireVariableDouble(const std::string name, + const bool readIn = true); + Variable<long double> *InquireVariableLDouble(const std::string name, + const bool readIn = true); + Variable<std::complex<float>> * + InquireVariableCFloat(const std::string name, const bool readIn = true); + Variable<std::complex<double>> * + InquireVariableCDouble(const std::string name, const bool readIn = true); + Variable<std::complex<long double>> * + InquireVariableCLDouble(const std::string name, const bool readIn = true); + + /** + * Not implemented + * @param name + * @param readIn + * @return + */ + VariableCompound *InquireVariableCompound(const std::string name, + const bool readIn = true); + + void Close(const int transportIndex = -1); private: - - capsule::STLVector m_Buffer; ///< heap capsule, contains data and metadata buffers - //format::BP1Writer m_BP1Writer; ///< format object will provide the required BP functionality to be applied on m_Buffer and m_Transports - - void Init( ); ///< calls InitCapsules and InitTransports based on Method, called from constructor - void InitCapsules( ); - void InitTransports( ); ///< from Transports - - std::string GetMdtmParameter( const std::string parameter, const std::map<std::string,std::string>& mdtmParameters ); - - - template< class T > - Variable<T>* InquireVariableCommon( const std::string name, const bool readIn ) - { - std::cout << "Hello BPReaderCommon\n"; - - //here read variable metadata (dimensions, type, etc.)...then create a Variable like below: - //Variable<T>& variable = m_ADIOS.DefineVariable<T>( m_Name + "/" + name, ) - //return &variable; //return address if success - return nullptr; //on failure - } + capsule::STLVector + m_Buffer; ///< heap capsule, contains data and metadata buffers + // format::BP1Writer m_BP1Writer; ///< format object will provide the required + // BP functionality to be applied on m_Buffer and m_Transports + + void Init(); ///< calls InitCapsules and InitTransports based on Method, + ///called from constructor + void InitCapsules(); + void InitTransports(); ///< from Transports + + std::string + GetMdtmParameter(const std::string parameter, + const std::map<std::string, std::string> &mdtmParameters); + + template <class T> + Variable<T> *InquireVariableCommon(const std::string name, const bool readIn) + { + std::cout << "Hello BPReaderCommon\n"; + + // here read variable metadata (dimensions, type, etc.)...then create a + // Variable like below: + // Variable<T>& variable = m_ADIOS.DefineVariable<T>( m_Name + "/" + name, ) + // return &variable; //return address if success + return nullptr; // on failure + } }; - - -} //end namespace adios - +} // end namespace adios #endif /* BPFILEREADER_H_ */ diff --git a/include/engine/adios1/ADIOS1Writer.h b/include/engine/adios1/ADIOS1Writer.h index bfa235ba0..990d7fbd6 100644 --- a/include/engine/adios1/ADIOS1Writer.h +++ b/include/engine/adios1/ADIOS1Writer.h @@ -12,107 +12,117 @@ #include "core/Engine.h" - namespace adios { #ifdef ADIOS_NOMPI -# define _NOMPI 1 +#define _NOMPI 1 #endif -#include "adios.h" // this is adios 1.x header file - +#include "adios.h" // this is adios 1.x header file class ADIOS1Writer : public Engine { public: - - /** - * Constructor for Writer writes in ADIOS 1.x BP format - * @param name unique name given to the engine - * @param accessMode - * @param mpiComm - * @param method - * @param debugMode - */ - ADIOS1Writer( ADIOS& adios, const std::string name, const std::string accessMode, MPI_Comm mpiComm, - const Method& method, const IOMode iomode, const float timeout_sec, - const bool debugMode = false, const unsigned int nthreads = 1 ); - - ~ADIOS1Writer( ); - - void Write( Variable<char>& variable, const char* values ); - void Write( Variable<unsigned char>& variable, const unsigned char* values ); - void Write( Variable<short>& variable, const short* values ); - void Write( Variable<unsigned short>& variable, const unsigned short* values ); - void Write( Variable<int>& variable, const int* values ); - void Write( Variable<unsigned int>& variable, const unsigned int* values ); - void Write( Variable<long int>& variable, const long int* values ); - void Write( Variable<unsigned long int>& variable, const unsigned long int* values ); - void Write( Variable<long long int>& variable, const long long int* values ); - void Write( Variable<unsigned long long int>& variable, const unsigned long long int* values ); - void Write( Variable<float>& variable, const float* values ); - void Write( Variable<double>& variable, const double* values ); - void Write( Variable<long double>& variable, const long double* values ); - void Write( Variable<std::complex<float>>& variable, const std::complex<float>* values ); - void Write( Variable<std::complex<double>>& variable, const std::complex<double>* values ); - void Write( Variable<std::complex<long double>>& variable, const std::complex<long double>* values ); - void Write( VariableCompound& variable, const void* values ); - - void Write( const std::string variableName, const char* values ); - void Write( const std::string variableName, const unsigned char* values ); - void Write( const std::string variableName, const short* values ); - void Write( const std::string variableName, const unsigned short* values ); - void Write( const std::string variableName, const int* values ); - void Write( const std::string variableName, const unsigned int* values ); - void Write( const std::string variableName, const long int* values ); - void Write( const std::string variableName, const unsigned long int* values ); - void Write( const std::string variableName, const long long int* values ); - void Write( const std::string variableName, const unsigned long long int* values ); - void Write( const std::string variableName, const float* values ); - void Write( const std::string variableName, const double* values ); - void Write( const std::string variableName, const long double* values ); - void Write( const std::string variableName, const std::complex<float>* values ); - void Write( const std::string variableName, const std::complex<double>* values ); - void Write( const std::string variableName, const std::complex<long double>* values ); - void Write( const std::string variableName, const void* values ); - - void Advance( ); - - /** - * Closes a single transport or all transports - * @param transportIndex, if -1 (default) closes all transports, otherwise it closes a transport in m_Transport[transportIndex]. In debug mode the latter is bounds-checked. - */ - void Close( const int transportIndex = -1 ); - + /** + * Constructor for Writer writes in ADIOS 1.x BP format + * @param name unique name given to the engine + * @param accessMode + * @param mpiComm + * @param method + * @param debugMode + */ + ADIOS1Writer(ADIOS &adios, const std::string name, + const std::string accessMode, MPI_Comm mpiComm, + const Method &method, const IOMode iomode, + const float timeout_sec, const bool debugMode = false, + const unsigned int nthreads = 1); + + ~ADIOS1Writer(); + + void Write(Variable<char> &variable, const char *values); + void Write(Variable<unsigned char> &variable, const unsigned char *values); + void Write(Variable<short> &variable, const short *values); + void Write(Variable<unsigned short> &variable, const unsigned short *values); + void Write(Variable<int> &variable, const int *values); + void Write(Variable<unsigned int> &variable, const unsigned int *values); + void Write(Variable<long int> &variable, const long int *values); + void Write(Variable<unsigned long int> &variable, + const unsigned long int *values); + void Write(Variable<long long int> &variable, const long long int *values); + void Write(Variable<unsigned long long int> &variable, + const unsigned long long int *values); + void Write(Variable<float> &variable, const float *values); + void Write(Variable<double> &variable, const double *values); + void Write(Variable<long double> &variable, const long double *values); + void Write(Variable<std::complex<float>> &variable, + const std::complex<float> *values); + void Write(Variable<std::complex<double>> &variable, + const std::complex<double> *values); + void Write(Variable<std::complex<long double>> &variable, + const std::complex<long double> *values); + void Write(VariableCompound &variable, const void *values); + + void Write(const std::string variableName, const char *values); + void Write(const std::string variableName, const unsigned char *values); + void Write(const std::string variableName, const short *values); + void Write(const std::string variableName, const unsigned short *values); + void Write(const std::string variableName, const int *values); + void Write(const std::string variableName, const unsigned int *values); + void Write(const std::string variableName, const long int *values); + void Write(const std::string variableName, const unsigned long int *values); + void Write(const std::string variableName, const long long int *values); + void Write(const std::string variableName, + const unsigned long long int *values); + void Write(const std::string variableName, const float *values); + void Write(const std::string variableName, const double *values); + void Write(const std::string variableName, const long double *values); + void Write(const std::string variableName, const std::complex<float> *values); + void Write(const std::string variableName, + const std::complex<double> *values); + void Write(const std::string variableName, + const std::complex<long double> *values); + void Write(const std::string variableName, const void *values); + + void Advance(); + + /** + * Closes a single transport or all transports + * @param transportIndex, if -1 (default) closes all transports, otherwise it + * closes a transport in m_Transport[transportIndex]. In debug mode the latter + * is bounds-checked. + */ + void Close(const int transportIndex = -1); private: - - const char * m_groupname; ///< ADIOS1 group name created from the method's name. Must be a unique group name. - const char * m_filename; ///< Save file name from constructor for Advance() when we re-open in ADIOS1 - MPI_Comm m_comm; ///< Save MPI communicator from constructor for Advance() when we re-open in ADIOS1 - - bool m_initialized = false; ///< set to true after calling adios_init() - int64_t m_adios_file = 0; ///< ADIOS1 file handler returned by adios_open() - int64_t m_adios_group = 0; ///< ADIOS1 group pointer that holds the ADIOS1 variable definitions - bool m_IsFileOpen = false; - - void Init( ); - // these are unused yet, keeping here to see if we need them - void InitParameters( ); - void InitTransports( ); - void InitProcessGroup( ); - - bool ReOpenAsNeeded( ); // return true if file is open or reopened - void DefineVariable( std::string name, bool isScalar, enum ADIOS_DATATYPES vartype, - std::string ldims, std::string gdims, std::string offs ); - void WriteVariable( std::string name, bool isScalar, enum ADIOS_DATATYPES vartype, - std::string ldims, std::string gdims, std::string offs, const void * values ); - + const char *m_groupname; ///< ADIOS1 group name created from the method's + ///name. Must be a unique group name. + const char *m_filename; ///< Save file name from constructor for Advance() + ///when we re-open in ADIOS1 + MPI_Comm m_comm; ///< Save MPI communicator from constructor for Advance() + ///when we re-open in ADIOS1 + + bool m_initialized = false; ///< set to true after calling adios_init() + int64_t m_adios_file = 0; ///< ADIOS1 file handler returned by adios_open() + int64_t m_adios_group = + 0; ///< ADIOS1 group pointer that holds the ADIOS1 variable definitions + bool m_IsFileOpen = false; + + void Init(); + // these are unused yet, keeping here to see if we need them + void InitParameters(); + void InitTransports(); + void InitProcessGroup(); + + bool ReOpenAsNeeded(); // return true if file is open or reopened + void DefineVariable(std::string name, bool isScalar, + enum ADIOS_DATATYPES vartype, std::string ldims, + std::string gdims, std::string offs); + void WriteVariable(std::string name, bool isScalar, + enum ADIOS_DATATYPES vartype, std::string ldims, + std::string gdims, std::string offs, const void *values); }; - -} //end namespace adios - +} // end namespace adios #endif /* ADIOS1WRITER_H_ */ diff --git a/include/engine/bp/BPFileReader.h b/include/engine/bp/BPFileReader.h index 445713c97..3cfdc39dc 100644 --- a/include/engine/bp/BPFileReader.h +++ b/include/engine/bp/BPFileReader.h @@ -12,91 +12,108 @@ #include "core/Engine.h" -//supported capsules +// supported capsules #include "capsule/heap/STLVector.h" - namespace adios { - class BPFileReader : public Engine { public: - - /** - * Constructor for single BP capsule engine, writes in BP format into a single heap capsule - * @param name unique name given to the engine - * @param accessMode - * @param mpiComm - * @param method - * @param debugMode - * @param hostLanguage - */ - BPFileReader( ADIOS& adios, const std::string name, const std::string accessMode, MPI_Comm mpiComm, - const Method& method, const IOMode iomode, const float timeout_sec, - const bool debugMode = false, const unsigned int nthreads = 1 ); - - ~BPFileReader( ); - - - Variable<void>* InquireVariable( const std::string name, const bool readIn = true ); - Variable<char>* InquireVariableChar( const std::string name, const bool readIn = true ); - Variable<unsigned char>* InquireVariableUChar( const std::string name, const bool readIn = true ); - Variable<short>* InquireVariableShort( const std::string name, const bool readIn = true ); - Variable<unsigned short>* InquireVariableUShort( const std::string name, const bool readIn = true ); - Variable<int>* InquireVariableInt( const std::string name, const bool readIn = true ); - Variable<unsigned int>* InquireVariableUInt( const std::string name, const bool readIn = true ); - Variable<long int>* InquireVariableLInt( const std::string name, const bool readIn = true ); - Variable<unsigned long int>* InquireVariableULInt( const std::string name, const bool readIn = true ); - Variable<long long int>* InquireVariableLLInt( const std::string name, const bool readIn = true ); - Variable<unsigned long long int>* InquireVariableULLInt( const std::string name, const bool readIn = true ); - Variable<float>* InquireVariableFloat( const std::string name, const bool readIn = true ); - Variable<double>* InquireVariableDouble( const std::string name, const bool readIn = true ); - Variable<long double>* InquireVariableLDouble( const std::string name, const bool readIn = true ); - Variable<std::complex<float>>* InquireVariableCFloat( const std::string name, const bool readIn = true ); - Variable<std::complex<double>>* InquireVariableCDouble( const std::string name, const bool readIn = true ); - Variable<std::complex<long double>>* InquireVariableCLDouble( const std::string name, const bool readIn = true ); - - /** - * Not implemented - * @param name - * @param readIn - * @return - */ - VariableCompound* InquireVariableCompound( const std::string name, const bool readIn = true ); - - - void Close( const int transportIndex = -1 ); + /** + * Constructor for single BP capsule engine, writes in BP format into a single + * heap capsule + * @param name unique name given to the engine + * @param accessMode + * @param mpiComm + * @param method + * @param debugMode + * @param hostLanguage + */ + BPFileReader(ADIOS &adios, const std::string name, + const std::string accessMode, MPI_Comm mpiComm, + const Method &method, const IOMode iomode, + const float timeout_sec, const bool debugMode = false, + const unsigned int nthreads = 1); + + ~BPFileReader(); + + Variable<void> *InquireVariable(const std::string name, + const bool readIn = true); + Variable<char> *InquireVariableChar(const std::string name, + const bool readIn = true); + Variable<unsigned char> *InquireVariableUChar(const std::string name, + const bool readIn = true); + Variable<short> *InquireVariableShort(const std::string name, + const bool readIn = true); + Variable<unsigned short> *InquireVariableUShort(const std::string name, + const bool readIn = true); + Variable<int> *InquireVariableInt(const std::string name, + const bool readIn = true); + Variable<unsigned int> *InquireVariableUInt(const std::string name, + const bool readIn = true); + Variable<long int> *InquireVariableLInt(const std::string name, + const bool readIn = true); + Variable<unsigned long int> *InquireVariableULInt(const std::string name, + const bool readIn = true); + Variable<long long int> *InquireVariableLLInt(const std::string name, + const bool readIn = true); + Variable<unsigned long long int> * + InquireVariableULLInt(const std::string name, const bool readIn = true); + Variable<float> *InquireVariableFloat(const std::string name, + const bool readIn = true); + Variable<double> *InquireVariableDouble(const std::string name, + const bool readIn = true); + Variable<long double> *InquireVariableLDouble(const std::string name, + const bool readIn = true); + Variable<std::complex<float>> * + InquireVariableCFloat(const std::string name, const bool readIn = true); + Variable<std::complex<double>> * + InquireVariableCDouble(const std::string name, const bool readIn = true); + Variable<std::complex<long double>> * + InquireVariableCLDouble(const std::string name, const bool readIn = true); + + /** + * Not implemented + * @param name + * @param readIn + * @return + */ + VariableCompound *InquireVariableCompound(const std::string name, + const bool readIn = true); + + void Close(const int transportIndex = -1); private: - - capsule::STLVector m_Buffer; ///< heap capsule, contains data and metadata buffers - //format::BP1Writer m_BP1Writer; ///< format object will provide the required BP functionality to be applied on m_Buffer and m_Transports - - void Init( ); ///< calls InitCapsules and InitTransports based on Method, called from constructor - void InitCapsules( ); - void InitTransports( ); ///< from Transports - - std::string GetMdtmParameter( const std::string parameter, const std::map<std::string,std::string>& mdtmParameters ); - - - template< class T > - Variable<T>* InquireVariableCommon( const std::string name, const bool readIn ) - { - std::cout << "Hello BPReaderCommon\n"; - - //here read variable metadata (dimensions, type, etc.)...then create a Variable like below: - //Variable<T>& variable = m_ADIOS.DefineVariable<T>( m_Name + "/" + name, ) - //return &variable; //return address if success - return nullptr; //on failure - } + capsule::STLVector + m_Buffer; ///< heap capsule, contains data and metadata buffers + // format::BP1Writer m_BP1Writer; ///< format object will provide the required + // BP functionality to be applied on m_Buffer and m_Transports + + void Init(); ///< calls InitCapsules and InitTransports based on Method, + ///called from constructor + void InitCapsules(); + void InitTransports(); ///< from Transports + + std::string + GetMdtmParameter(const std::string parameter, + const std::map<std::string, std::string> &mdtmParameters); + + template <class T> + Variable<T> *InquireVariableCommon(const std::string name, const bool readIn) + { + std::cout << "Hello BPReaderCommon\n"; + + // here read variable metadata (dimensions, type, etc.)...then create a + // Variable like below: + // Variable<T>& variable = m_ADIOS.DefineVariable<T>( m_Name + "/" + name, ) + // return &variable; //return address if success + return nullptr; // on failure + } }; - - -} //end namespace adios - +} // end namespace adios #endif /* BPFILEREADER_H_ */ diff --git a/include/engine/bp/BPFileWriter.h b/include/engine/bp/BPFileWriter.h index 923d0b227..ac9f5d008 100644 --- a/include/engine/bp/BPFileWriter.h +++ b/include/engine/bp/BPFileWriter.h @@ -9,13 +9,12 @@ #define BPFILEWRITER_H_ #include "core/Engine.h" -#include "format/BP1Writer.h" #include "format/BP1Aggregator.h" +#include "format/BP1Writer.h" -//supported capsules +// supported capsules #include "capsule/heap/STLVector.h" - namespace adios { @@ -23,138 +22,159 @@ class BPFileWriter : public Engine { public: - - /** - * Constructor for Writer writes in BP format into a single heap capsule, manages several transports - * @param name unique name given to the engine - * @param accessMode - * @param mpiComm - * @param method - * @param debugMode - */ - BPFileWriter( ADIOS& adios, const std::string name, const std::string accessMode, MPI_Comm mpiComm, - const Method& method, const IOMode iomode = IOMode::INDEPENDENT, const float timeout_sec = 0., - const bool debugMode = false, const unsigned int nthreads = 1 ); - - ~BPFileWriter( ); - - void Write( Variable<char>& variable, const char* values ); - void Write( Variable<unsigned char>& variable, const unsigned char* values ); - void Write( Variable<short>& variable, const short* values ); - void Write( Variable<unsigned short>& variable, const unsigned short* values ); - void Write( Variable<int>& variable, const int* values ); - void Write( Variable<unsigned int>& variable, const unsigned int* values ); - void Write( Variable<long int>& variable, const long int* values ); - void Write( Variable<unsigned long int>& variable, const unsigned long int* values ); - void Write( Variable<long long int>& variable, const long long int* values ); - void Write( Variable<unsigned long long int>& variable, const unsigned long long int* values ); - void Write( Variable<float>& variable, const float* values ); - void Write( Variable<double>& variable, const double* values ); - void Write( Variable<long double>& variable, const long double* values ); - void Write( Variable<std::complex<float>>& variable, const std::complex<float>* values ); - void Write( Variable<std::complex<double>>& variable, const std::complex<double>* values ); - void Write( Variable<std::complex<long double>>& variable, const std::complex<long double>* values ); - void Write( VariableCompound& variable, const void* values ); - - void Write( const std::string variableName, const char* values ); - void Write( const std::string variableName, const unsigned char* values ); - void Write( const std::string variableName, const short* values ); - void Write( const std::string variableName, const unsigned short* values ); - void Write( const std::string variableName, const int* values ); - void Write( const std::string variableName, const unsigned int* values ); - void Write( const std::string variableName, const long int* values ); - void Write( const std::string variableName, const unsigned long int* values ); - void Write( const std::string variableName, const long long int* values ); - void Write( const std::string variableName, const unsigned long long int* values ); - void Write( const std::string variableName, const float* values ); - void Write( const std::string variableName, const double* values ); - void Write( const std::string variableName, const long double* values ); - void Write( const std::string variableName, const std::complex<float>* values ); - void Write( const std::string variableName, const std::complex<double>* values ); - void Write( const std::string variableName, const std::complex<long double>* values ); - void Write( const std::string variableName, const void* values ); - - void Advance( float timeout_sec = 0.0 ); - - /** - * Closes a single transport or all transports - * @param transportIndex, if -1 (default) closes all transports, otherwise it closes a transport in m_Transport[transportIndex]. In debug mode the latter is bounds-checked. - */ - void Close( const int transportIndex = -1 ); - + /** + * Constructor for Writer writes in BP format into a single heap capsule, + * manages several transports + * @param name unique name given to the engine + * @param accessMode + * @param mpiComm + * @param method + * @param debugMode + */ + BPFileWriter(ADIOS &adios, const std::string name, + const std::string accessMode, MPI_Comm mpiComm, + const Method &method, const IOMode iomode = IOMode::INDEPENDENT, + const float timeout_sec = 0., const bool debugMode = false, + const unsigned int nthreads = 1); + + ~BPFileWriter(); + + void Write(Variable<char> &variable, const char *values); + void Write(Variable<unsigned char> &variable, const unsigned char *values); + void Write(Variable<short> &variable, const short *values); + void Write(Variable<unsigned short> &variable, const unsigned short *values); + void Write(Variable<int> &variable, const int *values); + void Write(Variable<unsigned int> &variable, const unsigned int *values); + void Write(Variable<long int> &variable, const long int *values); + void Write(Variable<unsigned long int> &variable, + const unsigned long int *values); + void Write(Variable<long long int> &variable, const long long int *values); + void Write(Variable<unsigned long long int> &variable, + const unsigned long long int *values); + void Write(Variable<float> &variable, const float *values); + void Write(Variable<double> &variable, const double *values); + void Write(Variable<long double> &variable, const long double *values); + void Write(Variable<std::complex<float>> &variable, + const std::complex<float> *values); + void Write(Variable<std::complex<double>> &variable, + const std::complex<double> *values); + void Write(Variable<std::complex<long double>> &variable, + const std::complex<long double> *values); + void Write(VariableCompound &variable, const void *values); + + void Write(const std::string variableName, const char *values); + void Write(const std::string variableName, const unsigned char *values); + void Write(const std::string variableName, const short *values); + void Write(const std::string variableName, const unsigned short *values); + void Write(const std::string variableName, const int *values); + void Write(const std::string variableName, const unsigned int *values); + void Write(const std::string variableName, const long int *values); + void Write(const std::string variableName, const unsigned long int *values); + void Write(const std::string variableName, const long long int *values); + void Write(const std::string variableName, + const unsigned long long int *values); + void Write(const std::string variableName, const float *values); + void Write(const std::string variableName, const double *values); + void Write(const std::string variableName, const long double *values); + void Write(const std::string variableName, const std::complex<float> *values); + void Write(const std::string variableName, + const std::complex<double> *values); + void Write(const std::string variableName, + const std::complex<long double> *values); + void Write(const std::string variableName, const void *values); + + void Advance(float timeout_sec = 0.0); + + /** + * Closes a single transport or all transports + * @param transportIndex, if -1 (default) closes all transports, otherwise it + * closes a transport in m_Transport[transportIndex]. In debug mode the latter + * is bounds-checked. + */ + void Close(const int transportIndex = -1); private: - - capsule::STLVector m_Buffer; ///< heap capsule using STL std::vector<char> - format::BP1Writer m_BP1Writer; ///< format object will provide the required BP functionality to be applied on m_Buffer and m_Transports - format::BP1MetadataSet m_MetadataSet; ///< metadata set accompanying the heap buffer data in bp format. Needed by m_BP1Writer - format::BP1Aggregator m_BP1Aggregator; - - bool m_IsFirstClose = true; ///< set to false after first Close is reached so metadata doesn't have to be accommodated for a subsequent Close - std::size_t m_MaxBufferSize; ///< maximum allowed memory to be allocated - float m_GrowthFactor = 1.5; ///< capsule memory growth factor, new_memory = m_GrowthFactor * current_memory - - bool m_TransportFlush = false; ///< true: transport flush happened, buffer must be reset - bool m_CloseProcessGroup = false; ///< set to true if advance is called, this prevents flattening the data and metadata in Close - - void Init( ); - void InitParameters( ); - void InitTransports( ); - void InitProcessGroup( ); - - void WriteProcessGroupIndex( ); - - /** - * Common function for primitive (including std::complex) writes - * @param group - * @param variableName - * @param variable - */ - template< class T > - void WriteVariableCommon( Variable<T>& variable, const T* values ) + capsule::STLVector m_Buffer; ///< heap capsule using STL std::vector<char> + format::BP1Writer m_BP1Writer; ///< format object will provide the required BP + ///functionality to be applied on m_Buffer and + ///m_Transports + format::BP1MetadataSet m_MetadataSet; ///< metadata set accompanying the heap + ///buffer data in bp format. Needed by + ///m_BP1Writer + format::BP1Aggregator m_BP1Aggregator; + + bool m_IsFirstClose = true; ///< set to false after first Close is reached so + ///metadata doesn't have to be accommodated for a + ///subsequent Close + std::size_t m_MaxBufferSize; ///< maximum allowed memory to be allocated + float m_GrowthFactor = 1.5; ///< capsule memory growth factor, new_memory = + ///m_GrowthFactor * current_memory + + bool m_TransportFlush = + false; ///< true: transport flush happened, buffer must be reset + bool m_CloseProcessGroup = false; ///< set to true if advance is called, this + ///prevents flattening the data and metadata + ///in Close + + void Init(); + void InitParameters(); + void InitTransports(); + void InitProcessGroup(); + + void WriteProcessGroupIndex(); + + /** + * Common function for primitive (including std::complex) writes + * @param group + * @param variableName + * @param variable + */ + template <class T> + void WriteVariableCommon(Variable<T> &variable, const T *values) + { + if (m_MetadataSet.Log.m_IsActive == true) + m_MetadataSet.Log.m_Timers[0].SetInitialTime(); + + // set variable + variable.m_AppValues = values; + m_WrittenVariables.insert(variable.m_Name); + + // if first timestep Write + if (m_MetadataSet.DataPGIsOpen == false) // create a new pg index + WriteProcessGroupIndex(); + + // pre-calculate new metadata and payload sizes + // m_TransportFlush = CheckBufferAllocation( + // m_BP1Writer.GetVariableIndexSize( variable ) + + // variable.PayLoadSize(), + // m_GrowthFactor, + // m_MaxBufferSize, + // m_Buffer.m_Data ); + + // WRITE INDEX to data buffer and metadata structure (in memory)// + m_BP1Writer.WriteVariableMetadata(variable, m_Buffer, m_MetadataSet); + + if (m_TransportFlush == true) // in batches { - if( m_MetadataSet.Log.m_IsActive == true ) - m_MetadataSet.Log.m_Timers[0].SetInitialTime(); - - //set variable - variable.m_AppValues = values; - m_WrittenVariables.insert( variable.m_Name ); - - //if first timestep Write - if( m_MetadataSet.DataPGIsOpen == false ) //create a new pg index - WriteProcessGroupIndex( ); - - //pre-calculate new metadata and payload sizes -// m_TransportFlush = CheckBufferAllocation( m_BP1Writer.GetVariableIndexSize( variable ) + variable.PayLoadSize(), -// m_GrowthFactor, m_MaxBufferSize, m_Buffer.m_Data ); - - //WRITE INDEX to data buffer and metadata structure (in memory)// - m_BP1Writer.WriteVariableMetadata( variable, m_Buffer, m_MetadataSet ); + // write pg index - if( m_TransportFlush == true ) //in batches - { - //write pg index + // flush to transports - //flush to transports - - //reset relative positions to zero, update absolute position - - } - else //Write data to buffer - { - m_BP1Writer.WriteVariablePayload( variable, m_Buffer, m_nThreads ); - } - - variable.m_AppValues = nullptr; //setting pointer to null as not needed after write - - if( m_MetadataSet.Log.m_IsActive == true ) - m_MetadataSet.Log.m_Timers[0].SetTime(); + // reset relative positions to zero, update absolute position + } + else // Write data to buffer + { + m_BP1Writer.WriteVariablePayload(variable, m_Buffer, m_nThreads); } -}; - + variable.m_AppValues = + nullptr; // setting pointer to null as not needed after write -} //end namespace adios + if (m_MetadataSet.Log.m_IsActive == true) + m_MetadataSet.Log.m_Timers[0].SetTime(); + } +}; +} // end namespace adios #endif /* BPFILEWRITER_H_ */ diff --git a/include/engine/dataman/DataManReader.h b/include/engine/dataman/DataManReader.h index 85a02c061..0f8d66a55 100644 --- a/include/engine/dataman/DataManReader.h +++ b/include/engine/dataman/DataManReader.h @@ -13,7 +13,7 @@ #include "core/Engine.h" #include "format/BP1Writer.h" -//supported capsules +// supported capsules #include "capsule/heap/STLVector.h" #include "DataManager.h" @@ -25,93 +25,116 @@ class DataManReader : public Engine { public: - - /** - * Constructor for dataman engine Reader for WAN communications - * @param adios - * @param name - * @param accessMode - * @param mpiComm - * @param method - * @param debugMode - * @param nthreads - */ - DataManReader( ADIOS& adios, const std::string name, const std::string accessMode, MPI_Comm mpiComm, - const Method& method, const IOMode iomode, const float timeout_sec, - const bool debugMode = false, const unsigned int nthreads = 1 ); - - ~DataManReader( ); - - /** - * Set callback function from user application - * @param callback function (get) provided by the user to be applied in DataMan - */ - void SetCallBack( std::function<void( const void*, std::string, std::string, std::string, Dims )> callback ); - - Variable<void>* InquireVariable( const std::string name, const bool readIn = true ); - Variable<char>* InquireVariableChar( const std::string name, const bool readIn = true ); - Variable<unsigned char>* InquireVariableUChar( const std::string name, const bool readIn = true ); - Variable<short>* InquireVariableShort( const std::string name, const bool readIn = true ); - Variable<unsigned short>* InquireVariableUShort( const std::string name, const bool readIn = true ); - Variable<int>* InquireVariableInt( const std::string name, const bool readIn = true ); - Variable<unsigned int>* InquireVariableUInt( const std::string name, const bool readIn = true ); - Variable<long int>* InquireVariableLInt( const std::string name, const bool readIn = true ); - Variable<unsigned long int>* InquireVariableULInt( const std::string name, const bool readIn = true ); - Variable<long long int>* InquireVariableLLInt( const std::string name, const bool readIn = true ); - Variable<unsigned long long int>* InquireVariableULLInt( const std::string name, const bool readIn = true ); - Variable<float>* InquireVariableFloat( const std::string name, const bool readIn = true ); - Variable<double>* InquireVariableDouble( const std::string name, const bool readIn = true ); - Variable<long double>* InquireVariableLDouble( const std::string name, const bool readIn = true ); - Variable<std::complex<float>>* InquireVariableCFloat( const std::string name, const bool readIn = true ); - Variable<std::complex<double>>* InquireVariableCDouble( const std::string name, const bool readIn = true ); - Variable<std::complex<long double>>* InquireVariableCLDouble( const std::string name, const bool readIn = true ); - - /** - * Not implemented - * @param name - * @param readIn - * @return - */ - VariableCompound* InquireVariableCompound( const std::string name, const bool readIn = true ); - - - void Close( const int transportIndex = -1 ); + /** + * Constructor for dataman engine Reader for WAN communications + * @param adios + * @param name + * @param accessMode + * @param mpiComm + * @param method + * @param debugMode + * @param nthreads + */ + DataManReader(ADIOS &adios, const std::string name, + const std::string accessMode, MPI_Comm mpiComm, + const Method &method, const IOMode iomode, + const float timeout_sec, const bool debugMode = false, + const unsigned int nthreads = 1); + + ~DataManReader(); + + /** + * Set callback function from user application + * @param callback function (get) provided by the user to be applied in + * DataMan + */ + void SetCallBack(std::function<void(const void *, std::string, std::string, + std::string, Dims)> + callback); + + Variable<void> *InquireVariable(const std::string name, + const bool readIn = true); + Variable<char> *InquireVariableChar(const std::string name, + const bool readIn = true); + Variable<unsigned char> *InquireVariableUChar(const std::string name, + const bool readIn = true); + Variable<short> *InquireVariableShort(const std::string name, + const bool readIn = true); + Variable<unsigned short> *InquireVariableUShort(const std::string name, + const bool readIn = true); + Variable<int> *InquireVariableInt(const std::string name, + const bool readIn = true); + Variable<unsigned int> *InquireVariableUInt(const std::string name, + const bool readIn = true); + Variable<long int> *InquireVariableLInt(const std::string name, + const bool readIn = true); + Variable<unsigned long int> *InquireVariableULInt(const std::string name, + const bool readIn = true); + Variable<long long int> *InquireVariableLLInt(const std::string name, + const bool readIn = true); + Variable<unsigned long long int> * + InquireVariableULLInt(const std::string name, const bool readIn = true); + Variable<float> *InquireVariableFloat(const std::string name, + const bool readIn = true); + Variable<double> *InquireVariableDouble(const std::string name, + const bool readIn = true); + Variable<long double> *InquireVariableLDouble(const std::string name, + const bool readIn = true); + Variable<std::complex<float>> * + InquireVariableCFloat(const std::string name, const bool readIn = true); + Variable<std::complex<double>> * + InquireVariableCDouble(const std::string name, const bool readIn = true); + Variable<std::complex<long double>> * + InquireVariableCLDouble(const std::string name, const bool readIn = true); + + /** + * Not implemented + * @param name + * @param readIn + * @return + */ + VariableCompound *InquireVariableCompound(const std::string name, + const bool readIn = true); + + void Close(const int transportIndex = -1); private: - - capsule::STLVector m_Buffer; ///< heap capsule, contains data and metadata buffers - format::BP1Writer m_BP1Writer; ///< format object will provide the required BP functionality to be applied on m_Buffer and m_Transports - - bool m_DoRealTime = false; - DataManager m_Man; - std::function<void( const void*, std::string, std::string, std::string, Dims )> m_CallBack; ///< call back function - - void Init( ); ///< calls InitCapsules and InitTransports based on Method, called from constructor - void InitCapsules( ); - void InitTransports( ); ///< from Transports - - std::string GetMdtmParameter( const std::string parameter, const std::map<std::string,std::string>& mdtmParameters ); - - - template< class T > - Variable<T>* InquireVariableCommon( const std::string name, const bool readIn ) - { - std::cout << "I am hooked to the DataMan library\n"; - std::cout << "Hello DatamanReader from rank " << m_RankMPI << "\n"; - std::cout << "Trying to read variable " << name << " from one of the variables coming from a WAN transport\n"; - - //here read variable metadata (dimensions, type, etc.)...then create a Variable like below: - //Variable<T>& variable = m_ADIOS.DefineVariable<T>( m_Name + "/" + name, ) - //return &variable; //return address if success - return nullptr; //on failure - } - - - + capsule::STLVector + m_Buffer; ///< heap capsule, contains data and metadata buffers + format::BP1Writer m_BP1Writer; ///< format object will provide the required BP + ///functionality to be applied on m_Buffer and + ///m_Transports + + bool m_DoRealTime = false; + DataManager m_Man; + std::function<void(const void *, std::string, std::string, std::string, Dims)> + m_CallBack; ///< call back function + + void Init(); ///< calls InitCapsules and InitTransports based on Method, + ///called from constructor + void InitCapsules(); + void InitTransports(); ///< from Transports + + std::string + GetMdtmParameter(const std::string parameter, + const std::map<std::string, std::string> &mdtmParameters); + + template <class T> + Variable<T> *InquireVariableCommon(const std::string name, const bool readIn) + { + std::cout << "I am hooked to the DataMan library\n"; + std::cout << "Hello DatamanReader from rank " << m_RankMPI << "\n"; + std::cout << "Trying to read variable " << name + << " from one of the variables coming from a WAN transport\n"; + + // here read variable metadata (dimensions, type, etc.)...then create a + // Variable like below: + // Variable<T>& variable = m_ADIOS.DefineVariable<T>( m_Name + "/" + name, ) + // return &variable; //return address if success + return nullptr; // on failure + } }; - -} //end namespace - +} // end namespace #endif /* DATAMANREADER_H_ */ diff --git a/include/engine/dataman/DataManWriter.h b/include/engine/dataman/DataManWriter.h index 106ae0ef9..ea5b8f6dc 100644 --- a/include/engine/dataman/DataManWriter.h +++ b/include/engine/dataman/DataManWriter.h @@ -14,12 +14,10 @@ #include "core/Engine.h" #include "format/BP1Writer.h" -//supported capsules +// supported capsules #include "capsule/heap/STLVector.h" - -#include "DataManager.h" //here comes your DataMan header - +#include "DataManager.h" //here comes your DataMan header namespace adios { @@ -28,136 +26,151 @@ class DataManWriter : public Engine { public: - - /** - * Constructor for dataman engine Writer for WAN communications - * @param adios - * @param name unique name given to the engine - * @param accessMode - * @param mpiComm - * @param method - * @param debugMode - * @param nthreads - */ - DataManWriter( ADIOS& adios, const std::string name, const std::string accessMode, MPI_Comm mpiComm, - const Method& method, const IOMode iomode, const float timeout_sec, - const bool debugMode = false, const unsigned int nthreads = 1 ); - - ~DataManWriter( ); - - void SetCallBack( std::function<void( const void*, std::string, std::string, std::string, Dims )> callback ); - - void Write( Variable<char>& variable, const char* values ); - void Write( Variable<unsigned char>& variable, const unsigned char* values ); - void Write( Variable<short>& variable, const short* values ); - void Write( Variable<unsigned short>& variable, const unsigned short* values ); - void Write( Variable<int>& variable, const int* values ); - void Write( Variable<unsigned int>& variable, const unsigned int* values ); - void Write( Variable<long int>& variable, const long int* values ); - void Write( Variable<unsigned long int>& variable, const unsigned long int* values ); - void Write( Variable<long long int>& variable, const long long int* values ); - void Write( Variable<unsigned long long int>& variable, const unsigned long long int* values ) ; - void Write( Variable<float>& variable, const float* values ); - void Write( Variable<double>& variable, const double* values ); - void Write( Variable<long double>& variable, const long double* values ); - void Write( Variable<std::complex<float>>& variable, const std::complex<float>* values ); - void Write( Variable<std::complex<double>>& variable, const std::complex<double>* values ); - void Write( Variable<std::complex<long double>>& variable, const std::complex<long double>* values ); - - void Write( const std::string variableName, const char* values ); - void Write( const std::string variableName, const unsigned char* values ); - void Write( const std::string variableName, const short* values ); - void Write( const std::string variableName, const unsigned short* values ); - void Write( const std::string variableName, const int* values ); - void Write( const std::string variableName, const unsigned int* values ); - void Write( const std::string variableName, const long int* values ); - void Write( const std::string variableName, const unsigned long int* values ); - void Write( const std::string variableName, const long long int* values ); - void Write( const std::string variableName, const unsigned long long int* values ); - void Write( const std::string variableName, const float* values ); - void Write( const std::string variableName, const double* values ); - void Write( const std::string variableName, const long double* values ); - void Write( const std::string variableName, const std::complex<float>* values ); - void Write( const std::string variableName, const std::complex<double>* values ); - void Write( const std::string variableName, const std::complex<long double>* values ); - - void Close( const int transportIndex = -1 ); + /** + * Constructor for dataman engine Writer for WAN communications + * @param adios + * @param name unique name given to the engine + * @param accessMode + * @param mpiComm + * @param method + * @param debugMode + * @param nthreads + */ + DataManWriter(ADIOS &adios, const std::string name, + const std::string accessMode, MPI_Comm mpiComm, + const Method &method, const IOMode iomode, + const float timeout_sec, const bool debugMode = false, + const unsigned int nthreads = 1); + + ~DataManWriter(); + + void SetCallBack(std::function<void(const void *, std::string, std::string, + std::string, Dims)> + callback); + + void Write(Variable<char> &variable, const char *values); + void Write(Variable<unsigned char> &variable, const unsigned char *values); + void Write(Variable<short> &variable, const short *values); + void Write(Variable<unsigned short> &variable, const unsigned short *values); + void Write(Variable<int> &variable, const int *values); + void Write(Variable<unsigned int> &variable, const unsigned int *values); + void Write(Variable<long int> &variable, const long int *values); + void Write(Variable<unsigned long int> &variable, + const unsigned long int *values); + void Write(Variable<long long int> &variable, const long long int *values); + void Write(Variable<unsigned long long int> &variable, + const unsigned long long int *values); + void Write(Variable<float> &variable, const float *values); + void Write(Variable<double> &variable, const double *values); + void Write(Variable<long double> &variable, const long double *values); + void Write(Variable<std::complex<float>> &variable, + const std::complex<float> *values); + void Write(Variable<std::complex<double>> &variable, + const std::complex<double> *values); + void Write(Variable<std::complex<long double>> &variable, + const std::complex<long double> *values); + + void Write(const std::string variableName, const char *values); + void Write(const std::string variableName, const unsigned char *values); + void Write(const std::string variableName, const short *values); + void Write(const std::string variableName, const unsigned short *values); + void Write(const std::string variableName, const int *values); + void Write(const std::string variableName, const unsigned int *values); + void Write(const std::string variableName, const long int *values); + void Write(const std::string variableName, const unsigned long int *values); + void Write(const std::string variableName, const long long int *values); + void Write(const std::string variableName, + const unsigned long long int *values); + void Write(const std::string variableName, const float *values); + void Write(const std::string variableName, const double *values); + void Write(const std::string variableName, const long double *values); + void Write(const std::string variableName, const std::complex<float> *values); + void Write(const std::string variableName, + const std::complex<double> *values); + void Write(const std::string variableName, + const std::complex<long double> *values); + + void Close(const int transportIndex = -1); private: - - capsule::STLVector m_Buffer; ///< heap capsule, contains data and metadata buffers - format::BP1Writer m_BP1Writer; ///< format object will provide the required BP functionality to be applied on m_Buffer and m_Transports - - bool m_DoRealTime = false; - bool m_DoMonitor = false; - DataManager m_Man; - std::function<void( const void*, std::string, std::string, std::string, Dims )> m_CallBack; ///< call back function - - void Init( ); ///< calls InitCapsules and InitTransports based on Method, called from constructor - void InitCapsules( ); - void InitTransports( ); ///< from Transports - - /** - * From transport Mdtm in m_Method - * @param parameter must be an accepted parameter - * @param mdtmParameters - * @return value either returns user-defined from "parameter=value" or a default - */ - std::string GetMdtmParameter( const std::string parameter, const std::map<std::string,std::string>& mdtmParameters ); - - - template<class T> - void WriteVariableCommon( Variable<T>& variable, const T* values ) + capsule::STLVector + m_Buffer; ///< heap capsule, contains data and metadata buffers + format::BP1Writer m_BP1Writer; ///< format object will provide the required BP + ///functionality to be applied on m_Buffer and + ///m_Transports + + bool m_DoRealTime = false; + bool m_DoMonitor = false; + DataManager m_Man; + std::function<void(const void *, std::string, std::string, std::string, Dims)> + m_CallBack; ///< call back function + + void Init(); ///< calls InitCapsules and InitTransports based on Method, + ///called from constructor + void InitCapsules(); + void InitTransports(); ///< from Transports + + /** + * From transport Mdtm in m_Method + * @param parameter must be an accepted parameter + * @param mdtmParameters + * @return value either returns user-defined from "parameter=value" or a + * default + */ + std::string + GetMdtmParameter(const std::string parameter, + const std::map<std::string, std::string> &mdtmParameters); + + template <class T> + void WriteVariableCommon(Variable<T> &variable, const T *values) + { + // here comes your magic at Writing now variable.m_UserValues has the data + // passed by the user + // set variable + variable.m_AppValues = values; + m_WrittenVariables.insert(variable.m_Name); + + // This part will go away, this is just to monitor variables per rank + + json jmsg; + jmsg["doid"] = m_Name; + jmsg["var"] = variable.m_Name; + jmsg["dtype"] = GetType<T>(); + jmsg["putshape"] = variable.m_Dimensions; + if (variable.m_GlobalDimensions.size() == 0) + variable.m_GlobalDimensions = variable.m_Dimensions; + jmsg["varshape"] = variable.m_GlobalDimensions; + if (variable.m_GlobalOffsets.size() == 0) + variable.m_GlobalOffsets.assign(variable.m_Dimensions.size(), 0); + jmsg["offset"] = variable.m_GlobalOffsets; + jmsg["timestep"] = 0; + m_Man.put(values, jmsg); + + if (m_DoMonitor) { - //here comes your magic at Writing now variable.m_UserValues has the data passed by the user - //set variable - variable.m_AppValues = values; - m_WrittenVariables.insert( variable.m_Name ); - - //This part will go away, this is just to monitor variables per rank - - json jmsg; - jmsg["doid"] = m_Name; - jmsg["var"] = variable.m_Name; - jmsg["dtype"] = GetType<T>(); - jmsg["putshape"] = variable.m_Dimensions; - if(variable.m_GlobalDimensions.size() == 0) variable.m_GlobalDimensions = variable.m_Dimensions; - jmsg["varshape"] = variable.m_GlobalDimensions; - if(variable.m_GlobalOffsets.size() == 0) variable.m_GlobalOffsets.assign(variable.m_Dimensions.size(),0); - jmsg["offset"] = variable.m_GlobalOffsets; - jmsg["timestep"] = 0; - m_Man.put(values, jmsg); - - if(m_DoMonitor){ - MPI_Barrier( m_MPIComm ); - std::cout << "I am hooked to the DataMan library\n"; - std::cout << "putshape " << variable.m_Dimensions.size() << endl; - std::cout << "varshape " << variable.m_GlobalDimensions.size() << endl; - std::cout << "offset " << variable.m_GlobalOffsets.size() << endl; - for( int i = 0; i < m_SizeMPI; ++i ) - { - if( i == m_RankMPI ) - { - std::cout << "Rank: " << m_RankMPI << "\n"; - variable.Monitor( std::cout ); - std::cout << std::endl; - } - else - { - sleep( 1 ); - } - } - MPI_Barrier( m_MPIComm ); + MPI_Barrier(m_MPIComm); + std::cout << "I am hooked to the DataMan library\n"; + std::cout << "putshape " << variable.m_Dimensions.size() << endl; + std::cout << "varshape " << variable.m_GlobalDimensions.size() << endl; + std::cout << "offset " << variable.m_GlobalOffsets.size() << endl; + for (int i = 0; i < m_SizeMPI; ++i) + { + if (i == m_RankMPI) + { + std::cout << "Rank: " << m_RankMPI << "\n"; + variable.Monitor(std::cout); + std::cout << std::endl; + } + else + { + sleep(1); } + } + MPI_Barrier(m_MPIComm); } - + } }; - -} //end namespace adios - - - - +} // end namespace adios #endif /* DATAMANWRITER_H_ */ diff --git a/include/format/BP1.h b/include/format/BP1.h index eed6b17be..3ff8f18b3 100644 --- a/include/format/BP1.h +++ b/include/format/BP1.h @@ -9,22 +9,21 @@ #define BP1_H_ /// \cond EXCLUDE_FROM_DOXYGEN -#include <memory> //std::shared_ptr #include <cstdint> //std::uintX_t +#include <memory> //std::shared_ptr #include <unordered_map> #include <vector> //#include <queue> //std::priority_queue to be added later /// \endcond #if ADIOS_NOMPI - #include "mpidummy.h" +#include "mpidummy.h" #else - #include <mpi.h> +#include <mpi.h> #endif -#include "core/Transport.h" #include "core/Profiler.h" - +#include "core/Transport.h" namespace adios { @@ -32,19 +31,20 @@ namespace format { /** - * Used for Variables and Attributes, needed in a container for characteristic sets merge independently for each Variable or Attribute + * Used for Variables and Attributes, needed in a container for characteristic + * sets merge independently for each Variable or Attribute */ struct BP1Index { - std::vector<char> Buffer; ///< metadata variable index, start with 100Kb - std::uint64_t Count = 0; ///< number of characteristics sets (time and spatial aggregation) - const std::uint32_t MemberID; - - BP1Index( const std::uint32_t memberID ): - MemberID{ memberID } - { - Buffer.reserve( 500 ); - } + std::vector<char> Buffer; ///< metadata variable index, start with 100Kb + std::uint64_t Count = + 0; ///< number of characteristics sets (time and spatial aggregation) + const std::uint32_t MemberID; + + BP1Index(const std::uint32_t memberID) : MemberID{memberID} + { + Buffer.reserve(500); + } }; /** @@ -52,24 +52,36 @@ struct BP1Index */ struct BP1MetadataSet { - std::uint32_t TimeStep; ///< current time step, updated with advance step, if append it will be updated to last, starts with one in ADIOS1 - - BP1Index PGIndex = BP1Index( 0 ); ///< single buffer for PGIndex - - //no priority for now - std::unordered_map< std::string, BP1Index > VarsIndices; ///< key: variable name, value: bp metadata variable index - std::unordered_map< std::string, BP1Index > AttributesIndices; ///< key: attribute name, value: bp metadata attribute index - - const unsigned int MiniFooterSize = 28; ///< from bpls reader - - //PG (relative) positions in Data buffer to be updated - std::uint64_t DataPGCount = 0; - std::size_t DataPGLengthPosition = 0; ///< current PG initial ( relative ) position, needs to be updated in every advance step or init - std::uint32_t DataPGVarsCount = 0; ///< variables in current PG - std::size_t DataPGVarsCountPosition = 0; ///< current PG variable count ( relative ) position, needs to be updated in every advance step or init - bool DataPGIsOpen = false; - - Profiler Log; ///< object that takes buffering profiling info + std::uint32_t TimeStep; ///< current time step, updated with advance step, if + ///append it will be updated to last, starts with one + ///in ADIOS1 + + BP1Index PGIndex = BP1Index(0); ///< single buffer for PGIndex + + // no priority for now + std::unordered_map<std::string, BP1Index> + VarsIndices; ///< key: variable name, value: bp metadata variable index + std::unordered_map<std::string, BP1Index> AttributesIndices; ///< key: + ///attribute + ///name, value: + ///bp metadata + ///attribute + ///index + + const unsigned int MiniFooterSize = 28; ///< from bpls reader + + // PG (relative) positions in Data buffer to be updated + std::uint64_t DataPGCount = 0; + std::size_t DataPGLengthPosition = 0; ///< current PG initial ( relative ) + ///position, needs to be updated in + ///every advance step or init + std::uint32_t DataPGVarsCount = 0; ///< variables in current PG + std::size_t DataPGVarsCountPosition = + 0; ///< current PG variable count ( relative ) position, needs to be + ///updated in every advance step or init + bool DataPGIsOpen = false; + + Profiler Log; ///< object that takes buffering profiling info }; /** @@ -79,178 +91,231 @@ class BP1 { public: - - /** - * Checks if input name has .bp extension and returns a .bp directory name - * @param name input (might or not have .bp) - * @return either name.bp (name has no .bp) or name (name has .bp extension) - */ - std::string GetDirectoryName( const std::string name ) const noexcept; - - /** - * Opens rank files in the following format: - * if transport.m_MPIComm different from MPI_Comm_SELF --> name.bp.dir/name.bp.rank - * @param name might contain .bp or not, if not .bp will be added - * @param accessMode "write" "w", "r" "read", "append" "a" - * @param transport file I/O transport - */ - void OpenRankFiles( const std::string name, const std::string accessMode, Transport& transport ) const; - + /** + * Checks if input name has .bp extension and returns a .bp directory name + * @param name input (might or not have .bp) + * @return either name.bp (name has no .bp) or name (name has .bp extension) + */ + std::string GetDirectoryName(const std::string name) const noexcept; + + /** + * Opens rank files in the following format: + * if transport.m_MPIComm different from MPI_Comm_SELF --> + * name.bp.dir/name.bp.rank + * @param name might contain .bp or not, if not .bp will be added + * @param accessMode "write" "w", "r" "read", "append" "a" + * @param transport file I/O transport + */ + void OpenRankFiles(const std::string name, const std::string accessMode, + Transport &transport) const; protected: - - /** - * method type for file I/O - */ - enum IO_METHOD { - METHOD_UNKNOWN = -2//!< ADIOS_METHOD_UNKNOWN - ,METHOD_NULL = -1 //!< ADIOS_METHOD_NULL - ,METHOD_MPI = 0 //!< METHOD_MPI - ,METHOD_DATATAP = 1 //OBSOLETE - ,METHOD_POSIX = 2 //!< METHOD_POSIX - ,METHOD_DATASPACES = 3 //!< METHOD_DATASPACES - ,METHOD_VTK = 4 //non-existent - ,METHOD_POSIX_ASCII = 5 //non-existent - ,METHOD_MPI_CIO = 6 //OBSOLETE - ,METHOD_PHDF5 = 7 //!< METHOD_PHDF5 - ,METHOD_PROVENANCE = 8 //OBSOLETE - ,METHOD_MPI_STRIPE = 9 //OBSOLETE - ,METHOD_MPI_LUSTRE = 10 //!< METHOD_MPI_LUSTRE - ,METHOD_MPI_STAGGER = 11 //OBSOLETE - ,METHOD_MPI_AGG = 12 //OBSOLETE - ,METHOD_ADAPTIVE = 13 //OBSOLETE - ,METHOD_POSIX1 = 14 //OBSOLETE - ,METHOD_NC4 = 15 //!< METHOD_NC4 - ,METHOD_MPI_AMR = 16 //!< METHOD_MPI_AMR - ,METHOD_MPI_AMR1 = 17 //OBSOLETE - ,METHOD_FLEXPATH = 18 //!< METHOD_FLEXPATH - ,METHOD_NSSI_STAGING = 19 //!< METHOD_NSSI_STAGING - ,METHOD_NSSI_FILTER = 20 //!< METHOD_NSSI_FILTER - ,METHOD_DIMES = 21 //!< METHOD_DIMES - ,METHOD_VAR_MERGE = 22 //!< METHOD_VAR_MERGE - ,METHOD_MPI_BGQ = 23 //!< METHOD_MPI_BGQ - ,METHOD_ICEE = 24 //!< METHOD_ICEE - ,METHOD_COUNT = 25 //!< METHOD_COUNT - ,METHOD_FSTREAM = 26 - ,METHOD_FILE = 27 - ,METHOD_ZMQ = 28 - ,METHOD_MDTM = 29 - }; - - - /** - * DataTypes mapping in BP Format - */ - enum DataTypes - { - type_unknown = -1, //!< type_unknown - type_byte = 0, //!< type_byte - type_short = 1, //!< type_short - type_integer = 2, //!< type_integer - type_long = 4, //!< type_long - - type_unsigned_byte = 50, //!< type_unsigned_byte - type_unsigned_short = 51, //!< type_unsigned_short - type_unsigned_integer = 52,//!< type_unsigned_integer - type_unsigned_long = 54, //!< type_unsigned_long - - type_real = 5, //!< type_real or float - type_double = 6, //!< type_double - type_long_double = 7, //!< type_long_double - - type_string = 9, //!< type_string - type_complex = 10, //!< type_complex - type_double_complex = 11, //!< type_double_complex - type_string_array = 12 //!< type_string_array - }; - - /** - * Characteristic ID in variable metadata - */ - enum VariableCharacteristicID - { - characteristic_value = 0, //!< characteristic_value - characteristic_min = 1, //!< Used to read in older bp file format - characteristic_max = 2, //!< Used to read in older bp file format - characteristic_offset = 3, //!< characteristic_offset - characteristic_dimensions = 4, //!< characteristic_dimensions - characteristic_var_id = 5, //!< characteristic_var_id - characteristic_payload_offset = 6, //!< characteristic_payload_offset - characteristic_file_index = 7, //!< characteristic_file_index - characteristic_time_index = 8, //!< characteristic_time_index - characteristic_bitmap = 9, //!< characteristic_bitmap - characteristic_stat = 10,//!< characteristic_stat - characteristic_transform_type = 11 //!< characteristic_transform_type - }; - - - /** Define statistics type for characteristic ID = 10 in bp1 format */ - enum VariableStatistics - { - statistic_min = 0, - statistic_max = 1, - statistic_cnt = 2, - statistic_sum = 3, - statistic_sum_square = 4, - statistic_hist = 5, - statistic_finite = 6 - }; - - template<class T> - struct Stats - { - T Min; - T Max; - std::uint64_t Offset; - std::uint64_t PayloadOffset; - std::uint32_t TimeIndex; - std::uint32_t MemberID; - - -// unsigned long int count; -// long double sum; -// long double sumSquare; - //unsigned long int histogram - //bool finite?? - }; - - - - /** - * Returns data type index from enum Datatypes - * @param variable input variable - * @return data type - */ - template< class T > inline std::int8_t GetDataType( ) const noexcept - { - return type_unknown; - } - - std::vector<std::uint8_t> GetMethodIDs( const std::vector< std::shared_ptr<Transport> >& transports ) const noexcept; - + /** + * method type for file I/O + */ + enum IO_METHOD + { + METHOD_UNKNOWN = -2 //!< ADIOS_METHOD_UNKNOWN + , + METHOD_NULL = -1 //!< ADIOS_METHOD_NULL + , + METHOD_MPI = 0 //!< METHOD_MPI + , + METHOD_DATATAP = 1 // OBSOLETE + , + METHOD_POSIX = 2 //!< METHOD_POSIX + , + METHOD_DATASPACES = 3 //!< METHOD_DATASPACES + , + METHOD_VTK = 4 // non-existent + , + METHOD_POSIX_ASCII = 5 // non-existent + , + METHOD_MPI_CIO = 6 // OBSOLETE + , + METHOD_PHDF5 = 7 //!< METHOD_PHDF5 + , + METHOD_PROVENANCE = 8 // OBSOLETE + , + METHOD_MPI_STRIPE = 9 // OBSOLETE + , + METHOD_MPI_LUSTRE = 10 //!< METHOD_MPI_LUSTRE + , + METHOD_MPI_STAGGER = 11 // OBSOLETE + , + METHOD_MPI_AGG = 12 // OBSOLETE + , + METHOD_ADAPTIVE = 13 // OBSOLETE + , + METHOD_POSIX1 = 14 // OBSOLETE + , + METHOD_NC4 = 15 //!< METHOD_NC4 + , + METHOD_MPI_AMR = 16 //!< METHOD_MPI_AMR + , + METHOD_MPI_AMR1 = 17 // OBSOLETE + , + METHOD_FLEXPATH = 18 //!< METHOD_FLEXPATH + , + METHOD_NSSI_STAGING = 19 //!< METHOD_NSSI_STAGING + , + METHOD_NSSI_FILTER = 20 //!< METHOD_NSSI_FILTER + , + METHOD_DIMES = 21 //!< METHOD_DIMES + , + METHOD_VAR_MERGE = 22 //!< METHOD_VAR_MERGE + , + METHOD_MPI_BGQ = 23 //!< METHOD_MPI_BGQ + , + METHOD_ICEE = 24 //!< METHOD_ICEE + , + METHOD_COUNT = 25 //!< METHOD_COUNT + , + METHOD_FSTREAM = 26, + METHOD_FILE = 27, + METHOD_ZMQ = 28, + METHOD_MDTM = 29 + }; + + /** + * DataTypes mapping in BP Format + */ + enum DataTypes + { + type_unknown = -1, //!< type_unknown + type_byte = 0, //!< type_byte + type_short = 1, //!< type_short + type_integer = 2, //!< type_integer + type_long = 4, //!< type_long + + type_unsigned_byte = 50, //!< type_unsigned_byte + type_unsigned_short = 51, //!< type_unsigned_short + type_unsigned_integer = 52, //!< type_unsigned_integer + type_unsigned_long = 54, //!< type_unsigned_long + + type_real = 5, //!< type_real or float + type_double = 6, //!< type_double + type_long_double = 7, //!< type_long_double + + type_string = 9, //!< type_string + type_complex = 10, //!< type_complex + type_double_complex = 11, //!< type_double_complex + type_string_array = 12 //!< type_string_array + }; + + /** + * Characteristic ID in variable metadata + */ + enum VariableCharacteristicID + { + characteristic_value = 0, //!< characteristic_value + characteristic_min = 1, //!< Used to read in older bp file format + characteristic_max = 2, //!< Used to read in older bp file format + characteristic_offset = 3, //!< characteristic_offset + characteristic_dimensions = 4, //!< characteristic_dimensions + characteristic_var_id = 5, //!< characteristic_var_id + characteristic_payload_offset = 6, //!< characteristic_payload_offset + characteristic_file_index = 7, //!< characteristic_file_index + characteristic_time_index = 8, //!< characteristic_time_index + characteristic_bitmap = 9, //!< characteristic_bitmap + characteristic_stat = 10, //!< characteristic_stat + characteristic_transform_type = 11 //!< characteristic_transform_type + }; + + /** Define statistics type for characteristic ID = 10 in bp1 format */ + enum VariableStatistics + { + statistic_min = 0, + statistic_max = 1, + statistic_cnt = 2, + statistic_sum = 3, + statistic_sum_square = 4, + statistic_hist = 5, + statistic_finite = 6 + }; + + template <class T> struct Stats + { + T Min; + T Max; + std::uint64_t Offset; + std::uint64_t PayloadOffset; + std::uint32_t TimeIndex; + std::uint32_t MemberID; + + // unsigned long int count; + // long double sum; + // long double sumSquare; + // unsigned long int histogram + // bool finite?? + }; + + /** + * Returns data type index from enum Datatypes + * @param variable input variable + * @return data type + */ + template <class T> inline std::int8_t GetDataType() const noexcept + { + return type_unknown; + } + + std::vector<std::uint8_t> + GetMethodIDs(const std::vector<std::shared_ptr<Transport>> &transports) const + noexcept; }; +// Moving template BP1Writer::GetDataType template specializations outside of +// the class +template <> inline std::int8_t BP1::GetDataType<char>() const noexcept +{ + return type_byte; +} +template <> inline std::int8_t BP1::GetDataType<short>() const noexcept +{ + return type_short; +} +template <> inline std::int8_t BP1::GetDataType<int>() const noexcept +{ + return type_integer; +} +template <> inline std::int8_t BP1::GetDataType<long int>() const noexcept +{ + return type_long; +} -//Moving template BP1Writer::GetDataType template specializations outside of the class -template< > inline std::int8_t BP1::GetDataType<char>( ) const noexcept { return type_byte; } -template< > inline std::int8_t BP1::GetDataType<short>( ) const noexcept{ return type_short; } -template< > inline std::int8_t BP1::GetDataType<int>( ) const noexcept{ return type_integer; } -template< > inline std::int8_t BP1::GetDataType<long int>( ) const noexcept{ return type_long; } - -template< > inline std::int8_t BP1::GetDataType<unsigned char>( ) const noexcept { return type_unsigned_byte; } -template< > inline std::int8_t BP1::GetDataType<unsigned short>( ) const noexcept{ return type_unsigned_short; } -template< > inline std::int8_t BP1::GetDataType<unsigned int>( ) const noexcept{ return type_unsigned_integer; } -template< > inline std::int8_t BP1::GetDataType<unsigned long int>( ) const noexcept{ return type_unsigned_long; } - -template< > inline std::int8_t BP1::GetDataType<float>( ) const noexcept{ return type_real; } -template< > inline std::int8_t BP1::GetDataType<double>( ) const noexcept{ return type_double; } -template< > inline std::int8_t BP1::GetDataType<long double>( ) const noexcept{ return type_long_double; } - - - -} //end namespace format -} //end namespace adios +template <> inline std::int8_t BP1::GetDataType<unsigned char>() const noexcept +{ + return type_unsigned_byte; +} +template <> inline std::int8_t BP1::GetDataType<unsigned short>() const noexcept +{ + return type_unsigned_short; +} +template <> inline std::int8_t BP1::GetDataType<unsigned int>() const noexcept +{ + return type_unsigned_integer; +} +template <> +inline std::int8_t BP1::GetDataType<unsigned long int>() const noexcept +{ + return type_unsigned_long; +} +template <> inline std::int8_t BP1::GetDataType<float>() const noexcept +{ + return type_real; +} +template <> inline std::int8_t BP1::GetDataType<double>() const noexcept +{ + return type_double; +} +template <> inline std::int8_t BP1::GetDataType<long double>() const noexcept +{ + return type_long_double; +} +} // end namespace format +} // end namespace adios #endif /* BP1_H_ */ diff --git a/include/format/BP1Aggregator.h b/include/format/BP1Aggregator.h index 60f1a8efa..736c33ff6 100644 --- a/include/format/BP1Aggregator.h +++ b/include/format/BP1Aggregator.h @@ -8,15 +8,12 @@ #ifndef BP1AGGREGATOR_H_ #define BP1AGGREGATOR_H_ - - #ifdef ADIOS_NOMPI - #include "mpidummy.h" +#include "mpidummy.h" #else - #include <mpi.h> +#include <mpi.h> #endif - namespace adios { namespace format @@ -29,35 +26,31 @@ class BP1Aggregator { public: - - MPI_Comm m_MPIComm = MPI_COMM_SELF; ///< MPI communicator from Engine - int m_RankMPI = 0; ///< current MPI rank process - int m_SizeMPI = 1; ///< current MPI processes size - - /** - * Unique constructor - * @param mpiComm coming from engine - */ - BP1Aggregator( MPI_Comm mpiComm, const bool debugMode = false ); - - ~BP1Aggregator( ); - - - /** - * Function that aggregates and writes (from rank = 0) profiling.log in python dictionary format - * @param rankLog contain rank profiling info to be aggregated - */ - void WriteProfilingLog( const std::string fileName, const std::string& rankLog ); + MPI_Comm m_MPIComm = MPI_COMM_SELF; ///< MPI communicator from Engine + int m_RankMPI = 0; ///< current MPI rank process + int m_SizeMPI = 1; ///< current MPI processes size + + /** + * Unique constructor + * @param mpiComm coming from engine + */ + BP1Aggregator(MPI_Comm mpiComm, const bool debugMode = false); + + ~BP1Aggregator(); + + /** + * Function that aggregates and writes (from rank = 0) profiling.log in python + * dictionary format + * @param rankLog contain rank profiling info to be aggregated + */ + void WriteProfilingLog(const std::string fileName, + const std::string &rankLog); private: - - const bool m_DebugMode = false; - - + const bool m_DebugMode = false; }; - -} //end namespace format -} //end namespace adios +} // end namespace format +} // end namespace adios #endif /* BP1AGGREGATOR_H_ */ diff --git a/include/format/BP1Writer.h b/include/format/BP1Writer.h index 5e68f083f..6b2ff4a13 100644 --- a/include/format/BP1Writer.h +++ b/include/format/BP1Writer.h @@ -10,440 +10,511 @@ /// \cond EXCLUDE_FROM_DOXYGEN #include <algorithm> //std::count, std::copy, std::for_each -#include <cstring> //std::memcpy -#include <cmath> //std::ceil +#include <cmath> //std::ceil +#include <cstring> //std::memcpy /// \endcond #include "BP1.h" -#include "core/Variable.h" +#include "capsule/heap/STLVector.h" #include "core/Capsule.h" #include "core/Profiler.h" -#include "capsule/heap/STLVector.h" -#include "functions/adiosTemplates.h" +#include "core/Variable.h" #include "functions/adiosFunctions.h" - +#include "functions/adiosTemplates.h" namespace adios { namespace format { - class BP1Writer : public BP1 { public: - - unsigned int m_Threads = 1; ///< number of threads for thread operations in large array (min,max) - unsigned int m_Verbosity = 0; ///< statistics verbosity, can change if redefined in Engine method. - float m_GrowthFactor = 1.5; ///< memory growth factor, can change if redefined in Engine method. - const std::uint8_t m_Version = 3; ///< BP format version - - /** - * Calculates the Process Index size in bytes according to the BP format, including list of method with no parameters (for now) - * @param name - * @param timeStepName - * @param numberOfTransports - * @return size of pg index - */ - std::size_t GetProcessGroupIndexSize( const std::string name, const std::string timeStepName, - const std::size_t numberOfTransports ) const noexcept; - - /** - * Writes a process group index PGIndex and list of methods (from transports), done at Open or aggregation of new time step - * Version that operates on a single heap buffer and metadataset. - * @param isFortran - * @param name - * @param processID - * @param transports - * @param buffer - * @param metadataSet - */ - void WriteProcessGroupIndex( const bool isFortran, const std::string name, const std::uint32_t processID, - const std::vector< std::shared_ptr<Transport> >& transports, - capsule::STLVector& heap, BP1MetadataSet& metadataSet ) const noexcept; - - /** - * Returns the estimated variable index size - * @param group - * @param variableName - * @param variable - * @param verbosity - * @return variable index size - */ - template< class T > - size_t GetVariableIndexSize( const Variable<T>& variable ) const noexcept + unsigned int m_Threads = + 1; ///< number of threads for thread operations in large array (min,max) + unsigned int m_Verbosity = + 0; ///< statistics verbosity, can change if redefined in Engine method. + float m_GrowthFactor = + 1.5; ///< memory growth factor, can change if redefined in Engine method. + const std::uint8_t m_Version = 3; ///< BP format version + + /** + * Calculates the Process Index size in bytes according to the BP format, + * including list of method with no parameters (for now) + * @param name + * @param timeStepName + * @param numberOfTransports + * @return size of pg index + */ + std::size_t + GetProcessGroupIndexSize(const std::string name, + const std::string timeStepName, + const std::size_t numberOfTransports) const noexcept; + + /** + * Writes a process group index PGIndex and list of methods (from transports), + * done at Open or aggregation of new time step + * Version that operates on a single heap buffer and metadataset. + * @param isFortran + * @param name + * @param processID + * @param transports + * @param buffer + * @param metadataSet + */ + void WriteProcessGroupIndex( + const bool isFortran, const std::string name, + const std::uint32_t processID, + const std::vector<std::shared_ptr<Transport>> &transports, + capsule::STLVector &heap, BP1MetadataSet &metadataSet) const noexcept; + + /** + * Returns the estimated variable index size + * @param group + * @param variableName + * @param variable + * @param verbosity + * @return variable index size + */ + template <class T> + size_t GetVariableIndexSize(const Variable<T> &variable) const noexcept + { + // size_t indexSize = varEntryLength + memberID + lengthGroupName + + // groupName + lengthVariableName + lengthOfPath + path + datatype + size_t indexSize = 23; // without characteristics + indexSize += variable.m_Name.size(); + + // characteristics 3 and 4, check variable number of dimensions + const std::size_t dimensions = + variable.DimensionsSize(); // number of commas in CSV + 1 + indexSize += 28 * dimensions; // 28 bytes per dimension + indexSize += 1; // id + + // characteristics, offset + payload offset in data + indexSize += 2 * (1 + 8); + // characteristic 0, if scalar add value, for now only allowing string + if (dimensions == 1) { - //size_t indexSize = varEntryLength + memberID + lengthGroupName + groupName + lengthVariableName + lengthOfPath + path + datatype - size_t indexSize = 23; //without characteristics - indexSize += variable.m_Name.size(); - - // characteristics 3 and 4, check variable number of dimensions - const std::size_t dimensions = variable.DimensionsSize(); //number of commas in CSV + 1 - indexSize += 28 * dimensions; //28 bytes per dimension - indexSize += 1; //id - - //characteristics, offset + payload offset in data - indexSize += 2*(1+8); - //characteristic 0, if scalar add value, for now only allowing string - if( dimensions == 1 ) - { - indexSize += sizeof(T); - indexSize += 1; //id - //must have an if here - indexSize += 2 + variable.m_Name.size(); - indexSize += 1; //id - } - - //characteristic statistics - if( m_Verbosity == 0 ) //default, only min and max - { - indexSize += 2 * ( sizeof(T) + 1 ); - indexSize += 1 + 1; //id - } - - return indexSize + 12; ///extra 12 bytes in case of attributes - //need to add transform characteristics + indexSize += sizeof(T); + indexSize += 1; // id + // must have an if here + indexSize += 2 + variable.m_Name.size(); + indexSize += 1; // id } - /** - * Version for primitive types (except std::complex<T>) - * @param variable - * @param heap - * @param metadataSet - */ - template<class T> inline - void WriteVariableMetadata( const Variable<T>& variable, capsule::STLVector& heap, BP1MetadataSet& metadataSet ) const noexcept + // characteristic statistics + if (m_Verbosity == 0) // default, only min and max { - Stats<T> stats = GetStats( variable ); - WriteVariableMetadataCommon( variable, stats, heap, metadataSet ); + indexSize += 2 * (sizeof(T) + 1); + indexSize += 1 + 1; // id } - /** - * Overloaded version for std::complex<T> variables - * @param variable - * @param heap - * @param metadataSet - */ - template<class T> - void WriteVariableMetadata( const Variable<std::complex<T>>& variable, capsule::STLVector& heap, BP1MetadataSet& metadataSet ) const noexcept + return indexSize + 12; /// extra 12 bytes in case of attributes + // need to add transform characteristics + } + + /** + * Version for primitive types (except std::complex<T>) + * @param variable + * @param heap + * @param metadataSet + */ + template <class T> + inline void WriteVariableMetadata(const Variable<T> &variable, + capsule::STLVector &heap, + BP1MetadataSet &metadataSet) const noexcept + { + Stats<T> stats = GetStats(variable); + WriteVariableMetadataCommon(variable, stats, heap, metadataSet); + } + + /** + * Overloaded version for std::complex<T> variables + * @param variable + * @param heap + * @param metadataSet + */ + template <class T> + void WriteVariableMetadata(const Variable<std::complex<T>> &variable, + capsule::STLVector &heap, + BP1MetadataSet &metadataSet) const noexcept + { + Stats<T> stats = GetStats(variable); + WriteVariableMetadataCommon(variable, stats, heap, metadataSet); + } + + /** + * Expensive part this is only for heap buffers need to adapt to vector of + * capsules + * @param variable + * @param buffer + */ + template <class T> + void WriteVariablePayload(const Variable<T> &variable, + capsule::STLVector &heap, + const unsigned int nthreads = 1) const noexcept + { + // EXPENSIVE part, might want to use threads if large, serial for now + CopyToBuffer(heap.m_Data, variable.m_AppValues, variable.TotalSize()); + heap.m_DataAbsolutePosition += variable.PayLoadSize(); + } + + void Advance(BP1MetadataSet &metadataSet, capsule::STLVector &buffer); + + /** + * Function that sets metadata (if first close) and writes to a single + * transport + * @param metadataSet current rank metadata set + * @param heap contains data buffer + * @param transport does a write after data and metadata is setup + * @param isFirstClose true: metadata has been set and aggregated + * @param doAggregation true: for N-to-M, false: for N-to-N + */ + void Close(BP1MetadataSet &metadataSet, capsule::STLVector &heap, + Transport &transport, bool &isFirstClose, + const bool doAggregation) const noexcept; + + /** + * Writes the ADIOS log information (buffering, open, write and close) for a + * rank process + * @param rank current rank + * @param metadataSet contains Profile info for buffering + * @param transports contains Profile info for transport open, writes and + * close + * @return string for this rank that will be aggregated into profiling.log + */ + std::string GetRankProfilingLog( + const int rank, const BP1MetadataSet &metadataSet, + const std::vector<std::shared_ptr<Transport>> &transports) const noexcept; + +private: + template <class T, class U> + void WriteVariableMetadataCommon(const Variable<T> &variable, Stats<U> &stats, + capsule::STLVector &heap, + BP1MetadataSet &metadataSet) const noexcept + { + stats.TimeIndex = metadataSet.TimeStep; + + // Get new Index or point to existing index + bool isNew = true; // flag to check if variable is new + BP1Index &varIndex = + GetBP1Index(variable.m_Name, metadataSet.VarsIndices, isNew); + stats.MemberID = varIndex.MemberID; + + // write metadata header in data and extract offsets + stats.Offset = heap.m_DataAbsolutePosition; + WriteVariableMetadataInData(variable, stats, heap); + stats.PayloadOffset = heap.m_DataAbsolutePosition; + + // write to metadata index + WriteVariableMetadataInIndex(variable, stats, isNew, varIndex); + + ++metadataSet.DataPGVarsCount; + } + + template <class T, class U> + void WriteVariableMetadataInData(const Variable<T> &variable, + const Stats<U> &stats, + capsule::STLVector &heap) const noexcept + { + auto &buffer = heap.m_Data; + + const std::size_t varLengthPosition = + buffer.size(); // capture initial position for variable length + buffer.insert(buffer.end(), 8, 0); // skip var length (8) + CopyToBuffer(buffer, &stats.MemberID); // memberID + WriteNameRecord(variable.m_Name, buffer); // variable name + buffer.insert(buffer.end(), 2, 0); // skip path + const std::uint8_t dataType = GetDataType<T>(); // dataType + CopyToBuffer(buffer, &dataType); + constexpr char no = 'n'; // isDimension + CopyToBuffer(buffer, &no); + + // write variable dimensions + const std::uint8_t dimensions = variable.m_Dimensions.size(); + CopyToBuffer(buffer, &dimensions); // count + std::uint16_t dimensionsLength = + 27 * dimensions; // 27 is from 9 bytes for each: var y/n + local, var + // y/n + global dimension, var y/n + global offset, + // changed for characteristic + CopyToBuffer(buffer, &dimensionsLength); // length + WriteDimensionsRecord(buffer, variable.m_Dimensions, + variable.m_GlobalDimensions, variable.m_GlobalOffsets, + 18, true); + + // CHARACTERISTICS + WriteVariableCharacteristics(variable, stats, buffer, true); + + // Back to varLength including payload size + const std::uint64_t varLength = buffer.size() - varLengthPosition + + variable.PayLoadSize() - + 8; // remove its own size + CopyToBuffer(buffer, varLengthPosition, &varLength); // length + + heap.m_DataAbsolutePosition += + buffer.size() - varLengthPosition; // update absolute position to be + // used as payload position + } + + template <class T, class U> + void WriteVariableMetadataInIndex(const Variable<T> &variable, + const Stats<U> &stats, const bool isNew, + BP1Index &index) const noexcept + { + auto &buffer = index.Buffer; + + if (isNew == + true) // write variable header (might be shared with attributes index) { - Stats<T> stats = GetStats( variable ); - WriteVariableMetadataCommon( variable, stats, heap, metadataSet ); + buffer.insert(buffer.end(), 4, 0); // skip var length (4) + CopyToBuffer(buffer, &stats.MemberID); + buffer.insert(buffer.end(), 2, 0); // skip group name + WriteNameRecord(variable.m_Name, buffer); + buffer.insert(buffer.end(), 2, 0); // skip path + + const std::uint8_t dataType = GetDataType<T>(); + CopyToBuffer(buffer, &dataType); + + // Characteristics Sets Count in Metadata + index.Count = 1; + CopyToBuffer(buffer, &index.Count); } - - - /** - * Expensive part this is only for heap buffers need to adapt to vector of capsules - * @param variable - * @param buffer - */ - template< class T > - void WriteVariablePayload( const Variable<T>& variable, capsule::STLVector& heap, const unsigned int nthreads = 1 ) const noexcept + else // update characteristics sets count { - //EXPENSIVE part, might want to use threads if large, serial for now - CopyToBuffer( heap.m_Data, variable.m_AppValues, variable.TotalSize() ); - heap.m_DataAbsolutePosition += variable.PayLoadSize(); + const std::size_t characteristicsSetsCountPosition = + 15 + variable.m_Name.size(); + ++index.Count; + CopyToBuffer(buffer, characteristicsSetsCountPosition, + &index.Count); // test } - - void Advance( BP1MetadataSet& metadataSet, capsule::STLVector& buffer ); - - /** - * Function that sets metadata (if first close) and writes to a single transport - * @param metadataSet current rank metadata set - * @param heap contains data buffer - * @param transport does a write after data and metadata is setup - * @param isFirstClose true: metadata has been set and aggregated - * @param doAggregation true: for N-to-M, false: for N-to-N - */ - void Close( BP1MetadataSet& metadataSet, capsule::STLVector& heap, Transport& transport, bool& isFirstClose, - const bool doAggregation ) const noexcept; - - - /** - * Writes the ADIOS log information (buffering, open, write and close) for a rank process - * @param rank current rank - * @param metadataSet contains Profile info for buffering - * @param transports contains Profile info for transport open, writes and close - * @return string for this rank that will be aggregated into profiling.log - */ - std::string GetRankProfilingLog( const int rank, const BP1MetadataSet& metadataSet, - const std::vector< std::shared_ptr<Transport> >& transports ) const noexcept; - -private: - - template< class T, class U > - void WriteVariableMetadataCommon( const Variable<T>& variable, Stats<U>& stats, - capsule::STLVector& heap, BP1MetadataSet& metadataSet ) const noexcept - { - stats.TimeIndex = metadataSet.TimeStep; - - //Get new Index or point to existing index - bool isNew = true; //flag to check if variable is new - BP1Index& varIndex = GetBP1Index( variable.m_Name, metadataSet.VarsIndices, isNew ); - stats.MemberID = varIndex.MemberID; - - //write metadata header in data and extract offsets - stats.Offset = heap.m_DataAbsolutePosition; - WriteVariableMetadataInData( variable, stats, heap ); - stats.PayloadOffset = heap.m_DataAbsolutePosition; - - //write to metadata index - WriteVariableMetadataInIndex( variable, stats, isNew, varIndex ); - - ++metadataSet.DataPGVarsCount; - } - - - template< class T, class U > - void WriteVariableMetadataInData( const Variable<T>& variable, const Stats<U>& stats, - capsule::STLVector& heap ) const noexcept + WriteVariableCharacteristics(variable, stats, buffer); + } + + template <class T, class U> + void WriteVariableCharacteristics(const Variable<T> &variable, + const Stats<U> &stats, + std::vector<char> &buffer, + const bool addLength = false) const noexcept + { + const std::size_t characteristicsCountPosition = + buffer.size(); // very important to track as writer is going back to + // this position + buffer.insert(buffer.end(), 5, + 0); // skip characteristics count(1) + length (4) + std::uint8_t characteristicsCounter = 0; + + // DIMENSIONS + std::uint8_t characteristicID = characteristic_dimensions; + CopyToBuffer(buffer, &characteristicID); + const std::uint8_t dimensions = variable.m_Dimensions.size(); + + if (addLength == true) { - auto& buffer = heap.m_Data; - - const std::size_t varLengthPosition = buffer.size(); //capture initial position for variable length - buffer.insert( buffer.end(), 8, 0 ); //skip var length (8) - CopyToBuffer( buffer, &stats.MemberID ); //memberID - WriteNameRecord( variable.m_Name, buffer ); //variable name - buffer.insert( buffer.end(), 2, 0 ); //skip path - const std::uint8_t dataType = GetDataType<T>(); //dataType - CopyToBuffer( buffer, &dataType ); - constexpr char no = 'n'; //isDimension - CopyToBuffer( buffer, &no ); - - //write variable dimensions - const std::uint8_t dimensions = variable.m_Dimensions.size(); - CopyToBuffer( buffer, &dimensions ); //count - std::uint16_t dimensionsLength = 27 * dimensions; //27 is from 9 bytes for each: var y/n + local, var y/n + global dimension, var y/n + global offset, changed for characteristic - CopyToBuffer( buffer, &dimensionsLength ); //length - WriteDimensionsRecord( buffer, variable.m_Dimensions, variable.m_GlobalDimensions, variable.m_GlobalOffsets, 18, true ); - - //CHARACTERISTICS - WriteVariableCharacteristics( variable, stats, buffer, true ); - - //Back to varLength including payload size - const std::uint64_t varLength = buffer.size() - varLengthPosition + variable.PayLoadSize() - 8; //remove its own size - CopyToBuffer( buffer, varLengthPosition, &varLength ); //length - - heap.m_DataAbsolutePosition += buffer.size() - varLengthPosition; // update absolute position to be used as payload position + const std::int16_t lengthOfDimensionsCharacteristic = + 24 * dimensions + + 3; // 24 = 3 local, global, global offset x 8 bytes/each + CopyToBuffer(buffer, &lengthOfDimensionsCharacteristic); } - - template< class T, class U> - void WriteVariableMetadataInIndex( const Variable<T>& variable, const Stats<U>& stats, - const bool isNew, BP1Index& index ) const noexcept + CopyToBuffer(buffer, &dimensions); // count + const std::uint16_t dimensionsLength = 24 * dimensions; + CopyToBuffer(buffer, &dimensionsLength); // length + WriteDimensionsRecord(buffer, variable.m_Dimensions, + variable.m_GlobalDimensions, variable.m_GlobalOffsets, + 16, addLength); + ++characteristicsCounter; + + // VALUE for SCALAR or STAT min, max for ARRAY + WriteBoundsRecord(variable.m_IsScalar, stats, buffer, + characteristicsCounter, addLength); + // TIME INDEX + WriteCharacteristicRecord(characteristic_time_index, stats.TimeIndex, + buffer, characteristicsCounter, addLength); + + if (addLength == false) // only in metadata offset and payload offset { - auto& buffer = index.Buffer; - - if( isNew == true ) //write variable header (might be shared with attributes index) - { - buffer.insert( buffer.end(), 4, 0 ); //skip var length (4) - CopyToBuffer( buffer, &stats.MemberID ); - buffer.insert( buffer.end(), 2, 0 ); //skip group name - WriteNameRecord( variable.m_Name, buffer ); - buffer.insert( buffer.end(), 2, 0 ); //skip path - - const std::uint8_t dataType = GetDataType<T>(); - CopyToBuffer( buffer, &dataType ); - - //Characteristics Sets Count in Metadata - index.Count = 1; - CopyToBuffer( buffer, &index.Count ); - } - else //update characteristics sets count - { - const std::size_t characteristicsSetsCountPosition = 15 + variable.m_Name.size(); - ++index.Count; - CopyToBuffer( buffer, characteristicsSetsCountPosition, &index.Count ); //test - } - - WriteVariableCharacteristics( variable, stats, buffer ); + WriteCharacteristicRecord(characteristic_offset, stats.Offset, buffer, + characteristicsCounter); + WriteCharacteristicRecord(characteristic_payload_offset, + stats.PayloadOffset, buffer, + characteristicsCounter); } - - - template<class T, class U> - void WriteVariableCharacteristics( const Variable<T>& variable, const Stats<U>& stats, std::vector<char>& buffer, - const bool addLength = false ) const noexcept + // END OF CHARACTERISTICS + + // Back to characteristics count and length + CopyToBuffer(buffer, characteristicsCountPosition, + &characteristicsCounter); // count (1) + const std::uint32_t characteristicsLength = + buffer.size() - characteristicsCountPosition - 4 - + 1; // remove its own length (4 bytes) + characteristic counter ( 1 byte + // ) + CopyToBuffer(buffer, characteristicsCountPosition + 1, + &characteristicsLength); // length + } + + /** + * Writes from &buffer[position]: [2 bytes:string.length()][string.length(): + * string.c_str()] + * @param name + * @param buffer + * @param position + */ + void WriteNameRecord(const std::string name, std::vector<char> &buffer) const + noexcept; + + /** + * Write a dimension record for a global variable used by WriteVariableCommon + * @param buffer + * @param position + * @param localDimensions + * @param globalDimensions + * @param globalOffsets + * @param addType true: for data buffers, false: for metadata buffer and data + * characteristic + */ + void WriteDimensionsRecord(std::vector<char> &buffer, + const std::vector<std::size_t> &localDimensions, + const std::vector<std::size_t> &globalDimensions, + const std::vector<std::size_t> &globalOffsets, + const unsigned int skip, + const bool addType = false) const noexcept; + + /** + * GetStats for primitive types except std::complex<T> types + * @param variable + * @return stats + */ + template <class T> + Stats<T> GetStats(const Variable<T> &variable) const noexcept + { + Stats<T> stats; + const std::size_t valuesSize = variable.TotalSize(); + + if (m_Verbosity == 0) { - const std::size_t characteristicsCountPosition = buffer.size(); //very important to track as writer is going back to this position - buffer.insert( buffer.end(), 5, 0 ); //skip characteristics count(1) + length (4) - std::uint8_t characteristicsCounter = 0; - - //DIMENSIONS - std::uint8_t characteristicID = characteristic_dimensions; - CopyToBuffer( buffer, &characteristicID ); - const std::uint8_t dimensions = variable.m_Dimensions.size(); - - if( addLength == true ) - { - const std::int16_t lengthOfDimensionsCharacteristic = 24 * dimensions + 3; // 24 = 3 local, global, global offset x 8 bytes/each - CopyToBuffer( buffer, &lengthOfDimensionsCharacteristic ); - } - - CopyToBuffer( buffer, &dimensions ); //count - const std::uint16_t dimensionsLength = 24 * dimensions; - CopyToBuffer( buffer, &dimensionsLength ); //length - WriteDimensionsRecord( buffer, variable.m_Dimensions, variable.m_GlobalDimensions, variable.m_GlobalOffsets, 16, addLength ); - ++characteristicsCounter; - - //VALUE for SCALAR or STAT min, max for ARRAY - WriteBoundsRecord( variable.m_IsScalar, stats, buffer, characteristicsCounter, addLength ); - //TIME INDEX - WriteCharacteristicRecord( characteristic_time_index, stats.TimeIndex, buffer, characteristicsCounter, addLength ); - - if( addLength == false )//only in metadata offset and payload offset - { - WriteCharacteristicRecord( characteristic_offset, stats.Offset, buffer, characteristicsCounter ); - WriteCharacteristicRecord( characteristic_payload_offset, stats.PayloadOffset, buffer, characteristicsCounter ); - } - //END OF CHARACTERISTICS - - //Back to characteristics count and length - CopyToBuffer( buffer, characteristicsCountPosition, &characteristicsCounter ); //count (1) - const std::uint32_t characteristicsLength = buffer.size() - characteristicsCountPosition - 4 - 1; //remove its own length (4 bytes) + characteristic counter ( 1 byte ) - CopyToBuffer( buffer, characteristicsCountPosition+1, &characteristicsLength ); //length + if (valuesSize >= 10000000) // ten million? this needs actual results + // //here we can make decisions for threads + // based on valuesSize + GetMinMax(variable.m_AppValues, valuesSize, stats.Min, stats.Max, + m_Threads); // here we can add cores from constructor + else + GetMinMax(variable.m_AppValues, valuesSize, stats.Min, stats.Max); } - - /** - * Writes from &buffer[position]: [2 bytes:string.length()][string.length(): string.c_str()] - * @param name - * @param buffer - * @param position - */ - void WriteNameRecord( const std::string name, std::vector<char>& buffer ) const noexcept; - - - /** - * Write a dimension record for a global variable used by WriteVariableCommon - * @param buffer - * @param position - * @param localDimensions - * @param globalDimensions - * @param globalOffsets - * @param addType true: for data buffers, false: for metadata buffer and data characteristic - */ - void WriteDimensionsRecord( std::vector<char>& buffer, - const std::vector<std::size_t>& localDimensions, - const std::vector<std::size_t>& globalDimensions, - const std::vector<std::size_t>& globalOffsets, - const unsigned int skip, - const bool addType = false ) const noexcept; - - /** - * GetStats for primitive types except std::complex<T> types - * @param variable - * @return stats - */ - template<class T> - Stats<T> GetStats( const Variable<T>& variable ) const noexcept - { - Stats<T> stats; - const std::size_t valuesSize = variable.TotalSize(); - - if( m_Verbosity == 0 ) - { - if( valuesSize >= 10000000 ) //ten million? this needs actual results //here we can make decisions for threads based on valuesSize - GetMinMax( variable.m_AppValues, valuesSize, stats.Min, stats.Max, m_Threads ); //here we can add cores from constructor - else - GetMinMax( variable.m_AppValues, valuesSize, stats.Min, stats.Max ); - } - return stats; - } - - /** - * GetStats for std::complex<T> types - * @param variable - * @return stats - */ - template<class T> - Stats<T> GetStats( const Variable<std::complex<T>>& variable ) const noexcept - { - Stats<T> stats; - const std::size_t valuesSize = variable.TotalSize(); - - if( m_Verbosity == 0 ) - { - if( valuesSize >= 10000000 ) //ten million? this needs actual results //here we can make decisions for threads based on valuesSize - GetMinMax( variable.m_AppValues, valuesSize, stats.Min, stats.Max, m_Threads ); //here we can add cores from constructor - else - GetMinMax( variable.m_AppValues, valuesSize, stats.Min, stats.Max ); - } - return stats; - } - - template< class T > - void WriteBoundsRecord( const bool isScalar, const Stats<T>& stats, std::vector<char>& buffer, - std::uint8_t& characteristicsCounter, const bool addLength ) const noexcept + return stats; + } + + /** + * GetStats for std::complex<T> types + * @param variable + * @return stats + */ + template <class T> + Stats<T> GetStats(const Variable<std::complex<T>> &variable) const noexcept + { + Stats<T> stats; + const std::size_t valuesSize = variable.TotalSize(); + + if (m_Verbosity == 0) { - if( isScalar == true ) - { - WriteCharacteristicRecord( characteristic_value, stats.Min, buffer, characteristicsCounter, addLength ); //stats.min = stats.max = value - return; - } - - if( m_Verbosity == 0 ) //default verbose - { - WriteCharacteristicRecord( characteristic_min, stats.Min, buffer, characteristicsCounter, addLength ); - WriteCharacteristicRecord( characteristic_max, stats.Max, buffer, characteristicsCounter, addLength ); - } + if (valuesSize >= 10000000) // ten million? this needs actual results + // //here we can make decisions for threads + // based on valuesSize + GetMinMax(variable.m_AppValues, valuesSize, stats.Min, stats.Max, + m_Threads); // here we can add cores from constructor + else + GetMinMax(variable.m_AppValues, valuesSize, stats.Min, stats.Max); } - - /** - * Write a characteristic value record to buffer - * @param id - * @param value - * @param buffers - * @param positions - * @param characvteristicsCounter to be updated by 1 - * @param addLength true for data, false for metadata - */ - template<class T> - void WriteCharacteristicRecord( const std::uint8_t characteristicID, const T& value, - std::vector<char>& buffer, std::uint8_t& characteristicsCounter, - const bool addLength = false ) const noexcept + return stats; + } + + template <class T> + void WriteBoundsRecord(const bool isScalar, const Stats<T> &stats, + std::vector<char> &buffer, + std::uint8_t &characteristicsCounter, + const bool addLength) const noexcept + { + if (isScalar == true) { - const std::uint8_t id = characteristicID; - CopyToBuffer( buffer, &id ); - - if( addLength == true ) - { - const std::uint16_t lengthOfCharacteristic = sizeof( T ); //id - CopyToBuffer( buffer, &lengthOfCharacteristic ); - } - - CopyToBuffer( buffer, &value ); - ++characteristicsCounter; + WriteCharacteristicRecord(characteristic_value, stats.Min, buffer, + characteristicsCounter, + addLength); // stats.min = stats.max = value + return; } - /** - * Returns corresponding index of type BP1Index, if doesn't exists creates a new one. - * Used for variables and attributes - * @param name variable or attribute name to look for index - * @param indices look up hash table of indices - * @param isNew true: index is newly created, false: index already exists in indices - * @return reference to BP1Index in indices - */ - BP1Index& GetBP1Index( const std::string name, std::unordered_map<std::string, BP1Index>& indices, bool& isNew ) const noexcept; - - /** - * Flattens the data and fills the pg length, vars count, vars length and attributes - * @param metadataSet - * @param buffer - */ - void FlattenData( BP1MetadataSet& metadataSet, capsule::STLVector& buffer ) const noexcept; - - /** - * Flattens the metadata indices into a single metadata buffer in capsule - * @param metadataSet - * @param buffer - */ - void FlattenMetadata( BP1MetadataSet& metadataSet, capsule::STLVector& buffer ) const noexcept; ///< sets the metadata buffer in capsule with indices and minifooter + if (m_Verbosity == 0) // default verbose + { + WriteCharacteristicRecord(characteristic_min, stats.Min, buffer, + characteristicsCounter, addLength); + WriteCharacteristicRecord(characteristic_max, stats.Max, buffer, + characteristicsCounter, addLength); + } + } + + /** + * Write a characteristic value record to buffer + * @param id + * @param value + * @param buffers + * @param positions + * @param characvteristicsCounter to be updated by 1 + * @param addLength true for data, false for metadata + */ + template <class T> + void WriteCharacteristicRecord(const std::uint8_t characteristicID, + const T &value, std::vector<char> &buffer, + std::uint8_t &characteristicsCounter, + const bool addLength = false) const noexcept + { + const std::uint8_t id = characteristicID; + CopyToBuffer(buffer, &id); + + if (addLength == true) + { + const std::uint16_t lengthOfCharacteristic = sizeof(T); // id + CopyToBuffer(buffer, &lengthOfCharacteristic); + } + CopyToBuffer(buffer, &value); + ++characteristicsCounter; + } + + /** + * Returns corresponding index of type BP1Index, if doesn't exists creates a + * new one. + * Used for variables and attributes + * @param name variable or attribute name to look for index + * @param indices look up hash table of indices + * @param isNew true: index is newly created, false: index already exists in + * indices + * @return reference to BP1Index in indices + */ + BP1Index &GetBP1Index(const std::string name, + std::unordered_map<std::string, BP1Index> &indices, + bool &isNew) const noexcept; + + /** + * Flattens the data and fills the pg length, vars count, vars length and + * attributes + * @param metadataSet + * @param buffer + */ + void FlattenData(BP1MetadataSet &metadataSet, + capsule::STLVector &buffer) const noexcept; + + /** + * Flattens the metadata indices into a single metadata buffer in capsule + * @param metadataSet + * @param buffer + */ + void FlattenMetadata(BP1MetadataSet &metadataSet, + capsule::STLVector &buffer) const + noexcept; ///< sets the metadata buffer in capsule with indices and + ///minifooter }; - -} //end namespace format -} //end namespace adios +} // end namespace format +} // end namespace adios #endif /* BP1WRITER_H_ */ diff --git a/include/functions/adiosFunctions.h b/include/functions/adiosFunctions.h index 46598ff85..2f1d35e89 100644 --- a/include/functions/adiosFunctions.h +++ b/include/functions/adiosFunctions.h @@ -9,17 +9,17 @@ #define ADIOSFUNCTIONS_H_ /// \cond EXCLUDE_FROM_DOXYGEN -#include <string> -#include <vector> -#include <map> #include <cstring> //std::size_t +#include <map> #include <memory> //std::shared_ptr +#include <string> +#include <vector> /// \endcond #ifdef ADIOS_NOMPI - #include "mpidummy.h" +#include "mpidummy.h" #else - #include <mpi.h> +#include <mpi.h> #endif #include "core/Transform.h" @@ -32,105 +32,127 @@ namespace adios * @param fileName file to be opened * @param fileContents output contains the entire file */ -void DumpFileToString( const std::string fileName, std::string& fileContents ); - +void DumpFileToString(const std::string fileName, std::string &fileContents); /** * Extracts a substring between two tags from content * @param initialTag * @param finalTag * @param content full string - * @param subString if found return substring between initialTag and finalTag, otherwise returns empty - * @param currentPosition to start the search, moved forward to finalTag position + * @param subString if found return substring between initialTag and finalTag, + * otherwise returns empty + * @param currentPosition to start the search, moved forward to finalTag + * position */ -void GetSubString ( const std::string initialTag, const std::string finalTag, const std::string content, std::string& subString, - std::string::size_type& currentPosition ); +void GetSubString(const std::string initialTag, const std::string finalTag, + const std::string content, std::string &subString, + std::string::size_type ¤tPosition); /** - * Extracts the value inside quotes in a string currentTag ( Example: currentTag --> field1="value1" field2="value2" ) + * Extracts the value inside quotes in a string currentTag ( Example: currentTag + * --> field1="value1" field2="value2" ) * @param quote double " or single ' * @param quotePosition position of the opening quote in currentTag - * @param currentTag initial tag value, modified by cutting the first found " " portion, currentTag --> field2="value2" + * @param currentTag initial tag value, modified by cutting the first found " " + * portion, currentTag --> field2="value2" * @param value value1 in the example above */ -void GetQuotedValue( const char quote, const std::string::size_type& quotePosition, - std::string& currentTag, std::string& value ); - +void GetQuotedValue(const char quote, + const std::string::size_type "ePosition, + std::string ¤tTag, std::string &value); /** - * Get attributes field1="value1" field2="value2" by looping through a single XML tag + * Get attributes field1="value1" field2="value2" by looping through a single + * XML tag * @param tag field0="value0" field1="value1" in a single string - * @param pairs pairs[0].first=field0 pairs[0].second=value0 pairs[1].first=field1 pairs[1].second=value1 + * @param pairs pairs[0].first=field0 pairs[0].second=value0 + * pairs[1].first=field1 pairs[1].second=value1 */ -void GetPairs( const std::string tag, std::vector< std::pair<const std::string, const std::string> >& pairs ) noexcept; - +void GetPairs(const std::string tag, + std::vector<std::pair<const std::string, const std::string>> + &pairs) noexcept; /** * Determine tag type and call GetPairs to populate pairs * @param fileContent file Content in a single string * @param tag field0="value0" field1="value1" in a single string - * @param pairs pairs[0].first=field0 pairs[0].second=value0 pairs[1].first=field1 pairs[1].second=value1 + * @param pairs pairs[0].first=field0 pairs[0].second=value0 + * pairs[1].first=field1 pairs[1].second=value1 */ -void GetPairsFromTag( const std::string& fileContent, const std::string tag, - std::vector< std::pair<const std::string, const std::string> >& pairs ); - +void GetPairsFromTag( + const std::string &fileContent, const std::string tag, + std::vector<std::pair<const std::string, const std::string>> &pairs); /** - * Set members m_Groups and m_HostLanguage from XML file content, called within Init functions + * Set members m_Groups and m_HostLanguage from XML file content, called within + * Init functions * @param fileContent file Content in a single string - * @param mpiComm MPI Communicator passed from application passed to Transport method if required + * @param mpiComm MPI Communicator passed from application passed to Transport + * method if required * @param hostLanguage return the host language from fileContent - * @param transforms return the modified transforms vector if there are variables with transformations + * @param transforms return the modified transforms vector if there are + * variables with transformations * @param groups passed returns the map of groups defined in fileContent */ -//void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm, -// std::string& hostLanguage, std::vector< std::shared_ptr<Transform> >& transforms, +// void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm, +// std::string& hostLanguage, std::vector< +// std::shared_ptr<Transform> >& transforms, // std::map< std::string, Group >& groups ); - /** - * Called inside the ADIOS XML constructors to get contents from file, broadcast and set hostLanguage and groups from ADIOS class + * Called inside the ADIOS XML constructors to get contents from file, broadcast + * and set hostLanguage and groups from ADIOS class * @param xmlConfigFile xml config file name * @param mpiComm communicator used from broadcasting * @param debugMode from ADIOS m_DebugMode passed to CGroup in groups * @param hostLanguage set from host-language in xml file - * @param transforms return the modified transforms vector if there are variables with transformations + * @param transforms return the modified transforms vector if there are + * variables with transformations * @param groups passed returns the map of groups defined in fileContent */ -//void InitXML( const std::string xmlConfigFile, const MPI_Comm mpiComm, const bool debugMode, -// std::string& hostLanguage, std::vector< std::shared_ptr<Transform> >& transforms, +// void InitXML( const std::string xmlConfigFile, const MPI_Comm mpiComm, const +// bool debugMode, +// std::string& hostLanguage, std::vector< +// std::shared_ptr<Transform> >& transforms, // std::map< std::string, Group >& groups ); - /** - * Loops through a vector containing dimensions and returns the product of all elements + * Loops through a vector containing dimensions and returns the product of all + * elements * @param dimensions input containing size on each dimension {Nx, Ny, Nz} * @return product of all dimensions Nx * Ny * Nz */ -std::size_t GetTotalSize( const std::vector<size_t>& dimensions ); - +std::size_t GetTotalSize(const std::vector<size_t> &dimensions); /** * Might need to add exceptions for debug mode * Creates a chain of directories using POSIX systems calls (stat, mkdir), - * Verifies if directory exists before creating a new one. Permissions are 777 for now + * Verifies if directory exists before creating a new one. Permissions are 777 + * for now * @param fullPath /full/path/for/directory */ -void CreateDirectory( const std::string fullPath ) noexcept; - +void CreateDirectory(const std::string fullPath) noexcept; /** - * Identifies, verifies the corresponding transform method and adds it the transforms container if neccesary. + * Identifies, verifies the corresponding transform method and adds it the + * transforms container if neccesary. * This functions must be updated as new transform methods are supported. - * @param variableTransforms methods to be added to transforms with format "method:compressionLevel", or "method" with compressionLevel=0 (default) - * @param transforms container of existing transform methods, owned by ADIOS class - * @param debugMode if true will do more checks, exceptions, warnings, expect slower code - * @param transformIndices returns the corresponding indices in ADIOS m_Transforms for a single variable - * @param parameters returns the corresponding parameters understood by a collection of transform="method:parameter" - */ -void SetTransformsHelper( const std::vector<std::string>& transformNames, std::vector< std::shared_ptr<Transform> >& transforms, - const bool debugMode, std::vector<short>& transformIndices, std::vector<short>& parameters ); - + * @param variableTransforms methods to be added to transforms with format + * "method:compressionLevel", or "method" with compressionLevel=0 (default) + * @param transforms container of existing transform methods, owned by ADIOS + * class + * @param debugMode if true will do more checks, exceptions, warnings, expect + * slower code + * @param transformIndices returns the corresponding indices in ADIOS + * m_Transforms for a single variable + * @param parameters returns the corresponding parameters understood by a + * collection of transform="method:parameter" + */ +void SetTransformsHelper(const std::vector<std::string> &transformNames, + std::vector<std::shared_ptr<Transform>> &transforms, + const bool debugMode, + std::vector<short> &transformIndices, + std::vector<short> ¶meters); /** * Transforms a vector @@ -138,17 +160,20 @@ void SetTransformsHelper( const std::vector<std::string>& transformNames, std::v * @param debugMode true=check parameters format, false=no checks * @return a map with unique key=field, value=corresponding value */ -std::map<std::string, std::string> BuildParametersMap( const std::vector<std::string>& parameters, const bool debugMode ); - +std::map<std::string, std::string> +BuildParametersMap(const std::vector<std::string> ¶meters, + const bool debugMode); /** - * Single call that extract data buffers information from Capsule. That way virtual Capsule functions are called a few times + * Single call that extract data buffers information from Capsule. That way + * virtual Capsule functions are called a few times * @param capsules input * @param dataBuffers from Capsule.GetData() * @param positions * @param absolutePositions */ -//void GetDataBuffers( const std::vector<Capsule*>& capsules, std::vector<char*>& dataBuffers, std::vector<std::size_t>& positions, +// void GetDataBuffers( const std::vector<Capsule*>& capsules, +// std::vector<char*>& dataBuffers, std::vector<std::size_t>& positions, // std::vector<std::size_t>& absolutePositions ); /** @@ -156,40 +181,41 @@ std::map<std::string, std::string> BuildParametersMap( const std::vector<std::st * @param csv "1,2,3" * @return vector<int> = { 1, 2, 3 } */ -std::vector<int> CSVToVectorInt( const std::string csv ); - +std::vector<int> CSVToVectorInt(const std::string csv); /** - * Common strategy to check for heap buffer allocation for data and metadata typically calculated in Write + * Common strategy to check for heap buffer allocation for data and metadata + * typically calculated in Write * @param newSize new data size - * @param growthFactor user provided growth factor for index and data memory buffers ( default = 1.5 ) + * @param growthFactor user provided growth factor for index and data memory + * buffers ( default = 1.5 ) * @param maxBufferSize user provided maximum buffer size * @param buffer to be reallocated - * @return true: must do a transport flush, false: buffer sizes are enough to contain incoming data, no need for transport flush + * @return true: must do a transport flush, false: buffer sizes are enough to + * contain incoming data, no need for transport flush */ -bool CheckBufferAllocation( const std::size_t newSize, const float growthFactor, const std::size_t maxBufferSize, - std::vector<char>& buffer ); +bool CheckBufferAllocation(const std::size_t newSize, const float growthFactor, + const std::size_t maxBufferSize, + std::vector<char> &buffer); /** - * Grows a buffer by a factor of n . growthFactor . currentCapacity to accommodate for incomingDataSize + * Grows a buffer by a factor of n . growthFactor . currentCapacity to + * accommodate for incomingDataSize * @param incomingDataSize size of new data required to be stored in buffer * @param growthFactor buffer grows in multiples of the growth buffer * @param buffer to be resized - * @return -1: failed to allocate (bad_alloc), 0: didn't have to allocate (enough space), 1: successful allocation + * @return -1: failed to allocate (bad_alloc), 0: didn't have to allocate + * (enough space), 1: successful allocation */ -int GrowBuffer( const std::size_t incomingDataSize, const float growthFactor, - std::vector<char>& buffer ); - +int GrowBuffer(const std::size_t incomingDataSize, const float growthFactor, + std::vector<char> &buffer); /** * Check if system is little endian * @return true: little endian, false: big endian */ -bool IsLittleEndian( ) noexcept; - - -} //end namespace - +bool IsLittleEndian() noexcept; +} // end namespace #endif /* ADIOSFUNCTIONS_H_ */ diff --git a/include/functions/adiosTemplates.h b/include/functions/adiosTemplates.h index 8d3730336..38b5cb911 100644 --- a/include/functions/adiosTemplates.h +++ b/include/functions/adiosTemplates.h @@ -9,65 +9,97 @@ #define ADIOSTEMPLATES_H_ /// \cond EXCLUDE_FROM_DOXYGEN -#include <cstring> //std::memcpy -#include <vector> -#include <thread> -#include <set> -#include <complex> #include <cmath> //std::sqrt +#include <complex> +#include <cstring> //std::memcpy #include <iostream> +#include <set> +#include <thread> +#include <vector> /// \endcond - namespace adios { /** * Get the primitive type in a string from a template * @return if T is a char, returns string = "char" */ -template<class T> inline std::string GetType( ) noexcept { return "compound"; } -template<> inline std::string GetType<void>() noexcept { return "unknown"; } -template<> inline std::string GetType<char>() noexcept { return "char"; } -template<> inline std::string GetType<unsigned char>() noexcept { return "unsigned char"; } -template<> inline std::string GetType<short>() noexcept { return "short"; } -template<> inline std::string GetType<unsigned short>() noexcept { return "unsigned short"; } -template<> inline std::string GetType<int>() noexcept { return "int"; } -template<> inline std::string GetType<unsigned int>() noexcept { return "unsigned int"; } -template<> inline std::string GetType<long int>() noexcept { return "long int"; } -template<> inline std::string GetType<unsigned long int>() noexcept { return "unsigned long int"; } -template<> inline std::string GetType<long long int>() noexcept { return "long long int"; } -template<> inline std::string GetType<unsigned long long int>() noexcept { return "unsigned long long int"; } -template<> inline std::string GetType<float>() noexcept { return "float"; } -template<> inline std::string GetType<double>() noexcept { return "double"; } -template<> inline std::string GetType<long double>() noexcept { return "long double"; } -template<> inline std::string GetType<std::complex<float>>() noexcept { return "float complex"; } -template<> inline std::string GetType<std::complex<double>>() noexcept { return "double complex"; } -template<> inline std::string GetType<std::complex<long double>>() noexcept { return "long double complex"; } - - +template <class T> inline std::string GetType() noexcept { return "compound"; } +template <> inline std::string GetType<void>() noexcept { return "unknown"; } +template <> inline std::string GetType<char>() noexcept { return "char"; } +template <> inline std::string GetType<unsigned char>() noexcept +{ + return "unsigned char"; +} +template <> inline std::string GetType<short>() noexcept { return "short"; } +template <> inline std::string GetType<unsigned short>() noexcept +{ + return "unsigned short"; +} +template <> inline std::string GetType<int>() noexcept { return "int"; } +template <> inline std::string GetType<unsigned int>() noexcept +{ + return "unsigned int"; +} +template <> inline std::string GetType<long int>() noexcept +{ + return "long int"; +} +template <> inline std::string GetType<unsigned long int>() noexcept +{ + return "unsigned long int"; +} +template <> inline std::string GetType<long long int>() noexcept +{ + return "long long int"; +} +template <> inline std::string GetType<unsigned long long int>() noexcept +{ + return "unsigned long long int"; +} +template <> inline std::string GetType<float>() noexcept { return "float"; } +template <> inline std::string GetType<double>() noexcept { return "double"; } +template <> inline std::string GetType<long double>() noexcept +{ + return "long double"; +} +template <> inline std::string GetType<std::complex<float>>() noexcept +{ + return "float complex"; +} +template <> inline std::string GetType<std::complex<double>>() noexcept +{ + return "double complex"; +} +template <> inline std::string GetType<std::complex<long double>>() noexcept +{ + return "long double complex"; +} /** * Check in types set if "type" is one of the aliases for a certain type, * (e.g. if type = integer is an accepted alias for "int", returning true) * @param type input to be compared with an alias - * @param aliases set containing aliases to a certain type, typically Support::DatatypesAliases from Support.h + * @param aliases set containing aliases to a certain type, typically + * Support::DatatypesAliases from Support.h * @return true: is an alias, false: is not */ -template<class T> -bool IsTypeAlias( const std::string type, - const std::map<std::string, std::set<std::string>>& aliases ) noexcept +template <class T> +bool IsTypeAlias( + const std::string type, + const std::map<std::string, std::set<std::string>> &aliases) noexcept { - if( type == GetType<T>() ) //most of the time we will pass the same type, which is a key in aliases - return true; + if (type == GetType<T>()) // most of the time we will pass the same type, + // which is a key in aliases + return true; - bool isAlias = false; - if( aliases.at( GetType<T>() ).count( type ) == 1 ) - isAlias = true; + bool isAlias = false; + if (aliases.at(GetType<T>()).count(type) == 1) + isAlias = true; - return isAlias; + return isAlias; } - /** * Get the minimum and maximum values in one loop * @param values array of primitives @@ -76,58 +108,61 @@ bool IsTypeAlias( const std::string type, * @param max from values * @param nthreads threaded version not yet implemented */ -template<class T> inline -void GetMinMax( const T* values, const std::size_t size, T& min, T& max, const unsigned int nthreads = 1 ) noexcept +template <class T> +inline void GetMinMax(const T *values, const std::size_t size, T &min, T &max, + const unsigned int nthreads = 1) noexcept { - min = values[0]; - max = min; + min = values[0]; + max = min; - for( std::size_t i = 1; i < size; ++i ) + for (std::size_t i = 1; i < size; ++i) + { + if (values[i] < min) { - if( values[i] < min ) - { - min = values[i]; - continue; - } - - if( values[i] > max ) - max = values[i]; + min = values[i]; + continue; } + + if (values[i] > max) + max = values[i]; + } } /** - * Overloaded version for complex types, gets the "doughnut" range between min and max modulus + * Overloaded version for complex types, gets the "doughnut" range between min + * and max modulus * @param values array of complex numbers * @param size of the values array * @param min modulus from values * @param max modulus from values * @param nthreads */ -template<class T> inline -void GetMinMax( const std::complex<T>* values, const std::size_t size, T& min, T& max, const unsigned int nthreads = 1 ) noexcept +template <class T> +inline void GetMinMax(const std::complex<T> *values, const std::size_t size, + T &min, T &max, const unsigned int nthreads = 1) noexcept { - min = std::norm( values[0] ); - max = min; + min = std::norm(values[0]); + max = min; + + for (std::size_t i = 1; i < size; ++i) + { + T norm = std::norm(values[i]); - for( std::size_t i = 1; i < size; ++i ) + if (norm < min) { - T norm = std::norm( values[i] ); - - if( norm < min ) - { - min = norm; - continue; - } - - if( norm > max ) - { - max = norm; - } + min = norm; + continue; } - min = std::sqrt( min ); - max = std::sqrt( max ); + if (norm > max) + { + max = norm; + } + } + + min = std::sqrt(min); + max = std::sqrt(max); } /** @@ -137,102 +172,111 @@ void GetMinMax( const std::complex<T>* values, const std::size_t size, T& min, T * @param count total number of bytes (as in memcpy) * @param nthreads */ -template<class T, class U> -void MemcpyThreads( T* destination, const U* source, std::size_t count, const unsigned int nthreads = 1 ) +template <class T, class U> +void MemcpyThreads(T *destination, const U *source, std::size_t count, + const unsigned int nthreads = 1) { - // do not decompose tasks to less than 4MB pieces - const std::size_t minBlockSize = 4194304; - const std::size_t maxNThreads = std::max( (std::size_t)nthreads, count / minBlockSize ); - - if( maxNThreads == 1) - { - std::memcpy( destination, source, count ); - return; - } - - const std::size_t stride = count/maxNThreads; - const std::size_t remainder = count % maxNThreads; - const std::size_t last = stride + remainder; - - std::vector<std::thread> memcpyThreads; - memcpyThreads.reserve( maxNThreads ); - - for( unsigned int t = 0; t < maxNThreads; ++t ) - { - const size_t initialDestination = stride * t / sizeof(T); - const size_t initialSource = stride * t / sizeof(U); - - if( t == maxNThreads-1 ) - memcpyThreads.push_back( std::thread( std::memcpy, &destination[initialDestination], &source[initialSource], last ) ); - else - memcpyThreads.push_back( std::thread( std::memcpy, &destination[initialDestination], &source[initialSource], stride ) ); - } - //Now join the threads (is this really needed?) - for( auto& thread : memcpyThreads ) - thread.join( ); + // do not decompose tasks to less than 4MB pieces + const std::size_t minBlockSize = 4194304; + const std::size_t maxNThreads = + std::max((std::size_t)nthreads, count / minBlockSize); + + if (maxNThreads == 1) + { + std::memcpy(destination, source, count); + return; + } + + const std::size_t stride = count / maxNThreads; + const std::size_t remainder = count % maxNThreads; + const std::size_t last = stride + remainder; + + std::vector<std::thread> memcpyThreads; + memcpyThreads.reserve(maxNThreads); + + for (unsigned int t = 0; t < maxNThreads; ++t) + { + const size_t initialDestination = stride * t / sizeof(T); + const size_t initialSource = stride * t / sizeof(U); + + if (t == maxNThreads - 1) + memcpyThreads.push_back(std::thread(std::memcpy, + &destination[initialDestination], + &source[initialSource], last)); + else + memcpyThreads.push_back(std::thread(std::memcpy, + &destination[initialDestination], + &source[initialSource], stride)); + } + // Now join the threads (is this really needed?) + for (auto &thread : memcpyThreads) + thread.join(); } - -template< class T > -void MemcpyToBuffer( std::vector<char>& raw, std::size_t& position, const T* source, std::size_t size ) noexcept +template <class T> +void MemcpyToBuffer(std::vector<char> &raw, std::size_t &position, + const T *source, std::size_t size) noexcept { - std::memcpy( &raw[position], source, size ); - position += size; + std::memcpy(&raw[position], source, size); + position += size; } - - /** - * Version that pushed to the end of the buffer, updates vec.size() automatically + * Version that pushed to the end of the buffer, updates vec.size() + * automatically * @param raw * @param source using pointer notation * @param elements */ -template<class T> -void CopyToBuffer( std::vector<char>& buffer, const T* source, const std::size_t elements = 1 ) noexcept +template <class T> +void CopyToBuffer(std::vector<char> &buffer, const T *source, + const std::size_t elements = 1) noexcept { - const char* src = reinterpret_cast<const char*>( source ); - buffer.insert( buffer.end(), src, src + elements*sizeof(T) ); + const char *src = reinterpret_cast<const char *>(source); + buffer.insert(buffer.end(), src, src + elements * sizeof(T)); } /** - * Overloaded version to copies data to a specific location in the buffer, doesn't update vec.size() + * Overloaded version to copies data to a specific location in the buffer, + * doesn't update vec.size() * @param raw * @param position * @param source * @param elements */ -template<class T> -void CopyToBuffer( std::vector<char>& buffer, const std::size_t position, const T* source, const std::size_t elements = 1 ) noexcept +template <class T> +void CopyToBuffer(std::vector<char> &buffer, const std::size_t position, + const T *source, const std::size_t elements = 1) noexcept { - const char* src = reinterpret_cast<const char*>( source ); - std::copy( src, src + elements*sizeof(T), buffer.begin() + position ); + const char *src = reinterpret_cast<const char *>(source); + std::copy(src, src + elements * sizeof(T), buffer.begin() + position); } - -template<class T> -void CopyFromBuffer( T* destination, std::size_t elements, const std::vector<char>& raw, std::size_t& position ) noexcept +template <class T> +void CopyFromBuffer(T *destination, std::size_t elements, + const std::vector<char> &raw, + std::size_t &position) noexcept { - std::copy( raw.begin() + position, raw.begin() + position + sizeof(T)*elements, reinterpret_cast<char*>(destination) ); - position += elements*sizeof(T); + std::copy(raw.begin() + position, + raw.begin() + position + sizeof(T) * elements, + reinterpret_cast<char *>(destination)); + position += elements * sizeof(T); } - -template< class T > -void PrintValues( const std::string name, const char* buffer, const std::size_t position, const std::size_t elements ) +template <class T> +void PrintValues(const std::string name, const char *buffer, + const std::size_t position, const std::size_t elements) { - std::vector<T> values( elements ); - std::memcpy( values.data(), &buffer[position], elements * sizeof(T) ); + std::vector<T> values(elements); + std::memcpy(values.data(), &buffer[position], elements * sizeof(T)); - std::cout << "Read " << name << "\n"; - for( const auto value : values ) - std::cout << value << " "; + std::cout << "Read " << name << "\n"; + for (const auto value : values) + std::cout << value << " "; - std::cout << "\n"; + std::cout << "\n"; } - -} //end namespace - +} // end namespace #endif /* ADIOSTEMPLATES_H_ */ diff --git a/include/functions/capsuleTemplates.h b/include/functions/capsuleTemplates.h index 8262ebedc..68ff55049 100644 --- a/include/functions/capsuleTemplates.h +++ b/include/functions/capsuleTemplates.h @@ -8,23 +8,17 @@ #ifndef CAPSULETEMPLATES_H_ #define CAPSULETEMPLATES_H_ - /// \cond EXCLUDE_FROM_DOXYGEN #include <cstring> //std::memcpy -#include <vector> #include <thread> +#include <vector> /// \endcond - #include "core/Transport.h" - namespace adios { - - - /** * * @param data @@ -34,12 +28,13 @@ namespace adios * @param maxBufferSize * @param buffer */ -//template<class T> -//void WriteToBuffer( const T* data, const size_t size, +// template<class T> +// void WriteToBuffer( const T* data, const size_t size, // std::vector< std::shared_ptr<Transport> >& transports, // const size_t maxBufferSize, std::vector<char>& buffer ) //{ -// auto lf_TransportsWrite = []( const int transportIndex, std::vector< std::shared_ptr<Transport> >& transports, +// auto lf_TransportsWrite = []( const int transportIndex, std::vector< +// std::shared_ptr<Transport> >& transports, // std::vector<char>& buffer ) // { // if( transportIndex == -1 ) // all transports @@ -59,7 +54,8 @@ namespace adios // { // for( auto& transport : transports ) // { -// if( transport->m_Method == "DataMan" ) //DataMan needs all the information +// if( transport->m_Method == "DataMan" ) //DataMan needs all the +// information // buffer.resize( dataBytes ); //resize buffer to fit all data // } // } @@ -71,22 +67,28 @@ namespace adios // // if( dataBytes <= buffer.size() ) // dataBytes < buffer.size() // { -// buffer.resize( dataBytes ); //this resize shouldn't change capacity or call realloc -// MemcpyThreads( &buffer[0], data, dataBytes, 1 ); //copy memory in threaded fashion, need to test with size, serial for now +// buffer.resize( dataBytes ); //this resize shouldn't change capacity or +// call realloc +// MemcpyThreads( &buffer[0], data, dataBytes, 1 ); //copy memory in +// threaded fashion, need to test with size, serial for now // lf_TransportsWrite( transportIndex, transports, buffer ); // return; // } // -// if( buffer.size() < dataBytes && dataBytes <= maxBufferSize ) // buffer.size() < dataBytes < maxBufferSize +// if( buffer.size() < dataBytes && dataBytes <= maxBufferSize ) // +// buffer.size() < dataBytes < maxBufferSize // { // buffer.resize( dataBytes ); -// MemcpyThreads( &buffer[0], data, dataBytes, 1 ); //copy memory in threaded fashion, need to test with size, serial for now +// MemcpyThreads( &buffer[0], data, dataBytes, 1 ); //copy memory in +// threaded fashion, need to test with size, serial for now // lf_TransportsWrite( transportIndex, transports, buffer ); // return; // } // -// // dataBytes > maxBufferSize == buffer.size() split the variable in buffer buckets -// buffer.resize( maxBufferSize ); //resize to maxBufferSize, this might call realloc +// // dataBytes > maxBufferSize == buffer.size() split the variable in buffer +// buckets +// buffer.resize( maxBufferSize ); //resize to maxBufferSize, this might call +// realloc // const size_t buckets = dataBytes / maxBufferSize + 1; // const size_t remainder = dataBytes % maxBufferSize; // @@ -103,10 +105,6 @@ namespace adios // } //} - - -} //end namespace - - +} // end namespace #endif /* CAPSULETEMPLATES_H_ */ diff --git a/include/mpidummy.h b/include/mpidummy.h index 5c1de7707..e718b2e28 100644 --- a/include/mpidummy.h +++ b/include/mpidummy.h @@ -9,64 +9,65 @@ #define __MPI_DUMMY_H__ /* - A dummy MPI 'implementation' for the BP READ API, to have an MPI-free version of the API + A dummy MPI 'implementation' for the BP READ API, to have an MPI-free version + of the API */ /// \cond EXCLUDE_FROM_DOXYGEN -#include <sys/types.h> -#include <sys/stat.h> #include <fcntl.h> #include <stdint.h> #include <stdio.h> +#include <sys/stat.h> +#include <sys/types.h> /// \endcond namespace adios { - typedef int MPI_Comm; typedef uint64_t MPI_Status; typedef uint64_t MPI_Request; typedef int MPI_File; typedef int MPI_Info; -typedef int MPI_Datatype; /* Store the byte size of a type in such vars */ +typedef int MPI_Datatype; /* Store the byte size of a type in such vars */ typedef uint64_t MPI_Offset; typedef int MPI_Fint; -#define MPI_SUCCESS 0 -#define MPI_ERR_BUFFER 1 /* Invalid buffer pointer */ -#define MPI_ERR_COUNT 2 /* Invalid count argument */ -#define MPI_ERR_TYPE 3 /* Invalid datatype argument */ -#define MPI_ERR_TAG 4 /* Invalid tag argument */ -#define MPI_ERR_COMM 5 /* Invalid communicator */ -#define MPI_MAX_ERROR_STRING 512 -#define MPI_MODE_RDONLY O_RDONLY -#define MPI_SEEK_SET SEEK_SET -#define MPI_SEEK_CUR SEEK_CUR -#define MPI_SEEK_END SEEK_END -#define MPI_BYTE 1 /* I need the size of the type here */ -#define MPI_INFO_NULL 0 - -#define MPI_COMM_NULL 0 -#define MPI_COMM_WORLD 1 -#define MPI_COMM_SELF 2 - -#define MPI_INT 1 -#define MPI_CHAR 2 -#define MPI_DOUBLE 3 - -#define MPI_ANY_SOURCE 0 -#define MPI_ANY_TAG 0 - -#define MPI_SUM 0 - -#define MPI_MAX_PROCESSOR_NAME 32 +#define MPI_SUCCESS 0 +#define MPI_ERR_BUFFER 1 /* Invalid buffer pointer */ +#define MPI_ERR_COUNT 2 /* Invalid count argument */ +#define MPI_ERR_TYPE 3 /* Invalid datatype argument */ +#define MPI_ERR_TAG 4 /* Invalid tag argument */ +#define MPI_ERR_COMM 5 /* Invalid communicator */ +#define MPI_MAX_ERROR_STRING 512 +#define MPI_MODE_RDONLY O_RDONLY +#define MPI_SEEK_SET SEEK_SET +#define MPI_SEEK_CUR SEEK_CUR +#define MPI_SEEK_END SEEK_END +#define MPI_BYTE 1 /* I need the size of the type here */ +#define MPI_INFO_NULL 0 + +#define MPI_COMM_NULL 0 +#define MPI_COMM_WORLD 1 +#define MPI_COMM_SELF 2 + +#define MPI_INT 1 +#define MPI_CHAR 2 +#define MPI_DOUBLE 3 + +#define MPI_ANY_SOURCE 0 +#define MPI_ANY_TAG 0 + +#define MPI_SUM 0 + +#define MPI_MAX_PROCESSOR_NAME 32 int MPI_Init(int *argc, char ***argv); int MPI_Finalize(); -int MPI_Initialized( int* flag ) ; +int MPI_Initialized(int *flag); int MPI_Barrier(MPI_Comm comm); -int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm); +int MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, + MPI_Comm comm); int MPI_Comm_dup(MPI_Comm comm, MPI_Comm *newcomm); int MPI_Comm_rank(MPI_Comm comm, int *rank); @@ -74,36 +75,49 @@ int MPI_Comm_size(MPI_Comm comm, int *size); int MPI_Comm_free(MPI_Comm *comm); MPI_Comm MPI_Comm_f2c(MPI_Fint comm); -int MPI_Gather(void *sendbuf, int sendcnt, MPI_Datatype sendtype, void *recvbuf, int recvcnt, MPI_Datatype recvtype, int root, MPI_Comm comm) ; -int MPI_Gatherv(void *sendbuf, int sendcnt, MPI_Datatype sendtype, void *recvbuf, int *recvcnts, int *displs, MPI_Datatype recvtype, int root, MPI_Comm comm); +int MPI_Gather(void *sendbuf, int sendcnt, MPI_Datatype sendtype, void *recvbuf, + int recvcnt, MPI_Datatype recvtype, int root, MPI_Comm comm); +int MPI_Gatherv(void *sendbuf, int sendcnt, MPI_Datatype sendtype, + void *recvbuf, int *recvcnts, int *displs, + MPI_Datatype recvtype, int root, MPI_Comm comm); int MPI_Allgather(void *sendbuf, int sendcount, MPI_Datatype sendtype, void *recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm); -int MPI_Scatter(void *sendbuf, int sendcnt, MPI_Datatype sendtype, void *recvbuf, int recvcnt, MPI_Datatype recvtype, int root, MPI_Comm comm); -int MPI_Scatterv(void *sendbuf, int *sendcnts, int *displs, MPI_Datatype sendtype, void *recvbuf, int recvcnt, MPI_Datatype recvtype, int root, MPI_Comm comm); - -int MPI_Recv( void *recvbuffer, int count, MPI_Datatype type, int source, int tag, MPI_Comm comm, MPI_Status* status ); -int MPI_Irecv( void *recvbuffer, int count, MPI_Datatype type, int source, int tag, MPI_Comm comm, MPI_Request* request ); -int MPI_Send( void *sendbuffer, int count, MPI_Datatype type, int destination, int tag, MPI_Comm comm ); -int MPI_Isend( void *recvbuffer, int count, MPI_Datatype type, int source, int tag, MPI_Comm comm, MPI_Request* request ); - -int MPI_Wait( MPI_Request* request, MPI_Status* status ); - -int MPI_File_open(MPI_Comm comm, char *filename, int amode, MPI_Info info, MPI_File *fh); +int MPI_Scatter(void *sendbuf, int sendcnt, MPI_Datatype sendtype, + void *recvbuf, int recvcnt, MPI_Datatype recvtype, int root, + MPI_Comm comm); +int MPI_Scatterv(void *sendbuf, int *sendcnts, int *displs, + MPI_Datatype sendtype, void *recvbuf, int recvcnt, + MPI_Datatype recvtype, int root, MPI_Comm comm); + +int MPI_Recv(void *recvbuffer, int count, MPI_Datatype type, int source, + int tag, MPI_Comm comm, MPI_Status *status); +int MPI_Irecv(void *recvbuffer, int count, MPI_Datatype type, int source, + int tag, MPI_Comm comm, MPI_Request *request); +int MPI_Send(void *sendbuffer, int count, MPI_Datatype type, int destination, + int tag, MPI_Comm comm); +int MPI_Isend(void *recvbuffer, int count, MPI_Datatype type, int source, + int tag, MPI_Comm comm, MPI_Request *request); + +int MPI_Wait(MPI_Request *request, MPI_Status *status); + +int MPI_File_open(MPI_Comm comm, char *filename, int amode, MPI_Info info, + MPI_File *fh); int MPI_File_close(MPI_File *fh); int MPI_File_get_size(MPI_File fh, MPI_Offset *size); -int MPI_File_read(MPI_File fh, void *buf, int count, MPI_Datatype datatype, MPI_Status *status); +int MPI_File_read(MPI_File fh, void *buf, int count, MPI_Datatype datatype, + MPI_Status *status); int MPI_File_seek(MPI_File fh, MPI_Offset offset, int whence); int MPI_Get_count(MPI_Status *status, MPI_Datatype datatype, int *count); int MPI_Error_string(int errorcode, char *string, int *resultlen); -int MPI_Comm_split ( MPI_Comm comm, int color, int key, MPI_Comm *comm_out ); +int MPI_Comm_split(MPI_Comm comm, int color, int key, MPI_Comm *comm_out); -int MPI_Get_processor_name (char *name, int *resultlen); +int MPI_Get_processor_name(char *name, int *resultlen); double MPI_Wtime(); -} //end namespace +} // end namespace #endif diff --git a/include/transform/BZip2.h b/include/transform/BZip2.h index 2f2daffc5..30c2b2e36 100644 --- a/include/transform/BZip2.h +++ b/include/transform/BZip2.h @@ -8,39 +8,34 @@ #ifndef BZIP2_H_ #define BZIP2_H_ - #include "core/Transform.h" - namespace adios { namespace transform { - class BZIP2 : public Transform { public: + /** + * Initialize parent method + * @param compressionLevel + * @param variable + */ + BZIP2(); - /** - * Initialize parent method - * @param compressionLevel - * @param variable - */ - BZIP2( ); - - ~BZIP2( ); + ~BZIP2(); - void Compress( const std::vector<char>& bufferIn, std::vector<char>& bufferOut ); + void Compress(const std::vector<char> &bufferIn, + std::vector<char> &bufferOut); - void Decompress( const std::vector<char>& bufferIn, std::vector<char>& bufferOut ); + void Decompress(const std::vector<char> &bufferIn, + std::vector<char> &bufferOut); }; - -} //end namespace transform -} //end namespace adios - - +} // end namespace transform +} // end namespace adios #endif /* BZIP2_H_ */ diff --git a/include/transport/file/FStream.h b/include/transport/file/FStream.h index fed11ac1f..023445c77 100644 --- a/include/transport/file/FStream.h +++ b/include/transport/file/FStream.h @@ -14,7 +14,6 @@ #include "core/Transport.h" - namespace adios { namespace transport @@ -27,32 +26,25 @@ class FStream : public Transport { public: + FStream(MPI_Comm mpiComm, const bool debugMode); - FStream( MPI_Comm mpiComm, const bool debugMode ); - - ~FStream( ); + ~FStream(); - void Open( const std::string name, const std::string accessMode ); + void Open(const std::string name, const std::string accessMode); - void SetBuffer( char* buffer, std::size_t size ); + void SetBuffer(char *buffer, std::size_t size); - void Write( const char* buffer, std::size_t size ); + void Write(const char *buffer, std::size_t size); - void Flush( ); - - void Close( ); + void Flush(); + void Close(); private: - - std::fstream m_FStream; ///< file stream under name.bp.dir/name.bp.rank - + std::fstream m_FStream; ///< file stream under name.bp.dir/name.bp.rank }; - -} //end namespace transport -} //end namespace - - +} // end namespace transport +} // end namespace #endif /* FSTREAM_H_ */ diff --git a/include/transport/file/FileDescriptor.h b/include/transport/file/FileDescriptor.h index 0e199659c..5e344e0d9 100644 --- a/include/transport/file/FileDescriptor.h +++ b/include/transport/file/FileDescriptor.h @@ -8,10 +8,8 @@ #ifndef FILEDESCRIPTOR_H_ #define FILEDESCRIPTOR_H_ - #include "core/Transport.h" - namespace adios { namespace transport @@ -24,25 +22,20 @@ class FileDescriptor : public Transport { public: + FileDescriptor(MPI_Comm mpiComm, const bool debugMode); - FileDescriptor( MPI_Comm mpiComm, const bool debugMode ); + ~FileDescriptor(); - ~FileDescriptor( ); + void Open(const std::string name, const std::string accessMode); - void Open( const std::string name, const std::string accessMode ); + void Write(const char *buffer, std::size_t size); - void Write( const char* buffer, std::size_t size ); - - void Close( ); + void Close(); private: - - int m_FileDescriptor = -1; ///< file descriptor returned by POSIX open - + int m_FileDescriptor = -1; ///< file descriptor returned by POSIX open }; - - -} //end namespace transport -} //end namespace +} // end namespace transport +} // end namespace #endif /* FILEDESCRIPTOR_H_ */ diff --git a/include/transport/file/FilePointer.h b/include/transport/file/FilePointer.h index cbe11ef60..5b665dfce 100644 --- a/include/transport/file/FilePointer.h +++ b/include/transport/file/FilePointer.h @@ -14,46 +14,38 @@ #include "core/Transport.h" - namespace adios { namespace transport { /** - * Class that defines a transport method using C file pointer (FP) to streams FILE* + * Class that defines a transport method using C file pointer (FP) to streams + * FILE* */ class FilePointer : public Transport { public: + FilePointer(MPI_Comm mpiComm, const bool debugMode); - FilePointer( MPI_Comm mpiComm, const bool debugMode ); - - ~FilePointer( ); - - void Open( const std::string name, const std::string accessMode ); + ~FilePointer(); - void SetBuffer( char* buffer, std::size_t size ); + void Open(const std::string name, const std::string accessMode); - void Write( const char* buffer, std::size_t size ); + void SetBuffer(char *buffer, std::size_t size); - void Flush( ); + void Write(const char *buffer, std::size_t size); - void Close( ); + void Flush(); + void Close(); private: - - FILE* m_File = NULL; ///< C file pointer - + FILE *m_File = NULL; ///< C file pointer }; - -} //end namespace transport -} //end namespace - - - +} // end namespace transport +} // end namespace #endif /* FILEPOINTER_H_ */ diff --git a/include/transport/file/MPI_File.h b/include/transport/file/MPI_File.h index 0e5d1892a..d2201b787 100644 --- a/include/transport/file/MPI_File.h +++ b/include/transport/file/MPI_File.h @@ -8,12 +8,10 @@ #ifndef MPI_FILE_H_ #define MPI_FILE_H_ - /// \cond EXCLUDE_FROM_DOXYGEN #include <mpi.h> /// \endcond - namespace adios { namespace transport @@ -26,35 +24,25 @@ class MPI_File : public Transport { public: + MPI_File(MPI_Comm mpiComm, const bool debugMode); - MPI_File( MPI_Comm mpiComm, const bool debugMode ); - - ~MPI_File( ); + ~MPI_File(); - void Open( const std::string streamName, const std::string accessMode ); + void Open(const std::string streamName, const std::string accessMode); - void SetBuffer( char* buffer, std::size_t size ); + void SetBuffer(char *buffer, std::size_t size); - void Write( const char* buffer, std::size_t size ); + void Write(const char *buffer, std::size_t size); - void Flush( ); - - void Close( ); + void Flush(); + void Close(); private: - - MPI_File m_MPIFile; ///< MPI File - + MPI_File m_MPIFile; ///< MPI File }; - - -} //end namespace transport -} //end namespace - - - - +} // end namespace transport +} // end namespace #endif /* MPI_FILE_H_ */ diff --git a/include/transport/wan/MdtmMan.h b/include/transport/wan/MdtmMan.h index d0fed7848..c9eb8243f 100644 --- a/include/transport/wan/MdtmMan.h +++ b/include/transport/wan/MdtmMan.h @@ -8,11 +8,10 @@ #ifndef MDTMMAN_H_ #define MDTMMAN_H_ - -#include "external/json.hpp" #include "core/Transport.h" +#include "external/json.hpp" -#include "DataMan.h" //here comes your DataMan header +#include "DataMan.h" //here comes your DataMan header namespace adios { @@ -23,115 +22,115 @@ class MdtmMan : public Transport { public: - - - /** - * - * @param localIP - * @param remoteIP - * @param mode - * @param prefix - * @param numberOfPipes - * @param tolerances - * @param priorities - * @param mpiComm - * @param debugMode - */ - MdtmMan( const std::string localIP, const std::string remoteIP, const std::string mode, const std::string prefix, - const int numberOfPipes, const std::vector<int> tolerances, const std::vector<int> priorities, - MPI_Comm mpiComm, const bool debugMode ); - - - ~MdtmMan( ); - - - void Open( const std::string name, const std::string accessMode ); - - void SetBuffer( char* buffer, std::size_t size ); - - /** - * We can always overload this function in the base class and accept other types of data pointers, e.g. Write( json* ); - * I'm sticking with char* as it's more general (only C++ libraries, e.g. boost understand std::std::vector, MPI, POSIX, Infiniband use pointer*) - * @param buffer - * @param size - */ - void Write( const char* buffer, std::size_t size ); - - void Flush( ); ///< not sure if this one is needed... - - void Close( ); - + /** + * + * @param localIP + * @param remoteIP + * @param mode + * @param prefix + * @param numberOfPipes + * @param tolerances + * @param priorities + * @param mpiComm + * @param debugMode + */ + MdtmMan(const std::string localIP, const std::string remoteIP, + const std::string mode, const std::string prefix, + const int numberOfPipes, const std::vector<int> tolerances, + const std::vector<int> priorities, MPI_Comm mpiComm, + const bool debugMode); + + ~MdtmMan(); + + void Open(const std::string name, const std::string accessMode); + + void SetBuffer(char *buffer, std::size_t size); + + /** + * We can always overload this function in the base class and accept other + * types of data pointers, e.g. Write( json* ); + * I'm sticking with char* as it's more general (only C++ libraries, e.g. + * boost understand std::std::vector, MPI, POSIX, Infiniband use pointer*) + * @param buffer + * @param size + */ + void Write(const char *buffer, std::size_t size); + + void Flush(); ///< not sure if this one is needed... + + void Close(); private: - - std::string m_LocalIP; ///< local ip address, can change over time - std::string m_RemoteIP; ///< remote ip address, can change over time - std::string m_Mode; ///< send/write, receive/read - std::string m_Prefix; ///< prefix given to message - int m_NumberOfPipes = -1; ///< should it be unsigned int? - std::vector<int> m_Tolerances; - std::vector<int> m_Priorities; - - /** - * Should we change data to char* ? - * @param data - * @param doid - * @param variable - * @param dType - * @param putShape - * @param varShape - * @param offset - * @param timestep - * @param tolerance - * @param priority - * @return - */ - int Put( const void* data, const std::string doid, const std::string variable, const std::string dType, - const std::vector<std::uint64_t>& putShape, const std::vector<uint64_t>& varShape, const std::vector<uint64_t>& offset, - const std::uint64_t timestep, const int tolerance, const int priority ); - - /** - * - * @param data - * @param doid - * @param variable - * @param dType - * @param putShape - * @param varShape - * @param offset - * @param timestep - * @param tolerance - * @param priority - * @return - */ - int Get( void* data, const std::string doid, const std::string variable, const std::string dType, - const std::vector<std::uint64_t>& putShape, const std::vector<uint64_t>& varShape, const std::vector<uint64_t>& offset, - const std::uint64_t timestep, const int tolerance, const int priority ); - - /** - * - * @param data - * @param doid - * @param variable - * @param dType - * @param varShape - * @param timestep - * @return - */ - int Get( void *data, const std::string doid, const std::string variable, const std::string dType, - std::vector<std::uint64_t>& varShape, const std::uint64_t timestep ); - - /** - * - * @param jData - */ - void OnReceive( nlohmann::json& jData ); + std::string m_LocalIP; ///< local ip address, can change over time + std::string m_RemoteIP; ///< remote ip address, can change over time + std::string m_Mode; ///< send/write, receive/read + std::string m_Prefix; ///< prefix given to message + int m_NumberOfPipes = -1; ///< should it be unsigned int? + std::vector<int> m_Tolerances; + std::vector<int> m_Priorities; + + /** + * Should we change data to char* ? + * @param data + * @param doid + * @param variable + * @param dType + * @param putShape + * @param varShape + * @param offset + * @param timestep + * @param tolerance + * @param priority + * @return + */ + int Put(const void *data, const std::string doid, const std::string variable, + const std::string dType, const std::vector<std::uint64_t> &putShape, + const std::vector<uint64_t> &varShape, + const std::vector<uint64_t> &offset, const std::uint64_t timestep, + const int tolerance, const int priority); + + /** + * + * @param data + * @param doid + * @param variable + * @param dType + * @param putShape + * @param varShape + * @param offset + * @param timestep + * @param tolerance + * @param priority + * @return + */ + int Get(void *data, const std::string doid, const std::string variable, + const std::string dType, const std::vector<std::uint64_t> &putShape, + const std::vector<uint64_t> &varShape, + const std::vector<uint64_t> &offset, const std::uint64_t timestep, + const int tolerance, const int priority); + + /** + * + * @param data + * @param doid + * @param variable + * @param dType + * @param varShape + * @param timestep + * @return + */ + int Get(void *data, const std::string doid, const std::string variable, + const std::string dType, std::vector<std::uint64_t> &varShape, + const std::uint64_t timestep); + + /** + * + * @param jData + */ + void OnReceive(nlohmann::json &jData); }; - -} //end namespace transport -} //end namespace - - +} // end namespace transport +} // end namespace #endif /* MDTMMAN_H_ */ -- GitLab