#include "base.h" FILE *logfile = NULL; // // Attempt to determine what the operating system sees in terms of the memory used by this process. // This is system-dependent; OSX does not have the /proc//status file, so we query the kernel // directly. Linux systems have a /proc//status file for each running process, so parse that. // #ifdef __MACH__ // source: http://blog.kuriositaet.de/?p=257 - I think the author is Tim Becker, based on some slides on the same blog! int getmem( unsigned int *rss, unsigned int *vs ) { struct task_basic_info t_info; mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; if( KERN_SUCCESS != task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&t_info, &t_info_count) ) return -1; *rss = t_info.resident_size; *vs = t_info.virtual_size; return 0; } #else // based on example code on the Lockless Inc. website: http://locklessinc.com/articles/memory_usage/ int getmem( unsigned int *rss, unsigned int *vs ) { char line[128], buf[64]; char *strings[2]; FILE *f; *rss = *vs = 0; for( int i=0; i<2; i++ ) strings[i] = NULL; sprintf( buf, "/proc/%d/status", getpid() ); if( (f = fopen( buf, "r" )) == NULL ) return 0; while( !strings[0] || !strings[1] ) { if( fgets( line, sizeof(line), f ) == NULL ) { fclose( f ); return 0; } if( strncmp( line, "VmSize:", 7 ) == 0 ) strings[0] = strdup( &line[7] ); else if( strncmp( line, "VmRSS:", 6 ) == 0 ) strings[1] = strdup( &line[6] ); } fclose( f ); for( int i=0; i<2; i++ ) { int len = strlen( strings[i] ); strings[i][ len - 4 ] = 0; } *vs = atoi( strings[0] ) * 1024; *rss = atoi( strings[1] ) * 1024; for( int i=0; i<2; i++ ) free( strings[i] ); return 0; } #endif double GetTime() { return MPI_Wtime(); } void Log( const char *format, ... ) { char buffer[512]; // you know what they say about assumptions, right? va_list args; va_start( args, format ); vsprintf( buffer, format, args ); va_end( args ); if( logfile != NULL ) fprintf( logfile, "%s", buffer ); } void Error( const char *called_from, const char *in_file, int on_line, const char *format, ... ) { int rank, nranks; va_list args; char buffer[1024]; // <- Turing weeps gently MPI_Comm_rank( MPI_COMM_WORLD, &rank ); MPI_Comm_size( MPI_COMM_WORLD, &nranks ); Log( "\n***** ERROR: rank %d/%d *****\n", rank, nranks ); Log( "\nSource: %s(), %s:%d\n", called_from, in_file, on_line ); va_start( args, format ); vsprintf( buffer, format, args ); va_end( args ); Log( "\nMessage: %s\n\n", buffer ); Log( "******************\n" ); if( logfile != NULL ) fflush( logfile ); MPI_Abort( MPI_COMM_WORLD, -1 ); }