diff --git a/include/core/CCapsule.h b/include/core/CCapsule.h index dbc1ab59728cbaa14abfd46c8313f168c8d1abcc..a8c7d2a8b15ed4f96faa9bc55d14c67507406ebe 100644 --- a/include/core/CCapsule.h +++ b/include/core/CCapsule.h @@ -66,7 +66,7 @@ public: ~CCapsule( ); /** - * + * Add a transport to a stream * @param streamName * @param accessMode * @param isDefault diff --git a/include/core/CGroup.h b/include/core/CGroup.h index 15420bedbf08459ad596f3621846df93d601d5db..6a6d83ec634d8740e188a43aa932a9fdccf8b2db 100644 --- a/include/core/CGroup.h +++ b/include/core/CGroup.h @@ -60,23 +60,33 @@ public: ~CGroup( ); ///< Using STL containers, no deallocation /** - * Creates a new variable in the group object + * Define a new variable in the group object * @param name variable name, must be unique in the group. If name exists it removes the current variable. In debug mode program will exit. * @param type variable type, must be in SSupport::Datatypes[hostLanguage] in public/SSupport.h * @param dimensionsCSV comma separated variable local dimensions (e.g. "Nx,Ny,Nz") * @param globalDimensionsCSV comma separated variable global dimensions (e.g. "gNx,gNy,gNz"), if globalOffsetsCSV is also empty variable is local * @param globalOffsetsCSV comma separated variable global dimensions (e.g. "gNx,gNy,gNz"), if globalOffsetsCSV is also empty variable is local */ - void DefineVariable( const std::string name, const std::string type, + void DefineVariable( const std::string variableName, const std::string type, const std::string dimensionsCSV, const std::string globalDimensionsCSV, const std::string globalOffsetsCSV ); + + /** + * Sets a variable transform contained in ADIOS.m_Transforms (single container for all groups and variables) + * @param variableName variable to be assigned a transformation + * @param transformIndex index in + * @param compressionLevel from 0 to 9 + */ + void SetTransform( const std::string variableName, const unsigned int transformIndex, const unsigned int compressionLevel ); + + /** - * - * @param name attribute name, must be unique. If name exists it removes the current variable. In debug mode program will exit. + * Define a new attribute + * @param attributeName attribute name, must be unique. If name exists it removes the current variable. In debug mode program will exit. * @param type attribute type string or numeric type * @param value information about the attribute */ - void DefineAttribute( const std::string name, const std::string type, const std::string value ); + void DefineAttribute( const std::string attributeName, const std::string type, const std::string value ); /** * @brief Dumps groups information to a file stream or standard output. diff --git a/include/core/SVariable.h b/include/core/SVariable.h index 74b21893a381fd4b75e1339d26cdc54e4f2d42dc..c4aedf6849c7a1d681fc5042374ac1f21b44acf5 100644 --- a/include/core/SVariable.h +++ b/include/core/SVariable.h @@ -23,10 +23,11 @@ namespace adios template< class T > struct SVariable { - const std::string m_DimensionsCSV; ///< comma separated list for variables to search for local dimensions - const T* m_Values; ///< pointer to values passed from ADIOS Write - const short m_GlobalBoundsIndex; ///< if global > 0, index corresponds to global-bounds in m_GlobalBounds in CGroup, if local then = -1 - short m_TransformIndex; ///< if global > 0, index corresponds to , if local then = -1 + const std::string DimensionsCSV; ///< comma separated list for variables to search for local dimensions + const T* Values; ///< pointer to values passed from ADIOS Write + const short GlobalBoundsIndex; ///< if global > 0, index corresponds to global-bounds in m_GlobalBounds in CGroup, if local then = -1 + short TransformIndex = -1; ///< if no transformation then = -1, otherwise index to m_Transforms container in ADIOS + unsigned short CompressionLevel = 0; ///< if 0, then use default, values from 1 to 9 indicate compression level }; diff --git a/include/public/ADIOS.h b/include/public/ADIOS.h index fb9a99634c6f5c49db5c56391cc1632406274a84..3fa2eaafc8c0391fa05d1e3f30e1857766726198 100644 --- a/include/public/ADIOS.h +++ b/include/public/ADIOS.h @@ -197,7 +197,6 @@ public: // PUBLIC Constructors and Functions define the User Interface with ADIO * @param variableName corresponding variable name * @param type variable type * @param dimensionsCSV comma separated (no space) dimensions "Nx,Ny,Nz" defined by other variables - * @param transform transformation method applied to current variable * @param globalDimensionsCSV comma separated (no space) global dimensions "gNx,gNy,gNz" defined by other variables * @param globalOffsetsCSV comma separated (no space) global offsets "oNx,oNy,oNz" defined by other variables */ diff --git a/src/core/CCapsule.cpp b/src/core/CCapsule.cpp index 83488cae2668f267d153cb2b1a93dfc9e539543f..620fb9cebc572b3f859d3e7c5c67ab42d0a8434c 100644 --- a/src/core/CCapsule.cpp +++ b/src/core/CCapsule.cpp @@ -62,6 +62,11 @@ int CCapsule::AddTransport( const std::string streamName, const std::string acce else if( transport == "DataMan" ) m_Transports.push_back( std::make_shared<CDataMan>( m_MPIComm, m_DebugMode, arguments ) ); + + int transportIndex = static_cast<int>( m_Transports.size() - 1 ); + m_Transports[ transportIndex ]->Open( name, accessMode ); + + return transportIndex; } @@ -99,36 +104,11 @@ std::string CCapsule::GetName( const std::vector<std::string>& arguments ) const if( m_DebugMode == true ) { if( name.empty() || isNameFound == false ) - std::invalid_argument("ERROR: argument to name= is empty in call to AddTransport" ); + std::invalid_argument( "ERROR: argument to name= is empty or not found in call to AddTransport" ); } return name; } - -//void CCapsule::CreateTransform( const std::string transform ) -//{ -// std::string method( transform ); -// auto colonPosition = transform.find(":"); -// -// if( colonPosition != transform.npos ) -// { -// method = transform.substr( 0, colonPosition ); -// } -// -// if( m_Transforms.find( method ) != m_Transforms.end() ) //transform method already exists, do nothing -// return; -// -// if( method == "bzip2" ) //here must add debug mode exception -// { -// #ifdef HAVE_BZIP2 -// m_Transforms["bzip2"] = std::make_shared<CBZIP2>( ); -// #endif -// } -//} - - - - } //end namespace diff --git a/src/core/CGroup.cpp b/src/core/CGroup.cpp index 70f5804c999bf90c13e723635380d029f2ccde89..015271e483e99e5bb2555198a26e6ee604b086b0 100644 --- a/src/core/CGroup.cpp +++ b/src/core/CGroup.cpp @@ -38,82 +38,165 @@ CGroup::~CGroup( ) { } -void CGroup::DefineVariable( const std::string name, const std::string type, +void CGroup::DefineVariable( const std::string variableName, const std::string type, const std::string dimensionsCSV, const std::string globalDimensionsCSV, const std::string globalOffsetsCSV ) { 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 - m_Variables[name] = std::make_pair( type, CurrentTypeIndex( type ) ); + throw std::invalid_argument( "ERROR: type " + type + " for variable " + variableName + " is not supported.\n" ); + if( m_Variables.count( variableName ) == 0 ) //variable doesn't exists + m_Variables[variableName] = std::make_pair( type, CurrentTypeIndex( type ) ); else //name is found - throw std::invalid_argument( "ERROR: variable " + name + " exists more than once.\n" ); + throw std::invalid_argument( "ERROR: variable " + variableName + " exists more than once.\n" ); } else { - m_Variables[name] = std::make_pair( type, CurrentTypeIndex( type ) ); + m_Variables[variableName] = std::make_pair( type, CurrentTypeIndex( type ) ); } - int transformIndex = SetTransforms( transform ); int globalBoundsIndex = SetGlobalBounds( globalDimensionsCSV, globalOffsetsCSV ); if( type == "char" || type == "character" ) - m_Char.push_back( SVariable<char>{ dimensionsCSV, nullptr, transformIndex, globalBoundsIndex } ); + m_Char.push_back( SVariable<char>{ dimensionsCSV, nullptr, globalBoundsIndex } ); else if( type == "unsigned char" ) - m_UChar.push_back( SVariable<unsigned char>{ dimensionsCSV, nullptr, transformIndex, globalBoundsIndex } ); + m_UChar.push_back( SVariable<unsigned char>{ dimensionsCSV, nullptr, globalBoundsIndex } ); else if( type == "short" || type == "integer*2" ) - m_Short.push_back( SVariable<short>{ dimensionsCSV, nullptr, transformIndex, globalBoundsIndex } ); + m_Short.push_back( SVariable<short>{ dimensionsCSV, nullptr, globalBoundsIndex } ); else if( type == "unsigned short" ) - m_UShort.push_back( SVariable<unsigned short>{ dimensionsCSV, nullptr, transformIndex, globalBoundsIndex } ); + m_UShort.push_back( SVariable<unsigned short>{ dimensionsCSV, nullptr, globalBoundsIndex } ); else if( type == "int" || type == "integer" ) - m_Int.push_back( SVariable<int>{ dimensionsCSV, nullptr, transformIndex, globalBoundsIndex } ); + m_Int.push_back( SVariable<int>{ dimensionsCSV, nullptr, globalBoundsIndex } ); else if( type == "unsigned int" || type == "unsigned integer" ) - m_UInt.push_back( SVariable<unsigned int>{ dimensionsCSV, nullptr, transformIndex, globalBoundsIndex } ); + m_UInt.push_back( SVariable<unsigned int>{ dimensionsCSV, nullptr, globalBoundsIndex } ); else if( type == "long int" || type == "long" || type == "long integer" ) - m_LInt.push_back( SVariable<long int>{ dimensionsCSV, nullptr, transformIndex, globalBoundsIndex } ); + m_LInt.push_back( SVariable<long int>{ dimensionsCSV, nullptr, globalBoundsIndex } ); + + else if( type == "unsigned long int" || type == "unsigned long" || type == "unsigned long integer" ) + m_ULInt.push_back( SVariable<unsigned long int>{ dimensionsCSV, nullptr, globalBoundsIndex } ); else if( type == "long long int" || type == "long long" || type == "long long integer" ) - m_LLInt.push_back( SVariable<long long int>{ dimensionsCSV, nullptr, transformIndex, globalBoundsIndex } ); + m_LLInt.push_back( SVariable<long long int>{ dimensionsCSV, nullptr, globalBoundsIndex } ); else if( type == "unsigned long long int" || type == "unsigned long long" || type == "unsigned long long integer" ) - m_ULLInt.push_back( SVariable<unsigned long long int>{ dimensionsCSV, nullptr, transformIndex, globalBoundsIndex } ); + m_ULLInt.push_back( SVariable<unsigned long long int>{ dimensionsCSV, nullptr, globalBoundsIndex } ); else if( type == "float" || type == "real" || type == "real*4" ) - m_Float.push_back( SVariable<float>{ dimensionsCSV, nullptr, transformIndex, globalBoundsIndex } ); + m_Float.push_back( SVariable<float>{ dimensionsCSV, nullptr, globalBoundsIndex } ); else if( type == "double" || type == "double precision" || type == "real*8" ) - m_Double.push_back( SVariable<double>{ dimensionsCSV, nullptr, transformIndex, globalBoundsIndex } ); + m_Double.push_back( SVariable<double>{ dimensionsCSV, nullptr, globalBoundsIndex } ); else if( type == "long double" || type == "real*16" ) - m_LDouble.push_back( SVariable<long double>{ dimensionsCSV, nullptr, transformIndex, globalBoundsIndex } ); + m_LDouble.push_back( SVariable<long double>{ dimensionsCSV, nullptr, globalBoundsIndex } ); + + m_SerialSize += variableName.size() + type.size() + dimensionsCSV.size() + 4 * sizeof( char ); //4, adding one more for globalBoundsIndex +} + + +void CGroup::SetTransform( const std::string variableName, const unsigned int transformIndex, const unsigned int compressionLevel ) +{ + auto itVariable = m_Variables.find( variableName ); + + if( m_DebugMode == true ) + { + if( itVariable == m_Variables.end() ) //variable doesn't exists + throw std::invalid_argument( "ERROR: variable " + variableName + " doesn't exist, in call to SetTransform.\n" ); + } + + const std::string type( itVariable->second.first ); + const unsigned int index = itVariable->second.second; - m_SerialSize += name.size() + type.size() + dimensionsCSV.size() + transform.size() + 5 * sizeof(char); //5, adding one more for globalBoundsIndex + if( type == "char" || type == "character" ) + { + m_Char[index].TransformIndex = transformIndex; + m_Char[index].CompressionLevel = compressionLevel; + } + else if( type == "unsigned char" ) + { + m_UChar[index].TransformIndex = transformIndex; + m_UChar[index].CompressionLevel = compressionLevel; + } + else if( type == "short" || type == "integer*2" ) + { + m_Short[index].TransformIndex = transformIndex; + m_Short[index].CompressionLevel = compressionLevel; + } + else if( type == "unsigned short" ) + { + m_UShort[index].TransformIndex = transformIndex; + m_UShort[index].CompressionLevel = compressionLevel; + } + else if( type == "int" || type == "integer" ) + { + m_Int[index].TransformIndex = transformIndex; + m_Int[index].CompressionLevel = compressionLevel; + } + else if( type == "unsigned int" || type == "unsigned integer" ) + { + m_UInt[index].TransformIndex = transformIndex; + m_UInt[index].CompressionLevel = compressionLevel; + } + else if( type == "long int" || type == "long" || type == "long integer" ) + { + m_LInt[index].TransformIndex = transformIndex; + m_LInt[index].CompressionLevel = compressionLevel; + } + else if( type == "unsigned long int" || type == "unsigned long" || type == "unsigned long integer" ) + { + m_ULInt[index].TransformIndex = transformIndex; + m_ULInt[index].CompressionLevel = compressionLevel; + } + else if( type == "long long int" || type == "long long" || type == "long long integer" ) + { + m_ULInt[index].TransformIndex = transformIndex; + m_ULInt[index].CompressionLevel = compressionLevel; + } + else if( type == "unsigned long long int" || type == "unsigned long long" || type == "unsigned long long integer" ) + { + m_ULLInt[index].TransformIndex = transformIndex; + m_ULLInt[index].CompressionLevel = compressionLevel; + } + else if( type == "float" || type == "real" || type == "real*4" ) + { + m_Float[index].TransformIndex = transformIndex; + m_Float[index].CompressionLevel = compressionLevel; + } + else if( type == "double" || type == "double precision" || type == "real*8" ) + { + m_Double[index].TransformIndex = transformIndex; + m_Double[index].CompressionLevel = compressionLevel; + } + else if( type == "long double" || type == "real*16" ) + { + m_LDouble[index].TransformIndex = transformIndex; + m_LDouble[index].CompressionLevel = compressionLevel; + } } -void CGroup::CreateAttribute( const std::string name, const std::string type, const std::string value ) +void CGroup::DefineAttribute( const std::string attributeName, const std::string type, const std::string value ) { if( m_DebugMode == true ) { - if( m_Attributes.count( name ) == 0 ) //variable doesn't exists - m_Attributes.emplace( name, SAttribute{ type, value } ); + if( m_Attributes.count( attributeName ) == 0 ) //attribute doesn't exists + m_Attributes.emplace( attributeName, SAttribute{ type, value } ); else //name is found - throw std::invalid_argument( "ERROR: attribute " + name + " exists, NOT setting a new variable\n" ); + throw std::invalid_argument( "ERROR: attribute " + attributeName + " exists, NOT setting a new variable\n" ); } else { - m_Attributes.emplace( name, SAttribute{ type, value } ); + m_Attributes.emplace( attributeName, SAttribute{ type, value } ); } - m_SerialSize += name.size() + type.size() + value.size() + 3; //3 is one byte storing the size as a char + m_SerialSize += attributeName.size() + type.size() + value.size() + 3 * sizeof( char ); //3 is one byte storing the size as a char } @@ -130,28 +213,28 @@ const unsigned long long int CGroup::GetIntVariableValue( const std::string vari const unsigned long long int value = 0; if( type == "short" ) - value = *( m_Short[index].m_Values ); + value = *( m_Short[index].Values ); else if( type == "unsigned short" ) - value = *( m_UShort[index].m_Values ); + value = *( m_UShort[index].Values ); else if( type == "int" ) - value = *( m_Int[index].m_Values ); + value = *( m_Int[index].Values ); else if( type == "unsigned int" ) - value = *( m_UInt[index].m_Values ); + value = *( m_UInt[index].Values ); else if( type == "long int" ) - value = *( m_LInt[index].m_Values ); + value = *( m_LInt[index].Values ); else if( type == "unsigned long int" ) - value = *( m_ULInt[index].m_Values ); + value = *( m_ULInt[index].Values ); else if( type == "long long int" ) - value = *( m_LLInt[index].m_Values ); + value = *( m_LLInt[index].Values ); else if( type == "unsigned long long int" ) - value = *( m_ULLInt[index].m_Values ); + value = *( m_ULLInt[index].Values ); else throw std::invalid_argument( "ERROR: variable " + variableName + " must be of short, int or associated type (long int, unsigned long int, etc.)\n" ); @@ -245,18 +328,18 @@ void CGroup::ParseXMLGroup( const std::string& xmlGroup ) else if( pair.first == "dimensions" ) dimensionsCSV = pair.second; else if( pair.first == "transform" ) transform = pair.second; } - CreateVariable( name, type, dimensionsCSV, transform, globalDimensionsCSV, globalOffsetsCSV ); + DefineVariable( name, type, dimensionsCSV, globalDimensionsCSV, globalOffsetsCSV ); } else if( tagName == "attribute" ) { - std::string name, path, value, type; + std::string name, value, type; for( auto& pair : pairs ) //loop through all pairs { if( pair.first == "name" ) name = pair.second; else if( pair.first == "value" ) value = pair.second; else if( pair.first == "type" ) type = pair.second; } - CreateAttribute( name, type, value, globalDimensionsCSV, globalOffsetsCSV ); + DefineAttribute( name, type, value ); } else if( tagName == "global-bounds" ) { @@ -351,25 +434,5 @@ const int CGroup::SetGlobalBounds( const std::string globalDimensionsCSV, const } -const int CGroup::SetTransforms( const std::string transform ) noexcept -{ - if( transform.empty() ) - return -1; - - int transformIndex = -1; - auto itTransform = std::find( m_Transforms.begin(), m_Transforms.end(), transform ); - if( itTransform != m_Transforms.end() ) - { - transformIndex = std::distance( m_Transforms.begin(), itTransform ); - } - else - { - m_Transforms.push_back( transform ); - transformIndex = m_Transforms.size(); - } - - return transformIndex; -} - } //end namespace diff --git a/src/public/ADIOS.cpp b/src/public/ADIOS.cpp index 71b66771074a47ccdd5d3d225db9c2777d49d438..961d1d8e213ef8587cd27b0e7efde3a1b1faa790 100644 --- a/src/public/ADIOS.cpp +++ b/src/public/ADIOS.cpp @@ -117,9 +117,32 @@ 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 ) { auto itGroup = m_Groups.find( groupName ); - if( m_DebugMode == true ) + if( m_DebugMode == true ) //check group and transform + { CheckGroup( itGroup, groupName, " from call to SetTransform \n" ); + if( SSupport::Transforms.count( transform ) == 0 ) + throw std::invalid_argument( "ERROR: transform method " + transform + " not supported, in call to SetTransform\n" ); + } + + //get method:compressionLevel from transform + std::string method( transform ); + int compressionLevel = 0; + + auto colonPosition = transform.find( ":" ); + + if( colonPosition != transform.npos ) + { + if( m_DebugMode == true ) + { + if( colonPosition == transform.size() - 1 ) + throw std::invalid_argument( "ERROR: wrong format for transform " + transform + ", in call to SetTransform\n" ); + } + + method = transform.substr( 0, colonPosition ); + compressionLevel = std::stoi( transform.substr( colonPosition+1 ) ); + } + int transformIndex = -1; for( unsigned int i = 0; i < m_Transforms.size(); ++i ) { @@ -129,7 +152,16 @@ void ADIOS::SetTransform( const std::string groupName, const std::string variabl break; } } - //itGroup->second.SetTransform( variableName, transform ); + + if( transformIndex == -1 ) //not found, then create a new transform + { + if( transform == "bzip2" ) + { + m_Transforms.push_back( std::make_shared<CBZIP2>( ) ); + } + } + + itGroup->second.SetTransform( variableName, transformIndex, compressionLevel ); } diff --git a/src/public/SSupport.cpp b/src/public/SSupport.cpp index eeafd7c177e2a6d639a8f8614e923b917bbc53cc..b0a2d38084a14dab88f4cc032d35138df8e41097 100644 --- a/src/public/SSupport.cpp +++ b/src/public/SSupport.cpp @@ -27,7 +27,7 @@ const std::set<std::string> SSupport::Transports{ const std::set<std::string> SSupport::Transforms{ - { "none", "identity", "bzip2", "isobar" } + { "none", "identity", "bzip2", "isobar", "szip" , "zlib" } };