diff --git a/include/core/Engine.h b/include/core/Engine.h index 5f053edeeb9f1254092c2fb548c5bb249c65f1d6..7c9b2b65f53b96f6b2192396553045833098e8b3 100644 --- a/include/core/Engine.h +++ b/include/core/Engine.h @@ -170,9 +170,10 @@ protected: const std::string parameterName, const std::string hint ) const; - void CheckDefaultGroup( ) const; ///< checks if default group m_Group is nullptr, throws exception if trying to use + bool TransportNamesUniqueness( ) const; ///< checks if transport names are unique among the same types (file I/O) + std::string GetName( const std::vector<std::string>& arguments ) const; //might move this to adiosFunctions }; diff --git a/include/core/Support.h b/include/core/Support.h index f472ce127ceca86872f29144e1f6d7426cd5c5a9..36f75e80b5e42b63876d749ee3a5fbe477bd56dc 100644 --- a/include/core/Support.h +++ b/include/core/Support.h @@ -28,6 +28,8 @@ struct Support 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 }; diff --git a/include/format/BP1.h b/include/format/BP1.h index ab6f371b2e78fec75fd956cf692a294edd9325c9..6b32c836e7c1b341a8daf141c993c087a2e80e8a 100644 --- a/include/format/BP1.h +++ b/include/format/BP1.h @@ -96,8 +96,6 @@ enum VariableStatistics - - } //end namespace format } //end namespace adios diff --git a/include/format/BP1Writer.h b/include/format/BP1Writer.h index f984c2748e1d2ca5b70519b9d3e19c8f69f1b17a..bf15ddd46f4144ed835b20d17a3085bb926fad1c 100644 --- a/include/format/BP1Writer.h +++ b/include/format/BP1Writer.h @@ -51,6 +51,15 @@ public: ~BP1Writer( ); + std::size_t GetProcessIndexSize( const std::string name, const std::string timeStepName ); + + void WriteProcessGroupIndex( const bool isFortran, const std::string name, const unsigned int processID, + const std::string timeStepName, const unsigned int timeStep, + 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 ); + /** * Returns the estimated variable index size * @param group @@ -69,7 +78,7 @@ public: indexSize += variableName.size(); // characteristics 3 and 4, check variable number of dimensions - std::size_t dimensions = std::count( variable.DimensionsCSV.begin(), variable.DimensionsCSV.end(), ',' ) + 1; //number of commas in CSV + 1 + const std::size_t dimensions = std::count( variable.DimensionsCSV.begin(), variable.DimensionsCSV.end(), ',' ) + 1; //number of commas in CSV + 1 indexSize += 28 * dimensions; //28 bytes per dimension indexSize += 1; //id @@ -129,7 +138,7 @@ public: //memberID MemcpyToBuffers( metadataBuffers, metadataPositions, &m_VariablesCount, 4 ); - //group, only in metadata + //group name, only in metadata const std::uint16_t lengthGroupName = group.m_Name.length(); WriteNameRecord( group.m_Name, lengthGroupName, metadataBuffers, metadataPositions ); @@ -291,12 +300,15 @@ public: ++m_VariablesCount; } //end of function - void Close( const BP1MetadataSet& metadataSet, Capsule& capsule, Transport& transport ); private: + + + + /** * Writes name record using a * @param name to be written @@ -304,7 +316,7 @@ private: * @param buffers to be written * @param positions to be moved */ - void WriteNameRecord( const std::string& name, const std::uint16_t& length, + void WriteNameRecord( const std::string name, const std::uint16_t length, std::vector<char*>& buffers, std::vector<std::size_t>& positions ); void WriteDimensionRecord( std::vector<char*>& buffers, std::vector<std::size_t>& positions, diff --git a/include/functions/adiosFunctions.h b/include/functions/adiosFunctions.h index afb081c92abad6f03490cfcae492aa61507a1c72..f43a7f3c9b44e027164234e3e4880acc5d3a6cd8 100644 --- a/include/functions/adiosFunctions.h +++ b/include/functions/adiosFunctions.h @@ -178,6 +178,7 @@ int GrowBuffer( const std::size_t incomingDataSize, const float growthFactor, co */ void MovePositions( const int bytes, std::vector<std::size_t>& positions ); + } //end namespace diff --git a/include/functions/engineTemplates.h b/include/functions/engineTemplates.h deleted file mode 100644 index 626755a6d1ec1841a5643667b3e92b98a3ce41bb..0000000000000000000000000000000000000000 --- a/include/functions/engineTemplates.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * GroupTemplates.h - * - * Created on: Nov 7, 2016 - * Author: wfg - */ - -#ifndef ENGINETEMPLATES_H_ -#define ENGINETEMPLATES_H_ - -/// \cond EXCLUDE_FROM_DOXYGEN -#include <string> -#include <stdexcept> -/// \endcond - - -#include "core/Group.h" -#include "core/Variable.h" -#include "core/Capsule.h" -#include "functions/adiosFunctions.h" - - - -namespace adios -{ - - -/** - * Intermediate function that assigns values from user to a Variable.Values pointer reference - * and dispatches it to different capsules. - * A variable's numerical dimensions are obtained from previously set variables in group. - * @param group variable owner, used to get all dimensions as numerical values - * @param variable variable to be written - * @param capsules container of capsules coming from an Engine - * @param transports used only if buffer size is larger than a certain maximum - */ -template<class T> -void WriteToCapsules( const Group& group, Variable<T>& variable, const T* values, - std::vector< std::shared_ptr<Capsule> >& capsules, - std::vector< std::shared_ptr<Transport> >& transports ) -{ - variable.Values = values; - auto localDimensions = group.GetDimensions( variable.DimensionsCSV ); - - std::vector< unsigned long long int > globalDimensions; - std::vector< unsigned long long int > globalOffsets; - - if( variable.GlobalBoundsIndex > -1 ) //global variable - { - globalDimensions = group.GetDimensions( group.m_GlobalBounds[ variable.GlobalBoundsIndex ].first ); - globalOffsets = group.GetDimensions( group.m_GlobalBounds[ variable.GlobalBoundsIndex ].second ); - } - - for( auto& capsule : capsules ) - { - //capsule->Write( variable, localDimensions, globalDimensions, globalOffsets, transports ); - } -} - - -} //end namespace - - - -#endif /* ENGINETEMPLATES_H_ */ diff --git a/src/core/Engine.cpp b/src/core/Engine.cpp index 7293df87dd22276bf6a230378409fe8098563e91..55eff35a845dee6468393991adabe68ffae00679 100644 --- a/src/core/Engine.cpp +++ b/src/core/Engine.cpp @@ -106,6 +106,42 @@ void Engine::CheckDefaultGroup( ) const } +bool Engine::TransportNamesUniqueness( ) const +{ + auto lf_CheckTransportsType = [&]( const std::set<std::string>& specificType ) -> bool + { + std::set<std::string> transportNames; + + for( const auto& parameters : m_Method.m_TransportParameters ) + { + auto itTransport = parameters.find( "transport" ); + if( m_DebugMode == true ) + { + if( itTransport == parameters.end() ) + throw std::invalid_argument( "ERROR: transport not defined in Method input to Engine " + m_Name ); + } + + const std::string type( itTransport->second ); + if( specificType.count( type ) == 1 ) //file transports type + { + std::string name( m_Name ); + auto itName = parameters.find("name"); + if( itName != parameters.end() ) + name = itName->second; + + if( transportNames.count( name ) == 0 ) + transportNames.insert( name ); + else + return false; + } + } + return true; + }; + + return lf_CheckTransportsType( Support::FileTransports ); +} + + std::string Engine::GetName( const std::vector<std::string>& arguments ) const { bool isNameFound = false; diff --git a/src/core/Support.cpp b/src/core/Support.cpp index 25804adb7432532874e15d128cf92a0a7160137d..670838cda448e5208dbe372f88afea56095c9935 100644 --- a/src/core/Support.cpp +++ b/src/core/Support.cpp @@ -104,5 +104,12 @@ const std::map<std::string, std::set<std::string> > Support::DatatypesAliases }; +const std::set<std::string> Support::FileTransports{ + { "POSIX", "File", "FStream", "MPIFile" } +}; + + + + } //end namespace diff --git a/src/engine/writer/Writer.cpp b/src/engine/writer/Writer.cpp index 2ff46fa9a210e2fe85eb68afc01d40b19d189e80..aff6b34bae7dbf37359b43cc7b096d8527075dc9 100644 --- a/src/engine/writer/Writer.cpp +++ b/src/engine/writer/Writer.cpp @@ -261,7 +261,9 @@ void Writer::Write( const std::string variableName, const long double* values ) void Writer::InitTransports( ) { - //Let BPFormat handle this?? + //Let BPFormat handle this + //InitTransportsBP( m_Method.m_TransportParameters, m_Transports, m_Name+m_EndMessage ); + std::set< std::string > transportStreamNames; //used to check for name conflict between transports const unsigned int transportsSize = m_Method.m_TransportParameters.size(); diff --git a/src/format/BP1Writer.cpp b/src/format/BP1Writer.cpp index b48a229bbc1b564ac7033c15fd52643ad16cdfa0..d7f2d398b8a8ec526c1b2942dd51d70192e24c07 100644 --- a/src/format/BP1Writer.cpp +++ b/src/format/BP1Writer.cpp @@ -25,6 +25,64 @@ BP1Writer::~BP1Writer( ) { } +std::size_t BP1Writer::GetProcessIndexSize( const std::string name, const std::string timeStepName ) +{ + return name.length() + timeStepName.length() + 23; +} + + +void BP1Writer::WriteProcessGroupIndex( const bool isFortran, const std::string name, const unsigned int processID, + const std::string timeStepName, const unsigned int timeStep, + 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 ) +{ + std::vector<std::size_t> metadataLengthPositions( metadataPositions ); //get length of pg position + + MovePositions( 2, metadataPositions ); //skip length of pg in metadata, 2 bytes, would write at the end + MovePositions( 8, dataPositions ); //skip length of pg including data, 8 bytes, would write at the end + + //write name to metadata + const std::uint16_t lengthOfName = name.length(); + WriteNameRecord( name, lengthOfName, metadataBuffers, metadataPositions ); + + //write is host language Fortran in metadata and data + const char hostFortran = ( isFortran ) ? 'y' : 'n'; //if host language is fortran + MemcpyToBuffers( metadataBuffers, metadataPositions, &hostFortran, 1 ); + MemcpyToBuffers( dataBuffers, dataPositions, &hostFortran, 1 ); + + //name in data + WriteNameRecord( name, lengthOfName, dataBuffers, dataPositions ); + + //processID, + MemcpyToBuffers( metadataBuffers, metadataPositions, &processID, 4 ); + //skip coordination var in data ....what is coordination var? + MovePositions( 4, dataPositions ); + + //time step name to metadata and data + const std::uint16_t lengthOfTimeStep = timeStepName.length(); + WriteNameRecord( timeStepName, lengthOfTimeStep, metadataBuffers, metadataPositions ); + WriteNameRecord( timeStepName, lengthOfTimeStep, dataBuffers, dataPositions ); + //time step to metadata and data + MemcpyToBuffers( metadataBuffers, metadataPositions, &timeStep, 4 ); + MemcpyToBuffers( dataBuffers, dataPositions, &timeStep, 4 ); + + //write offset to pg in data on metadata which is the current absolute position + MemcpyToBuffers( metadataBuffers, metadataPositions, dataAbsolutePositions, 8 ); + + + //get pg index length + std::vector<std::uint16_t> metadataIndexLengths( metadataPositions.size() ); + for( unsigned int i = 0; i < metadataPositions.size(); ++i ) + metadataIndexLengths[i] = metadataPositions[i] - metadataLengthPositions[i]; + + //write to metadata length position the pgIndex length + MemcpyToBuffers( metadataBuffers, metadataLengthPositions, metadataIndexLengths, 2 ); + MovePositions( -2, metadataLengthPositions ); //back to original position +} + + void BP1Writer::Close( const BP1MetadataSet& metadataSet, Capsule& capsule, Transport& transport ) { @@ -34,7 +92,7 @@ void BP1Writer::Close( const BP1MetadataSet& metadataSet, Capsule& capsule, Tran } //PRIVATE FUNCTIONS -void BP1Writer::WriteNameRecord( const std::string& name, const std::uint16_t& length, +void BP1Writer::WriteNameRecord( const std::string name, const std::uint16_t length, std::vector<char*>& buffers, std::vector<std::size_t>& positions ) { MemcpyToBuffers( buffers, positions, &length, 2 ); diff --git a/src/transport/POSIX.cpp b/src/transport/POSIX.cpp index dafd3d33d7de43840dadbc2c8137262809729a70..264ffb35b250d294858c4a25a46005ff86d6ad38 100644 --- a/src/transport/POSIX.cpp +++ b/src/transport/POSIX.cpp @@ -42,13 +42,17 @@ void POSIX::Open( const std::string name, const std::string accessMode ) m_AccessMode = accessMode; if( accessMode == "w" || accessMode == "write" ) + { m_FileDescriptor = open( m_Name.c_str(), O_WRONLY | O_CREAT, 0666 ); - + } else if( accessMode == "a" || accessMode == "append" ) + { m_FileDescriptor = open( m_Name.c_str(), O_WRONLY | O_APPEND ); - + } else if( accessMode == "r" || accessMode == "read" ) + { m_FileDescriptor = open( m_Name.c_str(), O_RDONLY ); + } if( m_DebugMode == true ) {