#include "IO/PIO.h" #include "common/Utilities.h" #include "common/MPI_Helpers.h" #include #include #include namespace IO { static ParallelStreamBuffer pout_buffer; static ParallelStreamBuffer perr_buffer; static ParallelStreamBuffer plog_buffer; std::ostream pout(&pout_buffer); std::ostream perr(&perr_buffer); std::ostream plog(&plog_buffer); /**************************************************************************** * Functions to control logging * ****************************************************************************/ std::ofstream *global_filestream=NULL; static void shutdownFilestream( ) { if ( global_filestream!=NULL ) { global_filestream->flush(); global_filestream->close(); delete global_filestream; global_filestream = NULL; } } void Utilities::logOnlyNodeZero( const std::string &filename ) { int rank = 0; #ifdef USE_MPI MPI_Comm_rank( MPI_COMM_WORLD, &rank ); #endif if ( rank == 0 ) logAllNodes(filename,true); } void Utilities::logAllNodes( const std::string &filename, bool singleStream ) { if ( singleStream ) ERROR("Not implimented yet"); // If the filestream was open, then close it and reset streams shutdownFilestream(); // Open the log stream and redirect output std::string full_filename = filename; if ( !singleStream ) { int rank = 0; #ifdef USE_MPI MPI_Comm_rank( MPI_COMM_WORLD, &rank ); #endif char tmp[100]; sprintf(tmp,".%04i",rank); full_filename += std::string(tmp); } global_filestream = new std::ofstream(full_filename.c_str()); if ( !(*global_filestream) ) { delete global_filestream; global_filestream = NULL; perr << "PIO: Could not open log file ``" << full_filename << "''\n"; } else { pout_buffer.setOutputStream(global_filestream); pout_buffer.setOutputStream(&std::cout); perr_buffer.setOutputStream(global_filestream); perr_buffer.setOutputStream(&std::cerr); plog_buffer.setOutputStream(global_filestream); } } /**************************************************************************** * ParallelStreamBuffer class * ****************************************************************************/ void Utilities::stopLogging( ) { pout_buffer.reset(); perr_buffer.reset(); plog_buffer.reset(); shutdownFilestream(); delete global_filestream; global_filestream = NULL; } /**************************************************************************** * ParallelStreamBuffer class * ****************************************************************************/ ParallelStreamBuffer::ParallelStreamBuffer( ): d_rank(0), d_size(0), d_buffer_size(0), d_buffer(NULL) { } ParallelStreamBuffer:: ~ParallelStreamBuffer() { delete [] d_buffer; } void ParallelStreamBuffer::setOutputStream( std::ostream *stream ) { d_stream.push_back( stream ); } int ParallelStreamBuffer::sync() { for (size_t i=0; i d_buffer_size ) { if ( d_buffer_size==0 ) { d_buffer_size = 1024; d_buffer = new char[d_buffer_size]; memset(d_buffer,0,d_buffer_size); } while ( size > d_buffer_size ) { char *tmp = d_buffer; d_buffer_size *= 2; d_buffer = new char[d_buffer_size]; memset(d_buffer,0,d_buffer_size); memcpy(d_buffer,tmp,d_size); delete [] tmp; } } } std::streamsize ParallelStreamBuffer::xsputn( const char* text, std::streamsize n ) { reserve(d_size+n); memcpy(&d_buffer[d_size],text,n); d_size += n; if ( text[n-1]==0 || text[n-1]==10 ) { sync(); } return n; } int ParallelStreamBuffer::overflow(int ch) { reserve(d_size+1); d_buffer[d_size] = ch; d_size++; if ( ch==0 || ch==10 ) { sync(); } return std::char_traits::to_int_type(ch); } int ParallelStreamBuffer::underflow() { return -1; } void ParallelStreamBuffer::reset() { sync(); d_stream.clear(); delete [] d_buffer; d_buffer = NULL; d_buffer_size = 0; } } // IO namespace