diff --git a/Makefile b/Makefile index ab0db8f0f1f613d200613c00cc159921b1689222..ea705d1d4e18a4eb215cd4dcc5b7fe35e7ccba2d 100644 --- a/Makefile +++ b/Makefile @@ -69,4 +69,4 @@ nompi: $(HFiles) $(OBJNoMPI) $(CC) $(CFLAGS) $(INC) -DADIOS_NOMPI -o $@ $< clean: - rm ./bin/mpi/*.o ./bin/nompi/*.o ./lib/*.a ./lib/*.so + rm ./bin/mpi/*.o ./bin/nompi/*.o ./lib/* diff --git a/bindings/python/test_hello.py b/bindings/python/test_hello.py index cb28d2f1eec22f733dc39305cbf494a7888a9da4..db0b2c6ef927d13f671d37d451f2b86b5db8bf29 100644 --- a/bindings/python/test_hello.py +++ b/bindings/python/test_hello.py @@ -27,8 +27,8 @@ if( rank % 2 == 1 ): # odd ranks only #Setup method and print summary ioSettings = adios.DeclareMethod("adiosSettings", "BPFileWriter") -ioSettings.SetParameters( max_buffer_size = '10000000' ) -ioSettings.AddTransport( 'File', have_metadata_file = 'yes', library = 'POSIX' ) # POSIX is default, just checking +ioSettings.SetParameters( profile_units = 'mus' ) +ioSettings.AddTransport( 'File', have_metadata_file = 'no', profile_units = 'mus' ) # POSIX is default, just checking #Start Engine bpFileWriter = adios.Open( "file.bp", "w", ioSettings, None ) # Open files using N-to-N method, None means no new MPI communicator diff --git a/examples/hello/bpWriter/helloBPWriter.cpp b/examples/hello/bpWriter/helloBPWriter.cpp index 496bdeb3fdf1ec298e46d991efac9c887d3da81c..b962d524a1aa17e7fd6c125b93a9725eb9ade77a 100644 --- a/examples/hello/bpWriter/helloBPWriter.cpp +++ b/examples/hello/bpWriter/helloBPWriter.cpp @@ -54,7 +54,8 @@ int main( int argc, char* argv [] ) //Define method for engine creation, it is basically straight-forward parameters adios::Method& bpWriterSettings = adios.DeclareMethod( "SingleFile" ); //default method type is BPWriter - bpWriterSettings.AddTransport( "File", "have_metadata_file=no" ); //uses default POSIX library + bpWriterSettings.SetParameters( "profile_units=mus" ); + bpWriterSettings.AddTransport( "File", "profile_units=mus", "have_metadata_file=no" ); //uses default POSIX library //Create engine smart pointer due to polymorphism, //Open returns a smart pointer to Engine containing the Derived class Writer diff --git a/examples/hello/bpWriter/helloBPWriter_nompi.cpp b/examples/hello/bpWriter/helloBPWriter_nompi.cpp index a06b1b06136b969c5962586894f50cf2fa2c7a1e..89eb754a1ae7f5f24ccc4b8041fabdcd5edee55d 100644 --- a/examples/hello/bpWriter/helloBPWriter_nompi.cpp +++ b/examples/hello/bpWriter/helloBPWriter_nompi.cpp @@ -40,7 +40,8 @@ int main( int argc, char* argv [] ) //Define method for engine creation, it is basically straight-forward parameters adios::Method& bpWriterSettings = adios.DeclareMethod( "SinglePOSIXFile" ); //default method type is Writer - bpWriterSettings.AddTransport( "File", "have_metadata_file=yes" ); + bpWriterSettings.SetParameters( "profile_units=mus" ); + bpWriterSettings.AddTransport( "File", "have_metadata_file=yes", "profile_units=mus" ); //Create engine smart pointer due to polymorphism, //Open returns a smart pointer to Engine containing the Derived class Writer diff --git a/include/core/Transport.h b/include/core/Transport.h index dc6409e6eb9ae9f8ad984cc038ee10d77dad8957..1c2c0d0bacec7fb76e4584ab5774723b0c0da8fd 100644 --- a/include/core/Transport.h +++ b/include/core/Transport.h @@ -78,7 +78,7 @@ public: virtual void Close( ); ///< closes current transport and flushes everything, transport becomes unreachable - virtual void InitProfiler( const Support::Resolutions resolution ); + virtual void InitProfiler( const std::string accessMode, const Support::Resolutions resolution ); protected: diff --git a/include/format/BP1.h b/include/format/BP1.h index 2e551ecec359039b984a8f4ff3259bf0eaaa1b8d..10c28a28214f8bbb1e02616c45c5ab3da372eeca 100644 --- a/include/format/BP1.h +++ b/include/format/BP1.h @@ -65,6 +65,13 @@ class BP1 public: + /** + * Checks if input name has .bp extension and returns a .bp directory name + * @param name input (might or not have .bp) + * @return either name.bp (name has no .bp) or name (name has .bp extension) + */ + std::string GetDirectoryName( const std::string name ) const noexcept; + /** * Opens rank files in the following format: * if transport.m_MPIComm different from MPI_Comm_SELF --> name.bp.dir/name.bp.rank @@ -72,7 +79,7 @@ public: * @param accessMode "write" "w", "r" "read", "append" "a" * @param transport file I/O transport */ - void OpenRankFiles( const std::string name, const std::string accessMode, Transport& transport ); + void OpenRankFiles( const std::string name, const std::string accessMode, Transport& transport ) const; protected: diff --git a/include/mpidummy.h b/include/mpidummy.h index 619a50ad9d554b5d06f4eca0352942934dfe5fb8..865320755eb511d564c3968f7be7ce3e1f4f3c30 100644 --- a/include/mpidummy.h +++ b/include/mpidummy.h @@ -92,6 +92,8 @@ int MPI_Irecv( void *recvbuffer, int count, MPI_Datatype type, int source, int t int MPI_Send( void *sendbuffer, int count, MPI_Datatype type, int destination, int tag, MPI_Comm comm ); int MPI_Isend( void *recvbuffer, int count, MPI_Datatype type, int source, int tag, MPI_Comm comm, MPI_Request* request ); +int MPI_Wait( MPI_Request* request, MPI_Status* status ); + int MPI_File_open(MPI_Comm comm, char *filename, int amode, MPI_Info info, MPI_File *fh); int MPI_File_close(MPI_File *fh); int MPI_File_get_size(MPI_File fh, MPI_Offset *size); diff --git a/src/core/Transport.cpp b/src/core/Transport.cpp index 81095c229661af8939a04b66da725fcbd30e6df7..4bbc1f7439e6f2db0e09859f16b0aecae7697bcb 100644 --- a/src/core/Transport.cpp +++ b/src/core/Transport.cpp @@ -37,17 +37,17 @@ void Transport::Close( ) { } -void Transport::InitProfiler( const Support::Resolutions resolution ) +void Transport::InitProfiler( const std::string accessMode, const Support::Resolutions resolution ) { m_Profiler.m_Timers.emplace_back( "open", Support::Resolutions::mus ); - if( m_AccessMode == "w" || m_AccessMode == "write" ) + if( accessMode == "w" || accessMode == "write" ) m_Profiler.m_Timers.emplace_back( "write", resolution ); - else if( m_AccessMode == "a" || m_AccessMode == "append" ) + else if( accessMode == "a" || accessMode == "append" ) m_Profiler.m_Timers.emplace_back( "append", resolution ); - else if( m_AccessMode == "r" || m_AccessMode == "read" ) + else if( accessMode == "r" || accessMode == "read" ) m_Profiler.m_Timers.emplace_back( "read", resolution ); m_Profiler.m_Timers.emplace_back( "close", Support::Resolutions::mus ); diff --git a/src/engine/bp/BPFileWriter.cpp b/src/engine/bp/BPFileWriter.cpp index 85fce4ace4aac55d5a75c7b30a6ac040ed381cb4..d717e6d01d31f0554dd39cbf2d4984335464e7a4 100644 --- a/src/engine/bp/BPFileWriter.cpp +++ b/src/engine/bp/BPFileWriter.cpp @@ -34,6 +34,7 @@ BPFileWriter::~BPFileWriter( ) void BPFileWriter::Init( ) { + InitParameters( ); InitTransports( ); InitProcessGroup( ); } @@ -177,8 +178,8 @@ void BPFileWriter::Close( const int transportIndex ) { const std::string rankLog = m_BP1Writer.GetRankProfilingLog( m_RankMPI, m_MetadataSet, m_Transports ); - - + const std::string fileName( m_BP1Writer.GetDirectoryName(m_Name) + "/profiling.log" ); + m_BP1Aggregator.WriteProfilingLog( fileName, rankLog ); } } @@ -211,7 +212,7 @@ void BPFileWriter::InitParameters( ) throw std::invalid_argument( "ERROR: Method buffer_growth argument can't be less of equal than 1, in " + m_EndMessage + "\n" ); } - m_MaxBufferSize = std::stoul( itMaxBufferSize->second ) * 1048576; //convert to bytes + m_MaxBufferSize = std::stoul( itMaxBufferSize->second ) * 1048576; //convert from MB to bytes } auto itVerbosity = m_Method.m_Parameters.find( "verbose" ); @@ -232,19 +233,19 @@ void BPFileWriter::InitParameters( ) auto& profiler = m_MetadataSet.Log; if( itProfile->second == "mus" || itProfile->second == "microseconds" ) - profiler.m_Timers.emplace_back( "Buffering", Support::Resolutions::mus ); + profiler.m_Timers.emplace_back( "buffering", Support::Resolutions::mus ); else if( itProfile->second == "ms" || itProfile->second == "milliseconds" ) - profiler.m_Timers.emplace_back( "Buffering", Support::Resolutions::ms ); + profiler.m_Timers.emplace_back( "buffering", Support::Resolutions::ms ); else if( itProfile->second == "s" || itProfile->second == "seconds" ) - profiler.m_Timers.emplace_back( "Buffering", Support::Resolutions::s ); + profiler.m_Timers.emplace_back( "buffering", Support::Resolutions::s ); else if( itProfile->second == "min" || itProfile->second == "minutes" ) - profiler.m_Timers.emplace_back( "Buffering", Support::Resolutions::m ); + profiler.m_Timers.emplace_back( "buffering", Support::Resolutions::m ); else if( itProfile->second == "h" || itProfile->second == "hours" ) - profiler.m_Timers.emplace_back( "Buffering", Support::Resolutions::h ); + profiler.m_Timers.emplace_back( "buffering", Support::Resolutions::h ); else { if( m_DebugMode == true ) @@ -270,6 +271,7 @@ void BPFileWriter::InitTransports( ) for( const auto& parameters : m_Method.m_TransportParameters ) { auto itProfile = parameters.find( "profile_units" ); + bool doProfiling = false; Support::Resolutions resolution = Support::Resolutions::s; //default is seconds if( itProfile != parameters.end() ) { @@ -293,6 +295,7 @@ void BPFileWriter::InitTransports( ) if( m_DebugMode == true ) throw std::invalid_argument( "ERROR: Transport profile_units argument must be mus, ms, s, min or h " + m_EndMessage ); } + doProfiling = true; } auto itTransport = parameters.find( "transport" ); @@ -303,8 +306,8 @@ void BPFileWriter::InitTransports( ) if( itLibrary == parameters.end() || itLibrary->second == "POSIX" ) //use default POSIX { auto file = std::make_shared<transport::FileDescriptor>( m_MPIComm, m_DebugMode ); - if( parameters.count( "profile_units" ) == 1 ) - file->InitProfiler( resolution ); + if( doProfiling == true ) + file->InitProfiler( m_AccessMode, resolution ); m_BP1Writer.OpenRankFiles( m_Name, m_AccessMode, *file ); m_Transports.push_back( std::move( file ) ); @@ -313,8 +316,8 @@ void BPFileWriter::InitTransports( ) else if( itLibrary->second == "FILE*" || itLibrary->second == "stdio" ) { auto file = std::make_shared<transport::FilePointer>( m_MPIComm, m_DebugMode ); - if( parameters.count( "profile_units" ) == 1 ) - file->InitProfiler( resolution ); + if( doProfiling == true ) + file->InitProfiler( m_AccessMode, resolution ); m_BP1Writer.OpenRankFiles( m_Name, m_AccessMode, *file ); m_Transports.push_back( std::move( file ) ); @@ -322,8 +325,9 @@ void BPFileWriter::InitTransports( ) else if( itLibrary->second == "fstream" || itLibrary->second == "std::fstream" ) { auto file = std::make_shared<transport::FStream>( m_MPIComm, m_DebugMode ); - if( parameters.count( "profile_units" ) == 1 ) - file->InitProfiler( resolution ); + + if( doProfiling == true ) + file->InitProfiler( m_AccessMode, resolution ); m_BP1Writer.OpenRankFiles( m_Name, m_AccessMode, *file ); m_Transports.push_back( std::move( file ) ); diff --git a/src/format/BP1.cpp b/src/format/BP1.cpp index 2c28f28cbc995ce5c8ae49887d14524b5dcf3550..ddf74bb83bdc6a48e9a1dbbb6faffc677cadfc11 100644 --- a/src/format/BP1.cpp +++ b/src/format/BP1.cpp @@ -16,29 +16,29 @@ namespace format { -void BP1::OpenRankFiles( const std::string name, const std::string accessMode, Transport& file ) +std::string BP1::GetDirectoryName( const std::string name ) const noexcept { std::string directory; - std::string baseName; - if( name.find(".bp") == name.size()-3 ) //need to test - { - baseName = name.substr( 0, name.size()-3 ); + if( name.find(".bp") == name.size()-3 ) directory = name; - } else - { - baseName = name; directory = name + ".bp"; - } + + return directory; +} + + +void BP1::OpenRankFiles( const std::string name, const std::string accessMode, Transport& file ) const +{ + const std::string directory = GetDirectoryName( name ); CreateDirectory( directory ); //creates a directory and sub-directories recursively - std::string fileName( directory + "/" + baseName + ".bp." + std::to_string( file.m_RankMPI ) ); + std::string fileName( directory + "/" + directory + "." + std::to_string( file.m_RankMPI ) ); file.Open( fileName, accessMode ); // opens a file transport under name.bp.dir/name.bp.rank reserve that location fro writing } - std::vector<int> BP1::GetMethodIDs( const std::vector< std::shared_ptr<Transport> >& transports ) const noexcept { auto lf_GetMethodID = []( const std::string method ) -> int diff --git a/src/format/BP1Aggregator.cpp b/src/format/BP1Aggregator.cpp index bb2328ff305d4e1f7a7cc7bf328e29bbee2dcb64..9e38f378639453dcbe9abb60db66914740a59397 100644 --- a/src/format/BP1Aggregator.cpp +++ b/src/format/BP1Aggregator.cpp @@ -7,6 +7,8 @@ #include <vector> #include <fstream> +#include <iostream> // must be deleted +#include <unistd.h> // must be deleted #include "format/BP1Aggregator.h" @@ -30,61 +32,61 @@ BP1Aggregator::~BP1Aggregator( ) { } - void BP1Aggregator::WriteProfilingLog( const std::string fileName, const std::string& rankLog ) { if( m_RankMPI == 0 ) { - std::vector< std::vector<char> > rankLogs( m_SizeMPI - 1 ); //rankLogs from other processes + unsigned int sizeMPI = static_cast<unsigned int>( m_SizeMPI ); + std::vector< std::vector<char> > rankLogs( sizeMPI - 1 ); //rankLogs from other processes + std::vector< int > rankLogsSizes( sizeMPI-1, -1 ); //init with -1 + std::vector<MPI_Request> requests( sizeMPI ); + std::vector<MPI_Status> statuses( sizeMPI ); //first receive sizes - unsigned int sizeMPI = static_cast<unsigned int>( m_SizeMPI ); + for( unsigned int i = 1; i < sizeMPI; ++i ) + MPI_Irecv( &rankLogsSizes[i-1], 1, MPI_INT, i, 0, m_MPIComm, &requests[i] ); for( unsigned int i = 1; i < sizeMPI; ++i ) { - int size = -1; - MPI_Request request; - MPI_Irecv( &size, 1, MPI_INT, i, 0, m_MPIComm, &request ); - + MPI_Wait( &requests[i], &statuses[i] ); if( m_DebugMode == true ) { - if( size == -1 ) + if( rankLogsSizes[i-1] == -1 ) throw std::runtime_error( "ERROR: couldn't get size from rank " + std::to_string(i) + ", in ADIOS aggregator for Profiling.log\n" ); - //here check request } - rankLogs[i-1].resize( size ); //allocate with zeros + rankLogs[i-1].resize( rankLogsSizes[i-1] ); //allocate with zeros } + //receive rankLog from other ranks for( unsigned int i = 1; i < sizeMPI; ++i ) - { - int size = static_cast<int>( rankLogs[i-1].size() ); - MPI_Request request; - MPI_Irecv( rankLogs[i-1].data(), size, MPI_CHAR, i, 0, m_MPIComm, &request ); + MPI_Irecv( rankLogs[i-1].data(), rankLogsSizes[i-1], MPI_CHAR, i, 1, m_MPIComm, &requests[i] ); + + for( unsigned int i = 1; i < sizeMPI; ++i ) + MPI_Wait( &requests[i], &statuses[i] ); - if( m_DebugMode == true ) - { - //here check request - } - } //write file - std::string logFile( "log = { " + rankLog + "\n" ); + std::string logFile( "log = { \n" ); + logFile += rankLog + "\n"; for( unsigned int i = 1; i < sizeMPI; ++i ) { - std::string rankLogStr( rankLogs[i-1].data() ); + const std::string rankLogStr( rankLogs[i-1].data(), rankLogs[i-1].size() ); logFile += rankLogStr + "\n"; } logFile += " }\n"; + std::cout << logFile; std::ofstream logStream( fileName ); logStream.write( logFile.c_str(), logFile.size() ); logStream.close(); } else { - int size = static_cast<int>( rankLog.size() ); - MPI_Request request; - MPI_Isend( &size, 1, MPI_INT, 0, 0, m_MPIComm, &request ); - MPI_Isend( const_cast<char*>( rankLog.c_str() ), size, MPI_CHAR, 0, 0, m_MPIComm, &request ); + int rankLogSize = static_cast<int>( rankLog.size() ); + MPI_Request requestSize; + MPI_Isend( &rankLogSize, 1, MPI_INT, 0, 0, m_MPIComm, &requestSize ); + + MPI_Request requestRankLog; + MPI_Isend( const_cast<char*>( rankLog.c_str() ), rankLogSize, MPI_CHAR, 0, 1, m_MPIComm, &requestRankLog ); } } diff --git a/src/format/BP1Writer.cpp b/src/format/BP1Writer.cpp index 2ad022f860b346623c309e4e46702622251576fd..cb63d54fdbb1f82c2207a1731d18014de46b040b 100644 --- a/src/format/BP1Writer.cpp +++ b/src/format/BP1Writer.cpp @@ -7,6 +7,8 @@ /// \cond EXCLUDE_FROM_DOXYGEN #include <string> +#include <iostream> +#include <unistd.h> //sleep must be removed /// \endcond #include "format/BP1Writer.h" @@ -103,8 +105,6 @@ void BP1Writer::WriteProcessGroupIndex( const bool isFortran, const std::string void BP1Writer::Advance( BP1MetadataSet& metadataSet, capsule::STLVector& buffer ) { FlattenData( metadataSet, buffer ); - - } @@ -150,29 +150,33 @@ void BP1Writer::Close( BP1MetadataSet& metadataSet, capsule::STLVector& buffer, std::string BP1Writer::GetRankProfilingLog( const int rank, const BP1MetadataSet& metadataSet, const std::vector< std::shared_ptr<Transport> >& transports ) const noexcept { - auto lf_WriterTimer = []( const std::string name, const Timer& timer, std::string rankLog ) + auto lf_WriterTimer = []( std::string& rankLog, const Timer& timer ) { - rankLog += "'" + name + "_" + timer.GetUnits() + "': " + std::to_string( timer.ProcessTime ) + ", "; + rankLog += timer.Process + "_" + timer.GetUnits() + "': " + std::to_string( timer.ProcessTime ) + ", "; }; //prepare string dictionary per rank std::string rankLog( "'rank_" + std::to_string( rank ) + "': { " ); auto& profiler = metadataSet.Log; - rankLog += "'totalBytes': " + std::to_string( profiler.m_TotalBytes[0] ) + ", "; - lf_WriterTimer( "t_buffering", profiler.m_Timers[0], rankLog ); + rankLog += "'bytes': " + std::to_string( profiler.m_TotalBytes[0] ) + ", "; + lf_WriterTimer( rankLog, profiler.m_Timers[0] ); for( unsigned int t = 0; t < transports.size(); ++t ) { auto& timers = transports[t]->m_Profiler.m_Timers; rankLog += "'transport_" + std::to_string(t) + "': { "; - lf_WriterTimer( "t_open", timers[0], rankLog ); - lf_WriterTimer( "t_write", timers[1], rankLog ); - lf_WriterTimer( "t_close", timers[2], rankLog ); + rankLog += "'lib:' " + transports[t]->m_Type + ", "; + + for( unsigned int i = 0; i < 3; ++i ) + lf_WriterTimer( rankLog, timers[i] ); + rankLog += " }, "; } rankLog += "}, "; + + //std::cout << rankLog << "\n"; return rankLog; } diff --git a/src/functions/adiosFunctions.cpp b/src/functions/adiosFunctions.cpp index 2abe0c7c4ff22dddc680b660eb6654b1bdda0866..48fd527502fbb3cd041587d9c3434e1602bbd668 100644 --- a/src/functions/adiosFunctions.cpp +++ b/src/functions/adiosFunctions.cpp @@ -378,9 +378,7 @@ void CreateDirectory( const std::string fullPath ) noexcept auto lf_Mkdir = []( const std::string directory, struct stat& st ) { if ( stat( directory.c_str(), &st ) == -1 ) - { mkdir( directory.c_str(), 0777 ); - } }; auto directoryPosition = fullPath.find( "/" ); diff --git a/src/mpidummy.cpp b/src/mpidummy.cpp index 52fd646e4c02b8cfe2c5e60099f1f0d5a0dd9f23..e58e1b817cdf2756be130428857f0c844079f0f4 100644 --- a/src/mpidummy.cpp +++ b/src/mpidummy.cpp @@ -177,6 +177,8 @@ int MPI_Send( void *sendbuffer, int count, MPI_Datatype type, int destination, i int MPI_Isend( void *recvbuffer, int count, MPI_Datatype type, int source, int tag, MPI_Comm comm, MPI_Request* request ) { return 0; } +int MPI_Wait( MPI_Request* request, MPI_Status* status ) +{ return 0; } int MPI_File_open(MPI_Comm comm, char *filename, int amode, MPI_Info info, MPI_File *fh) {