diff --git a/include/ADIOS.h b/include/ADIOS.h index 17f91629d1be312885878420efd3a446585bba1c..b60c71b52939ce4965b6a3a19133d4372c36431b 100644 --- a/include/ADIOS.h +++ b/include/ADIOS.h @@ -14,6 +14,8 @@ #include <memory> //shared_ptr #include <ostream> #include <unordered_map> +#include <set> +#include <map> /// \endcond #ifdef HAVE_MPI @@ -26,7 +28,6 @@ #include "core/Method.h" #include "core/Engine.h" #include "core/Support.h" -#include "functions/engineTemplates.h" namespace adios @@ -101,8 +102,6 @@ public: // PUBLIC Constructors and Functions define the User Interface with ADIO void DefineVariable( const std::string groupName, const std::string variableName, const std::string type, const std::string dimensionsCSV = "", const std::string globalDimensionsCSV = "", const std::string globalOffsetsCSV = "" ); - - /** * Sets a transform method to a variable, to be applied when writing * @param groupName corresponding variable group @@ -124,26 +123,67 @@ public: // PUBLIC Constructors and Functions define the User Interface with ADIO void DefineAttribute( const std::string groupName, const std::string attributeName, const std::string type, const std::string value ); + + /** + * Declares a new method + * @param name + * @param type + */ + void DeclareMethod( const std::string methodName, const std::string type ); + + /** + * Add a capsule type to method name defined from DeclareMethod + * @param methodName unique method name + * @param args variadic parameters with format parameter=value + */ + template< class ...Args> + void AddCapsule( const std::string methodName, const Args... args ) + { + auto itMethod = m_Methods.find( methodName ); + if( m_DebugMode == true ) + CheckMethod( itMethod, methodName, " from call to AddBuffer\n" ); + + itMethod->second.AddCapsule( args ); + } + + /** + * Add a transport type to method name defined from DeclareMethod + * @param methodName unique method name + * @param args variadic parameters with format parameter=value + */ + template< class ...Args> + void AddTransport( const std::string methodName, const Args... args ) + { + auto itMethod = m_Methods.find( methodName ); + if( m_DebugMode == true ) + CheckMethod( itMethod, methodName, " from call to AddTransport\n" ); + + itMethod->second.AddTransport( args ); + } + /** * @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" * @param mpiComm option to modify communicator from ADIOS class constructor * @param method looks for corresponding Method object in ADIOS to initialize the engine + * @param cores optional parameter for threaded operations * @return handler to created engine */ const unsigned int Open( const std::string streamName, const std::string accessMode, MPI_Comm mpiComm, - const std::string methodName ); + const std::string methodName, const unsigned int cores = 1 ); /** * @brief Open to Write, Read. Creates a new engine from previously defined method. Reuses MPI communicator from ADIOS class constructor. * @param streamName unique stream or file name * @param accessMode "w" or "write", "r" or "read", "a" or "append" - * @param method looks for corresponding Method object in ADIOS to initialize the engine + * @param methodName looks for corresponding Method object in ADIOS to initialize the engine + * @param cores optional parameter for threaded operations * @return handler to created engine */ - const unsigned int Open( const std::string streamName, const std::string accessMode, const std::string methodName ); + const unsigned int Open( const std::string streamName, const std::string accessMode, const std::string methodName, + const unsigned int cores = 1 ); /** @@ -257,15 +297,26 @@ private: //TRANSFORMS std::vector< std::shared_ptr<Transform> > m_Transforms; ///< transforms associated with ADIOS run + /** * @brief Checks for group existence in m_Groups, if failed throws std::invalid_argument exception - * @param itGroup m_Group iterator, usually from find function + * @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 CheckGroup( std::map< std::string, Group >::const_iterator itGroup, const std::string groupName, 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; + + /** * @brief Checks for engine existence in m_Engines, if failed throws std::invalid_argument exception * @param itEngine from Open diff --git a/include/core/Engine.h b/include/core/Engine.h index 26c938b28557bdf17f4e0733bfdadfa5bdd6c86e..b7e2bcd96af9b52f494247c37b381ec99c545201 100644 --- a/include/core/Engine.h +++ b/include/core/Engine.h @@ -64,16 +64,11 @@ public: * @param mpiComm * @param method */ - Engine( const std::string engineType, const std::string name, const std::string accessMode, const MPI_Comm mpiComm, - const Method& method, const bool debugMode = false, const unsigned int cores = 1 ); - + Engine( const std::string engineType, const std::string name, const std::string accessMode, + MPI_Comm mpiComm, const Method& method, const bool debugMode, const unsigned int cores ); virtual ~Engine( ); - - template< class T > - void Write( Group& group, const std::string variableName, const T* values ); - /** * @brief Write functions can be overridden by derived classes. Base class behavior is to: * 1) Write to Variable values (m_Values) in a group diff --git a/include/core/Method.h b/include/core/Method.h index e042cef0a4c9d2595337b2cc41bb90f05bf3f281..1c38e35254d42038fe17b48049d510f941c2bb5e 100644 --- a/include/core/Method.h +++ b/include/core/Method.h @@ -10,6 +10,7 @@ #include <vector> #include <string> +#include <map> namespace adios @@ -18,11 +19,45 @@ namespace adios /** * Serves as metadata to define an engine */ -struct Method +class Method { - std::string Name; ///< Method name - std::vector< std::string > Capsules; ///< Capsule type - std::map< std::string, std::vector<std::string> > Transports; ///< key: transports, value: arguments to Transport + +public: + + const std::string m_Type = "SingleBP"; ///< Method type + const bool m_DebugMode = false; ///< true: on, throws exceptions and do additional checks, false: off, faster, but unsafe + + /** + * Unique constructor, must have a type + * @param type must be an engine type, default = SingleBP + */ + Method( const std::string type = "SingleBP", const bool debugMode = false ); + + ~Method( ); + + template< class ...Args> + void AddCapsule( Args... args ) + { + std::vector<std::string> parameters = { args }; + AddCapsuleParameters( parameters ); + } + + template< class ...Args> + void AddTransport( Args... args ) + { + std::vector<std::string> parameters = { args }; + AddTransportParameters( parameters ); + } + + +private: + + std::vector< std::map<std::string, std::string> > m_CapsuleParameters; ///< each is a separate Transport containing their own parameters + std::vector< std::map<std::string, std::string> > m_TransportParameters; ///< each is a separate Transport containing their own parameters + + void AddCapsuleParameters( const std::vector<std::string>& parameters ); + void AddTransportParameters( const std::vector<std::string>& parameters ); + }; diff --git a/include/core/Transport.h b/include/core/Transport.h index 0637d0ef77e8c7f509325017c4eae6c230b39b05..4a0451c7fda7a3e955d50779bf9811c44a6ed691 100644 --- a/include/core/Transport.h +++ b/include/core/Transport.h @@ -19,7 +19,6 @@ #include "mpidummy.h" #endif -#include "core/Capsule.h" namespace adios diff --git a/include/engine/DataMan.h b/include/engine/DataMan.h deleted file mode 100644 index ec365e04548847cb735e7114aba5dced5a873df6..0000000000000000000000000000000000000000 --- a/include/engine/DataMan.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * DataMan.h - * - * Created on: Dec 16, 2016 - * Author: wfg - */ - -#ifndef DATAMAN_H_ -#define DATAMAN_H_ - -#include "core/Engine.h" - - -namespace adios -{ - -class DataMan : public Engine -{ - - - - -}; - - - - -} - - - -#endif /* DATAMAN_H_ */ diff --git a/include/engine/SIRIUS.h b/include/engine/SIRIUS.h deleted file mode 100644 index e67d6198996114afd61492b614831990f37c62d8..0000000000000000000000000000000000000000 --- a/include/engine/SIRIUS.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * SIRIUS.h - * - * Created on: Dec 16, 2016 - * Author: wfg - */ - -#ifndef SIRIUS_H_ -#define SIRIUS_H_ - - - -namespace adios -{ - - -class SIRIUS : public Engine -{ - - SIRIUS( const std::string name, const std::string accessMode, const MPI_Comm mpiComm, - const Method& method, const bool debugMode ); - - ~SIRIUS( ); - - - - -}; - - -} //namespace - - - -#endif /* SIRIUS_H_ */ diff --git a/include/engine/SingleBP.h b/include/engine/SingleBP.h index 4e3d08e7dc397f101689d98458b61d565ffffe8e..cebbed5e210ea21e5a7d4ae3d1960a53c1bd6109 100644 --- a/include/engine/SingleBP.h +++ b/include/engine/SingleBP.h @@ -28,7 +28,7 @@ public: * @param method * @param debugMode */ - SingleBP( const std::string name, const std::string accessMode, const MPI_Comm mpiComm, + SingleBP( const std::string name, const std::string accessMode, MPI_Comm mpiComm, const Method& method, const bool debugMode = false, const unsigned int cores = 1 ); ~SingleBP( ); diff --git a/include/functions/adiosFunctions.h b/include/functions/adiosFunctions.h index dfdbe661f96dc00a735865a42f26d41f4a9ba9e6..7d0a58ad2ed3f575ee1c328058d0b348b7f7f627 100644 --- a/include/functions/adiosFunctions.h +++ b/include/functions/adiosFunctions.h @@ -141,6 +141,14 @@ void SetTransformsHelper( const std::vector<std::string>& transformNames, std::v bool IsTypeAlias( const std::string type, const std::set<std::string>& types ); +/** + * Transforms a vector + * @param parameters vector of parameters with format "field=value" + * @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 ); + } //end namespace diff --git a/include/functions/engineTemplates.h b/include/functions/engineTemplates.h index bb68b25b0502af3e6029fd9661552f123b17947a..626755a6d1ec1841a5643667b3e92b98a3ce41bb 100644 --- a/include/functions/engineTemplates.h +++ b/include/functions/engineTemplates.h @@ -53,7 +53,7 @@ void WriteToCapsules( const Group& group, Variable<T>& variable, const T* values for( auto& capsule : capsules ) { - capsule->Write( variable, localDimensions, globalDimensions, globalOffsets, transports ); + //capsule->Write( variable, localDimensions, globalDimensions, globalOffsets, transports ); } } diff --git a/include/transport/FStream.h b/include/transport/FStream.h index a99000e3837323298c64c2eafc817b363473679c..feedb3a7b3398a3fa3f97baa62ed63822647ca2a 100644 --- a/include/transport/FStream.h +++ b/include/transport/FStream.h @@ -25,7 +25,7 @@ class FStream : public Transport public: - FStream( MPI_Comm mpiComm, const bool debugMode, const std::vector<std::string>& arguments ); + FStream( MPI_Comm mpiComm, const bool debugMode ); ~FStream( ); @@ -39,14 +39,10 @@ public: void Close( ); -private: - - std::fstream m_Data; ///< file stream under name.bp.dir/name.bp.rank - bool m_HasMetadataFile = false; ///< true if metadata file is defined in arguments as have_metadata_file=1 - std::fstream m_Metadata; ///< file stream under name.bp storing metadata +private: - void Init( const std::vector<std::string>& arguments ); + std::fstream m_FStream; ///< file stream under name.bp.dir/name.bp.rank }; diff --git a/include/transport/File.h b/include/transport/File.h new file mode 100644 index 0000000000000000000000000000000000000000..a9b763828f905cfab0a4f0ce6396a902c81f7d60 --- /dev/null +++ b/include/transport/File.h @@ -0,0 +1,55 @@ +/* + * File.h + * + * Created on: Jan 6, 2017 + * Author: wfg + */ + +#ifndef FILE_H_ +#define FILE_H_ + + +#include <stdio.h> // FILE* + +#include "core/Transport.h" + + +namespace adios +{ + +/** + * Class that defines a transport method using C file pointer to streams FILE* + */ +class File : public Transport +{ + +public: + + File( MPI_Comm mpiComm, const bool debugMode ); + + ~File( ); + + void Open( const std::string name, const std::string accessMode ); + + void SetBuffer( char* buffer, std::size_t size ); + + void Write( const char* buffer, std::size_t size ); + + void Flush( ); + + void Close( ); + + +private: + + FILE* m_File = NULL; ///< C file pointer + +}; + + +} //end namespace + + + + +#endif /* FILE_H_ */ diff --git a/include/transport/MPIFile.h b/include/transport/MPIFile.h index 50e0055c9b6d73fad22b9982b238b498856bf266..89d22765c90408f17f100323a8b5199877246750 100644 --- a/include/transport/MPIFile.h +++ b/include/transport/MPIFile.h @@ -39,7 +39,7 @@ public: private: - MPI_File m_MPIFile; + MPI_File m_MPIFile; ///< MPI File }; diff --git a/include/transport/POSIX.h b/include/transport/POSIX.h index 914307a4cc2b6c1e2a1e761c34bdda7fed3f8a9c..9dea1b463b10d43ca47c19087010433d9b7c5fcd 100644 --- a/include/transport/POSIX.h +++ b/include/transport/POSIX.h @@ -8,10 +8,6 @@ #ifndef POSIX_H_ #define POSIX_H_ -/// \cond EXCLUDE_FROM_DOXYGEN -/// \endcond - -#include <stdio.h> //FILE* #include "core/Transport.h" @@ -25,25 +21,20 @@ class POSIX : public Transport public: - POSIX( MPI_Comm mpiComm, const bool debugMode, const std::vector<std::string>& arguments ); + POSIX( MPI_Comm mpiComm, const bool debugMode ); ~POSIX( ); - void Open( const std::string streamName, const std::string accessMode ); - - void SetBuffer( std::vector<char>& buffer ); + void Open( const std::string name, const std::string accessMode ); - void Write( const Capsule& capsule ); + void Write( const char* buffer, std::size_t size ); - void Close( const Capsule& capsule ); + void Close( ); private: - FILE* m_File; ///< POSIX C file pointer - - void Init( const std::vector<std::string>& arguments ); - + int m_FileDescriptor = -1; ///< POSIX file descriptor }; diff --git a/src/ADIOS.cpp b/src/ADIOS.cpp index d4e8e4eb55f2d6cc45fc47e79b4be2aaadcf299a..b9b8df803532e3c1ce6b218eeb65db3e25108ba0 100644 --- a/src/ADIOS.cpp +++ b/src/ADIOS.cpp @@ -87,33 +87,31 @@ void ADIOS::SetGroup( const unsigned int handler, const std::string groupName ) const unsigned int ADIOS::Open( const std::string name, const std::string accessMode, - MPI_Comm mpiComm, const std::string methodName ) + MPI_Comm mpiComm, const std::string methodName, const unsigned int cores ) { + auto itMethod = m_Methods.find( methodName ); + if( m_DebugMode == true ) { - if( m_EngineNames.count( name ) == 1 ) //Engine exists - throw std::invalid_argument( "ERROR: method " + methodName + " already created by Open, in call from Open.\n" ); + CheckMethod( itMethod, methodName, " from call to Open\n" ); - if( m_Methods.count( methodName ) == 0 ) // - throw std::invalid_argument( "ERROR: method " + methodName + " has not been defined, in call from Open\n" ); + if( m_EngineNames.count( name ) == 1 ) //Check if Engine already exists + throw std::invalid_argument( "ERROR: engine name " + name + " already created by Open, in call from Open.\n" ); } ++m_EngineCounter; - if( methodName.empty() ) //default engine with one transport + if( methodName == "SingleBP" ) { - + m_Engines[ m_EngineCounter ] = std::make_shared<SingleBP>( name, accessMode, mpiComm, itMethod->second, cores ); + } + else if( methodName == "SIRIUS" ) + { + //here must complete } - else //special cases + else if( methodName == "DataMan" ) { -// if( methodName == "SIRIUS" ) -// { -// m_Engines[ m_EngineCounter ] = -// } -// else if( methodName == "DataMan" ) -// { -// m_Engines[ m_EngineCounter ] = ; -// } + //here must complete } return m_EngineCounter; @@ -143,7 +141,7 @@ void ADIOS::DefineVariable( const std::string groupName, const std::string varia } -void ADIOS::SetTransform( const std::string groupName, const std::string variableName, const std::string transform ) +void ADIOS::AddTransform( const std::string groupName, const std::string variableName, const std::string transform ) { auto itGroup = m_Groups.find( groupName ); if( m_DebugMode == true ) //check group and transform @@ -158,7 +156,7 @@ void ADIOS::SetTransform( const std::string groupName, const std::string variabl std::vector<std::string> transformName = { transform }; std::vector<short> transformIndices, parameters; SetTransformsHelper( transformName, m_Transforms, m_DebugMode, transformIndices, parameters ); - itGroup->second.SetTransform( variableName, *m_Transforms[ transformIndices[0] ], parameters[0] ); + itGroup->second.AddTransform( variableName, *m_Transforms[ transformIndices[0] ], parameters[0] ); } @@ -193,6 +191,14 @@ void ADIOS::CheckGroup( std::map< std::string, Group >::const_iterator itGroup, } +void ADIOS::CheckMethod( std::map< std::string, Method >::const_iterator itMethod, + const std::string methodName, const std::string hint ) const +{ + if( itMethod == m_Methods.end() ) + throw std::invalid_argument( "ERROR: method " + methodName + " not found " + hint + "\n" ); +} + + void ADIOS::CheckEngine( std::unordered_map< unsigned int, std::shared_ptr<Engine> >::const_iterator itEngine, const unsigned int handle, const std::string hint ) const { diff --git a/src/ADIOS_C.cpp b/src/ADIOS_C.cpp index 46bfde3cf81e917e21cf8a5bebba4d8e3ddd248b..c1423fd109ff605e4d9724cb6d61017a2a8bc252 100644 --- a/src/ADIOS_C.cpp +++ b/src/ADIOS_C.cpp @@ -5,15 +5,15 @@ * Author: wfg */ -#include "../../include/ADIOS_C.h" + #include <string> #include <fstream> #include <iostream> #include <cstring> -#include "../../include/ADIOS.h" - +#include "ADIOS.h" +#include "ADIOS_C.h" #ifdef __cplusplus extern "C" @@ -118,7 +118,7 @@ void adios_write( const ADIOS* adiosC, const char* groupName, const char* variab try { - adios->Write( std::string( groupName ), std::string( variableName ), values ); + adios->Write( const std::string( groupName ), const std::string( variableName ), values ); } catch( std::bad_alloc& e ) { diff --git a/src/core/Method.cpp b/src/core/Method.cpp new file mode 100644 index 0000000000000000000000000000000000000000..edf5551ba3f603c6f884aa3f88054ea2afcc5dfa --- /dev/null +++ b/src/core/Method.cpp @@ -0,0 +1,41 @@ +/* + * Method.cpp + * + * Created on: Jan 6, 2017 + * Author: wfg + */ + + +#include "core/Method.h" +#include "functions/adiosFunctions.h" + + +namespace adios +{ + + +Method::Method( const std::string type, const bool debugMode ): + m_Type{ type }, + m_DebugMode{ debugMode } +{ } + +Method::~Method( ) +{ } + + +//PRIVATE Functions +void Method::AddCapsuleParameters( const std::vector<std::string>& parameters ) +{ + m_CapsuleParameters.push_back( BuildParametersMap(parameters, m_DebugMode) ); +} + + +void Method::AddTransportParameters( const std::vector<std::string>& parameters ) +{ + m_TransportParameters.push_back( BuildParametersMap(parameters, m_DebugMode) ); +} + + +} //end namespace + + diff --git a/src/engine/SingleBP.cpp b/src/engine/SingleBP.cpp index 0a2ef4b28beb285a35a9f644c423b231dc928dd2..a1e750b7519b38a7c061931c1a9796f1a19e6d8c 100644 --- a/src/engine/SingleBP.cpp +++ b/src/engine/SingleBP.cpp @@ -49,11 +49,16 @@ void SingleBP::InitCapsules( ) { if( m_DebugMode == true ) { - if( m_Method.Capsules.size() != 1 ) + if( m_Method.m_CapsuleParameters.size() > 1 ) + { throw std::invalid_argument( "ERROR: SingleBP engine only allows one heap buffer, from SingleBP constructor in Open.\n" ); + } + else if( m_Method.m_CapsuleParameters.size() == 1 ) + { + if( m_Method.m_CapsuleParameters[0].at("type") != "Heap" ) + throw std::invalid_argument( "ERROR: SingleBP doesn't support Capsule of type " + + ", from SingleBP constructor in Open.\n" ); + } - if( m_Method.Capsules[0] != "Heap" ) - throw std::invalid_argument( "ERROR: SingleBP doesn't support Capsule of type " + m_Method.Capsules[0] + ", from SingleBP constructor in Open.\n" ); } //Create single capsule of type heap m_Capsules.push_back( std::make_shared<Heap>( m_AccessMode, m_RankMPI, m_Cores ) ); @@ -64,21 +69,29 @@ void SingleBP::InitCapsules( ) void SingleBP::InitTransports( ) { std::set< std::string > transportStreamNames; //used to check for name conflict between transports - std::string name = GetName( arguments ); - m_Transports.back()->Open( name, m_AccessMode ); - for( const auto& transportPair : m_Method.Transports ) + + for( const auto& parameters : m_Method.m_TransportParameters ) { - const std::string transport = transportPair.first; - const std::vector<std::string>& arguments = transportPair.second; + const std::string transport = parameters.at("type"); + const std::string name = parameters.at("name"); if( transport == "POSIX" ) { - m_Transports.push_back( std::make_shared<POSIX>( m_MPIComm, m_DebugMode, arguments ) ); + m_Transports.push_back( std::make_shared<POSIX>( m_MPIComm, m_DebugMode ) ); + } + else if( transport == "File" ) + { + m_Transports.push_back( std::make_shared<FStream>( m_MPIComm, m_DebugMode ) ); + } else if( transport == "FStream" ) { - m_Transports.push_back( std::make_shared<FStream>( m_MPIComm, m_DebugMode, arguments ) ); + m_Transports.push_back( std::make_shared<FStream>( m_MPIComm, m_DebugMode ) ); + } + else if( transport == "MPIFile" ) + { + m_Transports.push_back( std::make_shared<FStream>( m_MPIComm, m_DebugMode ) ); } else { @@ -87,6 +100,7 @@ void SingleBP::InitTransports( ) } + m_Transports.back()->Open( name, m_AccessMode ); } } diff --git a/src/functions/adiosFunctions.cpp b/src/functions/adiosFunctions.cpp index 5e7f19ad5847e08ed1fb9673dca7da7b1d5afbb8..05bcb0d6f5055fbada28d7230b08c969c234e6e4 100644 --- a/src/functions/adiosFunctions.cpp +++ b/src/functions/adiosFunctions.cpp @@ -478,4 +478,49 @@ bool IsTypeAlias( const std::string type, const std::set<std::string>& types ) } +std::map<std::string, std::string> BuildParametersMap( const std::vector<std::string>& parameters, + const bool debugMode ) +{ + auto lf_GetFieldValue = []( const std::string parameter, std::string& field, std::string& value, const bool debugMode ) + { + auto equalPosition = parameter.find( "=" ); + + if( debugMode == true ) + { + if( equalPosition == parameter.npos ) + throw std::invalid_argument( "ERROR: wrong format for parameter " + parameter + ", format must be field=value \n" ); + + if( equalPosition == parameter.size()-1 ) + throw std::invalid_argument( "ERROR: empty value in parameter " + parameter + ", format must be field=value \n" ); + } + + field = parameter.substr( 0, equalPosition ); + value = parameter.substr( equalPosition+1 ); //need to test + }; + + //BODY OF FUNCTION STARTS HERE + std::map<std::string, std::string> parametersOutput; + + for( const auto parameter : parameters ) + { + std::string field, value; + lf_GetFieldValue( parameter, field, value, debugMode ); + + if( debugMode == true ) + { + if( parametersOutput.count( field ) == 1 ) + throw std::invalid_argument( "ERROR: parameter " + field + " already exists, must be unique\n" ); + } + + parametersOutput[field] = value; + } + + return parametersOutput; +} + + + + + + } //end namespace diff --git a/src/transport/FStream.cpp b/src/transport/FStream.cpp index 67e577013d02af560e2976b77081ccbcc29329d4..08dde2e02312b1c1878295de343c8b5a693c78fb 100644 --- a/src/transport/FStream.cpp +++ b/src/transport/FStream.cpp @@ -6,14 +6,9 @@ */ /// \cond EXCLUDED_FROM_DOXYGEN -#include <iostream> -#include <sstream> -#include <cmath> #include <stdexcept> -#include <cstring> /// \endcond -#include "functions/adiosFunctions.h" //CreateDirectory #include "transport/FStream.h" @@ -21,7 +16,7 @@ namespace adios { -FStream::FStream( MPI_Comm mpiComm, const bool debugMode, const std::vector<std::string>& arguments ): +FStream::FStream( MPI_Comm mpiComm, const bool debugMode ): Transport( "FStream", mpiComm, debugMode ) { Init( arguments ); @@ -35,108 +30,56 @@ FStream::~FStream( ) void FStream::Open( const std::string name, const std::string accessMode ) { m_Name = name; - if( name.compare( name.size()-3, 3, ".bp" ) == 0 ) //check if .bp extension already exists - m_Name = name.substr( 0, name.size()-3 ); - m_AccessMode = accessMode; - const std::string directory( m_Name + ".bp.dir" ); //data.bp.dir - - if( m_MPIRank == 0 ) - CreateDirectory( directory ); - - MPI_Barrier( m_MPIComm ); //all processor wait until directory is created - - const std::string rankFile( directory + "/" + m_Name + ".bp." + std::to_string( m_MPIRank ) ); //data.bp.dir./data.bp.Rank - if( accessMode == "w" || accessMode == "write" ) - m_Data.open( rankFile, std::fstream::out ); + m_FStream.open( name, std::fstream::out ); else if( accessMode == "a" || accessMode == "append" ) - m_Data.open( rankFile, std::fstream::out | std::fstream::app ); + m_FStream.open( name, std::fstream::out | std::fstream::app ); else if( accessMode == "r" || accessMode == "read" ) - m_Data.open( rankFile, std::fstream::in ); - + m_FStream.open( name, std::fstream::in ); if( m_DebugMode == true ) { - if( !m_Data ) - throw std::ios_base::failure( "ERROR: couldn't open file " + rankFile + ", in call to Open from FStream transport\n" ); - } - - - if( m_HasMetadataFile == true ) - { - const std::string metadataFile( m_Name + ".bp" ); - if( accessMode == "w" || accessMode == "write" ) - m_Metadata.open( metadataFile, std::fstream::out ); - - else if( accessMode == "a" || accessMode == "append" ) - m_Metadata.open( metadataFile, std::fstream::out | std::fstream::app ); - - else if( accessMode == "r" || accessMode == "read" ) - m_Metadata.open( metadataFile, std::fstream::in ); - - if( !m_Metadata ) - throw std::ios_base::failure( "ERROR: couldn't open file " + metadataFile + ", in call to Open from FStream transport\n" ); + if( !m_FStream ) + throw std::ios_base::failure( "ERROR: couldn't open file " + name + ", in call to Open from FStream transport\n" ); } } void FStream::SetBuffer( char* buffer, std::size_t size ) { - m_Data.rdbuf()->pubsetbuf( buffer, size ); + m_FStream.rdbuf()->pubsetbuf( buffer, size ); } void FStream::Write( const char* buffer, std::size_t size ) { - m_Data.write( buffer, size ); -} + m_FStream.write( buffer, size ); - -void FStream::WriteMetadata( const char* buffer, std::size_t size ) -{ - m_Metadata.write( buffer, size ); + if( m_DebugMode == true ) + { + if( !m_FStream ) + throw std::ios_base::failure( "ERROR: couldn't write to file " + m_Name + + ", in call to FStream write\n" ); + } } void FStream::Flush( ) { - m_Data.flush( ); + m_FStream.flush( ); } void FStream::Close( ) { - m_Data.close(); - - if( m_Metadata ) - m_Metadata.close( ); + m_FStream.close(); } -void FStream::Init( const std::vector<std::string>& arguments ) -{ - for( const auto argument : arguments ) - { - if( argument.compare( 0, 19, "have_metadata_file=" ) == 0 ) - { - int haveMetadata = std::stoi( argument.substr(19) ); - - if( haveMetadata == 0 ) - m_HasMetadataFile = false; - else if( haveMetadata == 1 ) - m_HasMetadataFile = true; - else - throw std::invalid_argument( "ERROR: have_metadata_file= value must be 0 (off) or 1 (on), in FStream transport constructor\n" ); - } - } -} - - - //void CFStream::Write( const CVariable& variable ) ///this is aggregation //{ // //local buffer, to be send over MPI diff --git a/src/transport/File.cpp b/src/transport/File.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d259e124907af65f56bdceb59b2da69138a3cb88 --- /dev/null +++ b/src/transport/File.cpp @@ -0,0 +1,89 @@ +/* + * File.cpp + * + * Created on: Jan 6, 2017 + * Author: wfg + */ + +#include "transport/File.h" + + +namespace adios +{ + + +File::File( MPI_Comm mpiComm, const bool debugMode ): + Transport( "File", mpiComm, debugMode ) +{ } + + +File::~File( ) +{ + if( m_File != NULL ) + fclose( m_File ); +} + + +void File::Open( const std::string name, const std::string accessMode ) +{ + m_Name = name; + m_AccessMode = accessMode; + + if( accessMode == "w" || accessMode == "write" ) + m_File = fopen( name.c_str(), "w" ); + + else if( accessMode == "a" || accessMode == "append" ) + m_File = fopen( name.c_str(), "a" ); + + else if( accessMode == "r" || accessMode == "read" ) + m_File = fopen( name.c_str(), "r" ); + + if( m_DebugMode == true ) + { + if( m_File == NULL ) + throw std::ios_base::failure( "ERROR: couldn't open file " + name + ", " + "in call to Open from File transport\n" ); + } +} + + +void File::SetBuffer( char* buffer, std::size_t size ) +{ + int status = setvbuf( m_File, buffer, _IOFBF, size ); + + if( m_DebugMode == true ) + { + if( status == 1 ) + throw std::ios_base::failure( "ERROR: could not set buffer in rank " + + std::to_string( m_MPIRank ) + "\n" ); + } +} + + +void File::Write( const char* buffer, std::size_t size ) +{ + fwrite( buffer, sizeof(char), size, m_File ); + + if( m_DebugMode == true ) + { + if( ferror( m_File ) ) + throw std::ios_base::failure( "ERROR: couldn't write to file " + m_Name + + ", in call to File write\n" ); + } +} + + +void File::Flush( ) +{ + fflush( m_File ); +} + + +void File::Close( ) +{ + fclose( m_File ); +} + + + +} //end namespace diff --git a/src/transport/POSIX.cpp b/src/transport/POSIX.cpp index ddee445b54f052c2e8416aa943580208e2b57ce8..2bea6189c548ff8859c808b4dfe5e3390716ed1e 100644 --- a/src/transport/POSIX.cpp +++ b/src/transport/POSIX.cpp @@ -6,19 +6,19 @@ */ -#include <stdio.h> //fopen +#include <fcntl.h> +#include <sys/types.h> +#include <sys/stat.h> #include "transport/POSIX.h" -#include "functions/adiosFunctions.h" // CreateDirectory namespace adios { -POSIX::POSIX( MPI_Comm mpiComm, const bool debugMode, const std::vector<std::string>& arguments ): - Transport( "POSIX", mpiComm, debugMode ), - m_File( NULL ) +POSIX::POSIX( MPI_Comm mpiComm, const bool debugMode ): + Transport( "POSIX", mpiComm, debugMode ) { } @@ -26,66 +26,55 @@ POSIX::~POSIX( ) { } -void POSIX::Open( const std::string streamName, const std::string accessMode ) +void POSIX::Open( const std::string name, const std::string accessMode ) { - const std::string directory( streamName + ".dir" ); - - //data.bp.dir - if( m_MPIRank == 0 ) - CreateDirectory( directory ); - - MPI_Barrier( m_MPIComm ); //all processors must wait until directory is created - - const std::string streamNameRank( directory + "/" + streamName + "." + std::to_string( m_MPIRank ) ); + m_Name = name; + m_AccessMode = accessMode; if( accessMode == "w" || accessMode == "write" ) - m_File = fopen( streamNameRank.c_str(), "w" ); + m_FileDescriptor = open( m_Name.c_str(), O_WRONLY | O_CREAT, 0666 ); else if( accessMode == "a" || accessMode == "append" ) - m_File = fopen( streamNameRank.c_str(), "a" ); + m_FileDescriptor = open( m_Name.c_str(), O_WRONLY | O_APPEND ); else if( accessMode == "r" || accessMode == "read" ) - m_File = fopen( streamNameRank.c_str(), "r" ); + m_FileDescriptor = open( m_Name.c_str(), O_RDONLY ); if( m_DebugMode == true ) { - if( m_File == NULL ) - throw std::ios_base::failure( "ERROR: couldn't open file " + streamName + ", from call to Open in POSIX transport\n" ); + if( m_FileDescriptor == -1 ) + throw std::ios_base::failure( "ERROR: couldn't open file " + m_Name + + ", from call to Open in POSIX transport\n" ); } - - MPI_Barrier( m_MPIComm ); //all of them must wait until the file is opened } -void POSIX::SetBuffer( std::vector<char>& buffer ) +void POSIX::Write( const char* buffer, std::size_t size ) { - int status = setvbuf( m_File, &buffer[0], _IOFBF, buffer.size() ); + int status = write( m_FileDescriptor, buffer, size ); if( m_DebugMode == true ) { - if( status == 1 ) - throw std::ios_base::failure( "ERROR: could not set buffer in rank " + std::to_string( m_MPIRank ) + "\n" ); + if( status == -1 ) + throw std::ios_base::failure( "ERROR: couldn't write to file " + m_Name + + ", in call to POSIX write\n" ); } } -void POSIX::Write( const Capsule& capsule ) +void POSIX::Close( ) { - //fwrite( &buffer[0], sizeof(char), buffer.size(), m_File ); -} - + int status = close( m_FileDescriptor ); -void POSIX::Close( const Capsule& capsule ) -{ - //fclose( m_File ); + if( m_DebugMode == true ) + { + if( status == -1 ) + throw std::ios_base::failure( "ERROR: couldn't close file " + m_Name + + ", in call to POSIX write\n" ); + } } -//PRIVATE FUNCTIONS -void POSIX::Init( const std::vector<std::string>& arguments ) -{ - -}