From 6db92942d3ca12cad0b083dd0ed4a0a528841e6d Mon Sep 17 00:00:00 2001 From: wfg <wfg@pc0098504.ornl.gov> Date: Fri, 28 Oct 2016 17:13:19 -0400 Subject: [PATCH] Added more template functions to functions/GroupFunctions Decongest CGroup for Variable creation and value setting Partial testing and debug of XML read implementation to allow "< >" in names. Required to allow STL containers as types (e.g. "vector<double>"). Back to std::shared_ptr in CGroup members. std::make_pair calls the copy constructor by default. Will keep track of std::shared_ptr counts. Added more checks for debug version to guarantee exceptions. To do: Add and test more types. Add Capsule class and support. --- examples/hello/fstream.xml | 4 +- examples/hello/helloFStream.cpp | 13 ++- include/core/CGroup.h | 21 ++-- include/core/CTransport.h | 17 ++- include/functions/ADIOSFunctions.h | 3 +- include/functions/GroupFunctions.h | 21 +++- include/transport/CFStream.h | 10 +- include/transport/CPOSIX.h | 4 +- src/core/CGroup.cpp | 63 +++++------ src/functions/ADIOSFunctions.cpp | 164 +++++++++++++++++++---------- src/functions/GroupFunctions.cpp | 30 ++++-- src/public/ADIOS.cpp | 4 +- src/transport/CFStream.cpp | 57 ++++++---- src/transport/CPOSIX.cpp | 14 +-- 14 files changed, 255 insertions(+), 170 deletions(-) diff --git a/examples/hello/fstream.xml b/examples/hello/fstream.xml index 405eb95d4..937edb602 100644 --- a/examples/hello/fstream.xml +++ b/examples/hello/fstream.xml @@ -1,12 +1,12 @@ <?xml version="1.0"?> <adios-config host-language="C++"> <adios-group name="Types"> - <var name="Numbers" type="Vinteger"/> + <var name="Numbers" type="std::vector<int>"/> <attribute name="description" value="1 to 10"/> </adios-group> - <transport group="Vector" method="FStream">verbose=3</transport> + <transport group="Types" method="FStream">verbose=3</transport> <!-- <buffer size-MB="40" allocate-time="now"/> --> diff --git a/examples/hello/helloFStream.cpp b/examples/hello/helloFStream.cpp index d9bcc449e..0903c1998 100644 --- a/examples/hello/helloFStream.cpp +++ b/examples/hello/helloFStream.cpp @@ -6,8 +6,6 @@ */ - - #include <stdexcept> #include <iostream> #include <fstream> @@ -19,15 +17,15 @@ int main( int argc, char* argv [] ) { - try + try //need to think carefully how to handle C++ exceptions with MPI to avoid deadlocking { - const std::string group("Types"); - const std::string numbersVariable("Numbers"); + const std::string group( "Types" ); + const std::string numbersVariable( "Numbers" ); std::vector<int> myVector( 10 ); std::iota( myVector.begin(), myVector.end(), 1 ); - //testing with CPOSIXMPI + //testing with CFStream transport adios::ADIOS adios( "fstream.xml", true ); adios.MonitorGroups( std::cout ); //Get Monitor info adios.Write( group, numbersVariable, &myVector ); //Write @@ -43,8 +41,9 @@ int main( int argc, char* argv [] ) std::cout << "Invalid argument exception, STOPPING PROGRAM\n"; std::cout << e.what() << "\n"; } - catch( std::exception& e ) //need to think carefully how to handle C++ exceptions with MPI to avoid deadlocking + catch( std::exception& e ) { + std::cout << "Exception, STOPPING PROGRAM\n"; std::cout << e.what() << "\n"; } diff --git a/include/core/CGroup.h b/include/core/CGroup.h index 7d91f590a..926506efd 100644 --- a/include/core/CGroup.h +++ b/include/core/CGroup.h @@ -42,11 +42,11 @@ public: /** * @brief Constructor for XML config file * @param hostLanguage reference from ADIOS class - * @param xmlGroup contains <adios-group....</adios-group> single group definition from XML config file + * @param xmlGroup contains <adios-group (tag excluded)....</adios-group> single group definition from XML config file * @param groupName returns the groupName from <adios-group name=" " - * @param debugMode + * @param debugMode from ADIOS */ - CGroup( const std::string& hostLanguage, const std::string& xmlGroup, std::string& groupName, const bool debugMode = false ); + CGroup( const std::string& hostLanguage, const std::string& xmlGroup, const bool debugMode = false ); /** * Non-XML empty constructor @@ -128,7 +128,10 @@ public: private: - const std::string& m_HostLanguage; ///< reference to class ADIOS m_HostLanguage, this erases the copy constructor + const std::string& m_HostLanguage; ///< reference to class ADIOS m_HostLanguage, this erases the copy constructor. Might be moved later to non-reference const + const bool m_DebugMode = false; ///< if true will do more checks, exceptions, warnings, expect slower code + + bool m_IsOpen = false; ///< checks if group was opened for operations; /** * @brief Contains all group variables (from XML Config file). * <pre> @@ -136,7 +139,7 @@ private: * Value: Polymorphic value is always unique child defined in SVariableTemplate.h, allow different variable types * </pre> */ - std::map< std::string, std::unique_ptr<CVariableBase> > m_Variables; + std::map< std::string, std::shared_ptr<CVariableBase> > m_Variables; /** * @brief Contains all group attributes from SAttribute.h @@ -150,21 +153,17 @@ private: std::vector<std::string> m_GlobalDimensions; ///< from global-bounds in XML File, data in global space std::vector<std::string> m_GlobalOffsets; ///< from global-bounds in XML File, data in global space - std::unique_ptr<CTransport> m_Transport; ///< transport method defined in XML File, using unique_ptr as copy constructor is removed + std::shared_ptr<CTransport> m_Transport; ///< transport method defined in XML File, using shared_ptr as CGroup is put in a map copy constructor deleted std::string m_ActiveTransport; - bool m_DebugMode = false; ///< if true will do more checks, exceptions, warnings, expect slower code - bool m_IsOpen = false; ///< checks if group was opened for operations; std::string m_FileName; ///< associated fileName is the Group is opened. std::string m_AcessMode; ///< file access mode "r"->read, "w"->write, "a"->append /** * Called from XML constructor - * @param hostLanguage from ADIOS class, used to determine allowed variable types (Fortran -> real, C++-> std::vector ) * @param xmlGroup contains <adios-group....</adios-group> single group definition from XML config file passing by reference as it could be big - * @param groupName returns the groupName from <adios-group name=" " */ - void ParseXMLGroup( const std::string& xmlGroup, std::string& groupName ); + void ParseXMLGroup( const std::string& xmlGroup ); /** * Function that checks if transport method is valid, called from overloaded SetTransform functions diff --git a/include/core/CTransport.h b/include/core/CTransport.h index f95ba1250..012f210ad 100644 --- a/include/core/CTransport.h +++ b/include/core/CTransport.h @@ -19,9 +19,6 @@ #endif -#include "core/CVariableBase.h" - - namespace adios { @@ -36,7 +33,6 @@ public: MPI_Comm m_MPIComm; std::string m_FileName; ///< file name associated with a group that owns the transport - std::string m_AccessMode; ///< read, write, append CTransport( const std::string method, const unsigned int priority, const unsigned int iteration, MPI_Comm mpiComm ): @@ -50,13 +46,14 @@ public: { } - void Open( const std::string fileName, const std::string accessMode = "w" ) - { - m_FileName = fileName; - m_AccessMode = accessMode; - } + /** + * Open Output file accesing a mode + * @param fileName name of file + * @param accessMode r or read, w or write, a or append + */ + virtual void Open( const std::string fileName, const std::string accessMode ) = 0; - virtual void Write( const CVariableBase& variable ) = 0; + virtual void Close( ) = 0; //here think what needs to be passed }; diff --git a/include/functions/ADIOSFunctions.h b/include/functions/ADIOSFunctions.h index 628ba6da8..85e9b1f12 100644 --- a/include/functions/ADIOSFunctions.h +++ b/include/functions/ADIOSFunctions.h @@ -88,11 +88,12 @@ void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm, std::st * Called inside the ADIOS XML constructors to get contents from file, broadcast and set hostLanguage and groups from ADIOS class * @param xmlConfigFile xml config file name * @param mpiComm communicator used from broadcasting + * @param debugMode from ADIOS m_DebugMode passed to CGroup in groups * @param hostLanguage set from host-language in xml file * @param groups passed returns the map of groups defined in fileContent * @param debugMode if true will do more checks, exceptions, warnings, expect slower code */ -void InitXML( const std::string xmlConfigFile, const MPI_Comm mpiComm, std::string& hostLanguage, +void InitXML( const std::string xmlConfigFile, const MPI_Comm mpiComm, const bool debugMode, std::string& hostLanguage, std::map< std::string, CGroup >& groups ); } //end namespace diff --git a/include/functions/GroupFunctions.h b/include/functions/GroupFunctions.h index f70c6b425..d3258044d 100644 --- a/include/functions/GroupFunctions.h +++ b/include/functions/GroupFunctions.h @@ -21,6 +21,7 @@ #endif #include "core/CVariableBase.h" +#include "core/CTransport.h" namespace adios { @@ -37,7 +38,7 @@ namespace adios */ void CreateVariableLanguage( const std::string hostLanguage, const std::string name, const bool isGlobal, const std::string type, const std::string dimensionsCSV, const std::string transform, - std::map<std::string, std::unique_ptr<CVariableBase> >& variables ) noexcept; + std::map<std::string, std::shared_ptr<CVariableBase> >& variables ) noexcept; /** * Create a C++ supported variable, including STL vector types @@ -50,7 +51,7 @@ void CreateVariableLanguage( const std::string hostLanguage, const std::string n */ void CreateVariableCpp( const std::string name, const bool isGlobal, const std::string type, const std::string dimensionsCSV, const std::string transform, - std::map< std::string, std::unique_ptr<CVariableBase> >& variables ) noexcept; + std::map< std::string, std::shared_ptr<CVariableBase> >& variables ) noexcept; /** * Create a C supported variable, including STL vector types @@ -63,7 +64,7 @@ void CreateVariableCpp( const std::string name, const bool isGlobal, */ void CreateVariableC( const std::string name, const bool isGlobal, const std::string type, const std::string dimensionsCSV, const std::string transform, - std::map< std::string, std::unique_ptr<CVariableBase> >& variables ) noexcept; + std::map< std::string, std::shared_ptr<CVariableBase> >& variables ) noexcept; /** * Create a Fortran supported variable, including STL vector types @@ -76,7 +77,17 @@ void CreateVariableC( const std::string name, const bool isGlobal, */ void CreateVariableFortran( const std::string name, const bool isGlobal, const std::string type, const std::string dimensionsCSV, const std::string transform, - std::map< std::string, std::unique_ptr<CVariableBase> >& variables ) noexcept; + std::map< std::string, std::shared_ptr<CVariableBase> >& variables ) noexcept; + + +/** + * Looks up the variable type and cast the appropriate values type to m_Value in CVariable + * Maybe it produces exceptions? Must double-check + * @param variables always a derived CVariable object from CVariableBase + * @param values to be casted to the right type + */ +void SetVariableValues( CVariableBase& variable, const void* values ) noexcept; + /** @@ -88,7 +99,7 @@ void CreateVariableFortran( const std::string name, const bool isGlobal, * @param transport passed from CGroup m_Transport member */ void CreateTransport( const std::string method, const unsigned int priority, const unsigned int iteration, - const MPI_Comm mpiComm, std::unique_ptr<CTransport>& transport ) noexcept; + const MPI_Comm mpiComm, std::shared_ptr<CTransport>& transport ) noexcept; diff --git a/include/transport/CFStream.h b/include/transport/CFStream.h index c62212d70..ab8e72b8c 100644 --- a/include/transport/CFStream.h +++ b/include/transport/CFStream.h @@ -8,6 +8,7 @@ #ifndef CFSTREAM_H_ #define CFSTREAM_H_ +#include <fstream> #include "core/CTransport.h" @@ -27,7 +28,14 @@ public: ~CFStream( ); - void Write( const CVariableBase& variable ); + void Open( const std::string fileName, const std::string accessMode ); + + void Close( ); + +private: + + std::fstream m_FStream; ///< file stream corresponding to this transport + }; diff --git a/include/transport/CPOSIX.h b/include/transport/CPOSIX.h index ab2c48f98..125413137 100644 --- a/include/transport/CPOSIX.h +++ b/include/transport/CPOSIX.h @@ -25,7 +25,9 @@ public: ~CPOSIX( ); - void Write( const CVariableBase& variable ); + void Open( const std::string fileName, const std::string accessMode ); + + void Close( ); }; diff --git a/src/core/CGroup.cpp b/src/core/CGroup.cpp index 84a510cf9..58d8af5a3 100644 --- a/src/core/CGroup.cpp +++ b/src/core/CGroup.cpp @@ -12,7 +12,8 @@ #include "core/CGroup.h" #include "functions/GroupFunctions.h" //for CreateVariableLanguage #include "public/SSupport.h" -#include "functions/ADIOSFunctions.h" //for XML Parsing GetTag +#include "functions/ADIOSFunctions.h" //for XML Parsing functions (e.g. GetTag) +#include "core/CVariable.h" //for cast implementation of CVariableBase::Set that calls CVariable::Set namespace adios @@ -25,11 +26,11 @@ CGroup::CGroup( const std::string& hostLanguage, const bool debugMode ): { } -CGroup::CGroup( const std::string& hostLanguage, const std::string& xmlGroup, std::string& groupName, const bool debugMode ): +CGroup::CGroup( const std::string& hostLanguage, const std::string& xmlGroup, const bool debugMode ): m_HostLanguage{ hostLanguage }, m_DebugMode{ debugMode } { - ParseXMLGroup( xmlGroup, groupName ); + ParseXMLGroup( xmlGroup ); } @@ -49,6 +50,9 @@ void CGroup::SetVariable( const std::string name, const bool isGlobal, const std { if( m_DebugMode == true ) { + if( SSupport::Datatypes.at( m_HostLanguage ).count( type ) == 0 ) + throw std::invalid_argument( "ERROR: type " + type + " for variable " + name + " is not supported.\n" ); + if( m_Variables.count( name ) == 0 ) //variable doesn't exists CreateVariableLanguage( m_HostLanguage, name, isGlobal, type, dimensionsCSV, transform, m_Variables ); else //name is found @@ -110,7 +114,7 @@ void CGroup::SetTransport( const std::string method, const unsigned int priority throw std::invalid_argument( "ERROR: transport method " + method + " not supported. Check spelling or case sensitivity.\n" ); } - if( m_ActiveTransport.empty() == false ) //there is an existing transport method + if( m_ActiveTransport.empty() == false ) //there is an existing transport method, so reset m_Transport.reset(); CreateTransport( method, priority, iteration, mpiComm, m_Transport ); @@ -127,27 +131,16 @@ void CGroup::Write( const std::string variableName, const void* values ) if( itVariable == m_Variables.end() ) throw std::invalid_argument( "ERROR: variable " + variableName + " is undefined.\n" ); } - // must move this to GroupFunctions.h - - const std::string type = itVariable->second->m_Type; - auto& variable = itVariable->second; - - //Set variable values - if( type == "double" ) variable->Set<double>( values ); - else if( type == "integer" ) variable->Set<int>( values ); - else if( type == "std::vector<int>" || type == "vector<int>" ) variable->Set<std::vector<int>>( values ); -// else if( type == "unsigned integer" ) variable->Set<unsigned int>( values ); -// else if( type == "float" ) variable->Set<float>( values ); - - std::cout << "Hello from " << type << " variable " << variableName << "\n"; - m_Transport->Write( *variable ); //Using shared_ptr for Variable, must dereference + SetVariableValues( *itVariable->second, values ); //will check type and cast to appropriate template<type> + //here must do something with Capsule } void CGroup::Close( ) { //here must think what to do with Capsule and close Transport + m_Transport->Close( ); } //PRIVATE FUNCTIONS BELOW @@ -172,33 +165,31 @@ void CGroup::Monitor( std::ostream& logStream ) const } -void CGroup::ParseXMLGroup( const std::string& xmlGroup, std::string& groupName ) +void CGroup::ParseXMLGroup( const std::string& xmlGroup ) { - //get name - std::string tag; std::string::size_type currentPosition( 0 ); - GetSubString( "<adios-group ", ">", xmlGroup, tag, currentPosition ); - tag = tag.substr( 1, tag.size() - 2 ); //eliminate < > - - std::vector< std::pair<const std::string, const std::string> > pairs; - GetPairsFromTag( xmlGroup, tag, pairs ); - - for( auto& pair : pairs ) - { - if( pair.first == "name") groupName = pair.second; - } - bool isGlobal = false; while( currentPosition != std::string::npos ) { + //Get tag + std::string tag; GetSubString( "<", ">", xmlGroup, tag, currentPosition ); if( tag == "</adios-group>" ) break; if( tag == "</global-bounds>" ) isGlobal = false; - tag = tag.substr( 1, tag.size() - 2 ); //eliminate < > needs an exception? + if( m_DebugMode == true ) + { + if( tag.size() < 2 ) + throw std::invalid_argument( "ERROR: wrong tag " + tag + " when reading group \n" ); //check < or <=) + } + tag = tag.substr( 1, tag.size() - 2 ); //eliminate < > + + //Get pairs from tag + std::vector< std::pair<const std::string, const std::string> > pairs; GetPairsFromTag( xmlGroup, tag, pairs ); + //Check based on tagName const std::string tagName( tag.substr( 0, tag.find_first_of(" \t\n\r") ) ); if( tagName == "var" ) //assign a Group variable @@ -241,10 +232,4 @@ void CGroup::ParseXMLGroup( const std::string& xmlGroup, std::string& groupName } -void CGroup::CheckTransport( const std::string method ) -{ - -} - - } //end namespace diff --git a/src/functions/ADIOSFunctions.cpp b/src/functions/ADIOSFunctions.cpp index 06c03d68f..024ca5d87 100644 --- a/src/functions/ADIOSFunctions.cpp +++ b/src/functions/ADIOSFunctions.cpp @@ -42,13 +42,22 @@ void DumpFileToStream( const std::string fileName, std::string& fileContent ) void GetSubString( const std::string initialTag, const std::string finalTag, const std::string content, std::string& subString, std::string::size_type& currentPosition ) { - auto lf_Wipe =[]( std::string& subString, std::string::size_type& currentPosition ) + auto lf_Wipe = []( std::string& subString, std::string::size_type& currentPosition ) { subString.clear(); currentPosition = std::string::npos; }; - std::string::size_type start( content.find(initialTag, currentPosition ) ); + auto lf_SetPositions = []( const char quote, const std::string::size_type quotePosition, const std::string& content, + std::string::size_type& currentPosition, std::string::size_type& closingQuotePosition ) + { + currentPosition = quotePosition; + closingQuotePosition = content.find( quote, currentPosition+1 ); + }; + + + //BODY OF FUNCTION STARTS HERE + std::string::size_type start( content.find( initialTag, currentPosition ) ); if( start == content.npos ) { lf_Wipe( subString, currentPosition ); @@ -68,38 +77,40 @@ void GetSubString( const std::string initialTag, const std::string finalTag, con while( isValue == true ) { - std::string::size_type quotePosition = content.find( '\'', currentPosition ); + std::string::size_type singleQuotePosition = content.find( '\'', currentPosition ); std::string::size_type doubleQuotePosition = content.find( '\"', currentPosition ); - if( ( quotePosition == content.npos && doubleQuotePosition == content.npos ) || - ( quotePosition == content.npos && end < doubleQuotePosition ) || - ( doubleQuotePosition == content.npos && end < quotePosition ) || - ( end < quotePosition && end < doubleQuotePosition ) + if( ( singleQuotePosition == content.npos && doubleQuotePosition == content.npos ) || + ( singleQuotePosition == content.npos && end < doubleQuotePosition ) || + ( doubleQuotePosition == content.npos && end < singleQuotePosition ) || + ( end < singleQuotePosition && end < doubleQuotePosition ) ) break; - //first case - std::string::size_type closingPosition; - if( quotePosition < doubleQuotePosition ) //find the closing " - { - currentPosition = quotePosition; - closingPosition = content.find( '\'', currentPosition+1 ); - } - else //find the closing ' + //find the closing corresponding quote + std::string::size_type closingQuotePosition; + + if( singleQuotePosition == content.npos ) //no ' anywhere + lf_SetPositions( '\"', doubleQuotePosition, content, currentPosition, closingQuotePosition ); + else if( doubleQuotePosition == content.npos ) //no " anywhere + lf_SetPositions( '\'', singleQuotePosition, content, currentPosition, closingQuotePosition ); + else { - currentPosition = doubleQuotePosition; - closingPosition = content.find( '\"', currentPosition+1 ); + if( singleQuotePosition < doubleQuotePosition ) + lf_SetPositions( '\'', singleQuotePosition, content, currentPosition, closingQuotePosition ); + else //find the closing " + lf_SetPositions( '\"', doubleQuotePosition, content, currentPosition, closingQuotePosition ); } - if( closingPosition == content.npos ) //if can't find closing it's open until the end + if( closingQuotePosition == content.npos ) //if can't find closing it's open until the end { lf_Wipe( subString, currentPosition ); return; } - if( closingPosition < end ) - { - currentPosition = closingPosition+1; + + currentPosition = closingQuotePosition+1; + + if( closingQuotePosition < end ) continue; - } //if this point is reached it means it's a value inside " " or ' ', move to the next end end = content.find( finalTag, currentPosition ); @@ -157,9 +168,8 @@ void GetPairsFromTag( const std::string& fileContent, const std::string tag, { } else // opening tag { - //check for closing tagName const std::string tagName( tag.substr( 0, tag.find_first_of(" \t\n\r") ) ); - const std::string closingTagName( "</" + tagName + ">" ); + const std::string closingTagName( "</" + tagName + ">" ); //check for closing tagName if( fileContent.find( closingTagName ) == fileContent.npos ) throw std::invalid_argument( "ERROR: closing tag " + closingTagName + " missing, check XML file\n"); @@ -168,7 +178,8 @@ void GetPairsFromTag( const std::string& fileContent, const std::string tag, } } -void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm, + +void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm, const bool debugMode, std::string& hostLanguage, std::map< std::string, CGroup >& groups ) { //adios-config @@ -186,44 +197,92 @@ void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm, startComment = currentContent.find( "<!--" ); } - std::string tag; //use for < > tags - std::vector< std::pair<const std::string, const std::string> > pairs; // pairs in tag - //Tag <adios-config currentPosition = 0; - GetSubString( "<", ">", currentContent, tag, currentPosition ); + + std::string tag; //use for < > tags + GetSubString( "<adios-config", ">", currentContent, tag, currentPosition ); tag = tag.substr( 1, tag.size() - 2 ); //eliminate < > + + std::vector< std::pair<const std::string, const std::string> > pairs; // pairs in tag GetPairsFromTag( currentContent, tag, pairs ); for( auto& pair : pairs ) + if( pair.first == "host-language" ) + hostLanguage = pair.second; + + if( debugMode == true ) { - if( pair.first == "host-language" ) hostLanguage = pair.second; - } + if( SSupport::HostLanguages.count( hostLanguage ) == 0 ) + throw std::invalid_argument("ERROR: host language " + hostLanguage + " not supported.\n" ); - if( SSupport::HostLanguages.count( hostLanguage ) == 0 ) - throw std::invalid_argument("ERROR: host language " + hostLanguage + " not supported.\n" ); + if( hostLanguage.empty() == true ) + throw std::invalid_argument("ERROR: host language is empty.\n" ); + } //adios-group - std::string xmlGroup; + currentPosition = 0; + while( currentPosition != std::string::npos ) { - GetSubString("<adios-group ", "</adios-group>", currentContent, xmlGroup, currentPosition ); - if( xmlGroup.empty() ) break; + std::string xmlGroup; + GetSubString("<adios-group ", "</adios-group>", currentContent, xmlGroup, currentPosition ); //Get all group contents + if( xmlGroup.empty() ) //no more groups to find + break; + //get group name + std::string::size_type groupPosition( 0 ); + GetSubString( "<adios-group ", ">", xmlGroup, tag, groupPosition ); + if( debugMode == true ) + { + if( tag.size() < 2 ) + throw std::invalid_argument( "ERROR: wrong tag " + tag + " in adios-group\n" ); //check < or <= + } + + tag = tag.substr( 1, tag.size() - 2 ); //eliminate < > + GetPairsFromTag( xmlGroup, tag, pairs ); std::string groupName; - CGroup group( hostLanguage, xmlGroup, groupName ); //need to change formulation to be able to emplace - if( groups.count( groupName ) == 1 ) //group exists - throw std::invalid_argument("ERROR: group " + groupName + " defined twice.\n" ); + for( auto& pair : pairs ) + { + if( pair.first == "name") + groupName = pair.second; + } + + if( debugMode == true ) + { + if( groupName.empty() ) + throw std::invalid_argument( "ERROR: group name not found. \n" ); + + if( groups.count( groupName ) == 1 ) //group exists + throw std::invalid_argument( "ERROR: group " + groupName + " defined twice.\n" ); + } - groups.insert( std::make_pair( groupName, std::move( group ) ) ); //move rvalue as it has const members + groups.emplace( groupName, CGroup( hostLanguage, xmlGroup, debugMode ) ); currentContent.erase( currentContent.find( xmlGroup ), xmlGroup.size() ); currentPosition = 0; } //transport + //lambda function to check priority and iteration casting to unsigned int + auto lf_UIntCheck = []( const std::string method, const std::string fieldStr, const std::string fieldName, + const bool debugMode, int& field ) + { + field = 0; + if( fieldStr.empty() == false ) + { + field = std::stoi( fieldStr ); //throws invalid_argument + + if( debugMode == true ) + { + if( field < 0 ) + throw std::invalid_argument("ERROR: " + fieldName + " in transport " + method + " can't be negative\n" ); + } + } + }; + currentPosition = 0; while( currentPosition != std::string::npos ) { @@ -243,33 +302,22 @@ void SetMembers( const std::string& fileContent, const MPI_Comm mpiComm, } auto itGroup = groups.find( groupName ); - if( itGroup == groups.end() ) //not found + if( debugMode == true ) { - std::cout << "WARNING: group " << groupName << " in transport line not found \n"; - continue; + if( itGroup == groups.end() ) //not found + throw std::invalid_argument( "ERROR: in transport " + method + " group " + groupName + " not found.\n" ); } - //lambda function to check priority and iteration - auto lf_UIntCheck = []( const std::string method, const std::string fieldStr, const std::string fieldName, int& field ) - { - field = 0; - if( fieldStr.empty() == false ) - { - field = std::stoi( fieldStr ); //throws invalid_argument - if( field < 0 ) throw std::invalid_argument("ERROR: " + fieldName + " in transport " + method + " can't be negative\n" ); - } - }; - int priority, iteration; - lf_UIntCheck( method, priorityStr, "priority", priority ); - lf_UIntCheck( method, iterationStr, "iteration", iteration ); + lf_UIntCheck( method, priorityStr, "priority", debugMode, priority ); + lf_UIntCheck( method, iterationStr, "iteration", debugMode, iteration ); itGroup->second.SetTransport( method, (unsigned int)priority, (unsigned int)iteration, mpiComm ); } } -void InitXML( const std::string xmlConfigFile, const MPI_Comm mpiComm, +void InitXML( const std::string xmlConfigFile, const MPI_Comm mpiComm, const bool debugMode, std::string& hostLanguage, std::map< std::string, CGroup >& groups ) { int xmlFileContentSize; @@ -297,7 +345,7 @@ void InitXML( const std::string xmlConfigFile, const MPI_Comm mpiComm, delete []( xmlFileContentMPI ); //delete char* needed for MPI, might add size is moving to C++14 for optimization, avoid memory leak } - SetMembers( xmlFileContent, mpiComm, hostLanguage, groups ); + SetMembers( xmlFileContent, mpiComm, debugMode, hostLanguage, groups ); } diff --git a/src/functions/GroupFunctions.cpp b/src/functions/GroupFunctions.cpp index 88936be0f..e2679bc5f 100644 --- a/src/functions/GroupFunctions.cpp +++ b/src/functions/GroupFunctions.cpp @@ -20,7 +20,7 @@ namespace adios void CreateVariableLanguage( const std::string hostLanguage, const std::string name, const bool isGlobal, const std::string type, const std::string dimensionsCSV, const std::string transform, - std::map<std::string, std::unique_ptr<CVariableBase> >& variables ) noexcept + std::map<std::string, std::shared_ptr<CVariableBase> >& variables ) noexcept { if( hostLanguage == "C++" ) CreateVariableCpp( name, isGlobal, type, dimensionsCSV, transform, variables ); @@ -35,7 +35,7 @@ void CreateVariableLanguage( const std::string hostLanguage, const std::string n void CreateVariableCpp( const std::string name, const bool isGlobal, const std::string type, const std::string dimensionsCSV, const std::string transform, - std::map< std::string, std::unique_ptr<CVariableBase> >& variables ) noexcept + std::map< std::string, std::shared_ptr<CVariableBase> >& variables ) noexcept { using PVar = std::unique_ptr<CVariableBase>; //might be modified in C++17 if std::make_unique is available, local scope //using emplace to create object in-place, can't use copy constructors with unique_ptr @@ -113,27 +113,44 @@ void CreateVariableCpp( const std::string name, const bool isGlobal, variables.emplace( name, PVar( new CVariable< std::vector< std::complex<long double> > >( isGlobal, type, dimensionsCSV, transform ) ) ); } + void CreateVariableC( const std::string name, const bool isGlobal, const std::string type, const std::string dimensionsCSV, const std::string transform, - std::map< std::string, std::unique_ptr<CVariableBase> >& variables ) noexcept + std::map< std::string, std::shared_ptr<CVariableBase> >& variables ) noexcept { } + void CreateVariableFortran( const std::string name, const bool isGlobal, const std::string type, const std::string dimensionsCSV, const std::string transform, - std::map< std::string, std::unique_ptr<CVariableBase> >& variables ) noexcept + std::map< std::string, std::shared_ptr<CVariableBase> >& variables ) noexcept { } +void SetVariableValues( CVariableBase& variable, const void* values ) noexcept +{ + const std::string type = variable.m_Type; + + //Set variable values, add more support + if( type == "double" ) + variable.Set<double>( values ); + + else if( type == "integer" ) + variable.Set<int>( values ); + + else if( type == "std::vector<int>" || type == "vector<int>" ) + variable.Set<std::vector<int>>( values ); + +} void CreateTransport( const std::string method, const unsigned int priority, const unsigned int iteration, - const MPI_Comm mpiComm, std::unique_ptr<CTransport>& transport ) + const MPI_Comm mpiComm, std::shared_ptr<CTransport>& transport ) noexcept { - using PCT = std::unique_ptr<CTransport>; //might be modified in C++17 if std::make_unique is available, local scope + using PCT = std::shared_ptr<CTransport>; //might be modified in C++14 if std::make_unique is available, local scope if( method == "POSIX" ) transport = PCT( new CPOSIX( priority, iteration, mpiComm ) ); @@ -142,6 +159,7 @@ void CreateTransport( const std::string method, const unsigned int priority, con transport = PCT( new CFStream( priority, iteration, mpiComm ) ); } + } //end namespace diff --git a/src/public/ADIOS.cpp b/src/public/ADIOS.cpp index 27f9486a6..328634026 100644 --- a/src/public/ADIOS.cpp +++ b/src/public/ADIOS.cpp @@ -29,7 +29,7 @@ ADIOS::ADIOS( const std::string xmlConfigFile, const bool debugMode ): m_XMLConfigFile{ xmlConfigFile }, m_DebugMode{ debugMode } { - InitXML( m_XMLConfigFile, m_MPIComm, m_HostLanguage, m_Groups ); + InitXML( m_XMLConfigFile, m_MPIComm, m_DebugMode, m_HostLanguage, m_Groups ); } @@ -38,7 +38,7 @@ ADIOS::ADIOS( const std::string xmlConfigFile, const MPI_Comm mpiComm, const boo m_MPIComm{ mpiComm }, m_DebugMode{ debugMode } { - InitXML( m_XMLConfigFile, m_MPIComm, m_HostLanguage, m_Groups ); + InitXML( m_XMLConfigFile, m_MPIComm, m_DebugMode, m_HostLanguage, m_Groups ); } diff --git a/src/transport/CFStream.cpp b/src/transport/CFStream.cpp index ec6e77a63..f25850ba0 100644 --- a/src/transport/CFStream.cpp +++ b/src/transport/CFStream.cpp @@ -9,7 +9,6 @@ #include <iostream> #include "transport/CFStream.h" -#include "core/CVariable.h" // implements CVariableBase Get function namespace adios @@ -25,27 +24,43 @@ CFStream::~CFStream( ) { } -void CFStream::Write( const CVariableBase& variable ) +void CFStream::Open( const std::string fileName, const std::string accessMode ) { - int rank, size; - MPI_Comm_rank( m_MPIComm, &rank ); - MPI_Comm_size( m_MPIComm, &size ); //would write to file - - const std::string type( variable.m_Type ); - std::cout << "My variable type is " << variable.m_Type << "\n"; - - if( type[0] == 'V' ) //meaning it's a vector - { - //pointer to vector - auto values = variable.Get< std::vector<int> >(); - std::cout << "Vector of size " << values->size() << "\n"; - unsigned int i = 0; - for( auto element : *values ) - { - std::cout << "var[" << i << "] = " << element << "\n"; - ++i; - } - } + if( accessMode == "w" || accessMode == "write" ) + m_FStream.open( fileName, std::fstream::out ); + + else if( accessMode == "r" || accessMode == "read" ) + m_FStream.open( fileName, std::fstream::in ); + + else if( accessMode == "a" || accessMode == "append" ) + m_FStream.open( fileName, std::fstream::out | std::fstream::app ); +} + + +void CFStream::Close( ) +{ + m_FStream.close( ); //close the file + + //This part should go to a capsule +// int rank, size; +// MPI_Comm_rank( m_MPIComm, &rank ); +// MPI_Comm_size( m_MPIComm, &size ); //would write to file +// +// const std::string type( variable.m_Type ); +// std::cout << "My variable type is " << variable.m_Type << "\n"; +// +// if( type[0] == 'V' ) //meaning it's a vector +// { +// //pointer to vector +// auto values = variable.Get< std::vector<int> >(); +// std::cout << "Vector of size " << values->size() << "\n"; +// unsigned int i = 0; +// for( auto element : *values ) +// { +// std::cout << "var[" << i << "] = " << element << "\n"; +// ++i; +// } +// } } diff --git a/src/transport/CPOSIX.cpp b/src/transport/CPOSIX.cpp index bb80dd304..27092be94 100644 --- a/src/transport/CPOSIX.cpp +++ b/src/transport/CPOSIX.cpp @@ -24,14 +24,16 @@ CPOSIX::~CPOSIX( ) { } -void CPOSIX::Write( const CVariableBase& variable ) +void CPOSIX::Open( const std::string fileName, const std::string accessMode ) { - int rank, size; - MPI_Comm_rank( m_MPIComm, &rank ); - MPI_Comm_size( m_MPIComm, &size ); - std::cout << "Just saying Hello from CPOSIX Write from process " << rank << "/" << size << "\n"; } +void CPOSIX::Close( ) +{ + +} + + -} //end namespace +}//end namespace -- GitLab