diff --git a/README.md b/README.md index aa096b1f69069241721dfae3419f8eca72a7943e..adf4da6d499f5f164830a9bdaa5ab4ec51526f7b 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,15 @@ # ADIOSPP -Next generation ADIOS in C++ for exascale computations -Read ./doc/CodingGuidelines first if you are a developer - -Create ./lib and ./bin libraries before compiling -make -> build ./lib/libadios.a with truly MPI code (from mpi.h) -make mpi -> build ./lib/libadios.a with truly MPI code (from mpi.h) -make nompi -> build ./lib/libadios_nompi.a with serial (dummy MPI) code only calling ./public/mpiduumy.h - - +Next generation ADIOS in C++11/14 for exascale computations. +Read ./doc/CodingGuidelines first if you are a developer. +Doxygen documentation can be generated running doxygen under ./doc, a ./doc/html directory will be created + +Requirements: +1) C++11 compiler (e.g. gnu gcc 4.8.x and above) in PATH, default is g++ +2) MPI compiler (e.g. openmpi, mpich2 ) in PATH, default is mpic++ + +make -> build ./lib/libadios.a and ./lib/libadios_nompi.a +make mpi -> build ./lib/libadios.a with truly MPI code (from mpi.h) using mpic++ +make nompi -> build ./lib/libadios_nompi.a with serial (dummy MPI) code only calling mpiduumy.h using g++ (C++11) + +For examples, start with examples/hello/writer/helloWriter_OOP.cpp, build as above after ADIOS library is built \ No newline at end of file diff --git a/examples/hello/dataman/Makefile b/examples/hello/dataman/Makefile index 88896bd67f4553c5e1e5210179485ba1765fb072..16893cb71bd92822c1036dd0603502f8ef9e4d7a 100644 --- a/examples/hello/dataman/Makefile +++ b/examples/hello/dataman/Makefile @@ -7,9 +7,8 @@ BASE_NAME=helloDataMan_OOP TOOL_DIR=/usr/bin -CC=$(TOOL_DIR)/g++ # Compiling with mpicc for now -MPICC=$(TOOL_DIR)/mpic++ -AR=$(TOOL_DIR)/ar +CC=g++ # Compiling with mpicc for now +MPICC=mpic++ #ADIOS LOCATION ADIOS_DIR=../../.. diff --git a/examples/hello/dataman/helloDataMan_OOP.cpp b/examples/hello/dataman/helloDataMan_OOP.cpp index 2be3296e767cd15b244f84a65c3b6275a9caea63..da29cf6c6d81cdbd26f176a0781b6ed07f0d231a 100644 --- a/examples/hello/dataman/helloDataMan_OOP.cpp +++ b/examples/hello/dataman/helloDataMan_OOP.cpp @@ -27,30 +27,29 @@ int main( int argc, char* 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> myInts = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; - int myIntsSize = static_cast<int>( myInts.size() ); + std::vector<double> myNumbers = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + int myNX = static_cast<int>( myNumbers.size() ); try { //Define group and variables - adios::Group group( adiosDebug ); - group.DefineVariable( "myIntsSize", "int" ); //define size as scalar - group.DefineVariable( "myInts", "double", "myIntsSize" ); //define variable with associate size - - //Define method - adios::Method method( "DataMan", adiosDebug ); - method.AddCapsule( "Heap" ); - method.AddTransport( "POSIX", "have_metadata_file=0" ); //option to save to file - method.AddTransport( "TCP_IP", "fname=myfile.tcp" ); //here you can add as many options as you want in the format "parameter=value" - - //Create engine and Write - adios::engine::DataMan dataMan( "myMessage", "w", MPI_COMM_WORLD, method, adiosDebug ); - dataMan.SetDefaultGroup( group ); - dataMan.Write( "myIntsSize", &myIntsSize ); //issue hello - dataMan.Write( "myInts", &myInts.front() ); //issue hello - dataMan.Close( ); + adios::Group& wanGroup = adios.DeclareGroup( "WAN_Group" ); + adios::Var ioNX = wanGroup.DefineVariable<int>( "myNX" ); + adios::Dims ioDim1D = wanGroup.SetDimensions( {ioNX} ); //can be extended to many dimensions {ioNx, ioNy} + adios::Var ioNumbers = wanGroup.DefineVariable<double>( "myNumbers", ioDim1D ); + + adios::Method& wanMethod = adios.DeclareMethod( "WAN_Method", "DataMan" ); //name and type + wanMethod.AddTransport( "Mdtm", "localIP=128.0.0.0.1", "remoteIP=128.0.0.0.2", "tolerances=1,2,3" );//add as many as you want + //wanMethod.AddTransport( "POSIX", "have_metadata_file=true" ); + wanMethod.SetDefaultGroup( wanGroup ); + + auto dataManWriter = adios.Open( "hello_dataman", "w", wanMethod ); //here pass the method to your engine + dataManWriter->Write<int>( ioDim1D, &myNX ); //a template Write is good to have + dataManWriter->Write<double>( ioNumbers, myNumbers.data() ); + dataManWriter->Close( ); } catch( std::invalid_argument& e ) { diff --git a/include/core/Engine.h b/include/core/Engine.h index 2094f6882f6265a656bc8cff5233065af6307a15..65e41b5de2964cde22ecf3b513abce7120bb70bd 100644 --- a/include/core/Engine.h +++ b/include/core/Engine.h @@ -135,7 +135,7 @@ public: protected: - std::vector< std::shared_ptr<Capsule> > m_Capsules; ///< managed Capsules + //std::vector< std::shared_ptr<Capsule> > m_Capsules; ///< managed Capsules might not be needed by certain engines 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_Cores = 1; @@ -143,9 +143,9 @@ protected: std::vector< std::pair<Group*, std::string> > m_WrittenVariables; - virtual void Init( ) = 0; ///< Initialize m_Capsules and m_Transports, called from constructor - virtual void InitCapsules( ) = 0; ///< Initialize transports from Method, called from Init in constructor. - virtual void InitTransports( ) = 0; ///< Initialize transports from Method, called from Init in constructor. + virtual void Init( ); ///< Initialize m_Capsules and m_Transports, called from constructor + virtual void InitCapsules( ); ///< Initialize transports from Method, called from Init in constructor. + virtual void InitTransports( ); ///< Initialize transports from Method, called from Init in constructor. /** * Performs preliminary checks before writing a variable. Throws an exception if checks fail. diff --git a/include/engine/dataman/DataMan.h b/include/engine/dataman/DataMan.h index 69fa69ec23b33f0d8b7b886a99dfbfb92305dd9e..6ba92d7f0ad9a3971e174cb55ca0aebe929c6a6c 100644 --- a/include/engine/dataman/DataMan.h +++ b/include/engine/dataman/DataMan.h @@ -10,6 +10,8 @@ #include "core/Engine.h" +#include "capsule/Heap.h" +#include "format/BP1Writer.h" namespace adios @@ -66,10 +68,20 @@ public: private: + Heap 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( ); ///< from Method 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 ); + }; diff --git a/include/engine/dataman/DataManTemplates.h b/include/engine/dataman/DataManTemplates.h index f6a6140533c5c19f44a5381ffd41b6c59df36be7..2051dd5dfdc2fb5a785fac76bee52903e2ed193e 100644 --- a/include/engine/dataman/DataManTemplates.h +++ b/include/engine/dataman/DataManTemplates.h @@ -14,19 +14,35 @@ #include "core/Group.h" #include "core/Variable.h" -#include "core/Capsule.h" +#include "capsule/Heap.h" #include "core/Transport.h" +#include "format/BP1Writer.h" namespace adios { +/** + * + * @param group variable owner + * @param variableName string type + * @param variable + * @param buffer heap buffer to writer variables to for disk I/O + * @param transports + * @param bp1Writer + */ template<class T> -void DataManWriteVariable( Group& group, const std::string variableName, Variable<T>& variable, std::vector<std::shared_ptr<Capsule> >& capsules, - std::vector<std::shared_ptr<Transport> >& transports ) +void DataManWriteVariable( const Group& group, const Var variableName, Variable<T>& variable, + Heap& buffer, std::vector< std::shared_ptr<Transport> >& transports, + format::BP1Writer& bp1Writer ) + { - //here write your magic, this template replaces MACRO - std::cout << "Hello from DataMan Write variable " << variableName << "\n"; + //here write your magic, this template replaces C MACROS + std::cout << "Hello from DataMan, writing variable " << variableName << " of typeid(T).name() = " << typeid(T).name() << "\n"; + if( variable.IsDimension ) + { + std::cout << "Which is a dimension variable\n"; + } } diff --git a/include/engine/writer/Writer.h b/include/engine/writer/Writer.h index 676faa488cedf7556a0033403f7886e5eb3b1720..7e455e563d36c73508fdde136648c0d267d0075b 100644 --- a/include/engine/writer/Writer.h +++ b/include/engine/writer/Writer.h @@ -10,6 +10,7 @@ #include "core/Engine.h" #include "format/BP1Writer.h" +#include "capsule/Heap.h" namespace adios @@ -66,10 +67,10 @@ public: private: - format::BP1Writer m_BP1Writer; ///< format object will provide the required BP functionality to be applied on m_Capsules and m_Transports + Heap m_Buffer; ///< heap capsule + format::BP1Writer m_BP1Writer; ///< format object will provide the required BP functionality to be applied on m_Buffer and m_Transports void Init( ); - void InitCapsules( ); void InitTransports( ); }; diff --git a/include/engine/writer/WriterTemplates.h b/include/engine/writer/WriterTemplates.h index 37f2a4ea125d8388846178c8a43c28e3f4fce726..d21dd82b1580fbd7012e10599f0c32af94507802 100644 --- a/include/engine/writer/WriterTemplates.h +++ b/include/engine/writer/WriterTemplates.h @@ -34,7 +34,7 @@ namespace adios */ template <class T> void WriterWriteVariable( const Group& group, const std::string variableName, const Variable<T>& variable, - Capsule& buffers, std::vector< std::shared_ptr<Transport> >& transports, + Heap& buffer, std::vector< std::shared_ptr<Transport> >& transports, format::BP1Writer& bp1Writer ) { diff --git a/include/format/BP1Writer.h b/include/format/BP1Writer.h index 73a92cbfeef5a0f4a5f9e2a35dc5b099c53ef304..dbb0070463ad3af7c7d40d64b19bf24f3ed6ad1c 100644 --- a/include/format/BP1Writer.h +++ b/include/format/BP1Writer.h @@ -11,7 +11,7 @@ #include <vector> #include <cstdint> -#include <algorithm> //std::count, std::copy +#include <algorithm> //std::count, std::copy, std::for_each #include <cstring> //std::memcpy #include "core/Variable.h" @@ -104,52 +104,6 @@ public: }; - /** - * Returns data type index from enum Datatypes - * @param variable input variable - * @return data type - */ - template< class T > - std::int8_t GetDataType( const Variable<T>& variable ) noexcept - { - std::int8_t dataType = -1; - if( std::is_same<T,char>::value ) - dataType = type_byte; - - else if( std::is_same<T,short>::value ) - dataType = type_short; - - else if( std::is_same<T,int>::value ) - dataType = type_integer; - - else if( std::is_same<T,long int>::value ) - dataType = type_long; - - else if( std::is_same<T,unsigned char>::value ) - dataType = type_unsigned_byte; - - else if( std::is_same<T,unsigned short>::value ) - dataType = type_unsigned_short; - - else if( std::is_same<T,unsigned int>::value ) - dataType = type_unsigned_integer; - - else if( std::is_same<T,unsigned long int>::value ) - dataType = type_unsigned_long; - - else if( std::is_same<T,float>::value ) - dataType = type_real; - - else if( std::is_same<T,double>::value ) - dataType = type_double; - - else if( std::is_same<T,long double>::value ) - dataType = type_long_double; - //need to implement complex and string - return dataType; - } - - /** * Returns the estimated variable index size * @param group @@ -208,71 +162,117 @@ public: * @param offset */ template< class T > - void WriteToBuffers( std::vector<char*>& buffers, const T* source, std::size_t size, std::size_t& offset ) noexcept + void MemcpyToBuffers( std::vector<char*>& buffers, std::vector<std::size_t>& positions, const T* source, std::size_t size ) noexcept + { + const unsigned int length = buffers.size( ); + + for( unsigned int i = 0; i < length; ++i ) + { + std::memcpy( &buffers[positions[i]], source, size ); + positions[i] += size; + } + } + + template< class T > + void MemcpyToBuffers( std::vector<char*>& buffers, std::vector<std::size_t>& positions, + const std::vector<T>& source, std::size_t size ) noexcept { - for( auto& buffer : buffers ) + const unsigned int length = buffers.size( ); + + for( unsigned int i = 0; i < length; ++i ) { - std::memcpy( &buffer[offset], source, size ); + std::memcpy( &buffers[positions[i]], &source[i], size ); + positions[i] += size; } - offset += size; } + + template< class T, class U > - void CopyToBuffers( std::vector<char*>& buffers, const T* source, U size, std::size_t& offset ) noexcept + void CopyToBuffers( std::vector<char*>& buffers, std::vector<std::size_t>& positions, const T* source, U size ) noexcept { - for( auto& buffer : buffers ) + const unsigned int length = buffers.size( ); + + for( unsigned int i = 0; i < length; ++i ) { - std::copy( source, source+size, &buffer[offset] ); + std::copy( source, source+size, &buffers[ positions[i] ] ); + positions[i] += size; + } + } + + + template< class T, class U > + void CopyToBuffers( std::vector<char*>& buffers, std::vector<std::size_t>& positions, const std::vector<T>& source, U size ) noexcept + { + const unsigned int length = buffers.size( ); + + for( unsigned int i = 0; i < length; ++i ) + { + std::copy( &source[i], &source[i]+size, &buffers[ positions[i] ] ); + positions[i] += size; } - offset += size; } /** - * Writes a variable to BP format in data and metadata (index) buffers * @param group variable owner * @param variableName name of variable to be written * @param variable object carrying variable information * @param dataBuffers buffers to which variable metadata and payload (values) will be written. Metadata is added in case of system corruption to allow regeneration. - * @param dataPosition initial data position + * @param dataPosition initial data relative position + * @param dataAbsolutePosition data absolute position will be updated with dataPosition, needed for variable offset and variable payload offset * @param metadataBuffers buffers to which only variable metadata will be written - * @param metadataPosition - * @param memberID - * @return number of bytes written, needed for variable entry length + * @param metadataPosition position in metadataBuffer */ template< class T > - void WriteVariable( const Group& group, const Var variableName, - const Variable<T>& variable, - std::vector<char*>& dataBuffers, const std::size_t dataPosition, - std::vector<char*>& metadataBuffers, const std::size_t metadataPosition ) noexcept + void WriteVariable( const Group& group, const Var variableName, const Variable<T>& variable, + std::vector<char*>& dataBuffers, + std::vector<std::size_t>& dataPositions, + std::vector<std::size_t>& dataAbsolutePositions, + std::vector<char*>& metadataBuffers, + std::vector<std::size_t>& metadataPositions ) noexcept { - std::size_t metadataOffset = metadataPosition + 4; //length of var, will come at the end from this offset - std::size_t dataOffset = dataPosition + 8; //length of var, will come at the end from this offset + auto lf_MovePositions = []( const int bytes, std::vector<std::size_t>& positions ) + { + for( auto& position : positions ) // value or reference? + position += bytes; + }; + + const std::vector<std::size_t> metadataLengthPositions( metadataPositions ); + const std::vector<std::size_t> dataLengthPositions( dataPositions ); + + lf_MovePositions( 4, metadataPositions ); //length of var, will come at the end from this offset + lf_MovePositions( 8, dataPositions ); //length of var, will come at the end from this offset //memberID - WriteToBuffers( metadataBuffers, &m_VariablesCount, 4, metadataOffset ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &m_VariablesCount, 4 ); //group, only in metadata const std::uint16_t lengthGroupName = group.m_Name.length(); - WriteToBuffers( metadataBuffers, &lengthGroupName, 2, metadataOffset ); //2 bytes - WriteToBuffers( metadataBuffers, group.m_Name.c_str(), lengthGroupName, metadataOffset ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &lengthGroupName, 2 ); //2 bytes + MemcpyToBuffers( metadataBuffers, metadataPositions, group.m_Name.c_str(), lengthGroupName ); + //variable name to metadata and data const std::uint16_t lengthVariableName = variableName.length(); - WriteToBuffers( metadataBuffers, &lengthVariableName, 2, metadataOffset ); - WriteToBuffers( metadataBuffers, variableName.c_str(), lengthVariableName, metadataOffset ); - WriteToBuffers( dataBuffers, &lengthVariableName, 2, dataOffset ); - WriteToBuffers( dataBuffers, variableName.c_str(), lengthVariableName, dataOffset ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &lengthVariableName, 2 ); + MemcpyToBuffers( metadataBuffers, metadataPositions, variableName.c_str(), lengthVariableName ); + MemcpyToBuffers( dataBuffers, dataPositions, &lengthVariableName, 2 ); + MemcpyToBuffers( dataBuffers, dataPositions, variableName.c_str(), lengthVariableName ); + //skip path (jump 2 bytes, already set to zero) - metadataOffset += 2; - dataOffset += 2; + lf_MovePositions( 2, metadataPositions ); //length of var, will come at the end from this offset + lf_MovePositions( 2, dataPositions ); //length of var, will come at the end from this offset + //dataType - const std::uint8_t dataType = GetDataType( variable ); - WriteToBuffers( metadataBuffers, &dataType, 1, metadataOffset ); - WriteToBuffers( dataBuffers, &dataType, 1, dataOffset ); + const std::uint8_t dataType = GetDataType<T>(); + MemcpyToBuffers( metadataBuffers, metadataPositions, &dataType, 1 ); + MemcpyToBuffers( dataBuffers, dataPositions, &dataType, 1 ); //Characteristics Sets in Metadata and Data - //const std::size_t metadataCharacteristicsSetsCountPosition = metadataOffset; //very important piece - std::size_t dataCharacteristicsCountPosition = dataOffset; + //const std::vector<std::size_t> metadataCharacteristicsSetsCountPosition( metadataPositions ); //very important piece + std::vector<std::size_t> dataCharacteristicsCountPositions( dataPositions ); //very important piece + const std::uint64_t sets = 1; //write one for now - WriteToBuffers( metadataBuffers, &sets, 8, metadataOffset ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &sets, 8 ); + std::vector<std::size_t> metadataCharacteristicsCountPositions( metadataPositions ); //very important, can't be const as it is updated by MemcpyToBuffer std::uint8_t characteristicsCounter = 0; //used for characteristics count, characteristics length will be calculated at the end @@ -282,94 +282,92 @@ public: //write to metadata characteristic //characteristic: dimension std::uint8_t characteristicID = characteristic_dimensions; - WriteToBuffers( metadataBuffers, &characteristicID, 1, metadataOffset ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &characteristicID, 1 ); const std::uint8_t dimensions = localDimensions.size(); - WriteToBuffers( metadataBuffers, &dimensions, 1, metadataOffset ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &dimensions, 1 ); const std::uint16_t dimensionsLength = dimensions * 24; //24 is from 8 bytes for each: local dimension, global dimension, global offset - WriteToBuffers( metadataBuffers, &dimensionsLength, 2, metadataOffset ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &dimensionsLength, 2 ); //write in data if it's a dimension variable (scalar) y or n const char dimensionYorN = ( variable.IsDimension ) ? 'y' : 'n'; - WriteToBuffers( dataBuffers, &dimensionYorN, 1, dataOffset ); - WriteToBuffers( dataBuffers, &dimensions, 1, dataOffset ); + MemcpyToBuffers( dataBuffers, dataPositions, &dimensionYorN, 1 ); + MemcpyToBuffers( dataBuffers, dataPositions, &dimensions, 1 ); const std::uint16_t dimensionsLengthInData = dimensions * 27; //27 is from 9 bytes for each: var y/n + local, var y/n + global dimension, var y/n + global offset - WriteToBuffers( dataBuffers, &dimensionsLengthInData, 2, dataOffset ); + MemcpyToBuffers( dataBuffers, dataPositions, &dimensionsLengthInData, 2 ); if( variable.GlobalBoundsIndex == -1 ) //local variable { for( unsigned int d = 0; d < (unsigned int)localDimensions.size(); ++d ) { //metadata characteristics - WriteToBuffers( metadataBuffers, &localDimensions[d], 8, metadataOffset ); - metadataOffset += 16; //skipping global dimension(8), global offset (8) + MemcpyToBuffers( metadataBuffers, metadataPositions, &localDimensions[d], 8 ); + lf_MovePositions( 16, metadataPositions ); //skipping global dimension(8), global offset (8) } const char no = 'n'; //dimension format unsigned int value (not using memberID for now) for( unsigned int d = 0; d < (unsigned int)localDimensions.size(); ++d ) { //data dimensions - WriteToBuffers( dataBuffers, &no, 1, dataOffset ); - WriteToBuffers( dataBuffers, &localDimensions[d], 8, dataOffset ); - dataOffset += 18; //skipping var no + global dimension(8), var no + global offset (8) + MemcpyToBuffers( dataBuffers, dataPositions, &no, 1 ); + MemcpyToBuffers( dataBuffers, dataPositions, &localDimensions[d], 8 ); + lf_MovePositions( 18, dataPositions ); //skipping var no + global dimension(8), var no + global offset (8) } //dimensions in data characteristic entry - dataCharacteristicsCountPosition = dataOffset; - dataOffset += 5; //skip characteristics count(1) + length (4) - WriteToBuffers( dataBuffers, &characteristicID, 1, dataOffset ); + dataCharacteristicsCountPositions = dataPositions; //very important - std::int16_t lengthOfDimensionsCharacteristic = 3 + 24 * dimensions; // 3 = dimension(1) + length(2) ; 24 = 3 local, global, global offset x 8 bytes/each - WriteToBuffers( dataBuffers, &lengthOfDimensionsCharacteristic, 2, dataOffset ); + lf_MovePositions( 5, dataPositions ); //skip characteristics count(1) + length (4) + MemcpyToBuffers( dataBuffers, dataPositions, &characteristicID, 1 ); - WriteToBuffers( dataBuffers, &dimensions, 1, dataOffset ); - WriteToBuffers( dataBuffers, &dimensionsLength, 2, dataOffset ); + const std::int16_t lengthOfDimensionsCharacteristic = 3 + 24 * dimensions; // 3 = dimension(1) + length(2) ; 24 = 3 local, global, global offset x 8 bytes/each + MemcpyToBuffers( dataBuffers, dataPositions, &lengthOfDimensionsCharacteristic, 2 ); + MemcpyToBuffers( dataBuffers, dataPositions, &dimensions, 1 ); + MemcpyToBuffers( dataBuffers, dataPositions, &dimensionsLength, 2 ); for( unsigned int d = 0; d < (unsigned int)localDimensions.size(); ++d ) { - //data characteristics - WriteToBuffers( dataBuffers, &localDimensions[d], 8, dataOffset ); - metadataOffset += 16; //skipping global dimension(8), global offset (8) + MemcpyToBuffers( dataBuffers, dataPositions, &localDimensions[d], 8 ); + lf_MovePositions( 16, dataPositions ); } } else //global variable { - std::vector<unsigned long long int> globalDimensions = group.GetDimensions( group.m_GlobalBounds[variable.GlobalBoundsIndex].first ); - std::vector<unsigned long long int> globalOffsets = group.GetDimensions( group.m_GlobalBounds[variable.GlobalBoundsIndex].second ); + const std::vector<unsigned long long int> globalDimensions = group.GetDimensions( group.m_GlobalBounds[variable.GlobalBoundsIndex].first ); + const std::vector<unsigned long long int> globalOffsets = group.GetDimensions( group.m_GlobalBounds[variable.GlobalBoundsIndex].second ); //metadata, writing in characteristics for( unsigned int d = 0; d < (unsigned int)localDimensions.size(); ++d ) { - WriteToBuffers( metadataBuffers, &localDimensions[d], 8, metadataOffset ); - WriteToBuffers( metadataBuffers, &globalDimensions[d], 8, metadataOffset ); - WriteToBuffers( metadataBuffers, &globalOffsets[d], 8, metadataOffset ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &localDimensions[d], 8 ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &globalDimensions[d], 8 ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &globalOffsets[d], 8 ); } //data dimensions entry + const char no = 'n'; //dimension format unsigned int value for( unsigned int d = 0; d < (unsigned int)localDimensions.size(); ++d ) { - const char no = 'n'; //dimension format unsigned int value - WriteToBuffers( dataBuffers, &no, 1, dataOffset ); - WriteToBuffers( dataBuffers, &localDimensions[d], 8, dataOffset ); - WriteToBuffers( dataBuffers, &no, 1, dataOffset ); - WriteToBuffers( dataBuffers, &localDimensions[d], 8, dataOffset ); + MemcpyToBuffers( dataBuffers, dataPositions, &no, 1 ); + MemcpyToBuffers( dataBuffers, dataPositions, &localDimensions[d], 8 ); + MemcpyToBuffers( dataBuffers, dataPositions, &no, 1 ); + MemcpyToBuffers( dataBuffers, dataPositions, &localDimensions[d], 8 ); } - //dimensions in data characteristic entry (might not be required) - dataCharacteristicsCountPosition = dataOffset; - dataOffset += 5; //skip characteristics count(1) + length (4) - WriteToBuffers( dataBuffers, &characteristicID, 1, dataOffset ); //id - - std::int16_t lengthOfDimensionsCharacteristic = 3 + 24 * dimensions; // 3 = dimension(1) + length(2) ; 24 = 3 local, global, global offset x 8 bytes/each - WriteToBuffers( dataBuffers, &lengthOfDimensionsCharacteristic, 2, dataOffset ); + //dimensions in data characteristic entry + dataCharacteristicsCountPositions = dataPositions; + lf_MovePositions( 5, dataPositions ); //skip characteristics count(1) + length (4) + MemcpyToBuffers( dataBuffers, dataPositions, &characteristicID, 1 ); //id - WriteToBuffers( dataBuffers, &dimensions, 1, dataOffset ); - WriteToBuffers( dataBuffers, &dimensionsLength, 2, dataOffset ); + const std::int16_t lengthOfDimensionsCharacteristic = 3 + 24 * dimensions; // 3 = dimension(1) + length(2) ; 24 = 3 local, global, global offset x 8 bytes/each + MemcpyToBuffers( dataBuffers, dataPositions, &lengthOfDimensionsCharacteristic, 2 ); + MemcpyToBuffers( dataBuffers, dataPositions, &dimensions, 1 ); + MemcpyToBuffers( dataBuffers, dataPositions, &dimensionsLength, 2 ); for( unsigned int d = 0; d < (unsigned int)localDimensions.size(); ++d ) { - WriteToBuffers( dataBuffers, &localDimensions[d], 8, dataOffset ); - WriteToBuffers( dataBuffers, &globalDimensions[d], 8, dataOffset ); - WriteToBuffers( dataBuffers, &globalOffsets[d], 8, dataOffset ); + MemcpyToBuffers( dataBuffers, dataPositions, &localDimensions[d], 8 ); + MemcpyToBuffers( dataBuffers, dataPositions, &globalDimensions[d], 8 ); + MemcpyToBuffers( dataBuffers, dataPositions, &globalOffsets[d], 8 ); } } ++characteristicsCounter; @@ -379,18 +377,18 @@ public: if( variable.DimensionsCSV == "1" ) //scalar //just doing string scalars for now (by name), needs to be modified when user passes value { characteristicID = characteristic_value; - std::int16_t lenghtOfName = variableName.length(); + const std::int16_t lenghtOfName = variableName.length(); //metadata - WriteToBuffers( metadataBuffers, &characteristicID, 1, metadataOffset ); - WriteToBuffers( metadataBuffers, &lenghtOfName, 2, metadataOffset ); - WriteToBuffers( metadataBuffers, variableName.c_str(), lenghtOfName, metadataOffset ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &characteristicID, 1 ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &lenghtOfName, 2 ); + MemcpyToBuffers( metadataBuffers, metadataPositions, variableName.c_str(), lenghtOfName ); //data - WriteToBuffers( dataBuffers, &characteristicID, 1, dataOffset ); - std::int16_t lengthOfCharacteristic = 2 + lenghtOfName; - WriteToBuffers( dataBuffers, &lengthOfCharacteristic, 2, dataOffset ); - WriteToBuffers( dataBuffers, &lenghtOfName, 2, dataOffset ); - WriteToBuffers( dataBuffers, variableName.c_str(), lenghtOfName, dataOffset ); + MemcpyToBuffers( dataBuffers, dataPositions, &characteristicID, 1 ); + const std::int16_t lengthOfCharacteristic = 2 + lenghtOfName; + MemcpyToBuffers( dataBuffers, dataPositions, &lengthOfCharacteristic, 2 ); + MemcpyToBuffers( dataBuffers, dataPositions, &lenghtOfName, 2 ); + MemcpyToBuffers( dataBuffers, dataPositions, variableName.c_str(), lenghtOfName ); } else // Stat -> Min, Max for arrays, { @@ -398,10 +396,9 @@ public: { //Get min and max const std::size_t valuesSize = GetTotalSize( localDimensions ); - //here we can make decisions for threads based on valuesSize T min, max; - if( valuesSize >= 10000000 ) //ten million? this needs actual results + if( valuesSize >= 10000000 ) //ten million? this needs actual results //here we can make decisions for threads based on valuesSize GetMinMax( variable.Values, valuesSize, min, max, m_Cores ); //here we can add cores from constructor else GetMinMax( variable.Values, valuesSize, min, max ); @@ -412,55 +409,98 @@ public: const std::int8_t statisticMaxID = statistic_max; //write min and max to metadata - WriteToBuffers( metadataBuffers, &characteristicID, 1, metadataOffset ); //min - WriteToBuffers( metadataBuffers, &statisticMinID, 1, metadataOffset ); - WriteToBuffers( metadataBuffers, &min, sizeof(T), metadataOffset ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &characteristicID, 1 ); //min + MemcpyToBuffers( metadataBuffers, metadataPositions, &statisticMinID, 1 ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &min, sizeof(T) ); - WriteToBuffers( metadataBuffers, &characteristicID, 1, metadataOffset ); //max - WriteToBuffers( metadataBuffers, &statisticMaxID, 1, metadataOffset ); - WriteToBuffers( metadataBuffers, &max, sizeof(T), metadataOffset ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &characteristicID, 1 ); //max + MemcpyToBuffers( metadataBuffers, metadataPositions, &statisticMaxID, 1 ); + MemcpyToBuffers( metadataBuffers, metadataPositions, &max, sizeof(T) ); //write min and max to data - WriteToBuffers( dataBuffers, &characteristicID, 1, dataOffset ); //min + MemcpyToBuffers( dataBuffers, dataPositions, &characteristicID, 1 ); //min const std::int16_t lengthCharacteristic = 1 + sizeof( T ); - WriteToBuffers( dataBuffers, &lengthCharacteristic, 2, dataOffset ); - WriteToBuffers( dataBuffers, &statisticMinID, 1, dataOffset ); - WriteToBuffers( dataBuffers, &min, sizeof(T), dataOffset ); - - WriteToBuffers( dataBuffers, &characteristicID, 1, dataOffset ); //max - WriteToBuffers( dataBuffers, &lengthCharacteristic, 2, dataOffset ); - WriteToBuffers( dataBuffers, &statisticMaxID, 1, dataOffset ); - WriteToBuffers( dataBuffers, &max, sizeof(T), dataOffset ); + MemcpyToBuffers( dataBuffers, dataPositions, &lengthCharacteristic, 2 ); + MemcpyToBuffers( dataBuffers, dataPositions, &statisticMinID, 1 ); + MemcpyToBuffers( dataBuffers, dataPositions, &min, sizeof(T) ); + + MemcpyToBuffers( dataBuffers, dataPositions, &characteristicID, 1 ); //max + MemcpyToBuffers( dataBuffers, dataPositions, &lengthCharacteristic, 2 ); + MemcpyToBuffers( dataBuffers, dataPositions, &statisticMaxID, 1 ); + MemcpyToBuffers( dataBuffers, dataPositions, &max, sizeof(T) ); } } ++characteristicsCounter; - //here write characteristics count and length to data - std::uint32_t characteristicsLengthInData = dataOffset - dataCharacteristicsCountPosition; - WriteToBuffers( dataBuffers, &characteristicsCounter, 1, dataCharacteristicsCountPosition ); - WriteToBuffers( dataBuffers, &characteristicsLengthInData, 4, dataCharacteristicsCountPosition ); - dataCharacteristicsCountPosition -= 5; - //Offsets should be last and only written to metadata + //Characteristics count and length in Data + std::vector<std::uint32_t> dataCharacteristicsLengths( dataPositions ); + std::transform( dataCharacteristicsLengths.begin( ), dataCharacteristicsLengths.end( ), + dataCharacteristicsCountPositions.begin(), dataCharacteristicsCountPositions.end(), + std::minus<std::uint32_t>() ); + + MemcpyToBuffers( dataBuffers, dataCharacteristicsCountPositions, &characteristicsCounter, 1 ); + MemcpyToBuffers( dataBuffers, dataCharacteristicsCountPositions, dataCharacteristicsLengths, 4 ); //vector to vector + lf_MovePositions( -5, dataCharacteristicsCountPositions ); //back to original position + + //Offsets should be last and only written to metadata, they come from absolute positions characteristicID = characteristic_offset; - WriteToBuffers( metadataBuffers, &characteristicID, 1, metadataOffset ); //variable offset id - WriteToBuffers( metadataBuffers, &dataPosition, 8, metadataOffset ); //variable offset + MemcpyToBuffers( metadataBuffers, metadataPositions, &characteristicID, 1 ); //variable offset id + MemcpyToBuffers( metadataBuffers, metadataPositions, dataAbsolutePositions, 8 ); //variable offset ++characteristicsCounter; + //update absolute positions with dataPositions, this is the payload offset + std::transform( dataAbsolutePositions.begin(), dataAbsolutePositions.end(), + dataPositions.begin(), dataPositions.end(), std::plus<std::size_t>() ); + characteristicID = characteristic_payload_offset; - WriteToBuffers( metadataBuffers, &characteristicID, 1, metadataOffset ); //variable payload offset id - WriteToBuffers( metadataBuffers, &dataOffset, 8, metadataOffset ); //variable offset + MemcpyToBuffers( metadataBuffers, metadataPositions, &characteristicID, 1 ); //variable payload offset id + MemcpyToBuffers( metadataBuffers, metadataPositions, dataAbsolutePositions, 8 ); //variable payload offset ++characteristicsCounter; - //here write var entry length in metadata + //Characteristics count and length in Metadata + std::vector<std::uint32_t> metadataCharacteristicsLengths( metadataPositions ); + std::transform( metadataCharacteristicsLengths.begin( ), metadataCharacteristicsLengths.end( ), + metadataCharacteristicsCountPositions.begin(), metadataCharacteristicsCountPositions.end(), + std::minus<std::uint32_t>() ); + MemcpyToBuffers( metadataBuffers, metadataCharacteristicsCountPositions, &characteristicsCounter, 1 ); + MemcpyToBuffers( metadataBuffers, metadataCharacteristicsCountPositions, metadataCharacteristicsLengths, 4 ); //vector to vector + lf_MovePositions( -5, metadataCharacteristicsCountPositions ); //back to original position + + //here write payload + + ++m_VariablesCount; } //end of function + +private: + + /** + * Returns data type index from enum Datatypes + * @param variable input variable + * @return data type + */ + template< class T > inline std::int8_t GetDataType( ) noexcept { return type_unknown; } + }; +//Moving template BP1Writer::GetDataType template specializations outside of the class +template< > inline std::int8_t BP1Writer::GetDataType<char>( ) noexcept { return type_byte; } +template< > inline std::int8_t BP1Writer::GetDataType<short>( ) noexcept{ return type_short; } +template< > inline std::int8_t BP1Writer::GetDataType<int>( ) noexcept{ return type_integer; } +template< > inline std::int8_t BP1Writer::GetDataType<long int>( ) noexcept{ return type_long; } + +template< > inline std::int8_t BP1Writer::GetDataType<unsigned char>( ) noexcept { return type_unsigned_byte; } +template< > inline std::int8_t BP1Writer::GetDataType<unsigned short>( ) noexcept{ return type_unsigned_short; } +template< > inline std::int8_t BP1Writer::GetDataType<unsigned int>( ) noexcept{ return type_unsigned_integer; } +template< > inline std::int8_t BP1Writer::GetDataType<unsigned long int>( ) noexcept{ return type_unsigned_long; } +template< > inline std::int8_t BP1Writer::GetDataType<float>( ) noexcept{ return type_real; } +template< > inline std::int8_t BP1Writer::GetDataType<double>( ) noexcept{ return type_double; } +template< > inline std::int8_t BP1Writer::GetDataType<long double>( ) noexcept{ return type_long_double; } diff --git a/include/functions/adiosFunctions.h b/include/functions/adiosFunctions.h index 17697adcf989a4e757c52fd14123bac3579ed5f0..8ee76b130ae5c728d72f7993d24687e1f095403c 100644 --- a/include/functions/adiosFunctions.h +++ b/include/functions/adiosFunctions.h @@ -142,6 +142,23 @@ void SetTransformsHelper( const std::vector<std::string>& transformNames, std::v std::map<std::string, std::string> BuildParametersMap( const std::vector<std::string>& parameters, const bool debugMode ); +/** + * 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, +// std::vector<std::size_t>& absolutePositions ); + +/** + * Converts comma-separated values to a vector of integers + * @param csv "1,2,3" + * @return vector<int> = { 1, 2, 3 } + */ +std::vector<int> CSVToVectorInt( const std::string csv ); + } //end namespace diff --git a/include/functions/adiosTemplates.h b/include/functions/adiosTemplates.h index e8cf5c2f17e871a24b083accd52bcc526956d798..1e675933e3daf4d178e9f252968829971cbb618f 100644 --- a/include/functions/adiosTemplates.h +++ b/include/functions/adiosTemplates.h @@ -11,43 +11,23 @@ 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 ""; } -template< class T> inline -std::string GetType( ) noexcept -{ return ""; } - -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<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<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<float>() noexcept { return "float"; } +template<> inline std::string GetType<double>() noexcept { return "double"; } +template<> inline std::string GetType<long double>() noexcept { return "long double"; } /** @@ -61,7 +41,7 @@ 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 + 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; diff --git a/src/engine/dataman/DataMan.cpp b/src/engine/dataman/DataMan.cpp index 9c918fb7764cfe615fdaed1cbf149a0bb22c97cf..59ba6306ea0b3dcd50dd79dfd8391f20383b7256 100644 --- a/src/engine/dataman/DataMan.cpp +++ b/src/engine/dataman/DataMan.cpp @@ -11,6 +11,7 @@ #include "engine/dataman/DataMan.h" #include "engine/dataman/DataManTemplates.h" #include "core/Support.h" +#include "functions/adiosFunctions.h" //CSVToVector //supported capsules #include "capsule/Heap.h" @@ -19,6 +20,7 @@ #include "transport/POSIX.h" #include "transport/FStream.h" #include "transport/File.h" +#include "transport/MdtmMan.h" namespace adios @@ -28,7 +30,8 @@ namespace engine DataMan::DataMan( const std::string streamName, const std::string accessMode, const MPI_Comm mpiComm, const Method& method, const bool debugMode, const unsigned int cores ): - Engine( "DataMan", streamName, accessMode, mpiComm, method, debugMode, cores, " DataMan constructor (or call to ADIOS Open).\n" ) + Engine( "DataMan", streamName, accessMode, mpiComm, method, debugMode, cores, " DataMan constructor (or call to ADIOS Open).\n" ), + m_Buffer{ Heap( accessMode, m_RankMPI, m_DebugMode, cores ) } { Init( ); } @@ -50,7 +53,7 @@ void DataMan::Write( Group& group, const std::string variableName, const char* v auto index = PreSetVariable( group, variableName, " from call to Write char*" ); Variable<char>& variable = group.m_Char[index]; //must be a reference variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Capsules, m_Transports ); + DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } @@ -59,7 +62,7 @@ void DataMan::Write( Group& group, const std::string variableName, const unsigne auto index = PreSetVariable( group, variableName, " from call to Write unsigned char*" ); Variable<unsigned char>& variable = group.m_UChar[index]; //must be a reference variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Capsules, m_Transports ); + DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } @@ -68,7 +71,7 @@ void DataMan::Write( Group& group, const std::string variableName, const short* auto index = PreSetVariable( group, variableName, " from call to Write short*" ); Variable<short>& variable = group.m_Short[index]; //must be a reference variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Capsules, m_Transports ); + DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } @@ -77,7 +80,7 @@ void DataMan::Write( Group& group, const std::string variableName, const unsigne auto index = PreSetVariable( group, variableName, " from call to Write unsigned short*" ); Variable<unsigned short>& variable = group.m_UShort[index]; //must be a reference variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Capsules, m_Transports ); + DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } @@ -86,7 +89,7 @@ void DataMan::Write( Group& group, const std::string variableName, const int* va auto index = PreSetVariable( group, variableName, " from call to Write int*" ); Variable<int>& variable = group.m_Int[index]; //must be a reference variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Capsules, m_Transports ); + DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } @@ -95,7 +98,7 @@ void DataMan::Write( Group& group, const std::string variableName, const unsigne auto index = PreSetVariable( group, variableName, " from call to Write unsigned int*" ); Variable<unsigned int>& variable = group.m_UInt[index]; //must be a reference variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Capsules, m_Transports ); + DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } @@ -104,7 +107,7 @@ void DataMan::Write( Group& group, const std::string variableName, const long in auto index = PreSetVariable( group, variableName, " from call to Write long int*" ); Variable<long int>& variable = group.m_LInt[index]; //must be a reference variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Capsules, m_Transports ); + DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } @@ -113,7 +116,7 @@ void DataMan::Write( Group& group, const std::string variableName, const unsigne auto index = PreSetVariable( group, variableName, " from call to Write unsigned long int*" ); Variable<unsigned long int>& variable = group.m_ULInt[index]; //must be a reference variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Capsules, m_Transports ); + DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } @@ -122,7 +125,7 @@ void DataMan::Write( Group& group, const std::string variableName, const long lo auto index = PreSetVariable( group, variableName, " from call to Write long long int*" ); Variable<long long int>& variable = group.m_LLInt[index]; //must be a reference variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Capsules, m_Transports ); + DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } @@ -131,15 +134,16 @@ void DataMan::Write( Group& group, const std::string variableName, const unsigne auto index = PreSetVariable( group, variableName, " from call to Write unsigned long long int*" ); Variable<unsigned long long int>& variable = group.m_ULLInt[index]; //must be a reference variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Capsules, m_Transports ); + DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } + void DataMan::Write( Group& group, const std::string variableName, const float* values ) { auto index = PreSetVariable( group, variableName, " from call to Write float*" ); Variable<float>& variable = group.m_Float[index]; //must be a reference variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Capsules, m_Transports ); + DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } void DataMan::Write( Group& group, const std::string variableName, const double* values ) @@ -147,7 +151,7 @@ void DataMan::Write( Group& group, const std::string variableName, const double* auto index = PreSetVariable( group, variableName, " from call to Write double*" ); Variable<double>& variable = group.m_Double[index]; //must be a reference variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Capsules, m_Transports ); + DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } @@ -156,7 +160,7 @@ void DataMan::Write( Group& group, const std::string variableName, const long do auto index = PreSetVariable( group, variableName, " from call to Write long double*" ); Variable<long double>& variable = group.m_LDouble[index]; //must be a reference variable.Values = values; - DataManWriteVariable( group, variableName, variable, m_Capsules, m_Transports ); + DataManWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } //USING Preset Group @@ -239,18 +243,11 @@ void DataMan::Write( const std::string variableName, const long double* values ) } -void DataMan::InitCapsules( ) -{ - //Create single capsule of type heap - m_Capsules.push_back( std::make_shared<Heap>( m_AccessMode, m_RankMPI, m_Cores ) ); -} - - void DataMan::InitTransports( ) //maybe move this? { std::set< std::string > transportStreamNames; //used to check for name conflict between transports - const unsigned int transportsSize = m_Method.m_TransportParameters.size(); + //const unsigned int transportsSize = m_Method.m_TransportParameters.size(); for( const auto& parameters : m_Method.m_TransportParameters ) { @@ -258,7 +255,6 @@ void DataMan::InitTransports( ) //maybe move this? if( m_DebugMode == true ) CheckParameter( itTransport, parameters, "transport", ", in " + m_Name + m_EndMessage ); - if( itTransport->second == "POSIX" ) { m_Transports.push_back( std::make_shared<POSIX>( m_MPIComm, m_DebugMode ) ); @@ -271,9 +267,21 @@ void DataMan::InitTransports( ) //maybe move this? { m_Transports.push_back( std::make_shared<FStream>( m_MPIComm, m_DebugMode ) ); } + else if( itTransport->second == "Mdtm" || itTransport->second == "MdtmMan" ) + { + const std::string localIP( GetMdtmParameter( "localIP", parameters ) ); //mandatory + const std::string remoteIP( GetMdtmParameter( "remoteIP", parameters ) ); //mandatory + const std::string prefix( GetMdtmParameter( "prefix", parameters ) ); + const int numberOfPipes = std::stoi( GetMdtmParameter( "pipes", parameters ) ); + const std::vector<int> tolerances = CSVToVectorInt( GetMdtmParameter( "tolerances", parameters ) ); + const std::vector<int> priorities = CSVToVectorInt( GetMdtmParameter( "priorities", parameters ) ); + + m_Transports.push_back( std::make_shared<MdtmMan>( localIP, remoteIP, m_AccessMode, prefix, numberOfPipes, + tolerances, priorities, m_MPIComm, m_DebugMode ) ); + } else if( itTransport->second == "MPIFile" ) { - //m_Transports.push_back( std::make_shared<MPIFile>( m_MPIComm, m_DebugMode ) ); not yet supported + //m_Transports.push_back( std::make_shared<MPIFile>( m_MPIComm, m_DebugMode ) ); //not yet supported } else { @@ -281,36 +289,46 @@ void DataMan::InitTransports( ) //maybe move this? throw std::invalid_argument( "ERROR: transport + " + itTransport->second + " not supported, in " + m_Name + m_EndMessage ); } - //name - if( transportsSize > 1 ) - { - auto itName = parameters.find( "name" ); //first check name + } +} - if( m_DebugMode == true ) - CheckParameter( itName, parameters, "name", " in transport " + itTransport->second + - ", in " + m_Name + m_EndMessage ); - m_Transports.back()->Open( itName->second, m_AccessMode ); - } - else if( transportsSize == 1 ) - { - auto itName = parameters.find( "name" ); +std::string DataMan::GetMdtmParameter( const std::string parameter, const std::map<std::string,std::string>& mdtmParameters ) +{ + auto itParam = mdtmParameters.find( parameter ); + if( itParam != mdtmParameters.end() ) //found + { + return itParam->second; //return value + } + // if not found + //mandatory ones + if( parameter == "localIP" || parameter == "remoteIP" ) + { + if( m_DebugMode == true ) + throw std::invalid_argument( "ERROR: " + parameter + " parameter not found in Method, in call to DataMan constructor\n" ); + } + else if( parameter == "prefix" ) + { + return ""; + } + else if( parameter == "pipes" ) + { + return "0"; // or 1? + } + else if( parameter == "tolerances" ) //so far empty string + { - if( itName == parameters.end() ) //take streamName - m_Transports.back()->Open( m_Name, m_AccessMode ); - else - m_Transports.back()->Open( m_Name, m_AccessMode ); + } + else if( parameter == "priority" ) + { - } - else if( transportsSize == 0 ) - { - if( m_DebugMode == true ) - throw std::invalid_argument( "ERROR: transport not defined for engine " + m_Name + m_EndMessage ); - } } + + return ""; //return empty string } + } //end namespace engine } //end namespace adios diff --git a/src/engine/writer/Writer.cpp b/src/engine/writer/Writer.cpp index 89f832d613ceae67eb5d5df0bda3f2f3ddd4ef75..9e5fc7c22e8ce822dcf70e02ad339ce6ae0d0558 100644 --- a/src/engine/writer/Writer.cpp +++ b/src/engine/writer/Writer.cpp @@ -27,7 +27,8 @@ namespace adios Writer::Writer( const std::string streamName, const std::string accessMode, const MPI_Comm mpiComm, const Method& method, const bool debugMode, const unsigned int cores ): - Engine( "Writer", streamName, accessMode, mpiComm, method, debugMode, cores, " Writer constructor (or call to ADIOS Open).\n" ) + Engine( "Writer", streamName, accessMode, mpiComm, method, debugMode, cores, " Writer constructor (or call to ADIOS Open).\n" ), + m_Buffer{ Heap( accessMode, m_RankMPI, m_DebugMode, cores ) } { Init( ); } @@ -49,7 +50,7 @@ void Writer::Write( Group& group, const std::string variableName, const char* va auto index = PreSetVariable( group, variableName, " from call to Write char*" ); Variable<char>& variable = group.m_Char[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, *m_Capsules[0], m_Transports, m_BP1Writer ); + WriterWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } void Writer::Write( Group& group, const std::string variableName, const unsigned char* values ) @@ -57,7 +58,7 @@ void Writer::Write( Group& group, const std::string variableName, const unsigned auto index = PreSetVariable( group, variableName, " from call to Write unsigned char*" ); Variable<unsigned char>& variable = group.m_UChar[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, *m_Capsules[0], m_Transports, m_BP1Writer ); + WriterWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } void Writer::Write( Group& group, const std::string variableName, const short* values ) @@ -65,7 +66,7 @@ void Writer::Write( Group& group, const std::string variableName, const short* v auto index = PreSetVariable( group, variableName, " from call to Write short*" ); Variable<short>& variable = group.m_Short[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, *m_Capsules[0], m_Transports, m_BP1Writer ); + WriterWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } void Writer::Write( Group& group, const std::string variableName, const unsigned short* values ) @@ -73,7 +74,7 @@ void Writer::Write( Group& group, const std::string variableName, const unsigned auto index = PreSetVariable( group, variableName, " from call to Write unsigned short*" ); Variable<unsigned short>& variable = group.m_UShort[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, *m_Capsules[0], m_Transports, m_BP1Writer ); + WriterWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } void Writer::Write( Group& group, const std::string variableName, const int* values ) @@ -81,7 +82,7 @@ void Writer::Write( Group& group, const std::string variableName, const int* val auto index = PreSetVariable( group, variableName, " from call to Write int*" ); Variable<int>& variable = group.m_Int[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, *m_Capsules[0], m_Transports, m_BP1Writer ); + WriterWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } void Writer::Write( Group& group, const std::string variableName, const unsigned int* values ) @@ -89,7 +90,7 @@ void Writer::Write( Group& group, const std::string variableName, const unsigned auto index = PreSetVariable( group, variableName, " from call to Write unsigned int*" ); Variable<unsigned int>& variable = group.m_UInt[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, *m_Capsules[0], m_Transports, m_BP1Writer ); + WriterWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } void Writer::Write( Group& group, const std::string variableName, const long int* values ) @@ -97,7 +98,7 @@ void Writer::Write( Group& group, const std::string variableName, const long int auto index = PreSetVariable( group, variableName, " from call to Write long int*" ); Variable<long int>& variable = group.m_LInt[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, *m_Capsules[0], m_Transports, m_BP1Writer ); + WriterWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } void Writer::Write( Group& group, const std::string variableName, const unsigned long int* values ) @@ -105,7 +106,7 @@ void Writer::Write( Group& group, const std::string variableName, const unsigned auto index = PreSetVariable( group, variableName, " from call to Write unsigned long int*" ); Variable<unsigned long int>& variable = group.m_ULInt[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, *m_Capsules[0], m_Transports, m_BP1Writer ); + WriterWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } void Writer::Write( Group& group, const std::string variableName, const long long int* values ) @@ -113,7 +114,7 @@ void Writer::Write( Group& group, const std::string variableName, const long lon auto index = PreSetVariable( group, variableName, " from call to Write long long int*" ); Variable<long long int>& variable = group.m_LLInt[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, *m_Capsules[0], m_Transports, m_BP1Writer ); + WriterWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } void Writer::Write( Group& group, const std::string variableName, const unsigned long long int* values ) @@ -121,7 +122,7 @@ void Writer::Write( Group& group, const std::string variableName, const unsigned auto index = PreSetVariable( group, variableName, " from call to Write unsigned long long int*" ); Variable<unsigned long long int>& variable = group.m_ULLInt[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, *m_Capsules[0], m_Transports, m_BP1Writer ); + WriterWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } void Writer::Write( Group& group, const std::string variableName, const float* values ) @@ -129,7 +130,7 @@ void Writer::Write( Group& group, const std::string variableName, const float* v auto index = PreSetVariable( group, variableName, " from call to Write float*" ); Variable<float>& variable = group.m_Float[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, *m_Capsules[0], m_Transports, m_BP1Writer ); + WriterWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } @@ -138,7 +139,7 @@ void Writer::Write( Group& group, const std::string variableName, const double* auto index = PreSetVariable( group, variableName, " from call to Write double*" ); Variable<double>& variable = group.m_Double[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, *m_Capsules[0], m_Transports, m_BP1Writer ); + WriterWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } @@ -147,7 +148,7 @@ void Writer::Write( Group& group, const std::string variableName, const long dou auto index = PreSetVariable( group, variableName, " from call to Write long double*" ); Variable<long double>& variable = group.m_LDouble[index]; //must be a reference variable.Values = values; - WriterWriteVariable( group, variableName, variable, *m_Capsules[0], m_Transports, m_BP1Writer ); + WriterWriteVariable( group, variableName, variable, m_Buffer, m_Transports, m_BP1Writer ); } @@ -242,12 +243,6 @@ void Writer::Write( const std::string variableName, const long double* values ) } -void Writer::InitCapsules( ) -{ - m_Capsules.push_back( std::make_shared<Heap>( m_AccessMode, m_RankMPI, m_Cores ) ); -} - - void Writer::InitTransports( ) { //Let BPFormat handle this?? diff --git a/src/functions/adiosFunctions.cpp b/src/functions/adiosFunctions.cpp index 94230cff119a970f3a9474957be5f675673ca542..426b9c2cf549c4758498fc3b347b7f2a7b16bcce 100644 --- a/src/functions/adiosFunctions.cpp +++ b/src/functions/adiosFunctions.cpp @@ -12,6 +12,7 @@ #include <iostream> #include <thread> //std::thread #include <cstring> //std::memcpy +#include <algorithm> //std::count #include <sys/types.h> //CreateDirectory #include <sys/stat.h> //stat @@ -510,6 +511,32 @@ std::map<std::string, std::string> BuildParametersMap( const std::vector<std::st } +std::vector<int> CSVToVectorInt( const std::string csv ) +{ + std::vector<int> numbers; + if( csv.empty() ) + return numbers; + + if( csv.find(",") == csv.npos ) //check if no commas, one int + { + numbers.push_back( std::stoi( csv ) ); //might need to be checked + } + else + { + int count = std::count( csv.begin(), csv.end(), ',' ); + numbers.reserve( count ); + + std::istringstream csvSS( csv ); + std::string value; + while( std::getline( csvSS, value, ',' ) ) //need to test + { + numbers.push_back( std::stoi( csv ) ); + } + } + + return numbers; +} +